dovecot-2.2: Added io_loop_add/remove_switch_callback() to call ...

dovecot at dovecot.org dovecot at dovecot.org
Sun Nov 17 01:04:58 EET 2013


details:   http://hg.dovecot.org/dovecot-2.2/rev/54eb87b7761c
changeset: 16969:54eb87b7761c
user:      Timo Sirainen <tss at iki.fi>
date:      Sun Nov 17 01:04:50 2013 +0200
description:
Added io_loop_add/remove_switch_callback() to call a callback when ioloop is changed.

diffstat:

 src/lib/ioloop.c |  45 +++++++++++++++++++++++++++++++++++++++++----
 src/lib/ioloop.h |   4 ++++
 2 files changed, 45 insertions(+), 4 deletions(-)

diffs (100 lines):

diff -r 3937b2e39963 -r 54eb87b7761c src/lib/ioloop.c
--- a/src/lib/ioloop.c	Sun Nov 17 01:01:50 2013 +0200
+++ b/src/lib/ioloop.c	Sun Nov 17 01:04:50 2013 +0200
@@ -16,6 +16,7 @@
 struct timeval ioloop_timeval;
 
 struct ioloop *current_ioloop = NULL;
+static ARRAY(io_switch_callback_t *) io_switch_callbacks = ARRAY_INIT;
 
 static void io_loop_initialize_handler(struct ioloop *ioloop)
 {
@@ -467,6 +468,10 @@
 
 	*_ioloop = NULL;
 
+	/* ->prev won't work unless loops are destroyed in create order */
+        i_assert(ioloop == current_ioloop);
+	io_loop_set_current(current_ioloop->prev);
+
 	if (ioloop->notify_handler_context != NULL)
 		io_loop_notify_handler_deinit(ioloop);
 
@@ -495,10 +500,6 @@
 	if (ioloop->cur_ctx != NULL)
 		io_loop_context_deactivate(ioloop->cur_ctx);
 
-	/* ->prev won't work unless loops are destroyed in create order */
-        i_assert(ioloop == current_ioloop);
-	io_loop_set_current(current_ioloop->prev);
-
 	i_free(ioloop);
 }
 
@@ -508,9 +509,45 @@
 	ioloop->time_moved_callback = callback;
 }
 
+static void io_switch_callbacks_free(void)
+{
+	array_free(&io_switch_callbacks);
+}
+
 void io_loop_set_current(struct ioloop *ioloop)
 {
+	io_switch_callback_t *const *callbackp;
+	struct ioloop *prev_ioloop = current_ioloop;
+
 	current_ioloop = ioloop;
+	if (array_is_created(&io_switch_callbacks)) {
+		array_foreach(&io_switch_callbacks, callbackp)
+			(*callbackp)(prev_ioloop);
+	}
+}
+
+void io_loop_add_switch_callback(io_switch_callback_t *callback)
+{
+	if (!array_is_created(&io_switch_callbacks)) {
+		i_array_init(&io_switch_callbacks, 4);
+		lib_atexit(io_switch_callbacks_free);
+	}
+	array_append(&io_switch_callbacks, &callback, 1);
+}
+
+void io_loop_remove_switch_callback(io_switch_callback_t *callback)
+{
+	io_switch_callback_t *const *callbackp;
+	unsigned int idx;
+
+	array_foreach(&io_switch_callbacks, callbackp) {
+		if (*callbackp == callback) {
+			idx = array_foreach_idx(&io_switch_callbacks, callbackp);
+			array_delete(&io_switch_callbacks, idx, 1);
+			return;
+		}
+	}
+	i_unreached();
 }
 
 struct ioloop_context *io_loop_context_new(struct ioloop *ioloop)
diff -r 3937b2e39963 -r 54eb87b7761c src/lib/ioloop.h
--- a/src/lib/ioloop.h	Sun Nov 17 01:01:50 2013 +0200
+++ b/src/lib/ioloop.h	Sun Nov 17 01:04:50 2013 +0200
@@ -32,6 +32,7 @@
 typedef void io_callback_t(void *context);
 typedef void timeout_callback_t(void *context);
 typedef void io_loop_time_moved_callback_t(time_t old_time, time_t new_time);
+typedef void io_switch_callback_t(struct ioloop *prev_ioloop);
 
 /* Time when the I/O loop started calling handlers.
    Can be used instead of time(NULL). */
@@ -112,6 +113,9 @@
 
 /* Change the current_ioloop. */
 void io_loop_set_current(struct ioloop *ioloop);
+/* Call the callback whenever ioloop is changed. */
+void io_loop_add_switch_callback(io_switch_callback_t *callback);
+void io_loop_remove_switch_callback(io_switch_callback_t *callback);
 
 /* This context is used for all further I/O and timeout callbacks that are
    added until returning to ioloop. When a callback is called, this context is


More information about the dovecot-cvs mailing list