Move DNS Seed lookup to a new thread.
[novacoin.git] / src / net.cpp
index 5fca17a..1907397 100644 (file)
@@ -32,6 +32,7 @@ void ThreadOpenConnections2(void* parg);
 #ifdef USE_UPNP
 void ThreadMapPort2(void* parg);
 #endif
+void ThreadDNSAddressSeed2(void* parg);
 bool OpenNetworkConnection(const CAddress& addrConnect);
 
 
@@ -443,6 +444,10 @@ bool AddAddress(CAddress addr, int64 nTimePenalty, CAddrDB *pAddrDB)
     if (addr.ip == addrLocalHost.ip)
         return false;
     addr.nTime = max((int64)0, (int64)addr.nTime - nTimePenalty);
+    bool fUpdated = false;
+    bool fNew = false;
+    CAddress addrFound = addr;
+
     CRITICAL_BLOCK(cs_mapAddresses)
     {
         map<vector<unsigned char>, CAddress>::iterator it = mapAddresses.find(addr.GetKey());
@@ -451,16 +456,12 @@ bool AddAddress(CAddress addr, int64 nTimePenalty, CAddrDB *pAddrDB)
             // New address
             printf("AddAddress(%s)\n", addr.ToString().c_str());
             mapAddresses.insert(make_pair(addr.GetKey(), addr));
-            if (pAddrDB)
-                pAddrDB->WriteAddress(addr);
-            else
-                CAddrDB().WriteAddress(addr);
-            return true;
+            fUpdated = true;
+            fNew = true;
         }
         else
         {
-            bool fUpdated = false;
-            CAddress& addrFound = (*it).second;
+            addrFound = (*it).second;
             if ((addrFound.nServices | addr.nServices) != addrFound.nServices)
             {
                 // Services have been added
@@ -475,16 +476,22 @@ bool AddAddress(CAddress addr, int64 nTimePenalty, CAddrDB *pAddrDB)
                 addrFound.nTime = addr.nTime;
                 fUpdated = true;
             }
-            if (fUpdated)
-            {
-                if (pAddrDB)
-                    pAddrDB->WriteAddress(addrFound);
-                else
-                    CAddrDB().WriteAddress(addrFound);
-            }
         }
     }
-    return false;
+    // There is a nasty deadlock bug if this is done inside the cs_mapAddresses
+    // CRITICAL_BLOCK:
+    // Thread 1:  begin db transaction (locks inside-db-mutex)
+    //            then AddAddress (locks cs_mapAddresses)
+    // Thread 2:  AddAddress (locks cs_mapAddresses)
+    //             ... then db operation hangs waiting for inside-db-mutex
+    if (fUpdated)
+    {
+        if (pAddrDB)
+            pAddrDB->WriteAddress(addrFound);
+        else
+            CAddrDB().WriteAddress(addrFound);
+    }
+    return fNew;
 }
 
 void AddressCurrentlyConnected(const CAddress& addr)
@@ -1153,12 +1160,31 @@ void MapPort(bool /* unused fMapPort */)
 
 static const char *strDNSSeed[] = {
     "bitseed.xf2.org",
-    "bitseed.bitcoin.org.uk",
     "dnsseed.bluematt.me",
 };
 
-void DNSAddressSeed()
+void ThreadDNSAddressSeed(void* parg)
 {
+    IMPLEMENT_RANDOMIZE_STACK(ThreadDNSAddressSeed(parg));
+    try
+    {
+        vnThreadsRunning[6]++;
+        ThreadDNSAddressSeed2(parg);
+        vnThreadsRunning[6]--;
+    }
+    catch (std::exception& e) {
+        vnThreadsRunning[6]--;
+        PrintException(&e, "ThreadDNSAddressSeed()");
+    } catch (...) {
+        vnThreadsRunning[6]--;
+        throw; // support pthread_cancel()
+    }
+    printf("ThreadDNSAddressSeed exiting\n");
+}
+
+void ThreadDNSAddressSeed2(void* parg)
+{
+    printf("ThreadDNSAddressSeed started\n");
     int found = 0;
 
     if (!fTestNet)
@@ -1191,6 +1217,15 @@ void DNSAddressSeed()
 
 
 
+
+
+
+
+
+
+
+
+
 unsigned int pnSeed[] =
 {
     0x6884ac63, 0x3ffecead, 0x2919b953, 0x0942fe50, 0x7a1d922e, 0xcdd6734a, 0x953a5bb6, 0x2c46922e,
@@ -1698,6 +1733,12 @@ void StartNode(void* parg)
     // Start threads
     //
 
+    if (GetBoolArg("-nodnsseed"))
+        printf("DNS seeding disabled\n");
+    else
+        if (!CreateThread(ThreadDNSAddressSeed, NULL))
+            printf("Error: CreateThread(ThreadDNSAddressSeed) failed\n");
+
     // Map ports with UPnP
     if (fHaveUPnP)
         MapPort(fUseUPnP);
@@ -1707,7 +1748,8 @@ void StartNode(void* parg)
         printf("Error: CreateThread(ThreadIRCSeed) failed\n");
 
     // Send and receive from sockets, accept connections
-    CreateThread(ThreadSocketHandler, NULL, true);
+    if (!CreateThread(ThreadSocketHandler, NULL))
+        printf("Error: CreateThread(ThreadSocketHandler) failed\n");
 
     // Initiate outbound connections
     if (!CreateThread(ThreadOpenConnections, NULL))
@@ -1743,6 +1785,7 @@ bool StopNode()
     if (vnThreadsRunning[3] > 0) printf("ThreadBitcoinMiner still running\n");
     if (vnThreadsRunning[4] > 0) printf("ThreadRPCServer still running\n");
     if (fHaveUPnP && vnThreadsRunning[5] > 0) printf("ThreadMapPort still running\n");
+    if (vnThreadsRunning[6] > 0) printf("ThreadDNSAddressSeed still running\n");
     while (vnThreadsRunning[2] > 0 || vnThreadsRunning[4] > 0)
         Sleep(20);
     Sleep(50);