[glib/wip/gcleanup] gatomicarray: Support for cleaning up



commit cad746a858ace33932c13a4f0ffff5bb5aaf8ad6
Author: Stef Walter <stefw gnome org>
Date:   Thu Nov 7 22:42:39 2013 +0100

    gatomicarray: Support for cleaning up

 gobject/gatomicarray.c |   38 +++++++++++++++++++++++++++++++++++++-
 gobject/gatomicarray.h |    1 +
 2 files changed, 38 insertions(+), 1 deletions(-)
---
diff --git a/gobject/gatomicarray.c b/gobject/gatomicarray.c
index 77966f2..2b71c44 100644
--- a/gobject/gatomicarray.c
+++ b/gobject/gatomicarray.c
@@ -50,6 +50,9 @@ struct _FreeListNode {
   FreeListNode *next;
 };
 
+#define G_ATOMIC_ARRAY_REAL_SIZE_FROM(size) \
+  sizeof (gsize) + MAX (size, sizeof (FreeListNode))
+
 /* This is really a list of array memory blocks, using the
  * first item as the next pointer to chain them together.
  * Protected by array lock */
@@ -75,19 +78,45 @@ freelist_alloc (gsize size, gboolean reuse)
        }
     }
 
-  real_size = sizeof (gsize) + MAX (size, sizeof (FreeListNode));
+  real_size = G_ATOMIC_ARRAY_REAL_SIZE_FROM (size);
   mem = g_slice_alloc (real_size);
   mem = ((char *) mem) + sizeof (gsize);
   G_ATOMIC_ARRAY_DATA_SIZE (mem) = size;
   return mem;
 }
 
+static void
+freelist_cleanup (void)
+{
+  FreeListNode *cur, *next;
+
+  cur = freelist;
+  freelist = NULL;
+
+  for (; cur; cur = next)
+    {
+      gsize size, real_size;
+
+      next = cur->next;
+
+      size = G_ATOMIC_ARRAY_DATA_SIZE (cur);
+      real_size = G_ATOMIC_ARRAY_REAL_SIZE_FROM (size);
+      g_slice_free1 (real_size, ((char *) cur) - sizeof (gsize));
+    }
+}
+
 /* must hold array lock */
 static void
 freelist_free (gpointer mem)
 {
   FreeListNode *free;
 
+  if (freelist == NULL)
+    {
+      g_cleanup_list_push (G_CLEANUP_LIST, (GCleanupFunc)freelist_cleanup, NULL,
+                           G_CLEANUP_PHASE_GRAVEYARD, "freelist_cleanup");
+    }
+
   free = mem;
   free->next = freelist;
   freelist = free;
@@ -166,3 +195,10 @@ _g_atomic_array_update (GAtomicArray *array,
     freelist_free (old);
   G_UNLOCK (array);
 }
+
+void
+_g_atomic_array_free (GAtomicArray *array)
+{
+  if (array->data != NULL)
+    freelist_free (array->data);
+}
diff --git a/gobject/gatomicarray.h b/gobject/gatomicarray.h
index b2ad970..5a6a4db 100644
--- a/gobject/gatomicarray.h
+++ b/gobject/gatomicarray.h
@@ -35,6 +35,7 @@ struct _GAtomicArray {
 };
 
 void     _g_atomic_array_init   (GAtomicArray *array);
+void     _g_atomic_array_free   (GAtomicArray *array);
 gpointer _g_atomic_array_copy   (GAtomicArray *array,
                                 gsize         header_size,
                                 gsize         additional_element_size);


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