From 1f41c99ffa425f90d1b51c68d0e40be3c816de00 Mon Sep 17 00:00:00 2001 From: Peter Kosyh Date: Mon, 12 Nov 2018 09:13:27 +0300 Subject: [PATCH] mail: IMAP inbound protocol destructor fix This should fix crashes of mailer_daemon in IMAP workers. This patch makes IMAPConnection destructor wait for all working threads to finish. Also, do not call _Connect for QuitCommand (it speedups shutdown procedure). Change-Id: Idffcc00d3459a96a85a8a073a343bcf4cd4984be Reviewed-on: https://review.haiku-os.org/686 Reviewed-by: waddlesplash --- .../inbound_protocols/imap/IMAPConnectionWorker.cpp | 10 +++++++++- .../inbound_protocols/imap/IMAPProtocol.cpp | 9 +++++++++ 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/src/add-ons/mail_daemon/inbound_protocols/imap/IMAPConnectionWorker.cpp b/src/add-ons/mail_daemon/inbound_protocols/imap/IMAPConnectionWorker.cpp index cb747e5678..f30625e977 100644 --- a/src/add-ons/mail_daemon/inbound_protocols/imap/IMAPConnectionWorker.cpp +++ b/src/add-ons/mail_daemon/inbound_protocols/imap/IMAPConnectionWorker.cpp @@ -618,6 +618,10 @@ void IMAPConnectionWorker::Quit() { printf("IMAP: worker %p: enqueue quit\n", this); + BAutolock locker(fLocker); + while (!fPendingCommands.IsEmpty()) + delete(fPendingCommands.RemoveItemAt(0)); + locker.Unlock(); _EnqueueCommand(new QuitCommand()); } @@ -732,7 +736,11 @@ IMAPConnectionWorker::_Worker() CommandDeleter deleter(*this, command); - status_t status = _Connect(); + status_t status = B_OK; + + if (dynamic_cast(command) == NULL) // do not connect on QuitCommand + status = _Connect(); + if (status != B_OK) { fOwner.WorkerQuit(this); return status; diff --git a/src/add-ons/mail_daemon/inbound_protocols/imap/IMAPProtocol.cpp b/src/add-ons/mail_daemon/inbound_protocols/imap/IMAPProtocol.cpp index 2af060538f..6a2e80c2fe 100644 --- a/src/add-ons/mail_daemon/inbound_protocols/imap/IMAPProtocol.cpp +++ b/src/add-ons/mail_daemon/inbound_protocols/imap/IMAPProtocol.cpp @@ -38,6 +38,15 @@ IMAPProtocol::IMAPProtocol(const BMailAccountSettings& settings) IMAPProtocol::~IMAPProtocol() { + MutexLocker locker(fWorkerLock); + for (int32 i = 0; i < fWorkers.CountItems(); i++) + fWorkers.ItemAt(i)->Quit(); + int tries = 10; + while (fWorkers.CountItems() > 0 && --tries > 0) { + locker.Unlock(); + snooze(500000); + locker.Lock(); + } }