[glib] GThread posix: switch to Windows ABI



commit e081eadda598bc708fbf9dd53a190fc3b0e7fa76
Author: Ryan Lortie <desrt desrt ca>
Date:   Sun Oct 2 20:43:28 2011 -0400

    GThread posix: switch to Windows ABI
    
    Modify the POSIX implementation of the synchronisation primatives to use
    the same ABI as Windows: one pointer for each type.
    
    This frees us from having to #include <pthread.h> and avoids the problem
    with pthread_rwlock_t not being defined under certain compiler defines.
    
    A few more changes are expected to the ABI -- they will be committed
    separately.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=659866

 glib/gthread-posix.c |  198 ++++++++++++++++++++++++++++++++++++++------------
 glib/gthread.h       |   29 -------
 2 files changed, 152 insertions(+), 75 deletions(-)
---
diff --git a/glib/gthread-posix.c b/glib/gthread-posix.c
index 0423f42..f2c35ae 100644
--- a/glib/gthread-posix.c
+++ b/glib/gthread-posix.c
@@ -78,6 +78,58 @@ g_thread_abort (gint         status,
 
 /* {{{1 GMutex */
 
+static pthread_mutex_t *
+g_mutex_impl_new (void)
+{
+  pthread_mutexattr_t *pattr = NULL;
+  pthread_mutex_t *mutex;
+  gint status;
+
+  mutex = malloc (sizeof (pthread_mutex_t));
+  if G_UNLIKELY (mutex == NULL)
+    g_thread_abort (errno, "malloc");
+
+#ifdef PTHREAD_ADAPTIVE_MUTEX_INITIALIZER_NP
+  pthread_mutexattr_t attr;
+  pthread_mutexattr_init (&attr);
+  pthread_mutexattr_settype (&attr, PTHREAD_MUTEX_ADAPTIVE_NP);
+  pattr = &attr;
+#endif
+
+  if G_UNLIKELY ((status = pthread_mutex_init (mutex, pattr)) != 0)
+    g_thread_abort (status, "pthread_mutex_init");
+
+#ifdef PTHREAD_ADAPTIVE_MUTEX_NP
+  pthread_mutexattr_destroy (&attr);
+#endif
+
+  return mutex;
+}
+
+static void
+g_mutex_impl_free (pthread_mutex_t *mutex)
+{
+  pthread_mutex_destroy (mutex);
+  free (mutex);
+}
+
+static pthread_mutex_t *
+g_mutex_get_impl (GMutex *mutex)
+{
+  pthread_mutex_t *impl = mutex->impl;
+
+  if G_UNLIKELY (impl == NULL)
+    {
+      impl = g_mutex_impl_new ();
+      if (!g_atomic_pointer_compare_and_exchange (&mutex->impl, NULL, impl))
+        g_mutex_impl_free (impl);
+      impl = mutex->impl;
+    }
+
+  return impl;
+}
+
+
 /**
  * g_mutex_init:
  * @mutex: an uninitialized #GMutex
@@ -113,21 +165,7 @@ g_thread_abort (gint         status,
 void
 g_mutex_init (GMutex *mutex)
 {
-  gint status;
-  pthread_mutexattr_t *pattr = NULL;
-#ifdef PTHREAD_ADAPTIVE_MUTEX_INITIALIZER_NP
-  pthread_mutexattr_t attr;
-  pthread_mutexattr_init (&attr);
-  pthread_mutexattr_settype (&attr, PTHREAD_MUTEX_ADAPTIVE_NP);
-  pattr = &attr;
-#endif
-
-  if G_UNLIKELY ((status = pthread_mutex_init (&mutex->impl, pattr)) != 0)
-    g_thread_abort (status, "pthread_mutex_init");
-
-#ifdef PTHREAD_ADAPTIVE_MUTEX_NP
-  pthread_mutexattr_destroy (&attr);
-#endif
+  mutex->impl = g_mutex_impl_new ();
 }
 
 /**
@@ -147,10 +185,7 @@ g_mutex_init (GMutex *mutex)
 void
 g_mutex_clear (GMutex *mutex)
 {
-  gint status;
-
-  if G_UNLIKELY ((status = pthread_mutex_destroy (&mutex->impl)) != 0)
-    g_thread_abort (status, "pthread_mutex_destroy");
+  g_mutex_impl_free (mutex->impl);
 }
 
 /**
@@ -174,7 +209,7 @@ g_mutex_lock (GMutex *mutex)
 {
   gint status;
 
-  if G_UNLIKELY ((status = pthread_mutex_lock (&mutex->impl)) != 0)
+  if G_UNLIKELY ((status = pthread_mutex_lock (g_mutex_get_impl (mutex))) != 0)
     g_thread_abort (status, "pthread_mutex_lock");
 }
 
@@ -196,7 +231,7 @@ g_mutex_unlock (GMutex *mutex)
 {
   gint status;
 
-  if G_UNLIKELY ((status = pthread_mutex_unlock (&mutex->impl)) != 0)
+  if G_UNLIKELY ((status = pthread_mutex_unlock (g_mutex_get_impl (mutex))) != 0)
     g_thread_abort (status, "pthread_mutex_lock");
 }
 
@@ -223,7 +258,7 @@ g_mutex_trylock (GMutex *mutex)
 {
   gint status;
 
-  if G_LIKELY ((status = pthread_mutex_trylock (&mutex->impl)) == 0)
+  if G_LIKELY ((status = pthread_mutex_trylock (g_mutex_get_impl (mutex))) == 0)
     return TRUE;
 
   if G_UNLIKELY (status != EBUSY)
@@ -261,7 +296,7 @@ g_rec_mutex_get_impl (GRecMutex *rec_mutex)
 {
   pthread_mutex_t *impl = rec_mutex->impl;
 
-  if G_UNLIKELY (rec_mutex->impl == NULL)
+  if G_UNLIKELY (impl == NULL)
     {
       impl = g_rec_mutex_impl_new ();
       if (!g_atomic_pointer_compare_and_exchange (&rec_mutex->impl, NULL, impl))
@@ -330,8 +365,7 @@ g_rec_mutex_init (GRecMutex *rec_mutex)
 void
 g_rec_mutex_clear (GRecMutex *rec_mutex)
 {
-  if (rec_mutex->impl)
-    g_rec_mutex_impl_free (rec_mutex->impl);
+  g_rec_mutex_impl_free (rec_mutex->impl);
 }
 
 /**
@@ -395,6 +429,45 @@ g_rec_mutex_trylock (GRecMutex *rec_mutex)
 
 /* {{{1 GRWLock */
 
+static pthread_rwlock_t *
+g_rw_lock_impl_new (void)
+{
+  pthread_rwlock_t *rwlock;
+  gint status;
+
+  rwlock = malloc (sizeof (pthread_rwlock_t));
+  if G_UNLIKELY (rwlock == NULL)
+    g_thread_abort (errno, "malloc");
+
+  if G_UNLIKELY ((status = pthread_rwlock_init (rwlock, NULL)) != 0)
+    g_thread_abort (status, "pthread_rwlock_init");
+
+  return rwlock;
+}
+
+static void
+g_rw_lock_impl_free (pthread_rwlock_t *rwlock)
+{
+  pthread_rwlock_destroy (rwlock);
+  free (rwlock);
+}
+
+static pthread_rwlock_t *
+g_rw_lock_get_impl (GRWLock *lock)
+{
+  pthread_rwlock_t *impl = lock->impl;
+
+  if G_UNLIKELY (impl == NULL)
+    {
+      impl = g_rw_lock_impl_new ();
+      if (!g_atomic_pointer_compare_and_exchange (&lock->impl, NULL, impl))
+        g_rw_lock_impl_free (impl);
+      impl = lock->impl;
+    }
+
+  return impl;
+}
+
 /**
  * g_rw_lock_init:
  * @rw_lock: an uninitialized #GRWLock
@@ -429,7 +502,7 @@ g_rec_mutex_trylock (GRecMutex *rec_mutex)
 void
 g_rw_lock_init (GRWLock *rw_lock)
 {
-  pthread_rwlock_init (&rw_lock->impl, NULL);
+  rw_lock->impl = g_rw_lock_impl_new ();
 }
 
 /**
@@ -446,7 +519,7 @@ g_rw_lock_init (GRWLock *rw_lock)
 void
 g_rw_lock_clear (GRWLock *rw_lock)
 {
-  pthread_rwlock_destroy (&rw_lock->impl);
+  g_rw_lock_impl_free (rw_lock->impl);
 }
 
 /**
@@ -462,7 +535,7 @@ g_rw_lock_clear (GRWLock *rw_lock)
 void
 g_rw_lock_writer_lock (GRWLock *rw_lock)
 {
-  pthread_rwlock_wrlock (&rw_lock->impl);
+  pthread_rwlock_wrlock (g_rw_lock_get_impl (rw_lock));
 }
 
 /**
@@ -480,7 +553,7 @@ g_rw_lock_writer_lock (GRWLock *rw_lock)
 gboolean
 g_rw_lock_writer_trylock (GRWLock *rw_lock)
 {
-  if (pthread_rwlock_trywrlock (&rw_lock->impl) != 0)
+  if (pthread_rwlock_trywrlock (g_rw_lock_get_impl (rw_lock)) != 0)
     return FALSE;
 
   return TRUE;
@@ -500,7 +573,7 @@ g_rw_lock_writer_trylock (GRWLock *rw_lock)
 void
 g_rw_lock_writer_unlock (GRWLock *rw_lock)
 {
-  pthread_rwlock_unlock (&rw_lock->impl);
+  pthread_rwlock_unlock (g_rw_lock_get_impl (rw_lock));
 }
 
 /**
@@ -519,7 +592,7 @@ g_rw_lock_writer_unlock (GRWLock *rw_lock)
 void
 g_rw_lock_reader_lock (GRWLock *rw_lock)
 {
-  pthread_rwlock_rdlock (&rw_lock->impl);
+  pthread_rwlock_rdlock (g_rw_lock_get_impl (rw_lock));
 }
 
 /**
@@ -537,7 +610,7 @@ g_rw_lock_reader_lock (GRWLock *rw_lock)
 gboolean
 g_rw_lock_reader_trylock (GRWLock *rw_lock)
 {
-  if (pthread_rwlock_tryrdlock (&rw_lock->impl) != 0)
+  if (pthread_rwlock_tryrdlock (g_rw_lock_get_impl (rw_lock)) != 0)
     return FALSE;
 
   return TRUE;
@@ -557,11 +630,50 @@ g_rw_lock_reader_trylock (GRWLock *rw_lock)
 void
 g_rw_lock_reader_unlock (GRWLock *rw_lock)
 {
-  pthread_rwlock_unlock (&rw_lock->impl);
+  pthread_rwlock_unlock (g_rw_lock_get_impl (rw_lock));
 }
 
 /* {{{1 GCond */
 
+static pthread_cond_t *
+g_cond_impl_new (void)
+{
+  pthread_cond_t *cond;
+  gint status;
+
+  cond = malloc (sizeof (pthread_cond_t));
+  if G_UNLIKELY (cond == NULL)
+    g_thread_abort (errno, "malloc");
+
+  if G_UNLIKELY ((status = pthread_cond_init (cond, NULL)) != 0)
+    g_thread_abort (status, "pthread_cond_init");
+
+  return cond;
+}
+
+static void
+g_cond_impl_free (pthread_cond_t *cond)
+{
+  pthread_cond_destroy (cond);
+  free (cond);
+}
+
+static pthread_cond_t *
+g_cond_get_impl (GCond *cond)
+{
+  pthread_cond_t *impl = cond->impl;
+
+  if G_UNLIKELY (impl == NULL)
+    {
+      impl = g_cond_impl_new ();
+      if (!g_atomic_pointer_compare_and_exchange (&cond->impl, NULL, impl))
+        g_cond_impl_free (impl);
+      impl = cond->impl;
+    }
+
+  return impl;
+}
+
 /**
  * g_cond_init:
  * @cond: an uninitialized #GCond
@@ -585,10 +697,7 @@ g_rw_lock_reader_unlock (GRWLock *rw_lock)
 void
 g_cond_init (GCond *cond)
 {
-  gint status;
-
-  if G_UNLIKELY ((status = pthread_cond_init (&cond->impl, NULL)) != 0)
-    g_thread_abort (status, "pthread_cond_init");
+  cond->impl = g_cond_impl_new ();
 }
 
 /**
@@ -608,10 +717,7 @@ g_cond_init (GCond *cond)
 void
 g_cond_clear (GCond *cond)
 {
-  gint status;
-
-  if G_UNLIKELY ((status = pthread_cond_destroy (&cond->impl)) != 0)
-    g_thread_abort (status, "pthread_cond_destroy");
+  g_cond_impl_free (cond->impl);
 }
 
 /**
@@ -631,7 +737,7 @@ g_cond_wait (GCond  *cond,
 {
   gint status;
 
-  if G_UNLIKELY ((status = pthread_cond_wait (&cond->impl, &mutex->impl)) != 0)
+  if G_UNLIKELY ((status = pthread_cond_wait (g_cond_get_impl (cond), g_mutex_get_impl (mutex))) != 0)
     g_thread_abort (status, "pthread_cond_wait");
 }
 
@@ -652,7 +758,7 @@ g_cond_signal (GCond *cond)
 {
   gint status;
 
-  if G_UNLIKELY ((status = pthread_cond_signal (&cond->impl)) != 0)
+  if G_UNLIKELY ((status = pthread_cond_signal (g_cond_get_impl (cond))) != 0)
     g_thread_abort (status, "pthread_cond_signal");
 }
 
@@ -673,7 +779,7 @@ g_cond_broadcast (GCond *cond)
 {
   gint status;
 
-  if G_UNLIKELY ((status = pthread_cond_broadcast (&cond->impl)) != 0)
+  if G_UNLIKELY ((status = pthread_cond_broadcast (g_cond_get_impl (cond))) != 0)
     g_thread_abort (status, "pthread_cond_broadcast");
 }
 
@@ -714,7 +820,7 @@ g_cond_timed_wait (GCond    *cond,
   end_time.tv_sec = abs_time->tv_sec;
   end_time.tv_nsec = abs_time->tv_usec * 1000;
 
-  if ((status = pthread_cond_timedwait (&cond->impl, &mutex->impl, &end_time)) == 0)
+  if ((status = pthread_cond_timedwait (g_cond_get_impl (cond), g_mutex_get_impl (mutex), &end_time)) == 0)
     return TRUE;
 
   if G_UNLIKELY (status != ETIMEDOUT)
@@ -748,7 +854,7 @@ g_cond_timedwait (GCond  *cond,
   end_time.tv_sec = abs_time / 1000000;
   end_time.tv_nsec = (abs_time % 1000000) * 1000;
 
-  if ((status = pthread_cond_timedwait (&cond->impl, &mutex->impl, &end_time)) == 0)
+  if ((status = pthread_cond_timedwait (g_cond_get_impl (cond), g_mutex_get_impl (mutex), &end_time)) == 0)
     return TRUE;
 
   if G_UNLIKELY (status != ETIMEDOUT)
diff --git a/glib/gthread.h b/glib/gthread.h
index 93b78dd..4ef6bab 100644
--- a/glib/gthread.h
+++ b/glib/gthread.h
@@ -59,8 +59,6 @@ typedef struct _GCond           GCond;
 typedef struct _GPrivate        GPrivate;
 typedef struct _GStaticPrivate  GStaticPrivate;
 
-#ifdef G_OS_WIN32
-
 #define G_MUTEX_INIT { NULL }
 struct _GMutex
 {
@@ -78,33 +76,6 @@ struct _GCond
 {
   gpointer impl;
 };
-#else
-
-#include <pthread.h>
-
-#ifdef PTHREAD_ADAPTIVE_MUTEX_INITIALIZER_NP
-#define G_MUTEX_INIT { PTHREAD_ADAPTIVE_MUTEX_INITIALIZER_NP }
-#else
-#define G_MUTEX_INIT { PTHREAD_MUTEX_INITIALIZER }
-#endif
-struct _GMutex
-{
-  pthread_mutex_t impl;
-};
-
-#define G_RW_LOCK_INIT { PTHREAD_RWLOCK_INITIALIZER }
-struct _GRWLock
-{
-  pthread_rwlock_t impl;
-};
-
-#define G_COND_INIT { PTHREAD_COND_INITIALIZER }
-struct _GCond
-{
-  pthread_cond_t impl;
-};
-
-#endif
 
 #define G_REC_MUTEX_INIT { NULL }
 struct _GRecMutex



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]