diff options
| author | Joel Sing <joel@sing.id.au> | 2020-09-20 02:09:35 +1000 |
|---|---|---|
| committer | Joel Sing <joel@sing.id.au> | 2020-09-20 02:09:35 +1000 |
| commit | 17c88164016df821df2dff4b2b1291291ec4f28a (patch) | |
| tree | 343d82db6acdcb24c135e41731064ec1bf420e13 | |
| parent | 5bedaf92260fe08ac4df4e513471bfa970167253 (diff) | |
| download | portable-17c88164016df821df2dff4b2b1291291ec4f28a.tar.gz portable-17c88164016df821df2dff4b2b1291291ec4f28a.tar.bz2 portable-17c88164016df821df2dff4b2b1291291ec4f28a.zip | |
Make pthread_mutex static initialisation work on Windows.
This takes the dynamic initialisation code added to CRYPTO_lock() in e5081719
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).
| -rwxr-xr-x[-rw-r--r--] | include/compat/pthread.h | 28 |
1 files changed, 23 insertions, 5 deletions
diff --git a/include/compat/pthread.h b/include/compat/pthread.h index b2a42a6..1527d3c 100644..100755 --- a/include/compat/pthread.h +++ b/include/compat/pthread.h | |||
| @@ -8,6 +8,8 @@ | |||
| 8 | 8 | ||
| 9 | #ifdef _WIN32 | 9 | #ifdef _WIN32 |
| 10 | 10 | ||
| 11 | #include <malloc.h> | ||
| 12 | #include <stdlib.h> | ||
| 11 | #include <windows.h> | 13 | #include <windows.h> |
| 12 | 14 | ||
| 13 | /* | 15 | /* |
| @@ -18,7 +20,7 @@ | |||
| 18 | /* | 20 | /* |
| 19 | * Static mutex initialization values. | 21 | * Static mutex initialization values. |
| 20 | */ | 22 | */ |
| 21 | #define PTHREAD_MUTEX_INITIALIZER { 0, 0, 0, 0, 0, 0 } | 23 | #define PTHREAD_MUTEX_INITIALIZER { .lock = NULL } |
| 22 | 24 | ||
| 23 | /* | 25 | /* |
| 24 | * Once definitions. | 26 | * Once definitions. |
| @@ -60,27 +62,43 @@ pthread_equal(pthread_t t1, pthread_t t2) | |||
| 60 | return t1 == t2; | 62 | return t1 == t2; |
| 61 | } | 63 | } |
| 62 | 64 | ||
| 63 | typedef CRITICAL_SECTION pthread_mutex_t; | 65 | struct pthread_mutex { |
| 66 | volatile LPCRITICAL_SECTION lock; | ||
| 67 | }; | ||
| 68 | typedef struct pthread_mutex pthread_mutex_t; | ||
| 64 | typedef void pthread_mutexattr_t; | 69 | typedef void pthread_mutexattr_t; |
| 65 | 70 | ||
| 66 | static inline int | 71 | static inline int |
| 67 | pthread_mutex_init(pthread_mutex_t *mutex, const pthread_mutexattr_t *attr) | 72 | pthread_mutex_init(pthread_mutex_t *mutex, const pthread_mutexattr_t *attr) |
| 68 | { | 73 | { |
| 69 | InitializeCriticalSection(mutex); | 74 | if ((mutex->lock = malloc(sizeof(CRITICAL_SECTION))) == NULL) |
| 75 | exit(ENOMEM); | ||
| 76 | InitializeCriticalSection(mutex->lock); | ||
| 70 | return 0; | 77 | return 0; |
| 71 | } | 78 | } |
| 72 | 79 | ||
| 73 | static inline int | 80 | static inline int |
| 74 | pthread_mutex_lock(pthread_mutex_t *mutex) | 81 | pthread_mutex_lock(pthread_mutex_t *mutex) |
| 75 | { | 82 | { |
| 76 | EnterCriticalSection(mutex); | 83 | if (mutex->lock == NULL) { |
| 84 | LPCRITICAL_SECTION lcs; | ||
| 85 | |||
| 86 | if ((lcs = malloc(sizeof(CRITICAL_SECTION))) == NULL) | ||
| 87 | exit(ENOMEM); | ||
| 88 | InitializeCriticalSection(lcs); | ||
| 89 | if (InterlockedCompareExchangePointer((PVOID*)&mutex->lock, (PVOID)lcs, NULL) != NULL) { | ||
| 90 | DeleteCriticalSection(lcs); | ||
| 91 | free(lcs); | ||
| 92 | } | ||
| 93 | } | ||
| 94 | EnterCriticalSection(mutex->lock); | ||
| 77 | return 0; | 95 | return 0; |
| 78 | } | 96 | } |
| 79 | 97 | ||
| 80 | static inline int | 98 | static inline int |
| 81 | pthread_mutex_unlock(pthread_mutex_t *mutex) | 99 | pthread_mutex_unlock(pthread_mutex_t *mutex) |
| 82 | { | 100 | { |
| 83 | LeaveCriticalSection(mutex); | 101 | LeaveCriticalSection(mutex->lock); |
| 84 | return 0; | 102 | return 0; |
| 85 | } | 103 | } |
| 86 | 104 | ||
