Merge pull request #3051 from jeffhostetler/jeffhostetler/memleak_windows_tls_data Attempt to fix Windows TLS memory leak.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71
diff --git a/src/global.c b/src/global.c
index 1f3432d..f267fbd 100644
--- a/src/global.c
+++ b/src/global.c
@@ -223,13 +223,10 @@ int git_libgit2_init(void)
static void synchronized_threads_shutdown(void)
{
- void *ptr;
-
/* Shut down any subsystems that have global state */
git__shutdown();
- ptr = TlsGetValue(_tls_index);
- git__global_state_cleanup(ptr);
+ git__free_tls_data();
TlsFree(_tls_index);
git_mutex_free(&git__mwindow_mutex);
@@ -270,15 +267,20 @@ git_global_st *git__global_state(void)
return ptr;
}
-BOOL WINAPI DllMain(HINSTANCE dll, DWORD reason, LPVOID reserved)
+/**
+ * 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)
{
- if (reason == DLL_THREAD_DETACH) {
- void *ptr = TlsGetValue(_tls_index);
- git__global_state_cleanup(ptr);
- git__free(ptr);
- }
+ void *ptr = TlsGetValue(_tls_index);
+ if (!ptr)
+ return;
- return TRUE;
+ git__global_state_cleanup(ptr);
+ git__free(ptr);
+ TlsSetValue(_tls_index, NULL);
}
#elif defined(GIT_THREADS) && defined(_POSIX_THREADS)
diff --git a/src/global.h b/src/global.h
index a89a8d6..f56bec4 100644
--- a/src/global.h
+++ b/src/global.h
@@ -32,4 +32,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);
+
#endif
diff --git a/src/win32/pthread.c b/src/win32/pthread.c
index ec45ecb..a1cc189 100644
--- a/src/win32/pthread.c
+++ b/src/win32/pthread.c
@@ -20,6 +20,8 @@ static DWORD WINAPI git_win32__threadproc(LPVOID lpParameter)
thread->result = thread->proc(thread->param);
+ git__free_tls_data();
+
return CLEAN_THREAD_EXIT;
}