Split up AppInit2 into multiple steps: This allows doing some of the steps before daemonization and some later.
To avoid the issue described in #9009 (comment):
- Before daemonization, just probe the data directory lock and print an early error message if possible.
- After daemonization get the data directory lock again and hold on to it until exit. This creates a slight window for a race condition to happen, however this condition is harmless: it will at most make the process exit without printing a message to console as it will be detected after daemonization.
Solves #9009:
0$ src/bitcoind -testnet -daemon
1Bitcoin server starting
2$ src/bitcoind -testnet -daemon
3Error: Cannot obtain a lock on data directory /home/orion/.bitcoin/testnet3. Bitcoin Core is probably already running.
As for the AppInit2 split: This is something I’ve been wanting to do for a while. Note that, to reduce risk of regressions, this is just mechanic code movement and doesn’t change ordering, besides the daemon()
invocation.
Some smarter things could be done such as:
- Move basic context initialization from
AppInitBasicSetup()
toSetupEnvironment()
where possible, especially things such as the windows DEP activation - Unify
InitParameterInteraction()
andAppInitParameterInteraction()
if/where possible. I’m not sure why this is done in two steps with justAppInitBasicSetup()
in between right now. - Do something smarter than
// Variables internal to initialization process only
(e.g. an initialization context structure). Some variables there may be completely avoided by moving the code to extract the arguments. - Splitting up further steps, this will allow factoring out
ENABLE_WALLET
sections fromlibbitcoin_server.a
(which contains init.cpp) and remove the circular dependencies (#7965) - It is now possible to do unit testing on our initialization steps in isolation.
However I do not intend to do these things in this pull.