From 3f1c2f90b227698e73837b6990364fbc7b6824cd Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?S=C3=A9bastien=20Blin?=
 <sebastien.blin@savoirfairelinux.com>
Date: Wed, 11 Nov 2020 13:14:53 -0500
Subject: [PATCH] connectionmanager: avoid lock

Change-Id: I2300c349545a8820fb1302ee508d3664037450ea
---
 src/jamidht/connectionmanager.cpp  | 23 +++++----------------
 src/jamidht/multiplexed_socket.cpp | 33 ++++++++++++++++--------------
 2 files changed, 23 insertions(+), 33 deletions(-)

diff --git a/src/jamidht/connectionmanager.cpp b/src/jamidht/connectionmanager.cpp
index 686a9eca10..5d97023053 100644
--- a/src/jamidht/connectionmanager.cpp
+++ b/src/jamidht/connectionmanager.cpp
@@ -75,6 +75,11 @@ public:
                     info->tls_->shutdown();
                 if (info->socket_)
                     info->socket_->shutdown();
+                if (info->ice_) {
+                    info->ice_->cancelOperations();
+                    info->ice_->stop();
+                }
+                info->responseCv_.notify_all();
                 if (deviceId && key.first == deviceId) {
                     erased = true;
                     it = infos_.erase(it);
@@ -97,24 +102,6 @@ public:
             std::lock_guard<std::mutex> lk(connectCbsMtx_);
             pendingCbs_.clear();
         }
-        {
-            std::lock_guard<std::mutex> lk(infosMtx_);
-            for (auto& [key, connInfo] : infos_) {
-                if (!connInfo)
-                    continue;
-                if (connInfo->ice_) {
-                    connInfo->ice_->cancelOperations();
-                    connInfo->ice_->stop();
-                }
-                connInfo->responseCv_.notify_all();
-            }
-            // This is called when the account is only disabled.
-            // Move this on the thread pool because each
-            // IceTransport takes 500ms to delete, and it's sequential
-            // So, it can increase quickly the time to unregister an account
-            dht::ThreadPool::io().run(
-                [co = std::make_shared<decltype(infos_)>(std::move(infos_))] { co->clear(); });
-        }
         removeUnusedConnections();
     }
 
diff --git a/src/jamidht/multiplexed_socket.cpp b/src/jamidht/multiplexed_socket.cpp
index 0a9c485a1a..2b8d605be9 100644
--- a/src/jamidht/multiplexed_socket.cpp
+++ b/src/jamidht/multiplexed_socket.cpp
@@ -61,16 +61,27 @@ public:
                 endpoint->setOnStateChange({});
             shutdown();
         } else {
-            std::lock_guard<std::mutex> lkSockets(socketsMutex);
-            for (auto& socket : sockets) {
-                if (socket.second)
-                    socket.second->stop();
-            }
-            sockets.clear();
+            clearSockets();
         }
         eventLoopThread_.join();
     }
 
+    void clearSockets()
+    {
+        decltype(sockets) socks;
+        {
+            std::lock_guard<std::mutex> lkSockets(socketsMutex);
+            socks = std::move(sockets);
+        }
+        for (auto& socket : socks) {
+            // Just trigger onShutdown() to make client know
+            // No need to write the EOF for the channel, the write will fail because endpoint is
+            // already shutdown
+            if (socket.second)
+                socket.second->stop();
+        }
+    }
+
     void shutdown()
     {
         if (isShutdown_)
@@ -83,15 +94,7 @@ public:
             std::unique_lock<std::mutex> lk(writeMtx);
             endpoint->shutdown();
         }
-        std::lock_guard<std::mutex> lkSockets(socketsMutex);
-        for (auto& socket : sockets) {
-            // Just trigger onShutdown() to make client know
-            // No need to write the EOF for the channel, the write will fail because endpoint is
-            // already shutdown
-            if (socket.second)
-                socket.second->stop();
-        }
-        sockets.clear();
+        clearSockets();
     }
 
     /**
-- 
GitLab