summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCarlos Martín Nieto <cmn@dwim.me>2016-11-15 13:09:38 +0100
committerCarlos Martín Nieto <cmn@dwim.me>2016-11-15 13:09:38 +0100
commit50f74f4dee47b009086b082890360415effc585a (patch)
treeb2db8b3d78b32bcfb2ca96ce5e23e79ffb45192d
parent03285fdb3fe5997fe914022c1df22ea8bc34cfa3 (diff)
downloadlibgit2-50f74f4dee47b009086b082890360415effc585a.tar.gz
Set cancellations as active for the current thread
-rw-r--r--include/git2/cancellation.h28
-rw-r--r--src/cancellation.c25
-rw-r--r--src/cancellation.h27
-rw-r--r--src/global.h2
4 files changed, 80 insertions, 2 deletions
diff --git a/include/git2/cancellation.h b/include/git2/cancellation.h
index 8c5964697..2223b1784 100644
--- a/include/git2/cancellation.h
+++ b/include/git2/cancellation.h
@@ -72,4 +72,32 @@ GIT_EXTERN(int) git_cancellation_register(git_cancellation *c, git_cancellation_
*/
GIT_EXTERN(int) git_cancellation_request(git_cancellation *c);
+/**
+ * Activate the cancellation for this thread
+ *
+ * Put the cancellation structure in thread-local storage where the next public
+ * function which supports cancellations can make use of it. This overwrites any
+ * cancellation that is currently active.
+ *
+ * The ownership of the cancellation moves to the library. Do not free its
+ * memory after calling this function.
+ *
+ * @param c the cancellation to activate
+ * @return 0
+ */
+GIT_EXTERN(int) git_cancellation_activate(git_cancellation *c);
+
+/**
+ * Deactivate the current cancellation for this thread
+ *
+ * If there is a cancellation set for this thread, remove it from thread-local
+ * storage and free it.
+ *
+ * You can use this after calling into the library to make sure there are no
+ * spurious cancellation triggers.
+ *
+ * @return 0
+ */
+GIT_EXTERN(int) git_cancellation_deactivate(void);
+
#endif
diff --git a/src/cancellation.c b/src/cancellation.c
index eac200804..62e49ba83 100644
--- a/src/cancellation.c
+++ b/src/cancellation.c
@@ -6,16 +6,17 @@
*/
#include "common.h"
+#include "global.h"
#include "array.h"
-#include "git2/cancellation.h"
+#include "cancellation.h"
typedef struct {
git_cancellation_cb cb;
void *payload;
} registration;
-struct git_cancellation {
+struct git_cancellation {
/* Lock over the whole structure */
git_mutex lock;
git_array_t(registration) registrations;
@@ -117,3 +118,23 @@ int git_cancellation_request(git_cancellation *c)
git_mutex_unlock(&c->lock);
return error;
}
+
+int git_cancellation_activate(git_cancellation *c)
+{
+ git_cancellation *old;
+
+ old = git__swap(GIT_GLOBAL->cancellation, c);
+
+ git_cancellation_free(old);
+ return 0;
+}
+
+int git_cancellation_deactivate(void)
+{
+ git_cancellation *old;
+
+ old = git__swap(GIT_GLOBAL->cancellation, NULL);
+
+ git_cancellation_free(old);
+ return 0;
+}
diff --git a/src/cancellation.h b/src/cancellation.h
new file mode 100644
index 000000000..d447e00c6
--- /dev/null
+++ b/src/cancellation.h
@@ -0,0 +1,27 @@
+/*
+ * 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_cancellation_h__
+#define INCLUDE_cancellation_h__
+
+#include "git2/cancellation.h"
+
+#include "global.h"
+
+/**
+ * Check whether there's an active cancellation that's been canceled.
+ */
+GIT_INLINE(bool) git_cancellation__cancelled(void)
+{
+ git_cancellation *c = GIT_GLOBAL->cancellation;
+
+ if (!c)
+ return false;
+
+ return git_cancellation_requested(c);
+}
+
+#endif
diff --git a/src/global.h b/src/global.h
index 219951525..30a616f98 100644
--- a/src/global.h
+++ b/src/global.h
@@ -10,12 +10,14 @@
#include "common.h"
#include "mwindow.h"
#include "hash.h"
+#include "git2/cancellation.h"
typedef struct {
git_error *last_error;
git_error error_t;
git_buf error_buf;
char oid_fmt[GIT_OID_HEXSZ+1];
+ git_cancellation *cancellation;
} git_global_st;
#ifdef GIT_OPENSSL