Hash :
27f50a66
Author :
Date :
2021-09-02T18:59:19
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
/*
* Copyright (C) the libgit2 contributors. All rights reserved.
*
* This file is part of libgit2, distributed under the GNU GPL v2 with
* a Linking Exception. For full terms see the included COPYING file.
*/
#include "threadstate.h"
#include "runtime.h"
/**
* Handle the thread-local state
*
* `git_threadstate_global_init` will be called as part
* of `git_libgit2_init` (which itself must be called
* before calling any other function in the library).
*
* This function allocates a TLS index to store the per-
* thread state.
*
* Any internal method that requires thread-local state
* will then call `git_threadstate_get()` which returns a
* pointer to the thread-local state structure; this
* structure is lazily allocated on each thread.
*
* This mechanism will register a shutdown handler
* (`git_threadstate_global_shutdown`) which will free the
* TLS index. This shutdown handler will be called by
* `git_libgit2_shutdown`.
*/
static git_tlsdata_key tls_key;
static void threadstate_dispose(git_threadstate *threadstate)
{
if (!threadstate)
return;
if (threadstate->error_t.message != git_buf__initbuf)
git__free(threadstate->error_t.message);
threadstate->error_t.message = NULL;
}
static void GIT_SYSTEM_CALL threadstate_free(void *threadstate)
{
threadstate_dispose(threadstate);
git__free(threadstate);
}
static void git_threadstate_global_shutdown(void)
{
git_threadstate *threadstate;
threadstate = git_tlsdata_get(tls_key);
git_tlsdata_set(tls_key, NULL);
threadstate_dispose(threadstate);
git__free(threadstate);
git_tlsdata_dispose(tls_key);
}
int git_threadstate_global_init(void)
{
if (git_tlsdata_init(&tls_key, &threadstate_free) != 0)
return -1;
return git_runtime_shutdown_register(git_threadstate_global_shutdown);
}
git_threadstate *git_threadstate_get(void)
{
git_threadstate *threadstate;
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;
git_tlsdata_set(tls_key, threadstate);
return threadstate;
}