dovecot-2.2: ioloop: Added io_set_pending()
dovecot at dovecot.org
dovecot at dovecot.org
Thu Apr 3 16:52:23 UTC 2014
details: http://hg.dovecot.org/dovecot-2.2/rev/d2a6f57e174f
changeset: 17187:d2a6f57e174f
user: Timo Sirainen <tss at iki.fi>
date: Thu Apr 03 19:47:49 2014 +0300
description:
ioloop: Added io_set_pending()
diffstat:
src/lib/ioloop-epoll.c | 2 +-
src/lib/ioloop-kqueue.c | 2 +-
src/lib/ioloop-poll.c | 2 +-
src/lib/ioloop-private.h | 7 +++++++
src/lib/ioloop-select.c | 2 +-
src/lib/ioloop.c | 42 ++++++++++++++++++++++++++++++++++++++++++
src/lib/ioloop.h | 6 ++++++
7 files changed, 59 insertions(+), 4 deletions(-)
diffs (182 lines):
diff -r 8328d67e2329 -r d2a6f57e174f src/lib/ioloop-epoll.c
--- a/src/lib/ioloop-epoll.c Thu Apr 03 18:21:39 2014 +0300
+++ b/src/lib/ioloop-epoll.c Thu Apr 03 19:47:49 2014 +0300
@@ -161,7 +161,7 @@
i_free(io);
}
-void io_loop_handler_run(struct ioloop *ioloop)
+void io_loop_handler_run_internal(struct ioloop *ioloop)
{
struct ioloop_handler_context *ctx = ioloop->handler_context;
struct epoll_event *events;
diff -r 8328d67e2329 -r d2a6f57e174f src/lib/ioloop-kqueue.c
--- a/src/lib/ioloop-kqueue.c Thu Apr 03 18:21:39 2014 +0300
+++ b/src/lib/ioloop-kqueue.c Thu Apr 03 19:47:49 2014 +0300
@@ -108,7 +108,7 @@
i_free(io);
}
-void io_loop_handler_run(struct ioloop *ioloop)
+void io_loop_handler_run_internal(struct ioloop *ioloop)
{
struct ioloop_handler_context *ctx = ioloop->handler_context;
struct kevent *events;
diff -r 8328d67e2329 -r d2a6f57e174f src/lib/ioloop-poll.c
--- a/src/lib/ioloop-poll.c Thu Apr 03 18:21:39 2014 +0300
+++ b/src/lib/ioloop-poll.c Thu Apr 03 19:47:49 2014 +0300
@@ -143,7 +143,7 @@
}
}
-void io_loop_handler_run(struct ioloop *ioloop)
+void io_loop_handler_run_internal(struct ioloop *ioloop)
{
struct ioloop_handler_context *ctx = ioloop->handler_context;
struct pollfd *pollfd;
diff -r 8328d67e2329 -r d2a6f57e174f src/lib/ioloop-private.h
--- a/src/lib/ioloop-private.h Thu Apr 03 18:21:39 2014 +0300
+++ b/src/lib/ioloop-private.h Thu Apr 03 19:47:49 2014 +0300
@@ -24,6 +24,8 @@
io_loop_time_moved_callback_t *time_moved_callback;
time_t next_max_time;
+ unsigned int io_pending_count;
+
unsigned int running:1;
unsigned int iolooping:1;
};
@@ -31,6 +33,9 @@
struct io {
enum io_condition condition;
unsigned int source_linenum;
+ /* trigger I/O callback even if OS doesn't think there is input
+ pending */
+ bool pending;
io_callback_t *callback;
void *context;
@@ -79,6 +84,8 @@
void io_loop_handle_timeouts(struct ioloop *ioloop);
void io_loop_call_io(struct io *io);
+void io_loop_handler_run_internal(struct ioloop *ioloop);
+
/* I/O handler calls */
void io_loop_handle_add(struct io_file *io);
void io_loop_handle_remove(struct io_file *io, bool closed);
diff -r 8328d67e2329 -r d2a6f57e174f src/lib/ioloop-select.c
--- a/src/lib/ioloop-select.c Thu Apr 03 18:21:39 2014 +0300
+++ b/src/lib/ioloop-select.c Thu Apr 03 19:47:49 2014 +0300
@@ -103,7 +103,7 @@
(FD_ISSET((fd), &(ctx)->tmp_write_fds) && ((cond) & IO_WRITE)) || \
(FD_ISSET((fd), &(ctx)->tmp_except_fds)))
-void io_loop_handler_run(struct ioloop *ioloop)
+void io_loop_handler_run_internal(struct ioloop *ioloop)
{
struct ioloop_handler_context *ctx = ioloop->handler_context;
struct timeval tv;
diff -r 8328d67e2329 -r d2a6f57e174f src/lib/ioloop.c
--- a/src/lib/ioloop.c Thu Apr 03 18:21:39 2014 +0300
+++ b/src/lib/ioloop.c Thu Apr 03 19:47:49 2014 +0300
@@ -93,6 +93,11 @@
kqueue code relies on this. */
io->callback = NULL;
+ if (io->pending) {
+ i_assert(io->ioloop->io_pending_count > 0);
+ io->ioloop->io_pending_count--;
+ }
+
if (io->ctx != NULL)
io_loop_context_unref(&io->ctx);
@@ -118,6 +123,16 @@
io_remove_full(io, TRUE);
}
+void io_set_pending(struct io *io)
+{
+ i_assert((io->condition & IO_NOTIFY) == 0);
+
+ if (!io->pending) {
+ io->pending = TRUE;
+ io->ioloop->io_pending_count++;
+ }
+}
+
static void timeout_update_next(struct timeout *timeout, struct timeval *tv_now)
{
if (tv_now == NULL) {
@@ -382,6 +397,12 @@
struct ioloop *ioloop = io->ioloop;
unsigned int t_id;
+ if (io->pending) {
+ i_assert(ioloop->io_pending_count > 0);
+ ioloop->io_pending_count--;
+ io->pending = FALSE;
+ }
+
if (io->ctx != NULL)
io_loop_context_activate(io->ctx);
t_id = t_push();
@@ -413,6 +434,24 @@
ioloop->iolooping = FALSE;
}
+static void io_loop_call_pending(struct ioloop *ioloop)
+{
+ struct io_file *io;
+
+ for (io = ioloop->io_files; ioloop->io_pending_count > 0; ) {
+ ioloop->next_io_file = io->next;
+ if (io->io.pending)
+ io_loop_call_io(&io->io);
+ io = ioloop->next_io_file;
+ }
+}
+
+void io_loop_handler_run(struct ioloop *ioloop)
+{
+ io_loop_handler_run_internal(ioloop);
+ io_loop_call_pending(ioloop);
+}
+
void io_loop_stop(struct ioloop *ioloop)
{
ioloop->running = FALSE;
@@ -484,6 +523,7 @@
io->io.source_linenum, io->fd);
io_remove(&_io);
}
+ i_assert(ioloop->io_pending_count == 0);
while ((item = priorityq_pop(ioloop->timeouts)) != NULL) {
struct timeout *to = (struct timeout *)item;
@@ -686,6 +726,8 @@
new_io = io_add(old_io_file->fd, old_io->condition,
old_io->source_linenum,
old_io->callback, old_io->context);
+ if (old_io->pending)
+ io_set_pending(new_io);
io_remove(_io);
return new_io;
}
diff -r 8328d67e2329 -r d2a6f57e174f src/lib/ioloop.h
--- a/src/lib/ioloop.h Thu Apr 03 18:21:39 2014 +0300
+++ b/src/lib/ioloop.h Thu Apr 03 19:47:49 2014 +0300
@@ -67,6 +67,12 @@
With some backends this simply frees the memory. */
void io_remove_closed(struct io **io);
+/* Make sure the I/O callback is called by io_loop_run() even if there isn't
+ any input actually pending currently as seen by the OS. This may be useful
+ if some of the input has already read into some internal buffer and the
+ caller wants to handle it the same way as if the fd itself had input. */
+void io_set_pending(struct io *io);
+
/* Timeout handlers */
struct timeout *
timeout_add(unsigned int msecs, unsigned int source_linenum,
More information about the dovecot-cvs
mailing list