diff --git a/src/Makefile.am b/src/Makefile.am index 972a3e279bf..41fab024c6f 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -257,6 +257,7 @@ BITCOIN_CORE_H = \ util/spanparsing.h \ util/string.h \ util/system.h \ + util/thread.h \ util/threadnames.h \ util/time.h \ util/tokenpipe.h \ @@ -590,6 +591,7 @@ libbitcoin_util_a_SOURCES = \ util/rbf.cpp \ util/readwritefile.cpp \ util/settings.cpp \ + util/thread.cpp \ util/threadnames.cpp \ util/spanparsing.cpp \ util/strencodings.cpp \ diff --git a/src/index/base.cpp b/src/index/base.cpp index 357c4fbaf92..0ab49f8a376 100644 --- a/src/index/base.cpp +++ b/src/index/base.cpp @@ -8,7 +8,7 @@ #include #include #include -#include +#include #include #include // For g_chainman #include @@ -349,8 +349,7 @@ void BaseIndex::Start() return; } - m_thread_sync = std::thread(&TraceThread>, GetName(), - std::bind(&BaseIndex::ThreadSync, this)); + m_thread_sync = std::thread(&util::TraceThread, GetName(), [this] { ThreadSync(); }); } void BaseIndex::Stop() diff --git a/src/init.cpp b/src/init.cpp index a0241f4c3d9..481c3c7d635 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -59,6 +59,7 @@ #include #include #include +#include #include #include #include @@ -1114,7 +1115,7 @@ bool AppInitMain(NodeContext& node, interfaces::BlockAndHeaderTipInfo* tip_info) 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([]{ @@ -1629,7 +1630,7 @@ bool AppInitMain(NodeContext& node, interfaces::BlockAndHeaderTipInfo* tip_info) 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, vImportFiles, args); }); diff --git a/src/mapport.cpp b/src/mapport.cpp index 2df4ce45d2f..135efb561e1 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 ea5d11da186..bbc0b810561 100644 --- a/src/net.cpp +++ b/src/net.cpp @@ -23,6 +23,7 @@ #include #include #include +#include #include #ifdef WIN32 @@ -2519,15 +2520,15 @@ bool CConnman::Start(CScheduler& scheduler, const Options& connOptions) } // 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", DEFAULT_DNSSEED)) 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 manual connections - 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) { @@ -2537,16 +2538,18 @@ 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); }); + } // 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/test/util/setup_common.cpp b/src/test/util/setup_common.cpp index ffc51151458..f92e4c4b990 100644 --- a/src/test/util/setup_common.cpp +++ b/src/test/util/setup_common.cpp @@ -28,6 +28,8 @@ #include #include #include +#include +#include #include #include #include @@ -135,7 +137,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 6666e49a2b5..19d0a5da81c 100644 --- a/src/torcontrol.cpp +++ b/src/torcontrol.cpp @@ -15,6 +15,7 @@ #include #include #include +#include #include #include @@ -596,7 +597,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 67549fc13d4..5957637e810 100644 --- a/src/txmempool.cpp +++ b/src/txmempool.cpp @@ -18,6 +18,7 @@ #include #include +#include #include CTxMemPoolEntry::CTxMemPoolEntry(const CTransactionRef& _tx, const CAmount& _nFee, diff --git a/src/util/system.h b/src/util/system.h index 61f862c93a6..f68975ffa3a 100644 --- a/src/util/system.h +++ b/src/util/system.h @@ -22,7 +22,6 @@ #include #include #include -#include #include #include @@ -478,28 +477,6 @@ std::string HelpMessageOpt(const std::string& option, const std::string& message */ int GetNumCores(); -/** - * .. and a wrapper that just calls func once - */ -template void TraceThread(const char* name, Callable func) -{ - util::ThreadRename(name); - try - { - LogPrintf("%s thread start\n", name); - func(); - LogPrintf("%s thread exit\n", name); - } - catch (const std::exception& e) { - PrintExceptionContinue(&e, name); - throw; - } - catch (...) { - PrintExceptionContinue(nullptr, name); - throw; - } -} - std::string CopyrightHolders(const std::string& strPrefix); /** diff --git a/src/util/thread.cpp b/src/util/thread.cpp new file mode 100644 index 00000000000..14be6686859 --- /dev/null +++ b/src/util/thread.cpp @@ -0,0 +1,27 @@ +// 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 (const std::exception& e) { + PrintExceptionContinue(&e, thread_name); + throw; + } catch (...) { + PrintExceptionContinue(nullptr, thread_name); + throw; + } +} diff --git a/src/util/thread.h b/src/util/thread.h new file mode 100644 index 00000000000..ca2eccc0c31 --- /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