aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/init.cpp14
-rw-r--r--src/net.cpp86
-rw-r--r--src/net.h10
-rw-r--r--src/qt/optionsmodel.cpp7
-rw-r--r--src/torcontrol.cpp6
-rw-r--r--src/torcontrol.h2
-rw-r--r--src/validation.cpp3
-rw-r--r--src/wallet/wallet.cpp4
8 files changed, 74 insertions, 58 deletions
diff --git a/src/init.cpp b/src/init.cpp
index 4ff875f9aa..b28baba779 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.
@@ -545,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
}
}
@@ -1674,12 +1676,14 @@ bool AppInitMain()
LogPrintf("nBestHeight = %d\n", chain_active_height);
if (gArgs.GetBoolArg("-listenonion", DEFAULT_LISTEN_ONION))
- StartTorControl(threadGroup, scheduler);
+ StartTorControl();
- Discover(threadGroup);
+ Discover();
// 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 03ed7e7fc1..201914685c 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");
-
- 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;
+ 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)));
+
+ 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<boost::thread> upnp_thread;
+ if (!g_upnp_thread.joinable()) {
+ assert(!g_upnp_interrupt);
+ g_upnp_thread = std::thread((std::bind(&TraceThread<void (*)()>, "upnp", &ThreadMapPort)));
+ }
+}
- if (fUseUPnP)
- {
- if (upnp_thread) {
- upnp_thread->interrupt();
- upnp_thread->join();
- }
- upnp_thread.reset(new boost::thread(boost::bind(&TraceThread<void (*)()>, "upnp", &ThreadMapPort)));
+void InterruptMapPort()
+{
+ if(g_upnp_thread.joinable()) {
+ g_upnp_interrupt();
}
- else if (upnp_thread) {
- upnp_thread->interrupt();
- upnp_thread->join();
- upnp_thread.reset();
+}
+
+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.
}
@@ -2121,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 0542ec1aaa..8378a303b8 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,8 +437,10 @@ private:
friend struct CConnmanTest;
};
extern std::unique_ptr<CConnman> g_connman;
-void Discover(boost::thread_group& threadGroup);
-void MapPort(bool fUseUPnP);
+void Discover();
+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 4ade88d843..909be1c264 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();
diff --git a/src/torcontrol.cpp b/src/torcontrol.cpp
index d875008ef2..717d1cf7e5 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<void (*)()>, "torcontrol", &TorControlThread));
+ torControlThread = std::thread(std::bind(&TraceThread<void (*)()>, "torcontrol", &TorControlThread));
}
void InterruptTorControl()
diff --git a/src/torcontrol.h b/src/torcontrol.h
index 20514f7bbf..2be6701fa5 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();
diff --git a/src/validation.cpp b/src/validation.cpp
index 978aaf7d06..371460a6f0 100644
--- a/src/validation.cpp
+++ b/src/validation.cpp
@@ -1182,7 +1182,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 7f36aefeaf..513819606b 100644
--- a/src/wallet/wallet.cpp
+++ b/src/wallet/wallet.cpp
@@ -34,7 +34,6 @@
#include <future>
#include <boost/algorithm/string/replace.hpp>
-#include <boost/thread.hpp>
std::vector<CWalletRef> 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;