diff options
| author | Vicent Martà <vicent@github.com> | 2012-11-13 13:28:08 -0800 |
|---|---|---|
| committer | Vicent Martà <vicent@github.com> | 2012-11-13 13:28:08 -0800 |
| commit | 3741a37f5ee80d7475cdfedcd4de7d8ea64cf1e8 (patch) | |
| tree | 8861ec34c51061c59ed2daf945d2b7cf77456fed /src/global.c | |
| parent | 70572ff80b071aae5d6b398572e1aa0be45f6844 (diff) | |
| parent | 2a612fe3c31f2c386236ccb1483741835a5db318 (diff) | |
| download | libgit2-3741a37f5ee80d7475cdfedcd4de7d8ea64cf1e8.tar.gz | |
Merge pull request #1055 from ethomson/sha1_win32
Win32 CryptoAPI and CNG support for SHA1
Diffstat (limited to 'src/global.c')
| -rw-r--r-- | src/global.c | 51 |
1 files changed, 44 insertions, 7 deletions
diff --git a/src/global.c b/src/global.c index 22127faf7..d085089c3 100644 --- a/src/global.c +++ b/src/global.c @@ -6,6 +6,7 @@ */ #include "common.h" #include "global.h" +#include "hash.h" #include "git2/threads.h" #include "thread-utils.h" @@ -38,19 +39,39 @@ git_mutex git__mwindow_mutex; * functions are not available in that case. */ +/* + * `git_threads_init()` allows subsystems to perform global setup, + * which may take place in the global scope. An explicit memory + * fence exists at the exit of `git_threads_init()`. Without this, + * CPU cores are free to reorder cache invalidation of `_tls_init` + * before cache invalidation of the subsystems' newly written global + * state. + */ #if defined(GIT_THREADS) && defined(GIT_WIN32) static DWORD _tls_index; static int _tls_init = 0; -void git_threads_init(void) +int git_threads_init(void) { + int error; + if (_tls_init) - return; + return 0; _tls_index = TlsAlloc(); - _tls_init = 1; git_mutex_init(&git__mwindow_mutex); + + /* Initialize any other subsystems that have global state */ + if ((error = git_hash_global_init()) >= 0) + _tls_init = 1; + + if (error == 0) + _tls_init = 1; + + GIT_MEMORY_BARRIER; + + return error; } void git_threads_shutdown(void) @@ -58,6 +79,9 @@ void git_threads_shutdown(void) TlsFree(_tls_index); _tls_init = 0; git_mutex_free(&git__mwindow_mutex); + + /* Shut down any subsystems that have global state */ + git_hash_global_shutdown(); } git_global_st *git__global_state(void) @@ -88,19 +112,31 @@ static void cb__free_status(void *st) git__free(st); } -void git_threads_init(void) +int git_threads_init(void) { + int error = 0; + if (_tls_init) - return; + return 0; pthread_key_create(&_tls_key, &cb__free_status); - _tls_init = 1; + + /* Initialize any other subsystems that have global state */ + if ((error = git_hash_global_init()) >= 0) + _tls_init = 1; + + GIT_MEMORY_BARRIER; + + return error; } void git_threads_shutdown(void) { pthread_key_delete(_tls_key); _tls_init = 0; + + /* Shut down any subsystems that have global state */ + git_hash_global_shutdown(); } git_global_st *git__global_state(void) @@ -125,9 +161,10 @@ git_global_st *git__global_state(void) static git_global_st __state; -void git_threads_init(void) +int git_threads_init(void) { /* noop */ + return 0; } void git_threads_shutdown(void) |
