]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
Don't break if io_remove() or timeout_remove() are called for non-active ioloops.
authorTimo Sirainen <tss@iki.fi>
Sat, 1 Nov 2008 12:14:42 +0000 (14:14 +0200)
committerTimo Sirainen <tss@iki.fi>
Sat, 1 Nov 2008 12:14:42 +0000 (14:14 +0200)
--HG--
branch : HEAD

12 files changed:
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

index 9f7377e0268e60a7d9c9cd4ff9a4bdadfe3e98f8..f657f57fad86d84b48adceab82875f982661f441 100644 (file)
@@ -83,9 +83,9 @@ static int epoll_event_mask(struct io_list *list)
        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_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_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;
index c153b1c01d6a49115a9bd0886205b8ece0448d18..7a61be8270a4e1f1a27105876bd944755c975102 100644 (file)
@@ -26,6 +26,8 @@ struct io {
 
        io_callback_t *callback;
         void *context;
+
+       struct ioloop *ioloop;
 };
 
 struct io_file {
@@ -46,6 +48,8 @@ struct timeout {
 
        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 @@ int io_loop_get_wait_time(struct ioloop *ioloop, struct timeval *tv_r,
 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
index c45e2870d5d62a104b4b7646efd364bb1ca3f8b1..e34792f46653179830b543a9e7d88e242c6e942d 100644 (file)
@@ -56,9 +56,9 @@ void io_loop_handler_deinit(struct ioloop *ioloop)
        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 io_loop_handle_add(struct ioloop *ioloop, struct io_file *io)
                (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) {
index 9466e778fe66106d001413b066ab70091f6d5b00..c2a269ab2f9d753ad4197403182eba15ff8d1524 100644 (file)
@@ -148,10 +148,10 @@ enum io_notify_result io_add_notify(const char *path, io_callback_t *callback,
        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)
index 8dfcf378f49b8ea2bbba5dbe98c8a27d17952c78..5a8705f748f97ec666395f0458fbe9e818f66319 100644 (file)
@@ -15,6 +15,7 @@ struct io *io_notify_fd_add(struct ioloop_notify_fd_context *ctx, int fd,
        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) {
index d0a91ca2e686ce7c40e0af1633d45c99825f3ce7..6026feb2c64e6f492e296bdd2891e419ce263395 100644 (file)
@@ -120,10 +120,10 @@ enum io_notify_result io_add_notify(const char *path, io_callback_t *callback,
        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) {
index 0477bd56edb4f9749a31b7eaf96cdc7ca23026a6..9ae2a9ef07d8eba136c7883ada86611a79b43605 100644 (file)
@@ -130,6 +130,7 @@ enum io_notify_result io_add_notify(const char *path, io_callback_t *callback,
        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 @@ enum io_notify_result io_add_notify(const char *path, io_callback_t *callback,
 
        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;
 
index 4cef6eaf450afc6ac5537328e386210194d9a1b2..7dcde9f307ae7defce820a47699ee093948c99f9 100644 (file)
@@ -15,8 +15,7 @@ io_add_notify(const char *path ATTR_UNUSED,
        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)
 {
 }
 
index ba8adfaf15abb7481db3eb5b66bf8d543d54cfbb..fc425e52c18e940ed7f21f75a417129f2ca3c8d5 100644 (file)
@@ -42,9 +42,9 @@ void io_loop_handler_deinit(struct ioloop *ioloop)
 #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 @@ void io_loop_handle_add(struct ioloop *ioloop, struct io_file *io)
                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;
 
index 1c636370884b0373e990af32bb05ef9fdb0ad056..0a396526643d08cd3cea17ec3fecba93a9e40272 100644 (file)
@@ -53,9 +53,9 @@ void io_loop_handler_deinit(struct ioloop *ioloop)
         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 @@ void io_loop_handle_add(struct ioloop *ioloop, struct io_file *io)
                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 @@ void io_loop_handle_remove(struct ioloop *ioloop, struct io_file *io,
 
                /* 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);
 }
index 0d194d9a1f426553f0ad53ce27b01b24f0d1ffdc..deae0ce715905f5f03cd73dbc0fcb7629af6021c 100644 (file)
@@ -33,18 +33,19 @@ struct io *io_add(int fd, enum io_condition condition,
         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 @@ static void io_file_unlink(struct io_file *io)
        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 @@ static void io_remove_full(struct io **_io, bool closed)
        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 @@ struct timeout *timeout_add(unsigned int msecs, timeout_callback_t *callback,
 
        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 @@ void timeout_remove(struct timeout **_timeout)
        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_reset_timeval(struct timeout *timeout, struct timeval *tv_now)
                 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 @@ void io_loop_destroy(struct ioloop **_ioloop)
        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;
+}
index f86b00dbd6129332d8d615e9e87f8a7bfe74f22e..9d1c5ed8524a3e64f854ba253a84f1d9ff7fb4b8 100644 (file)
@@ -91,4 +91,7 @@ struct ioloop *io_loop_create(void);
 /* 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