dovecot-2.2: liblib: Added lib_atexit() to register process dein...

dovecot at dovecot.org dovecot at dovecot.org
Tue Nov 27 00:44:46 EET 2012


details:   http://hg.dovecot.org/dovecot-2.2/rev/2aef2557bdf1
changeset: 15416:2aef2557bdf1
user:      Timo Sirainen <tss at iki.fi>
date:      Tue Nov 27 00:43:23 2012 +0200
description:
liblib: Added lib_atexit() to register process deinit callbacks.

diffstat:

 src/lib/lib.c |  53 +++++++++++++++++++++++++++++++++++++++++------------
 src/lib/lib.h |   8 ++++++++
 2 files changed, 49 insertions(+), 12 deletions(-)

diffs (111 lines):

diff -r 8f0994194f45 -r 2aef2557bdf1 src/lib/lib.c
--- a/src/lib/lib.c	Tue Nov 27 00:31:40 2012 +0200
+++ b/src/lib/lib.c	Tue Nov 27 00:43:23 2012 +0200
@@ -1,6 +1,7 @@
 /* Copyright (c) 2001-2012 Dovecot authors, see the included COPYING file */
 
 #include "lib.h"
+#include "array.h"
 #include "env-util.h"
 #include "hostpid.h"
 #include "ipwd.h"
@@ -10,6 +11,8 @@
 #include <unistd.h>
 #include <sys/time.h>
 
+static ARRAY(lib_atexit_callback_t *) atexit_callbacks = ARRAY_INIT;
+
 size_t nearest_power(size_t num)
 {
 	size_t n = 1;
@@ -20,6 +23,36 @@
 	return n;
 }
 
+int close_keep_errno(int *fd)
+{
+	int ret, old_errno = errno;
+
+	i_assert(*fd != -1);
+
+	ret = close(*fd);
+	*fd = -1;
+	errno = old_errno;
+	return ret;
+}
+
+void lib_atexit(lib_atexit_callback_t *callback)
+{
+	lib_atexit_callback_t *const *callbacks;
+	unsigned int i, count;
+
+	if (!array_is_created(&atexit_callbacks))
+		i_array_init(&atexit_callbacks, 8);
+	else {
+		/* skip if it's already added */
+		callbacks = array_get(&atexit_callbacks, &count);
+		for (i = count; i > 0; i--) {
+			if (callbacks[i-1] == callback)
+				return;
+		}
+	}
+	array_append(&atexit_callbacks, &callback, 1);
+}
+
 void lib_init(void)
 {
 	struct timeval tv;
@@ -33,20 +66,16 @@
 	hostpid_init();
 }
 
-int close_keep_errno(int *fd)
-{
-	int ret, old_errno = errno;
-
-	i_assert(*fd != -1);
-
-	ret = close(*fd);
-	*fd = -1;
-	errno = old_errno;
-	return ret;
-}
-
 void lib_deinit(void)
 {
+	lib_atexit_callback_t *const *cbp;
+
+	if (array_is_created(&atexit_callbacks)) {
+		array_foreach(&atexit_callbacks, cbp)
+			(**cbp)();
+		array_free(&atexit_callbacks);
+	}
+
 	ipwd_deinit();
 	data_stack_deinit();
 	env_deinit();
diff -r 8f0994194f45 -r 2aef2557bdf1 src/lib/lib.h
--- a/src/lib/lib.h	Tue Nov 27 00:31:40 2012 +0200
+++ b/src/lib/lib.h	Tue Nov 27 00:43:23 2012 +0200
@@ -35,6 +35,8 @@
 struct istream;
 struct ostream;
 
+typedef void lib_atexit_callback_t(void);
+
 #include "array-decl.h" /* ARRAY*()s may exist in any header */
 #include "hash-decl.h" /* HASH_TABLE*()s may exist in any header */
 #include "strfuncs.h"
@@ -43,6 +45,12 @@
 size_t nearest_power(size_t num) ATTR_CONST;
 int close_keep_errno(int *fd);
 
+/* Call the given callback at the beginning of lib_deinit(). The main
+   difference to atexit() is that liblib's memory allocation and logging
+   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);
+
 void lib_init(void);
 void lib_deinit(void);
 


More information about the dovecot-cvs mailing list