mirror of
https://git.proxmox.com/git/libgit2
synced 2025-05-20 21:48:50 +00:00
Merge pull request #3974 from libgit2/pks/synchronize-shutdown
global: synchronize initialization and shutdown with pthreads
This commit is contained in:
commit
5fe5557e8a
23
src/global.c
23
src/global.c
@ -247,6 +247,7 @@ BOOL WINAPI DllMain(HINSTANCE hInstDll, DWORD fdwReason, LPVOID lpvReserved)
|
||||
#elif defined(GIT_THREADS) && defined(_POSIX_THREADS)
|
||||
|
||||
static pthread_key_t _tls_key;
|
||||
static pthread_mutex_t _init_mutex = PTHREAD_MUTEX_INITIALIZER;
|
||||
static pthread_once_t _once_init = PTHREAD_ONCE_INIT;
|
||||
int init_error = 0;
|
||||
|
||||
@ -268,12 +269,19 @@ static void init_once(void)
|
||||
|
||||
int git_libgit2_init(void)
|
||||
{
|
||||
int ret;
|
||||
int ret, err;
|
||||
|
||||
ret = git_atomic_inc(&git__n_inits);
|
||||
pthread_once(&_once_init, init_once);
|
||||
|
||||
return init_error ? init_error : ret;
|
||||
if ((err = pthread_mutex_lock(&_init_mutex)) != 0)
|
||||
return err;
|
||||
err = pthread_once(&_once_init, init_once);
|
||||
err |= pthread_mutex_unlock(&_init_mutex);
|
||||
|
||||
if (err || init_error)
|
||||
return err | init_error;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int git_libgit2_shutdown(void)
|
||||
@ -285,6 +293,9 @@ int git_libgit2_shutdown(void)
|
||||
if ((ret = git_atomic_dec(&git__n_inits)) != 0)
|
||||
return ret;
|
||||
|
||||
if ((ret = pthread_mutex_lock(&_init_mutex)) != 0)
|
||||
return ret;
|
||||
|
||||
/* Shut down any subsystems that have global state */
|
||||
shutdown_common();
|
||||
|
||||
@ -298,6 +309,9 @@ int git_libgit2_shutdown(void)
|
||||
git_mutex_free(&git__mwindow_mutex);
|
||||
_once_init = new_once;
|
||||
|
||||
if ((ret = pthread_mutex_unlock(&_init_mutex)) != 0)
|
||||
return ret;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -327,7 +341,7 @@ int git_libgit2_init(void)
|
||||
{
|
||||
int ret;
|
||||
|
||||
/* Only init SSL the first time */
|
||||
/* Only init subsystems the first time */
|
||||
if ((ret = git_atomic_inc(&git__n_inits)) != 1)
|
||||
return ret;
|
||||
|
||||
@ -345,6 +359,7 @@ int git_libgit2_shutdown(void)
|
||||
if ((ret = git_atomic_dec(&git__n_inits)) == 0) {
|
||||
shutdown_common();
|
||||
git__global_state_cleanup(&__state);
|
||||
memset(&__state, 0, sizeof(__state));
|
||||
}
|
||||
|
||||
return ret;
|
||||
|
@ -12,3 +12,43 @@ void test_core_init__returns_count(void)
|
||||
cl_assert_equal_i(1, git_libgit2_shutdown());
|
||||
}
|
||||
|
||||
void test_core_init__reinit_succeeds(void)
|
||||
{
|
||||
cl_assert_equal_i(0, git_libgit2_shutdown());
|
||||
cl_assert_equal_i(1, git_libgit2_init());
|
||||
cl_sandbox_set_search_path_defaults();
|
||||
}
|
||||
|
||||
#ifdef GIT_THREADS
|
||||
static void *reinit(void *unused)
|
||||
{
|
||||
unsigned i;
|
||||
|
||||
for (i = 0; i < 20; i++) {
|
||||
cl_assert(git_libgit2_init() > 0);
|
||||
cl_assert(git_libgit2_shutdown() >= 0);
|
||||
}
|
||||
|
||||
return unused;
|
||||
}
|
||||
#endif
|
||||
|
||||
void test_core_init__concurrent_init_succeeds(void)
|
||||
{
|
||||
#ifdef GIT_THREADS
|
||||
git_thread threads[10];
|
||||
unsigned i;
|
||||
|
||||
cl_assert_equal_i(0, git_libgit2_shutdown());
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(threads); i++)
|
||||
git_thread_create(&threads[i], reinit, NULL);
|
||||
for (i = 0; i < ARRAY_SIZE(threads); i++)
|
||||
git_thread_join(&threads[i], NULL);
|
||||
|
||||
cl_assert_equal_i(1, git_libgit2_init());
|
||||
cl_sandbox_set_search_path_defaults();
|
||||
#else
|
||||
cl_skip();
|
||||
#endif
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user