From a5344495a00d7c595870fe35a044645c61a219b7 Mon Sep 17 00:00:00 2001 From: Kateryna Kostiuk <katryna.kostiuk@savoirfairelinux.com> Date: Tue, 4 Apr 2023 12:41:39 -0400 Subject: [PATCH] account: prevent deadlock during unregister This patch runs DHT listener callbacks on a different thread to prevent locking the configurationMutex, as it is used during account unregistering and could potentially lead to a deadlock. Change-Id: Id42b92118713b5d16eb10a74ccf14a788142418d --- src/jamidht/jamiaccount.cpp | 72 ++++++++++++++++++++----------------- 1 file changed, 40 insertions(+), 32 deletions(-) diff --git a/src/jamidht/jamiaccount.cpp b/src/jamidht/jamiaccount.cpp index f7f2caf156..9837ef551e 100644 --- a/src/jamidht/jamiaccount.cpp +++ b/src/jamidht/jamiaccount.cpp @@ -1115,23 +1115,27 @@ JamiAccount::loadAccount(const std::string& archive_password, time_t received) { if (!id_.first) return; - clearProfileCache(uri); - if (conversationId.empty()) { - // Old path - emitSignal<libjami::ConfigurationSignal::IncomingTrustRequest>(getAccountID(), - conversationId, - uri, - payload, - received); - return; - } - // Here account can be initializing - if (auto cm = convModule()) { - auto activeConv = cm->getOneToOneConversation(uri); - if (activeConv != conversationId) { - cm->onTrustRequest(uri, conversationId, payload, received); + dht::ThreadPool::io().run([w = weak(), uri, conversationId, payload, received] { + if (auto shared = w.lock()) { + shared->clearProfileCache(uri); + if (conversationId.empty()) { + // Old path + emitSignal<libjami::ConfigurationSignal::IncomingTrustRequest>(shared->getAccountID(), + conversationId, + uri, + payload, + received); + return; + } + // Here account can be initializing + if (auto cm = shared->convModule()) { + auto activeConv = cm->getOneToOneConversation(uri); + if (activeConv != conversationId) { + cm->onTrustRequest(uri, conversationId, payload, received); + } + } } - } + }); }, [this](const std::map<DeviceId, KnownDevice>& devices) { std::map<std::string, std::string> ids; @@ -1151,23 +1155,27 @@ JamiAccount::loadAccount(const std::string& archive_password, convModule()->acceptConversationRequest(conversationId); }, [this](const std::string& uri, const std::string& convFromReq) { - // Remove cached payload if there is one - auto requestPath = cachePath_ + DIR_SEPARATOR_STR + "requests" + DIR_SEPARATOR_STR - + uri; - fileutils::remove(requestPath); - if (!convFromReq.empty()) { - auto oldConv = convModule()->getOneToOneConversation(uri); - // If we previously removed the contact, and re-add it, we may - // receive a convId different from the request. In that case, - // we need to remove the current conversation and clone the old - // one (given by convFromReq). - // TODO: In the future, we may want to re-commit the messages we - // may have send in the request we sent. - if (oldConv != convFromReq && updateConvForContact(uri, oldConv, convFromReq)) { - convModule()->initReplay(oldConv, convFromReq); - convModule()->cloneConversationFrom(convFromReq, uri, oldConv); + dht::ThreadPool::io().run([w = weak(), convFromReq, uri] { + if (auto shared = w.lock()) { + // Remove cached payload if there is one + auto requestPath = shared->cachePath_ + DIR_SEPARATOR_STR + "requests" + DIR_SEPARATOR_STR + + uri; + fileutils::remove(requestPath); + if (!convFromReq.empty()) { + auto oldConv = shared->convModule()->getOneToOneConversation(uri); + // If we previously removed the contact, and re-add it, we may + // receive a convId different from the request. In that case, + // we need to remove the current conversation and clone the old + // one (given by convFromReq). + // TODO: In the future, we may want to re-commit the messages we + // may have send in the request we sent. + if (oldConv != convFromReq && shared->updateConvForContact(uri, oldConv, convFromReq)) { + shared->convModule()->initReplay(oldConv, convFromReq); + shared->convModule()->cloneConversationFrom(convFromReq, uri, oldConv); + } + } } - } + }); }}; const auto& conf = config(); -- GitLab