dovecot-2.0: ioloop: Added support for per-io/timeout callback l...

dovecot at dovecot.org dovecot at dovecot.org
Fri Dec 3 09:00:20 EET 2010


details:   http://hg.dovecot.org/dovecot-2.0/rev/1bac1c09201a
changeset: 12497:1bac1c09201a
user:      Timo Sirainen <tss at iki.fi>
date:      Fri Dec 03 06:58:38 2010 +0000
description:
ioloop: Added support for per-io/timeout callback log prefix automation.

diffstat:

 src/lib/ioloop-epoll.c    |   13 +---
 src/lib/ioloop-internal.h |   12 ++++
 src/lib/ioloop-kqueue.c   |   13 +---
 src/lib/ioloop-poll.c     |   12 +---
 src/lib/ioloop-select.c   |   10 +---
 src/lib/ioloop.c          |  107 +++++++++++++++++++++++++++++++++++-
 src/lib/ioloop.h          |   11 +++
 7 files changed, 138 insertions(+), 40 deletions(-)

diffs (truncated from 347 to 300 lines):

diff -r 841f56ea9d54 -r 1bac1c09201a src/lib/ioloop-epoll.c
--- a/src/lib/ioloop-epoll.c	Fri Dec 03 06:57:58 2010 +0000
+++ b/src/lib/ioloop-epoll.c	Fri Dec 03 06:58:38 2010 +0000
@@ -170,7 +170,7 @@
 	struct io_list *list;
 	struct io_file *io;
 	struct timeval tv;
-	unsigned int events_count, t_id;
+	unsigned int events_count;
 	int msecs, ret, i, j;
 	bool call;
 
@@ -209,15 +209,8 @@
 			else if ((io->io.condition & IO_ERROR) != 0)
 				call = (event->events & IO_EPOLL_ERROR) != 0;
 
-			if (call) {
-				t_id = t_push();
-				io->io.callback(io->io.context);
-				if (t_pop() != t_id) {
-					i_panic("Leaked a t_pop() call in "
-						"I/O handler %p",
-						(void *)io->io.callback);
-				}
-			}
+			if (call)
+				io_loop_call_io(&io->io);
 		}
 	}
 }
diff -r 841f56ea9d54 -r 1bac1c09201a src/lib/ioloop-internal.h
--- a/src/lib/ioloop-internal.h	Fri Dec 03 06:57:58 2010 +0000
+++ b/src/lib/ioloop-internal.h	Fri Dec 03 06:58:38 2010 +0000
@@ -11,6 +11,9 @@
 struct ioloop {
         struct ioloop *prev;
 
+	struct ioloop_log *cur_log;
+	char *default_log_prefix;
+
 	struct io_file *io_files;
 	struct io_file *next_io_file;
 	struct priorityq *timeouts;
@@ -32,6 +35,7 @@
         void *context;
 
 	struct ioloop *ioloop;
+	struct ioloop_log *log;
 };
 
 struct io_file {
@@ -54,10 +58,18 @@
         void *context;
 
 	struct ioloop *ioloop;
+	struct ioloop_log *log;
+};
+
+struct ioloop_log {
+	int refcount;
+	char *prefix;
+	struct ioloop *ioloop;
 };
 
 int io_loop_get_wait_time(struct ioloop *ioloop, struct timeval *tv_r);
 void io_loop_handle_timeouts(struct ioloop *ioloop);
+void io_loop_call_io(struct io *io);
 
 /* I/O handler calls */
 void io_loop_handle_add(struct io_file *io);
diff -r 841f56ea9d54 -r 1bac1c09201a src/lib/ioloop-kqueue.c
--- a/src/lib/ioloop-kqueue.c	Fri Dec 03 06:57:58 2010 +0000
+++ b/src/lib/ioloop-kqueue.c	Fri Dec 03 06:58:38 2010 +0000
@@ -114,7 +114,7 @@
 	struct timeval tv;
 	struct timespec ts;
 	struct io_file *io;
-	unsigned int events_count, t_id;
+	unsigned int events_count;
 	int ret, i;
 
 	/* get the time left for next timeout task */
@@ -144,15 +144,8 @@
 		io = (void *)event->udata;
 
 		/* callback is NULL if io_remove() was already called */
-		if (io->io.callback != NULL) {
-			t_id = t_push();
-			io->io.callback(io->io.context);
-			if (t_pop() != t_id) {
-				i_panic("Leaked a t_pop() call in "
-					"I/O handler %p",
-					(void *)io->io.callback);
-			}
-		}
+		if (io->io.callback != NULL)
+			io_loop_call_io(&io->io);
 
 		i_assert(io->refcount > 0);
 		if (--io->refcount == 0)
diff -r 841f56ea9d54 -r 1bac1c09201a src/lib/ioloop-poll.c
--- a/src/lib/ioloop-poll.c	Fri Dec 03 06:57:58 2010 +0000
+++ b/src/lib/ioloop-poll.c	Fri Dec 03 06:58:38 2010 +0000
@@ -149,7 +149,6 @@
         struct pollfd *pollfd;
         struct timeval tv;
 	struct io_file *io;
-	unsigned int t_id;
 	int msecs, ret;
 	bool call;
 
@@ -208,15 +207,8 @@
 			if (pollfd->revents == 0)
 				ret--;
 
-			if (call) {
-				t_id = t_push();
-				io->io.callback(io->io.context);
-				if (t_pop() != t_id) {
-					i_panic("Leaked a t_pop() call in "
-						"I/O handler %p",
-						(void *)io->io.callback);
-				}
-			}
+			if (call)
+				io_loop_call_io(&io->io);
 		}
 	}
 }
diff -r 841f56ea9d54 -r 1bac1c09201a src/lib/ioloop-select.c
--- a/src/lib/ioloop-select.c	Fri Dec 03 06:57:58 2010 +0000
+++ b/src/lib/ioloop-select.c	Fri Dec 03 06:58:38 2010 +0000
@@ -108,7 +108,6 @@
 	struct ioloop_handler_context *ctx = ioloop->handler_context;
 	struct timeval tv;
 	struct io_file *io;
-	unsigned int t_id;
 	int ret;
 
 	/* get the time left for next timeout task */
@@ -137,14 +136,7 @@
 
 		if (io_check_condition(ctx, io->fd, io->io.condition)) {
 			ret--;
-
-			t_id = t_push();
-			io->io.callback(io->io.context);
-			if (t_pop() != t_id) {
-				i_panic("Leaked a t_pop() call in "
-					"I/O handler %p",
-					(void *)io->io.callback);
-			}
+			io_loop_call_io(&io->io);
 		}
 	}
 }
diff -r 841f56ea9d54 -r 1bac1c09201a src/lib/ioloop.c
--- a/src/lib/ioloop.c	Fri Dec 03 06:57:58 2010 +0000
+++ b/src/lib/ioloop.c	Fri Dec 03 06:58:38 2010 +0000
@@ -44,6 +44,11 @@
 	io->refcount = 1;
 	io->fd = fd;
 
+	if (io->io.ioloop->cur_log != NULL) {
+		io->io.log = io->io.ioloop->cur_log;
+		io_loop_log_ref(io->io.log);
+	}
+
 	if (io->io.ioloop->handler_context == NULL)
 		io_loop_initialize_handler(io->io.ioloop);
 	io_loop_handle_add(io);
@@ -84,6 +89,9 @@
 	   kqueue code relies on this. */
 	io->callback = NULL;
 
+	if (io->log != NULL)
+		io_loop_log_unref(&io->log);
+
 	if ((io->condition & IO_NOTIFY) != 0)
 		io_loop_notify_remove(io);
 	else {
@@ -142,19 +150,31 @@
 	timeout->callback = callback;
 	timeout->context = context;
 
+	if (timeout->ioloop->cur_log != NULL) {
+		timeout->log = timeout->ioloop->cur_log;
+		io_loop_log_ref(timeout->log);
+	}
+
 	timeout_update_next(timeout, timeout->ioloop->running ?
 			    NULL : &ioloop_timeval);
 	priorityq_add(timeout->ioloop->timeouts, &timeout->item);
 	return timeout;
 }
 
+static void timeout_free(struct timeout *timeout)
+{
+	if (timeout->log != NULL)
+		io_loop_log_unref(&timeout->log);
+	i_free(timeout);
+}
+
 void timeout_remove(struct timeout **_timeout)
 {
 	struct timeout *timeout = *_timeout;
 
 	*_timeout = NULL;
 	priorityq_remove(timeout->ioloop->timeouts, &timeout->item);
-	i_free(timeout);
+	timeout_free(timeout);
 }
 
 static void
@@ -324,12 +344,21 @@
 		/* update timeout's next_run and reposition it in the queue */
 		timeout_reset_timeval(timeout, &tv_call);
 
+		if (timeout->log != NULL) {
+			ioloop->cur_log = timeout->log;
+			io_loop_log_ref(ioloop->cur_log);
+			i_set_failure_prefix(timeout->log->prefix);
+		}
                 t_id = t_push();
 		timeout->callback(timeout->context);
 		if (t_pop() != t_id) {
 			i_panic("Leaked a t_pop() call in timeout handler %p",
 				(void *)timeout->callback);
 		}
+		if (ioloop->cur_log != NULL) {
+			io_loop_log_unref(&ioloop->cur_log);
+			i_set_failure_prefix(ioloop->default_log_prefix);
+		}
 	}
 }
 
@@ -340,11 +369,36 @@
 	} T_END;
 }
 
+void io_loop_call_io(struct io *io)
+{
+	struct ioloop *ioloop = io->ioloop;
+	unsigned int t_id;
+
+	if (io->log != NULL) {
+		ioloop->cur_log = io->log;
+		io_loop_log_ref(ioloop->cur_log);
+		i_set_failure_prefix(io->log->prefix);
+	}
+	t_id = t_push();
+	io->callback(io->context);
+	if (t_pop() != t_id) {
+		i_panic("Leaked a t_pop() call in I/O handler %p",
+			(void *)io->callback);
+	}
+	if (ioloop->cur_log != NULL) {
+		io_loop_log_unref(&ioloop->cur_log);
+		i_set_failure_prefix(ioloop->default_log_prefix);
+	}
+}
+
 void io_loop_run(struct ioloop *ioloop)
 {
 	if (ioloop->handler_context == NULL)
 		io_loop_initialize_handler(ioloop);
 
+	if (ioloop->cur_log != NULL)
+		io_loop_log_unref(&ioloop->cur_log);
+
 	ioloop->running = TRUE;
 	while (ioloop->running)
 		io_loop_handler_run(ioloop);
@@ -438,3 +492,54 @@
 {
 	current_ioloop = ioloop;
 }
+
+struct ioloop_log *io_loop_log_new(struct ioloop *ioloop)
+{
+	struct ioloop_log *log;
+
+	log = i_new(struct ioloop_log, 1);
+	log->refcount = 2;
+	log->prefix = i_strdup("");
+
+	log->ioloop = ioloop;
+	if (ioloop->cur_log != NULL)
+		io_loop_log_unref(&ioloop->cur_log);
+	ioloop->cur_log = log;
+	return log;
+}
+
+void io_loop_log_ref(struct ioloop_log *log)
+{
+	i_assert(log->refcount > 0);
+
+	log->refcount++;
+}
+


More information about the dovecot-cvs mailing list