changeset 8366:2c111b572eee HEAD

Don't break if io_remove() or timeout_remove() are called for non-active ioloops.
author Timo Sirainen <tss@iki.fi>
date Sat, 01 Nov 2008 14:14:42 +0200
parents f97099eb4dee
children 0d49326397b4
files src/lib/ioloop-epoll.c src/lib/ioloop-internal.h src/lib/ioloop-kqueue.c src/lib/ioloop-notify-dn.c src/lib/ioloop-notify-fd.c src/lib/ioloop-notify-inotify.c src/lib/ioloop-notify-kqueue.c src/lib/ioloop-notify-none.c src/lib/ioloop-poll.c src/lib/ioloop-select.c src/lib/ioloop.c src/lib/ioloop.h
diffstat 12 files changed, 63 insertions(+), 53 deletions(-) [+]
line wrap: on
line diff
--- a/src/lib/ioloop-epoll.c	Fri Oct 24 16:06:07 2008 +0200
+++ b/src/lib/ioloop-epoll.c	Sat Nov 01 14:14:42 2008 +0200
@@ -83,9 +83,9 @@
 	return events;
 }
 
-void io_loop_handle_add(struct ioloop *ioloop, struct io_file *io)
+void io_loop_handle_add(struct io_file *io)
 {
-	struct ioloop_handler_context *ctx = ioloop->handler_context;
+	struct ioloop_handler_context *ctx = io->io.ioloop->handler_context;
 	struct io_list **list;
 	struct epoll_event event;
 	int op;
@@ -118,10 +118,9 @@
 	}
 }
 
-void io_loop_handle_remove(struct ioloop *ioloop, struct io_file *io,
-			   bool closed)
+void io_loop_handle_remove(struct io_file *io, bool closed)
 {
-	struct ioloop_handler_context *ctx = ioloop->handler_context;
+	struct ioloop_handler_context *ctx = io->io.ioloop->handler_context;
 	struct io_list **list;
 	struct epoll_event event;
 	int op;
--- a/src/lib/ioloop-internal.h	Fri Oct 24 16:06:07 2008 +0200
+++ b/src/lib/ioloop-internal.h	Sat Nov 01 14:14:42 2008 +0200
@@ -26,6 +26,8 @@
 
 	io_callback_t *callback;
         void *context;
+
+	struct ioloop *ioloop;
 };
 
 struct io_file {
@@ -46,6 +48,8 @@
 
 	timeout_callback_t *callback;
         void *context;
+
+	struct ioloop *ioloop;
 };
 
 int io_loop_get_wait_time(struct ioloop *ioloop, struct timeval *tv_r,
@@ -53,14 +57,13 @@
 void io_loop_handle_timeouts(struct ioloop *ioloop);
 
 /* I/O handler calls */
-void io_loop_handle_add(struct ioloop *ioloop, struct io_file *io);
-void io_loop_handle_remove(struct ioloop *ioloop, struct io_file *io,
-			   bool closed);
+void io_loop_handle_add(struct io_file *io);
+void io_loop_handle_remove(struct io_file *io, bool closed);
 
 void io_loop_handler_init(struct ioloop *ioloop);
 void io_loop_handler_deinit(struct ioloop *ioloop);
 
-void io_loop_notify_remove(struct ioloop *ioloop, struct io *io);
+void io_loop_notify_remove(struct io *io);
 void io_loop_notify_handler_deinit(struct ioloop *ioloop);
 
 #endif
--- a/src/lib/ioloop-kqueue.c	Fri Oct 24 16:06:07 2008 +0200
+++ b/src/lib/ioloop-kqueue.c	Sat Nov 01 14:14:42 2008 +0200
@@ -56,9 +56,9 @@
 	i_free(ioloop->handler_context);
 }
 
-void io_loop_handle_add(struct ioloop *ioloop, struct io_file *io)
+void io_loop_handle_add(struct io_file *io)
 {
-	struct ioloop_handler_context *ctx = ioloop->handler_context;
+	struct ioloop_handler_context *ctx = io->io.ioloop->handler_context;
 	struct kevent ev;
 
 	if ((io->io.condition & (IO_READ | IO_ERROR)) != 0) {
@@ -80,10 +80,9 @@
 		(void)array_append_space(&ctx->events);
 }
 
-void io_loop_handle_remove(struct ioloop *ioloop, struct io_file *io,
-			   bool closed)
+void io_loop_handle_remove(struct io_file *io, bool closed)
 {
-	struct ioloop_handler_context *ctx = ioloop->handler_context;
+	struct ioloop_handler_context *ctx = io->io.ioloop->handler_context;
 	struct kevent ev;
 
 	if ((io->io.condition & (IO_READ | IO_ERROR)) != 0 && !closed) {
--- a/src/lib/ioloop-notify-dn.c	Fri Oct 24 16:06:07 2008 +0200
+++ b/src/lib/ioloop-notify-dn.c	Sat Nov 01 14:14:42 2008 +0200
@@ -148,10 +148,10 @@
 	return IO_NOTIFY_ADDED;
 }
 
-void io_loop_notify_remove(struct ioloop *ioloop, struct io *_io)
+void io_loop_notify_remove(struct io *_io)
 {
 	struct ioloop_notify_handler_context *ctx =
-		ioloop->notify_handler_context;
+		_io->ioloop->notify_handler_context;
 	struct io_notify *io = (struct io_notify *)_io;
 
 	if (fcntl(io->fd, F_NOTIFY, 0) < 0)
--- a/src/lib/ioloop-notify-fd.c	Fri Oct 24 16:06:07 2008 +0200
+++ b/src/lib/ioloop-notify-fd.c	Sat Nov 01 14:14:42 2008 +0200
@@ -15,6 +15,7 @@
 	io->io.condition = IO_NOTIFY;
 	io->io.callback = callback;
 	io->io.context = context;
+	io->io.ioloop = current_ioloop;
 	io->fd = fd;
 
 	if (ctx->notifies != NULL) {
--- a/src/lib/ioloop-notify-inotify.c	Fri Oct 24 16:06:07 2008 +0200
+++ b/src/lib/ioloop-notify-inotify.c	Sat Nov 01 14:14:42 2008 +0200
@@ -120,10 +120,10 @@
 	return IO_NOTIFY_ADDED;
 }
 
-void io_loop_notify_remove(struct ioloop *ioloop, struct io *_io)
+void io_loop_notify_remove(struct io *_io)
 {
 	struct ioloop_notify_handler_context *ctx =
-		ioloop->notify_handler_context;
+		_io->ioloop->notify_handler_context;
 	struct io_notify *io = (struct io_notify *)_io;
 
 	if (io->fd != -1) {
--- a/src/lib/ioloop-notify-kqueue.c	Fri Oct 24 16:06:07 2008 +0200
+++ b/src/lib/ioloop-notify-kqueue.c	Sat Nov 01 14:14:42 2008 +0200
@@ -130,6 +130,7 @@
 	io->io.condition = IO_NOTIFY;
 	io->io.callback = callback;
 	io->io.context = context;
+	io->io.ioloop = current_ioloop;
 	io->refcount = 1;
 	io->fd = fd;
 
@@ -147,16 +148,16 @@
 
 	if (ctx->event_io == NULL) {
 		ctx->event_io = io_add(ctx->kq, IO_READ, event_callback,
-				       current_ioloop->notify_handler_context);
+				       io->io.ioloop->notify_handler_context);
 	}
 	*io_r = &io->io;
 	return IO_NOTIFY_ADDED;
 }
 
-void io_loop_notify_remove(struct ioloop *ioloop, struct io *_io)
+void io_loop_notify_remove(struct io *_io)
 {
 	struct ioloop_notify_handler_context *ctx =
-		ioloop->notify_handler_context;
+		_io->ioloop->notify_handler_context;
 	struct io_notify *io = (struct io_notify *)_io;
 	struct kevent ev;
 
--- a/src/lib/ioloop-notify-none.c	Fri Oct 24 16:06:07 2008 +0200
+++ b/src/lib/ioloop-notify-none.c	Sat Nov 01 14:14:42 2008 +0200
@@ -15,8 +15,7 @@
 	return IO_NOTIFY_NOSUPPORT;
 }
 
-void io_loop_notify_remove(struct ioloop *ioloop ATTR_UNUSED,
-			   struct io *io ATTR_UNUSED)
+void io_loop_notify_remove(struct io *io ATTR_UNUSED)
 {
 }
 
--- a/src/lib/ioloop-poll.c	Fri Oct 24 16:06:07 2008 +0200
+++ b/src/lib/ioloop-poll.c	Sat Nov 01 14:14:42 2008 +0200
@@ -42,9 +42,9 @@
 #define IO_POLL_INPUT (POLLIN | POLLPRI | IO_POLL_ERROR)
 #define IO_POLL_OUTPUT (POLLOUT | IO_POLL_ERROR)
 
-void io_loop_handle_add(struct ioloop *ioloop, struct io_file *io)
+void io_loop_handle_add(struct io_file *io)
 {
-	struct ioloop_handler_context *ctx = ioloop->handler_context;
+	struct ioloop_handler_context *ctx = io->io.ioloop->handler_context;
 	enum io_condition condition = io->io.condition;
 	unsigned int old_count;
 	int index, fd = io->fd;
@@ -94,10 +94,9 @@
 		ctx->fds[index].events |= IO_POLL_ERROR;
 }
 
-void io_loop_handle_remove(struct ioloop *ioloop,  struct io_file *io,
-			   bool closed ATTR_UNUSED)
+void io_loop_handle_remove(struct io_file *io, bool closed ATTR_UNUSED)
 {
-	struct ioloop_handler_context *ctx = ioloop->handler_context;
+	struct ioloop_handler_context *ctx = io->io.ioloop->handler_context;
 	enum io_condition condition = io->io.condition;
 	int index, fd = io->fd;
 
--- a/src/lib/ioloop-select.c	Fri Oct 24 16:06:07 2008 +0200
+++ b/src/lib/ioloop-select.c	Sat Nov 01 14:14:42 2008 +0200
@@ -53,9 +53,9 @@
         i_free(ioloop->handler_context);
 }
 
-void io_loop_handle_add(struct ioloop *ioloop, struct io_file *io)
+void io_loop_handle_add(struct io_file *io)
 {
-	struct ioloop_handler_context *ctx = ioloop->handler_context;
+	struct ioloop_handler_context *ctx = io->io.ioloop->handler_context;
 	enum io_condition condition = io->io.condition;
 	int fd = io->fd;
 
@@ -74,10 +74,9 @@
 		ctx->highest_fd = io->fd;
 }
 
-void io_loop_handle_remove(struct ioloop *ioloop, struct io_file *io,
-			   bool closed ATTR_UNUSED)
+void io_loop_handle_remove(struct io_file *io, bool closed ATTR_UNUSED)
 {
-	struct ioloop_handler_context *ctx = ioloop->handler_context;
+	struct ioloop_handler_context *ctx = io->io.ioloop->handler_context;
 	enum io_condition condition = io->io.condition;
 	int fd = io->fd;
 
@@ -93,7 +92,7 @@
 
 		/* check if we removed the highest fd */
 		if (io->fd == ctx->highest_fd)
-			update_highest_fd(ioloop);
+			update_highest_fd(io->io.ioloop);
 	}
 	i_free(io);
 }
--- a/src/lib/ioloop.c	Fri Oct 24 16:06:07 2008 +0200
+++ b/src/lib/ioloop.c	Sat Nov 01 14:14:42 2008 +0200
@@ -33,18 +33,19 @@
         io->io.condition = condition;
 	io->io.callback = callback;
         io->io.context = context;
+	io->io.ioloop = current_ioloop;
 	io->refcount = 1;
 	io->fd = fd;
 
-	if (current_ioloop->handler_context == NULL)
-		io_loop_handler_init(current_ioloop);
-	io_loop_handle_add(current_ioloop, io);
+	if (io->io.ioloop->handler_context == NULL)
+		io_loop_handler_init(io->io.ioloop);
+	io_loop_handle_add(io);
 
-	if (current_ioloop->io_files != NULL) {
-		current_ioloop->io_files->prev = io;
-		io->next = current_ioloop->io_files;
+	if (io->io.ioloop->io_files != NULL) {
+		io->io.ioloop->io_files->prev = io;
+		io->next = io->io.ioloop->io_files;
 	}
-	current_ioloop->io_files = io;
+	io->io.ioloop->io_files = io;
 	return &io->io;
 }
 
@@ -53,15 +54,15 @@
 	if (io->prev != NULL)
 		io->prev->next = io->next;
 	else
-		current_ioloop->io_files = io->next;
+		io->io.ioloop->io_files = io->next;
 
 	if (io->next != NULL)
 		io->next->prev = io->prev;
 
 	/* if we got here from an I/O handler callback, make sure we
 	   don't try to handle this one next. */
-	if (current_ioloop->next_io_file == io)
-		current_ioloop->next_io_file = io->next;
+	if (io->io.ioloop->next_io_file == io)
+		io->io.ioloop->next_io_file = io->next;
 }
 
 static void io_remove_full(struct io **_io, bool closed)
@@ -77,12 +78,12 @@
 	io->callback = NULL;
 
 	if ((io->condition & IO_NOTIFY) != 0)
-		io_loop_notify_remove(current_ioloop, io);
+		io_loop_notify_remove(io);
 	else {
 		struct io_file *io_file = (struct io_file *)io;
 
 		io_file_unlink(io_file);
-		io_loop_handle_remove(current_ioloop, io_file, closed);
+		io_loop_handle_remove(io_file, closed);
 	}
 }
 
@@ -129,13 +130,14 @@
 
 	timeout = i_new(struct timeout, 1);
         timeout->msecs = msecs;
+	timeout->ioloop = current_ioloop;
 
 	timeout->callback = callback;
 	timeout->context = context;
 
-	timeout_update_next(timeout, current_ioloop->running ?
+	timeout_update_next(timeout, timeout->ioloop->running ?
 			    NULL : &ioloop_timeval);
-	priorityq_add(current_ioloop->timeouts, &timeout->item);
+	priorityq_add(timeout->ioloop->timeouts, &timeout->item);
 	return timeout;
 }
 
@@ -144,7 +146,7 @@
 	struct timeout *timeout = *_timeout;
 
 	*_timeout = NULL;
-	priorityq_remove(current_ioloop->timeouts, &timeout->item);
+	priorityq_remove(timeout->ioloop->timeouts, &timeout->item);
 	i_free(timeout);
 }
 
@@ -166,13 +168,13 @@
 		 timeout->next_run.tv_sec > tv_now->tv_sec ||
 		 (timeout->next_run.tv_sec == tv_now->tv_sec &&
 		  timeout->next_run.tv_usec > tv_now->tv_usec));
-	priorityq_remove(current_ioloop->timeouts, &timeout->item);
-	priorityq_add(current_ioloop->timeouts, &timeout->item);
+	priorityq_remove(timeout->ioloop->timeouts, &timeout->item);
+	priorityq_add(timeout->ioloop->timeouts, &timeout->item);
 }
 
 void timeout_reset(struct timeout *timeout)
 {
-	timeout_reset_timeval(timeout, current_ioloop->running ? NULL :
+	timeout_reset_timeval(timeout, timeout->ioloop->running ? NULL :
 			      &ioloop_timeval);
 }
 
@@ -382,9 +384,14 @@
 	if (ioloop->handler_context != NULL)
 		io_loop_handler_deinit(ioloop);
 
-        /* ->prev won't work unless loops are destroyed in create order */
+	/* ->prev won't work unless loops are destroyed in create order */
         i_assert(ioloop == current_ioloop);
 	current_ioloop = current_ioloop->prev;
 
 	i_free(ioloop);
 }
+
+void io_loop_set_current(struct ioloop *ioloop)
+{
+	current_ioloop = ioloop;
+}
--- a/src/lib/ioloop.h	Fri Oct 24 16:06:07 2008 +0200
+++ b/src/lib/ioloop.h	Sat Nov 01 14:14:42 2008 +0200
@@ -91,4 +91,7 @@
 /* Destroy I/O loop and set ioloop pointer to NULL. */
 void io_loop_destroy(struct ioloop **ioloop);
 
+/* Change the current_ioloop. */
+void io_loop_set_current(struct ioloop *ioloop);
+
 #endif