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();
+ }
}