ConnectionManager: avoid sending request twice
Change-Id: I5bc6cdc830959dfc37f2b0f620340653ed2342a9
diff --git a/src/connectionmanager.cpp b/src/connectionmanager.cpp
index 0304c21..2eb0a1c 100644
--- a/src/connectionmanager.cpp
+++ b/src/connectionmanager.cpp
@@ -148,6 +148,7 @@
struct PendingCb {
std::string name;
ConnectCallback cb;
+ bool requested {false};
};
struct DeviceInfo {
@@ -235,12 +236,29 @@
executePendingOperations(lock, vid, sock, accepted);
}
- std::map<dht::Value::Id, std::string> getPendingIds() const {
- std::map<dht::Value::Id, std::string> ret;
+ bool isConnecting(const std::string& name) const {
for (const auto& [id, pc]: connecting)
- ret[id] = pc.name;
+ if (pc.name == name)
+ return true;
for (const auto& [id, pc]: waiting)
- ret[id] = pc.name;
+ if (pc.name == name)
+ return true;
+ return false;
+ }
+ std::map<dht::Value::Id, std::string> requestPendingOps() {
+ std::map<dht::Value::Id, std::string> ret;
+ for (auto& [id, pc]: connecting) {
+ if (!pc.requested) {
+ ret[id] = pc.name;
+ pc.requested = true;
+ }
+ }
+ for (auto& [id, pc]: waiting) {
+ if (!pc.requested) {
+ ret[id] = pc.name;
+ pc.requested = true;
+ }
+ }
return ret;
}
@@ -865,16 +883,17 @@
// Note: we can be in a state where first
// socket is negotiated and first channel is pending
// so return only after we checked the info
- if (isConnectingToDevice && !forceNewSocket)
- di->waiting[vid] = PendingCb {name, std::move(cb)};
- else
- di->connecting[vid] = PendingCb {name, std::move(cb)};
-
+ auto& diw = (isConnectingToDevice && !forceNewSocket)
+ ? di->waiting[vid]
+ : di->connecting[vid];
+ diw = PendingCb {name, std::move(cb)};
+
// Check if already negotiated
if (auto info = di->getConnectedInfo()) {
std::unique_lock<std::mutex> lkc(info->mutex_);
if (auto sock = info->socket_) {
info->cbIds_.emplace(vid);
+ diw.requested = true;
lkc.unlock();
lk.unlock();
if (sthis->config_->logger)
@@ -1176,7 +1195,7 @@
// Note: do not remove pending there it's done in sendChannelRequest
std::unique_lock<std::mutex> lk2 {dinfo->mtx_};
- auto pendingIds = dinfo->getPendingIds();
+ auto pendingIds = dinfo->requestPendingOps();
lk2.unlock();
std::unique_lock<std::mutex> lk {info->mutex_};
addNewMultiplexedSocket(dinfo, deviceId, vid, info);
@@ -1838,10 +1857,7 @@
{
if (auto dinfo = pimpl_->infos_.getDeviceInfo(deviceId)) {
std::unique_lock<std::mutex> lk {dinfo->mtx_};
- auto pending = dinfo->getPendingIds();
- lk.unlock();
- return std::find_if(pending.begin(), pending.end(), [&](const auto& p) { return p.second == name; })
- != pending.end();
+ return dinfo->isConnecting(name);
}
return false;
}