diff options
Diffstat (limited to 'glib/gnode.c')
-rw-r--r-- | glib/gnode.c | 36 |
1 files changed, 31 insertions, 5 deletions
diff --git a/glib/gnode.c b/glib/gnode.c index 9f6e544ba..089a4996d 100644 --- a/glib/gnode.c +++ b/glib/gnode.c @@ -19,6 +19,11 @@ * Free Software Foundation, Inc., 59 Temple Place - Suite 330, * Boston, MA 02111-1307, USA. */ + +/* + * MT safe + */ + #include "glib.h" /* node allocation @@ -34,10 +39,12 @@ struct _GAllocator /* from gmem.c */ GNode *free_nodes; /* implementation specific */ }; +static G_LOCK_DEFINE(current_allocator); static GAllocator *current_allocator = NULL; -void -g_node_push_allocator (GAllocator *allocator) +/* HOLDS: current_allocator_lock */ +static void +g_node_validate_allocator (GAllocator *allocator) { g_return_if_fail (allocator != NULL); g_return_if_fail (allocator->is_unused == TRUE); @@ -62,13 +69,22 @@ g_node_push_allocator (GAllocator *allocator) } allocator->is_unused = FALSE; +} + +void +g_node_push_allocator (GAllocator *allocator) +{ + g_node_validate_allocator ( allocator ); + g_lock (current_allocator); allocator->last = current_allocator; current_allocator = allocator; + g_unlock (current_allocator); } void g_node_pop_allocator (void) { + g_lock (current_allocator); if (current_allocator) { GAllocator *allocator; @@ -78,6 +94,7 @@ g_node_pop_allocator (void) allocator->last = NULL; allocator->is_unused = TRUE; } + g_unlock (current_allocator); } @@ -87,9 +104,15 @@ g_node_new (gpointer data) { GNode *node; + g_lock (current_allocator); if (!current_allocator) - g_node_push_allocator (g_allocator_new ("GLib default GNode allocator", 1024)); - + { + GAllocator *allocator = g_allocator_new ("GLib default GNode allocator", + 1024); + g_node_validate_allocator (allocator); + allocator->last = NULL; + current_allocator = allocator; + } if (!current_allocator->free_nodes) node = g_chunk_new (GNode, current_allocator->mem_chunk); else @@ -97,6 +120,7 @@ g_node_new (gpointer data) node = current_allocator->free_nodes; current_allocator->free_nodes = node->next; } + g_unlock (current_allocator); node->data = data; node->next = NULL; @@ -122,9 +146,11 @@ g_nodes_free (GNode *node) else break; } - + + g_lock (current_allocator); parent->next = current_allocator->free_nodes; current_allocator->free_nodes = node; + g_unlock (current_allocator); } void |