40
40
#include < miniupnpc/upnperrors.h>
41
41
#endif
42
42
43
- #include < boost/filesystem.hpp>
44
- #include < boost/thread.hpp>
45
43
46
44
#include < math.h>
47
45
@@ -1071,7 +1069,7 @@ void CConnman::AcceptConnection(const ListenSocket& hListenSocket) {
1071
1069
void CConnman::ThreadSocketHandler ()
1072
1070
{
1073
1071
unsigned int nPrevNodeCount = 0 ;
1074
- while (true )
1072
+ while (!interruptNet )
1075
1073
{
1076
1074
//
1077
1075
// Disconnect nodes
@@ -1211,7 +1209,8 @@ void CConnman::ThreadSocketHandler()
1211
1209
1212
1210
int nSelect = select (have_fds ? hSocketMax + 1 : 0 ,
1213
1211
&fdsetRecv, &fdsetSend, &fdsetError, &timeout);
1214
- boost::this_thread::interruption_point ();
1212
+ if (interruptNet)
1213
+ return ;
1215
1214
1216
1215
if (nSelect == SOCKET_ERROR)
1217
1216
{
@@ -1224,7 +1223,8 @@ void CConnman::ThreadSocketHandler()
1224
1223
}
1225
1224
FD_ZERO (&fdsetSend);
1226
1225
FD_ZERO (&fdsetError);
1227
- MilliSleep (timeout.tv_usec /1000 );
1226
+ if (!interruptNet.sleep_for (std::chrono::milliseconds (timeout.tv_usec /1000 )))
1227
+ return ;
1228
1228
}
1229
1229
1230
1230
//
@@ -1244,7 +1244,8 @@ void CConnman::ThreadSocketHandler()
1244
1244
std::vector<CNode*> vNodesCopy = CopyNodeVector ();
1245
1245
BOOST_FOREACH (CNode* pnode, vNodesCopy)
1246
1246
{
1247
- boost::this_thread::interruption_point ();
1247
+ if (interruptNet)
1248
+ return ;
1248
1249
1249
1250
//
1250
1251
// Receive
@@ -1266,7 +1267,7 @@ void CConnman::ThreadSocketHandler()
1266
1267
if (!pnode->ReceiveMsgBytes (pchBuf, nBytes, notify))
1267
1268
pnode->CloseSocketDisconnect ();
1268
1269
if (notify)
1269
- messageHandlerCondition .notify_one ();
1270
+ condMsgProc .notify_one ();
1270
1271
pnode->nLastRecv = GetTime ();
1271
1272
pnode->nRecvBytes += nBytes;
1272
1273
RecordBytesRecv (nBytes);
@@ -1471,7 +1472,8 @@ void CConnman::ThreadDNSAddressSeed()
1471
1472
// goal: only query DNS seeds if address need is acute
1472
1473
if ((addrman.size () > 0 ) &&
1473
1474
(!GetBoolArg (" -forcednsseed" , DEFAULT_FORCEDNSSEED))) {
1474
- MilliSleep (11 * 1000 );
1475
+ if (!interruptNet.sleep_for (std::chrono::seconds (11 )))
1476
+ return ;
1475
1477
1476
1478
LOCK (cs_vNodes);
1477
1479
if (vNodes.size () >= 2 ) {
@@ -1569,10 +1571,12 @@ void CConnman::ThreadOpenConnections()
1569
1571
OpenNetworkConnection (addr, NULL , strAddr.c_str ());
1570
1572
for (int i = 0 ; i < 10 && i < nLoop; i++)
1571
1573
{
1572
- MilliSleep (500 );
1574
+ if (!interruptNet.sleep_for (std::chrono::milliseconds (500 )))
1575
+ return ;
1573
1576
}
1574
1577
}
1575
- MilliSleep (500 );
1578
+ if (!interruptNet.sleep_for (std::chrono::milliseconds (500 )))
1579
+ return ;
1576
1580
}
1577
1581
}
1578
1582
@@ -1581,14 +1585,16 @@ void CConnman::ThreadOpenConnections()
1581
1585
1582
1586
// Minimum time before next feeler connection (in microseconds).
1583
1587
int64_t nNextFeeler = PoissonNextSend (nStart*1000 *1000 , FEELER_INTERVAL);
1584
- while (true )
1588
+ while (!interruptNet )
1585
1589
{
1586
1590
ProcessOneShot ();
1587
1591
1588
- MilliSleep (500 );
1592
+ if (!interruptNet.sleep_for (std::chrono::milliseconds (500 )))
1593
+ return ;
1589
1594
1590
1595
CSemaphoreGrant grant (*semOutbound);
1591
- boost::this_thread::interruption_point ();
1596
+ if (interruptNet)
1597
+ return ;
1592
1598
1593
1599
// Add seed nodes if DNS seeds are all down (an infrastructure attack?).
1594
1600
if (addrman.size () == 0 && (GetTime () - nStart > 60 )) {
@@ -1645,7 +1651,7 @@ void CConnman::ThreadOpenConnections()
1645
1651
1646
1652
int64_t nANow = GetAdjustedTime ();
1647
1653
int nTries = 0 ;
1648
- while (true )
1654
+ while (!interruptNet )
1649
1655
{
1650
1656
CAddrInfo addr = addrman.Select (fFeeler );
1651
1657
@@ -1684,7 +1690,8 @@ void CConnman::ThreadOpenConnections()
1684
1690
if (fFeeler ) {
1685
1691
// Add small amount of random noise before connection to avoid synchronization.
1686
1692
int randsleep = GetRandInt (FEELER_SLEEP_WINDOW * 1000 );
1687
- MilliSleep (randsleep);
1693
+ if (!interruptNet.sleep_for (std::chrono::milliseconds (randsleep)))
1694
+ return ;
1688
1695
LogPrint (" net" , " Making feeler connection to %s\n " , addrConnect.ToString ());
1689
1696
}
1690
1697
@@ -1762,11 +1769,12 @@ void CConnman::ThreadOpenAddedConnections()
1762
1769
// OpenNetworkConnection can detect existing connections to that IP/port.
1763
1770
CService service (info.strAddedNode , Params ().GetDefaultPort ());
1764
1771
OpenNetworkConnection (CAddress (service, NODE_NONE), &grant, info.strAddedNode .c_str (), false );
1765
- MilliSleep (500 );
1772
+ if (!interruptNet.sleep_for (std::chrono::milliseconds (500 )))
1773
+ return ;
1766
1774
}
1767
1775
}
1768
-
1769
- MilliSleep ( 120000 ); // Retry every 2 minutes
1776
+ if (!interruptNet. sleep_for ( std::chrono::minutes ( 2 )))
1777
+ return ;
1770
1778
}
1771
1779
}
1772
1780
@@ -1776,12 +1784,14 @@ void CConnman::ThreadMnbRequestConnections()
1776
1784
if (mapArgs.count (" -connect" ) && mapMultiArgs[" -connect" ].size () > 0 )
1777
1785
return ;
1778
1786
1779
- while (true )
1787
+ while (!interruptNet )
1780
1788
{
1781
- MilliSleep (1000 );
1789
+ if (!interruptNet.sleep_for (std::chrono::milliseconds (1000 )))
1790
+ return ;
1782
1791
1783
1792
CSemaphoreGrant grant (*semMasternodeOutbound);
1784
- boost::this_thread::interruption_point ();
1793
+ if (interruptNet)
1794
+ return ;
1785
1795
1786
1796
std::pair<CService, std::set<uint256> > p = mnodeman.PopScheduledMnbRequestConnection ();
1787
1797
if (p.first == CService () || p.second .empty ()) continue ;
@@ -1820,7 +1830,9 @@ bool CConnman::OpenNetworkConnection(const CAddress& addrConnect, CSemaphoreGran
1820
1830
//
1821
1831
// Initiate outbound network connection
1822
1832
//
1823
- boost::this_thread::interruption_point ();
1833
+ if (interruptNet) {
1834
+ return false ;
1835
+ }
1824
1836
if (!pszDest) {
1825
1837
if (IsLocal (addrConnect) ||
1826
1838
FindNode ((CNetAddr)addrConnect) || IsBanned (addrConnect) ||
@@ -1830,7 +1842,6 @@ bool CConnman::OpenNetworkConnection(const CAddress& addrConnect, CSemaphoreGran
1830
1842
return false ;
1831
1843
1832
1844
CNode* pnode = ConnectNode (addrConnect, pszDest);
1833
- boost::this_thread::interruption_point ();
1834
1845
1835
1846
if (!pnode)
1836
1847
return false ;
@@ -1844,14 +1855,10 @@ bool CConnman::OpenNetworkConnection(const CAddress& addrConnect, CSemaphoreGran
1844
1855
return true ;
1845
1856
}
1846
1857
1847
-
1848
1858
void CConnman::ThreadMessageHandler ()
1849
1859
{
1850
- boost::mutex condition_mutex;
1851
- boost::unique_lock<boost::mutex> lock (condition_mutex);
1852
-
1853
1860
SetThreadPriority (THREAD_PRIORITY_BELOW_NORMAL);
1854
- while (true )
1861
+ while (!flagInterruptMsgProc )
1855
1862
{
1856
1863
std::vector<CNode*> vNodesCopy = CopyNodeVector ();
1857
1864
@@ -1867,7 +1874,7 @@ void CConnman::ThreadMessageHandler()
1867
1874
TRY_LOCK (pnode->cs_vRecvMsg , lockRecv);
1868
1875
if (lockRecv)
1869
1876
{
1870
- if (!GetNodeSignals ().ProcessMessages (pnode, *this ))
1877
+ if (!GetNodeSignals ().ProcessMessages (pnode, *this , flagInterruptMsgProc ))
1871
1878
pnode->fDisconnect = true ;
1872
1879
1873
1880
if (pnode->nSendSize < GetSendBufferSize ())
@@ -1879,21 +1886,25 @@ void CConnman::ThreadMessageHandler()
1879
1886
}
1880
1887
}
1881
1888
}
1882
- boost::this_thread::interruption_point ();
1889
+ if (flagInterruptMsgProc)
1890
+ return ;
1883
1891
1884
1892
// Send messages
1885
1893
{
1886
1894
TRY_LOCK (pnode->cs_vSend , lockSend);
1887
1895
if (lockSend)
1888
- GetNodeSignals ().SendMessages (pnode, *this );
1896
+ GetNodeSignals ().SendMessages (pnode, *this , flagInterruptMsgProc );
1889
1897
}
1890
- boost::this_thread::interruption_point ();
1898
+ if (flagInterruptMsgProc)
1899
+ return ;
1891
1900
}
1892
1901
1893
1902
ReleaseNodeVector (vNodesCopy);
1894
1903
1895
- if (fSleep )
1896
- messageHandlerCondition.timed_wait (lock, boost::posix_time::microsec_clock::universal_time () + boost::posix_time::milliseconds (100 ));
1904
+ if (fSleep ) {
1905
+ std::unique_lock<std::mutex> lock (mutexMsgProc);
1906
+ condMsgProc.wait_until (lock, std::chrono::steady_clock::now () + std::chrono::milliseconds (100 ));
1907
+ }
1897
1908
}
1898
1909
}
1899
1910
@@ -2064,14 +2075,15 @@ CConnman::CConnman()
2064
2075
nMaxOutbound = 0 ;
2065
2076
nBestHeight = 0 ;
2066
2077
clientInterface = NULL ;
2078
+ flagInterruptMsgProc = false ;
2067
2079
}
2068
2080
2069
2081
NodeId CConnman::GetNewNodeId ()
2070
2082
{
2071
2083
return nLastNodeId.fetch_add (1 , std::memory_order_relaxed);
2072
2084
}
2073
2085
2074
- bool CConnman::Start (boost::thread_group& threadGroup, CScheduler& scheduler, std::string& strNodeError, Options connOptions)
2086
+ bool CConnman::Start (CScheduler& scheduler, std::string& strNodeError, Options connOptions)
2075
2087
{
2076
2088
nTotalBytesRecv = 0 ;
2077
2089
nTotalBytesSent = 0 ;
@@ -2145,26 +2157,29 @@ bool CConnman::Start(boost::thread_group& threadGroup, CScheduler& scheduler, st
2145
2157
//
2146
2158
// Start threads
2147
2159
//
2160
+ InterruptSocks5 (false );
2161
+ interruptNet.reset ();
2162
+ flagInterruptMsgProc = false ;
2163
+
2164
+ // Send and receive from sockets, accept connections
2165
+ threadSocketHandler = std::thread (&TraceThread<std::function<void ()> >, " net" , std::function<void ()>(std::bind (&CConnman::ThreadSocketHandler, this )));
2148
2166
2149
2167
if (!GetBoolArg (" -dnsseed" , true ))
2150
2168
LogPrintf (" DNS seeding disabled\n " );
2151
2169
else
2152
- threadGroup.create_thread (boost::bind (&TraceThread<boost::function<void ()> >, " dnsseed" , boost::function<void ()>(boost::bind (&CConnman::ThreadDNSAddressSeed, this ))));
2153
-
2154
- // Send and receive from sockets, accept connections
2155
- threadGroup.create_thread (boost::bind (&TraceThread<boost::function<void ()> >, " net" , boost::function<void ()>(boost::bind (&CConnman::ThreadSocketHandler, this ))));
2170
+ threadDNSAddressSeed = std::thread (&TraceThread<std::function<void ()> >, " dnsseed" , std::function<void ()>(std::bind (&CConnman::ThreadDNSAddressSeed, this )));
2156
2171
2157
2172
// Initiate outbound connections from -addnode
2158
- threadGroup. create_thread ( boost::bind (&TraceThread<boost ::function<void ()> >, " addcon" , boost ::function<void ()>(boost ::bind (&CConnman::ThreadOpenAddedConnections, this ) )));
2173
+ threadOpenAddedConnections = std::thread (&TraceThread<std ::function<void ()> >, " addcon" , std ::function<void ()>(std ::bind (&CConnman::ThreadOpenAddedConnections, this )));
2159
2174
2160
2175
// Initiate outbound connections
2161
- threadGroup. create_thread ( boost::bind (&TraceThread<boost ::function<void ()> >, " opencon" , boost ::function<void ()>(boost ::bind (&CConnman::ThreadOpenConnections, this ) )));
2176
+ threadOpenConnections = std::thread (&TraceThread<std ::function<void ()> >, " opencon" , std ::function<void ()>(std ::bind (&CConnman::ThreadOpenConnections, this )));
2162
2177
2163
2178
// Initiate masternode connections
2164
- threadGroup. create_thread ( boost::bind (&TraceThread<boost ::function<void ()> >, " mnbcon" , boost ::function<void ()>(boost ::bind (&CConnman::ThreadMnbRequestConnections, this ) )));
2179
+ threadMnbRequestConnections = std::thread (&TraceThread<std ::function<void ()> >, " mnbcon" , std ::function<void ()>(std ::bind (&CConnman::ThreadMnbRequestConnections, this )));
2165
2180
2166
2181
// Process messages
2167
- threadGroup. create_thread ( boost::bind (&TraceThread<boost ::function<void ()> >, " msghand" , boost ::function<void ()>(boost ::bind (&CConnman::ThreadMessageHandler, this ) )));
2182
+ threadMessageHandler = std::thread (&TraceThread<std ::function<void ()> >, " msghand" , std ::function<void ()>(std ::bind (&CConnman::ThreadMessageHandler, this )));
2168
2183
2169
2184
// Dump network addresses
2170
2185
scheduler.scheduleEvery (boost::bind (&CConnman::DumpData, this ), DUMP_ADDRESSES_INTERVAL);
@@ -2195,12 +2210,36 @@ void CExplicitNetCleanup::callCleanup()
2195
2210
delete tmp; // Stroustrup's gonna kill me for that
2196
2211
}
2197
2212
2198
- void CConnman::Stop ()
2213
+ void CConnman::Interrupt ()
2199
2214
{
2200
- LogPrintf (" %s\n " ,__func__);
2215
+ {
2216
+ std::lock_guard<std::mutex> lock (mutexMsgProc);
2217
+ flagInterruptMsgProc = true ;
2218
+ }
2219
+ condMsgProc.notify_all ();
2220
+
2221
+ interruptNet ();
2222
+ InterruptSocks5 (true );
2223
+
2201
2224
if (semOutbound)
2202
2225
for (int i=0 ; i<(nMaxOutbound + nMaxFeeler); i++)
2203
2226
semOutbound->post ();
2227
+ }
2228
+
2229
+ void CConnman::Stop ()
2230
+ {
2231
+ if (threadMessageHandler.joinable ())
2232
+ threadMessageHandler.join ();
2233
+ if (threadMnbRequestConnections.joinable ())
2234
+ threadMnbRequestConnections.join ();
2235
+ if (threadOpenConnections.joinable ())
2236
+ threadOpenConnections.join ();
2237
+ if (threadOpenAddedConnections.joinable ())
2238
+ threadOpenAddedConnections.join ();
2239
+ if (threadDNSAddressSeed.joinable ())
2240
+ threadDNSAddressSeed.join ();
2241
+ if (threadSocketHandler.joinable ())
2242
+ threadSocketHandler.join ();
2204
2243
2205
2244
if (semMasternodeOutbound)
2206
2245
for (int i=0 ; i<MAX_OUTBOUND_MASTERNODE_CONNECTIONS; i++)
@@ -2252,6 +2291,7 @@ void CConnman::DeleteNode(CNode* pnode)
2252
2291
2253
2292
CConnman::~CConnman ()
2254
2293
{
2294
+ Interrupt ();
2255
2295
Stop ();
2256
2296
}
2257
2297
0 commit comments