]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
lib: ioloop-kqueue - Fix memory leak when ioloop stops before all IO callbacks are...
authorTimo Sirainen <timo.sirainen@open-xchange.com>
Mon, 8 Jan 2024 14:25:33 +0000 (09:25 -0500)
committerAki Tuomi <aki.tuomi@open-xchange.com>
Fri, 2 Feb 2024 09:18:48 +0000 (11:18 +0200)
Broken by 720a6e0e67c3f04dcfee4c80b34f0291c7217cfa

src/lib/ioloop-kqueue.c

index 0af05c846c1fa71d3ab56bd5459d5081dc19866f..87cd8a4546cffa96df5cb283e7772da6e6fddc74 100644 (file)
@@ -163,9 +163,7 @@ void io_loop_handler_run_internal(struct ioloop *ioloop)
        /* execute timeout handlers */
        io_loop_handle_timeouts(ioloop);
 
-       if (!ioloop->running)
-               return;
-
+       bool call_callbacks = ioloop->running;
        for (i = 0; i < ret; i++) {
                /* io_loop_handle_add() may cause events array reallocation,
                   so we have use array_idx() */
@@ -173,10 +171,14 @@ void io_loop_handler_run_internal(struct ioloop *ioloop)
                io = (void *)event->udata;
 
                /* callback is NULL if io_remove() was already called */
-               if (io->io.callback != NULL) {
+               if (io->io.callback != NULL && call_callbacks) {
                        io_loop_call_io(&io->io);
-                       if (!ioloop->running)
-                               break;
+                       if (!ioloop->running) {
+                               /* Don't call any further callbacks, but the
+                                  rest of the IOs still need to be
+                                  unreferenced. */
+                               call_callbacks = FALSE;
+                       }
                }
 
                i_assert(io->refcount > 0);