summaryrefslogtreecommitdiff
path: root/src/global.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/global.c')
-rw-r--r--src/global.c170
1 files changed, 20 insertions, 150 deletions
diff --git a/src/global.c b/src/global.c
index c4e925b73..e6b7f46f0 100644
--- a/src/global.c
+++ b/src/global.c
@@ -5,7 +5,7 @@
* a Linking Exception. For full terms see the included COPYING file.
*/
-#include "global.h"
+#include "runtime.h"
#include "alloc.h"
#include "threadstate.h"
@@ -24,159 +24,29 @@
#include "transports/ssh.h"
#include "win32/w32_stack.h"
-typedef int (*git_global_init_fn)(void);
-
-static git_global_init_fn git__init_callbacks[] = {
- git_allocator_global_init,
- git_threadstate_global_init,
- git_threads_global_init,
- git_hash_global_init,
- git_sysdir_global_init,
- git_filter_global_init,
- git_merge_driver_global_init,
- git_transport_ssh_global_init,
- git_stream_registry_global_init,
- git_openssl_stream_global_init,
- git_mbedtls_stream_global_init,
- git_mwindow_global_init,
- git_pool_global_init,
- git_settings_global_init
-};
-
-static git_global_shutdown_fn git__shutdown_callbacks[ARRAY_SIZE(git__init_callbacks)];
-
-static git_atomic git__n_shutdown_callbacks;
-static git_atomic git__n_inits;
-
-void git__on_shutdown(git_global_shutdown_fn callback)
-{
- int count = git_atomic_inc(&git__n_shutdown_callbacks);
- assert(count <= (int) ARRAY_SIZE(git__shutdown_callbacks) && count > 0);
- git__shutdown_callbacks[count - 1] = callback;
-}
-
-static int init_common(void)
-{
- size_t i;
- int ret;
-
- /* Initialize subsystems that have global state */
- for (i = 0; i < ARRAY_SIZE(git__init_callbacks); i++)
- if ((ret = git__init_callbacks[i]()) != 0)
- break;
-
- GIT_MEMORY_BARRIER;
-
- return ret;
-}
-
-static void shutdown_common(void)
-{
- int pos;
-
- /* Shutdown subsystems that have registered */
- for (pos = git_atomic_get(&git__n_shutdown_callbacks);
- pos > 0;
- pos = git_atomic_dec(&git__n_shutdown_callbacks)) {
-
- git_global_shutdown_fn cb = git__swap(
- git__shutdown_callbacks[pos - 1], NULL);
-
- if (cb != NULL)
- cb();
- }
-}
-
-/*
- * `git_libgit2_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_libgit2_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)
-
-/*
- * On Win32, we use a spinlock to provide locking semantics. This is
- * lighter-weight than a proper critical section.
- */
-static volatile LONG init_spinlock = 0;
-
-GIT_INLINE(int) init_lock(void)
-{
- while (InterlockedCompareExchange(&init_spinlock, 1, 0)) { Sleep(0); }
- return 0;
-}
-
-GIT_INLINE(int) init_unlock(void)
-{
- InterlockedExchange(&init_spinlock, 0);
- return 0;
-}
-
-#elif defined(GIT_THREADS) && defined(_POSIX_THREADS)
-
-/*
- * On POSIX, we need to use a proper mutex for locking. We might prefer
- * a spinlock here, too, but there's no static initializer for a
- * pthread_spinlock_t.
- */
-static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
-
-GIT_INLINE(int) init_lock(void)
-{
- return pthread_mutex_lock(&mutex) == 0 ? 0 : -1;
-}
-
-GIT_INLINE(int) init_unlock(void)
-{
- return pthread_mutex_unlock(&mutex) == 0 ? 0 : -1;
-}
-
-#elif defined(GIT_THREADS)
-# error unknown threading model
-#else
-
-# define init_lock() 0
-# define init_unlock() 0
-
-#endif
-
int git_libgit2_init(void)
{
- int ret;
-
- if (init_lock() < 0)
- return -1;
-
- /* Only do work on a 0 -> 1 transition of the refcount */
- if ((ret = git_atomic_inc(&git__n_inits)) == 1) {
- if (init_common() < 0)
- ret = -1;
- }
-
- if (init_unlock() < 0)
- return -1;
-
- return ret;
+ static git_runtime_init_fn init_fns[] = {
+ git_allocator_global_init,
+ git_threadstate_global_init,
+ git_threads_global_init,
+ git_hash_global_init,
+ git_sysdir_global_init,
+ git_filter_global_init,
+ git_merge_driver_global_init,
+ git_transport_ssh_global_init,
+ git_stream_registry_global_init,
+ git_openssl_stream_global_init,
+ git_mbedtls_stream_global_init,
+ git_mwindow_global_init,
+ git_pool_global_init,
+ git_settings_global_init
+ };
+
+ return git_runtime_init(init_fns, ARRAY_SIZE(init_fns));
}
int git_libgit2_shutdown(void)
{
- int ret;
-
- /* Enter the lock */
- if (init_lock() < 0)
- return -1;
-
- /* Only do work on a 1 -> 0 transition of the refcount */
- if ((ret = git_atomic_dec(&git__n_inits)) == 0)
- shutdown_common();
-
- /* Exit the lock */
- if (init_unlock() < 0)
- return -1;
-
- return ret;
+ return git_runtime_shutdown();
}