]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
push-notification: Switch to main ioloop while calling drivers' commit callbacks
authorTimo Sirainen <timo.sirainen@dovecot.fi>
Mon, 12 Jun 2017 20:45:05 +0000 (23:45 +0300)
committerVille Savolainen <ville.savolainen@dovecot.fi>
Fri, 16 Jun 2017 06:17:49 +0000 (09:17 +0300)
There aren't any guarantees what ioloop happens to be active at the time
the commit is called. The active ioloop can also be destroyed early on,
which can cause an I/O leak and crashes later on.

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

index e3f284749d717a7f2757c4daccde9dbe6c03e1c5..407e37b6ff33917084b7a2919a6ffadf213f7b83 100644 (file)
@@ -2,6 +2,7 @@
 
 #include "lib.h"
 #include "array.h"
+#include "ioloop.h"
 #include "mail-namespace.h"
 #include "mail-storage.h"
 #include "mail-storage-private.h"
@@ -24,7 +25,7 @@
         MODULE_CONTEXT(obj, push_notification_user_module)
 static MODULE_CONTEXT_DEFINE_INIT(push_notification_user_module,
                                   &mail_user_module_register);
-
+static struct ioloop *main_ioloop;
 
 static void
 push_notification_transaction_init(struct push_notification_txn *ptxn)
@@ -102,7 +103,12 @@ static void push_notification_transaction_commit
 (void *txn, struct mail_transaction_commit_changes *changes)
 {
     struct push_notification_txn *ptxn = (struct push_notification_txn *)txn;
+    struct ioloop *prev_ioloop = current_ioloop;
 
+    /* Make sure we're not in just any random ioloop, which could get
+       destroyed soon. This way the push-notification drivers can do async
+       operations that finish in the main ioloop. */
+    io_loop_set_current(main_ioloop);
     if (changes == NULL) {
         push_notification_txn_mbox_end(ptxn);
     } else {
@@ -110,6 +116,7 @@ static void push_notification_transaction_commit
     }
 
     push_notification_transaction_end(ptxn, TRUE);
+    io_loop_set_current(prev_ioloop);
 }
 
 static void push_notification_mailbox_create(struct mailbox *box)
@@ -337,6 +344,8 @@ void push_notification_plugin_init(struct module *module)
     push_notification_driver_register(&push_notification_driver_ox);
 
     push_notification_event_register_rfc5423_events();
+    main_ioloop = current_ioloop;
+    i_assert(main_ioloop != NULL);
 }
 
 void push_notification_plugin_deinit(void)