aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJoel Sing <joel@sing.id.au>2020-09-20 02:09:35 +1000
committerJoel Sing <joel@sing.id.au>2020-09-20 02:09:35 +1000
commit17c88164016df821df2dff4b2b1291291ec4f28a (patch)
tree343d82db6acdcb24c135e41731064ec1bf420e13
parent5bedaf92260fe08ac4df4e513471bfa970167253 (diff)
downloadportable-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.h28
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
63typedef CRITICAL_SECTION pthread_mutex_t; 65struct pthread_mutex {
66 volatile LPCRITICAL_SECTION lock;
67};
68typedef struct pthread_mutex pthread_mutex_t;
64typedef void pthread_mutexattr_t; 69typedef void pthread_mutexattr_t;
65 70
66static inline int 71static inline int
67pthread_mutex_init(pthread_mutex_t *mutex, const pthread_mutexattr_t *attr) 72pthread_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
73static inline int 80static inline int
74pthread_mutex_lock(pthread_mutex_t *mutex) 81pthread_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
80static inline int 98static inline int
81pthread_mutex_unlock(pthread_mutex_t *mutex) 99pthread_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