[gegl] TileHandlerCache: Always discard tiles in dispose()



commit fa3123afcdfa5d0b695daf786ac044c98126781b
Author: Daniel Sabo <DanielSabo gmail com>
Date:   Sun Jan 26 23:10:03 2014 -0800

    TileHandlerCache: Always discard tiles in dispose()
    
    Previously GeglBuffer always called _reinit() in its
    destructor, so the cache would always be empty by the
    time _dispose() was called.

 gegl/buffer/gegl-buffer.c             |    7 ---
 gegl/buffer/gegl-tile-handler-cache.c |   78 ++++++++-------------------------
 gegl/buffer/gegl-tile-handler-cache.h |    1 -
 3 files changed, 18 insertions(+), 68 deletions(-)
---
diff --git a/gegl/buffer/gegl-buffer.c b/gegl/buffer/gegl-buffer.c
index 80b6fe5..0bdd585 100644
--- a/gegl/buffer/gegl-buffer.c
+++ b/gegl/buffer/gegl-buffer.c
@@ -404,13 +404,6 @@ gegl_buffer_dispose (GObject *object)
 
       if (gegl_tile_backend_get_flush_on_destroy (backend))
         gegl_buffer_flush (buffer);
-
-      gegl_tile_source_reinit (GEGL_TILE_SOURCE (handler->source));
-
-#if 0
-      g_object_unref (handler->source);
-      handler->source = NULL; /* this might be a dangerous way of marking that we have already voided */
-#endif
     }
 
   _gegl_buffer_drop_hot_tile (buffer);
diff --git a/gegl/buffer/gegl-tile-handler-cache.c b/gegl/buffer/gegl-tile-handler-cache.c
index bb91b7b..07228b4 100644
--- a/gegl/buffer/gegl-tile-handler-cache.c
+++ b/gegl/buffer/gegl-tile-handler-cache.c
@@ -113,23 +113,29 @@ gegl_tile_handler_cache_init (GeglTileHandlerCache *cache)
   gegl_tile_cache_init ();
 }
 
+typedef struct
+{
+  GeglTileHandlerCache *cache;
+  GSList               *free_list;
+} CacheReInitContext;
 
 static void
-gegl_tile_handler_cache_reinit_buffer_tiles (gpointer itm,
+gegl_tile_handler_cache_reinit_buffer_tiles (gpointer queue_item,
                                              gpointer userdata)
 {
-  CacheItem *item;
-  item = itm;
-  if (item->handler == userdata)
+  CacheReInitContext *ctx  = userdata;
+  CacheItem          *item = queue_item;
+
+  if (item->handler == ctx->cache)
     {
-      GeglTileHandlerCache *cache = userdata;
-      cache->free_list = g_slist_prepend (cache->free_list, item);
+      ctx->free_list = g_slist_prepend (ctx->free_list, item);
     }
 }
 
 static void
 gegl_tile_handler_cache_reinit (GeglTileHandlerCache *cache)
 {
+  CacheReInitContext    ctx = {cache, NULL};
   CacheItem            *item;
   GSList               *iter;
 
@@ -143,11 +149,8 @@ gegl_tile_handler_cache_reinit (GeglTileHandlerCache *cache)
     return;
 
   g_mutex_lock (&mutex);
-  /* only throw out items belonging to this cache instance */
-
-  cache->free_list = NULL;
-  g_queue_foreach (cache_queue, gegl_tile_handler_cache_reinit_buffer_tiles, cache);
-  for (iter = cache->free_list; iter; iter = g_slist_next (iter))
+  g_queue_foreach (cache_queue, gegl_tile_handler_cache_reinit_buffer_tiles, &ctx);
+  for (iter = ctx.free_list; iter; iter = g_slist_next (iter))
     {
       item = iter->data;
       if (item->tile)
@@ -161,67 +164,22 @@ gegl_tile_handler_cache_reinit (GeglTileHandlerCache *cache)
       g_hash_table_remove (cache_ht, item);
       g_slice_free (CacheItem, item);
     }
-  g_slist_free (cache->free_list);
-  cache->free_list = NULL;
+  g_slist_free (ctx.free_list);
   g_mutex_unlock (&mutex);
 }
 
 static void
-gegl_tile_handler_cache_dispose_buffer_tiles (gpointer itm,
-                                              gpointer userdata)
-{
-  CacheItem *item;
-  item = itm;
-  if (item->handler == userdata)
-    {
-      GeglTileHandlerCache *cache = userdata;
-      cache->free_list = g_slist_prepend (cache->free_list, item);
-    }
-}
-
-static void
 gegl_tile_handler_cache_dispose (GObject *object)
 {
-  GeglTileHandlerCache *cache;
-  CacheItem            *item;
-  GSList               *iter;
-
-  cache = (GeglTileHandlerCache*) (object);
-
-  /* only throw out items belonging to this cache instance */
-
-  cache->free_list = NULL;
-  /* XXX: for optimization this could be delayed,. or collected among multiple
-   * buffer destructions, to avoid the overhead of walking the full queue for
-   * every tiny buffer being destroyed.
-   */
+  GeglTileHandlerCache *cache = GEGL_TILE_HANDLER_CACHE (object);
 
-  if (cache->count)
-    {
-      g_mutex_lock (&mutex);
-      g_queue_foreach (cache_queue, gegl_tile_handler_cache_dispose_buffer_tiles, cache);
-      for (iter = cache->free_list; iter; iter = g_slist_next (iter))
-        {
-            item = iter->data;
-            if (item->tile)
-              {
-                cache_total -= item->tile->size;
-                gegl_tile_unref (item->tile);
-                cache->count--;
-              }
-            g_queue_unlink (cache_queue, &item->link);
-            g_hash_table_remove (cache_ht, item);
-            g_slice_free (CacheItem, item);
-        }
-      g_slist_free (cache->free_list);
-      cache->free_list = NULL;
-      g_mutex_unlock (&mutex);
-    }
+  gegl_tile_handler_cache_reinit (cache);
 
   if (cache->count < 0)
     {
       g_warning ("cache-handler tile balance not zero: %i\n", cache->count);
     }
+
   G_OBJECT_CLASS (gegl_tile_handler_cache_parent_class)->dispose (object);
 }
 
diff --git a/gegl/buffer/gegl-tile-handler-cache.h b/gegl/buffer/gegl-tile-handler-cache.h
index b130a62..ad80cfe 100644
--- a/gegl/buffer/gegl-tile-handler-cache.h
+++ b/gegl/buffer/gegl-tile-handler-cache.h
@@ -40,7 +40,6 @@ struct _GeglTileHandlerCache
 {
   GeglTileHandler  parent_instance;
   GeglTileStorage *tile_storage;
-  GSList          *free_list;
   int              count; /* number of items held by cache */
 };
 


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]