diff options
-rw-r--r-- | include/git2/atexit.h | 19 | ||||
-rw-r--r-- | src/atexit.c | 47 | ||||
-rw-r--r-- | src/atexit.h | 44 | ||||
-rw-r--r-- | src/global.c | 4 |
4 files changed, 113 insertions, 1 deletions
diff --git a/include/git2/atexit.h b/include/git2/atexit.h new file mode 100644 index 000000000..cab8e1872 --- /dev/null +++ b/include/git2/atexit.h @@ -0,0 +1,19 @@ +/* + * Copyright (C) the libgit2 contributors. All rights reserved. + * + * This file is part of libgit2, distributed under the GNU GPL v2 with + * a Linking Exception. For full terms see the included COPYING file. + */ +#ifndef INCLUDE_git_atexit_h__ +#define INCLUDE_git_atexit_h__ + +#include "common.h" + +/** + * Execute cleanup for in-process operations + * + * This will e.g. delete lockfiles we own. + */ +GIT_EXTERN(int) git_atexit(void); + +#endif /* INCLUDE_git_atexit_h__ */ diff --git a/src/atexit.c b/src/atexit.c new file mode 100644 index 000000000..1e15a15bc --- /dev/null +++ b/src/atexit.c @@ -0,0 +1,47 @@ +/* + * Copyright (C) the libgit2 contributors. All rights reserved. + * + * This file is part of libgit2, distributed under the GNU GPL v2 with + * a Linking Exception. For full terms see the included COPYING file. + */ + +#include "common.h" +#include "vector.h" +#include "atexit.h" + +static git_vector rollbacks; + +int git_atexit_global_init(void) +{ + return git_vector_init(&rollbacks, 0, NULL); +} + +int git__atexit_register(git__atexit *atexit) +{ + return git_vector_insert(&rollbacks, atexit); +} + +int git__atexit_unregister(git__atexit *atexit) +{ + int error; + size_t pos; + + if ((error = git_vector_search(&pos, &rollbacks, atexit)) < 0) + return error; + + return git_vector_remove(&rollbacks, pos); +} + +int git_atexit(void) +{ + size_t i; + int error; + git__atexit *atexit; + + git_vector_foreach(&rollbacks, i, atexit) { + if ((error = atexit->execute(atexit)) < 0) + return error; + } + + return 0; +} diff --git a/src/atexit.h b/src/atexit.h new file mode 100644 index 000000000..9ac9dd74c --- /dev/null +++ b/src/atexit.h @@ -0,0 +1,44 @@ +/* + * Copyright (C) the libgit2 contributors. All rights reserved. + * + * This file is part of libgit2, distributed under the GNU GPL v2 with + * a Linking Exception. For full terms see the included COPYING file. + */ +#ifndef INCLUDE_atexit_h__ +#define INCLUDE_atexit_h__ + +#include "common.h" +#include "git2/atexit.h" + +typedef struct git__atexit git__atexit; + +/** + * The signature of the function which will be called in order to execute this + * rollback. + */ +typedef int (*git__atexit_execute)(git__atexit *atexit); + +/** + * Include this header as the first element in your atexit cancellation + * structure. + */ +struct git__atexit { + /** + * Execute this rollback. This function may be called from any thread. + */ + git__atexit_execute execute; +}; + +/** + * Register a rollback. + */ +int git__atexit_register(git__atexit* atexit); + +/** + * UnRegister a rollback. + */ +int git__atexit_unregister(git__atexit* atexit); + +int git_atexit_global_init(void); + +#endif diff --git a/src/global.c b/src/global.c index 89183080b..853f90270 100644 --- a/src/global.c +++ b/src/global.c @@ -15,6 +15,7 @@ #include "thread-utils.h" #include "git2/global.h" #include "transports/ssh.h" +#include "atexit.h" #if defined(GIT_MSVC_CRTDBG) #include "win32/w32_stack.h" @@ -63,7 +64,8 @@ static int init_common(void) (ret = git_filter_global_init()) == 0 && (ret = git_merge_driver_global_init()) == 0 && (ret = git_transport_ssh_global_init()) == 0 && - (ret = git_openssl_stream_global_init()) == 0) + (ret = git_openssl_stream_global_init()) == 0 && + (ret = git_atexit_global_init() == 0)) ret = git_mwindow_global_init(); GIT_MEMORY_BARRIER; |