Signed-off-by: Erik Faye-Lund <kusmabite@xxxxxxxxx> --- Every now and then, someone suggest using PTHREAD_MUTEX_INITIALIZER, but some times gets show down by our lack of support on Windows. I'm working on something myself that could benefit from this, so I gave it a stab. The result looks promising to me, but I haven't really debugged it yet. But is there a fundamental reason why we haven't done something like this before? :) compat/win32/pthread.c | 28 +++++++++++++++++++++++++--- compat/win32/pthread.h | 18 ++++++++++++------ 2 files changed, 37 insertions(+), 9 deletions(-) diff --git a/compat/win32/pthread.c b/compat/win32/pthread.c index 010e875..14f91d5 100644 --- a/compat/win32/pthread.c +++ b/compat/win32/pthread.c @@ -57,6 +57,28 @@ pthread_t pthread_self(void) return t; } +int pthread_mutex_init(pthread_mutex_t *mutex, const pthread_mutexattr_t *attr) +{ + InitializeCriticalSection(&mutex->cs); + mutex->autoinit = 0; + return 0; +} + +int pthread_mutex_lock(pthread_mutex_t *mutex) +{ + if (mutex->autoinit) { + if (InterlockedCompareExchange(&mutex->autoinit, -1, 1) != -1) { + pthread_mutex_init(mutex, NULL); + mutex->autoinit = 0; + } else + while (mutex->autoinit != 0) + ; /* wait for other thread */ + } + + EnterCriticalSection(&mutex->cs); + return 0; +} + int pthread_cond_init(pthread_cond_t *cond, const void *unused) { cond->waiters = 0; @@ -85,7 +107,7 @@ int pthread_cond_destroy(pthread_cond_t *cond) return 0; } -int pthread_cond_wait(pthread_cond_t *cond, CRITICAL_SECTION *mutex) +int pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex) { int last_waiter; @@ -99,7 +121,7 @@ int pthread_cond_wait(pthread_cond_t *cond, CRITICAL_SECTION *mutex) * waiters count above, so there's no problem with * leaving mutex unlocked before we wait on semaphore. */ - LeaveCriticalSection(mutex); + LeaveCriticalSection(&mutex->cs); /* let's wait - ignore return value */ WaitForSingleObject(cond->sema, INFINITE); @@ -133,7 +155,7 @@ int pthread_cond_wait(pthread_cond_t *cond, CRITICAL_SECTION *mutex) */ } /* lock external mutex again */ - EnterCriticalSection(mutex); + EnterCriticalSection(&mutex->cs); return 0; } diff --git a/compat/win32/pthread.h b/compat/win32/pthread.h index 2e20548..647e6d4 100644 --- a/compat/win32/pthread.h +++ b/compat/win32/pthread.h @@ -16,14 +16,20 @@ /* * Defines that adapt Windows API threads to pthreads API */ -#define pthread_mutex_t CRITICAL_SECTION +typedef struct { + CRITICAL_SECTION cs; + LONG volatile autoinit; +} pthread_mutex_t; -#define pthread_mutex_init(a,b) (InitializeCriticalSection((a)), 0) -#define pthread_mutex_destroy(a) DeleteCriticalSection((a)) -#define pthread_mutex_lock EnterCriticalSection -#define pthread_mutex_unlock LeaveCriticalSection +#define PTHREAD_MUTEX_INITIALIZER { { 0 }, 1 } typedef int pthread_mutexattr_t; + +int pthread_mutex_init(pthread_mutex_t *, const pthread_mutexattr_t *); +#define pthread_mutex_destroy(a) DeleteCriticalSection(&(a)->cs) +int pthread_mutex_lock(pthread_mutex_t *); +#define pthread_mutex_unlock(a) LeaveCriticalSection(&(a)->cs) + #define pthread_mutexattr_init(a) (*(a) = 0) #define pthread_mutexattr_destroy(a) do {} while (0) #define pthread_mutexattr_settype(a, t) 0 @@ -47,7 +53,7 @@ typedef struct { extern int pthread_cond_init(pthread_cond_t *cond, const void *unused); extern int pthread_cond_destroy(pthread_cond_t *cond); -extern int pthread_cond_wait(pthread_cond_t *cond, CRITICAL_SECTION *mutex); +extern int pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex); extern int pthread_cond_signal(pthread_cond_t *cond); extern int pthread_cond_broadcast(pthread_cond_t *cond); -- 1.7.7.msysgit.1.1.g7b316 -- To unsubscribe from this list: send the line "unsubscribe git" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html