diff options
Diffstat (limited to 'src/net.cpp')
-rw-r--r-- | src/net.cpp | 401 |
1 files changed, 73 insertions, 328 deletions
diff --git a/src/net.cpp b/src/net.cpp index 669f44b639..5f8b5ba32b 100644 --- a/src/net.cpp +++ b/src/net.cpp @@ -26,14 +26,6 @@ using namespace boost; static const int MAX_OUTBOUND_CONNECTIONS = 8; -void ThreadMessageHandler2(void* parg); -void ThreadSocketHandler2(void* parg); -void ThreadOpenConnections2(void* parg); -void ThreadOpenAddedConnections2(void* parg); -#ifdef USE_UPNP -void ThreadMapPort2(void* parg); -#endif -void ThreadDNSAddressSeed2(void* parg); bool OpenNetworkConnection(const CAddress& addrConnect, CSemaphoreGrant *grantOutbound = NULL, const char *strDest = NULL, bool fOneShot = false); @@ -46,7 +38,6 @@ struct LocalServiceInfo { // Global state variables // bool fDiscover = true; -bool fUseUPnP = false; uint64 nLocalServices = NODE_NETWORK; static CCriticalSection cs_mapLocalHost; static map<CNetAddr, LocalServiceInfo> mapLocalHost; @@ -54,7 +45,6 @@ static bool vfReachable[NET_MAX] = {}; static bool vfLimited[NET_MAX] = {}; static CNode* pnodeLocalHost = NULL; uint64 nLocalHostNonce = 0; -array<int, THREAD_MAX> vnThreadsRunning; static std::vector<SOCKET> vhListenSocket; CAddrMan addrman; @@ -63,7 +53,7 @@ CCriticalSection cs_vNodes; map<CInv, CDataStream> mapRelay; deque<pair<int64, CInv> > vRelayExpiration; CCriticalSection cs_mapRelay; -map<CInv, int64> mapAlreadyAskedFor; +limitedmap<CInv, int64> mapAlreadyAskedFor(MAX_INV_SZ); static deque<string> vOneShots; CCriticalSection cs_vOneShots; @@ -156,8 +146,7 @@ bool RecvLine(SOCKET hSocket, string& strLine) } else if (nBytes <= 0) { - if (fShutdown) - return false; + boost::this_thread::interruption_point(); if (nBytes < 0) { int nErr = WSAGetLastError(); @@ -165,7 +154,7 @@ bool RecvLine(SOCKET hSocket, string& strLine) continue; if (nErr == WSAEWOULDBLOCK || nErr == WSAEINTR || nErr == WSAEINPROGRESS) { - Sleep(10); + MilliSleep(10); continue; } } @@ -754,32 +743,10 @@ void SocketSendData(CNode *pnode) pnode->vSendMsg.erase(pnode->vSendMsg.begin(), it); } -void ThreadSocketHandler(void* parg) -{ - // Make this thread recognisable as the networking thread - RenameThread("bitcoin-net"); - - try - { - vnThreadsRunning[THREAD_SOCKETHANDLER]++; - ThreadSocketHandler2(parg); - vnThreadsRunning[THREAD_SOCKETHANDLER]--; - } - catch (std::exception& e) { - vnThreadsRunning[THREAD_SOCKETHANDLER]--; - PrintException(&e, "ThreadSocketHandler()"); - } catch (...) { - vnThreadsRunning[THREAD_SOCKETHANDLER]--; - throw; // support pthread_cancel() - } - printf("ThreadSocketHandler exited\n"); -} - static list<CNode*> vNodesDisconnected; -void ThreadSocketHandler2(void* parg) +void ThreadSocketHandler() { - printf("ThreadSocketHandler started\n"); unsigned int nPrevNodeCount = 0; loop { @@ -892,12 +859,10 @@ void ThreadSocketHandler2(void* parg) } } - vnThreadsRunning[THREAD_SOCKETHANDLER]--; int nSelect = select(have_fds ? hSocketMax + 1 : 0, &fdsetRecv, &fdsetSend, &fdsetError, &timeout); - vnThreadsRunning[THREAD_SOCKETHANDLER]++; - if (fShutdown) - return; + boost::this_thread::interruption_point(); + if (nSelect == SOCKET_ERROR) { if (have_fds) @@ -909,7 +874,7 @@ void ThreadSocketHandler2(void* parg) } FD_ZERO(&fdsetSend); FD_ZERO(&fdsetError); - Sleep(timeout.tv_usec/1000); + MilliSleep(timeout.tv_usec/1000); } @@ -984,8 +949,7 @@ void ThreadSocketHandler2(void* parg) } BOOST_FOREACH(CNode* pnode, vNodesCopy) { - if (fShutdown) - return; + boost::this_thread::interruption_point(); // // Receive @@ -1076,7 +1040,7 @@ void ThreadSocketHandler2(void* parg) pnode->Release(); } - Sleep(10); + MilliSleep(10); } } @@ -1089,31 +1053,8 @@ void ThreadSocketHandler2(void* parg) #ifdef USE_UPNP -void ThreadMapPort(void* parg) +void ThreadMapPort() { - // Make this thread recognisable as the UPnP thread - RenameThread("bitcoin-UPnP"); - - try - { - vnThreadsRunning[THREAD_UPNP]++; - ThreadMapPort2(parg); - vnThreadsRunning[THREAD_UPNP]--; - } - catch (std::exception& e) { - vnThreadsRunning[THREAD_UPNP]--; - PrintException(&e, "ThreadMapPort()"); - } catch (...) { - vnThreadsRunning[THREAD_UPNP]--; - PrintException(NULL, "ThreadMapPort()"); - } - printf("ThreadMapPort exited\n"); -} - -void ThreadMapPort2(void* parg) -{ - printf("ThreadMapPort started\n"); - std::string port = strprintf("%u", GetListenPort()); const char * multicastif = 0; const char * minissdpdpath = 0; @@ -1154,33 +1095,9 @@ void ThreadMapPort2(void* parg) } string strDesc = "Bitcoin " + FormatFullVersion(); -#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); -#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"); -#endif - if(r!=UPNPCOMMAND_SUCCESS) - printf("AddPortMapping(%s, %s, %s) failed with code %d (%s)\n", - port.c_str(), port.c_str(), lanaddr, r, strupnperror(r)); - else - printf("UPnP Port Mapping successful.\n"); - int i = 1; - loop { - if (fShutdown || !fUseUPnP) - { - r = UPNP_DeletePortMapping(urls.controlURL, data.first.servicetype, port.c_str(), "TCP", 0); - printf("UPNP_DeletePortMapping() returned : %d\n", r); - freeUPNPDevlist(devlist); devlist = 0; - FreeUPNPUrls(&urls); - return; - } - if (i % 600 == 0) // Refresh every 20 minutes - { + try { + loop { #ifndef UPNPDISCOVER_SUCCESS /* miniupnpc 1.5 */ r = UPNP_AddPortMapping(urls.controlURL, data.first.servicetype, @@ -1196,33 +1113,49 @@ void ThreadMapPort2(void* parg) port.c_str(), port.c_str(), lanaddr, r, strupnperror(r)); else printf("UPnP Port Mapping successful.\n");; + + MilliSleep(20*60*1000); // Refresh every 20 minutes } - Sleep(2000); - i++; + } + catch (boost::thread_interrupted) + { + r = UPNP_DeletePortMapping(urls.controlURL, data.first.servicetype, port.c_str(), "TCP", 0); + printf("UPNP_DeletePortMapping() returned : %d\n", r); + freeUPNPDevlist(devlist); devlist = 0; + FreeUPNPUrls(&urls); + throw; } } else { printf("No valid UPnP IGDs found\n"); freeUPNPDevlist(devlist); devlist = 0; if (r != 0) FreeUPNPUrls(&urls); - loop { - if (fShutdown || !fUseUPnP) - return; - Sleep(2000); - } } } -void MapPort() +void MapPort(bool fUseUPnP) { - if (fUseUPnP && vnThreadsRunning[THREAD_UPNP] < 1) + static boost::thread* upnp_thread = NULL; + + if (fUseUPnP) { - if (!NewThread(ThreadMapPort, NULL)) - printf("Error: ThreadMapPort(ThreadMapPort) failed\n"); + if (upnp_thread) { + upnp_thread->interrupt(); + upnp_thread->join(); + delete upnp_thread; + } + upnp_thread = new boost::thread(boost::bind(&TraceThread<boost::function<void()> >, "upnp", &ThreadMapPort)); + } + else if (upnp_thread) { + upnp_thread->interrupt(); + upnp_thread->join(); + delete upnp_thread; + upnp_thread = NULL; } } + #else -void MapPort() +void MapPort(bool) { // Intentionally left blank. } @@ -1254,32 +1187,10 @@ static const char *strTestNetDNSSeed[][2] = { {NULL, NULL} }; -void ThreadDNSAddressSeed(void* parg) -{ - // Make this thread recognisable as the DNS seeding thread - RenameThread("bitcoin-dnsseed"); - - try - { - vnThreadsRunning[THREAD_DNSSEED]++; - ThreadDNSAddressSeed2(parg); - vnThreadsRunning[THREAD_DNSSEED]--; - } - catch (std::exception& e) { - vnThreadsRunning[THREAD_DNSSEED]--; - PrintException(&e, "ThreadDNSAddressSeed()"); - } catch (...) { - vnThreadsRunning[THREAD_DNSSEED]--; - throw; // support pthread_cancel() - } - printf("ThreadDNSAddressSeed exited\n"); -} - -void ThreadDNSAddressSeed2(void* parg) +void ThreadDNSAddressSeed() { static const char *(*strDNSSeed)[2] = fTestNet ? strTestNetDNSSeed : strMainNetDNSSeed; - printf("ThreadDNSAddressSeed started\n"); int found = 0; printf("Loading addresses from DNS seeds (could take a while)\n"); @@ -1409,57 +1320,6 @@ void DumpAddresses() addrman.size(), GetTimeMillis() - nStart); } -void ThreadDumpAddress2(void* parg) -{ - printf("ThreadDumpAddress started\n"); - - vnThreadsRunning[THREAD_DUMPADDRESS]++; - while (!fShutdown) - { - DumpAddresses(); - vnThreadsRunning[THREAD_DUMPADDRESS]--; - Sleep(100000); - vnThreadsRunning[THREAD_DUMPADDRESS]++; - } - vnThreadsRunning[THREAD_DUMPADDRESS]--; -} - -void ThreadDumpAddress(void* parg) -{ - // Make this thread recognisable as the address dumping thread - RenameThread("bitcoin-adrdump"); - - try - { - ThreadDumpAddress2(parg); - } - catch (std::exception& e) { - PrintException(&e, "ThreadDumpAddress()"); - } - printf("ThreadDumpAddress exited\n"); -} - -void ThreadOpenConnections(void* parg) -{ - // Make this thread recognisable as the connection opening thread - RenameThread("bitcoin-opencon"); - - try - { - vnThreadsRunning[THREAD_OPENCONNECTIONS]++; - ThreadOpenConnections2(parg); - vnThreadsRunning[THREAD_OPENCONNECTIONS]--; - } - catch (std::exception& e) { - vnThreadsRunning[THREAD_OPENCONNECTIONS]--; - PrintException(&e, "ThreadOpenConnections()"); - } catch (...) { - vnThreadsRunning[THREAD_OPENCONNECTIONS]--; - PrintException(NULL, "ThreadOpenConnections()"); - } - printf("ThreadOpenConnections exited\n"); -} - void static ProcessOneShot() { string strDest; @@ -1478,10 +1338,8 @@ void static ProcessOneShot() } } -void ThreadOpenConnections2(void* parg) +void ThreadOpenConnections() { - printf("ThreadOpenConnections started\n"); - // Connect to specific addresses if (mapArgs.count("-connect") && mapMultiArgs["-connect"].size() > 0) { @@ -1494,12 +1352,10 @@ void ThreadOpenConnections2(void* parg) OpenNetworkConnection(addr, NULL, strAddr.c_str()); for (int i = 0; i < 10 && i < nLoop; i++) { - Sleep(500); - if (fShutdown) - return; + MilliSleep(500); } } - Sleep(500); + MilliSleep(500); } } @@ -1509,18 +1365,10 @@ void ThreadOpenConnections2(void* parg) { ProcessOneShot(); - vnThreadsRunning[THREAD_OPENCONNECTIONS]--; - Sleep(500); - vnThreadsRunning[THREAD_OPENCONNECTIONS]++; - if (fShutdown) - return; - + MilliSleep(500); - vnThreadsRunning[THREAD_OPENCONNECTIONS]--; CSemaphoreGrant grant(*semOutbound); - vnThreadsRunning[THREAD_OPENCONNECTIONS]++; - if (fShutdown) - return; + boost::this_thread::interruption_point(); // Add seed nodes if IRC isn't working if (addrman.size()==0 && (GetTime() - nStart > 60) && !fTestNet) @@ -1600,38 +1448,15 @@ void ThreadOpenConnections2(void* parg) } } -void ThreadOpenAddedConnections(void* parg) -{ - // Make this thread recognisable as the connection opening thread - RenameThread("bitcoin-opencon"); - - try - { - vnThreadsRunning[THREAD_ADDEDCONNECTIONS]++; - ThreadOpenAddedConnections2(parg); - vnThreadsRunning[THREAD_ADDEDCONNECTIONS]--; - } - catch (std::exception& e) { - vnThreadsRunning[THREAD_ADDEDCONNECTIONS]--; - PrintException(&e, "ThreadOpenAddedConnections()"); - } catch (...) { - vnThreadsRunning[THREAD_ADDEDCONNECTIONS]--; - PrintException(NULL, "ThreadOpenAddedConnections()"); - } - printf("ThreadOpenAddedConnections exited\n"); -} - -void ThreadOpenAddedConnections2(void* parg) +void ThreadOpenAddedConnections() { - printf("ThreadOpenAddedConnections started\n"); - { LOCK(cs_vAddedNodes); vAddedNodes = mapMultiArgs["-addnode"]; } if (HaveNameProxy()) { - while(!fShutdown) { + while(true) { list<string> lAddresses(0); { LOCK(cs_vAddedNodes); @@ -1642,15 +1467,10 @@ void ThreadOpenAddedConnections2(void* parg) CAddress addr; CSemaphoreGrant grant(*semOutbound); OpenNetworkConnection(addr, &grant, strAddNode.c_str()); - Sleep(500); - if (fShutdown) - return; + MilliSleep(500); } - vnThreadsRunning[THREAD_ADDEDCONNECTIONS]--; - Sleep(120000); // Retry every 2 minutes - vnThreadsRunning[THREAD_ADDEDCONNECTIONS]++; + MilliSleep(120000); // Retry every 2 minutes } - return; } for (unsigned int i = 0; true; i++) @@ -1694,17 +1514,9 @@ void ThreadOpenAddedConnections2(void* parg) { CSemaphoreGrant grant(*semOutbound); OpenNetworkConnection(CAddress(vserv[i % vserv.size()]), &grant); - Sleep(500); - if (fShutdown) - return; + MilliSleep(500); } - if (fShutdown) - return; - vnThreadsRunning[THREAD_ADDEDCONNECTIONS]--; - Sleep(120000); // Retry every 2 minutes - vnThreadsRunning[THREAD_ADDEDCONNECTIONS]++; - if (fShutdown) - return; + MilliSleep(120000); // Retry every 2 minutes } } @@ -1714,8 +1526,7 @@ bool OpenNetworkConnection(const CAddress& addrConnect, CSemaphoreGrant *grantOu // // Initiate outbound network connection // - if (fShutdown) - return false; + boost::this_thread::interruption_point(); if (!strDest) if (IsLocal(addrConnect) || FindNode((CNetAddr)addrConnect) || CNode::IsBanned(addrConnect) || @@ -1724,11 +1535,9 @@ bool OpenNetworkConnection(const CAddress& addrConnect, CSemaphoreGrant *grantOu if (strDest && FindNode(strDest)) return false; - vnThreadsRunning[THREAD_OPENCONNECTIONS]--; CNode* pnode = ConnectNode(addrConnect, strDest); - vnThreadsRunning[THREAD_OPENCONNECTIONS]++; - if (fShutdown) - return false; + boost::this_thread::interruption_point(); + if (!pnode) return false; if (grantOutbound) @@ -1746,33 +1555,10 @@ bool OpenNetworkConnection(const CAddress& addrConnect, CSemaphoreGrant *grantOu - -void ThreadMessageHandler(void* parg) +void ThreadMessageHandler() { - // Make this thread recognisable as the message handling thread - RenameThread("bitcoin-msghand"); - - try - { - vnThreadsRunning[THREAD_MESSAGEHANDLER]++; - ThreadMessageHandler2(parg); - vnThreadsRunning[THREAD_MESSAGEHANDLER]--; - } - catch (std::exception& e) { - vnThreadsRunning[THREAD_MESSAGEHANDLER]--; - PrintException(&e, "ThreadMessageHandler()"); - } catch (...) { - vnThreadsRunning[THREAD_MESSAGEHANDLER]--; - PrintException(NULL, "ThreadMessageHandler()"); - } - printf("ThreadMessageHandler exited\n"); -} - -void ThreadMessageHandler2(void* parg) -{ - printf("ThreadMessageHandler started\n"); SetThreadPriority(THREAD_PRIORITY_BELOW_NORMAL); - while (!fShutdown) + while (true) { vector<CNode*> vNodesCopy; { @@ -1798,8 +1584,7 @@ void ThreadMessageHandler2(void* parg) if (!ProcessMessages(pnode)) pnode->CloseSocketDisconnect(); } - if (fShutdown) - return; + boost::this_thread::interruption_point(); // Send messages { @@ -1807,8 +1592,7 @@ void ThreadMessageHandler2(void* parg) if (lockSend) SendMessages(pnode, pnode == pnodeTrickle); } - if (fShutdown) - return; + boost::this_thread::interruption_point(); } { @@ -1817,16 +1601,7 @@ void ThreadMessageHandler2(void* parg) pnode->Release(); } - // Wait and allow messages to bunch up. - // Reduce vnThreadsRunning so StopNode has permission to exit while - // we're sleeping, but we must always check fShutdown after doing this. - vnThreadsRunning[THREAD_MESSAGEHANDLER]--; - Sleep(100); - if (fRequestShutdown) - StartShutdown(); - vnThreadsRunning[THREAD_MESSAGEHANDLER]++; - if (fShutdown) - return; + MilliSleep(100); } } @@ -1998,7 +1773,7 @@ void static Discover() NewThread(ThreadGetMyExternalIP, NULL); } -void StartNode(void* parg) +void StartNode(boost::thread_group& threadGroup) { // Make this thread recognisable as the startup thread RenameThread("bitcoin-start"); @@ -2021,69 +1796,39 @@ void StartNode(void* parg) if (!GetBoolArg("-dnsseed", true)) printf("DNS seeding disabled\n"); else - if (!NewThread(ThreadDNSAddressSeed, NULL)) - printf("Error: NewThread(ThreadDNSAddressSeed) failed\n"); + threadGroup.create_thread(boost::bind(&TraceThread<boost::function<void()> >, "dnsseed", &ThreadDNSAddressSeed)); +#ifdef USE_UPNP // Map ports with UPnP - if (fUseUPnP) - MapPort(); + MapPort(GetBoolArg("-upnp", USE_UPNP)); +#endif // Send and receive from sockets, accept connections - if (!NewThread(ThreadSocketHandler, NULL)) - printf("Error: NewThread(ThreadSocketHandler) failed\n"); + threadGroup.create_thread(boost::bind(&TraceThread<void (*)()>, "net", &ThreadSocketHandler)); // Initiate outbound connections from -addnode - if (!NewThread(ThreadOpenAddedConnections, NULL)) - printf("Error: NewThread(ThreadOpenAddedConnections) failed\n"); + threadGroup.create_thread(boost::bind(&TraceThread<void (*)()>, "addcon", &ThreadOpenAddedConnections)); // Initiate outbound connections - if (!NewThread(ThreadOpenConnections, NULL)) - printf("Error: NewThread(ThreadOpenConnections) failed\n"); + threadGroup.create_thread(boost::bind(&TraceThread<void (*)()>, "opencon", &ThreadOpenConnections)); // Process messages - if (!NewThread(ThreadMessageHandler, NULL)) - printf("Error: NewThread(ThreadMessageHandler) failed\n"); + threadGroup.create_thread(boost::bind(&TraceThread<void (*)()>, "msghand", &ThreadMessageHandler)); // Dump network addresses - if (!NewThread(ThreadDumpAddress, NULL)) - printf("Error; NewThread(ThreadDumpAddress) failed\n"); + threadGroup.create_thread(boost::bind(&LoopForever<void (*)()>, "dumpaddr", &DumpAddresses, 10000)); } bool StopNode() { printf("StopNode()\n"); - fShutdown = true; + GenerateBitcoins(false, NULL); + MapPort(false); nTransactionsUpdated++; - int64 nStart = GetTime(); if (semOutbound) for (int i=0; i<MAX_OUTBOUND_CONNECTIONS; i++) semOutbound->post(); - do - { - int nThreadsRunning = 0; - for (int n = 0; n < THREAD_MAX; n++) - nThreadsRunning += vnThreadsRunning[n]; - if (nThreadsRunning == 0) - break; - if (GetTime() - nStart > 20) - break; - Sleep(20); - } while(true); - if (vnThreadsRunning[THREAD_SOCKETHANDLER] > 0) printf("ThreadSocketHandler still running\n"); - if (vnThreadsRunning[THREAD_OPENCONNECTIONS] > 0) printf("ThreadOpenConnections still running\n"); - if (vnThreadsRunning[THREAD_MESSAGEHANDLER] > 0) printf("ThreadMessageHandler still running\n"); - if (vnThreadsRunning[THREAD_MINER] > 0) printf("ThreadBitcoinMiner still running\n"); - if (vnThreadsRunning[THREAD_RPCLISTENER] > 0) printf("ThreadRPCListener still running\n"); - if (vnThreadsRunning[THREAD_RPCHANDLER] > 0) printf("ThreadsRPCServer still running\n"); -#ifdef USE_UPNP - if (vnThreadsRunning[THREAD_UPNP] > 0) printf("ThreadMapPort still running\n"); -#endif - if (vnThreadsRunning[THREAD_DNSSEED] > 0) printf("ThreadDNSAddressSeed still running\n"); - if (vnThreadsRunning[THREAD_ADDEDCONNECTIONS] > 0) printf("ThreadOpenAddedConnections still running\n"); - if (vnThreadsRunning[THREAD_DUMPADDRESS] > 0) printf("ThreadDumpAddresses still running\n"); - while (vnThreadsRunning[THREAD_MESSAGEHANDLER] > 0 || vnThreadsRunning[THREAD_RPCHANDLER] > 0) - Sleep(20); - Sleep(50); + MilliSleep(50); DumpAddresses(); return true; |