8
8
#include "pthread.h"
9
9
#include "../global.h"
10
10
11
- int pthread_create (
12
- pthread_t * GIT_RESTRICT thread ,
11
+ #define CLEAN_THREAD_EXIT 0x6F012842
12
+
13
+ /* The thread procedure stub used to invoke the caller's procedure
14
+ * and capture the return value for later collection. Windows will
15
+ * only hold a DWORD, but we need to be able to store an entire
16
+ * void pointer. This requires the indirection. */
17
+ static DWORD WINAPI git_win32__threadproc (LPVOID lpParameter )
18
+ {
19
+ git_win32_thread * thread = lpParameter ;
20
+
21
+ thread -> result = thread -> proc (thread -> param );
22
+
23
+ return CLEAN_THREAD_EXIT ;
24
+ }
25
+
26
+ int git_win32__thread_create (
27
+ git_win32_thread * GIT_RESTRICT thread ,
13
28
const pthread_attr_t * GIT_RESTRICT attr ,
14
29
void * (* start_routine )(void * ),
15
30
void * GIT_RESTRICT arg )
16
31
{
17
32
GIT_UNUSED (attr );
18
- * thread = CreateThread (
19
- NULL , 0 , (LPTHREAD_START_ROUTINE )start_routine , arg , 0 , NULL );
20
- return * thread ? 0 : -1 ;
33
+
34
+ thread -> result = NULL ;
35
+ thread -> param = arg ;
36
+ thread -> proc = start_routine ;
37
+ thread -> thread = CreateThread (
38
+ NULL , 0 , git_win32__threadproc , thread , 0 , NULL );
39
+
40
+ return thread -> thread ? 0 : -1 ;
21
41
}
22
42
23
- int pthread_join (pthread_t thread , void * * value_ptr )
43
+ int git_win32__thread_join (
44
+ git_win32_thread * thread ,
45
+ void * * value_ptr )
24
46
{
25
- DWORD ret = WaitForSingleObject (thread , INFINITE );
47
+ DWORD exit ;
48
+
49
+ if (WaitForSingleObject (thread -> thread , INFINITE ) != WAIT_OBJECT_0 )
50
+ return -1 ;
51
+
52
+ if (!GetExitCodeThread (thread -> thread , & exit )) {
53
+ CloseHandle (thread -> thread );
54
+ return -1 ;
55
+ }
26
56
27
- if (ret == WAIT_OBJECT_0 ) {
28
- if (value_ptr != NULL ) {
29
- * value_ptr = NULL ;
30
- GetExitCodeThread (thread , (void * )value_ptr );
31
- }
32
- CloseHandle (thread );
33
- return 0 ;
57
+ /* Check for the thread having exited uncleanly. If exit was unclean,
58
+ * then we don't have a return value to give back to the caller. */
59
+ if (exit != CLEAN_THREAD_EXIT ) {
60
+ assert (false);
61
+ thread -> result = NULL ;
34
62
}
35
63
36
- return -1 ;
64
+ if (value_ptr )
65
+ * value_ptr = thread -> result ;
66
+
67
+ CloseHandle (thread -> thread );
68
+ return 0 ;
37
69
}
38
70
39
71
int pthread_mutex_init (
@@ -144,9 +176,6 @@ int pthread_num_processors_np(void)
144
176
return n ? n : 1 ;
145
177
}
146
178
147
-
148
- static HINSTANCE win32_kernel32_dll ;
149
-
150
179
typedef void (WINAPI * win32_srwlock_fn )(GIT_SRWLOCK * );
151
180
152
181
static win32_srwlock_fn win32_srwlock_initialize ;
@@ -159,7 +188,7 @@ int pthread_rwlock_init(
159
188
pthread_rwlock_t * GIT_RESTRICT lock ,
160
189
const pthread_rwlockattr_t * GIT_RESTRICT attr )
161
190
{
162
- ( void ) attr ;
191
+ GIT_UNUSED ( attr ) ;
163
192
164
193
if (win32_srwlock_initialize )
165
194
win32_srwlock_initialize (& lock -> native .srwl );
@@ -217,38 +246,22 @@ int pthread_rwlock_destroy(pthread_rwlock_t *lock)
217
246
return 0 ;
218
247
}
219
248
220
-
221
- static void win32_pthread_shutdown (void )
222
- {
223
- if (win32_kernel32_dll ) {
224
- FreeLibrary (win32_kernel32_dll );
225
- win32_kernel32_dll = NULL ;
226
- }
227
- }
228
-
229
249
int win32_pthread_initialize (void )
230
250
{
231
- if (win32_kernel32_dll )
232
- return 0 ;
233
-
234
- win32_kernel32_dll = LoadLibrary ("Kernel32.dll" );
235
- if (!win32_kernel32_dll ) {
236
- giterr_set (GITERR_OS , "Could not load Kernel32.dll!" );
237
- return -1 ;
251
+ HMODULE hModule = GetModuleHandleW (L"kernel32" );
252
+
253
+ if (hModule ) {
254
+ win32_srwlock_initialize = (win32_srwlock_fn )
255
+ GetProcAddress (hModule , "InitializeSRWLock" );
256
+ win32_srwlock_acquire_shared = (win32_srwlock_fn )
257
+ GetProcAddress (hModule , "AcquireSRWLockShared" );
258
+ win32_srwlock_release_shared = (win32_srwlock_fn )
259
+ GetProcAddress (hModule , "ReleaseSRWLockShared" );
260
+ win32_srwlock_acquire_exclusive = (win32_srwlock_fn )
261
+ GetProcAddress (hModule , "AcquireSRWLockExclusive" );
262
+ win32_srwlock_release_exclusive = (win32_srwlock_fn )
263
+ GetProcAddress (hModule , "ReleaseSRWLockExclusive" );
238
264
}
239
265
240
- win32_srwlock_initialize = (win32_srwlock_fn )
241
- GetProcAddress (win32_kernel32_dll , "InitializeSRWLock" );
242
- win32_srwlock_acquire_shared = (win32_srwlock_fn )
243
- GetProcAddress (win32_kernel32_dll , "AcquireSRWLockShared" );
244
- win32_srwlock_release_shared = (win32_srwlock_fn )
245
- GetProcAddress (win32_kernel32_dll , "ReleaseSRWLockShared" );
246
- win32_srwlock_acquire_exclusive = (win32_srwlock_fn )
247
- GetProcAddress (win32_kernel32_dll , "AcquireSRWLockExclusive" );
248
- win32_srwlock_release_exclusive = (win32_srwlock_fn )
249
- GetProcAddress (win32_kernel32_dll , "ReleaseSRWLockExclusive" );
250
-
251
- git__on_shutdown (win32_pthread_shutdown );
252
-
253
266
return 0 ;
254
267
}
0 commit comments