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