Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 9560203

Browse files
author
Vicent Marti
committed
Merge pull request libgit2#2409 from phkelley/win32_thread_fixes
Win32: Fix object::cache::threadmania test on x64
2 parents df19219 + 1b4e29b commit 9560203

File tree

8 files changed

+107
-71
lines changed

8 files changed

+107
-71
lines changed

src/global.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,7 @@ static void git__shutdown(void)
7878
static DWORD _tls_index;
7979
static volatile LONG _mutex = 0;
8080

81-
static int synchronized_threads_init()
81+
static int synchronized_threads_init(void)
8282
{
8383
int error;
8484

@@ -112,7 +112,7 @@ int git_threads_init(void)
112112
return error;
113113
}
114114

115-
static void synchronized_threads_shutdown()
115+
static void synchronized_threads_shutdown(void)
116116
{
117117
/* Shut down any subsystems that have global state */
118118
git__shutdown();

src/pack-objects.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1209,7 +1209,7 @@ static int ll_find_deltas(git_packbuilder *pb, git_pobject **list,
12091209
git_mutex_unlock(&target->mutex);
12101210

12111211
if (!sub_size) {
1212-
git_thread_join(target->thread, NULL);
1212+
git_thread_join(&target->thread, NULL);
12131213
git_cond_free(&target->cond);
12141214
git_mutex_free(&target->mutex);
12151215
active_threads--;

src/thread-utils.h

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -40,12 +40,18 @@ typedef git_atomic git_atomic_ssize;
4040

4141
#ifdef GIT_THREADS
4242

43-
#define git_thread pthread_t
44-
#define git_thread_create(thread, attr, start_routine, arg) \
45-
pthread_create(thread, attr, start_routine, arg)
46-
#define git_thread_kill(thread) pthread_cancel(thread)
47-
#define git_thread_exit(status) pthread_exit(status)
48-
#define git_thread_join(id, status) pthread_join(id, status)
43+
#if !defined(GIT_WIN32)
44+
45+
typedef struct {
46+
pthread_t thread;
47+
} git_thread;
48+
49+
#define git_thread_create(git_thread_ptr, attr, start_routine, arg) \
50+
pthread_create(&(git_thread_ptr)->thread, attr, start_routine, arg)
51+
#define git_thread_join(git_thread_ptr, status) \
52+
pthread_join((git_thread_ptr)->thread, status)
53+
54+
#endif
4955

5056
#if defined(GIT_WIN32)
5157
#define git_thread_yield() Sleep(0)
@@ -179,8 +185,6 @@ GIT_INLINE(int64_t) git_atomic64_add(git_atomic64 *a, int64_t addend)
179185

180186
#define git_thread unsigned int
181187
#define git_thread_create(thread, attr, start_routine, arg) 0
182-
#define git_thread_kill(thread) (void)0
183-
#define git_thread_exit(status) (void)0
184188
#define git_thread_join(id, status) (void)0
185189
#define git_thread_yield() (void)0
186190

src/win32/pthread.c

Lines changed: 61 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -8,32 +8,64 @@
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->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,
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->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;
2141
}
2242

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)
2446
{
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+
}
2656

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;
3462
}
3563

36-
return -1;
64+
if (value_ptr)
65+
*value_ptr = thread->result;
66+
67+
CloseHandle(thread->thread);
68+
return 0;
3769
}
3870

3971
int pthread_mutex_init(
@@ -144,9 +176,6 @@ int pthread_num_processors_np(void)
144176
return n ? n : 1;
145177
}
146178

147-
148-
static HINSTANCE win32_kernel32_dll;
149-
150179
typedef void (WINAPI *win32_srwlock_fn)(GIT_SRWLOCK *);
151180

152181
static win32_srwlock_fn win32_srwlock_initialize;
@@ -159,7 +188,7 @@ int pthread_rwlock_init(
159188
pthread_rwlock_t *GIT_RESTRICT lock,
160189
const pthread_rwlockattr_t *GIT_RESTRICT attr)
161190
{
162-
(void)attr;
191+
GIT_UNUSED(attr);
163192

164193
if (win32_srwlock_initialize)
165194
win32_srwlock_initialize(&lock->native.srwl);
@@ -217,38 +246,22 @@ int pthread_rwlock_destroy(pthread_rwlock_t *lock)
217246
return 0;
218247
}
219248

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-
229249
int win32_pthread_initialize(void)
230250
{
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");
238264
}
239265

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-
253266
return 0;
254267
}

src/win32/pthread.h

Lines changed: 26 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -16,13 +16,19 @@
1616
# define GIT_RESTRICT __restrict__
1717
#endif
1818

19+
typedef struct {
20+
HANDLE thread;
21+
void *(*proc)(void *);
22+
void *param;
23+
void *result;
24+
} git_win32_thread;
25+
1926
typedef int pthread_mutexattr_t;
2027
typedef int pthread_condattr_t;
2128
typedef int pthread_attr_t;
2229
typedef int pthread_rwlockattr_t;
2330

2431
typedef CRITICAL_SECTION pthread_mutex_t;
25-
typedef HANDLE pthread_t;
2632
typedef HANDLE pthread_cond_t;
2733

2834
typedef struct { void *Ptr; } GIT_SRWLOCK;
@@ -36,13 +42,26 @@ typedef struct {
3642

3743
#define PTHREAD_MUTEX_INITIALIZER {(void*)-1}
3844

39-
int pthread_create(
40-
pthread_t *GIT_RESTRICT thread,
41-
const pthread_attr_t *GIT_RESTRICT attr,
42-
void *(*start_routine)(void*),
43-
void *GIT_RESTRICT arg);
45+
int git_win32__thread_create(
46+
git_win32_thread *GIT_RESTRICT,
47+
const pthread_attr_t *GIT_RESTRICT,
48+
void *(*) (void *),
49+
void *GIT_RESTRICT);
50+
51+
int git_win32__thread_join(
52+
git_win32_thread *,
53+
void **);
54+
55+
#ifdef GIT_THREADS
4456

45-
int pthread_join(pthread_t, void **);
57+
typedef git_win32_thread git_thread;
58+
59+
#define git_thread_create(git_thread_ptr, attr, start_routine, arg) \
60+
git_win32__thread_create(git_thread_ptr, attr, start_routine, arg)
61+
#define git_thread_join(git_thread_ptr, status) \
62+
git_win32__thread_join(git_thread_ptr, status)
63+
64+
#endif
4665

4766
int pthread_mutex_init(
4867
pthread_mutex_t *GIT_RESTRICT mutex,

tests/object/cache.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -229,7 +229,7 @@ void test_object_cache__threadmania(void)
229229

230230
#ifdef GIT_THREADS
231231
for (th = 0; th < THREADCOUNT; ++th) {
232-
cl_git_pass(git_thread_join(t[th], &data));
232+
cl_git_pass(git_thread_join(&t[th], &data));
233233
cl_assert_equal_i(th, ((int *)data)[0]);
234234
git__free(data);
235235
}
@@ -276,7 +276,7 @@ void test_object_cache__fast_thread_rush(void)
276276
#ifdef GIT_THREADS
277277
for (th = 0; th < THREADCOUNT*2; ++th) {
278278
void *rval;
279-
cl_git_pass(git_thread_join(t[th], &rval));
279+
cl_git_pass(git_thread_join(&t[th], &rval));
280280
cl_assert_equal_i(th, *((int *)rval));
281281
}
282282
#endif

tests/threads/refdb.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,7 @@ void test_threads_refdb__iterator(void)
8484

8585
#ifdef GIT_THREADS
8686
for (t = 0; t < THREADS; ++t) {
87-
cl_git_pass(git_thread_join(th[t], NULL));
87+
cl_git_pass(git_thread_join(&th[t], NULL));
8888
}
8989
#endif
9090

@@ -215,7 +215,7 @@ void test_threads_refdb__edit_while_iterate(void)
215215
}
216216

217217
for (t = 0; t < THREADS; ++t) {
218-
cl_git_pass(git_thread_join(th[t], NULL));
218+
cl_git_pass(git_thread_join(&th[t], NULL));
219219
}
220220
#endif
221221
}

tests/threads/thread_helpers.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ void run_in_parallel(
3232

3333
#ifdef GIT_THREADS
3434
for (t = 0; t < threads; ++t)
35-
cl_git_pass(git_thread_join(th[t], NULL));
35+
cl_git_pass(git_thread_join(&th[t], NULL));
3636
memset(th, 0, threads * sizeof(git_thread));
3737
#endif
3838

0 commit comments

Comments
 (0)