@@ -1459,6 +1459,8 @@ void CConnman::WakeMessageHandler()
1459
1459
1460
1460
1461
1461
#ifdef USE_UPNP
1462
+ static CThreadInterrupt g_upnp_interrupt;
1463
+ static std::thread g_upnp_thread;
1462
1464
void ThreadMapPort ()
1463
1465
{
1464
1466
std::string port = strprintf (" %u" , GetListenPort ());
@@ -1509,35 +1511,29 @@ void ThreadMapPort()
1509
1511
1510
1512
std::string strDesc = " Bitcoin " + FormatFullVersion ();
1511
1513
1512
- try {
1513
- while (true ) {
1514
+ do {
1514
1515
#ifndef UPNPDISCOVER_SUCCESS
1515
- /* miniupnpc 1.5 */
1516
- r = UPNP_AddPortMapping (urls.controlURL , data.first .servicetype ,
1517
- port.c_str (), port.c_str (), lanaddr, strDesc.c_str (), " TCP" , 0 );
1516
+ /* miniupnpc 1.5 */
1517
+ r = UPNP_AddPortMapping (urls.controlURL , data.first .servicetype ,
1518
+ port.c_str (), port.c_str (), lanaddr, strDesc.c_str (), " TCP" , 0 );
1518
1519
#else
1519
- /* miniupnpc 1.6 */
1520
- r = UPNP_AddPortMapping (urls.controlURL , data.first .servicetype ,
1521
- port.c_str (), port.c_str (), lanaddr, strDesc.c_str (), " TCP" , 0 , " 0" );
1520
+ /* miniupnpc 1.6 */
1521
+ r = UPNP_AddPortMapping (urls.controlURL , data.first .servicetype ,
1522
+ port.c_str (), port.c_str (), lanaddr, strDesc.c_str (), " TCP" , 0 , " 0" );
1522
1523
#endif
1523
1524
1524
- if (r!=UPNPCOMMAND_SUCCESS)
1525
- LogPrintf (" AddPortMapping(%s, %s, %s) failed with code %d (%s)\n " ,
1526
- port, port, lanaddr, r, strupnperror (r));
1527
- else
1528
- LogPrintf (" UPnP Port Mapping successful.\n " );
1529
-
1530
- MilliSleep (20 *60 *1000 ); // Refresh every 20 minutes
1531
- }
1532
- }
1533
- catch (const boost::thread_interrupted&)
1534
- {
1535
- r = UPNP_DeletePortMapping (urls.controlURL , data.first .servicetype , port.c_str (), " TCP" , 0 );
1536
- LogPrintf (" UPNP_DeletePortMapping() returned: %d\n " , r);
1537
- freeUPNPDevlist (devlist); devlist = nullptr ;
1538
- FreeUPNPUrls (&urls);
1539
- throw ;
1525
+ if (r!=UPNPCOMMAND_SUCCESS)
1526
+ LogPrintf (" AddPortMapping(%s, %s, %s) failed with code %d (%s)\n " ,
1527
+ port, port, lanaddr, r, strupnperror (r));
1528
+ else
1529
+ LogPrintf (" UPnP Port Mapping successful.\n " );
1540
1530
}
1531
+ while (g_upnp_interrupt.sleep_for (std::chrono::minutes (20 )));
1532
+
1533
+ r = UPNP_DeletePortMapping (urls.controlURL , data.first .servicetype , port.c_str (), " TCP" , 0 );
1534
+ LogPrintf (" UPNP_DeletePortMapping() returned: %d\n " , r);
1535
+ freeUPNPDevlist (devlist); devlist = nullptr ;
1536
+ FreeUPNPUrls (&urls);
1541
1537
} else {
1542
1538
LogPrintf (" No valid UPnP IGDs found\n " );
1543
1539
freeUPNPDevlist (devlist); devlist = nullptr ;
@@ -1546,27 +1542,39 @@ void ThreadMapPort()
1546
1542
}
1547
1543
}
1548
1544
1549
- void MapPort ( bool fUseUPnP )
1545
+ void StartMapPort ( )
1550
1546
{
1551
- static std::unique_ptr<boost::thread> upnp_thread;
1547
+ if (!g_upnp_thread.joinable ()) {
1548
+ assert (!g_upnp_interrupt);
1549
+ g_upnp_thread = std::thread ((std::bind (&TraceThread<void (*)()>, " upnp" , &ThreadMapPort)));
1550
+ }
1551
+ }
1552
1552
1553
- if (fUseUPnP )
1554
- {
1555
- if (upnp_thread) {
1556
- upnp_thread->interrupt ();
1557
- upnp_thread->join ();
1558
- }
1559
- upnp_thread.reset (new boost::thread (boost::bind (&TraceThread<void (*)()>, " upnp" , &ThreadMapPort)));
1553
+ void InterruptMapPort ()
1554
+ {
1555
+ if (g_upnp_thread.joinable ()) {
1556
+ g_upnp_interrupt ();
1560
1557
}
1561
- else if (upnp_thread) {
1562
- upnp_thread->interrupt ();
1563
- upnp_thread->join ();
1564
- upnp_thread.reset ();
1558
+ }
1559
+
1560
+ void StopMapPort ()
1561
+ {
1562
+ if (g_upnp_thread.joinable ()) {
1563
+ g_upnp_thread.join ();
1564
+ g_upnp_interrupt.reset ();
1565
1565
}
1566
1566
}
1567
1567
1568
1568
#else
1569
- void MapPort (bool )
1569
+ void StartMapPort ()
1570
+ {
1571
+ // Intentionally left blank.
1572
+ }
1573
+ void InterruptMapPort ()
1574
+ {
1575
+ // Intentionally left blank.
1576
+ }
1577
+ void StopMapPort ()
1570
1578
{
1571
1579
// Intentionally left blank.
1572
1580
}
0 commit comments