diff --git a/glib/gatomic.c b/glib/gatomic.c index 1e83f193f..5b354c44a 100644 --- a/glib/gatomic.c +++ b/glib/gatomic.c @@ -82,6 +82,17 @@ * perform the operations normally and then release the lock. **/ +/* NOTE CAREFULLY: + * + * This file is the lowest-level part of GLib. + * + * Other lowlevel parts of GLib (threads, slice allocator, g_malloc, + * messages, etc) call into these functions and macros to get work done. + * + * As such, these functions can not call back into any part of GLib + * without risking recursion. + */ + #ifdef G_ATOMIC_OP_USE_GCC_BUILTINS #ifndef __GNUC__ @@ -604,18 +615,24 @@ gsize #else -#include "gthread.h" +/* We are not permitted to call into any GLib functions from here, so we + * can not use GMutex. + * + * Fortunately, we already take care of the Windows case above, and all + * non-Windows platforms on which glib runs have pthreads. Use those. + */ +#include -static GStaticMutex g_atomic_lock; +static pthread_mutex_t g_atomic_lock = PTHREAD_MUTEX_INITIALIZER; gint (g_atomic_int_get) (volatile gint *atomic) { gint value; - g_static_mutex_lock (&g_atomic_lock); + pthread_mutex_lock (&g_atomic_lock); value = *atomic; - g_static_mutex_unlock (&g_atomic_lock); + pthread_mutex_unlock (&g_atomic_lock); return value; } @@ -624,17 +641,17 @@ void (g_atomic_int_set) (volatile gint *atomic, gint value) { - g_static_mutex_lock (&g_atomic_lock); + pthread_mutex_lock (&g_atomic_lock); *atomic = value; - g_static_mutex_unlock (&g_atomic_lock); + pthread_mutex_unlock (&g_atomic_lock); } void (g_atomic_int_inc) (volatile gint *atomic) { - g_static_mutex_lock (&g_atomic_lock); + pthread_mutex_lock (&g_atomic_lock); (*atomic)++; - g_static_mutex_unlock (&g_atomic_lock); + pthread_mutex_unlock (&g_atomic_lock); } gboolean @@ -642,9 +659,9 @@ gboolean { gboolean is_zero; - g_static_mutex_lock (&g_atomic_lock); + pthread_mutex_lock (&g_atomic_lock); is_zero = --(*atomic) == 0; - g_static_mutex_unlock (&g_atomic_lock); + pthread_mutex_unlock (&g_atomic_lock); return is_zero; } @@ -656,12 +673,12 @@ gboolean { gboolean success; - g_static_mutex_lock (&g_atomic_lock); + pthread_mutex_lock (&g_atomic_lock); if ((success = (*atomic == oldval))) *atomic = newval; - g_static_mutex_unlock (&g_atomic_lock); + pthread_mutex_unlock (&g_atomic_lock); return success; } @@ -672,10 +689,10 @@ gint { gint oldval; - g_static_mutex_lock (&g_atomic_lock); + pthread_mutex_lock (&g_atomic_lock); oldval = *atomic; *atomic = oldval + val; - g_static_mutex_unlock (&g_atomic_lock); + pthread_mutex_unlock (&g_atomic_lock); return oldval; } @@ -686,10 +703,10 @@ guint { guint oldval; - g_static_mutex_lock (&g_atomic_lock); + pthread_mutex_lock (&g_atomic_lock); oldval = *atomic; *atomic = oldval & val; - g_static_mutex_unlock (&g_atomic_lock); + pthread_mutex_unlock (&g_atomic_lock); return oldval; } @@ -700,10 +717,10 @@ guint { guint oldval; - g_static_mutex_lock (&g_atomic_lock); + pthread_mutex_lock (&g_atomic_lock); oldval = *atomic; *atomic = oldval | val; - g_static_mutex_unlock (&g_atomic_lock); + pthread_mutex_unlock (&g_atomic_lock); return oldval; } @@ -714,10 +731,10 @@ guint { guint oldval; - g_static_mutex_lock (&g_atomic_lock); + pthread_mutex_lock (&g_atomic_lock); oldval = *atomic; *atomic = oldval ^ val; - g_static_mutex_unlock (&g_atomic_lock); + pthread_mutex_unlock (&g_atomic_lock); return oldval; } @@ -729,9 +746,9 @@ gpointer volatile gpointer *ptr = atomic; gpointer value; - g_static_mutex_lock (&g_atomic_lock); + pthread_mutex_lock (&g_atomic_lock); value = *ptr; - g_static_mutex_unlock (&g_atomic_lock); + pthread_mutex_unlock (&g_atomic_lock); return value; } @@ -742,9 +759,9 @@ void { volatile gpointer *ptr = atomic; - g_static_mutex_lock (&g_atomic_lock); + pthread_mutex_lock (&g_atomic_lock); *ptr = newval; - g_static_mutex_unlock (&g_atomic_lock); + pthread_mutex_unlock (&g_atomic_lock); } gboolean @@ -755,12 +772,12 @@ gboolean volatile gpointer *ptr = atomic; gboolean success; - g_static_mutex_lock (&g_atomic_lock); + pthread_mutex_lock (&g_atomic_lock); if ((success = (*ptr == oldval))) *ptr = newval; - g_static_mutex_unlock (&g_atomic_lock); + pthread_mutex_unlock (&g_atomic_lock); return success; } @@ -772,10 +789,10 @@ gssize volatile gssize *ptr = atomic; gssize oldval; - g_static_mutex_lock (&g_atomic_lock); + pthread_mutex_lock (&g_atomic_lock); oldval = *ptr; *ptr = oldval + val; - g_static_mutex_unlock (&g_atomic_lock); + pthread_mutex_unlock (&g_atomic_lock); return oldval; } @@ -787,10 +804,10 @@ gsize volatile gsize *ptr = atomic; gsize oldval; - g_static_mutex_lock (&g_atomic_lock); + pthread_mutex_lock (&g_atomic_lock); oldval = *ptr; *ptr = oldval & val; - g_static_mutex_unlock (&g_atomic_lock); + pthread_mutex_unlock (&g_atomic_lock); return oldval; } @@ -802,10 +819,10 @@ gsize volatile gsize *ptr = atomic; gsize oldval; - g_static_mutex_lock (&g_atomic_lock); + pthread_mutex_lock (&g_atomic_lock); oldval = *ptr; *ptr = oldval | val; - g_static_mutex_unlock (&g_atomic_lock); + pthread_mutex_unlock (&g_atomic_lock); return oldval; } @@ -817,10 +834,10 @@ gsize volatile gsize *ptr = atomic; gsize oldval; - g_static_mutex_lock (&g_atomic_lock); + pthread_mutex_lock (&g_atomic_lock); oldval = *ptr; *ptr = oldval ^ val; - g_static_mutex_unlock (&g_atomic_lock); + pthread_mutex_unlock (&g_atomic_lock); return oldval; }