summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCarlos Martín Nieto <cmn@dwim.me>2014-12-05 07:09:08 +0100
committerCarlos Martín Nieto <cmn@dwim.me>2014-12-05 07:09:08 +0100
commite79fbd9e8aafab6eb58a6e60b55291487232570c (patch)
treeee7ffb241585e9ed2aefe711eceb7b5ca82444f4
parent8bfbe6988fe749a4970613db371a214f18fc5c9b (diff)
parent6d91dc53514aa9eec4bdf2326d1f7657ac2426b3 (diff)
downloadlibgit2-e79fbd9e8aafab6eb58a6e60b55291487232570c.tar.gz
Merge pull request #2743 from ethomson/init_val
init: return the number of initializations
-rw-r--r--CHANGELOG.md4
-rw-r--r--include/git2/global.h14
-rw-r--r--src/global.c44
-rw-r--r--tests/core/init.c14
4 files changed, 58 insertions, 18 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 4b9d92442..7bc40c511 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -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.
diff --git a/include/git2/global.h b/include/git2/global.h
index 4f90c4c20..ce5bdf444 100644
--- a/include/git2/global.h
+++ b/include/git2/global.h
@@ -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
diff --git a/src/global.c b/src/global.c
index 067872d44..b09e6df02 100644
--- a/src/global.c
+++ b/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)
diff --git a/tests/core/init.c b/tests/core/init.c
new file mode 100644
index 000000000..e17b7845f
--- /dev/null
+++ b/tests/core/init.c
@@ -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());
+}
+