4040#include < miniupnpc/upnperrors.h>
4141#endif
4242
43- #include < boost/filesystem.hpp>
44- #include < boost/thread.hpp>
4543
4644#include < math.h>
4745
@@ -1071,7 +1069,7 @@ void CConnman::AcceptConnection(const ListenSocket& hListenSocket) {
10711069void CConnman::ThreadSocketHandler ()
10721070{
10731071 unsigned int nPrevNodeCount = 0 ;
1074- while (true )
1072+ while (!interruptNet )
10751073 {
10761074 //
10771075 // Disconnect nodes
@@ -1211,7 +1209,8 @@ void CConnman::ThreadSocketHandler()
12111209
12121210 int nSelect = select (have_fds ? hSocketMax + 1 : 0 ,
12131211 &fdsetRecv, &fdsetSend, &fdsetError, &timeout);
1214- boost::this_thread::interruption_point ();
1212+ if (interruptNet)
1213+ return ;
12151214
12161215 if (nSelect == SOCKET_ERROR)
12171216 {
@@ -1224,7 +1223,8 @@ void CConnman::ThreadSocketHandler()
12241223 }
12251224 FD_ZERO (&fdsetSend);
12261225 FD_ZERO (&fdsetError);
1227- MilliSleep (timeout.tv_usec /1000 );
1226+ if (!interruptNet.sleep_for (std::chrono::milliseconds (timeout.tv_usec /1000 )))
1227+ return ;
12281228 }
12291229
12301230 //
@@ -1244,7 +1244,8 @@ void CConnman::ThreadSocketHandler()
12441244 std::vector<CNode*> vNodesCopy = CopyNodeVector ();
12451245 BOOST_FOREACH (CNode* pnode, vNodesCopy)
12461246 {
1247- boost::this_thread::interruption_point ();
1247+ if (interruptNet)
1248+ return ;
12481249
12491250 //
12501251 // Receive
@@ -1266,7 +1267,7 @@ void CConnman::ThreadSocketHandler()
12661267 if (!pnode->ReceiveMsgBytes (pchBuf, nBytes, notify))
12671268 pnode->CloseSocketDisconnect ();
12681269 if (notify)
1269- messageHandlerCondition .notify_one ();
1270+ condMsgProc .notify_one ();
12701271 pnode->nLastRecv = GetTime ();
12711272 pnode->nRecvBytes += nBytes;
12721273 RecordBytesRecv (nBytes);
@@ -1471,7 +1472,8 @@ void CConnman::ThreadDNSAddressSeed()
14711472 // goal: only query DNS seeds if address need is acute
14721473 if ((addrman.size () > 0 ) &&
14731474 (!GetBoolArg (" -forcednsseed" , DEFAULT_FORCEDNSSEED))) {
1474- MilliSleep (11 * 1000 );
1475+ if (!interruptNet.sleep_for (std::chrono::seconds (11 )))
1476+ return ;
14751477
14761478 LOCK (cs_vNodes);
14771479 if (vNodes.size () >= 2 ) {
@@ -1569,10 +1571,12 @@ void CConnman::ThreadOpenConnections()
15691571 OpenNetworkConnection (addr, NULL , strAddr.c_str ());
15701572 for (int i = 0 ; i < 10 && i < nLoop; i++)
15711573 {
1572- MilliSleep (500 );
1574+ if (!interruptNet.sleep_for (std::chrono::milliseconds (500 )))
1575+ return ;
15731576 }
15741577 }
1575- MilliSleep (500 );
1578+ if (!interruptNet.sleep_for (std::chrono::milliseconds (500 )))
1579+ return ;
15761580 }
15771581 }
15781582
@@ -1581,14 +1585,16 @@ void CConnman::ThreadOpenConnections()
15811585
15821586 // Minimum time before next feeler connection (in microseconds).
15831587 int64_t nNextFeeler = PoissonNextSend (nStart*1000 *1000 , FEELER_INTERVAL);
1584- while (true )
1588+ while (!interruptNet )
15851589 {
15861590 ProcessOneShot ();
15871591
1588- MilliSleep (500 );
1592+ if (!interruptNet.sleep_for (std::chrono::milliseconds (500 )))
1593+ return ;
15891594
15901595 CSemaphoreGrant grant (*semOutbound);
1591- boost::this_thread::interruption_point ();
1596+ if (interruptNet)
1597+ return ;
15921598
15931599 // Add seed nodes if DNS seeds are all down (an infrastructure attack?).
15941600 if (addrman.size () == 0 && (GetTime () - nStart > 60 )) {
@@ -1645,7 +1651,7 @@ void CConnman::ThreadOpenConnections()
16451651
16461652 int64_t nANow = GetAdjustedTime ();
16471653 int nTries = 0 ;
1648- while (true )
1654+ while (!interruptNet )
16491655 {
16501656 CAddrInfo addr = addrman.Select (fFeeler );
16511657
@@ -1684,7 +1690,8 @@ void CConnman::ThreadOpenConnections()
16841690 if (fFeeler ) {
16851691 // Add small amount of random noise before connection to avoid synchronization.
16861692 int randsleep = GetRandInt (FEELER_SLEEP_WINDOW * 1000 );
1687- MilliSleep (randsleep);
1693+ if (!interruptNet.sleep_for (std::chrono::milliseconds (randsleep)))
1694+ return ;
16881695 LogPrint (" net" , " Making feeler connection to %s\n " , addrConnect.ToString ());
16891696 }
16901697
@@ -1762,11 +1769,12 @@ void CConnman::ThreadOpenAddedConnections()
17621769 // OpenNetworkConnection can detect existing connections to that IP/port.
17631770 CService service (info.strAddedNode , Params ().GetDefaultPort ());
17641771 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 ;
17661774 }
17671775 }
1768-
1769- MilliSleep ( 120000 ); // Retry every 2 minutes
1776+ if (!interruptNet. sleep_for ( std::chrono::minutes ( 2 )))
1777+ return ;
17701778 }
17711779}
17721780
@@ -1776,12 +1784,14 @@ void CConnman::ThreadMnbRequestConnections()
17761784 if (mapArgs.count (" -connect" ) && mapMultiArgs[" -connect" ].size () > 0 )
17771785 return ;
17781786
1779- while (true )
1787+ while (!interruptNet )
17801788 {
1781- MilliSleep (1000 );
1789+ if (!interruptNet.sleep_for (std::chrono::milliseconds (1000 )))
1790+ return ;
17821791
17831792 CSemaphoreGrant grant (*semMasternodeOutbound);
1784- boost::this_thread::interruption_point ();
1793+ if (interruptNet)
1794+ return ;
17851795
17861796 std::pair<CService, std::set<uint256> > p = mnodeman.PopScheduledMnbRequestConnection ();
17871797 if (p.first == CService () || p.second .empty ()) continue ;
@@ -1820,7 +1830,9 @@ bool CConnman::OpenNetworkConnection(const CAddress& addrConnect, CSemaphoreGran
18201830 //
18211831 // Initiate outbound network connection
18221832 //
1823- boost::this_thread::interruption_point ();
1833+ if (interruptNet) {
1834+ return false ;
1835+ }
18241836 if (!pszDest) {
18251837 if (IsLocal (addrConnect) ||
18261838 FindNode ((CNetAddr)addrConnect) || IsBanned (addrConnect) ||
@@ -1830,7 +1842,6 @@ bool CConnman::OpenNetworkConnection(const CAddress& addrConnect, CSemaphoreGran
18301842 return false ;
18311843
18321844 CNode* pnode = ConnectNode (addrConnect, pszDest);
1833- boost::this_thread::interruption_point ();
18341845
18351846 if (!pnode)
18361847 return false ;
@@ -1844,14 +1855,10 @@ bool CConnman::OpenNetworkConnection(const CAddress& addrConnect, CSemaphoreGran
18441855 return true ;
18451856}
18461857
1847-
18481858void CConnman::ThreadMessageHandler ()
18491859{
1850- boost::mutex condition_mutex;
1851- boost::unique_lock<boost::mutex> lock (condition_mutex);
1852-
18531860 SetThreadPriority (THREAD_PRIORITY_BELOW_NORMAL);
1854- while (true )
1861+ while (!flagInterruptMsgProc )
18551862 {
18561863 std::vector<CNode*> vNodesCopy = CopyNodeVector ();
18571864
@@ -1867,7 +1874,7 @@ void CConnman::ThreadMessageHandler()
18671874 TRY_LOCK (pnode->cs_vRecvMsg , lockRecv);
18681875 if (lockRecv)
18691876 {
1870- if (!GetNodeSignals ().ProcessMessages (pnode, *this ))
1877+ if (!GetNodeSignals ().ProcessMessages (pnode, *this , flagInterruptMsgProc ))
18711878 pnode->fDisconnect = true ;
18721879
18731880 if (pnode->nSendSize < GetSendBufferSize ())
@@ -1879,21 +1886,25 @@ void CConnman::ThreadMessageHandler()
18791886 }
18801887 }
18811888 }
1882- boost::this_thread::interruption_point ();
1889+ if (flagInterruptMsgProc)
1890+ return ;
18831891
18841892 // Send messages
18851893 {
18861894 TRY_LOCK (pnode->cs_vSend , lockSend);
18871895 if (lockSend)
1888- GetNodeSignals ().SendMessages (pnode, *this );
1896+ GetNodeSignals ().SendMessages (pnode, *this , flagInterruptMsgProc );
18891897 }
1890- boost::this_thread::interruption_point ();
1898+ if (flagInterruptMsgProc)
1899+ return ;
18911900 }
18921901
18931902 ReleaseNodeVector (vNodesCopy);
18941903
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+ }
18971908 }
18981909}
18991910
@@ -2064,14 +2075,15 @@ CConnman::CConnman()
20642075 nMaxOutbound = 0 ;
20652076 nBestHeight = 0 ;
20662077 clientInterface = NULL ;
2078+ flagInterruptMsgProc = false ;
20672079}
20682080
20692081NodeId CConnman::GetNewNodeId ()
20702082{
20712083 return nLastNodeId.fetch_add (1 , std::memory_order_relaxed);
20722084}
20732085
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)
20752087{
20762088 nTotalBytesRecv = 0 ;
20772089 nTotalBytesSent = 0 ;
@@ -2145,26 +2157,29 @@ bool CConnman::Start(boost::thread_group& threadGroup, CScheduler& scheduler, st
21452157 //
21462158 // Start threads
21472159 //
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 )));
21482166
21492167 if (!GetBoolArg (" -dnsseed" , true ))
21502168 LogPrintf (" DNS seeding disabled\n " );
21512169 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 )));
21562171
21572172 // 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 )));
21592174
21602175 // 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 )));
21622177
21632178 // 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 )));
21652180
21662181 // 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 )));
21682183
21692184 // Dump network addresses
21702185 scheduler.scheduleEvery (boost::bind (&CConnman::DumpData, this ), DUMP_ADDRESSES_INTERVAL);
@@ -2195,12 +2210,36 @@ void CExplicitNetCleanup::callCleanup()
21952210 delete tmp; // Stroustrup's gonna kill me for that
21962211}
21972212
2198- void CConnman::Stop ()
2213+ void CConnman::Interrupt ()
21992214{
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+
22012224 if (semOutbound)
22022225 for (int i=0 ; i<(nMaxOutbound + nMaxFeeler); i++)
22032226 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 ();
22042243
22052244 if (semMasternodeOutbound)
22062245 for (int i=0 ; i<MAX_OUTBOUND_MASTERNODE_CONNECTIONS; i++)
@@ -2252,6 +2291,7 @@ void CConnman::DeleteNode(CNode* pnode)
22522291
22532292CConnman::~CConnman ()
22542293{
2294+ Interrupt ();
22552295 Stop ();
22562296}
22572297
0 commit comments