2 * Copyright (C) the libgit2 contributors. All rights reserved.
4 * This file is part of libgit2, distributed under the GNU GPL v2 with
5 * a Linking Exception. For full terms see the included COPYING file.
8 #include "threadstate.h"
12 * Handle the thread-local state
14 * `git_threadstate_global_init` will be called as part
15 * of `git_libgit2_init` (which itself must be called
16 * before calling any other function in the library).
18 * This function allocates a TLS index to store the per-
21 * Any internal method that requires thread-local state
22 * will then call `git_threadstate_get()` which returns a
23 * pointer to the thread-local state structure; this
24 * structure is lazily allocated on each thread.
26 * This mechanism will register a shutdown handler
27 * (`git_threadstate_global_shutdown`) which will free the
28 * TLS index. This shutdown handler will be called by
29 * `git_libgit2_shutdown`.
32 static git_tlsdata_key tls_key
;
34 static void threadstate_dispose(git_threadstate
*threadstate
)
39 if (threadstate
->error_t
.message
!= git_buf__initbuf
)
40 git__free(threadstate
->error_t
.message
);
41 threadstate
->error_t
.message
= NULL
;
44 static void GIT_SYSTEM_CALL
threadstate_free(void *threadstate
)
46 threadstate_dispose(threadstate
);
47 git__free(threadstate
);
50 static void git_threadstate_global_shutdown(void)
52 git_threadstate
*threadstate
;
54 threadstate
= git_tlsdata_get(tls_key
);
55 git_tlsdata_set(tls_key
, NULL
);
57 threadstate_dispose(threadstate
);
58 git__free(threadstate
);
60 git_tlsdata_dispose(tls_key
);
63 int git_threadstate_global_init(void)
65 if (git_tlsdata_init(&tls_key
, &threadstate_free
) != 0)
68 return git_runtime_shutdown_register(git_threadstate_global_shutdown
);
71 git_threadstate
*git_threadstate_get(void)
73 git_threadstate
*threadstate
;
75 if ((threadstate
= git_tlsdata_get(tls_key
)) != NULL
)
78 if ((threadstate
= git__calloc(1, sizeof(git_threadstate
))) == NULL
||
79 git_buf_init(&threadstate
->error_buf
, 0) < 0)
82 git_tlsdata_set(tls_key
, threadstate
);