diff options
author | bitground <70304874+bitground@users.noreply.github.com> | 2020-09-14 17:03:09 +0800 |
---|---|---|
committer | dormando <dormando@rydia.net> | 2020-10-26 16:36:00 -0700 |
commit | b031143f8ab61296ddbf6c4470c5dcdbf7ae588b (patch) | |
tree | 39ad84ea0e932ddfd496b6543b5880a0f6fab53b /testapp.c | |
parent | 6b319c8c7a29e9c353dec83dc92f01905f6c8966 (diff) | |
download | memcached-b031143f8ab61296ddbf6c4470c5dcdbf7ae588b.tar.gz |
Fix over-freeing in internal object cache
When returning item to the cache and the items allocated exceeded cache->limit, we should free the item and not put it to the cache.
The current code will free any item that tried returned to the cache when cache->total < cache->limit which is true in most cases if the total objects has never exceeded the limit.
Diffstat (limited to 'testapp.c')
-rw-r--r-- | testapp.c | 29 |
1 files changed, 29 insertions, 0 deletions
@@ -244,6 +244,34 @@ static enum test_return cache_redzone_test(void) #endif } +static enum test_return cache_limit_revised_downward_test(void) +{ + int limit = 10, allocated_num = limit + 1, i; + char ** alloc_objs = calloc(allocated_num, sizeof(char *)); + + cache_t *cache = cache_create("test", sizeof(uint32_t), sizeof(char*), + NULL, NULL); + assert(cache != NULL); + + /* cache->limit is 0 and we can allocate limit+1 items */ + for (i = 0; i < allocated_num; i++) { + alloc_objs[i] = cache_alloc(cache); + assert(alloc_objs[i] != NULL); + } + assert(cache->total == allocated_num); + + /* revised downward cache->limit */ + cache_set_limit(cache, limit); + + /* If we free one item, the cache->total should decreased by one*/ + cache_free(cache, alloc_objs[0]); + + assert(cache->total == allocated_num-1); + cache_destroy(cache); + + return TEST_PASS; +} + static enum test_return test_stats_prefix_find(void) { PREFIX_STATS *pfs1, *pfs2; @@ -2237,6 +2265,7 @@ struct testcase testcases[] = { { "cache_destructor", cache_destructor_test }, { "cache_reuse", cache_reuse_test }, { "cache_redzone", cache_redzone_test }, + { "cache_limit_revised_downward", cache_limit_revised_downward_test }, { "stats_prefix_find", test_stats_prefix_find }, { "stats_prefix_record_get", test_stats_prefix_record_get }, { "stats_prefix_record_delete", test_stats_prefix_record_delete }, |