diff --git a/src/jamidht/jamiaccount.cpp b/src/jamidht/jamiaccount.cpp index f0c62fb15..67426a11b 100644 --- a/src/jamidht/jamiaccount.cpp +++ b/src/jamidht/jamiaccount.cpp @@ -2007,13 +2007,17 @@ JamiAccount::doRegister_() if (accountManager_->getInfo()->deviceId == deviceId) return; - std::unique_lock lk(connManagerMtx_); - initConnectionManager(); - lk.unlock(); - requestSIPConnection( - getUsername(), - crt->getLongId(), - "sync"); // For git notifications, will use the same socket as sync + dht::ThreadPool::io().run([w = weak(), deviceId, crt] { + auto shared = w.lock(); + if (!shared) return; + std::unique_lock lk(shared->connManagerMtx_); + shared->initConnectionManager(); + lk.unlock(); + shared->requestSIPConnection( + shared->getUsername(), + crt->getLongId(), + "sync"); // For git notifications, will use the same socket as sync + }); } }, [this] { @@ -2080,7 +2084,7 @@ JamiAccount::doRegister_() } auto uri = Uri(name); - std::lock_guard lk(connManagerMtx_); + std::shared_lock lk(connManagerMtx_); auto itHandler = channelHandlers_.find(uri.scheme()); if (itHandler != channelHandlers_.end() && itHandler->second) return itHandler->second->onRequest(cert, name); @@ -2171,7 +2175,7 @@ JamiAccount::doRegister_() }); } else { // TODO move git:// - std::lock_guard lk(connManagerMtx_); + std::shared_lock lk(connManagerMtx_); auto uri = Uri(name); auto itHandler = channelHandlers_.find(uri.scheme()); if (itHandler != channelHandlers_.end() && itHandler->second) @@ -2258,7 +2262,7 @@ JamiAccount::convModule(bool noCreation) cb({}); return; } - std::unique_lock lkCM(shared->connManagerMtx_); + std::shared_lock lkCM(shared->connManagerMtx_); if (!shared->connectionManager_) { lkCM.unlock(); cb({}); @@ -2304,7 +2308,7 @@ JamiAccount::convModule(bool noCreation) if (!shared) return; auto cm = shared->convModule(); - std::lock_guard lkCM(shared->connManagerMtx_); + std::shared_lock lkCM(shared->connManagerMtx_); if (!shared->connectionManager_ || !cm || cm->isBanned(convId, deviceId)) { Manager::instance().ioContext()->post([cb] { cb({}); }); return; @@ -2494,7 +2498,7 @@ JamiAccount::connectivityChanged() cm->connectivityChanged(); dht_->connectivityChanged(); { - std::lock_guard lkCM(connManagerMtx_); + std::shared_lock lkCM(connManagerMtx_); if (connectionManager_) { connectionManager_->connectivityChanged(); // reset cache @@ -3091,7 +3095,7 @@ JamiAccount::sendMessage(const std::string& to, auto devices = std::make_shared>(); // Use the Message channel if available - std::unique_lock clk(connManagerMtx_); + std::shared_lock clk(connManagerMtx_); auto* handler = static_cast( channelHandlers_[Uri::Scheme::MESSAGE].get()); if (!handler) { @@ -3776,7 +3780,7 @@ JamiAccount::requestSIPConnection(const std::string& peerId, return; } // If not present, create it - std::lock_guard lkCM(connManagerMtx_); + std::shared_lock lkCM(connManagerMtx_); if (!connectionManager_) return; // Note, Even if we send 50 "sip" request, the connectionManager_ will only use one socket. @@ -3813,7 +3817,7 @@ JamiAccount::requestSIPConnection(const std::string& peerId, bool JamiAccount::isConnectedWith(const DeviceId& deviceId) const { - std::lock_guard lkCM(connManagerMtx_); + std::shared_lock lkCM(connManagerMtx_); if (connectionManager_) return connectionManager_->isConnected(deviceId); return false; @@ -4168,7 +4172,7 @@ JamiAccount::monitor() if (auto cm = convModule()) cm->monitor(); - std::lock_guard lkCM(connManagerMtx_); + std::shared_lock lkCM(connManagerMtx_); if (connectionManager_) connectionManager_->monitor(); } @@ -4176,7 +4180,7 @@ JamiAccount::monitor() std::vector> JamiAccount::getConnectionList(const std::string& conversationId) { - std::lock_guard lkCM(connManagerMtx_); + std::shared_lock lkCM(connManagerMtx_); if (connectionManager_ && conversationId.empty()) { return connectionManager_->getConnectionList(); } else if (connectionManager_ && convModule_) { @@ -4199,7 +4203,7 @@ JamiAccount::getConnectionList(const std::string& conversationId) std::vector> JamiAccount::getChannelList(const std::string& connectionId) { - std::lock_guard lkCM(connManagerMtx_); + std::shared_lock lkCM(connManagerMtx_); if (!connectionManager_) return {}; return connectionManager_->getChannelList(connectionId); @@ -4310,7 +4314,7 @@ JamiAccount::transferFile(const std::string& conversationId, conversationId, currentDeviceId(), fid); - std::lock_guard lkCM(connManagerMtx_); + std::shared_lock lkCM(connManagerMtx_); if (!connectionManager_) return; connectionManager_ @@ -4359,7 +4363,7 @@ JamiAccount::askForFileChannel(const std::string& conversationId, size_t end) { auto tryDevice = [=](const auto& did) { - std::lock_guard lkCM(connManagerMtx_); + std::shared_lock lkCM(connManagerMtx_); if (!connectionManager_) return; @@ -4419,7 +4423,7 @@ JamiAccount::askForProfile(const std::string& conversationId, const std::string& deviceId, const std::string& memberUri) { - std::lock_guard lkCM(connManagerMtx_); + std::shared_lock lkCM(connManagerMtx_); if (!connectionManager_) return; diff --git a/src/jamidht/jamiaccount.h b/src/jamidht/jamiaccount.h index 7d33ede3b..183d6993d 100644 --- a/src/jamidht/jamiaccount.h +++ b/src/jamidht/jamiaccount.h @@ -60,6 +60,7 @@ #include #include #include +#include #if HAVE_RINGNS #include "namedirectory.h" @@ -789,7 +790,10 @@ private: pjsip_transport* via_tp_ {nullptr}; - mutable std::mutex connManagerMtx_ {}; + /** ConnectionManager is thread-safe. + * The shared mutex protects the pointer while allowing + * multiple threads to access the ConnectionManager concurrently */ + mutable std::shared_mutex connManagerMtx_ {}; std::unique_ptr connectionManager_; virtual void updateUpnpController() override;