]> git.proxmox.com Git - libgit2.git/commitdiff
init: return the number of initializations
authorEdward Thomson <ethomson@microsoft.com>
Wed, 3 Dec 2014 20:28:44 +0000 (15:28 -0500)
committerEdward Thomson <ethomson@microsoft.com>
Fri, 5 Dec 2014 01:42:27 +0000 (20:42 -0500)
CHANGELOG.md
include/git2/global.h
src/global.c
tests/core/init.c [new file with mode: 0644]

index 4b9d9244215f4621130fff1f02bc3d1700a8725d..7bc40c511843095d7cd13fec73d540cebca70dee 100644 (file)
@@ -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.
index 4f90c4c2040c92cf9824d68be70ee15ca65344b2..ce5bdf444060a9e28e2316fa168b6b488fc0b0b0 100644 (file)
@@ -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
index 006202a2cc9c5afbf2f7ef28ceb3a4852331fb61..b3e75a0e267aa48e41b0076fb30b75a05751bc6e 100644 (file)
@@ -194,19 +194,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)
@@ -217,17 +219,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)
@@ -281,17 +287,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();
@@ -303,6 +314,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)
@@ -336,15 +349,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 (file)
index 0000000..e17b784
--- /dev/null
@@ -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());
+}
+