GStaticMutex: ABI fixup

Everything was OK as long as GMutex was backed by pthread_mutex_t on
POSIX.  Since this is no longer the case, the ABI of GStaticMutex was
broken.

Fix that up by using pthread_mutex_t directly in the structure.  Since
that's potentially incompatible with our GMutex implementation, set
g_thread_use_default_impl to FALSE to cause the fallback code (which
manually allocates a GMutex) to run, even in the case of
already-existing code (without the need for a recompile).  This will
cause the pthread_mutex_t part of the struct to be completely ignored.
This commit is contained in:
Ryan Lortie 2011-10-10 13:13:31 -04:00
parent 2c1cbde21e
commit 3e5a30fc17
2 changed files with 21 additions and 17 deletions

View File

@ -113,7 +113,10 @@
/* {{{1 Exported Variables */ /* {{{1 Exported Variables */
gboolean g_thread_use_default_impl = TRUE; /* Set this FALSE to have previously-compiled GStaticMutex code use the
* slow path (ie: call into us) to avoid compatibility problems.
*/
gboolean g_thread_use_default_impl = FALSE;
GThreadFunctions g_thread_functions_for_glib_use = GThreadFunctions g_thread_functions_for_glib_use =
{ {
@ -492,24 +495,24 @@ g_static_mutex_init (GStaticMutex *mutex)
* Deprecated: 2.32: Just use a #GMutex * Deprecated: 2.32: Just use a #GMutex
*/ */
GMutex * GMutex *
g_static_mutex_get_mutex_impl (GMutex** mutex) g_static_mutex_get_mutex_impl (GStaticMutex* mutex)
{ {
GMutex *result; GMutex *result;
if (!g_thread_supported ()) if (!g_thread_supported ())
return NULL; return NULL;
result = g_atomic_pointer_get (mutex); result = g_atomic_pointer_get (&mutex->mutex);
if (!result) if (!result)
{ {
g_mutex_lock (&g_once_mutex); g_mutex_lock (&g_once_mutex);
result = *mutex; result = mutex->mutex;
if (!result) if (!result)
{ {
result = g_mutex_new (); result = g_mutex_new ();
g_atomic_pointer_set (mutex, result); g_atomic_pointer_set (&mutex->mutex, result);
} }
g_mutex_unlock (&g_once_mutex); g_mutex_unlock (&g_once_mutex);

View File

@ -114,18 +114,20 @@ void g_thread_set_priority (GThread *thread,
void g_thread_foreach (GFunc thread_func, void g_thread_foreach (GFunc thread_func,
gpointer user_data) G_GNUC_DEPRECATED; gpointer user_data) G_GNUC_DEPRECATED;
#ifdef G_OS_WIN32 #ifndef G_OS_WIN32
typedef GMutex * GStaticMutex; #include <pthread.h>
#define G_STATIC_MUTEX_INIT NULL #endif
#define g_static_mutex_get_mutex g_static_mutex_get_mutex_impl #define g_static_mutex_get_mutex g_static_mutex_get_mutex_impl
#else /* G_OS_WIN32 */ #define G_STATIC_MUTEX_INIT { NULL }
typedef struct { typedef struct
GMutex *unused; {
GMutex mutex; GMutex *mutex;
#ifndef G_OS_WIN32
/* only for ABI compatibility reasons */
pthread_mutex_t unused;
#endif
} GStaticMutex; } GStaticMutex;
#define G_STATIC_MUTEX_INIT { NULL, { NULL } }
#define g_static_mutex_get_mutex(s) (&(s)->mutex)
#endif /* G_OS_WIN32 */
#define g_static_mutex_lock(mutex) \ #define g_static_mutex_lock(mutex) \
g_mutex_lock (g_static_mutex_get_mutex (mutex)) g_mutex_lock (g_static_mutex_get_mutex (mutex))
@ -135,6 +137,7 @@ typedef struct {
g_mutex_unlock (g_static_mutex_get_mutex (mutex)) g_mutex_unlock (g_static_mutex_get_mutex (mutex))
void g_static_mutex_init (GStaticMutex *mutex) G_GNUC_DEPRECATED_FOR(g_mutex_init); void g_static_mutex_init (GStaticMutex *mutex) G_GNUC_DEPRECATED_FOR(g_mutex_init);
void g_static_mutex_free (GStaticMutex *mutex) G_GNUC_DEPRECATED_FOR(g_mutex_free); void g_static_mutex_free (GStaticMutex *mutex) G_GNUC_DEPRECATED_FOR(g_mutex_free);
GMutex* g_static_mutex_get_mutex_impl (GStaticMutex *mutex);
typedef struct _GStaticRecMutex GStaticRecMutex; typedef struct _GStaticRecMutex GStaticRecMutex;
struct _GStaticRecMutex struct _GStaticRecMutex
@ -210,8 +213,6 @@ GLIB_VAR gboolean g_threads_got_initialized;
#define g_thread_supported() (g_threads_got_initialized) #define g_thread_supported() (g_threads_got_initialized)
#endif #endif
GMutex* g_static_mutex_get_mutex_impl (GMutex **mutex);
GMutex * g_mutex_new (void) G_GNUC_DEPRECATED; GMutex * g_mutex_new (void) G_GNUC_DEPRECATED;
void g_mutex_free (GMutex *mutex) G_GNUC_DEPRECATED; void g_mutex_free (GMutex *mutex) G_GNUC_DEPRECATED;
GCond * g_cond_new (void) G_GNUC_DEPRECATED; GCond * g_cond_new (void) G_GNUC_DEPRECATED;