]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
push-notification: Switch to main ioloop while calling drivers' deinit/cleanup callbacks
authorTimo Sirainen <timo.sirainen@dovecot.fi>
Wed, 9 Aug 2017 10:23:36 +0000 (13:23 +0300)
committerVille Savolainen <ville.savolainen@dovecot.fi>
Thu, 10 Aug 2017 10:25:36 +0000 (13:25 +0300)
Continues a44595f7b1afc7ccbd8653598753b32899d01c76 to other functions.
For example the OX backend would call http_client_wait(), which would move
the I/Os and timeouts to the current ioloop, which might not be main_ioloop
always. When that ioloop gets destroyed, I/O and timeout leaks are logged
and eventually the process crashes when calling http_client_deinit() in
cleanup() (this would happen later for another mail_user).

src/plugins/push-notification/push-notification-plugin.c

index 407e37b6ff33917084b7a2919a6ffadf213f7b83..c2b16d0e076b69cdadfd30ae01c0cf15b32abf23 100644 (file)
@@ -275,6 +275,11 @@ static void push_notification_user_deinit(struct mail_user *user)
     struct push_notification_user *puser = PUSH_NOTIFICATION_USER_CONTEXT(user);
     struct push_notification_driver_list *dlist = puser->driverlist;
     struct push_notification_driver_user **duser;
+    struct ioloop *prev_ioloop = current_ioloop;
+
+    /* Make sure we're in the main ioloop, so if the deinit/cleanup moves any
+       I/Os or timeouts they won't get moved to some temporary ioloop. */
+    io_loop_set_current(main_ioloop);
 
     array_foreach_modifiable(&dlist->drivers, duser) {
         if ((*duser)->driver->v.deinit != NULL) {
@@ -285,6 +290,8 @@ static void push_notification_user_deinit(struct mail_user *user)
             (*duser)->driver->v.cleanup();
         }
     }
+    io_loop_set_current(prev_ioloop);
+
     puser->module_ctx.super.deinit(user);
 }