From f26866b9caf9ff27d129c703f51b8c2922000243 Mon Sep 17 00:00:00 2001 From: Cory Fields Date: Wed, 7 Feb 2018 17:20:16 -0500 Subject: [PATCH 1/4] boost: drop boost threads for upnp --- src/init.cpp | 7 +++- src/net.cpp | 86 ++++++++++++++++++++++------------------- src/net.h | 4 +- src/qt/optionsmodel.cpp | 7 +++- 4 files changed, 61 insertions(+), 43 deletions(-) diff --git a/src/init.cpp b/src/init.cpp index 50643ff96..2912beec6 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -165,6 +165,7 @@ void Interrupt() InterruptRPC(); InterruptREST(); InterruptTorControl(); + InterruptMapPort(); if (g_connman) g_connman->Interrupt(); } @@ -191,7 +192,7 @@ void Shutdown() #ifdef ENABLE_WALLET FlushWallets(); #endif - MapPort(false); + StopMapPort(); // Because these depend on each-other, we make sure that neither can be // using the other before destroying them. @@ -1669,7 +1670,9 @@ bool AppInitMain() Discover(threadGroup); // Map ports with UPnP - MapPort(gArgs.GetBoolArg("-upnp", DEFAULT_UPNP)); + if (gArgs.GetBoolArg("-upnp", DEFAULT_UPNP)) { + StartMapPort(); + } CConnman::Options connOptions; connOptions.nLocalServices = nLocalServices; diff --git a/src/net.cpp b/src/net.cpp index 03ed7e7fc..307e5d49d 100644 --- a/src/net.cpp +++ b/src/net.cpp @@ -1459,6 +1459,8 @@ void CConnman::WakeMessageHandler() #ifdef USE_UPNP +static CThreadInterrupt g_upnp_interrupt; +static std::thread g_upnp_thread; void ThreadMapPort() { std::string port = strprintf("%u", GetListenPort()); @@ -1509,35 +1511,29 @@ void ThreadMapPort() std::string strDesc = "Bitcoin " + FormatFullVersion(); - try { - while (true) { + do { #ifndef UPNPDISCOVER_SUCCESS - /* miniupnpc 1.5 */ - r = UPNP_AddPortMapping(urls.controlURL, data.first.servicetype, - port.c_str(), port.c_str(), lanaddr, strDesc.c_str(), "TCP", 0); + /* miniupnpc 1.5 */ + r = UPNP_AddPortMapping(urls.controlURL, data.first.servicetype, + port.c_str(), port.c_str(), lanaddr, strDesc.c_str(), "TCP", 0); #else - /* miniupnpc 1.6 */ - r = UPNP_AddPortMapping(urls.controlURL, data.first.servicetype, - port.c_str(), port.c_str(), lanaddr, strDesc.c_str(), "TCP", 0, "0"); + /* miniupnpc 1.6 */ + r = UPNP_AddPortMapping(urls.controlURL, data.first.servicetype, + port.c_str(), port.c_str(), lanaddr, strDesc.c_str(), "TCP", 0, "0"); #endif - if(r!=UPNPCOMMAND_SUCCESS) - LogPrintf("AddPortMapping(%s, %s, %s) failed with code %d (%s)\n", - port, port, lanaddr, r, strupnperror(r)); - else - LogPrintf("UPnP Port Mapping successful.\n"); + if(r!=UPNPCOMMAND_SUCCESS) + LogPrintf("AddPortMapping(%s, %s, %s) failed with code %d (%s)\n", + port, port, lanaddr, r, strupnperror(r)); + else + LogPrintf("UPnP Port Mapping successful.\n"); + } + while(g_upnp_interrupt.sleep_for(std::chrono::minutes(20))); - MilliSleep(20*60*1000); // Refresh every 20 minutes - } - } - catch (const boost::thread_interrupted&) - { - r = UPNP_DeletePortMapping(urls.controlURL, data.first.servicetype, port.c_str(), "TCP", 0); - LogPrintf("UPNP_DeletePortMapping() returned: %d\n", r); - freeUPNPDevlist(devlist); devlist = nullptr; - FreeUPNPUrls(&urls); - throw; - } + r = UPNP_DeletePortMapping(urls.controlURL, data.first.servicetype, port.c_str(), "TCP", 0); + LogPrintf("UPNP_DeletePortMapping() returned: %d\n", r); + freeUPNPDevlist(devlist); devlist = nullptr; + FreeUPNPUrls(&urls); } else { LogPrintf("No valid UPnP IGDs found\n"); freeUPNPDevlist(devlist); devlist = nullptr; @@ -1546,27 +1542,39 @@ void ThreadMapPort() } } -void MapPort(bool fUseUPnP) +void StartMapPort() { - static std::unique_ptr upnp_thread; - - if (fUseUPnP) - { - if (upnp_thread) { - upnp_thread->interrupt(); - upnp_thread->join(); - } - upnp_thread.reset(new boost::thread(boost::bind(&TraceThread, "upnp", &ThreadMapPort))); + if (!g_upnp_thread.joinable()) { + assert(!g_upnp_interrupt); + g_upnp_thread = std::thread((std::bind(&TraceThread, "upnp", &ThreadMapPort))); } - else if (upnp_thread) { - upnp_thread->interrupt(); - upnp_thread->join(); - upnp_thread.reset(); +} + +void InterruptMapPort() +{ + if(g_upnp_thread.joinable()) { + g_upnp_interrupt(); + } +} + +void StopMapPort() +{ + if(g_upnp_thread.joinable()) { + g_upnp_thread.join(); + g_upnp_interrupt.reset(); } } #else -void MapPort(bool) +void StartMapPort() +{ + // Intentionally left blank. +} +void InterruptMapPort() +{ + // Intentionally left blank. +} +void StopMapPort() { // Intentionally left blank. } diff --git a/src/net.h b/src/net.h index 0542ec1aa..daa0eea8b 100644 --- a/src/net.h +++ b/src/net.h @@ -442,7 +442,9 @@ private: }; extern std::unique_ptr g_connman; void Discover(boost::thread_group& threadGroup); -void MapPort(bool fUseUPnP); +void StartMapPort(); +void InterruptMapPort(); +void StopMapPort(); unsigned short GetListenPort(); bool BindListenPort(const CService &bindAddr, std::string& strError, bool fWhitelisted = false); diff --git a/src/qt/optionsmodel.cpp b/src/qt/optionsmodel.cpp index 4ade88d84..909be1c26 100644 --- a/src/qt/optionsmodel.cpp +++ b/src/qt/optionsmodel.cpp @@ -315,7 +315,12 @@ bool OptionsModel::setData(const QModelIndex & index, const QVariant & value, in break; case MapPortUPnP: // core option - can be changed on-the-fly settings.setValue("fUseUPnP", value.toBool()); - MapPort(value.toBool()); + if (value.toBool()) { + StartMapPort(); + } else { + InterruptMapPort(); + StopMapPort(); + } break; case MinimizeOnClose: fMinimizeOnClose = value.toBool(); From ba917249486310985a34a5250bb570ca18821322 Mon Sep 17 00:00:00 2001 From: Cory Fields Date: Wed, 7 Feb 2018 17:42:39 -0500 Subject: [PATCH 2/4] boost: remove useless threadGroup parameter from Discover --- src/init.cpp | 2 +- src/net.cpp | 2 +- src/net.h | 6 +----- 3 files changed, 3 insertions(+), 7 deletions(-) diff --git a/src/init.cpp b/src/init.cpp index 2912beec6..9524da93c 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -1667,7 +1667,7 @@ bool AppInitMain() if (gArgs.GetBoolArg("-listenonion", DEFAULT_LISTEN_ONION)) StartTorControl(threadGroup, scheduler); - Discover(threadGroup); + Discover(); // Map ports with UPnP if (gArgs.GetBoolArg("-upnp", DEFAULT_UPNP)) { diff --git a/src/net.cpp b/src/net.cpp index 307e5d49d..201914685 100644 --- a/src/net.cpp +++ b/src/net.cpp @@ -2129,7 +2129,7 @@ bool CConnman::BindListenPort(const CService &addrBind, std::string& strError, b return true; } -void Discover(boost::thread_group& threadGroup) +void Discover() { if (!fDiscover) return; diff --git a/src/net.h b/src/net.h index daa0eea8b..8378a303b 100644 --- a/src/net.h +++ b/src/net.h @@ -37,10 +37,6 @@ class CScheduler; class CNode; -namespace boost { - class thread_group; -} // namespace boost - /** Time between pings automatically sent out for latency probing and keepalive (in seconds). */ static const int PING_INTERVAL = 2 * 60; /** Time after which to disconnect, after waiting for a ping response (or inactivity). */ @@ -441,7 +437,7 @@ private: friend struct CConnmanTest; }; extern std::unique_ptr g_connman; -void Discover(boost::thread_group& threadGroup); +void Discover(); void StartMapPort(); void InterruptMapPort(); void StopMapPort(); From 08272671d2218eb69589a0639cbb61ef7cde3004 Mon Sep 17 00:00:00 2001 From: Cory Fields Date: Wed, 7 Feb 2018 18:33:20 -0500 Subject: [PATCH 3/4] boost: drop boost threads from torcontrol --- src/init.cpp | 2 +- src/torcontrol.cpp | 6 +++--- src/torcontrol.h | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/init.cpp b/src/init.cpp index 9524da93c..9f61989a2 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -1665,7 +1665,7 @@ bool AppInitMain() LogPrintf("nBestHeight = %d\n", chain_active_height); if (gArgs.GetBoolArg("-listenonion", DEFAULT_LISTEN_ONION)) - StartTorControl(threadGroup, scheduler); + StartTorControl(); Discover(); diff --git a/src/torcontrol.cpp b/src/torcontrol.cpp index d875008ef..717d1cf7e 100644 --- a/src/torcontrol.cpp +++ b/src/torcontrol.cpp @@ -731,7 +731,7 @@ void TorController::reconnect_cb(evutil_socket_t fd, short what, void *arg) /****** Thread ********/ static struct event_base *gBase; -static boost::thread torControlThread; +static std::thread torControlThread; static void TorControlThread() { @@ -740,7 +740,7 @@ static void TorControlThread() event_base_dispatch(gBase); } -void StartTorControl(boost::thread_group& threadGroup, CScheduler& scheduler) +void StartTorControl() { assert(!gBase); #ifdef WIN32 @@ -754,7 +754,7 @@ void StartTorControl(boost::thread_group& threadGroup, CScheduler& scheduler) return; } - torControlThread = boost::thread(boost::bind(&TraceThread, "torcontrol", &TorControlThread)); + torControlThread = std::thread(std::bind(&TraceThread, "torcontrol", &TorControlThread)); } void InterruptTorControl() diff --git a/src/torcontrol.h b/src/torcontrol.h index 20514f7bb..2be6701fa 100644 --- a/src/torcontrol.h +++ b/src/torcontrol.h @@ -13,7 +13,7 @@ extern const std::string DEFAULT_TOR_CONTROL; static const bool DEFAULT_LISTEN_ONION = true; -void StartTorControl(boost::thread_group& threadGroup, CScheduler& scheduler); +void StartTorControl(); void InterruptTorControl(); void StopTorControl(); From 004f9999464c7ef4a57b281dcbb407e5d193e798 Mon Sep 17 00:00:00 2001 From: Cory Fields Date: Wed, 7 Feb 2018 19:19:34 -0500 Subject: [PATCH 4/4] boost: drop boost threads for [alert|block|wallet]notify --- src/init.cpp | 3 ++- src/validation.cpp | 3 ++- src/wallet/wallet.cpp | 4 ++-- 3 files changed, 6 insertions(+), 4 deletions(-) diff --git a/src/init.cpp b/src/init.cpp index 9f61989a2..ec2edd9ca 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -546,7 +546,8 @@ static void BlockNotifyCallback(bool initialSync, const CBlockIndex *pBlockIndex std::string strCmd = gArgs.GetArg("-blocknotify", ""); if (!strCmd.empty()) { boost::replace_all(strCmd, "%s", pBlockIndex->GetBlockHash().GetHex()); - boost::thread t(runCommand, strCmd); // thread runs free + std::thread t(runCommand, strCmd); + t.detach(); // thread runs free } } diff --git a/src/validation.cpp b/src/validation.cpp index 16b656c7f..6b02c0920 100644 --- a/src/validation.cpp +++ b/src/validation.cpp @@ -1188,7 +1188,8 @@ static void AlertNotify(const std::string& strMessage) safeStatus = singleQuote+safeStatus+singleQuote; boost::replace_all(strCmd, "%s", safeStatus); - boost::thread t(runCommand, strCmd); // thread runs free + std::thread t(runCommand, strCmd); + t.detach(); // thread runs free } static void CheckForkWarningConditions() diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp index 2b8019395..3b8ecce6d 100644 --- a/src/wallet/wallet.cpp +++ b/src/wallet/wallet.cpp @@ -34,7 +34,6 @@ #include #include -#include std::vector vpwallets; /** Transaction fee set by the user */ @@ -976,7 +975,8 @@ bool CWallet::AddToWallet(const CWalletTx& wtxIn, bool fFlushOnClose) if (!strCmd.empty()) { boost::replace_all(strCmd, "%s", wtxIn.GetHash().GetHex()); - boost::thread t(runCommand, strCmd); // thread runs free + std::thread t(runCommand, strCmd); + t.detach(); // thread runs free } return true;