88#include "pthread.h"
99#include "../global.h"
1010
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 -> value = thread -> proc (thread -> value );
22+
23+ return CLEAN_THREAD_EXIT ;
24+ }
25+
26+ int git_win32__thread_create (
27+ git_win32_thread * GIT_RESTRICT thread ,
1328 const pthread_attr_t * GIT_RESTRICT attr ,
1429 void * (* start_routine )(void * ),
1530 void * GIT_RESTRICT arg )
1631{
1732 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 -> value = arg ;
35+ thread -> proc = start_routine ;
36+ thread -> thread = CreateThread (
37+ NULL , 0 , git_win32__threadproc , thread , 0 , NULL );
38+
39+ return thread -> thread ? 0 : -1 ;
2140}
2241
23- int pthread_join (pthread_t thread , void * * value_ptr )
42+ int git_win32__thread_join (
43+ git_win32_thread * thread ,
44+ void * * value_ptr )
2445{
25- DWORD ret = WaitForSingleObject (thread , INFINITE );
46+ DWORD exit ;
47+
48+ if (WaitForSingleObject (thread -> thread , INFINITE ) != WAIT_OBJECT_0 )
49+ return -1 ;
50+
51+ if (!GetExitCodeThread (thread -> thread , & exit )) {
52+ CloseHandle (thread -> thread );
53+ return -1 ;
54+ }
2655
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 ;
56+ /* Check for the thread having exited uncleanly. If exit was unclean,
57+ * then we don't have a return value to give back to the caller. */
58+ if (exit != CLEAN_THREAD_EXIT ) {
59+ assert (false);
60+ thread -> value = NULL ;
3461 }
3562
36- return -1 ;
63+ if (value_ptr )
64+ * value_ptr = thread -> value ;
65+
66+ CloseHandle (thread -> thread );
67+ return 0 ;
3768}
3869
3970int pthread_mutex_init (
@@ -144,9 +175,6 @@ int pthread_num_processors_np(void)
144175 return n ? n : 1 ;
145176}
146177
147-
148- static HINSTANCE win32_kernel32_dll ;
149-
150178typedef void (WINAPI * win32_srwlock_fn )(GIT_SRWLOCK * );
151179
152180static win32_srwlock_fn win32_srwlock_initialize ;
@@ -159,7 +187,7 @@ int pthread_rwlock_init(
159187 pthread_rwlock_t * GIT_RESTRICT lock ,
160188 const pthread_rwlockattr_t * GIT_RESTRICT attr )
161189{
162- ( void ) attr ;
190+ GIT_UNUSED ( attr ) ;
163191
164192 if (win32_srwlock_initialize )
165193 win32_srwlock_initialize (& lock -> native .srwl );
@@ -217,38 +245,22 @@ int pthread_rwlock_destroy(pthread_rwlock_t *lock)
217245 return 0 ;
218246}
219247
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-
229248int win32_pthread_initialize (void )
230249{
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 ;
250+ HMODULE hModule = GetModuleHandleW (L"kernel32" );
251+
252+ if (hModule ) {
253+ win32_srwlock_initialize = (win32_srwlock_fn )
254+ GetProcAddress (hModule , "InitializeSRWLock" );
255+ win32_srwlock_acquire_shared = (win32_srwlock_fn )
256+ GetProcAddress (hModule , "AcquireSRWLockShared" );
257+ win32_srwlock_release_shared = (win32_srwlock_fn )
258+ GetProcAddress (hModule , "ReleaseSRWLockShared" );
259+ win32_srwlock_acquire_exclusive = (win32_srwlock_fn )
260+ GetProcAddress (hModule , "AcquireSRWLockExclusive" );
261+ win32_srwlock_release_exclusive = (win32_srwlock_fn )
262+ GetProcAddress (hModule , "ReleaseSRWLockExclusive" );
238263 }
239264
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-
253265 return 0 ;
254266}
0 commit comments