global: refactor setup and cleanup Move the common initialization and cleanup methods to reduce unnecessary duplication.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248
diff --git a/src/global.c b/src/global.c
index 0eab8d5..35595fb 100644
--- a/src/global.c
+++ b/src/global.c
@@ -33,6 +33,9 @@ static git_atomic git__n_shutdown_callbacks;
static git_atomic git__n_inits;
char *git__user_agent;
+static int init_ssl(void);
+static void shutdown_ssl(void);
+
void git__on_shutdown(git_global_shutdown_fn callback)
{
int count = git_atomic_inc(&git__n_shutdown_callbacks);
@@ -49,16 +52,51 @@ static void git__global_state_cleanup(git_global_st *st)
st->error_t.message = NULL;
}
-static void git__shutdown(void)
+static int init_common(void)
+{
+ int ret;
+
+ /* Initialize the CRT debug allocator first, before our first malloc */
+#if defined(GIT_MSVC_CRTDBG)
+ git_win32__crtdbg_stacktrace_init();
+ git_win32__stack_init();
+#endif
+
+ /* Initialize any other subsystems that have global state */
+ if ((ret = git_hash_global_init()) == 0 &&
+ (ret = git_sysdir_global_init()) == 0 &&
+ (ret = init_ssl()) == 0) {
+ }
+
+ 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);
+ 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();
}
+
+ shutdown_ssl();
+
+ git__free(git__user_agent);
+
+#if defined(GIT_MSVC_CRTDBG)
+ git_win32__crtdbg_stacktrace_cleanup();
+ git_win32__stack_cleanup();
+#endif
}
#if defined(GIT_THREADS) && defined(GIT_OPENSSL)
@@ -91,7 +129,7 @@ static void shutdown_ssl_locking(void)
}
#endif
-static void init_ssl(void)
+static int init_ssl(void)
{
#ifdef GIT_OPENSSL
long ssl_opts = SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3;
@@ -116,15 +154,18 @@ static void init_ssl(void)
if (!SSL_CTX_set_default_verify_paths(git__ssl_ctx)) {
SSL_CTX_free(git__ssl_ctx);
git__ssl_ctx = NULL;
+ return -1;
}
#endif
+
+ return 0;
}
/**
* This function aims to clean-up the SSL context which
* we allocated.
*/
-static void uninit_ssl(void)
+static void shutdown_ssl(void)
{
#ifdef GIT_OPENSSL
if (git__ssl_ctx) {
@@ -208,14 +249,13 @@ static int synchronized_threads_init(void)
int error;
_tls_index = TlsAlloc();
+
+ win32_pthread_initialize();
+
if (git_mutex_init(&git__mwindow_mutex))
return -1;
- /* Initialize any other subsystems that have global state */
- if ((error = git_hash_global_init()) >= 0)
- error = git_sysdir_global_init();
-
- win32_pthread_initialize();
+ error = init_common();
return error;
}
@@ -229,11 +269,6 @@ int git_libgit2_init(void)
/* Only do work on a 0 -> 1 transition of the refcount */
if ((ret = git_atomic_inc(&git__n_inits)) == 1) {
-#if defined(GIT_MSVC_CRTDBG)
- git_win32__crtdbg_stacktrace_init();
- git_win32__stack_init();
-#endif
-
if (synchronized_threads_init() < 0)
ret = -1;
}
@@ -244,17 +279,6 @@ int git_libgit2_init(void)
return ret;
}
-static void synchronized_threads_shutdown(void)
-{
- /* Shut down any subsystems that have global state */
- git__shutdown();
-
- git__free_tls_data();
-
- TlsFree(_tls_index);
- git_mutex_free(&git__mwindow_mutex);
-}
-
int git_libgit2_shutdown(void)
{
int ret;
@@ -264,14 +288,12 @@ int git_libgit2_shutdown(void)
/* Only do work on a 1 -> 0 transition of the refcount */
if ((ret = git_atomic_dec(&git__n_inits)) == 0) {
- synchronized_threads_shutdown();
+ shutdown_common();
-#if defined(GIT_MSVC_CRTDBG)
- git_win32__crtdbg_stacktrace_cleanup();
- git_win32__stack_cleanup();
-#endif
+ git__free_tls_data();
- git__free(git__user_agent);
+ TlsFree(_tls_index);
+ git_mutex_free(&git__mwindow_mutex);
}
/* Exit the lock */
@@ -331,17 +353,10 @@ static void init_once(void)
{
if ((init_error = git_mutex_init(&git__mwindow_mutex)) != 0)
return;
- pthread_key_create(&_tls_key, &cb__free_status);
-
-
- /* Initialize any other subsystems that have global state */
- if ((init_error = git_hash_global_init()) >= 0)
- init_error = git_sysdir_global_init();
- /* OpenSSL needs to be initialized from the main thread */
- init_ssl();
+ pthread_key_create(&_tls_key, &cb__free_status);
- GIT_MEMORY_BARRIER;
+ init_error = init_common();
}
int git_libgit2_init(void)
@@ -364,15 +379,13 @@ int git_libgit2_shutdown(void)
return ret;
/* Shut down any subsystems that have global state */
- git__shutdown();
- uninit_ssl();
+ shutdown_common();
ptr = pthread_getspecific(_tls_key);
pthread_setspecific(_tls_key, NULL);
git__global_state_cleanup(ptr);
git__free(ptr);
- git__free(git__user_agent);
pthread_key_delete(_tls_key);
git_mutex_free(&git__mwindow_mutex);
@@ -405,15 +418,16 @@ static git_global_st __state;
int git_libgit2_init(void)
{
- static int ssl_inited = 0;
+ int ret;
- if (!ssl_inited) {
- init_ssl();
- ssl_inited = 1;
- }
+ /* Only init SSL the first time */
+ if ((ret = git_atomic_inc(&git__n_inits)) != 1)
+ return ret;
+
+ if ((ret = init_common()) < 0)
+ return ret;
- git_buf_init(&__state.error_buf, 0);
- return git_atomic_inc(&git__n_inits);
+ return 1;
}
int git_libgit2_shutdown(void)
@@ -421,15 +435,12 @@ int git_libgit2_shutdown(void)
int ret;
/* Shut down any subsystems that have global state */
- if ((ret = git_atomic_dec(&git__n_inits)) != 0)
- return ret;
-
- git__shutdown();
- git__global_state_cleanup(&__state);
- uninit_ssl();
- git__free(git__user_agent);
+ if ((ret = git_atomic_dec(&git__n_inits)) == 0) {
+ shutdown_common();
+ git__global_state_cleanup(&__state);
+ }
- return 0;
+ return ret;
}
git_global_st *git__global_state(void)