Replace global storage TLS with new interface
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 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162
diff --git a/src/threadstate.c b/src/threadstate.c
index 1c5ac60..6031e82 100644
--- a/src/threadstate.c
+++ b/src/threadstate.c
@@ -8,8 +8,6 @@
#include "threadstate.h"
#include "runtime.h"
-static void threadstate_dispose(git_threadstate *threadstate);
-
/**
* Handle the thread-local state
*
@@ -17,8 +15,7 @@ static void threadstate_dispose(git_threadstate *threadstate);
* of `git_libgit2_init` (which itself must be called
* before calling any other function in the library).
*
- * This function allocates a TLS index (using pthreads
- * or fiber-local storage in Win32) to store the per-
+ * This function allocates a TLS index to store the per-
* thread state.
*
* Any internal method that requires thread-local state
@@ -30,77 +27,41 @@ static void threadstate_dispose(git_threadstate *threadstate);
* (`git_threadstate_global_shutdown`) which will free the
* TLS index. This shutdown handler will be called by
* `git_libgit2_shutdown`.
- *
- * If libgit2 is built without threading support, the
- * `git_threadstate_get()` call returns a pointer to a single,
- * statically allocated global state. The `git_thread_`
- * functions are not available in that case.
*/
-#if defined(GIT_THREADS) && defined(GIT_WIN32)
+static git_tlsdata_key tls_key;
-static DWORD fls_index;
-
-static void git_threadstate_global_shutdown(void)
+static void threadstate_dispose(git_threadstate *threadstate)
{
- FlsFree(fls_index);
+ if (!threadstate)
+ return;
+
+ git__free(threadstate->error_t.message);
+ threadstate->error_t.message = NULL;
}
-static void WINAPI fls_free(void *threadstate)
+static void GIT_SYSTEM_CALL threadstate_free(void *threadstate)
{
threadstate_dispose(threadstate);
git__free(threadstate);
}
-int git_threadstate_global_init(void)
-{
- if ((fls_index = FlsAlloc(fls_free)) == FLS_OUT_OF_INDEXES)
- return -1;
-
- return git_runtime_shutdown_register(git_threadstate_global_shutdown);
-}
-
-git_threadstate *git_threadstate_get(void)
-{
- git_threadstate *threadstate;
-
- if ((threadstate = FlsGetValue(fls_index)) != NULL)
- return threadstate;
-
- if ((threadstate = git__calloc(1, sizeof(git_threadstate))) == NULL ||
- git_buf_init(&threadstate->error_buf, 0) < 0)
- return NULL;
-
- FlsSetValue(fls_index, threadstate);
- return threadstate;
-}
-
-#elif defined(GIT_THREADS) && defined(_POSIX_THREADS)
-
-static pthread_key_t tls_key;
-
static void git_threadstate_global_shutdown(void)
{
git_threadstate *threadstate;
- threadstate = pthread_getspecific(tls_key);
- pthread_setspecific(tls_key, NULL);
+ threadstate = git_tlsdata_get(tls_key);
+ git_tlsdata_set(tls_key, NULL);
threadstate_dispose(threadstate);
git__free(threadstate);
- pthread_key_delete(tls_key);
-}
-
-static void tls_free(void *threadstate)
-{
- threadstate_dispose(threadstate);
- git__free(threadstate);
+ git_tlsdata_dispose(tls_key);
}
int git_threadstate_global_init(void)
{
- if (pthread_key_create(&tls_key, &tls_free) != 0)
+ if (git_tlsdata_init(&tls_key, &threadstate_free) != 0)
return -1;
return git_runtime_shutdown_register(git_threadstate_global_shutdown);
@@ -110,46 +71,13 @@ git_threadstate *git_threadstate_get(void)
{
git_threadstate *threadstate;
- if ((threadstate = pthread_getspecific(tls_key)) != NULL)
+ if ((threadstate = git_tlsdata_get(tls_key)) != NULL)
return threadstate;
if ((threadstate = git__calloc(1, sizeof(git_threadstate))) == NULL ||
git_buf_init(&threadstate->error_buf, 0) < 0)
return NULL;
- pthread_setspecific(tls_key, threadstate);
+ git_tlsdata_set(tls_key, threadstate);
return threadstate;
}
-
-#elif defined(GIT_THREADS)
-# error unknown threading model
-#else
-
-static git_threadstate threadstate;
-
-static void git_threadstate_global_shutdown(void)
-{
- threadstate_dispose(&threadstate);
- memset(&threadstate, 0, sizeof(git_threadstate));
-}
-
-int git_threadstate_global_init(void)
-{
- return git_runtime_shutdown_register(git_threadstate_global_shutdown);
-}
-
-git_threadstate *git_threadstate_get(void)
-{
- return &threadstate;
-}
-
-#endif
-
-static void threadstate_dispose(git_threadstate *threadstate)
-{
- if (!threadstate)
- return;
-
- git__free(threadstate->error_t.message);
- threadstate->error_t.message = NULL;
-}