diff --git a/src/Makefile.am b/src/Makefile.am index 56c1226e59..d3eabbf2f3 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -332,6 +332,7 @@ BITCOIN_CORE_H = \ util/sock.h \ util/string.h \ util/time.h \ + util/thread.h \ util/threadnames.h \ util/trace.h \ util/translation.h \ @@ -755,6 +756,7 @@ libbitcoin_util_a_SOURCES = \ util/time.cpp \ util/serfloat.cpp \ util/string.cpp \ + util/thread.cpp \ util/threadnames.cpp \ $(BITCOIN_CORE_H) diff --git a/src/index/base.cpp b/src/index/base.cpp index cc8e12b77b..9d99117c9a 100644 --- a/src/index/base.cpp +++ b/src/index/base.cpp @@ -8,6 +8,7 @@ #include #include #include +#include #include #include // For g_chainman #include @@ -353,8 +354,7 @@ bool BaseIndex::Start(CChainState& active_chainstate) return false; } - m_thread_sync = std::thread(&TraceThread>, GetName(), - std::bind(&BaseIndex::ThreadSync, this)); + m_thread_sync = std::thread(&util::TraceThread, GetName(), [this] { ThreadSync(); }); return true; } diff --git a/src/init.cpp b/src/init.cpp index 92b7cb64ff..ea2ca1590d 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -61,6 +61,7 @@ #include #include #include +#include #include #include #include @@ -1618,7 +1619,7 @@ bool AppInitMain(const CoreContext& context, NodeContext& node, interfaces::Bloc node.scheduler = std::make_unique(); // Start the lightweight task scheduler thread - node.scheduler->m_service_thread = std::thread([&] { TraceThread("scheduler", [&] { node.scheduler->serviceQueue(); }); }); + node.scheduler->m_service_thread = std::thread(util::TraceThread, "scheduler", [&] { node.scheduler->serviceQueue(); }); // Gather some entropy once per minute. node.scheduler->scheduleEvery([]{ @@ -2391,7 +2392,7 @@ bool AppInitMain(const CoreContext& context, NodeContext& node, interfaces::Bloc vImportFiles.push_back(strFile); } - chainman.m_load_block = std::thread(&TraceThread>, "loadblk", [=, &chainman, &args] { + chainman.m_load_block = std::thread(&util::TraceThread, "loadblk", [=, &chainman, &args] { ThreadImport(chainman, *pdsNotificationInterface ,vImportFiles, args); }); diff --git a/src/llmq/chainlocks.cpp b/src/llmq/chainlocks.cpp index ea74ef86ff..977824a0e4 100644 --- a/src/llmq/chainlocks.cpp +++ b/src/llmq/chainlocks.cpp @@ -18,6 +18,7 @@ #include #include #include +#include #include namespace llmq @@ -37,7 +38,7 @@ CChainLocksHandler::CChainLocksHandler(CChainState& chainstate, CConnman& _connm mempool(_mempool), m_peerman(peerman), scheduler(std::make_unique()), - scheduler_thread(std::make_unique([&] { TraceThread("cl-schdlr", [&] { scheduler->serviceQueue(); }); })) + scheduler_thread(std::make_unique(std::thread(util::TraceThread, "cl-schdlr", [&] { scheduler->serviceQueue(); }))) { } diff --git a/src/llmq/dkgsessionhandler.cpp b/src/llmq/dkgsessionhandler.cpp index 6fa5ae4ed8..b5f515e13f 100644 --- a/src/llmq/dkgsessionhandler.cpp +++ b/src/llmq/dkgsessionhandler.cpp @@ -16,6 +16,7 @@ #include #include #include +#include #include namespace llmq @@ -151,8 +152,8 @@ void CDKGSessionHandler::StartThread() throw std::runtime_error("Tried to start an already started CDKGSessionHandler thread."); } - std::string threadName = strprintf("llmq-%d-%d", ToUnderlying(params.type), quorumIndex); - phaseHandlerThread = std::thread(&TraceThread >, threadName, std::function(std::bind(&CDKGSessionHandler::PhaseHandlerThread, this))); + m_thread_name = strprintf("llmq-%d-%d", ToUnderlying(params.type), quorumIndex); + phaseHandlerThread = std::thread(util::TraceThread, m_thread_name.c_str(), [this] { PhaseHandlerThread(); }); } void CDKGSessionHandler::StopThread() diff --git a/src/llmq/dkgsessionhandler.h b/src/llmq/dkgsessionhandler.h index 78b2c3abc3..901086f521 100644 --- a/src/llmq/dkgsessionhandler.h +++ b/src/llmq/dkgsessionhandler.h @@ -127,6 +127,7 @@ private: std::unique_ptr curSession; std::thread phaseHandlerThread; + std::string m_thread_name; // Do not guard these, they protect their internals themselves CDKGPendingMessages pendingContributions; diff --git a/src/llmq/instantsend.cpp b/src/llmq/instantsend.cpp index 99736d970e..94fb2c7851 100644 --- a/src/llmq/instantsend.cpp +++ b/src/llmq/instantsend.cpp @@ -20,6 +20,7 @@ #include #include #include +#include #include #include @@ -459,7 +460,7 @@ void CInstantSendManager::Start() assert(false); } - workThread = std::thread(&TraceThread >, "isman", std::function(std::bind(&CInstantSendManager::WorkThreadMain, this))); + workThread = std::thread(&util::TraceThread, "isman", [this] { WorkThreadMain(); }); sigman.RegisterRecoveredSigsListener(this); } diff --git a/src/llmq/signing_shares.cpp b/src/llmq/signing_shares.cpp index 116f7591d2..7c6539cb42 100644 --- a/src/llmq/signing_shares.cpp +++ b/src/llmq/signing_shares.cpp @@ -17,6 +17,7 @@ #include #include #include +#include #include #include @@ -183,9 +184,7 @@ void CSigSharesManager::StartWorkerThread() assert(false); } - workThread = std::thread(&TraceThread >, - "sigshares", - std::function(std::bind(&CSigSharesManager::WorkThreadMain, this))); + workThread = std::thread(&util::TraceThread, "sigshares", [this] { WorkThreadMain(); }); } void CSigSharesManager::StopWorkerThread() diff --git a/src/mapport.cpp b/src/mapport.cpp index 2df4ce45d2..135efb561e 100644 --- a/src/mapport.cpp +++ b/src/mapport.cpp @@ -15,6 +15,7 @@ #include #include #include +#include #ifdef USE_NATPMP #include @@ -255,7 +256,7 @@ void StartThreadMapPort() { if (!g_mapport_thread.joinable()) { assert(!g_mapport_interrupt); - g_mapport_thread = std::thread(std::bind(&TraceThread, "mapport", &ThreadMapPort)); + g_mapport_thread = std::thread(&util::TraceThread, "mapport", &ThreadMapPort); } } diff --git a/src/net.cpp b/src/net.cpp index ecd96534e0..f5a606dd78 100644 --- a/src/net.cpp +++ b/src/net.cpp @@ -25,6 +25,7 @@ #include #include #include +#include #include #include @@ -3195,15 +3196,15 @@ bool CConnman::Start(CScheduler& scheduler, const Options& connOptions) #endif // Send and receive from sockets, accept connections - threadSocketHandler = std::thread(&TraceThread >, "net", std::function(std::bind(&CConnman::ThreadSocketHandler, this))); + threadSocketHandler = std::thread(&util::TraceThread, "net", [this] { ThreadSocketHandler(); }); if (!gArgs.GetBoolArg("-dnsseed", true)) LogPrintf("DNS seeding disabled\n"); else - threadDNSAddressSeed = std::thread(&TraceThread >, "dnsseed", std::function(std::bind(&CConnman::ThreadDNSAddressSeed, this))); + threadDNSAddressSeed = std::thread(&util::TraceThread, "dnsseed", [this] { ThreadDNSAddressSeed(); }); // Initiate outbound connections from -addnode - threadOpenAddedConnections = std::thread(&TraceThread >, "addcon", std::function(std::bind(&CConnman::ThreadOpenAddedConnections, this))); + threadOpenAddedConnections = std::thread(&util::TraceThread, "addcon", [this] { ThreadOpenAddedConnections(); }); if (connOptions.m_use_addrman_outgoing && !connOptions.m_specified_outgoing.empty()) { if (clientInterface) { @@ -3213,19 +3214,21 @@ bool CConnman::Start(CScheduler& scheduler, const Options& connOptions) } return false; } - if (connOptions.m_use_addrman_outgoing || !connOptions.m_specified_outgoing.empty()) - threadOpenConnections = std::thread(&TraceThread >, "opencon", std::function(std::bind(&CConnman::ThreadOpenConnections, this, connOptions.m_specified_outgoing))); + if (connOptions.m_use_addrman_outgoing || !connOptions.m_specified_outgoing.empty()) { + threadOpenConnections = std::thread( + &util::TraceThread, "opencon", + [this, connect = connOptions.m_specified_outgoing] { ThreadOpenConnections(connect); }); + } // Initiate masternode connections - threadOpenMasternodeConnections = std::thread(&TraceThread >, "mncon", std::function(std::bind(&CConnman::ThreadOpenMasternodeConnections, this))); + threadOpenMasternodeConnections = std::thread(&util::TraceThread, "mncon", [this] { ThreadOpenMasternodeConnections(); }); // Process messages - threadMessageHandler = std::thread(&TraceThread >, "msghand", std::function(std::bind(&CConnman::ThreadMessageHandler, this))); + threadMessageHandler = std::thread(&util::TraceThread, "msghand", [this] { ThreadMessageHandler(); }); if (connOptions.m_i2p_accept_incoming && m_i2p_sam_session.get() != nullptr) { threadI2PAcceptIncoming = - std::thread(&TraceThread>, "i2paccept", - std::function(std::bind(&CConnman::ThreadI2PAcceptIncoming, this))); + std::thread(&util::TraceThread, "i2paccept", [this] { ThreadI2PAcceptIncoming(); }); } // Dump network addresses diff --git a/src/qt/bitcoin.cpp b/src/qt/bitcoin.cpp index 6e39f7800b..54a2e1160a 100644 --- a/src/qt/bitcoin.cpp +++ b/src/qt/bitcoin.cpp @@ -37,6 +37,7 @@ #include #include #include +#include #include #include diff --git a/src/test/util/setup_common.cpp b/src/test/util/setup_common.cpp index bc96ae7f14..948e2932d1 100644 --- a/src/test/util/setup_common.cpp +++ b/src/test/util/setup_common.cpp @@ -43,6 +43,8 @@ #include #include #include +#include +#include #include #include #include @@ -188,7 +190,7 @@ ChainTestingSetup::ChainTestingSetup(const std::string& chainName, const std::ve // We have to run a scheduler thread to prevent ActivateBestChain // from blocking due to queue overrun. m_node.scheduler = std::make_unique(); - m_node.scheduler->m_service_thread = std::thread([&] { TraceThread("scheduler", [&] { m_node.scheduler->serviceQueue(); }); }); + m_node.scheduler->m_service_thread = std::thread(util::TraceThread, "scheduler", [&] { m_node.scheduler->serviceQueue(); }); GetMainSignals().RegisterBackgroundSignalScheduler(*m_node.scheduler); pblocktree.reset(new CBlockTreeDB(1 << 20, true)); diff --git a/src/torcontrol.cpp b/src/torcontrol.cpp index ca9eef212f..80f192732a 100644 --- a/src/torcontrol.cpp +++ b/src/torcontrol.cpp @@ -15,6 +15,7 @@ #include #include #include +#include #include #include @@ -601,7 +602,7 @@ void StartTorControl(CService onion_service_target) return; } - torControlThread = std::thread(&TraceThread>, "torcontrol", [onion_service_target] { + torControlThread = std::thread(&util::TraceThread, "torcontrol", [onion_service_target] { TorControlThread(onion_service_target); }); } diff --git a/src/txmempool.cpp b/src/txmempool.cpp index 37cd75a165..aae9e0d61c 100644 --- a/src/txmempool.cpp +++ b/src/txmempool.cpp @@ -25,6 +25,7 @@ #include #include +#include #include CTxMemPoolEntry::CTxMemPoolEntry(const CTransactionRef& _tx, const CAmount& _nFee, diff --git a/src/util/system.cpp b/src/util/system.cpp index dd61721282..9f006b0216 100644 --- a/src/util/system.cpp +++ b/src/util/system.cpp @@ -13,6 +13,7 @@ #include #include #include +#include #include diff --git a/src/util/system.h b/src/util/system.h index d086b779dd..63a0940cf0 100644 --- a/src/util/system.h +++ b/src/util/system.h @@ -23,7 +23,6 @@ #include #include #include -#include #include #include @@ -468,24 +467,6 @@ namespace ctpl { } void RenameThreadPool(ctpl::thread_pool& tp, const char* baseName); -/** - * .. and a wrapper that just calls func once - */ -template void TraceThread(const std::string name, Callable func) -{ - util::ThreadRename(name.c_str()); - try - { - LogPrintf("%s thread start\n", name); - func(); - LogPrintf("%s thread exit\n", name); - } - catch (...) { - PrintExceptionContinue(std::current_exception(), name.c_str()); - throw; - } -} - std::string CopyrightHolders(const std::string& strPrefix, unsigned int nStartYear, unsigned int nEndYear); /** diff --git a/src/util/thread.cpp b/src/util/thread.cpp new file mode 100644 index 0000000000..1bf3d36bef --- /dev/null +++ b/src/util/thread.cpp @@ -0,0 +1,24 @@ +// Copyright (c) 2021 The Bitcoin Core developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#include + +#include +#include +#include + +#include + +void util::TraceThread(const char* thread_name, std::function thread_func) +{ + util::ThreadRename(thread_name); + try { + LogPrintf("%s thread start\n", thread_name); + thread_func(); + LogPrintf("%s thread exit\n", thread_name); + } catch (...) { + PrintExceptionContinue(std::current_exception(), thread_name); + throw; + } +} diff --git a/src/util/thread.h b/src/util/thread.h new file mode 100644 index 0000000000..ca2eccc0c3 --- /dev/null +++ b/src/util/thread.h @@ -0,0 +1,18 @@ +// Copyright (c) 2021 The Bitcoin Core developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#ifndef BITCOIN_UTIL_THREAD_H +#define BITCOIN_UTIL_THREAD_H + +#include + +namespace util { +/** + * A wrapper for do-something-once thread functions. + */ +void TraceThread(const char* thread_name, std::function thread_func); + +} // namespace util + +#endif // BITCOIN_UTIL_THREAD_H