]> Git Repo - VerusCoin.git/commitdiff
Shutdown cleanup prep-work
authorGavin Andresen <[email protected]>
Thu, 7 Mar 2013 03:16:05 +0000 (22:16 -0500)
committerGavin Andresen <[email protected]>
Wed, 3 Apr 2013 18:04:21 +0000 (14:04 -0400)
Create a boost::thread_group object at the qt/bitcoind main-loop level
that will hold pointers to all the main-loop threads.

This will replace the vnThreadsRunning[] array.

For testing, ported the BitcoinMiner threads to use its
own boost::thread_group.

src/init.cpp
src/init.h
src/main.cpp
src/net.cpp
src/net.h
src/qt/bitcoin.cpp
src/util.cpp
src/util.h

index aac46d489d0af7734bb72419dba112cfe2ff630a..a5015adc48c25d42528e1fda0a45a350773070e2 100644 (file)
@@ -122,6 +122,16 @@ void Shutdown(void* parg)
     }
 }
 
+//
+// Signal handlers are very limited in what they are allowed to do, so:
+//
+void DetectShutdownThread(boost::thread_group* threadGroup)
+{
+    while (fRequestShutdown == false)
+        Sleep(200);
+    threadGroup->interrupt_all();
+}
+
 void HandleSIGTERM(int)
 {
     fRequestShutdown = true;
@@ -143,6 +153,7 @@ void HandleSIGHUP(int)
 #if !defined(QT_GUI)
 bool AppInit(int argc, char* argv[])
 {
+    boost::thread_group threadGroup;
     bool fRet = false;
     try
     {
@@ -185,7 +196,7 @@ bool AppInit(int argc, char* argv[])
             exit(ret);
         }
 
-        fRet = AppInit2();
+        fRet = AppInit2(threadGroup);
     }
     catch (std::exception& e) {
         PrintExceptionContinue(&e, "AppInit()");
@@ -193,7 +204,11 @@ bool AppInit(int argc, char* argv[])
         PrintExceptionContinue(NULL, "AppInit()");
     }
     if (!fRet)
+    {
         Shutdown(NULL);
+        threadGroup.interrupt_all();
+        threadGroup.join_all();
+    }
     return fRet;
 }
 
@@ -405,7 +420,7 @@ void ThreadImport(void *data) {
 /** Initialize bitcoin.
  *  @pre Parameters should be parsed and config file should be read.
  */
-bool AppInit2()
+bool AppInit2(boost::thread_group& threadGroup)
 {
     // ********************************************************* Step 1: setup
 #ifdef _MSC_VER
@@ -449,6 +464,8 @@ bool AppInit2()
     sigaction(SIGHUP, &sa_hup, NULL);
 #endif
 
+    threadGroup.create_thread(boost::bind(&DetectShutdownThread, &threadGroup));
+
     // ********************************************************* Step 2: parameter interactions
 
     fTestNet = GetBoolArg("-testnet");
index 8308ee648bcc0cfc372dfe651e1d116c5cdaa1ac..8986ff6208ed6c3ca54109bdf36a410afccd7f5d 100644 (file)
@@ -7,11 +7,12 @@
 
 #include "wallet.h"
 
+class boost::thread_group;
 extern CWallet* pwalletMain;
 
 void StartShutdown();
 void Shutdown(void* parg);
-bool AppInit2();
+bool AppInit2(boost::thread_group& threadGroup);
 std::string HelpMessage();
 
 #endif
index 60593c0d5f73f9223d85dc96b1c8982daf5763e9..df9ea4443566164ca9ea806c326739b7f7c02644 100644 (file)
@@ -61,8 +61,8 @@ CScript COINBASE_FLAGS;
 
 const string strMessageMagic = "Bitcoin Signed Message:\n";
 
-double dHashesPerSec;
-int64 nHPSTimerStart;
+double dHashesPerSec = 0.0;
+int64 nHPSTimerStart = 0;
 
 // Settings
 int64 nTransactionFee = 0;
@@ -4089,6 +4089,8 @@ unsigned int static ScanHash_CryptoPP(char* pmidstate, char* pdata, char* phash1
             nHashesDone = 0xffff+1;
             return (unsigned int) -1;
         }
+        if ((nNonce & 0xfff) == 0)
+            boost::this_thread::interruption_point();
     }
 }
 
@@ -4506,37 +4508,19 @@ bool CheckWork(CBlock* pblock, CWallet& wallet, CReserveKey& reservekey)
     return true;
 }
 
-void static ThreadBitcoinMiner(void* parg);
-
-static bool fGenerateBitcoins = false;
-static bool fLimitProcessors = false;
-static int nLimitProcessors = -1;
-
 void static BitcoinMiner(CWallet *pwallet)
 {
     printf("BitcoinMiner started\n");
     SetThreadPriority(THREAD_PRIORITY_LOWEST);
-
-    // Make this thread recognisable as the mining thread
     RenameThread("bitcoin-miner");
 
     // Each thread has its own key and counter
     CReserveKey reservekey(pwallet);
     unsigned int nExtraNonce = 0;
 
-    while (fGenerateBitcoins)
-    {
-        if (fShutdown)
-            return;
-        while (vNodes.empty() || IsInitialBlockDownload())
-        {
+    try { loop {
+        while (vNodes.empty())
             Sleep(1000);
-            if (fShutdown)
-                return;
-            if (!fGenerateBitcoins)
-                return;
-        }
-
 
         //
         // Create new block
@@ -4553,7 +4537,6 @@ void static BitcoinMiner(CWallet *pwallet)
         printf("Running BitcoinMiner with %"PRIszu" transactions in block (%u bytes)\n", pblock->vtx.size(),
                ::GetSerializeSize(*pblock, SER_NETWORK, PROTOCOL_VERSION));
 
-
         //
         // Pre-build hash buffers
         //
@@ -4626,19 +4609,14 @@ void static BitcoinMiner(CWallet *pwallet)
                         if (GetTime() - nLogTime > 30 * 60)
                         {
                             nLogTime = GetTime();
-                            printf("hashmeter %3d CPUs %6.0f khash/s\n", vnThreadsRunning[THREAD_MINER], dHashesPerSec/1000.0);
+                            printf("hashmeter %6.0f khash/s\n", dHashesPerSec/1000.0);
                         }
                     }
                 }
             }
 
             // Check for stop or if block needs to be rebuilt
-            if (fShutdown)
-                return;
-            if (!fGenerateBitcoins)
-                return;
-            if (fLimitProcessors && vnThreadsRunning[THREAD_MINER] > nLimitProcessors)
-                return;
+            boost::this_thread::interruption_point();
             if (vNodes.empty())
                 break;
             if (nBlockNonce >= 0xffff0000)
@@ -4658,57 +4636,35 @@ void static BitcoinMiner(CWallet *pwallet)
                 hashTarget = CBigNum().SetCompact(pblock->nBits).getuint256();
             }
         }
-    }
-}
-
-void static ThreadBitcoinMiner(void* parg)
-{
-    CWallet* pwallet = (CWallet*)parg;
-    try
+    } }
+    catch (boost::thread_interrupted)
     {
-        vnThreadsRunning[THREAD_MINER]++;
-        BitcoinMiner(pwallet);
-        vnThreadsRunning[THREAD_MINER]--;
-    }
-    catch (std::exception& e) {
-        vnThreadsRunning[THREAD_MINER]--;
-        PrintException(&e, "ThreadBitcoinMiner()");
-    } catch (...) {
-        vnThreadsRunning[THREAD_MINER]--;
-        PrintException(NULL, "ThreadBitcoinMiner()");
-    }
-    nHPSTimerStart = 0;
-    if (vnThreadsRunning[THREAD_MINER] == 0)
-        dHashesPerSec = 0;
-    printf("ThreadBitcoinMiner exiting, %d threads remaining\n", vnThreadsRunning[THREAD_MINER]);
+        printf("BitcoinMiner terminated\n");
+        throw;
+    }
 }
 
-
 void GenerateBitcoins(bool fGenerate, CWallet* pwallet)
 {
-    fGenerateBitcoins = fGenerate;
-    nLimitProcessors = GetArg("-genproclimit", -1);
-    if (nLimitProcessors == 0)
-        fGenerateBitcoins = false;
-    fLimitProcessors = (nLimitProcessors != -1);
+    static boost::thread_group* minerThreads = NULL;
+
+    int nThreads = GetArg("-genproclimit", -1);
+    if (nThreads < 0)
+        nThreads = boost::thread::hardware_concurrency();
 
-    if (fGenerate)
+    if (minerThreads != NULL)
     {
-        int nProcessors = boost::thread::hardware_concurrency();
-        printf("%d processors\n", nProcessors);
-        if (nProcessors < 1)
-            nProcessors = 1;
-        if (fLimitProcessors && nProcessors > nLimitProcessors)
-            nProcessors = nLimitProcessors;
-        int nAddThreads = nProcessors - vnThreadsRunning[THREAD_MINER];
-        printf("Starting %d BitcoinMiner threads\n", nAddThreads);
-        for (int i = 0; i < nAddThreads; i++)
-        {
-            if (!NewThread(ThreadBitcoinMiner, pwallet))
-                printf("Error: NewThread(ThreadBitcoinMiner) failed\n");
-            Sleep(10);
-        }
+        minerThreads->interrupt_all();
+        delete minerThreads;
+        minerThreads = NULL;
     }
+
+    if (nThreads == 0 || !fGenerate)
+        return;
+
+    minerThreads = new boost::thread_group();
+    for (int i = 0; i < nThreads; i++)
+        minerThreads->create_thread(boost::bind(&BitcoinMiner, pwallet));
 }
 
 // Amount compression:
index 669f44b639ad25e264d8ff1f0595ef58972e9161..097f480b850035931bb94b3ca96764e297632397 100644 (file)
@@ -2052,6 +2052,7 @@ void StartNode(void* parg)
 bool StopNode()
 {
     printf("StopNode()\n");
+    GenerateBitcoins(false, NULL);
     fShutdown = true;
     nTransactionsUpdated++;
     int64 nStart = GetTime();
@@ -2072,7 +2073,6 @@ bool StopNode()
     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
index 368e4cd4bbcab0f2b6af15d4b557bc68423f90de..66e528acbb6e88d62b4df067bae92aafa05cc0d0 100644 (file)
--- a/src/net.h
+++ b/src/net.h
@@ -75,7 +75,6 @@ enum threadId
     THREAD_SOCKETHANDLER,
     THREAD_OPENCONNECTIONS,
     THREAD_MESSAGEHANDLER,
-    THREAD_MINER,
     THREAD_RPCLISTENER,
     THREAD_UPNP,
     THREAD_DNSSEED,
index 2c47f30e92c25a6cadcb7ef9f9599cddec3c9f8b..a805e350e6dee88b6351e0441576627f208945c3 100644 (file)
@@ -11,6 +11,7 @@
 #include "guiutil.h"
 #include "guiconstants.h"
 #include "init.h"
+#include "util.h"
 #include "ui_interface.h"
 #include "paymentserver.h"
 
@@ -215,9 +216,10 @@ int main(int argc, char *argv[])
         if (GUIUtil::GetStartOnSystemStartup())
             GUIUtil::SetStartOnSystemStartup(true);
 
+        boost::thread_group threadGroup;
         BitcoinGUI window;
         guiref = &window;
-        if(AppInit2())
+        if(AppInit2(threadGroup))
         {
             {
                 // Put this in a block, so that the Model objects are cleaned up before
@@ -259,6 +261,8 @@ int main(int argc, char *argv[])
             }
             // Shutdown the core and its threads, but don't exit Bitcoin-Qt here
             Shutdown(NULL);
+            threadGroup.interrupt_all();
+            threadGroup.join_all();
         }
         else
         {
index fc3e846a6bf0570f01e5530ac8ed2f9bc94d8939..ba012d3216e3b627b86d4486562e369745eaffd0 100644 (file)
@@ -1431,9 +1431,12 @@ void RenameThread(const char* name)
     //       removed.
     pthread_set_name_np(pthread_self(), name);
 
-// This is XCode 10.6-and-later; bring back if we drop 10.5 support:
-// #elif defined(MAC_OSX)
-//    pthread_setname_np(name);
+#elif defined(MAC_OSX) && defined(__MAC_OS_X_VERSION_MAX_ALLOWED)
+
+// pthread_setname_np is XCode 10.6-and-later
+#if __MAC_OS_X_VERSION_MAX_ALLOWED >= 1060
+    pthread_setname_np(name);
+#endif
 
 #else
     // Prevent warnings for unused parameters...
index d129d1369215012201bac4b0f4ae26acc6f827c5..2c261203392a56994bcce5f25e736d6c0a2c008c 100644 (file)
@@ -15,6 +15,8 @@
 typedef int pid_t; /* define for Windows compatibility */
 #endif
 #include <map>
+#include <list>
+#include <utility>
 #include <vector>
 #include <string>
 
@@ -523,4 +525,3 @@ inline uint32_t ByteReverse(uint32_t value)
 }
 
 #endif
-
This page took 0.050216 seconds and 4 git commands to generate.