]> git.proxmox.com Git - libgit2.git/blobdiff - src/win32/thread.c
New upstream version 1.3.0+dfsg.1
[libgit2.git] / src / win32 / thread.c
index 42dba7f9740990d9be033874597032941d47a4a7..f5cacd320d89008b26bfe18b93cdf6cbfceb2c2f 100644 (file)
@@ -6,8 +6,7 @@
  */
 
 #include "thread.h"
-
-#include "../global.h"
+#include "runtime.h"
 
 #define CLEAN_THREAD_EXIT 0x6F012842
 
@@ -19,6 +18,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,14 +29,19 @@ static DWORD WINAPI git_win32__threadproc(LPVOID lpParameter)
        git_thread *thread = lpParameter;
 
        /* Set the current thread for `git_thread_exit` */
-       GIT_GLOBAL->current_thread = thread;
+       FlsSetValue(fls_index, thread);
 
        thread->result = thread->proc(thread->param);
 
        return CLEAN_THREAD_EXIT;
 }
 
-int git_threads_init(void)
+static void git_threads_global_shutdown(void)
+{
+       FlsFree(fls_index);
+}
+
+int git_threads_global_init(void)
 {
        HMODULE hModule = GetModuleHandleW(L"kernel32");
 
@@ -52,7 +58,10 @@ int git_threads_init(void)
                        GetProcAddress(hModule, "ReleaseSRWLockExclusive");
        }
 
-       return 0;
+       if ((fls_index = FlsAlloc(NULL)) == FLS_OUT_OF_INDEXES)
+               return -1;
+
+       return git_runtime_shutdown_register(git_threads_global_shutdown);
 }
 
 int git_thread_create(
@@ -85,10 +94,7 @@ int git_thread_join(
 
        /* Check for the thread having exited uncleanly. If exit was unclean,
         * then we don't have a return value to give back to the caller. */
-       if (exit != CLEAN_THREAD_EXIT) {
-               assert(false);
-               thread->result = NULL;
-       }
+       GIT_ASSERT(exit == CLEAN_THREAD_EXIT);
 
        if (value_ptr)
                *value_ptr = thread->result;
@@ -99,8 +105,11 @@ int git_thread_join(
 
 void git_thread_exit(void *value)
 {
-       assert(GIT_GLOBAL->current_thread);
-       GIT_GLOBAL->current_thread->result = value;
+       git_thread *thread = FlsGetValue(fls_index);
+
+       if (thread)
+               thread->result = value;
+
        ExitThread(CLEAN_THREAD_EXIT);
 }
 
@@ -137,7 +146,7 @@ int git_cond_init(git_cond *cond)
 {
        /* This is an auto-reset event. */
        *cond = CreateEventW(NULL, FALSE, FALSE, NULL);
-       assert(*cond);
+       GIT_ASSERT(*cond);
 
        /* If we can't create the event, claim that the reason was out-of-memory.
         * The actual reason can be fetched with GetLastError(). */
@@ -152,7 +161,7 @@ int git_cond_free(git_cond *cond)
                return EINVAL;
 
        closed = CloseHandle(*cond);
-       assert(closed);
+       GIT_ASSERT(closed);
        GIT_UNUSED(closed);
 
        *cond = NULL;
@@ -174,7 +183,7 @@ int git_cond_wait(git_cond *cond, git_mutex *mutex)
                return error;
 
        wait_result = WaitForSingleObject(*cond, INFINITE);
-       assert(WAIT_OBJECT_0 == wait_result);
+       GIT_ASSERT(WAIT_OBJECT_0 == wait_result);
        GIT_UNUSED(wait_result);
 
        return git_mutex_lock(mutex);
@@ -188,7 +197,7 @@ int git_cond_signal(git_cond *cond)
                return EINVAL;
 
        signaled = SetEvent(*cond);
-       assert(signaled);
+       GIT_ASSERT(signaled);
        GIT_UNUSED(signaled);
 
        return 0;