Commit 20ce17f0 by Tyler Ang-Wanek Committed by Edward Thomson

Replace global storage TLS with new interface

parent fd2d4759
...@@ -8,8 +8,6 @@ ...@@ -8,8 +8,6 @@
#include "threadstate.h" #include "threadstate.h"
#include "runtime.h" #include "runtime.h"
static void threadstate_dispose(git_threadstate *threadstate);
/** /**
* Handle the thread-local state * Handle the thread-local state
* *
...@@ -17,8 +15,7 @@ static void threadstate_dispose(git_threadstate *threadstate); ...@@ -17,8 +15,7 @@ static void threadstate_dispose(git_threadstate *threadstate);
* of `git_libgit2_init` (which itself must be called * of `git_libgit2_init` (which itself must be called
* before calling any other function in the library). * before calling any other function in the library).
* *
* This function allocates a TLS index (using pthreads * This function allocates a TLS index to store the per-
* or fiber-local storage in Win32) to store the per-
* thread state. * thread state.
* *
* Any internal method that requires thread-local state * Any internal method that requires thread-local state
...@@ -30,77 +27,41 @@ static void threadstate_dispose(git_threadstate *threadstate); ...@@ -30,77 +27,41 @@ static void threadstate_dispose(git_threadstate *threadstate);
* (`git_threadstate_global_shutdown`) which will free the * (`git_threadstate_global_shutdown`) which will free the
* TLS index. This shutdown handler will be called by * TLS index. This shutdown handler will be called by
* `git_libgit2_shutdown`. * `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 threadstate_dispose(git_threadstate *threadstate)
static void git_threadstate_global_shutdown(void)
{ {
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); threadstate_dispose(threadstate);
git__free(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) static void git_threadstate_global_shutdown(void)
{ {
git_threadstate *threadstate; git_threadstate *threadstate;
threadstate = pthread_getspecific(tls_key); threadstate = git_tlsdata_get(tls_key);
pthread_setspecific(tls_key, NULL); git_tlsdata_set(tls_key, NULL);
threadstate_dispose(threadstate); threadstate_dispose(threadstate);
git__free(threadstate); git__free(threadstate);
pthread_key_delete(tls_key); git_tlsdata_dispose(tls_key);
}
static void tls_free(void *threadstate)
{
threadstate_dispose(threadstate);
git__free(threadstate);
} }
int git_threadstate_global_init(void) 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 -1;
return git_runtime_shutdown_register(git_threadstate_global_shutdown); return git_runtime_shutdown_register(git_threadstate_global_shutdown);
...@@ -110,46 +71,13 @@ git_threadstate *git_threadstate_get(void) ...@@ -110,46 +71,13 @@ git_threadstate *git_threadstate_get(void)
{ {
git_threadstate *threadstate; git_threadstate *threadstate;
if ((threadstate = pthread_getspecific(tls_key)) != NULL) if ((threadstate = git_tlsdata_get(tls_key)) != NULL)
return threadstate; return threadstate;
if ((threadstate = git__calloc(1, sizeof(git_threadstate))) == NULL || if ((threadstate = git__calloc(1, sizeof(git_threadstate))) == NULL ||
git_buf_init(&threadstate->error_buf, 0) < 0) git_buf_init(&threadstate->error_buf, 0) < 0)
return NULL; return NULL;
pthread_setspecific(tls_key, threadstate); git_tlsdata_set(tls_key, threadstate);
return 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;
}
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