aboutsummaryrefslogtreecommitdiff
path: root/src/net.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/net.cpp')
-rw-r--r--src/net.cpp84
1 files changed, 46 insertions, 38 deletions
diff --git a/src/net.cpp b/src/net.cpp
index 03ed7e7fc1..307e5d49d5 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.
}