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 */
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 =
{
@ -492,24 +495,24 @@ g_static_mutex_init (GStaticMutex *mutex)
* Deprecated: 2.32: Just use a #GMutex
*/
GMutex *
g_static_mutex_get_mutex_impl (GMutex** mutex)
g_static_mutex_get_mutex_impl (GStaticMutex* mutex)
{
GMutex *result;
if (!g_thread_supported ())
return NULL;
result = g_atomic_pointer_get (mutex);
result = g_atomic_pointer_get (&mutex->mutex);
if (!result)
{
g_mutex_lock (&g_once_mutex);
result = *mutex;
result = mutex->mutex;
if (!result)
{
result = g_mutex_new ();
g_atomic_pointer_set (mutex, result);
g_atomic_pointer_set (&mutex->mutex, result);
}
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,
gpointer user_data) G_GNUC_DEPRECATED;
#ifdef G_OS_WIN32
typedef GMutex * GStaticMutex;
#define G_STATIC_MUTEX_INIT NULL
#ifndef G_OS_WIN32
#include <pthread.h>
#endif
#define g_static_mutex_get_mutex g_static_mutex_get_mutex_impl
#else /* G_OS_WIN32 */
typedef struct {
GMutex *unused;
GMutex mutex;
#define G_STATIC_MUTEX_INIT { NULL }
typedef struct
{
GMutex *mutex;
#ifndef G_OS_WIN32
/* only for ABI compatibility reasons */
pthread_mutex_t unused;
#endif
} 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) \
g_mutex_lock (g_static_mutex_get_mutex (mutex))
@ -135,6 +137,7 @@ typedef struct {
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_free (GStaticMutex *mutex) G_GNUC_DEPRECATED_FOR(g_mutex_free);
GMutex* g_static_mutex_get_mutex_impl (GStaticMutex *mutex);
typedef struct _GStaticRecMutex GStaticRecMutex;
struct _GStaticRecMutex
@ -210,8 +213,6 @@ GLIB_VAR gboolean g_threads_got_initialized;
#define g_thread_supported() (g_threads_got_initialized)
#endif
GMutex* g_static_mutex_get_mutex_impl (GMutex **mutex);
GMutex * g_mutex_new (void) G_GNUC_DEPRECATED;
void g_mutex_free (GMutex *mutex) G_GNUC_DEPRECATED;
GCond * g_cond_new (void) G_GNUC_DEPRECATED;