diff --git a/src/init.cpp b/src/init.cpp --- a/src/init.cpp +++ b/src/init.cpp @@ -177,7 +177,6 @@ static std::unique_ptr globalVerifyHandle; static boost::thread_group threadGroup; -static CScheduler scheduler; void Interrupt(NodeContext &node) { InterruptHTTPServer(); @@ -325,6 +324,7 @@ if (node.mempool) { node.mempool = nullptr; } + node.scheduler.reset(); LogPrintf("%s: done\n", __func__); } @@ -2138,21 +2138,25 @@ } } + assert(!node.scheduler); + node.scheduler = std::make_unique(); + // Start the lightweight task scheduler thread - CScheduler::Function serviceLoop = - std::bind(&CScheduler::serviceQueue, &scheduler); + CScheduler::Function serviceLoop = [&node] { + node.scheduler->serviceQueue(); + }; threadGroup.create_thread(std::bind(&TraceThread, "scheduler", serviceLoop)); // Gather some entropy once per minute. - scheduler.scheduleEvery( + node.scheduler->scheduleEvery( [] { RandAddPeriodic(); return true; }, 60000); - GetMainSignals().RegisterBackgroundSignalScheduler(scheduler); + GetMainSignals().RegisterBackgroundSignalScheduler(*node.scheduler); // Create client interfaces for wallets that are supposed to be loaded // according to -wallet and -disablewallet options. This only constructs @@ -2211,9 +2215,9 @@ config, GetRand(std::numeric_limits::max()), GetRand(std::numeric_limits::max())); - node.peer_logic = std::make_unique( - node.connman.get(), node.banman.get(), scheduler, - gArgs.GetBoolArg("-enablebip61", DEFAULT_ENABLE_BIP61)); + node.peer_logic.reset(new PeerLogicValidation( + node.connman.get(), node.banman.get(), *node.scheduler, + gArgs.GetBoolArg("-enablebip61", DEFAULT_ENABLE_BIP61))); RegisterValidationInterface(node.peer_logic.get()); // sanitize comments per BIP-0014, format user agent and check total size @@ -2784,7 +2788,7 @@ connOptions.m_specified_outgoing = connect; } } - if (!node.connman->Start(scheduler, connOptions)) { + if (!node.connman->Start(*node.scheduler, connOptions)) { return false; } @@ -2794,11 +2798,11 @@ uiInterface.InitMessage(_("Done loading").translated); for (const auto &client : node.chain_clients) { - client->start(scheduler); + client->start(*node.scheduler); } BanMan *banman = node.banman.get(); - scheduler.scheduleEvery( + node.scheduler->scheduleEvery( [banman] { banman->DumpBanlist(); return true; @@ -2806,7 +2810,7 @@ DUMP_BANS_INTERVAL * 1000); // Start Avalanche's event loop. - g_avalanche->startEventLoop(scheduler); + g_avalanche->startEventLoop(*node.scheduler); return true; } diff --git a/src/node/context.h b/src/node/context.h --- a/src/node/context.h +++ b/src/node/context.h @@ -10,6 +10,7 @@ class BanMan; class CConnman; +class CScheduler; class CTxMemPool; class PeerLogicValidation; namespace interfaces { @@ -35,6 +36,7 @@ std::unique_ptr banman; std::unique_ptr chain; std::vector> chain_clients; + std::unique_ptr scheduler; //! Declare default constructor and destructor that are not inline, so code //! instantiating the NodeContext struct doesn't need to #include class diff --git a/src/node/context.cpp b/src/node/context.cpp --- a/src/node/context.cpp +++ b/src/node/context.cpp @@ -8,6 +8,7 @@ #include #include #include +#include NodeContext::NodeContext() {} NodeContext::~NodeContext() {} diff --git a/src/test/avalanche_tests.cpp b/src/test/avalanche_tests.cpp --- a/src/test/avalanche_tests.cpp +++ b/src/test/avalanche_tests.cpp @@ -214,7 +214,7 @@ auto connman = std::make_unique(config, 0x1337, 0x1337); auto peerLogic = std::make_unique( - connman.get(), nullptr, scheduler, false); + connman.get(), nullptr, *m_node.scheduler, false); AvalancheProcessor p(connman.get()); std::vector updates; @@ -382,7 +382,7 @@ auto connman = std::make_unique(config, 0x1337, 0x1337); auto peerLogic = std::make_unique( - connman.get(), nullptr, scheduler, false); + connman.get(), nullptr, *m_node.scheduler, false); AvalancheProcessor p(connman.get()); CBlockIndex indexA, indexB; @@ -499,7 +499,7 @@ auto connman = std::make_unique(config, 0x1337, 0x1337); auto peerLogic = std::make_unique( - connman.get(), nullptr, scheduler, false); + connman.get(), nullptr, *m_node.scheduler, false); AvalancheProcessor p(connman.get()); @@ -654,7 +654,7 @@ auto connman = std::make_unique(config, 0x1337, 0x1337); auto peerLogic = std::make_unique( - connman.get(), nullptr, scheduler, false); + connman.get(), nullptr, *m_node.scheduler, false); AvalancheProcessor p(connman.get()); @@ -722,7 +722,7 @@ auto connman = std::make_unique(config, 0x1337, 0x1337); auto peerLogic = std::make_unique( - connman.get(), nullptr, scheduler, false); + connman.get(), nullptr, *m_node.scheduler, false); AvalancheProcessor p(connman.get()); @@ -785,7 +785,7 @@ auto connman = std::make_unique(config, 0x1337, 0x1337); auto peerLogic = std::make_unique( - connman.get(), nullptr, scheduler, false); + connman.get(), nullptr, *m_node.scheduler, false); AvalancheProcessor p(connman.get()); std::vector updates; @@ -861,7 +861,7 @@ auto connman = std::make_unique(config, 0x1337, 0x1337); auto peerLogic = std::make_unique( - connman.get(), nullptr, scheduler, false); + connman.get(), nullptr, *m_node.scheduler, false); AvalancheProcessor p(connman.get()); CScheduler s; diff --git a/src/test/denialofservice_tests.cpp b/src/test/denialofservice_tests.cpp --- a/src/test/denialofservice_tests.cpp +++ b/src/test/denialofservice_tests.cpp @@ -77,7 +77,7 @@ auto connman = std::make_unique(config, 0x1337, 0x1337); auto peerLogic = std::make_unique( - connman.get(), nullptr, scheduler, false); + connman.get(), nullptr, *m_node.scheduler, false); // Mock an outbound peer CAddress addr1(ip(0xa0b0c001), NODE_NONE); @@ -158,7 +158,7 @@ auto connman = std::make_unique(config, 0x1337, 0x1337); auto peerLogic = std::make_unique( - connman.get(), nullptr, scheduler, false); + connman.get(), nullptr, *m_node.scheduler, false); const Consensus::Params &consensusParams = config.GetChainParams().GetConsensus(); @@ -237,7 +237,7 @@ DEFAULT_MISBEHAVING_BANTIME); auto connman = std::make_unique(config, 0x1337, 0x1337); auto peerLogic = std::make_unique( - connman.get(), banman.get(), scheduler, false); + connman.get(), banman.get(), *m_node.scheduler, false); banman->ClearBanned(); CAddress addr1(ip(0xa0b0c001), NODE_NONE); @@ -303,7 +303,7 @@ DEFAULT_MISBEHAVING_BANTIME); auto connman = std::make_unique(config, 0x1337, 0x1337); auto peerLogic = std::make_unique( - connman.get(), banman.get(), scheduler, false); + connman.get(), banman.get(), *m_node.scheduler, false); banman->ClearBanned(); // because 11 is my favorite number. @@ -357,7 +357,7 @@ DEFAULT_MISBEHAVING_BANTIME); auto connman = std::make_unique(config, 0x1337, 0x1337); auto peerLogic = std::make_unique( - connman.get(), banman.get(), scheduler, false); + connman.get(), banman.get(), *m_node.scheduler, false); banman->ClearBanned(); int64_t nStartTime = GetTime(); diff --git a/src/test/util/setup_common.h b/src/test/util/setup_common.h --- a/src/test/util/setup_common.h +++ b/src/test/util/setup_common.h @@ -93,7 +93,6 @@ struct TestingSetup : public BasicTestingSetup { NodeContext m_node; boost::thread_group threadGroup; - CScheduler scheduler; explicit TestingSetup( const std::string &chainName = CBaseChainParams::MAIN); diff --git a/src/test/util/setup_common.cpp b/src/test/util/setup_common.cpp --- a/src/test/util/setup_common.cpp +++ b/src/test/util/setup_common.cpp @@ -108,10 +108,12 @@ SetRPCWarmupFinished(); } + m_node.scheduler = std::make_unique(); + // We have to run a scheduler thread to prevent ActivateBestChain // from blocking due to queue overrun. - threadGroup.create_thread(std::bind(&CScheduler::serviceQueue, &scheduler)); - GetMainSignals().RegisterBackgroundSignalScheduler(scheduler); + threadGroup.create_thread([&] { m_node.scheduler->serviceQueue(); }); + GetMainSignals().RegisterBackgroundSignalScheduler(*g_rpc_node->scheduler); pblocktree.reset(new CBlockTreeDB(1 << 20, true)); pcoinsdbview.reset(new CCoinsViewDB(1 << 23, true)); @@ -149,6 +151,7 @@ m_node.connman.reset(); m_node.banman.reset(); m_node.mempool = nullptr; + m_node.scheduler.reset(); UnloadBlockIndex(); pcoinsTip.reset(); pcoinsdbview.reset();