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

Replace global storage TLS with new interface

parent fd2d4759
......@@ -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;
}
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