Mercurial > dovecot > core-2.2
changeset 22223:7fa4ccc9a738
push-notification: Switch to main ioloop while calling drivers' commit callbacks
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.
author | Timo Sirainen <timo.sirainen@dovecot.fi> |
---|---|
date | Mon, 12 Jun 2017 23:45:05 +0300 |
parents | 03534f251ebb |
children | dc1996f95c89 |
files | src/plugins/push-notification/push-notification-plugin.c |
diffstat | 1 files changed, 10 insertions(+), 1 deletions(-) [+] |
line wrap: on
line diff
--- a/src/plugins/push-notification/push-notification-plugin.c Fri Jun 09 18:10:14 2017 +0300 +++ b/src/plugins/push-notification/push-notification-plugin.c Mon Jun 12 23:45:05 2017 +0300 @@ -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 @@ (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 @@ } 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 @@ 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)