init: Split up AppInit2 into multiple phases
This allows doing some of the steps before e.g. daemonization and some fater.
This commit is contained in:
parent
67728a389c
commit
0cc8b6bc44
4 changed files with 95 additions and 21 deletions
|
@ -128,6 +128,26 @@ bool AppInit(int argc, char* argv[])
|
|||
fprintf(stderr, "Error: There is no RPC client functionality in bitcoind anymore. Use the bitcoin-cli utility instead.\n");
|
||||
exit(1);
|
||||
}
|
||||
// -server defaults to true for bitcoind but not for the GUI so do this here
|
||||
SoftSetBoolArg("-server", true);
|
||||
// Set this early so that parameter interactions go to console
|
||||
InitLogging();
|
||||
InitParameterInteraction();
|
||||
if (!AppInitBasicSetup())
|
||||
{
|
||||
// InitError will have been called with detailed error, which ends up on console
|
||||
exit(1);
|
||||
}
|
||||
if (!AppInitParameterInteraction())
|
||||
{
|
||||
// InitError will have been called with detailed error, which ends up on console
|
||||
exit(1);
|
||||
}
|
||||
if (!AppInitSanityChecks())
|
||||
{
|
||||
// InitError will have been called with detailed error, which ends up on console
|
||||
exit(1);
|
||||
}
|
||||
if (GetBoolArg("-daemon", false))
|
||||
{
|
||||
#if HAVE_DECL_DAEMON
|
||||
|
@ -143,12 +163,8 @@ bool AppInit(int argc, char* argv[])
|
|||
return false;
|
||||
#endif // HAVE_DECL_DAEMON
|
||||
}
|
||||
SoftSetBoolArg("-server", true);
|
||||
|
||||
// Set this early so that parameter interactions go to console
|
||||
InitLogging();
|
||||
InitParameterInteraction();
|
||||
fRet = AppInit2(threadGroup, scheduler);
|
||||
fRet = AppInitMain(threadGroup, scheduler);
|
||||
}
|
||||
catch (const std::exception& e) {
|
||||
PrintExceptionContinue(&e, "AppInit()");
|
||||
|
|
48
src/init.cpp
48
src/init.cpp
|
@ -788,10 +788,17 @@ void InitLogging()
|
|||
LogPrintf("Bitcoin version %s\n", FormatFullVersion());
|
||||
}
|
||||
|
||||
/** Initialize bitcoin.
|
||||
* @pre Parameters should be parsed and config file should be read.
|
||||
*/
|
||||
bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler)
|
||||
namespace { // Variables internal to initialization process only
|
||||
|
||||
ServiceFlags nRelevantServices = NODE_NETWORK;
|
||||
int nMaxConnections;
|
||||
int nUserMaxConnections;
|
||||
int nFD;
|
||||
ServiceFlags nLocalServices = NODE_NETWORK;
|
||||
|
||||
}
|
||||
|
||||
bool AppInitBasicSetup()
|
||||
{
|
||||
// ********************************************************* Step 1: setup
|
||||
#ifdef _MSC_VER
|
||||
|
@ -843,9 +850,13 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler)
|
|||
// Ignore SIGPIPE, otherwise it will bring the daemon down if the client closes unexpectedly
|
||||
signal(SIGPIPE, SIG_IGN);
|
||||
#endif
|
||||
return true;
|
||||
}
|
||||
|
||||
// ********************************************************* Step 2: parameter interactions
|
||||
bool AppInitParameterInteraction()
|
||||
{
|
||||
const CChainParams& chainparams = Params();
|
||||
// ********************************************************* Step 2: parameter interactions
|
||||
|
||||
// also see: InitParameterInteraction()
|
||||
|
||||
|
@ -857,12 +868,12 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler)
|
|||
|
||||
// Make sure enough file descriptors are available
|
||||
int nBind = std::max((int)mapArgs.count("-bind") + (int)mapArgs.count("-whitebind"), 1);
|
||||
int nUserMaxConnections = GetArg("-maxconnections", DEFAULT_MAX_PEER_CONNECTIONS);
|
||||
int nMaxConnections = std::max(nUserMaxConnections, 0);
|
||||
nUserMaxConnections = GetArg("-maxconnections", DEFAULT_MAX_PEER_CONNECTIONS);
|
||||
nMaxConnections = std::max(nUserMaxConnections, 0);
|
||||
|
||||
// Trim requested connection counts, to fit into system limitations
|
||||
nMaxConnections = std::max(std::min(nMaxConnections, (int)(FD_SETSIZE - nBind - MIN_CORE_FILEDESCRIPTORS)), 0);
|
||||
int nFD = RaiseFileDescriptorLimit(nMaxConnections + MIN_CORE_FILEDESCRIPTORS);
|
||||
nFD = RaiseFileDescriptorLimit(nMaxConnections + MIN_CORE_FILEDESCRIPTORS);
|
||||
if (nFD < MIN_CORE_FILEDESCRIPTORS)
|
||||
return InitError(_("Not enough file descriptors available."));
|
||||
nMaxConnections = std::min(nFD - MIN_CORE_FILEDESCRIPTORS, nMaxConnections);
|
||||
|
@ -977,9 +988,6 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler)
|
|||
// Option to startup with mocktime set (used for regression testing):
|
||||
SetMockTime(GetArg("-mocktime", 0)); // SetMockTime(0) is a no-op
|
||||
|
||||
ServiceFlags nLocalServices = NODE_NETWORK;
|
||||
ServiceFlags nRelevantServices = NODE_NETWORK;
|
||||
|
||||
if (GetBoolArg("-peerbloomfilters", DEFAULT_PEERBLOOMFILTERS))
|
||||
nLocalServices = ServiceFlags(nLocalServices | NODE_BLOOM);
|
||||
|
||||
|
@ -1028,8 +1036,12 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler)
|
|||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// ********************************************************* Step 4: application initialization: dir lock, daemonize, pidfile, debug log
|
||||
bool AppInitSanityChecks()
|
||||
{
|
||||
// ********************************************************* Step 4: sanity checks
|
||||
|
||||
// Initialize elliptic curve code
|
||||
ECC_Start();
|
||||
|
@ -1048,11 +1060,19 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler)
|
|||
|
||||
try {
|
||||
static boost::interprocess::file_lock lock(pathLockFile.string().c_str());
|
||||
if (!lock.try_lock())
|
||||
if (!lock.try_lock()) {
|
||||
return InitError(strprintf(_("Cannot obtain a lock on data directory %s. %s is probably already running."), strDataDir, _(PACKAGE_NAME)));
|
||||
}
|
||||
} 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()));
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool AppInitMain(boost::thread_group& threadGroup, CScheduler& scheduler)
|
||||
{
|
||||
const CChainParams& chainparams = Params();
|
||||
// ********************************************************* Step 4a: application initialization
|
||||
|
||||
#ifndef WIN32
|
||||
CreatePidFile(GetPidFile(), getpid());
|
||||
|
@ -1066,7 +1086,7 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler)
|
|||
if (!fLogTimestamps)
|
||||
LogPrintf("Startup time: %s\n", DateTimeStrFormat("%Y-%m-%d %H:%M:%S", GetTime()));
|
||||
LogPrintf("Default data directory %s\n", GetDefaultDataDir().string());
|
||||
LogPrintf("Using data directory %s\n", strDataDir);
|
||||
LogPrintf("Using data directory %s\n", GetDataDir().string());
|
||||
LogPrintf("Using config file %s\n", GetConfigFile(GetArg("-conf", BITCOIN_CONF_FILENAME)).string());
|
||||
LogPrintf("Using at most %i connections (%i file descriptors available)\n", nMaxConnections, nFD);
|
||||
|
||||
|
|
25
src/init.h
25
src/init.h
|
@ -25,7 +25,30 @@ void Shutdown();
|
|||
void InitLogging();
|
||||
//!Parameter interaction: change current parameters depending on various rules
|
||||
void InitParameterInteraction();
|
||||
bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler);
|
||||
|
||||
/** Initialize bitcoin core: Basic context setup.
|
||||
* @note This can be done before daemonization.
|
||||
* @pre Parameters should be parsed and config file should be read.
|
||||
*/
|
||||
bool AppInitBasicSetup();
|
||||
/**
|
||||
* Initialization: parameter interaction.
|
||||
* @note This can be done before daemonization.
|
||||
* @pre Parameters should be parsed and config file should be read, AppInitBasicSetup should have been called.
|
||||
*/
|
||||
bool AppInitParameterInteraction();
|
||||
/**
|
||||
* Initialization sanity checks: ecc init, sanity checks, dir lock.
|
||||
* @note This can be done before daemonization.
|
||||
* @pre Parameters should be parsed and config file should be read, AppInitParameterInteraction should have been called.
|
||||
*/
|
||||
bool AppInitSanityChecks();
|
||||
/**
|
||||
* Bitcoin core main initialization.
|
||||
* @note This should only be done after daemonization.
|
||||
* @pre Parameters should be parsed and config file should be read, AppInitSanityChecks should have been called.
|
||||
*/
|
||||
bool AppInitMain(boost::thread_group& threadGroup, CScheduler& scheduler);
|
||||
|
||||
/** The help message mode determines what help message to show */
|
||||
enum HelpMessageMode {
|
||||
|
|
|
@ -267,7 +267,22 @@ void BitcoinCore::initialize()
|
|||
try
|
||||
{
|
||||
qDebug() << __func__ << ": Running AppInit2 in thread";
|
||||
int rv = AppInit2(threadGroup, scheduler);
|
||||
if (!AppInitBasicSetup())
|
||||
{
|
||||
Q_EMIT initializeResult(false);
|
||||
return;
|
||||
}
|
||||
if (!AppInitParameterInteraction())
|
||||
{
|
||||
Q_EMIT initializeResult(false);
|
||||
return;
|
||||
}
|
||||
if (!AppInitSanityChecks())
|
||||
{
|
||||
Q_EMIT initializeResult(false);
|
||||
return;
|
||||
}
|
||||
int rv = AppInitMain(threadGroup, scheduler);
|
||||
Q_EMIT initializeResult(rv);
|
||||
} catch (const std::exception& e) {
|
||||
handleRunawayException(&e);
|
||||
|
|
Loading…
Reference in a new issue