aboutsummaryrefslogtreecommitdiff
path: root/src/init.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/init.cpp')
-rw-r--r--src/init.cpp84
1 files changed, 55 insertions, 29 deletions
diff --git a/src/init.cpp b/src/init.cpp
index 9356862999..2a37ae780f 100644
--- a/src/init.cpp
+++ b/src/init.cpp
@@ -1,5 +1,5 @@
// Copyright (c) 2009-2010 Satoshi Nakamoto
-// Copyright (c) 2009-2016 The Bitcoin Core developers
+// Copyright (c) 2009-2017 The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
@@ -155,7 +155,10 @@ public:
static std::unique_ptr<CCoinsViewErrorCatcher> pcoinscatcher;
static std::unique_ptr<ECCVerifyHandle> globalVerifyHandle;
-void Interrupt(boost::thread_group& threadGroup)
+static boost::thread_group threadGroup;
+static CScheduler scheduler;
+
+void Interrupt()
{
InterruptHTTPServer();
InterruptHTTPRPC();
@@ -164,7 +167,6 @@ void Interrupt(boost::thread_group& threadGroup)
InterruptTorControl();
if (g_connman)
g_connman->Interrupt();
- threadGroup.interrupt_all();
}
void Shutdown()
@@ -199,6 +201,12 @@ void Shutdown()
g_connman.reset();
StopTorControl();
+
+ // After everything has been shut down, but before things get flushed, stop the
+ // CScheduler/checkqueue threadGroup
+ threadGroup.interrupt_all();
+ threadGroup.join_all();
+
if (fDumpMempoolLater && gArgs.GetArg("-persistmempool", DEFAULT_PERSIST_MEMPOOL)) {
DumpMempool();
}
@@ -342,6 +350,7 @@ std::string HelpMessage(HelpMessageMode mode)
if (showDebug)
strUsage += HelpMessageOpt("-feefilter", strprintf("Tell other nodes to filter invs to us by our mempool min fee (default: %u)", DEFAULT_FEEFILTER));
strUsage += HelpMessageOpt("-loadblock=<file>", _("Imports blocks from external blk000??.dat file on startup"));
+ strUsage += HelpMessageOpt("-debuglogfile=<file>", strprintf(_("Specify location of debug log file: this can be an absolute path or a path relative to the data directory (default: %s)"), DEFAULT_DEBUGLOGFILE));
strUsage += HelpMessageOpt("-maxorphantx=<n>", strprintf(_("Keep at most <n> unconnectable transactions in memory (default: %u)"), DEFAULT_MAX_ORPHAN_TRANSACTIONS));
strUsage += HelpMessageOpt("-maxmempool=<n>", strprintf(_("Keep the transaction memory pool below <n> megabytes (default: %u)"), DEFAULT_MAX_MEMPOOL_SIZE));
strUsage += HelpMessageOpt("-mempoolexpiry=<n>", strprintf(_("Do not keep transactions in the mempool longer than <n> hours (default: %u)"), DEFAULT_MEMPOOL_EXPIRY));
@@ -669,11 +678,13 @@ void ThreadImport(std::vector<fs::path> vImportFiles)
if (!ActivateBestChain(state, chainparams)) {
LogPrintf("Failed to connect best block");
StartShutdown();
+ return;
}
if (gArgs.GetBoolArg("-stopafterblockimport", DEFAULT_STOPAFTERBLOCKIMPORT)) {
LogPrintf("Stopping after block import\n");
StartShutdown();
+ return;
}
} // End scope of CImportingNow
if (gArgs.GetArg("-persistmempool", DEFAULT_PERSIST_MEMPOOL)) {
@@ -704,7 +715,7 @@ bool InitSanityCheck(void)
return true;
}
-bool AppInitServers(boost::thread_group& threadGroup)
+bool AppInitServers()
{
RPCServer::OnStarted(&OnRPCStarted);
RPCServer::OnStopped(&OnRPCStopped);
@@ -807,7 +818,13 @@ void InitLogging()
fLogIPs = gArgs.GetBoolArg("-logips", DEFAULT_LOGIPS);
LogPrintf("\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n");
- LogPrintf("Bitcoin version %s\n", FormatFullVersion());
+ std::string version_string = FormatFullVersion();
+#ifdef DEBUG
+ version_string += " (debug build)";
+#else
+ version_string += " (release build)";
+#endif
+ LogPrintf(PACKAGE_NAME " version %s\n", version_string);
}
namespace { // Variables internal to initialization process only
@@ -815,7 +832,7 @@ namespace { // Variables internal to initialization process only
int nMaxConnections;
int nUserMaxConnections;
int nFD;
-ServiceFlags nLocalServices = NODE_NETWORK;
+ServiceFlags nLocalServices = ServiceFlags(NODE_NETWORK | NODE_NETWORK_LIMITED);
} // namespace
@@ -1142,23 +1159,10 @@ bool AppInitParameterInteraction()
static bool LockDataDirectory(bool probeOnly)
{
- std::string strDataDir = GetDataDir().string();
-
// Make sure only a single Bitcoin process is using the data directory.
- fs::path pathLockFile = GetDataDir() / ".lock";
- FILE* file = fsbridge::fopen(pathLockFile, "a"); // empty lock file; created if it doesn't exist.
- if (file) fclose(file);
-
- try {
- static boost::interprocess::file_lock lock(pathLockFile.string().c_str());
- if (!lock.try_lock()) {
- return InitError(strprintf(_("Cannot obtain a lock on data directory %s. %s is probably already running."), strDataDir, _(PACKAGE_NAME)));
- }
- if (probeOnly) {
- lock.unlock();
- }
- } catch(const boost::interprocess::interprocess_exception& e) {
- return InitError(strprintf(_("Cannot obtain a lock on data directory %s. %s is probably already running.") + " %s.", strDataDir, _(PACKAGE_NAME), e.what()));
+ fs::path datadir = GetDataDir();
+ if (!LockDirectory(datadir, ".lock", probeOnly)) {
+ return InitError(strprintf(_("Cannot obtain a lock on data directory %s. %s is probably already running."), datadir.string(), _(PACKAGE_NAME)));
}
return true;
}
@@ -1196,7 +1200,7 @@ bool AppInitLockDataDirectory()
return true;
}
-bool AppInitMain(boost::thread_group& threadGroup, CScheduler& scheduler)
+bool AppInitMain()
{
const CChainParams& chainparams = Params();
// ********************************************************* Step 4a: application initialization
@@ -1209,8 +1213,11 @@ bool AppInitMain(boost::thread_group& threadGroup, CScheduler& scheduler)
ShrinkDebugFile();
}
- if (fPrintToDebugLog)
- OpenDebugLog();
+ if (fPrintToDebugLog) {
+ if (!OpenDebugLog()) {
+ return InitError(strprintf("Could not open debug log file %s", GetDebugLogPath().string()));
+ }
+ }
if (!fLogTimestamps)
LogPrintf("Startup time: %s\n", DateTimeStrFormat("%Y-%m-%d %H:%M:%S", GetTime()));
@@ -1219,6 +1226,15 @@ bool AppInitMain(boost::thread_group& threadGroup, CScheduler& scheduler)
LogPrintf("Using config file %s\n", GetConfigFile(gArgs.GetArg("-conf", BITCOIN_CONF_FILENAME)).string());
LogPrintf("Using at most %i automatic connections (%i file descriptors available)\n", nMaxConnections, nFD);
+ // Warn about relative -datadir path.
+ if (gArgs.IsArgSet("-datadir") && !fs::path(gArgs.GetArg("-datadir", "")).is_absolute()) {
+ LogPrintf("Warning: relative datadir option '%s' specified, which will be interpreted relative to the "
+ "current working directory '%s'. This is fragile, because if bitcoin is started in the future "
+ "from a different location, it will be unable to locate the current data files. There could "
+ "also be data loss if bitcoin is started while in a temporary directory.\n",
+ gArgs.GetArg("-datadir", ""), fs::current_path().string());
+ }
+
InitSignatureCache();
InitScriptExecutionCache();
@@ -1251,7 +1267,7 @@ bool AppInitMain(boost::thread_group& threadGroup, CScheduler& scheduler)
if (gArgs.GetBoolArg("-server", false))
{
uiInterface.InitMessage.connect(SetRPCWarmupStatus);
- if (!AppInitServers(threadGroup))
+ if (!AppInitServers())
return InitError(_("Unable to start HTTP server. See debug log for details."));
}
@@ -1411,6 +1427,9 @@ bool AppInitMain(boost::thread_group& threadGroup, CScheduler& scheduler)
pcoinsTip.reset();
pcoinsdbview.reset();
pcoinscatcher.reset();
+ // new CBlockTreeDB tries to delete the existing file, which
+ // fails if it's still open from the previous loop. Close it first:
+ pblocktree.reset();
pblocktree.reset(new CBlockTreeDB(nBlockTreeDBCache, false, fReset));
if (fReset) {
@@ -1631,12 +1650,19 @@ bool AppInitMain(boost::thread_group& threadGroup, CScheduler& scheduler)
// Wait for genesis block to be processed
{
WaitableLock lock(cs_GenesisWait);
- while (!fHaveGenesis) {
- condvar_GenesisWait.wait(lock);
+ // We previously could hang here if StartShutdown() is called prior to
+ // ThreadImport getting started, so instead we just wait on a timer to
+ // check ShutdownRequested() regularly.
+ while (!fHaveGenesis && !ShutdownRequested()) {
+ condvar_GenesisWait.wait_for(lock, std::chrono::milliseconds(500));
}
uiInterface.NotifyBlockTip.disconnect(BlockNotifyGenesisWait);
}
+ if (ShutdownRequested()) {
+ return false;
+ }
+
// ********************************************************* Step 11: start node
int chain_active_height;
@@ -1722,5 +1748,5 @@ bool AppInitMain(boost::thread_group& threadGroup, CScheduler& scheduler)
StartWallets(scheduler);
#endif
- return !fRequestShutdown;
+ return true;
}