diff --git a/src/connectionmanager.cpp b/src/connectionmanager.cpp index 5f70622..a341b95 100644 --- a/src/connectionmanager.cpp +++ b/src/connectionmanager.cpp @@ -181,7 +181,8 @@ struct DeviceInfo { return info.empty() && connecting.empty() && waiting.empty(); } - dht::Value::Id newId(std::mt19937_64& rand) const { + dht::Value::Id newId(std::mt19937_64& rand, std::mutex& mtx) const { + std::lock_guard lkr(mtx); ValueIdDist dist(1, ID_MAX_VAL); dht::Value::Id id; do { @@ -557,7 +558,7 @@ class ConnectionManager::Impl : public std::enable_shared_from_this& dinfo, const DeviceId& deviceId, const dht::Value::Id& vid, const std::shared_ptr& info); void onPeerResponse(PeerConnectionRequest&& req); void onDhtConnected(const dht::crypto::PublicKey& devicePk); - void retryOnError(const std::shared_ptr& deviceInfo); + void retryOnError(const std::shared_ptr& deviceInfo, std::unique_lock& lk); const std::shared_future dhParams() const; tls::CertificateStore& certStore() const { return *config_->certStore; } @@ -626,7 +627,7 @@ class ConnectionManager::Impl : public std::enable_shared_from_this config_; std::unique_ptr ioContextRunner_; - mutable std::mutex randMtx_; + mutable std::mutex randMutex_; mutable std::mt19937_64 rand_; iOSConnectedCallback iOSConnectedCb_ {}; @@ -925,11 +926,7 @@ ConnectionManager::Impl::connectDevice(const std::shared_ptrcert = cert; } - dht::Value::Id vid; - { - std::lock_guard lkr(sthis->randMtx_); - vid = di->newId(sthis->rand_); - } + dht::Value::Id vid = di->newId(sthis->rand_, sthis->randMutex_); // Check if already connecting auto isConnectingToDevice = di->isConnecting(); @@ -1580,14 +1577,20 @@ ConnectionManager::Impl::addNewMultiplexedSocket(const std::weak_ptr sthis->infos_.removeDeviceInfo(deviceInfo->deviceId); } lkc.unlock(); - lkd.unlock(); - - for (auto& op : ops) - op.cb(nullptr, deviceInfo->deviceId); if (retry) { - if (auto sthis = w.lock()) - sthis->retryOnError(deviceInfo); + if (auto sthis = w.lock()) { + // Reset state and ID of the connecting channel + if (auto connecting = deviceInfo->connecting.extract(vid)) { + dht::Value::Id vid = deviceInfo->newId(sthis->rand_, sthis->randMutex_); + deviceInfo->waiting[vid] = std::move(connecting.mapped()); + } + sthis->retryOnError(deviceInfo, lkd); + } } + if (lkd) + lkd.unlock(); + for (auto& op : ops) + op.cb(nullptr, deviceInfo->deviceId); } } }); @@ -1595,9 +1598,8 @@ ConnectionManager::Impl::addNewMultiplexedSocket(const std::weak_ptr } void -ConnectionManager::Impl::retryOnError(const std::shared_ptr& deviceInfo) +ConnectionManager::Impl::retryOnError(const std::shared_ptr& deviceInfo, std::unique_lock& lk) { - std::unique_lock lk(deviceInfo->mutex_); if (not deviceInfo->isConnecting()) return; if (auto i = deviceInfo->getConnectedInfo()) {