Increase threadsafety annotation coverage

This commit is contained in:
Anthony Towns 2022-04-20 16:47:29 +10:00
parent 9db941d773
commit 7d73f58e9c
12 changed files with 101 additions and 86 deletions

View File

@ -66,7 +66,7 @@ private:
bool m_request_stop GUARDED_BY(m_mutex){false}; bool m_request_stop GUARDED_BY(m_mutex){false};
/** Internal function that does bulk of the verification work. */ /** Internal function that does bulk of the verification work. */
bool Loop(bool fMaster) bool Loop(bool fMaster) EXCLUSIVE_LOCKS_REQUIRED(!m_mutex)
{ {
std::condition_variable& cond = fMaster ? m_master_cv : m_worker_cv; std::condition_variable& cond = fMaster ? m_master_cv : m_worker_cv;
std::vector<T> vChecks; std::vector<T> vChecks;
@ -140,7 +140,7 @@ public:
} }
//! Create a pool of new worker threads. //! Create a pool of new worker threads.
void StartWorkerThreads(const int threads_num) void StartWorkerThreads(const int threads_num) EXCLUSIVE_LOCKS_REQUIRED(!m_mutex)
{ {
{ {
LOCK(m_mutex); LOCK(m_mutex);
@ -159,13 +159,13 @@ public:
} }
//! Wait until execution finishes, and return whether all evaluations were successful. //! Wait until execution finishes, and return whether all evaluations were successful.
bool Wait() bool Wait() EXCLUSIVE_LOCKS_REQUIRED(!m_mutex)
{ {
return Loop(true /* master thread */); return Loop(true /* master thread */);
} }
//! Add a batch of checks to the queue //! Add a batch of checks to the queue
void Add(std::vector<T>& vChecks) void Add(std::vector<T>& vChecks) EXCLUSIVE_LOCKS_REQUIRED(!m_mutex)
{ {
if (vChecks.empty()) { if (vChecks.empty()) {
return; return;
@ -188,7 +188,7 @@ public:
} }
//! Stop all of the worker threads. //! Stop all of the worker threads.
void StopWorkerThreads() void StopWorkerThreads() EXCLUSIVE_LOCKS_REQUIRED(!m_mutex)
{ {
WITH_LOCK(m_mutex, m_request_stop = true); WITH_LOCK(m_mutex, m_request_stop = true);
m_worker_cv.notify_all(); m_worker_cv.notify_all();

View File

@ -87,7 +87,7 @@ public:
{ {
} }
/** Enqueue a work item */ /** Enqueue a work item */
bool Enqueue(WorkItem* item) bool Enqueue(WorkItem* item) EXCLUSIVE_LOCKS_REQUIRED(!cs)
{ {
LOCK(cs); LOCK(cs);
if (!running || queue.size() >= maxDepth) { if (!running || queue.size() >= maxDepth) {
@ -98,7 +98,7 @@ public:
return true; return true;
} }
/** Thread function */ /** Thread function */
void Run() void Run() EXCLUSIVE_LOCKS_REQUIRED(!cs)
{ {
while (true) { while (true) {
std::unique_ptr<WorkItem> i; std::unique_ptr<WorkItem> i;
@ -115,7 +115,7 @@ public:
} }
} }
/** Interrupt and exit loops */ /** Interrupt and exit loops */
void Interrupt() void Interrupt() EXCLUSIVE_LOCKS_REQUIRED(!cs)
{ {
LOCK(cs); LOCK(cs);
running = false; running = false;

View File

@ -84,7 +84,7 @@ public:
* to the listening socket and address. * to the listening socket and address.
* @return true on success * @return true on success
*/ */
bool Listen(Connection& conn); bool Listen(Connection& conn) EXCLUSIVE_LOCKS_REQUIRED(!m_mutex);
/** /**
* Wait for and accept a new incoming connection. * Wait for and accept a new incoming connection.
@ -103,7 +103,7 @@ public:
* it is set to `false`. Only set if `false` is returned. * it is set to `false`. Only set if `false` is returned.
* @return true on success * @return true on success
*/ */
bool Connect(const CService& to, Connection& conn, bool& proxy_error); bool Connect(const CService& to, Connection& conn, bool& proxy_error) EXCLUSIVE_LOCKS_REQUIRED(!m_mutex);
private: private:
/** /**
@ -172,7 +172,7 @@ private:
/** /**
* Check the control socket for errors and possibly disconnect. * Check the control socket for errors and possibly disconnect.
*/ */
void CheckControlSock(); void CheckControlSock() EXCLUSIVE_LOCKS_REQUIRED(!m_mutex);
/** /**
* Generate a new destination with the SAM proxy and set `m_private_key` to it. * Generate a new destination with the SAM proxy and set `m_private_key` to it.

View File

@ -64,7 +64,7 @@ public:
bool LookupFilter(const CBlockIndex* block_index, BlockFilter& filter_out) const; bool LookupFilter(const CBlockIndex* block_index, BlockFilter& filter_out) const;
/** Get a single filter header by block. */ /** Get a single filter header by block. */
bool LookupFilterHeader(const CBlockIndex* block_index, uint256& header_out); bool LookupFilterHeader(const CBlockIndex* block_index, uint256& header_out) EXCLUSIVE_LOCKS_REQUIRED(!m_cs_headers_cache);
/** Get a range of filters between two heights on a chain. */ /** Get a range of filters between two heights on a chain. */
bool LookupFilterRange(int start_height, const CBlockIndex* stop_index, bool LookupFilterRange(int start_height, const CBlockIndex* stop_index,

View File

@ -613,7 +613,7 @@ public:
* @return True if the peer should stay connected, * @return True if the peer should stay connected,
* False if the peer should be disconnected from. * False if the peer should be disconnected from.
*/ */
bool ReceiveMsgBytes(Span<const uint8_t> msg_bytes, bool& complete); bool ReceiveMsgBytes(Span<const uint8_t> msg_bytes, bool& complete) EXCLUSIVE_LOCKS_REQUIRED(!cs_vRecv);
void SetCommonVersion(int greatest_common_version) void SetCommonVersion(int greatest_common_version)
{ {
@ -625,9 +625,9 @@ public:
return m_greatest_common_version; return m_greatest_common_version;
} }
CService GetAddrLocal() const LOCKS_EXCLUDED(m_addr_local_mutex); CService GetAddrLocal() const EXCLUSIVE_LOCKS_REQUIRED(!m_addr_local_mutex);
//! May not be called more than once //! May not be called more than once
void SetAddrLocal(const CService& addrLocalIn) LOCKS_EXCLUDED(m_addr_local_mutex); void SetAddrLocal(const CService& addrLocalIn) EXCLUSIVE_LOCKS_REQUIRED(!m_addr_local_mutex);
CNode* AddRef() CNode* AddRef()
{ {
@ -640,9 +640,9 @@ public:
nRefCount--; nRefCount--;
} }
void CloseSocketDisconnect(); void CloseSocketDisconnect() EXCLUSIVE_LOCKS_REQUIRED(!m_sock_mutex);
void CopyStats(CNodeStats& stats); void CopyStats(CNodeStats& stats) EXCLUSIVE_LOCKS_REQUIRED(!m_subver_mutex, !m_addr_local_mutex, !cs_vSend, !cs_vRecv);
ServiceFlags GetLocalServices() const ServiceFlags GetLocalServices() const
{ {
@ -761,7 +761,7 @@ public:
bool m_i2p_accept_incoming; bool m_i2p_accept_incoming;
}; };
void Init(const Options& connOptions) EXCLUSIVE_LOCKS_REQUIRED(!m_total_bytes_sent_mutex) void Init(const Options& connOptions) EXCLUSIVE_LOCKS_REQUIRED(!m_added_nodes_mutex, !m_total_bytes_sent_mutex)
{ {
AssertLockNotHeld(m_total_bytes_sent_mutex); AssertLockNotHeld(m_total_bytes_sent_mutex);
@ -795,7 +795,8 @@ public:
bool network_active = true); bool network_active = true);
~CConnman(); ~CConnman();
bool Start(CScheduler& scheduler, const Options& options) EXCLUSIVE_LOCKS_REQUIRED(!m_total_bytes_sent_mutex);
bool Start(CScheduler& scheduler, const Options& options) EXCLUSIVE_LOCKS_REQUIRED(!m_total_bytes_sent_mutex, !m_added_nodes_mutex, !m_addr_fetches_mutex, !mutexMsgProc);
void StopThreads(); void StopThreads();
void StopNodes(); void StopNodes();
@ -805,7 +806,7 @@ public:
StopNodes(); StopNodes();
}; };
void Interrupt(); void Interrupt() EXCLUSIVE_LOCKS_REQUIRED(!mutexMsgProc);
bool GetNetworkActive() const { return fNetworkActive; }; bool GetNetworkActive() const { return fNetworkActive; };
bool GetUseAddrmanOutgoing() const { return m_use_addrman_outgoing; }; bool GetUseAddrmanOutgoing() const { return m_use_addrman_outgoing; };
void SetNetworkActive(bool active); void SetNetworkActive(bool active);
@ -872,9 +873,9 @@ public:
// Count the number of block-relay-only peers we have over our limit. // Count the number of block-relay-only peers we have over our limit.
int GetExtraBlockRelayCount() const; int GetExtraBlockRelayCount() const;
bool AddNode(const std::string& node); bool AddNode(const std::string& node) EXCLUSIVE_LOCKS_REQUIRED(!m_added_nodes_mutex);
bool RemoveAddedNode(const std::string& node); bool RemoveAddedNode(const std::string& node) EXCLUSIVE_LOCKS_REQUIRED(!m_added_nodes_mutex);
std::vector<AddedNodeInfo> GetAddedNodeInfo() const; std::vector<AddedNodeInfo> GetAddedNodeInfo() const EXCLUSIVE_LOCKS_REQUIRED(!m_added_nodes_mutex);
/** /**
* Attempts to open a connection. Currently only used from tests. * Attempts to open a connection. Currently only used from tests.
@ -927,7 +928,7 @@ public:
unsigned int GetReceiveFloodSize() const; unsigned int GetReceiveFloodSize() const;
void WakeMessageHandler(); void WakeMessageHandler() EXCLUSIVE_LOCKS_REQUIRED(!mutexMsgProc);
/** Return true if we should disconnect the peer for failing an inactivity check. */ /** Return true if we should disconnect the peer for failing an inactivity check. */
bool ShouldRunInactivityChecks(const CNode& node, std::chrono::seconds now) const; bool ShouldRunInactivityChecks(const CNode& node, std::chrono::seconds now) const;
@ -954,11 +955,11 @@ private:
bool Bind(const CService& addr, unsigned int flags, NetPermissionFlags permissions); bool Bind(const CService& addr, unsigned int flags, NetPermissionFlags permissions);
bool InitBinds(const Options& options); bool InitBinds(const Options& options);
void ThreadOpenAddedConnections(); void ThreadOpenAddedConnections() EXCLUSIVE_LOCKS_REQUIRED(!m_added_nodes_mutex);
void AddAddrFetch(const std::string& strDest); void AddAddrFetch(const std::string& strDest) EXCLUSIVE_LOCKS_REQUIRED(!m_addr_fetches_mutex);
void ProcessAddrFetch(); void ProcessAddrFetch() EXCLUSIVE_LOCKS_REQUIRED(!m_addr_fetches_mutex);
void ThreadOpenConnections(std::vector<std::string> connect); void ThreadOpenConnections(std::vector<std::string> connect) EXCLUSIVE_LOCKS_REQUIRED(!m_addr_fetches_mutex, !m_added_nodes_mutex, !m_nodes_mutex);
void ThreadMessageHandler(); void ThreadMessageHandler() EXCLUSIVE_LOCKS_REQUIRED(!mutexMsgProc);
void ThreadI2PAcceptIncoming(); void ThreadI2PAcceptIncoming();
void AcceptConnection(const ListenSocket& hListenSocket); void AcceptConnection(const ListenSocket& hListenSocket);
@ -1009,7 +1010,7 @@ private:
/** /**
* Check connected and listening sockets for IO readiness and process them accordingly. * Check connected and listening sockets for IO readiness and process them accordingly.
*/ */
void SocketHandler() EXCLUSIVE_LOCKS_REQUIRED(!m_total_bytes_sent_mutex); void SocketHandler() EXCLUSIVE_LOCKS_REQUIRED(!m_total_bytes_sent_mutex, !mutexMsgProc);
/** /**
* Do the read/write for connected sockets that are ready for IO. * Do the read/write for connected sockets that are ready for IO.
@ -1023,7 +1024,7 @@ private:
const std::set<SOCKET>& recv_set, const std::set<SOCKET>& recv_set,
const std::set<SOCKET>& send_set, const std::set<SOCKET>& send_set,
const std::set<SOCKET>& error_set) const std::set<SOCKET>& error_set)
EXCLUSIVE_LOCKS_REQUIRED(!m_total_bytes_sent_mutex); EXCLUSIVE_LOCKS_REQUIRED(!m_total_bytes_sent_mutex, !mutexMsgProc);
/** /**
* Accept incoming connections, one from each read-ready listening socket. * Accept incoming connections, one from each read-ready listening socket.
@ -1031,8 +1032,8 @@ private:
*/ */
void SocketHandlerListening(const std::set<SOCKET>& recv_set); void SocketHandlerListening(const std::set<SOCKET>& recv_set);
void ThreadSocketHandler() EXCLUSIVE_LOCKS_REQUIRED(!m_total_bytes_sent_mutex); void ThreadSocketHandler() EXCLUSIVE_LOCKS_REQUIRED(!m_total_bytes_sent_mutex, !mutexMsgProc);
void ThreadDNSAddressSeed(); void ThreadDNSAddressSeed() EXCLUSIVE_LOCKS_REQUIRED(!m_addr_fetches_mutex, !m_nodes_mutex);
uint64_t CalculateKeyedNetGroup(const CAddress& ad) const; uint64_t CalculateKeyedNetGroup(const CAddress& ad) const;

View File

@ -440,30 +440,37 @@ public:
CTxMemPool& pool, bool ignore_incoming_txs); CTxMemPool& pool, bool ignore_incoming_txs);
/** Overridden from CValidationInterface. */ /** Overridden from CValidationInterface. */
void BlockConnected(const std::shared_ptr<const CBlock>& pblock, const CBlockIndex* pindexConnected) override; void BlockConnected(const std::shared_ptr<const CBlock>& pblock, const CBlockIndex* pindexConnected) override
void BlockDisconnected(const std::shared_ptr<const CBlock> &block, const CBlockIndex* pindex) override; EXCLUSIVE_LOCKS_REQUIRED(!m_recent_confirmed_transactions_mutex);
void UpdatedBlockTip(const CBlockIndex *pindexNew, const CBlockIndex *pindexFork, bool fInitialDownload) override; void BlockDisconnected(const std::shared_ptr<const CBlock> &block, const CBlockIndex* pindex) override
void BlockChecked(const CBlock& block, const BlockValidationState& state) override; EXCLUSIVE_LOCKS_REQUIRED(!m_recent_confirmed_transactions_mutex);
void UpdatedBlockTip(const CBlockIndex *pindexNew, const CBlockIndex *pindexFork, bool fInitialDownload) override
EXCLUSIVE_LOCKS_REQUIRED(!m_peer_mutex);
void BlockChecked(const CBlock& block, const BlockValidationState& state) override
EXCLUSIVE_LOCKS_REQUIRED(!m_peer_mutex);
void NewPoWValidBlock(const CBlockIndex *pindex, const std::shared_ptr<const CBlock>& pblock) override; void NewPoWValidBlock(const CBlockIndex *pindex, const std::shared_ptr<const CBlock>& pblock) override;
/** Implement NetEventsInterface */ /** Implement NetEventsInterface */
void InitializeNode(CNode* pnode) override; void InitializeNode(CNode* pnode) override EXCLUSIVE_LOCKS_REQUIRED(!m_peer_mutex);
void FinalizeNode(const CNode& node) override; void FinalizeNode(const CNode& node) override EXCLUSIVE_LOCKS_REQUIRED(!m_peer_mutex);
bool ProcessMessages(CNode* pfrom, std::atomic<bool>& interrupt) override; bool ProcessMessages(CNode* pfrom, std::atomic<bool>& interrupt) override
bool SendMessages(CNode* pto) override EXCLUSIVE_LOCKS_REQUIRED(pto->cs_sendProcessing); EXCLUSIVE_LOCKS_REQUIRED(!m_peer_mutex, !m_recent_confirmed_transactions_mutex);
bool SendMessages(CNode* pto) override EXCLUSIVE_LOCKS_REQUIRED(pto->cs_sendProcessing)
EXCLUSIVE_LOCKS_REQUIRED(!m_peer_mutex, !m_recent_confirmed_transactions_mutex);
/** Implement PeerManager */ /** Implement PeerManager */
void StartScheduledTasks(CScheduler& scheduler) override; void StartScheduledTasks(CScheduler& scheduler) override;
void CheckForStaleTipAndEvictPeers() override; void CheckForStaleTipAndEvictPeers() override;
std::optional<std::string> FetchBlock(NodeId peer_id, const CBlockIndex& block_index) override; std::optional<std::string> FetchBlock(NodeId peer_id, const CBlockIndex& block_index) override;
bool GetNodeStateStats(NodeId nodeid, CNodeStateStats& stats) const override; bool GetNodeStateStats(NodeId nodeid, CNodeStateStats& stats) const override EXCLUSIVE_LOCKS_REQUIRED(!m_peer_mutex);
bool IgnoresIncomingTxs() override { return m_ignore_incoming_txs; } bool IgnoresIncomingTxs() override { return m_ignore_incoming_txs; }
void SendPings() override; void SendPings() override EXCLUSIVE_LOCKS_REQUIRED(!m_peer_mutex);
void RelayTransaction(const uint256& txid, const uint256& wtxid) override; void RelayTransaction(const uint256& txid, const uint256& wtxid) override EXCLUSIVE_LOCKS_REQUIRED(!m_peer_mutex);
void SetBestHeight(int height) override { m_best_height = height; }; void SetBestHeight(int height) override { m_best_height = height; };
void Misbehaving(const NodeId pnode, const int howmuch, const std::string& message) override; void Misbehaving(const NodeId pnode, const int howmuch, const std::string& message) override EXCLUSIVE_LOCKS_REQUIRED(!m_peer_mutex);
void ProcessMessage(CNode& pfrom, const std::string& msg_type, CDataStream& vRecv, void ProcessMessage(CNode& pfrom, const std::string& msg_type, CDataStream& vRecv,
const std::chrono::microseconds time_received, const std::atomic<bool>& interruptMsgProc) override; const std::chrono::microseconds time_received, const std::atomic<bool>& interruptMsgProc) override
EXCLUSIVE_LOCKS_REQUIRED(!m_peer_mutex, !m_recent_confirmed_transactions_mutex);
void UpdateLastBlockAnnounceTime(NodeId node, int64_t time_in_seconds) override; void UpdateLastBlockAnnounceTime(NodeId node, int64_t time_in_seconds) override;
private: private:
@ -474,15 +481,15 @@ private:
void EvictExtraOutboundPeers(std::chrono::seconds now) EXCLUSIVE_LOCKS_REQUIRED(cs_main); void EvictExtraOutboundPeers(std::chrono::seconds now) EXCLUSIVE_LOCKS_REQUIRED(cs_main);
/** Retrieve unbroadcast transactions from the mempool and reattempt sending to peers */ /** Retrieve unbroadcast transactions from the mempool and reattempt sending to peers */
void ReattemptInitialBroadcast(CScheduler& scheduler); void ReattemptInitialBroadcast(CScheduler& scheduler) EXCLUSIVE_LOCKS_REQUIRED(!m_peer_mutex);
/** Get a shared pointer to the Peer object. /** Get a shared pointer to the Peer object.
* May return an empty shared_ptr if the Peer object can't be found. */ * May return an empty shared_ptr if the Peer object can't be found. */
PeerRef GetPeerRef(NodeId id) const; PeerRef GetPeerRef(NodeId id) const EXCLUSIVE_LOCKS_REQUIRED(!m_peer_mutex);
/** Get a shared pointer to the Peer object and remove it from m_peer_map. /** Get a shared pointer to the Peer object and remove it from m_peer_map.
* May return an empty shared_ptr if the Peer object can't be found. */ * May return an empty shared_ptr if the Peer object can't be found. */
PeerRef RemovePeer(NodeId id); PeerRef RemovePeer(NodeId id) EXCLUSIVE_LOCKS_REQUIRED(!m_peer_mutex);
/** /**
* Potentially mark a node discouraged based on the contents of a BlockValidationState object * Potentially mark a node discouraged based on the contents of a BlockValidationState object
@ -495,14 +502,16 @@ private:
* @return Returns true if the peer was punished (probably disconnected) * @return Returns true if the peer was punished (probably disconnected)
*/ */
bool MaybePunishNodeForBlock(NodeId nodeid, const BlockValidationState& state, bool MaybePunishNodeForBlock(NodeId nodeid, const BlockValidationState& state,
bool via_compact_block, const std::string& message = ""); bool via_compact_block, const std::string& message = "")
EXCLUSIVE_LOCKS_REQUIRED(!m_peer_mutex);
/** /**
* Potentially disconnect and discourage a node based on the contents of a TxValidationState object * Potentially disconnect and discourage a node based on the contents of a TxValidationState object
* *
* @return Returns true if the peer was punished (probably disconnected) * @return Returns true if the peer was punished (probably disconnected)
*/ */
bool MaybePunishNodeForTx(NodeId nodeid, const TxValidationState& state, const std::string& message = ""); bool MaybePunishNodeForTx(NodeId nodeid, const TxValidationState& state, const std::string& message = "")
EXCLUSIVE_LOCKS_REQUIRED(!m_peer_mutex);
/** Maybe disconnect a peer and discourage future connections from its address. /** Maybe disconnect a peer and discourage future connections from its address.
* *
@ -512,13 +521,16 @@ private:
*/ */
bool MaybeDiscourageAndDisconnect(CNode& pnode, Peer& peer); bool MaybeDiscourageAndDisconnect(CNode& pnode, Peer& peer);
void ProcessOrphanTx(std::set<uint256>& orphan_work_set) EXCLUSIVE_LOCKS_REQUIRED(cs_main, g_cs_orphans); void ProcessOrphanTx(std::set<uint256>& orphan_work_set) EXCLUSIVE_LOCKS_REQUIRED(cs_main, g_cs_orphans)
EXCLUSIVE_LOCKS_REQUIRED(!m_peer_mutex);
/** Process a single headers message from a peer. */ /** Process a single headers message from a peer. */
void ProcessHeadersMessage(CNode& pfrom, const Peer& peer, void ProcessHeadersMessage(CNode& pfrom, const Peer& peer,
const std::vector<CBlockHeader>& headers, const std::vector<CBlockHeader>& headers,
bool via_compact_block); bool via_compact_block)
EXCLUSIVE_LOCKS_REQUIRED(!m_peer_mutex);
void SendBlockTransactions(CNode& pfrom, const CBlock& block, const BlockTransactionsRequest& req); void SendBlockTransactions(CNode& pfrom, const CBlock& block, const BlockTransactionsRequest& req)
EXCLUSIVE_LOCKS_REQUIRED(!m_peer_mutex);
/** Register with TxRequestTracker that an INV has been received from a /** Register with TxRequestTracker that an INV has been received from a
* peer. The announcement parameters are decided in PeerManager and then * peer. The announcement parameters are decided in PeerManager and then
@ -545,7 +557,7 @@ private:
* @param[in] fReachable Whether the address' network is reachable. We relay unreachable * @param[in] fReachable Whether the address' network is reachable. We relay unreachable
* addresses less. * addresses less.
*/ */
void RelayAddress(NodeId originator, const CAddress& addr, bool fReachable); void RelayAddress(NodeId originator, const CAddress& addr, bool fReachable) EXCLUSIVE_LOCKS_REQUIRED(!m_peer_mutex);
/** Send `feefilter` message. */ /** Send `feefilter` message. */
void MaybeSendFeefilter(CNode& node, Peer& peer, std::chrono::microseconds current_time); void MaybeSendFeefilter(CNode& node, Peer& peer, std::chrono::microseconds current_time);
@ -615,7 +627,8 @@ private:
/** Number of preferable block download peers. */ /** Number of preferable block download peers. */
int m_num_preferred_download_peers GUARDED_BY(cs_main){0}; int m_num_preferred_download_peers GUARDED_BY(cs_main){0};
bool AlreadyHaveTx(const GenTxid& gtxid) EXCLUSIVE_LOCKS_REQUIRED(cs_main); bool AlreadyHaveTx(const GenTxid& gtxid)
EXCLUSIVE_LOCKS_REQUIRED(cs_main, !m_recent_confirmed_transactions_mutex);
/** /**
* Filter for transactions that were recently rejected by the mempool. * Filter for transactions that were recently rejected by the mempool.

View File

@ -61,7 +61,7 @@ public:
//! Return number of connections, default is in- and outbound (total) //! Return number of connections, default is in- and outbound (total)
int getNumConnections(unsigned int flags = CONNECTIONS_ALL) const; int getNumConnections(unsigned int flags = CONNECTIONS_ALL) const;
int getNumBlocks() const; int getNumBlocks() const;
uint256 getBestBlockHash(); uint256 getBestBlockHash() EXCLUSIVE_LOCKS_REQUIRED(!m_cached_tip_mutex);
int getHeaderTipHeight() const; int getHeaderTipHeight() const;
int64_t getHeaderTipTime() const; int64_t getHeaderTipTime() const;

View File

@ -374,7 +374,7 @@ public:
{ {
} }
void AddEvent(uint32_t event_info) noexcept void AddEvent(uint32_t event_info) noexcept EXCLUSIVE_LOCKS_REQUIRED(!m_events_mutex)
{ {
LOCK(m_events_mutex); LOCK(m_events_mutex);
@ -388,7 +388,7 @@ public:
/** /**
* Feed (the hash of) all events added through AddEvent() to hasher. * Feed (the hash of) all events added through AddEvent() to hasher.
*/ */
void SeedEvents(CSHA512& hasher) noexcept void SeedEvents(CSHA512& hasher) noexcept EXCLUSIVE_LOCKS_REQUIRED(!m_events_mutex)
{ {
// We use only SHA256 for the events hashing to get the ASM speedups we have for SHA256, // We use only SHA256 for the events hashing to get the ASM speedups we have for SHA256,
// since we want it to be fast as network peers may be able to trigger it repeatedly. // since we want it to be fast as network peers may be able to trigger it repeatedly.
@ -407,7 +407,7 @@ public:
* *
* If this function has never been called with strong_seed = true, false is returned. * If this function has never been called with strong_seed = true, false is returned.
*/ */
bool MixExtract(unsigned char* out, size_t num, CSHA512&& hasher, bool strong_seed) noexcept bool MixExtract(unsigned char* out, size_t num, CSHA512&& hasher, bool strong_seed) noexcept EXCLUSIVE_LOCKS_REQUIRED(!m_mutex)
{ {
assert(num <= 32); assert(num <= 32);
unsigned char buf[64]; unsigned char buf[64];

View File

@ -46,10 +46,10 @@ public:
typedef std::function<void()> Function; typedef std::function<void()> Function;
/** Call func at/after time t */ /** Call func at/after time t */
void schedule(Function f, std::chrono::steady_clock::time_point t); void schedule(Function f, std::chrono::steady_clock::time_point t) EXCLUSIVE_LOCKS_REQUIRED(!newTaskMutex);
/** Call f once after the delta has passed */ /** Call f once after the delta has passed */
void scheduleFromNow(Function f, std::chrono::milliseconds delta) void scheduleFromNow(Function f, std::chrono::milliseconds delta) EXCLUSIVE_LOCKS_REQUIRED(!newTaskMutex)
{ {
schedule(std::move(f), std::chrono::steady_clock::now() + delta); schedule(std::move(f), std::chrono::steady_clock::now() + delta);
} }
@ -60,29 +60,29 @@ public:
* The timing is not exact: Every time f is finished, it is rescheduled to run again after delta. If you need more * The timing is not exact: Every time f is finished, it is rescheduled to run again after delta. If you need more
* accurate scheduling, don't use this method. * accurate scheduling, don't use this method.
*/ */
void scheduleEvery(Function f, std::chrono::milliseconds delta); void scheduleEvery(Function f, std::chrono::milliseconds delta) EXCLUSIVE_LOCKS_REQUIRED(!newTaskMutex);
/** /**
* Mock the scheduler to fast forward in time. * Mock the scheduler to fast forward in time.
* Iterates through items on taskQueue and reschedules them * Iterates through items on taskQueue and reschedules them
* to be delta_seconds sooner. * to be delta_seconds sooner.
*/ */
void MockForward(std::chrono::seconds delta_seconds); void MockForward(std::chrono::seconds delta_seconds) EXCLUSIVE_LOCKS_REQUIRED(!newTaskMutex);
/** /**
* Services the queue 'forever'. Should be run in a thread. * Services the queue 'forever'. Should be run in a thread.
*/ */
void serviceQueue(); void serviceQueue() EXCLUSIVE_LOCKS_REQUIRED(!newTaskMutex);
/** Tell any threads running serviceQueue to stop as soon as the current task is done */ /** Tell any threads running serviceQueue to stop as soon as the current task is done */
void stop() void stop() EXCLUSIVE_LOCKS_REQUIRED(!newTaskMutex)
{ {
WITH_LOCK(newTaskMutex, stopRequested = true); WITH_LOCK(newTaskMutex, stopRequested = true);
newTaskScheduled.notify_all(); newTaskScheduled.notify_all();
if (m_service_thread.joinable()) m_service_thread.join(); if (m_service_thread.joinable()) m_service_thread.join();
} }
/** Tell any threads running serviceQueue to stop when there is no work left to be done */ /** Tell any threads running serviceQueue to stop when there is no work left to be done */
void StopWhenDrained() void StopWhenDrained() EXCLUSIVE_LOCKS_REQUIRED(!newTaskMutex)
{ {
WITH_LOCK(newTaskMutex, stopWhenEmpty = true); WITH_LOCK(newTaskMutex, stopWhenEmpty = true);
newTaskScheduled.notify_all(); newTaskScheduled.notify_all();
@ -94,10 +94,11 @@ public:
* and first and last task times * and first and last task times
*/ */
size_t getQueueInfo(std::chrono::steady_clock::time_point& first, size_t getQueueInfo(std::chrono::steady_clock::time_point& first,
std::chrono::steady_clock::time_point& last) const; std::chrono::steady_clock::time_point& last) const
EXCLUSIVE_LOCKS_REQUIRED(!newTaskMutex);
/** Returns true if there are threads actively running in serviceQueue() */ /** Returns true if there are threads actively running in serviceQueue() */
bool AreThreadsServicingQueue() const; bool AreThreadsServicingQueue() const EXCLUSIVE_LOCKS_REQUIRED(!newTaskMutex);
private: private:
mutable Mutex newTaskMutex; mutable Mutex newTaskMutex;
@ -128,8 +129,8 @@ private:
std::list<std::function<void()>> m_callbacks_pending GUARDED_BY(m_callbacks_mutex); std::list<std::function<void()>> m_callbacks_pending GUARDED_BY(m_callbacks_mutex);
bool m_are_callbacks_running GUARDED_BY(m_callbacks_mutex) = false; bool m_are_callbacks_running GUARDED_BY(m_callbacks_mutex) = false;
void MaybeScheduleProcessQueue(); void MaybeScheduleProcessQueue() EXCLUSIVE_LOCKS_REQUIRED(!m_callbacks_mutex);
void ProcessQueue(); void ProcessQueue() EXCLUSIVE_LOCKS_REQUIRED(!m_callbacks_mutex);
public: public:
explicit SingleThreadedSchedulerClient(CScheduler& scheduler LIFETIMEBOUND) : m_scheduler{scheduler} {} explicit SingleThreadedSchedulerClient(CScheduler& scheduler LIFETIMEBOUND) : m_scheduler{scheduler} {}
@ -140,15 +141,15 @@ public:
* Practically, this means that callbacks can behave as if they are executed * Practically, this means that callbacks can behave as if they are executed
* in order by a single thread. * in order by a single thread.
*/ */
void AddToProcessQueue(std::function<void()> func); void AddToProcessQueue(std::function<void()> func) EXCLUSIVE_LOCKS_REQUIRED(!m_callbacks_mutex);
/** /**
* Processes all remaining queue members on the calling thread, blocking until queue is empty * Processes all remaining queue members on the calling thread, blocking until queue is empty
* Must be called after the CScheduler has no remaining processing threads! * Must be called after the CScheduler has no remaining processing threads!
*/ */
void EmptyQueue(); void EmptyQueue() EXCLUSIVE_LOCKS_REQUIRED(!m_callbacks_mutex);
size_t CallbacksPending(); size_t CallbacksPending() EXCLUSIVE_LOCKS_REQUIRED(!m_callbacks_mutex);
}; };
#endif // BITCOIN_SCHEDULER_H #endif // BITCOIN_SCHEDULER_H

View File

@ -21,11 +21,11 @@ class CThreadInterrupt
public: public:
CThreadInterrupt(); CThreadInterrupt();
explicit operator bool() const; explicit operator bool() const;
void operator()(); void operator()() EXCLUSIVE_LOCKS_REQUIRED(!mut);
void reset(); void reset();
bool sleep_for(std::chrono::milliseconds rel_time); bool sleep_for(std::chrono::milliseconds rel_time) EXCLUSIVE_LOCKS_REQUIRED(!mut);
bool sleep_for(std::chrono::seconds rel_time); bool sleep_for(std::chrono::seconds rel_time) EXCLUSIVE_LOCKS_REQUIRED(!mut);
bool sleep_for(std::chrono::minutes rel_time); bool sleep_for(std::chrono::minutes rel_time) EXCLUSIVE_LOCKS_REQUIRED(!mut);
private: private:
std::condition_variable cond; std::condition_variable cond;

View File

@ -42,7 +42,7 @@ public:
explicit MainSignalsInstance(CScheduler& scheduler LIFETIMEBOUND) : m_schedulerClient(scheduler) {} explicit MainSignalsInstance(CScheduler& scheduler LIFETIMEBOUND) : m_schedulerClient(scheduler) {}
void Register(std::shared_ptr<CValidationInterface> callbacks) void Register(std::shared_ptr<CValidationInterface> callbacks) EXCLUSIVE_LOCKS_REQUIRED(!m_mutex)
{ {
LOCK(m_mutex); LOCK(m_mutex);
auto inserted = m_map.emplace(callbacks.get(), m_list.end()); auto inserted = m_map.emplace(callbacks.get(), m_list.end());
@ -50,7 +50,7 @@ public:
inserted.first->second->callbacks = std::move(callbacks); inserted.first->second->callbacks = std::move(callbacks);
} }
void Unregister(CValidationInterface* callbacks) void Unregister(CValidationInterface* callbacks) EXCLUSIVE_LOCKS_REQUIRED(!m_mutex)
{ {
LOCK(m_mutex); LOCK(m_mutex);
auto it = m_map.find(callbacks); auto it = m_map.find(callbacks);
@ -64,7 +64,7 @@ public:
//! map entry. After this call, the list may still contain callbacks that //! map entry. After this call, the list may still contain callbacks that
//! are currently executing, but it will be cleared when they are done //! are currently executing, but it will be cleared when they are done
//! executing. //! executing.
void Clear() void Clear() EXCLUSIVE_LOCKS_REQUIRED(!m_mutex)
{ {
LOCK(m_mutex); LOCK(m_mutex);
for (const auto& entry : m_map) { for (const auto& entry : m_map) {
@ -73,7 +73,7 @@ public:
m_map.clear(); m_map.clear();
} }
template<typename F> void Iterate(F&& f) template<typename F> void Iterate(F&& f) EXCLUSIVE_LOCKS_REQUIRED(!m_mutex)
{ {
WAIT_LOCK(m_mutex, lock); WAIT_LOCK(m_mutex, lock);
for (auto it = m_list.begin(); it != m_list.end();) { for (auto it = m_list.begin(); it != m_list.end();) {

View File

@ -92,16 +92,16 @@ public:
static uint32_t Mask(const Consensus::Params& params, Consensus::DeploymentPos pos); static uint32_t Mask(const Consensus::Params& params, Consensus::DeploymentPos pos);
/** Get the BIP9 state for a given deployment for the block after pindexPrev. */ /** Get the BIP9 state for a given deployment for the block after pindexPrev. */
ThresholdState State(const CBlockIndex* pindexPrev, const Consensus::Params& params, Consensus::DeploymentPos pos); ThresholdState State(const CBlockIndex* pindexPrev, const Consensus::Params& params, Consensus::DeploymentPos pos) EXCLUSIVE_LOCKS_REQUIRED(!m_mutex);
/** Get the block height at which the BIP9 deployment switched into the state for the block after pindexPrev. */ /** Get the block height at which the BIP9 deployment switched into the state for the block after pindexPrev. */
int StateSinceHeight(const CBlockIndex* pindexPrev, const Consensus::Params& params, Consensus::DeploymentPos pos); int StateSinceHeight(const CBlockIndex* pindexPrev, const Consensus::Params& params, Consensus::DeploymentPos pos) EXCLUSIVE_LOCKS_REQUIRED(!m_mutex);
/** Determine what nVersion a new block should use /** Determine what nVersion a new block should use
*/ */
int32_t ComputeBlockVersion(const CBlockIndex* pindexPrev, const Consensus::Params& params); int32_t ComputeBlockVersion(const CBlockIndex* pindexPrev, const Consensus::Params& params) EXCLUSIVE_LOCKS_REQUIRED(!m_mutex);
void Clear(); void Clear() EXCLUSIVE_LOCKS_REQUIRED(!m_mutex);
}; };
#endif // BITCOIN_VERSIONBITS_H #endif // BITCOIN_VERSIONBITS_H