dovecot-2.2: lib: Added lib_atexit_priority()

dovecot at dovecot.org dovecot at dovecot.org
Thu Oct 30 20:04:00 UTC 2014


details:   http://hg.dovecot.org/dovecot-2.2/rev/54eb3436c83b
changeset: 18047:54eb3436c83b
user:      Timo Sirainen <tss at iki.fi>
date:      Thu Oct 30 22:00:14 2014 +0200
description:
lib: Added lib_atexit_priority()

diffstat:

 src/lib/lib.c |  36 +++++++++++++++++++++++++++++-------
 src/lib/lib.h |   7 +++++++
 2 files changed, 36 insertions(+), 7 deletions(-)

diffs (93 lines):

diff -r 53613f102450 -r 54eb3436c83b src/lib/lib.c
--- a/src/lib/lib.c	Thu Oct 30 04:41:11 2014 +0200
+++ b/src/lib/lib.c	Thu Oct 30 22:00:14 2014 +0200
@@ -11,7 +11,12 @@
 #include <unistd.h>
 #include <sys/time.h>
 
-static ARRAY(lib_atexit_callback_t *) atexit_callbacks = ARRAY_INIT;
+struct atexit_callback {
+	int priority;
+	lib_atexit_callback_t *callback;
+};
+
+static ARRAY(struct atexit_callback) atexit_callbacks = ARRAY_INIT;
 
 int close_keep_errno(int *fd)
 {
@@ -27,7 +32,13 @@
 
 void lib_atexit(lib_atexit_callback_t *callback)
 {
-	lib_atexit_callback_t *const *callbacks;
+	lib_atexit_priority(callback, 0);
+}
+
+void lib_atexit_priority(lib_atexit_callback_t *callback, int priority)
+{
+	struct atexit_callback *cb;
+	const struct atexit_callback *callbacks;
 	unsigned int i, count;
 
 	if (!array_is_created(&atexit_callbacks))
@@ -36,20 +47,31 @@
 		/* skip if it's already added */
 		callbacks = array_get(&atexit_callbacks, &count);
 		for (i = count; i > 0; i--) {
-			if (callbacks[i-1] == callback)
+			if (callbacks[i-1].callback == callback) {
+				i_assert(callbacks[i-1].priority == priority);
 				return;
+			}
 		}
 	}
-	array_append(&atexit_callbacks, &callback, 1);
+	cb = array_append_space(&atexit_callbacks);
+	cb->priority = priority;
+	cb->callback = callback;
+}
+
+static int atexit_callback_priority_cmp(const struct atexit_callback *cb1,
+					const struct atexit_callback *cb2)
+{
+	return cb1->priority - cb2->priority;
 }
 
 void lib_atexit_run(void)
 {
-	lib_atexit_callback_t *const *cbp;
+	const struct atexit_callback *cb;
 
 	if (array_is_created(&atexit_callbacks)) {
-		array_foreach(&atexit_callbacks, cbp)
-			(**cbp)();
+		array_sort(&atexit_callbacks, atexit_callback_priority_cmp);
+		array_foreach(&atexit_callbacks, cb)
+			(*cb->callback)();
 		array_free(&atexit_callbacks);
 	}
 }
diff -r 53613f102450 -r 54eb3436c83b src/lib/lib.h
--- a/src/lib/lib.h	Thu Oct 30 04:41:11 2014 +0200
+++ b/src/lib/lib.h	Thu Oct 30 22:00:14 2014 +0200
@@ -44,6 +44,10 @@
 #include "strfuncs.h"
 #include "strnum.h"
 
+#define LIB_ATEXIT_PRIORITY_HIGH -10
+#define LIB_ATEXIT_PRIORITY_DEFAULT 0
+#define LIB_ATEXIT_PRIORITY_LOW 10
+
 int close_keep_errno(int *fd);
 
 /* Call the given callback at the beginning of lib_deinit(). The main
@@ -51,6 +55,9 @@
    functions are still available. Also if lib_atexit() is called multiple times
    to the same callback, it's added only once. */
 void lib_atexit(lib_atexit_callback_t *callback);
+/* Specify the order in which the callback is called. Lowest numbered
+   priorities are called first. lib_atexit() is called with priority=0. */
+void lib_atexit_priority(lib_atexit_callback_t *callback, int priority);
 /* Manually run the atexit callbacks. lib_deinit() also does this if not
    explicitly called. */
 void lib_atexit_run(void);


More information about the dovecot-cvs mailing list