mirror of
https://gitlab.gnome.org/GNOME/glib.git
synced 2025-05-03 04:26:52 +02:00
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
This commit is contained in:
parent
151756631d
commit
e081eadda5
@ -78,6 +78,58 @@ g_thread_abort (gint status,
|
|||||||
|
|
||||||
/* {{{1 GMutex */
|
/* {{{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:
|
* g_mutex_init:
|
||||||
* @mutex: an uninitialized #GMutex
|
* @mutex: an uninitialized #GMutex
|
||||||
@ -113,21 +165,7 @@ g_thread_abort (gint status,
|
|||||||
void
|
void
|
||||||
g_mutex_init (GMutex *mutex)
|
g_mutex_init (GMutex *mutex)
|
||||||
{
|
{
|
||||||
gint status;
|
mutex->impl = g_mutex_impl_new ();
|
||||||
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
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -147,10 +185,7 @@ g_mutex_init (GMutex *mutex)
|
|||||||
void
|
void
|
||||||
g_mutex_clear (GMutex *mutex)
|
g_mutex_clear (GMutex *mutex)
|
||||||
{
|
{
|
||||||
gint status;
|
g_mutex_impl_free (mutex->impl);
|
||||||
|
|
||||||
if G_UNLIKELY ((status = pthread_mutex_destroy (&mutex->impl)) != 0)
|
|
||||||
g_thread_abort (status, "pthread_mutex_destroy");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -174,7 +209,7 @@ g_mutex_lock (GMutex *mutex)
|
|||||||
{
|
{
|
||||||
gint status;
|
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");
|
g_thread_abort (status, "pthread_mutex_lock");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -196,7 +231,7 @@ g_mutex_unlock (GMutex *mutex)
|
|||||||
{
|
{
|
||||||
gint status;
|
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");
|
g_thread_abort (status, "pthread_mutex_lock");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -223,7 +258,7 @@ g_mutex_trylock (GMutex *mutex)
|
|||||||
{
|
{
|
||||||
gint status;
|
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;
|
return TRUE;
|
||||||
|
|
||||||
if G_UNLIKELY (status != EBUSY)
|
if G_UNLIKELY (status != EBUSY)
|
||||||
@ -261,7 +296,7 @@ g_rec_mutex_get_impl (GRecMutex *rec_mutex)
|
|||||||
{
|
{
|
||||||
pthread_mutex_t *impl = rec_mutex->impl;
|
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 ();
|
impl = g_rec_mutex_impl_new ();
|
||||||
if (!g_atomic_pointer_compare_and_exchange (&rec_mutex->impl, NULL, impl))
|
if (!g_atomic_pointer_compare_and_exchange (&rec_mutex->impl, NULL, impl))
|
||||||
@ -330,8 +365,7 @@ g_rec_mutex_init (GRecMutex *rec_mutex)
|
|||||||
void
|
void
|
||||||
g_rec_mutex_clear (GRecMutex *rec_mutex)
|
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 */
|
/* {{{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:
|
* g_rw_lock_init:
|
||||||
* @rw_lock: an uninitialized #GRWLock
|
* @rw_lock: an uninitialized #GRWLock
|
||||||
@ -429,7 +502,7 @@ g_rec_mutex_trylock (GRecMutex *rec_mutex)
|
|||||||
void
|
void
|
||||||
g_rw_lock_init (GRWLock *rw_lock)
|
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
|
void
|
||||||
g_rw_lock_clear (GRWLock *rw_lock)
|
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
|
void
|
||||||
g_rw_lock_writer_lock (GRWLock *rw_lock)
|
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
|
gboolean
|
||||||
g_rw_lock_writer_trylock (GRWLock *rw_lock)
|
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 FALSE;
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
@ -500,7 +573,7 @@ g_rw_lock_writer_trylock (GRWLock *rw_lock)
|
|||||||
void
|
void
|
||||||
g_rw_lock_writer_unlock (GRWLock *rw_lock)
|
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
|
void
|
||||||
g_rw_lock_reader_lock (GRWLock *rw_lock)
|
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
|
gboolean
|
||||||
g_rw_lock_reader_trylock (GRWLock *rw_lock)
|
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 FALSE;
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
@ -557,11 +630,50 @@ g_rw_lock_reader_trylock (GRWLock *rw_lock)
|
|||||||
void
|
void
|
||||||
g_rw_lock_reader_unlock (GRWLock *rw_lock)
|
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 */
|
/* {{{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:
|
* g_cond_init:
|
||||||
* @cond: an uninitialized #GCond
|
* @cond: an uninitialized #GCond
|
||||||
@ -585,10 +697,7 @@ g_rw_lock_reader_unlock (GRWLock *rw_lock)
|
|||||||
void
|
void
|
||||||
g_cond_init (GCond *cond)
|
g_cond_init (GCond *cond)
|
||||||
{
|
{
|
||||||
gint status;
|
cond->impl = g_cond_impl_new ();
|
||||||
|
|
||||||
if G_UNLIKELY ((status = pthread_cond_init (&cond->impl, NULL)) != 0)
|
|
||||||
g_thread_abort (status, "pthread_cond_init");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -608,10 +717,7 @@ g_cond_init (GCond *cond)
|
|||||||
void
|
void
|
||||||
g_cond_clear (GCond *cond)
|
g_cond_clear (GCond *cond)
|
||||||
{
|
{
|
||||||
gint status;
|
g_cond_impl_free (cond->impl);
|
||||||
|
|
||||||
if G_UNLIKELY ((status = pthread_cond_destroy (&cond->impl)) != 0)
|
|
||||||
g_thread_abort (status, "pthread_cond_destroy");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -631,7 +737,7 @@ g_cond_wait (GCond *cond,
|
|||||||
{
|
{
|
||||||
gint status;
|
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");
|
g_thread_abort (status, "pthread_cond_wait");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -652,7 +758,7 @@ g_cond_signal (GCond *cond)
|
|||||||
{
|
{
|
||||||
gint status;
|
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");
|
g_thread_abort (status, "pthread_cond_signal");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -673,7 +779,7 @@ g_cond_broadcast (GCond *cond)
|
|||||||
{
|
{
|
||||||
gint status;
|
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");
|
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_sec = abs_time->tv_sec;
|
||||||
end_time.tv_nsec = abs_time->tv_usec * 1000;
|
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;
|
return TRUE;
|
||||||
|
|
||||||
if G_UNLIKELY (status != ETIMEDOUT)
|
if G_UNLIKELY (status != ETIMEDOUT)
|
||||||
@ -748,7 +854,7 @@ g_cond_timedwait (GCond *cond,
|
|||||||
end_time.tv_sec = abs_time / 1000000;
|
end_time.tv_sec = abs_time / 1000000;
|
||||||
end_time.tv_nsec = (abs_time % 1000000) * 1000;
|
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;
|
return TRUE;
|
||||||
|
|
||||||
if G_UNLIKELY (status != ETIMEDOUT)
|
if G_UNLIKELY (status != ETIMEDOUT)
|
||||||
|
@ -59,8 +59,6 @@ typedef struct _GCond GCond;
|
|||||||
typedef struct _GPrivate GPrivate;
|
typedef struct _GPrivate GPrivate;
|
||||||
typedef struct _GStaticPrivate GStaticPrivate;
|
typedef struct _GStaticPrivate GStaticPrivate;
|
||||||
|
|
||||||
#ifdef G_OS_WIN32
|
|
||||||
|
|
||||||
#define G_MUTEX_INIT { NULL }
|
#define G_MUTEX_INIT { NULL }
|
||||||
struct _GMutex
|
struct _GMutex
|
||||||
{
|
{
|
||||||
@ -78,33 +76,6 @@ struct _GCond
|
|||||||
{
|
{
|
||||||
gpointer impl;
|
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 }
|
#define G_REC_MUTEX_INIT { NULL }
|
||||||
struct _GRecMutex
|
struct _GRecMutex
|
||||||
|
Loading…
x
Reference in New Issue
Block a user