From 6703968f73d89821f59806ea93b54dbf517e64a9 Mon Sep 17 00:00:00 2001 From: Peter Johnson Date: Sat, 1 Aug 2015 23:36:28 -0700 Subject: [PATCH] Dispatcher: Fix shutdown order race. We need to wait until after the dispatch and client/server threads have been stopped before closing connections, as these threads can add connections. --- src/Dispatcher.cpp | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/src/Dispatcher.cpp b/src/Dispatcher.cpp index beea340e4e..4c44342628 100644 --- a/src/Dispatcher.cpp +++ b/src/Dispatcher.cpp @@ -67,13 +67,7 @@ void Dispatcher::StartClient(const char* server_name, unsigned int port) { } void Dispatcher::Stop() { - { - std::lock_guard lock(m_user_mutex); - m_active = false; - - // close all connections - for (auto& conn : m_connections) conn.net->Stop(); - } + m_active = false; // wake up dispatch thread with a flush m_flush_cv.notify_one(); @@ -87,6 +81,15 @@ void Dispatcher::Stop() { // join threads if (m_dispatch_thread.joinable()) m_dispatch_thread.join(); if (m_clientserver_thread.joinable()) m_clientserver_thread.join(); + + std::vector conns; + { + std::lock_guard lock(m_user_mutex); + conns.swap(m_connections); + } + + // close all connections + conns.resize(0); } void Dispatcher::SetUpdateRate(double interval) { @@ -247,7 +250,7 @@ void Dispatcher::ClientThreadMain(const char* server_name, unsigned int port) { // block until told to reconnect m_do_reconnect = false; - m_reconnect_cv.wait(lock, [&] { return m_do_reconnect; }); + m_reconnect_cv.wait(lock, [&] { return !m_active || m_do_reconnect; }); } }