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