ConnectionManager: refactor to reduce contention
* merge info, waiting and pending maps into DeviceInfo,
improving consistency of various operations
* DeviceInfo has its own mutex,
and operations keep a weak pointer to it,
reducing contention
* DeviceInfoSet encapsulate atomic management of DeviceInfos,
enforcing proper locking order
Change-Id: I12c107782600355a34d460e7802d92ae9d590993
diff --git a/tests/connectionManager.cpp b/tests/connectionManager.cpp
index 946aa2d..8391442 100644
--- a/tests/connectionManager.cpp
+++ b/tests/connectionManager.cpp
@@ -23,6 +23,7 @@
#include <opendht/log.h>
#include <asio/executor_work_guard.hpp>
#include <asio/io_context.hpp>
+#include <fmt/compile.h>
#include <cppunit/TestAssert.h>
#include <cppunit/TestFixture.h>
@@ -1342,6 +1343,7 @@
CPPUNIT_ASSERT(cv.wait_for(lk, 30s, [&] { return notConnected; }));
}
+
void
ConnectionManagerTest::testGetChannelList()
{
@@ -1353,11 +1355,10 @@
bob->connectionManager->onChannelRequest(
[](const std::shared_ptr<dht::crypto::Certificate>&, const std::string&) { return true; });
bob->connectionManager->onConnectionReady(
- [&receiverConnected,
- &cv](const DeviceId&, const std::string&, std::shared_ptr<ChannelSocket> socket) {
+ [&](const DeviceId&, const std::string&, std::shared_ptr<ChannelSocket> socket) {
+ std::lock_guard<std::mutex> lk {mtx};
if (socket)
receiverConnected += 1;
-
cv.notify_one();
});
std::string channelId;
@@ -1365,36 +1366,27 @@
"git://*",
[&](std::shared_ptr<ChannelSocket> socket,
const DeviceId&) {
+ std::lock_guard<std::mutex> lk {mtx};
if (socket) {
- channelId = std::to_string(socket->channel());
+ channelId = fmt::format(FMT_COMPILE("{:x}"), socket->channel());
successfullyConnected = true;
}
-
cv.notify_one();
});
CPPUNIT_ASSERT(
cv.wait_for(lk, 60s, [&] { return successfullyConnected && receiverConnected == 1; }));
std::vector<std::map<std::string, std::string>> expectedList = {
- {{"channel", channelId}, {"channelName", "git://*"}}};
+ {{"id", channelId}, {"name", "git://*"}}};
auto connectionList = alice->connectionManager->getConnectionList();
CPPUNIT_ASSERT(!connectionList.empty());
const auto& connectionInfo = connectionList[0];
auto it = connectionInfo.find("id");
CPPUNIT_ASSERT(it != connectionInfo.end());
- std::string connectionId = it->second;
- auto actualList = alice->connectionManager->getChannelList(connectionId);
+ auto actualList = alice->connectionManager->getChannelList(it->second);
CPPUNIT_ASSERT(expectedList.size() == actualList.size());
- CPPUNIT_ASSERT(std::equal(expectedList.begin(), expectedList.end(), actualList.begin()));
for (const auto& expectedMap : expectedList) {
- auto it = std::find_if(actualList.begin(),
- actualList.end(),
- [&](const std::map<std::string, std::string>& actualMap) {
- return expectedMap.size() == actualMap.size()
- && std::equal(expectedMap.begin(),
- expectedMap.end(),
- actualMap.begin());
- });
- CPPUNIT_ASSERT(it != actualList.end());
+ CPPUNIT_ASSERT(std::find(actualList.begin(), actualList.end(), expectedMap)
+ != actualList.end());
}
}