diff --git a/gobject/gatomicarray.c b/gobject/gatomicarray.c index 77966f2eb..99019fe65 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,13 +78,33 @@ 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; } +void +_g_atomic_array_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) @@ -166,3 +189,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 b2ad9705d..79a87d81f 100644 --- a/gobject/gatomicarray.h +++ b/gobject/gatomicarray.h @@ -35,11 +35,13 @@ 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); void _g_atomic_array_update (GAtomicArray *array, gpointer new_data); +void _g_atomic_array_cleanup(void); #define G_ATOMIC_ARRAY_GET_LOCKED(_array, _type) ((_type *)((_array)->data))