From: Timo Sirainen Date: Thu, 30 Oct 2014 20:00:14 +0000 (+0200) Subject: lib: Added lib_atexit_priority() X-Git-Tag: 2.2.16.rc1~259 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=cd7cecf1486532977b417c39f61b10e521e2224a;p=thirdparty%2Fdovecot%2Fcore.git lib: Added lib_atexit_priority() --- diff --git a/src/lib/lib.c b/src/lib/lib.c index 24a980e29b..3d2051c131 100644 --- a/src/lib/lib.c +++ b/src/lib/lib.c @@ -11,7 +11,12 @@ #include #include -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 @@ int close_keep_errno(int *fd) 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 @@ void lib_atexit(lib_atexit_callback_t *callback) /* 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 --git a/src/lib/lib.h b/src/lib/lib.h index 225971cb33..2102d195f2 100644 --- a/src/lib/lib.h +++ b/src/lib/lib.h @@ -44,6 +44,10 @@ typedef void lib_atexit_callback_t(void); #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 @@ int close_keep_errno(int *fd); 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);