From fd2f2815448ce4072dcbc3995950788573d63f3b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Blin?= <sebastien.blin@savoirfairelinux.com> Date: Fri, 24 May 2024 10:03:40 -0400 Subject: [PATCH] conversation_module: avoid deadlock on member change Conversation::pull lock writeMtx_ while announcing new commits. If a member changes occurs, this can lock conv->mtx and other operations can wait on writeMtx_ too. GitLab: #994 Change-Id: I605ba6d4acb7b25a591be86bf37e9d549eeba8c0 --- src/jamidht/conversation_module.cpp | 23 +++++++++++++++++------ 1 file changed, 17 insertions(+), 6 deletions(-) diff --git a/src/jamidht/conversation_module.cpp b/src/jamidht/conversation_module.cpp index db16c086d1..75044ef201 100644 --- a/src/jamidht/conversation_module.cpp +++ b/src/jamidht/conversation_module.cpp @@ -743,8 +743,12 @@ ConversationModule::Impl::handlePendingConversation(const std::string& conversat }; try { auto conversation = std::make_shared<Conversation>(acc, deviceId, conversationId); - conversation->onMembersChanged([this, conversationId](const auto& members) { - setConversationMembers(conversationId, members); + conversation->onMembersChanged([w=weak_from_this(), conversationId](const auto& members) { + // Delay in another thread to avoid deadlocks + dht::ThreadPool::io().run([w, conversationId, members = std::move(members)] { + if (auto sthis = w.lock()) + sthis->setConversationMembers(conversationId, members); + }); }); conversation->onMessageStatusChanged([this, conversationId](const auto& status) { auto msg = std::make_shared<SyncMsg>(); @@ -1550,8 +1554,11 @@ ConversationModule::loadConversations() }); conv->onMembersChanged( [w = pimpl_->weak_from_this(), repository](const auto& members) { - if (auto p = w.lock()) - p->setConversationMembers(repository, members); + // Delay in another thread to avoid deadlocks + dht::ThreadPool::io().run([w, repository, members = std::move(members)] { + if (auto sthis = w.lock()) + sthis->setConversationMembers(repository, members); + }); }); conv->onNeedSocket(pimpl_->onNeedSwarmSocket_); auto members = conv->memberUris(acc->getUsername(), {}); @@ -2022,8 +2029,12 @@ ConversationModule::startConversation(ConversationMode mode, const std::string& msg->ms = {{conversationId, status}}; pimpl_->needsSyncingCb_(std::move(msg)); }); - conversation->onMembersChanged([this, conversationId](const auto& members) { - pimpl_->setConversationMembers(conversationId, members); + conversation->onMembersChanged([w=pimpl_->weak_from_this(), conversationId](const auto& members) { + // Delay in another thread to avoid deadlocks + dht::ThreadPool::io().run([w, conversationId, members = std::move(members)] { + if (auto sthis = w.lock()) + sthis->setConversationMembers(conversationId, members); + }); }); conversation->onNeedSocket(pimpl_->onNeedSwarmSocket_); #ifdef LIBJAMI_TESTABLE -- GitLab