Good point! I do not know why I chose lowercase since it also violates the coding style. Maybe it was like that before and I left it as it is even though I touched those lines and the callers.
Append the following as a new commit or amend it into the last one fuzz: make it possible to mock (fuzz) CThreadInterrupt?
<details>
<summary>[patch] Uppercase methods of CThreadInterrupt</summary>
commit 486db14b9ce13a90b69f69dafb59d3d8932498f7 (HEAD -> fuzz_connman)
Parent: 0802398e749c5e16fa7085cd87c91a31bbe043bd
Author: Vasil Dimov <vd@FreeBSD.org>
AuthorDate: Tue Sep 2 13:40:35 2025 +0200
Commit: Vasil Dimov <vd@FreeBSD.org>
CommitDate: Tue Sep 2 13:40:35 2025 +0200
gpg: Signature made Tue Sep 2 13:42:45 2025 CEST
gpg: using RSA key E64D8D45614DB07545D9CCC154DF06F64B55CBBF
gpg: Good signature from "Vasil Dimov <vd@myforest.net>" [ultimate]
gpg: aka "Vasil Dimov <vd@FreeBSD.org>" [ultimate]
gpg: aka "Vasil Dimov <vasild@gmail.com>" [ultimate]
util: Uppercase methods of CThreadInterrupt
Rename
`CThreadInterrupt::interrupted()` -> `CThreadInterrupt::Interrupted()`
`CThreadInterrupt::reset()` -> `CThreadInterrupt::Reset()`
`CThreadInterrupt::sleep_for()` -> `CThreadInterrupt::SleepFor()`
for consistency with the coding style and to avoid confusing the
`reset()` method of `CThreadInterrupt` with the `reset()` methods of
smart pointers.
diff --git a/src/i2p.cpp b/src/i2p.cpp
index 80f3bde4cf..2ebd0b8c45 100644
--- a/src/i2p.cpp
+++ b/src/i2p.cpp
@@ -159,13 +159,13 @@ bool Session::Accept(Connection& conn)
{
AssertLockNotHeld(m_mutex);
std::string errmsg;
bool disconnect{false};
- while (!m_interrupt->interrupted()) {
+ while (!m_interrupt->Interrupted()) {
Sock::Event occurred;
if (!conn.sock->Wait(MAX_WAIT_FOR_IO, Sock::RECV, &occurred)) {
errmsg = "wait on socket failed";
break;
}
@@ -202,13 +202,13 @@ bool Session::Accept(Connection& conn)
conn.peer = CService(peer_addr, I2P_SAM31_PORT);
return true;
}
- if (m_interrupt->interrupted()) {
+ if (m_interrupt->Interrupted()) {
LogPrintLevel(BCLog::I2P, BCLog::Level::Debug, "Accept was interrupted\n");
} else {
LogPrintLevel(BCLog::I2P, BCLog::Level::Debug, "Error accepting%s: %s\n", disconnect ? " (will close the session)" : "", errmsg);
}
if (disconnect) {
LOCK(m_mutex);
diff --git a/src/index/base.cpp b/src/index/base.cpp
index 5767116ce5..cd36967ac6 100644
--- a/src/index/base.cpp
+++ b/src/index/base.cpp
@@ -83,13 +83,13 @@ BaseIndex::~BaseIndex()
bool BaseIndex::Init()
{
AssertLockNotHeld(cs_main);
// May need reset if index is being restarted.
- m_interrupt.reset();
+ m_interrupt.Reset();
// m_chainstate member gives indexing code access to node internals. It is
// removed in followup [#24230](/bitcoin-bitcoin/24230/)
m_chainstate = WITH_LOCK(::cs_main,
return &m_chain->context()->chainman->GetChainstateForIndexing());
// Register to validation interface before setting the 'm_synced' flag, so that
diff --git a/src/mapport.cpp b/src/mapport.cpp
index 83105f51fd..4d2f1f1957 100644
--- a/src/mapport.cpp
+++ b/src/mapport.cpp
@@ -110,23 +110,23 @@ static void ProcessPCP()
}
// RFC6887 11.2.1 recommends that clients send their first renewal packet at a time chosen with uniform random
// distribution in the range 1/2 to 5/8 of expiration time.
std::chrono::seconds sleep_time_min(actual_lifetime / 2);
std::chrono::seconds sleep_time_max(actual_lifetime * 5 / 8);
sleep_time = sleep_time_min + FastRandomContext().randrange<std::chrono::milliseconds>(sleep_time_max - sleep_time_min);
- } while (ret && g_mapport_interrupt.sleep_for(sleep_time));
+ } while (ret && g_mapport_interrupt.SleepFor(sleep_time));
// We don't delete the mappings when the thread is interrupted because this would add additional complexity, so
// we rather just choose a fairly short expiry time.
}
static void ThreadMapPort()
{
do {
ProcessPCP();
- } while (g_mapport_interrupt.sleep_for(PORT_MAPPING_RETRY_PERIOD));
+ } while (g_mapport_interrupt.SleepFor(PORT_MAPPING_RETRY_PERIOD));
}
void StartThreadMapPort()
{
if (!g_mapport_thread.joinable()) {
assert(!g_mapport_interrupt);
@@ -152,9 +152,9 @@ void InterruptMapPort()
}
void StopMapPort()
{
if (g_mapport_thread.joinable()) {
g_mapport_thread.join();
- g_mapport_interrupt.reset();
+ g_mapport_interrupt.Reset();
}
}
diff --git a/src/net.cpp b/src/net.cpp
index 85c25543d3..ee34b09ebd 100644
--- a/src/net.cpp
+++ b/src/net.cpp
@@ -2091,13 +2091,13 @@ void CConnman::SocketHandler()
// Check for the readiness of the already connected sockets and the
// listening sockets in one call ("readiness" as in poll(2) or
// select(2)). If none are ready, wait for a short while and return
// empty sets.
events_per_sock = GenerateWaitSockets(snap.Nodes());
if (events_per_sock.empty() || !events_per_sock.begin()->first->WaitMany(timeout, events_per_sock)) {
- m_interrupt_net->sleep_for(timeout);
+ m_interrupt_net->SleepFor(timeout);
}
// Service (send/receive) each of the already connected nodes.
SocketHandlerConnected(snap.Nodes(), events_per_sock);
}
@@ -2108,13 +2108,13 @@ void CConnman::SocketHandler()
void CConnman::SocketHandlerConnected(const std::vector<CNode*>& nodes,
const Sock::EventsPerSock& events_per_sock)
{
AssertLockNotHeld(m_total_bytes_sent_mutex);
for (CNode* pnode : nodes) {
- if (m_interrupt_net->interrupted()) {
+ if (m_interrupt_net->Interrupted()) {
return;
}
//
// Receive
//
@@ -2205,13 +2205,13 @@ void CConnman::SocketHandlerConnected(const std::vector<CNode*>& nodes,
}
}
void CConnman::SocketHandlerListening(const Sock::EventsPerSock& events_per_sock)
{
for (const ListenSocket& listen_socket : vhListenSocket) {
- if (m_interrupt_net->interrupted()) {
+ if (m_interrupt_net->Interrupted()) {
return;
}
const auto it = events_per_sock.find(listen_socket.sock);
if (it != events_per_sock.end() && it->second.occurred & Sock::RECV) {
AcceptConnection(listen_socket);
}
@@ -2219,13 +2219,13 @@ void CConnman::SocketHandlerListening(const Sock::EventsPerSock& events_per_sock
}
void CConnman::ThreadSocketHandler()
{
AssertLockNotHeld(m_total_bytes_sent_mutex);
- while (!m_interrupt_net->interrupted()) {
+ while (!m_interrupt_net->Interrupted()) {
DisconnectNodes();
NotifyNumConnectionsChanged();
SocketHandler();
}
}
@@ -2243,14 +2243,14 @@ void CConnman::ThreadDNSAddressSeed()
int outbound_connection_count = 0;
if (!gArgs.GetArgs("-seednode").empty()) {
auto start = NodeClock::now();
constexpr std::chrono::seconds SEEDNODE_TIMEOUT = 30s;
LogPrintf("-seednode enabled. Trying the provided seeds for %d seconds before defaulting to the dnsseeds.\n", SEEDNODE_TIMEOUT.count());
- while (!m_interrupt_net->interrupted()) {
- if (!m_interrupt_net->sleep_for(500ms)) {
+ while (!m_interrupt_net->Interrupted()) {
+ if (!m_interrupt_net->SleepFor(500ms)) {
return;
}
// Abort if we have spent enough time without reaching our target.
// Giving seed nodes 30 seconds so this does not become a race against fixedseeds (which triggers after 1 min)
if (NodeClock::now() > start + SEEDNODE_TIMEOUT) {
@@ -2307,13 +2307,13 @@ void CConnman::ThreadDNSAddressSeed()
std::chrono::seconds to_wait = seeds_wait_time;
while (to_wait.count() > 0) {
// if sleeping for the MANY_PEERS interval, wake up
// early to see if we have enough peers and can stop
// this thread entirely freeing up its resources
std::chrono::seconds w = std::min(DNSSEEDS_DELAY_FEW_PEERS, to_wait);
- if (!m_interrupt_net->sleep_for(w)) return;
+ if (!m_interrupt_net->SleepFor(w)) return;
to_wait -= w;
if (GetFullOutboundConnCount() >= SEED_OUTBOUND_CONNECTION_THRESHOLD) {
if (found > 0) {
LogPrintf("%d addresses found from DNS seeds\n", found);
LogPrintf("P2P peers available. Finished DNS seeding.\n");
@@ -2323,19 +2323,19 @@ void CConnman::ThreadDNSAddressSeed()
return;
}
}
}
}
- if (m_interrupt_net->interrupted()) return;
+ if (m_interrupt_net->Interrupted()) return;
// hold off on querying seeds if P2P network deactivated
if (!fNetworkActive) {
LogPrintf("Waiting for network to be reactivated before querying DNS seeds.\n");
do {
- if (!m_interrupt_net->sleep_for(1s)) return;
+ if (!m_interrupt_net->SleepFor(1s)) return;
} while (!fNetworkActive);
}
LogPrintf("Loading addresses from DNS seed %s\n", seed);
// If -proxy is in use, we make an ADDR_FETCH connection to the DNS resolved peer address
// for the base dns seed domain in chainparams
@@ -2524,18 +2524,18 @@ void CConnman::ThreadOpenConnections(const std::vector<std::string> connect, std
for (const std::string& strAddr : connect)
{
CAddress addr(CService(), NODE_NONE);
OpenNetworkConnection(addr, false, {}, strAddr.c_str(), ConnectionType::MANUAL, /*use_v2transport=*/use_v2transport);
for (int i = 0; i < 10 && i < nLoop; i++)
{
- if (!m_interrupt_net->sleep_for(500ms)) {
+ if (!m_interrupt_net->SleepFor(500ms)) {
return;
}
}
}
- if (!m_interrupt_net->sleep_for(500ms)) {
+ if (!m_interrupt_net->SleepFor(500ms)) {
return;
}
PerformReconnections();
}
}
@@ -2555,13 +2555,13 @@ void CConnman::ThreadOpenConnections(const std::vector<std::string> connect, std
constexpr std::chrono::seconds ADD_NEXT_SEEDNODE = 10s;
if (!add_fixed_seeds) {
LogPrintf("Fixed seeds are disabled\n");
}
- while (!m_interrupt_net->interrupted()) {
+ while (!m_interrupt_net->Interrupted()) {
if (add_addr_fetch) {
add_addr_fetch = false;
const auto& seed{SpanPopBack(seed_nodes)};
AddAddrFetch(seed);
if (addrman.Size() == 0) {
@@ -2570,20 +2570,20 @@ void CConnman::ThreadOpenConnections(const std::vector<std::string> connect, std
LogInfo("Couldn't connect to peers from addrman after %d seconds. Adding seednode (%s) to addrfetch\n", ADD_NEXT_SEEDNODE.count(), seed);
}
}
ProcessAddrFetch();
- if (!m_interrupt_net->sleep_for(500ms)) {
+ if (!m_interrupt_net->SleepFor(500ms)) {
return;
}
PerformReconnections();
CountingSemaphoreGrant<> grant(*semOutbound);
- if (m_interrupt_net->interrupted()) {
+ if (m_interrupt_net->Interrupted()) {
return;
}
const std::unordered_set<Network> fixed_seed_networks{GetReachableEmptyNetworks()};
if (add_fixed_seeds && !fixed_seed_networks.empty()) {
// When the node starts with an empty peers.dat, there are a few other sources of peers before
@@ -2753,13 +2753,13 @@ void CConnman::ThreadOpenConnections(const std::vector<std::string> connect, std
addrman.ResolveCollisions();
const auto current_time{NodeClock::now()};
int nTries = 0;
const auto reachable_nets{g_reachable_nets.All()};
- while (!m_interrupt_net->interrupted()) {
+ while (!m_interrupt_net->Interrupted()) {
if (anchor && !m_anchors.empty()) {
const CAddress addr = m_anchors.back();
m_anchors.pop_back();
if (!addr.IsValid() || IsLocal(addr) || !g_reachable_nets.Contains(addr) ||
!m_msgproc->HasAllDesirableServiceFlags(addr.nServices) ||
outbound_ipv46_peer_netgroups.count(m_netgroupman.GetGroup(addr))) continue;
@@ -2855,13 +2855,13 @@ void CConnman::ThreadOpenConnections(const std::vector<std::string> connect, std
break;
}
if (addrConnect.IsValid()) {
if (fFeeler) {
// Add small amount of random noise before connection to avoid synchronization.
- if (!m_interrupt_net->sleep_for(rng.rand_uniform_duration<CThreadInterrupt::Clock>(FEELER_SLEEP_WINDOW))) {
+ if (!m_interrupt_net->SleepFor(rng.rand_uniform_duration<CThreadInterrupt::Clock>(FEELER_SLEEP_WINDOW))) {
return;
}
LogDebug(BCLog::NET, "Making feeler connection to %s\n", addrConnect.ToStringAddrPort());
}
if (preferred_net != std::nullopt) LogDebug(BCLog::NET, "Making network specific connection to %s on %s.\n", addrConnect.ToStringAddrPort(), GetNetworkName(preferred_net.value()));
@@ -2966,19 +2966,19 @@ void CConnman::ThreadOpenAddedConnections()
// the addednodeinfo state might change.
break;
}
tried = true;
CAddress addr(CService(), NODE_NONE);
OpenNetworkConnection(addr, false, std::move(grant), info.m_params.m_added_node.c_str(), ConnectionType::MANUAL, info.m_params.m_use_v2transport);
- if (!m_interrupt_net->sleep_for(500ms)) return;
+ if (!m_interrupt_net->SleepFor(500ms)) return;
grant = CountingSemaphoreGrant<>(*semAddnode, /*fTry=*/true);
}
// See if any reconnections are desired.
PerformReconnections();
// Retry every 60 seconds if a connection was attempted, otherwise two seconds
- if (!m_interrupt_net->sleep_for(tried ? 60s : 2s)) {
+ if (!m_interrupt_net->SleepFor(tried ? 60s : 2s)) {
return;
}
}
}
// if successful, this moves the passed grant to the constructed node
@@ -2987,13 +2987,13 @@ void CConnman::OpenNetworkConnection(const CAddress& addrConnect, bool fCountFai
AssertLockNotHeld(m_unused_i2p_sessions_mutex);
assert(conn_type != ConnectionType::INBOUND);
//
// Initiate outbound network connection
//
- if (m_interrupt_net->interrupted()) {
+ if (m_interrupt_net->Interrupted()) {
return;
}
if (!fNetworkActive) {
return;
}
if (!pszDest) {
@@ -3075,19 +3075,19 @@ void CConnman::ThreadI2PAcceptIncoming()
auto err_wait = err_wait_begin;
bool advertising_listen_addr = false;
i2p::Connection conn;
auto SleepOnFailure = [&]() {
- m_interrupt_net->sleep_for(err_wait);
+ m_interrupt_net->SleepFor(err_wait);
if (err_wait < err_wait_cap) {
err_wait += 1s;
}
};
- while (!m_interrupt_net->interrupted()) {
+ while (!m_interrupt_net->Interrupted()) {
if (!m_i2p_sam_session->Listen(conn)) {
if (advertising_listen_addr && conn.me.IsValid()) {
RemoveLocal(conn.me);
advertising_listen_addr = false;
}
@@ -3347,13 +3347,13 @@ bool CConnman::Start(CScheduler& scheduler, const Options& connOptions)
}
//
// Start threads
//
assert(m_msgproc);
- m_interrupt_net->reset();
+ m_interrupt_net->Reset();
flagInterruptMsgProc = false;
{
LOCK(mutexMsgProc);
fMsgProcWake = false;
}
diff --git a/src/test/fuzz/util/threadinterrupt.cpp b/src/test/fuzz/util/threadinterrupt.cpp
index 5dd87e0588..5e23402447 100644
--- a/src/test/fuzz/util/threadinterrupt.cpp
+++ b/src/test/fuzz/util/threadinterrupt.cpp
@@ -7,16 +7,16 @@
FuzzedThreadInterrupt::FuzzedThreadInterrupt(FuzzedDataProvider& fuzzed_data_provider)
: m_fuzzed_data_provider{fuzzed_data_provider}
{
}
-bool FuzzedThreadInterrupt::interrupted() const
+bool FuzzedThreadInterrupt::Interrupted() const
{
return m_fuzzed_data_provider.ConsumeBool();
}
-bool FuzzedThreadInterrupt::sleep_for(Clock::duration)
+bool FuzzedThreadInterrupt::SleepFor(Clock::duration)
{
SetMockTime(ConsumeTime(m_fuzzed_data_provider)); // Time could go backwards.
return m_fuzzed_data_provider.ConsumeBool();
}
diff --git a/src/test/fuzz/util/threadinterrupt.h b/src/test/fuzz/util/threadinterrupt.h
index d56aefd919..71ce2ddd3f 100644
--- a/src/test/fuzz/util/threadinterrupt.h
+++ b/src/test/fuzz/util/threadinterrupt.h
@@ -15,14 +15,14 @@
*/
class FuzzedThreadInterrupt : public CThreadInterrupt
{
public:
explicit FuzzedThreadInterrupt(FuzzedDataProvider& fuzzed_data_provider);
- virtual bool interrupted() const override;
- virtual bool sleep_for(Clock::duration) override;
+ virtual bool Interrupted() const override;
+ virtual bool SleepFor(Clock::duration) override;
private:
FuzzedDataProvider& m_fuzzed_data_provider;
};
[[nodiscard]] inline std::shared_ptr<CThreadInterrupt> ConsumeThreadInterrupt(FuzzedDataProvider& fuzzed_data_provider)
diff --git a/src/util/threadinterrupt.cpp b/src/util/threadinterrupt.cpp
index aaa9e831a9..8402181cf0 100644
--- a/src/util/threadinterrupt.cpp
+++ b/src/util/threadinterrupt.cpp
@@ -6,23 +6,23 @@
#include <util/threadinterrupt.h>
#include <sync.h>
CThreadInterrupt::CThreadInterrupt() : flag(false) {}
-bool CThreadInterrupt::interrupted() const
+bool CThreadInterrupt::Interrupted() const
{
return flag.load(std::memory_order_acquire);
}
CThreadInterrupt::operator bool() const
{
- return interrupted();
+ return Interrupted();
}
-void CThreadInterrupt::reset()
+void CThreadInterrupt::Reset()
{
flag.store(false, std::memory_order_release);
}
void CThreadInterrupt::operator()()
{
@@ -30,11 +30,11 @@ void CThreadInterrupt::operator()()
LOCK(mut);
flag.store(true, std::memory_order_release);
}
cond.notify_all();
}
-bool CThreadInterrupt::sleep_for(Clock::duration rel_time)
+bool CThreadInterrupt::SleepFor(Clock::duration rel_time)
{
WAIT_LOCK(mut, lock);
return !cond.wait_for(lock, rel_time, [this]() { return flag.load(std::memory_order_acquire); });
}
diff --git a/src/util/threadinterrupt.h b/src/util/threadinterrupt.h
index 8b393c26df..e11ff1881b 100644
--- a/src/util/threadinterrupt.h
+++ b/src/util/threadinterrupt.h
@@ -30,27 +30,27 @@ public:
CThreadInterrupt();
virtual ~CThreadInterrupt() = default;
/// Return true if `operator()()` has been called.
- virtual bool interrupted() const;
+ virtual bool Interrupted() const;
/// An alias for `interrupted()`.
virtual explicit operator bool() const;
/// Interrupt any sleeps. After this `interrupted()` will return `true`.
virtual void operator()() EXCLUSIVE_LOCKS_REQUIRED(!mut);
/// Reset to an non-interrupted state.
- virtual void reset();
+ virtual void Reset();
/// Sleep for the given duration.
/// [@retval](/bitcoin-bitcoin/contributor/retval/) true The time passed.
/// [@retval](/bitcoin-bitcoin/contributor/retval/) false The sleep was interrupted.
- virtual bool sleep_for(Clock::duration rel_time) EXCLUSIVE_LOCKS_REQUIRED(!mut);
+ virtual bool SleepFor(Clock::duration rel_time) EXCLUSIVE_LOCKS_REQUIRED(!mut);
private:
std::condition_variable cond;
Mutex mut;
std::atomic<bool> flag;
};
</details>