aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGavin Andresen <gavinandresen@gmail.com>2013-03-06 22:16:05 -0500
committerGavin Andresen <gavinandresen@gmail.com>2013-04-03 14:04:21 -0400
commitc8c2fbe07f1a5475aea3a2680af9130558c7e5c8 (patch)
tree78e8007fa6898d8f7f6826ab59c0bab8a4aae417 /src
parent87b9931bed5ec6633348ac506f0e9b5a96446df8 (diff)
downloadbitcoin-c8c2fbe07f1a5475aea3a2680af9130558c7e5c8.tar.xz
Shutdown cleanup prep-work
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.
Diffstat (limited to 'src')
-rw-r--r--src/init.cpp21
-rw-r--r--src/init.h3
-rw-r--r--src/main.cpp102
-rw-r--r--src/net.cpp2
-rw-r--r--src/net.h1
-rw-r--r--src/qt/bitcoin.cpp6
-rw-r--r--src/util.cpp9
-rw-r--r--src/util.h3
8 files changed, 64 insertions, 83 deletions
diff --git a/src/init.cpp b/src/init.cpp
index aac46d489d..a5015adc48 100644
--- a/src/init.cpp
+++ b/src/init.cpp
@@ -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");
diff --git a/src/init.h b/src/init.h
index 8308ee648b..8986ff6208 100644
--- a/src/init.h
+++ b/src/init.h
@@ -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
diff --git a/src/main.cpp b/src/main.cpp
index 60593c0d5f..df9ea44435 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -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:
diff --git a/src/net.cpp b/src/net.cpp
index 669f44b639..097f480b85 100644
--- a/src/net.cpp
+++ b/src/net.cpp
@@ -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
diff --git a/src/net.h b/src/net.h
index 368e4cd4bb..66e528acbb 100644
--- 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,
diff --git a/src/qt/bitcoin.cpp b/src/qt/bitcoin.cpp
index 2c47f30e92..a805e350e6 100644
--- a/src/qt/bitcoin.cpp
+++ b/src/qt/bitcoin.cpp
@@ -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
{
diff --git a/src/util.cpp b/src/util.cpp
index fc3e846a6b..ba012d3216 100644
--- a/src/util.cpp
+++ b/src/util.cpp
@@ -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...
diff --git a/src/util.h b/src/util.h
index d129d13692..2c26120339 100644
--- a/src/util.h
+++ b/src/util.h
@@ -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
-