diff options
author | Edward Thomson <ethomson@edwardthomson.com> | 2020-05-15 10:29:41 +0100 |
---|---|---|
committer | Edward Thomson <ethomson@edwardthomson.com> | 2020-10-11 20:07:12 +0100 |
commit | 8970acb750ecf4b86883d9ea1a8cb280517e6c86 (patch) | |
tree | ba9767f201e1018214ca4434d72d4493e7d89e2a | |
parent | c40d2dc5ff2058bf04d816423507dec42e7dd0cc (diff) | |
download | libgit2-8970acb750ecf4b86883d9ea1a8cb280517e6c86.tar.gz |
thread: don't use the global tlsdata for thread exit
We want to store a pointer to emulate `pthread_exit` on Windows. Do
this within the threading infrastructure so that it could potentially be
re-used outside of the context of libgit2 itself.
-rw-r--r-- | src/threadstate.h | 6 | ||||
-rw-r--r-- | src/win32/thread.c | 23 |
2 files changed, 18 insertions, 11 deletions
diff --git a/src/threadstate.h b/src/threadstate.h index 9a4ef4d3a..51810a939 100644 --- a/src/threadstate.h +++ b/src/threadstate.h @@ -14,12 +14,6 @@ typedef struct { git_error error_t; git_buf error_buf; char oid_fmt[GIT_OID_HEXSZ+1]; - - /* On Windows, this is the current child thread that was started by - * `git_thread_create`. This is used to set the thread's exit code - * when terminated by `git_thread_exit`. It is unused on POSIX. - */ - git_thread *current_thread; } git_threadstate; extern int git_threadstate_global_init(void); diff --git a/src/win32/thread.c b/src/win32/thread.c index b9f8bc9d7..dad32ef38 100644 --- a/src/win32/thread.c +++ b/src/win32/thread.c @@ -7,8 +7,6 @@ #include "thread.h" -#include "../tlsdata.h" - #define CLEAN_THREAD_EXIT 0x6F012842 typedef void (WINAPI *win32_srwlock_fn)(GIT_SRWLOCK *); @@ -19,6 +17,8 @@ static win32_srwlock_fn win32_srwlock_release_shared; static win32_srwlock_fn win32_srwlock_acquire_exclusive; static win32_srwlock_fn win32_srwlock_release_exclusive; +static DWORD fls_index; + /* The thread procedure stub used to invoke the caller's procedure * and capture the return value for later collection. Windows will * only hold a DWORD, but we need to be able to store an entire @@ -28,13 +28,18 @@ static DWORD WINAPI git_win32__threadproc(LPVOID lpParameter) git_thread *thread = lpParameter; /* Set the current thread for `git_thread_exit` */ - GIT_TLSDATA->current_thread = thread; + FlsSetValue(fls_index, thread); thread->result = thread->proc(thread->param); return CLEAN_THREAD_EXIT; } +static void git_threads_global_shutdown(void) +{ + FlsFree(fls_index); +} + int git_threads_global_init(void) { HMODULE hModule = GetModuleHandleW(L"kernel32"); @@ -52,6 +57,11 @@ int git_threads_global_init(void) GetProcAddress(hModule, "ReleaseSRWLockExclusive"); } + if ((fls_index = FlsAlloc(NULL)) == FLS_OUT_OF_INDEXES) + return -1; + + git__on_shutdown(git_threads_global_shutdown); + return 0; } @@ -99,8 +109,11 @@ int git_thread_join( void git_thread_exit(void *value) { - assert(GIT_TLSDATA->current_thread); - GIT_TLSDATA->current_thread->result = value; + git_thread *thread = FlsGetValue(fls_index); + + if (thread) + thread->result = value; + ExitThread(CLEAN_THREAD_EXIT); } |