From d32c0f99bd8e05dfb3a878bc49e1ce96a68caf85 Mon Sep 17 00:00:00 2001 From: Lucas De Marchi Date: Fri, 10 Sep 2010 23:00:26 +0000 Subject: [PATCH] Fix accounting of memory usage in image cache Memory usage was not accounted right because cache->func.mem_size_get(ie) returns 0 when called after cache->func.destructor(ie). Thus the total memory used, kept on cache->usage, is never decremented in _evas_cache_image_remove_activ() This implies that cache->usage will keep growing and eventually it will overflow, becoming negative. So evas_cache_image_flush() will not do its job because cache->limit (assumed to be positive) will not be less than cache->usage anymore. So the total memory allocated will start to grow and the limit won't be respected. Strictly speaking, it's not a leak, since all the memory will be eventually freed when evas shutdown is called, but the program might be killed by over allocating memory. This is caught by valgrind with the massif tool. The graphic below shows that in the end a huge memory amount is allocated. This is the moment when cache->usage became negative. MB 26.04^ # | #:::: | #:::: | #:::: | #:::: | #:::: | #:::: | #:::: | #:::: | #:::: | #:::: | #:::: | #:::: | #:::: | #:::: | #:::: | #:::: | #:::: | :::::::::::::::::@@:::::::::@:::@::::::@::::::::::::::::::::::::::#:::: | : ::: ::: ::: :::@ :: ::: : @:: @:: :::@: :: ::: : : :: :: : ::: :#:::: 0 +----------------------------------------------------------------------->Gi 0 54.83 This patch is a one line fix, which swaps the calls to _evas_cache_image_remove_activ() and cache->func.destructor() making cache->limit to be respected. SVN revision: 52149 --- legacy/evas/src/lib/cache/evas_cache_image.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/legacy/evas/src/lib/cache/evas_cache_image.c b/legacy/evas/src/lib/cache/evas_cache_image.c index 445d99eae5..afdd94395c 100644 --- a/legacy/evas/src/lib/cache/evas_cache_image.c +++ b/legacy/evas/src/lib/cache/evas_cache_image.c @@ -213,10 +213,10 @@ _evas_cache_image_entry_delete(Evas_Cache_Image *cache, Image_Entry *ie) } #endif - cache->func.destructor(ie); - _evas_cache_image_remove_activ(cache, ie); + cache->func.destructor(ie); + if (ie->cache_key) { eina_stringshare_del(ie->cache_key);