File Coverage

deps/libgit2/src/libgit2/threadstate.c
Criterion Covered Total %
statement 19 29 65.5
branch 5 8 62.5
condition n/a
subroutine n/a
pod n/a
total 24 37 64.8


line stmt bran cond sub pod time code
1             /*
2             * Copyright (C) the libgit2 contributors. All rights reserved.
3             *
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.
6             */
7              
8             #include "threadstate.h"
9             #include "runtime.h"
10              
11             /**
12             * Handle the thread-local state
13             *
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).
17             *
18             * This function allocates a TLS index to store the per-
19             * thread state.
20             *
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.
25             *
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`.
30             */
31              
32             static git_tlsdata_key tls_key;
33              
34 1           static void threadstate_dispose(git_threadstate *threadstate)
35             {
36 1 50         if (!threadstate)
37 0           return;
38              
39 1 50         if (threadstate->error_t.message != git_str__initstr)
40 1           git__free(threadstate->error_t.message);
41 1           threadstate->error_t.message = NULL;
42             }
43              
44 1           static void GIT_SYSTEM_CALL threadstate_free(void *threadstate)
45             {
46 1           threadstate_dispose(threadstate);
47 1           git__free(threadstate);
48 1           }
49              
50 0           static void git_threadstate_global_shutdown(void)
51             {
52             git_threadstate *threadstate;
53              
54 0           threadstate = git_tlsdata_get(tls_key);
55 0           git_tlsdata_set(tls_key, NULL);
56              
57 0           threadstate_dispose(threadstate);
58 0           git__free(threadstate);
59              
60 0           git_tlsdata_dispose(tls_key);
61 0           }
62              
63 87           int git_threadstate_global_init(void)
64             {
65 87 50         if (git_tlsdata_init(&tls_key, &threadstate_free) != 0)
66 0           return -1;
67              
68 87           return git_runtime_shutdown_register(git_threadstate_global_shutdown);
69             }
70              
71 35418           git_threadstate *git_threadstate_get(void)
72             {
73             git_threadstate *threadstate;
74              
75 35418 100         if ((threadstate = git_tlsdata_get(tls_key)) != NULL)
76 35387           return threadstate;
77              
78 62           if ((threadstate = git__calloc(1, sizeof(git_threadstate))) == NULL ||
79 31           git_str_init(&threadstate->error_buf, 0) < 0)
80 0           return NULL;
81              
82 31           git_tlsdata_set(tls_key, threadstate);
83 31           return threadstate;
84             }