Commit 8970acb7 by Edward Thomson

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.
parent c40d2dc5
...@@ -14,12 +14,6 @@ typedef struct { ...@@ -14,12 +14,6 @@ typedef struct {
git_error error_t; git_error error_t;
git_buf error_buf; git_buf error_buf;
char oid_fmt[GIT_OID_HEXSZ+1]; 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; } git_threadstate;
extern int git_threadstate_global_init(void); extern int git_threadstate_global_init(void);
......
...@@ -7,8 +7,6 @@ ...@@ -7,8 +7,6 @@
#include "thread.h" #include "thread.h"
#include "../tlsdata.h"
#define CLEAN_THREAD_EXIT 0x6F012842 #define CLEAN_THREAD_EXIT 0x6F012842
typedef void (WINAPI *win32_srwlock_fn)(GIT_SRWLOCK *); typedef void (WINAPI *win32_srwlock_fn)(GIT_SRWLOCK *);
...@@ -19,6 +17,8 @@ static win32_srwlock_fn win32_srwlock_release_shared; ...@@ -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_acquire_exclusive;
static win32_srwlock_fn win32_srwlock_release_exclusive; static win32_srwlock_fn win32_srwlock_release_exclusive;
static DWORD fls_index;
/* The thread procedure stub used to invoke the caller's procedure /* The thread procedure stub used to invoke the caller's procedure
* and capture the return value for later collection. Windows will * and capture the return value for later collection. Windows will
* only hold a DWORD, but we need to be able to store an entire * 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) ...@@ -28,13 +28,18 @@ static DWORD WINAPI git_win32__threadproc(LPVOID lpParameter)
git_thread *thread = lpParameter; git_thread *thread = lpParameter;
/* Set the current thread for `git_thread_exit` */ /* Set the current thread for `git_thread_exit` */
GIT_TLSDATA->current_thread = thread; FlsSetValue(fls_index, thread);
thread->result = thread->proc(thread->param); thread->result = thread->proc(thread->param);
return CLEAN_THREAD_EXIT; return CLEAN_THREAD_EXIT;
} }
static void git_threads_global_shutdown(void)
{
FlsFree(fls_index);
}
int git_threads_global_init(void) int git_threads_global_init(void)
{ {
HMODULE hModule = GetModuleHandleW(L"kernel32"); HMODULE hModule = GetModuleHandleW(L"kernel32");
...@@ -52,6 +57,11 @@ int git_threads_global_init(void) ...@@ -52,6 +57,11 @@ int git_threads_global_init(void)
GetProcAddress(hModule, "ReleaseSRWLockExclusive"); GetProcAddress(hModule, "ReleaseSRWLockExclusive");
} }
if ((fls_index = FlsAlloc(NULL)) == FLS_OUT_OF_INDEXES)
return -1;
git__on_shutdown(git_threads_global_shutdown);
return 0; return 0;
} }
...@@ -99,8 +109,11 @@ int git_thread_join( ...@@ -99,8 +109,11 @@ int git_thread_join(
void git_thread_exit(void *value) void git_thread_exit(void *value)
{ {
assert(GIT_TLSDATA->current_thread); git_thread *thread = FlsGetValue(fls_index);
GIT_TLSDATA->current_thread->result = value;
if (thread)
thread->result = value;
ExitThread(CLEAN_THREAD_EXIT); ExitThread(CLEAN_THREAD_EXIT);
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment