summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEdward Thomson <ethomson@edwardthomson.com>2019-12-01 14:38:54 +1100
committerGitHub <noreply@github.com>2019-12-01 14:38:54 +1100
commit36bfc27a45ac34e8425271c9d3c79ce62564e195 (patch)
tree3e99e9063a9ea639c6a752a09e1c898332dcf82d
parentd298f9b2879170612dff7512c8c20e64baad69d1 (diff)
parent5c6180b5a0e9f9bd1c82938137582720d7a2e6e6 (diff)
downloadlibgit2-36bfc27a45ac34e8425271c9d3c79ce62564e195.tar.gz
Merge pull request #5314 from pks-t/pks/dll-main-removal
global: convert to fiber-local storage to fix exit races
-rw-r--r--src/global.c52
-rw-r--r--src/global.h2
-rw-r--r--src/win32/thread.c5
3 files changed, 12 insertions, 47 deletions
diff --git a/src/global.c b/src/global.c
index 418c036c1..5af35aa62 100644
--- a/src/global.c
+++ b/src/global.c
@@ -141,14 +141,21 @@ static void shutdown_common(void)
*/
#if defined(GIT_THREADS) && defined(GIT_WIN32)
-static DWORD _tls_index;
+static DWORD _fls_index;
static volatile LONG _mutex = 0;
+static void WINAPI fls_free(void *st)
+{
+ git__global_state_cleanup(st);
+ git__free(st);
+}
+
static int synchronized_threads_init(void)
{
int error;
- _tls_index = TlsAlloc();
+ if ((_fls_index = FlsAlloc(fls_free)) == FLS_OUT_OF_INDEXES)
+ return -1;
git_threads_init();
@@ -190,9 +197,7 @@ int git_libgit2_shutdown(void)
if ((ret = git_atomic_dec(&git__n_inits)) == 0) {
shutdown_common();
- git__free_tls_data();
-
- TlsFree(_tls_index);
+ FlsFree(_fls_index);
git_mutex_free(&git__mwindow_mutex);
#if defined(GIT_MSVC_CRTDBG)
@@ -213,7 +218,7 @@ git_global_st *git__global_state(void)
assert(git_atomic_get(&git__n_inits) > 0);
- if ((ptr = TlsGetValue(_tls_index)) != NULL)
+ if ((ptr = FlsGetValue(_fls_index)) != NULL)
return ptr;
ptr = git__calloc(1, sizeof(git_global_st));
@@ -222,43 +227,10 @@ git_global_st *git__global_state(void)
git_buf_init(&ptr->error_buf, 0);
- TlsSetValue(_tls_index, ptr);
+ FlsSetValue(_fls_index, ptr);
return ptr;
}
-/**
- * Free the TLS data associated with this thread.
- * This should only be used by the thread as it
- * is exiting.
- */
-void git__free_tls_data(void)
-{
- void *ptr = TlsGetValue(_tls_index);
- if (!ptr)
- return;
-
- git__global_state_cleanup(ptr);
- git__free(ptr);
- TlsSetValue(_tls_index, NULL);
-}
-
-BOOL WINAPI DllMain(HINSTANCE hInstDll, DWORD fdwReason, LPVOID lpvReserved)
-{
- GIT_UNUSED(hInstDll);
- GIT_UNUSED(lpvReserved);
-
- /* This is how Windows lets us know our thread is being shut down */
- if (fdwReason == DLL_THREAD_DETACH) {
- git__free_tls_data();
- }
-
- /*
- * Windows pays attention to this during library loading. We don't do anything
- * so we trivially succeed.
- */
- return TRUE;
-}
-
#elif defined(GIT_THREADS) && defined(_POSIX_THREADS)
static pthread_key_t _tls_key;
diff --git a/src/global.h b/src/global.h
index 3c0559c68..db41dad1f 100644
--- a/src/global.h
+++ b/src/global.h
@@ -35,8 +35,6 @@ typedef void (*git_global_shutdown_fn)(void);
extern void git__on_shutdown(git_global_shutdown_fn callback);
-extern void git__free_tls_data(void);
-
extern const char *git_libgit2__user_agent(void);
extern const char *git_libgit2__ssl_ciphers(void);
diff --git a/src/win32/thread.c b/src/win32/thread.c
index c3a6c0e28..42dba7f97 100644
--- a/src/win32/thread.c
+++ b/src/win32/thread.c
@@ -32,8 +32,6 @@ static DWORD WINAPI git_win32__threadproc(LPVOID lpParameter)
thread->result = thread->proc(thread->param);
- git__free_tls_data();
-
return CLEAN_THREAD_EXIT;
}
@@ -103,9 +101,6 @@ void git_thread_exit(void *value)
{
assert(GIT_GLOBAL->current_thread);
GIT_GLOBAL->current_thread->result = value;
-
- git__free_tls_data();
-
ExitThread(CLEAN_THREAD_EXIT);
}