mirror of
https://git.proxmox.com/git/libgit2
synced 2025-05-09 20:29:27 +00:00
Merge pull request #2743 from ethomson/init_val
init: return the number of initializations
This commit is contained in:
commit
e79fbd9e8a
@ -126,3 +126,7 @@ v0.21 + 1
|
||||
* git_threads_init() and git_threads_shutdown() have been renamed to
|
||||
git_libgit2_init() and git_libgit2_shutdown() to better explain what
|
||||
their purpose is, as it's grown to be more than just about threads.
|
||||
|
||||
* git_libgit2_init() and git_libgit2_shutdown() now return the number of
|
||||
initializations of the library, so consumers may schedule work on the
|
||||
first initialization.
|
||||
|
@ -17,9 +17,11 @@ GIT_BEGIN_DECL
|
||||
* This function must the called before any other libgit2 function in
|
||||
* order to set up global state and threading.
|
||||
*
|
||||
* This function may be called multiple times.
|
||||
* This function may be called multiple times - it will return the number
|
||||
* of times the initialization has been called (including this one) that have
|
||||
* not subsequently been shutdown.
|
||||
*
|
||||
* @return 0 or an error code
|
||||
* @return the number of initializations of the library, or an error code.
|
||||
*/
|
||||
GIT_EXTERN(int) git_libgit2_init(void);
|
||||
|
||||
@ -27,10 +29,14 @@ GIT_EXTERN(int) git_libgit2_init(void);
|
||||
* Shutdown the global state
|
||||
*
|
||||
* Clean up the global state and threading context after calling it as
|
||||
* many times as `git_libgit2_init()` was called.
|
||||
* many times as `git_libgit2_init()` was called - it will return the
|
||||
* number of remainining initializations that have not been shutdown
|
||||
* (after this one).
|
||||
*
|
||||
* @return the number of remaining initializations of the library, or an
|
||||
* error code.
|
||||
*/
|
||||
GIT_EXTERN(void) git_libgit2_shutdown(void);
|
||||
GIT_EXTERN(int) git_libgit2_shutdown(void);
|
||||
|
||||
/** @} */
|
||||
GIT_END_DECL
|
||||
|
44
src/global.c
44
src/global.c
@ -195,19 +195,21 @@ static int synchronized_threads_init(void)
|
||||
|
||||
int git_libgit2_init(void)
|
||||
{
|
||||
int error = 0;
|
||||
int ret;
|
||||
|
||||
/* Enter the lock */
|
||||
while (InterlockedCompareExchange(&_mutex, 1, 0)) { Sleep(0); }
|
||||
|
||||
/* Only do work on a 0 -> 1 transition of the refcount */
|
||||
if (1 == git_atomic_inc(&git__n_inits))
|
||||
error = synchronized_threads_init();
|
||||
if ((ret = git_atomic_inc(&git__n_inits)) == 1) {
|
||||
if (synchronized_threads_init() < 0)
|
||||
ret = -1;
|
||||
}
|
||||
|
||||
/* Exit the lock */
|
||||
InterlockedExchange(&_mutex, 0);
|
||||
|
||||
return error;
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void synchronized_threads_shutdown(void)
|
||||
@ -218,17 +220,21 @@ static void synchronized_threads_shutdown(void)
|
||||
git_mutex_free(&git__mwindow_mutex);
|
||||
}
|
||||
|
||||
void git_libgit2_shutdown(void)
|
||||
int git_libgit2_shutdown(void)
|
||||
{
|
||||
int ret;
|
||||
|
||||
/* Enter the lock */
|
||||
while (InterlockedCompareExchange(&_mutex, 1, 0)) { Sleep(0); }
|
||||
|
||||
/* Only do work on a 1 -> 0 transition of the refcount */
|
||||
if (0 == git_atomic_dec(&git__n_inits))
|
||||
if ((ret = git_atomic_dec(&git__n_inits)) == 0)
|
||||
synchronized_threads_shutdown();
|
||||
|
||||
/* Exit the lock */
|
||||
InterlockedExchange(&_mutex, 0);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
git_global_st *git__global_state(void)
|
||||
@ -282,17 +288,22 @@ static void init_once(void)
|
||||
|
||||
int git_libgit2_init(void)
|
||||
{
|
||||
int ret;
|
||||
|
||||
pthread_once(&_once_init, init_once);
|
||||
git_atomic_inc(&git__n_inits);
|
||||
return init_error;
|
||||
ret = git_atomic_inc(&git__n_inits);
|
||||
|
||||
return init_error ? init_error : ret;
|
||||
}
|
||||
|
||||
void git_libgit2_shutdown(void)
|
||||
int git_libgit2_shutdown(void)
|
||||
{
|
||||
void *ptr = NULL;
|
||||
pthread_once_t new_once = PTHREAD_ONCE_INIT;
|
||||
int ret;
|
||||
|
||||
if (git_atomic_dec(&git__n_inits) > 0) return;
|
||||
if ((ret = git_atomic_dec(&git__n_inits)) > 0)
|
||||
return ret;
|
||||
|
||||
/* Shut down any subsystems that have global state */
|
||||
git__shutdown();
|
||||
@ -304,6 +315,8 @@ void git_libgit2_shutdown(void)
|
||||
pthread_key_delete(_tls_key);
|
||||
git_mutex_free(&git__mwindow_mutex);
|
||||
_once_init = new_once;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
git_global_st *git__global_state(void)
|
||||
@ -337,15 +350,18 @@ int git_libgit2_init(void)
|
||||
ssl_inited = 1;
|
||||
}
|
||||
|
||||
git_atomic_inc(&git__n_inits);
|
||||
return 0;
|
||||
return git_atomic_inc(&git__n_inits);
|
||||
}
|
||||
|
||||
void git_libgit2_shutdown(void)
|
||||
int git_libgit2_shutdown(void)
|
||||
{
|
||||
int ret;
|
||||
|
||||
/* Shut down any subsystems that have global state */
|
||||
if (0 == git_atomic_dec(&git__n_inits))
|
||||
if (ret = git_atomic_dec(&git__n_inits))
|
||||
git__shutdown();
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
git_global_st *git__global_state(void)
|
||||
|
14
tests/core/init.c
Normal file
14
tests/core/init.c
Normal file
@ -0,0 +1,14 @@
|
||||
#include "clar_libgit2.h"
|
||||
|
||||
void test_core_init__returns_count(void)
|
||||
{
|
||||
/* libgit2_clar initializes us first, so we have an existing
|
||||
* initialization.
|
||||
*/
|
||||
cl_assert_equal_i(2, git_libgit2_init());
|
||||
cl_assert_equal_i(3, git_libgit2_init());
|
||||
|
||||
cl_assert_equal_i(2, git_libgit2_shutdown());
|
||||
cl_assert_equal_i(1, git_libgit2_shutdown());
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user