Skip to content

Commit

Permalink
Make pthread_mutex static initialisation work on Windows.
Browse files Browse the repository at this point in the history
This takes the dynamic initialisation code added to CRYPTO_lock() in e508171
and applies it to the Window's pthread_mutex implementation. This allows for
PTHREAD_MUTEX_INITIALIZER to be used on Windows.

bcook has agreed to place this code in the public domain (as per the rest of
the code in pthread.h).
  • Loading branch information
4a6f656c committed Sep 19, 2020
1 parent 5bedaf9 commit 17c8816
Showing 1 changed file with 23 additions and 5 deletions.
28 changes: 23 additions & 5 deletions include/compat/pthread.h
100644 → 100755
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@

#ifdef _WIN32

#include <malloc.h>
#include <stdlib.h>
#include <windows.h>

/*
Expand All @@ -18,7 +20,7 @@
/*
* Static mutex initialization values.
*/
#define PTHREAD_MUTEX_INITIALIZER { 0, 0, 0, 0, 0, 0 }
#define PTHREAD_MUTEX_INITIALIZER { .lock = NULL }

/*
* Once definitions.
Expand Down Expand Up @@ -60,27 +62,43 @@ pthread_equal(pthread_t t1, pthread_t t2)
return t1 == t2;
}

typedef CRITICAL_SECTION pthread_mutex_t;
struct pthread_mutex {
volatile LPCRITICAL_SECTION lock;
};
typedef struct pthread_mutex pthread_mutex_t;
typedef void pthread_mutexattr_t;

static inline int
pthread_mutex_init(pthread_mutex_t *mutex, const pthread_mutexattr_t *attr)
{
InitializeCriticalSection(mutex);
if ((mutex->lock = malloc(sizeof(CRITICAL_SECTION))) == NULL)
exit(ENOMEM);
InitializeCriticalSection(mutex->lock);
return 0;
}

static inline int
pthread_mutex_lock(pthread_mutex_t *mutex)
{
EnterCriticalSection(mutex);
if (mutex->lock == NULL) {
LPCRITICAL_SECTION lcs;

if ((lcs = malloc(sizeof(CRITICAL_SECTION))) == NULL)
exit(ENOMEM);
InitializeCriticalSection(lcs);
if (InterlockedCompareExchangePointer((PVOID*)&mutex->lock, (PVOID)lcs, NULL) != NULL) {
DeleteCriticalSection(lcs);
free(lcs);
}
}
EnterCriticalSection(mutex->lock);
return 0;
}

static inline int
pthread_mutex_unlock(pthread_mutex_t *mutex)
{
LeaveCriticalSection(mutex);
LeaveCriticalSection(mutex->lock);
return 0;
}

Expand Down

0 comments on commit 17c8816

Please sign in to comment.