@@ -1042,7 +1042,7 @@ void CConnman::AcceptConnection(const ListenSocket& hListenSocket) {
1042
1042
void CConnman::ThreadSocketHandler ()
1043
1043
{
1044
1044
unsigned int nPrevNodeCount = 0 ;
1045
- while (true )
1045
+ while (!interruptNet )
1046
1046
{
1047
1047
//
1048
1048
// Disconnect nodes
@@ -1180,7 +1180,8 @@ void CConnman::ThreadSocketHandler()
1180
1180
1181
1181
int nSelect = select (have_fds ? hSocketMax + 1 : 0 ,
1182
1182
&fdsetRecv, &fdsetSend, &fdsetError, &timeout);
1183
- boost::this_thread::interruption_point ();
1183
+ if (interruptNet)
1184
+ return ;
1184
1185
1185
1186
if (nSelect == SOCKET_ERROR)
1186
1187
{
@@ -1193,7 +1194,8 @@ void CConnman::ThreadSocketHandler()
1193
1194
}
1194
1195
FD_ZERO (&fdsetSend);
1195
1196
FD_ZERO (&fdsetError);
1196
- MilliSleep (timeout.tv_usec /1000 );
1197
+ if (!interruptNet.sleep_for (std::chrono::milliseconds (timeout.tv_usec /1000 )))
1198
+ return ;
1197
1199
}
1198
1200
1199
1201
//
@@ -1219,7 +1221,8 @@ void CConnman::ThreadSocketHandler()
1219
1221
}
1220
1222
BOOST_FOREACH (CNode* pnode, vNodesCopy)
1221
1223
{
1222
- boost::this_thread::interruption_point ();
1224
+ if (interruptNet)
1225
+ return ;
1223
1226
1224
1227
//
1225
1228
// Receive
@@ -1241,7 +1244,7 @@ void CConnman::ThreadSocketHandler()
1241
1244
if (!pnode->ReceiveMsgBytes (pchBuf, nBytes, notify))
1242
1245
pnode->CloseSocketDisconnect ();
1243
1246
if (notify)
1244
- messageHandlerCondition .notify_one ();
1247
+ condMsgProc .notify_one ();
1245
1248
pnode->nLastRecv = GetTime ();
1246
1249
pnode->nRecvBytes += nBytes;
1247
1250
RecordBytesRecv (nBytes);
@@ -1469,7 +1472,8 @@ void CConnman::ThreadDNSAddressSeed()
1469
1472
// less influence on the network topology, and reduces traffic to the seeds.
1470
1473
if ((addrman.size () > 0 ) &&
1471
1474
(!GetBoolArg (" -forcednsseed" , DEFAULT_FORCEDNSSEED))) {
1472
- MilliSleep (11 * 1000 );
1475
+ if (!interruptNet.sleep_for (std::chrono::seconds (11 )))
1476
+ return ;
1473
1477
1474
1478
LOCK (cs_vNodes);
1475
1479
int nRelevant = 0 ;
@@ -1580,10 +1584,12 @@ void CConnman::ThreadOpenConnections()
1580
1584
OpenNetworkConnection (addr, false , NULL , strAddr.c_str ());
1581
1585
for (int i = 0 ; i < 10 && i < nLoop; i++)
1582
1586
{
1583
- MilliSleep (500 );
1587
+ if (!interruptNet.sleep_for (std::chrono::milliseconds (500 )))
1588
+ return ;
1584
1589
}
1585
1590
}
1586
- MilliSleep (500 );
1591
+ if (!interruptNet.sleep_for (std::chrono::milliseconds (500 )))
1592
+ return ;
1587
1593
}
1588
1594
}
1589
1595
@@ -1592,14 +1598,16 @@ void CConnman::ThreadOpenConnections()
1592
1598
1593
1599
// Minimum time before next feeler connection (in microseconds).
1594
1600
int64_t nNextFeeler = PoissonNextSend (nStart*1000 *1000 , FEELER_INTERVAL);
1595
- while (true )
1601
+ while (!interruptNet )
1596
1602
{
1597
1603
ProcessOneShot ();
1598
1604
1599
- MilliSleep (500 );
1605
+ if (!interruptNet.sleep_for (std::chrono::milliseconds (500 )))
1606
+ return ;
1600
1607
1601
1608
CSemaphoreGrant grant (*semOutbound);
1602
- boost::this_thread::interruption_point ();
1609
+ if (interruptNet)
1610
+ return ;
1603
1611
1604
1612
// Add seed nodes if DNS seeds are all down (an infrastructure attack?).
1605
1613
if (addrman.size () == 0 && (GetTime () - nStart > 60 )) {
@@ -1657,7 +1665,7 @@ void CConnman::ThreadOpenConnections()
1657
1665
1658
1666
int64_t nANow = GetAdjustedTime ();
1659
1667
int nTries = 0 ;
1660
- while (true )
1668
+ while (!interruptNet )
1661
1669
{
1662
1670
CAddrInfo addr = addrman.Select (fFeeler );
1663
1671
@@ -1700,7 +1708,8 @@ void CConnman::ThreadOpenConnections()
1700
1708
if (fFeeler ) {
1701
1709
// Add small amount of random noise before connection to avoid synchronization.
1702
1710
int randsleep = GetRandInt (FEELER_SLEEP_WINDOW * 1000 );
1703
- MilliSleep (randsleep);
1711
+ if (!interruptNet.sleep_for (std::chrono::milliseconds (randsleep)))
1712
+ return ;
1704
1713
LogPrint (" net" , " Making feeler connection to %s\n " , addrConnect.ToString ());
1705
1714
}
1706
1715
@@ -1779,11 +1788,12 @@ void CConnman::ThreadOpenAddedConnections()
1779
1788
// OpenNetworkConnection can detect existing connections to that IP/port.
1780
1789
CService service (LookupNumeric (info.strAddedNode .c_str (), Params ().GetDefaultPort ()));
1781
1790
OpenNetworkConnection (CAddress (service, NODE_NONE), false , &grant, info.strAddedNode .c_str (), false );
1782
- MilliSleep (500 );
1791
+ if (!interruptNet.sleep_for (std::chrono::milliseconds (500 )))
1792
+ return ;
1783
1793
}
1784
1794
}
1785
-
1786
- MilliSleep ( 120000 ); // Retry every 2 minutes
1795
+ if (!interruptNet. sleep_for ( std::chrono::minutes ( 2 )))
1796
+ return ;
1787
1797
}
1788
1798
}
1789
1799
@@ -1793,7 +1803,9 @@ bool CConnman::OpenNetworkConnection(const CAddress& addrConnect, bool fCountFai
1793
1803
//
1794
1804
// Initiate outbound network connection
1795
1805
//
1796
- boost::this_thread::interruption_point ();
1806
+ if (interruptNet) {
1807
+ return false ;
1808
+ }
1797
1809
if (!fNetworkActive ) {
1798
1810
return false ;
1799
1811
}
@@ -1819,13 +1831,9 @@ bool CConnman::OpenNetworkConnection(const CAddress& addrConnect, bool fCountFai
1819
1831
return true ;
1820
1832
}
1821
1833
1822
-
1823
1834
void CConnman::ThreadMessageHandler ()
1824
1835
{
1825
- boost::mutex condition_mutex;
1826
- boost::unique_lock<boost::mutex> lock (condition_mutex);
1827
-
1828
- while (true )
1836
+ while (!flagInterruptMsgProc)
1829
1837
{
1830
1838
std::vector<CNode*> vNodesCopy;
1831
1839
{
@@ -1860,15 +1868,17 @@ void CConnman::ThreadMessageHandler()
1860
1868
}
1861
1869
}
1862
1870
}
1863
- boost::this_thread::interruption_point ();
1871
+ if (flagInterruptMsgProc)
1872
+ return ;
1864
1873
1865
1874
// Send messages
1866
1875
{
1867
1876
TRY_LOCK (pnode->cs_vSend , lockSend);
1868
1877
if (lockSend)
1869
1878
GetNodeSignals ().SendMessages (pnode, *this );
1870
1879
}
1871
- boost::this_thread::interruption_point ();
1880
+ if (flagInterruptMsgProc)
1881
+ return ;
1872
1882
}
1873
1883
1874
1884
{
@@ -1877,8 +1887,10 @@ void CConnman::ThreadMessageHandler()
1877
1887
pnode->Release ();
1878
1888
}
1879
1889
1880
- if (fSleep )
1881
- messageHandlerCondition.timed_wait (lock, boost::posix_time::microsec_clock::universal_time () + boost::posix_time::milliseconds (100 ));
1890
+ if (fSleep ) {
1891
+ std::unique_lock<std::mutex> lock (mutexMsgProc);
1892
+ condMsgProc.wait_until (lock, std::chrono::steady_clock::now () + std::chrono::milliseconds (100 ));
1893
+ }
1882
1894
}
1883
1895
}
1884
1896
@@ -2070,14 +2082,15 @@ CConnman::CConnman(uint64_t nSeed0In, uint64_t nSeed1In) : nSeed0(nSeed0In), nSe
2070
2082
nMaxOutbound = 0 ;
2071
2083
nBestHeight = 0 ;
2072
2084
clientInterface = NULL ;
2085
+ flagInterruptMsgProc = false ;
2073
2086
}
2074
2087
2075
2088
NodeId CConnman::GetNewNodeId ()
2076
2089
{
2077
2090
return nLastNodeId.fetch_add (1 , std::memory_order_relaxed);
2078
2091
}
2079
2092
2080
- bool CConnman::Start (boost::thread_group& threadGroup, CScheduler& scheduler, std::string& strNodeError, Options connOptions)
2093
+ bool CConnman::Start (CScheduler& scheduler, std::string& strNodeError, Options connOptions)
2081
2094
{
2082
2095
nTotalBytesRecv = 0 ;
2083
2096
nTotalBytesSent = 0 ;
@@ -2144,24 +2157,26 @@ bool CConnman::Start(boost::thread_group& threadGroup, CScheduler& scheduler, st
2144
2157
//
2145
2158
// Start threads
2146
2159
//
2160
+ interruptNet.reset ();
2161
+ flagInterruptMsgProc = false ;
2147
2162
2148
2163
// Send and receive from sockets, accept connections
2149
- threadGroup. create_thread ( boost::bind (&TraceThread<boost ::function<void ()> >, " net" , boost ::function<void ()>(boost ::bind (&CConnman::ThreadSocketHandler, this ) )));
2164
+ threadSocketHandler = std::thread (&TraceThread<std ::function<void ()> >, " net" , std ::function<void ()>(std ::bind (&CConnman::ThreadSocketHandler, this )));
2150
2165
2151
2166
if (!GetBoolArg (" -dnsseed" , true ))
2152
2167
LogPrintf (" DNS seeding disabled\n " );
2153
2168
else
2154
- threadGroup. create_thread ( boost::bind (&TraceThread<boost ::function<void ()> >, " dnsseed" , boost ::function<void ()>(boost ::bind (&CConnman::ThreadDNSAddressSeed, this ) )));
2169
+ threadDNSAddressSeed = std::thread (&TraceThread<std ::function<void ()> >, " dnsseed" , std ::function<void ()>(std ::bind (&CConnman::ThreadDNSAddressSeed, this )));
2155
2170
2156
2171
// Initiate outbound connections from -addnode
2157
- threadGroup. create_thread ( boost::bind (&TraceThread<boost ::function<void ()> >, " addcon" , boost ::function<void ()>(boost ::bind (&CConnman::ThreadOpenAddedConnections, this ) )));
2172
+ threadOpenAddedConnections = std::thread (&TraceThread<std ::function<void ()> >, " addcon" , std ::function<void ()>(std ::bind (&CConnman::ThreadOpenAddedConnections, this )));
2158
2173
2159
2174
// Initiate outbound connections unless connect=0
2160
2175
if (!mapMultiArgs.count (" -connect" ) || mapMultiArgs.at (" -connect" ).size () != 1 || mapMultiArgs.at (" -connect" )[0 ] != " 0" )
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
// Process messages
2164
- threadGroup. create_thread ( boost::bind (&TraceThread<boost ::function<void ()> >, " msghand" , boost ::function<void ()>(boost ::bind (&CConnman::ThreadMessageHandler, this ) )));
2179
+ threadMessageHandler = std::thread (&TraceThread<std ::function<void ()> >, " msghand" , std ::function<void ()>(std ::bind (&CConnman::ThreadMessageHandler, this )));
2165
2180
2166
2181
// Dump network addresses
2167
2182
scheduler.scheduleEvery (boost::bind (&CConnman::DumpData, this ), DUMP_ADDRESSES_INTERVAL);
@@ -2184,12 +2199,33 @@ class CNetCleanup
2184
2199
}
2185
2200
instance_of_cnetcleanup;
2186
2201
2187
- void CConnman::Stop ()
2202
+ void CConnman::Interrupt ()
2188
2203
{
2189
- LogPrintf (" %s\n " ,__func__);
2204
+ {
2205
+ std::lock_guard<std::mutex> lock (mutexMsgProc);
2206
+ flagInterruptMsgProc = true ;
2207
+ }
2208
+ condMsgProc.notify_all ();
2209
+
2210
+ interruptNet ();
2211
+
2190
2212
if (semOutbound)
2191
2213
for (int i=0 ; i<(nMaxOutbound + nMaxFeeler); i++)
2192
2214
semOutbound->post ();
2215
+ }
2216
+
2217
+ void CConnman::Stop ()
2218
+ {
2219
+ if (threadMessageHandler.joinable ())
2220
+ threadMessageHandler.join ();
2221
+ if (threadOpenConnections.joinable ())
2222
+ threadOpenConnections.join ();
2223
+ if (threadOpenAddedConnections.joinable ())
2224
+ threadOpenAddedConnections.join ();
2225
+ if (threadDNSAddressSeed.joinable ())
2226
+ threadDNSAddressSeed.join ();
2227
+ if (threadSocketHandler.joinable ())
2228
+ threadSocketHandler.join ();
2193
2229
2194
2230
if (fAddressesInitialized )
2195
2231
{
@@ -2232,6 +2268,7 @@ void CConnman::DeleteNode(CNode* pnode)
2232
2268
2233
2269
CConnman::~CConnman ()
2234
2270
{
2271
+ Interrupt ();
2235
2272
Stop ();
2236
2273
}
2237
2274
0 commit comments