diff options
author | Russell Belfer <rb@github.com> | 2013-09-11 12:45:20 -0700 |
---|---|---|
committer | Russell Belfer <rb@github.com> | 2013-09-17 09:31:45 -0700 |
commit | a3aa5f4d5dcbe038f1d1c5ff40eed29d27953fbe (patch) | |
tree | 6ef7a6b5bdfc26e10279c2629f58036f4025f199 /src/global.c | |
parent | e7d0ced2192c5efeea6d9f5667d366891010b86a (diff) | |
download | libgit2-a3aa5f4d5dcbe038f1d1c5ff40eed29d27953fbe.tar.gz |
Add simple global shutdown hooks
Increasingly there are a number of components that want to do some
cleanup at global shutdown time (at least if there are not going
to be memory leaks). This creates a very simple system of shutdown
hooks that will be invoked by git_threads_shutdown. Right now, the
maximum number of hooks is hardcoded, but since adding a hook is
not a public API, it should be fine and I thought it was better to
start off with really simple code.
Diffstat (limited to 'src/global.c')
-rw-r--r-- | src/global.c | 38 |
1 files changed, 28 insertions, 10 deletions
diff --git a/src/global.c b/src/global.c index b504e5e0a..4f024f17e 100644 --- a/src/global.c +++ b/src/global.c @@ -14,6 +14,28 @@ git_mutex git__mwindow_mutex; +#define MAX_SHUTDOWN_CB 8 + +git_global_shutdown_fn git__shutdown_callbacks[MAX_SHUTDOWN_CB]; +git_atomic git__n_shutdown_callbacks; + +void git__on_shutdown(git_global_shutdown_fn callback) +{ + int count = git_atomic_inc(&git__n_shutdown_callbacks); + assert(count <= MAX_SHUTDOWN_CB); + git__shutdown_callbacks[count - 1] = callback; +} + +static void git__shutdown(void) +{ + int pos; + + while ((pos = git_atomic_dec(&git__n_shutdown_callbacks)) >= 0) { + if (git__shutdown_callbacks[pos]) + git__shutdown_callbacks[pos](); + } +} + /** * Handle the global state with TLS * @@ -79,9 +101,7 @@ int git_threads_init(void) void git_threads_shutdown(void) { /* Shut down any subsystems that have global state */ - win32_pthread_shutdown(); - git_futils_dirs_free(); - git_hash_global_shutdown(); + git__shutdown(); TlsFree(_tls_index); _tls_init = 0; @@ -140,6 +160,9 @@ int git_threads_init(void) void git_threads_shutdown(void) { + /* Shut down any subsystems that have global state */ + git__shutdown(); + if (_tls_init) { void *ptr = pthread_getspecific(_tls_key); pthread_setspecific(_tls_key, NULL); @@ -149,10 +172,6 @@ void git_threads_shutdown(void) pthread_key_delete(_tls_key); _tls_init = 0; git_mutex_free(&git__mwindow_mutex); - - /* Shut down any subsystems that have global state */ - git_hash_global_shutdown(); - git_futils_dirs_free(); } git_global_st *git__global_state(void) @@ -179,15 +198,14 @@ static git_global_st __state; int git_threads_init(void) { - /* noop */ + /* noop */ return 0; } void git_threads_shutdown(void) { /* Shut down any subsystems that have global state */ - git_hash_global_shutdown(); - git_futils_dirs_free(); + git__shutdown(); } git_global_st *git__global_state(void) |