mirror of
https://github.com/dashpay/dash.git
synced 2024-12-25 03:52:49 +01:00
Merge bitcoin/bitcoin#19238: refactor: Make CAddrMan::cs non-recursive
ae98aec9c0521cdcec76459c8200bd45ff6a1485 refactor: Make CAddrMan::cs non-recursive (Hennadii Stepanov) f5d1c7fac70f424114dae3be270fdc31589a8c34 Add AssertLockHeld to CAddrMan private functions (Hennadii Stepanov) 5ef1d0b6982f05f70ff2164ab9af1ac1d2f97f5d Add thread safety annotations to CAddrMan public functions (Hennadii Stepanov) b138973a8b4bbe061ad97011f278a21e08ea79e6 refactor: Avoid recursive locking in CAddrMan::Clear (Hennadii Stepanov) f79a664314b88941c1a2796623e846d0a5916c06 refactor: Apply consistent pattern for CAddrMan::Check usage (Hennadii Stepanov) 187b7d2bb36e6de9cd960378021ebe690619a2ef refactor: Avoid recursive locking in CAddrMan::Check (Hennadii Stepanov) f77d9c79aa41dab4285e95c9432cc6d853be67a3 refactor: Fix CAddrMan::Check style (Hennadii Stepanov) 06703973c758c2c5d0ff916993aa7055f609d2d7 Make CAddrMan::Check private (Hennadii Stepanov) efc6fac951e75ba913350bb470c3d4e6a4e284b9 refactor: Avoid recursive locking in CAddrMan::size (Hennadii Stepanov) 2da95545ea42f925dbc7703e42e9356908a8c83e test: Drop excessive locking in CAddrManTest::SimConnFail (Hennadii Stepanov) Pull request description: This PR replaces `RecursiveMutex CAddrMan::cs` with `Mutex CAddrMan::cs`. All of the related code branches are covered by appropriate lock assertions to insure that the mutex locking policy has not been changed by accident. Related to #19303. Based on #22025, and first three commits belong to it. ACKs for top commit: vasild: ACK ae98aec9c0521cdcec76459c8200bd45ff6a1485 Tree-SHA512: c3a2d3d955a75befd7e497a802b8c10730e393be9111ca263ad0464d32fae6c7edf9bd173ffb6bc9bb61c4b39073a74eba12979d47f26b0b7b4a861d100942df
This commit is contained in:
parent
535d7cd5b0
commit
3ff5348d97
@ -132,6 +132,7 @@ CAddrInfo* CAddrMan::Create(const CAddress& addr, const CNetAddr& addrSource, in
|
||||
if (!discriminatePorts) {
|
||||
addr2.SetPort(0);
|
||||
}
|
||||
AssertLockHeld(cs);
|
||||
|
||||
int nId = nIdCount++;
|
||||
mapInfo[nId] = CAddrInfo(addr, addrSource);
|
||||
@ -145,6 +146,8 @@ CAddrInfo* CAddrMan::Create(const CAddress& addr, const CNetAddr& addrSource, in
|
||||
|
||||
void CAddrMan::SwapRandom(unsigned int nRndPos1, unsigned int nRndPos2)
|
||||
{
|
||||
AssertLockHeld(cs);
|
||||
|
||||
if (nRndPos1 == nRndPos2)
|
||||
return;
|
||||
|
||||
@ -165,6 +168,8 @@ void CAddrMan::SwapRandom(unsigned int nRndPos1, unsigned int nRndPos2)
|
||||
|
||||
void CAddrMan::Delete(int nId)
|
||||
{
|
||||
AssertLockHeld(cs);
|
||||
|
||||
assert(mapInfo.count(nId) != 0);
|
||||
CAddrInfo& info = mapInfo[nId];
|
||||
assert(!info.fInTried);
|
||||
@ -184,6 +189,8 @@ void CAddrMan::Delete(int nId)
|
||||
|
||||
void CAddrMan::ClearNew(int nUBucket, int nUBucketPos)
|
||||
{
|
||||
AssertLockHeld(cs);
|
||||
|
||||
// if there is an entry in the specified bucket, delete it.
|
||||
if (vvNew[nUBucket][nUBucketPos] != -1) {
|
||||
int nIdDelete = vvNew[nUBucket][nUBucketPos];
|
||||
@ -199,6 +206,8 @@ void CAddrMan::ClearNew(int nUBucket, int nUBucketPos)
|
||||
|
||||
void CAddrMan::MakeTried(CAddrInfo& info, int nId)
|
||||
{
|
||||
AssertLockHeld(cs);
|
||||
|
||||
// remove the entry from all new buckets
|
||||
for (int bucket = 0; bucket < ADDRMAN_NEW_BUCKET_COUNT; bucket++) {
|
||||
int pos = info.GetBucketPosition(nKey, true, bucket);
|
||||
@ -247,6 +256,8 @@ void CAddrMan::MakeTried(CAddrInfo& info, int nId)
|
||||
|
||||
void CAddrMan::Good_(const CService& addr, bool test_before_evict, int64_t nTime)
|
||||
{
|
||||
AssertLockHeld(cs);
|
||||
|
||||
int nId;
|
||||
|
||||
nLastGood = nTime;
|
||||
@ -317,6 +328,8 @@ void CAddrMan::Good_(const CService& addr, bool test_before_evict, int64_t nTime
|
||||
|
||||
bool CAddrMan::Add_(const CAddress& addr, const CNetAddr& source, int64_t nTimePenalty)
|
||||
{
|
||||
AssertLockHeld(cs);
|
||||
|
||||
if (!addr.IsRoutable())
|
||||
return false;
|
||||
|
||||
@ -390,6 +403,8 @@ bool CAddrMan::Add_(const CAddress& addr, const CNetAddr& source, int64_t nTimeP
|
||||
|
||||
void CAddrMan::Attempt_(const CService& addr, bool fCountFailure, int64_t nTime)
|
||||
{
|
||||
AssertLockHeld(cs);
|
||||
|
||||
CAddrInfo* pinfo = Find(addr);
|
||||
|
||||
// if not found, bail out
|
||||
@ -412,7 +427,9 @@ void CAddrMan::Attempt_(const CService& addr, bool fCountFailure, int64_t nTime)
|
||||
|
||||
CAddrInfo CAddrMan::Select_(bool newOnly)
|
||||
{
|
||||
if (size() == 0)
|
||||
AssertLockHeld(cs);
|
||||
|
||||
if (vRandom.empty())
|
||||
return CAddrInfo();
|
||||
|
||||
if (newOnly && nNew == 0)
|
||||
@ -460,6 +477,7 @@ CAddrInfo CAddrMan::Select_(bool newOnly)
|
||||
#ifdef DEBUG_ADDRMAN
|
||||
int CAddrMan::Check_()
|
||||
{
|
||||
AssertLockHeld(cs);
|
||||
std::set<int> setTried;
|
||||
std::map<int, int> mapNew;
|
||||
|
||||
@ -537,6 +555,8 @@ int CAddrMan::Check_()
|
||||
|
||||
void CAddrMan::GetAddr_(std::vector<CAddress>& vAddr, size_t max_addresses, size_t max_pct, std::optional<Network> network)
|
||||
{
|
||||
AssertLockHeld(cs);
|
||||
|
||||
size_t nNodes = vRandom.size();
|
||||
if (max_pct != 0) {
|
||||
nNodes = max_pct * nNodes / 100;
|
||||
@ -569,6 +589,8 @@ void CAddrMan::GetAddr_(std::vector<CAddress>& vAddr, size_t max_addresses, size
|
||||
|
||||
void CAddrMan::Connected_(const CService& addr, int64_t nTime)
|
||||
{
|
||||
AssertLockHeld(cs);
|
||||
|
||||
CAddrInfo* pinfo = Find(addr);
|
||||
|
||||
// if not found, bail out
|
||||
@ -589,6 +611,8 @@ void CAddrMan::Connected_(const CService& addr, int64_t nTime)
|
||||
|
||||
void CAddrMan::SetServices_(const CService& addr, ServiceFlags nServices)
|
||||
{
|
||||
AssertLockHeld(cs);
|
||||
|
||||
CAddrInfo* pinfo = Find(addr);
|
||||
|
||||
// if not found, bail out
|
||||
@ -624,6 +648,8 @@ CAddrInfo CAddrMan::GetAddressInfo_(const CService& addr)
|
||||
|
||||
void CAddrMan::ResolveCollisions_()
|
||||
{
|
||||
AssertLockHeld(cs);
|
||||
|
||||
for (std::set<int>::iterator it = m_tried_collisions.begin(); it != m_tried_collisions.end();) {
|
||||
int id_new = *it;
|
||||
|
||||
@ -683,6 +709,8 @@ void CAddrMan::ResolveCollisions_()
|
||||
|
||||
CAddrInfo CAddrMan::SelectTriedCollision_()
|
||||
{
|
||||
AssertLockHeld(cs);
|
||||
|
||||
if (m_tried_collisions.size() == 0) return CAddrInfo();
|
||||
|
||||
std::set<int>::iterator it = m_tried_collisions.begin();
|
||||
|
@ -236,6 +236,7 @@ public:
|
||||
*/
|
||||
template <typename Stream>
|
||||
void Serialize(Stream& s_) const
|
||||
EXCLUSIVE_LOCKS_REQUIRED(!cs)
|
||||
{
|
||||
LOCK(cs);
|
||||
|
||||
@ -301,10 +302,11 @@ public:
|
||||
|
||||
template <typename Stream>
|
||||
void Unserialize(Stream& s_)
|
||||
EXCLUSIVE_LOCKS_REQUIRED(!cs)
|
||||
{
|
||||
LOCK(cs);
|
||||
|
||||
Clear();
|
||||
assert(vRandom.empty());
|
||||
|
||||
Format format;
|
||||
s_ >> Using<CustomUintFormatter<1>>(format);
|
||||
@ -467,6 +469,7 @@ public:
|
||||
}
|
||||
|
||||
void Clear()
|
||||
EXCLUSIVE_LOCKS_REQUIRED(!cs)
|
||||
{
|
||||
LOCK(cs);
|
||||
std::vector<int>().swap(vRandom);
|
||||
@ -503,26 +506,15 @@ public:
|
||||
|
||||
//! Return the number of (unique) addresses in all tables.
|
||||
size_t size() const
|
||||
EXCLUSIVE_LOCKS_REQUIRED(!cs)
|
||||
{
|
||||
LOCK(cs); // TODO: Cache this in an atomic to avoid this overhead
|
||||
return vRandom.size();
|
||||
}
|
||||
|
||||
//! Consistency check
|
||||
void Check()
|
||||
{
|
||||
#ifdef DEBUG_ADDRMAN
|
||||
{
|
||||
LOCK(cs);
|
||||
int err;
|
||||
if ((err=Check_()))
|
||||
LogPrintf("ADDRMAN CONSISTENCY CHECK FAILED!!! err=%i\n", err);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
//! Add a single address.
|
||||
bool Add(const CAddress &addr, const CNetAddr& source, int64_t nTimePenalty = 0)
|
||||
EXCLUSIVE_LOCKS_REQUIRED(!cs)
|
||||
{
|
||||
LOCK(cs);
|
||||
bool fRet = false;
|
||||
@ -537,6 +529,7 @@ public:
|
||||
|
||||
//! Add multiple addresses.
|
||||
bool Add(const std::vector<CAddress> &vAddr, const CNetAddr& source, int64_t nTimePenalty = 0)
|
||||
EXCLUSIVE_LOCKS_REQUIRED(!cs)
|
||||
{
|
||||
LOCK(cs);
|
||||
int nAdd = 0;
|
||||
@ -552,6 +545,7 @@ public:
|
||||
|
||||
//! Mark an entry as accessible.
|
||||
void Good(const CService &addr, bool test_before_evict = true, int64_t nTime = GetAdjustedTime())
|
||||
EXCLUSIVE_LOCKS_REQUIRED(!cs)
|
||||
{
|
||||
LOCK(cs);
|
||||
Check();
|
||||
@ -561,6 +555,7 @@ public:
|
||||
|
||||
//! Mark an entry as connection attempted to.
|
||||
void Attempt(const CService &addr, bool fCountFailure, int64_t nTime = GetAdjustedTime())
|
||||
EXCLUSIVE_LOCKS_REQUIRED(!cs)
|
||||
{
|
||||
LOCK(cs);
|
||||
Check();
|
||||
@ -570,6 +565,7 @@ public:
|
||||
|
||||
//! See if any to-be-evicted tried table entries have been tested and if so resolve the collisions.
|
||||
void ResolveCollisions()
|
||||
EXCLUSIVE_LOCKS_REQUIRED(!cs)
|
||||
{
|
||||
LOCK(cs);
|
||||
Check();
|
||||
@ -579,14 +575,12 @@ public:
|
||||
|
||||
//! Randomly select an address in tried that another address is attempting to evict.
|
||||
CAddrInfo SelectTriedCollision()
|
||||
{
|
||||
CAddrInfo ret;
|
||||
EXCLUSIVE_LOCKS_REQUIRED(!cs)
|
||||
{
|
||||
LOCK(cs);
|
||||
Check();
|
||||
ret = SelectTriedCollision_();
|
||||
const CAddrInfo ret = SelectTriedCollision_();
|
||||
Check();
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -594,14 +588,12 @@ public:
|
||||
* Choose an address to connect to.
|
||||
*/
|
||||
CAddrInfo Select(bool newOnly = false)
|
||||
{
|
||||
CAddrInfo addrRet;
|
||||
EXCLUSIVE_LOCKS_REQUIRED(!cs)
|
||||
{
|
||||
LOCK(cs);
|
||||
Check();
|
||||
addrRet = Select_(newOnly);
|
||||
const CAddrInfo addrRet = Select_(newOnly);
|
||||
Check();
|
||||
}
|
||||
return addrRet;
|
||||
}
|
||||
|
||||
@ -613,19 +605,19 @@ public:
|
||||
* @param[in] network Select only addresses of this network (nullopt = all).
|
||||
*/
|
||||
std::vector<CAddress> GetAddr(size_t max_addresses, size_t max_pct, std::optional<Network> network)
|
||||
{
|
||||
Check();
|
||||
std::vector<CAddress> vAddr;
|
||||
EXCLUSIVE_LOCKS_REQUIRED(!cs)
|
||||
{
|
||||
LOCK(cs);
|
||||
Check();
|
||||
std::vector<CAddress> vAddr;
|
||||
GetAddr_(vAddr, max_addresses, max_pct, network);
|
||||
}
|
||||
Check();
|
||||
return vAddr;
|
||||
}
|
||||
|
||||
//! Outer function for Connected_()
|
||||
void Connected(const CService &addr, int64_t nTime = GetAdjustedTime())
|
||||
EXCLUSIVE_LOCKS_REQUIRED(!cs)
|
||||
{
|
||||
LOCK(cs);
|
||||
Check();
|
||||
@ -634,6 +626,7 @@ public:
|
||||
}
|
||||
|
||||
void SetServices(const CService &addr, ServiceFlags nServices)
|
||||
EXCLUSIVE_LOCKS_REQUIRED(!cs)
|
||||
{
|
||||
LOCK(cs);
|
||||
Check();
|
||||
@ -660,8 +653,8 @@ protected:
|
||||
FastRandomContext insecure_rand;
|
||||
|
||||
private:
|
||||
//! critical section to protect the inner data structures
|
||||
mutable RecursiveMutex cs;
|
||||
//! A mutex to protect the inner data structures.
|
||||
mutable Mutex cs;
|
||||
|
||||
//! Serialization versions.
|
||||
enum Format : uint8_t {
|
||||
@ -754,6 +747,19 @@ private:
|
||||
//! Return a random to-be-evicted tried table address.
|
||||
CAddrInfo SelectTriedCollision_() EXCLUSIVE_LOCKS_REQUIRED(cs);
|
||||
|
||||
//! Consistency check
|
||||
void Check()
|
||||
EXCLUSIVE_LOCKS_REQUIRED(cs)
|
||||
{
|
||||
#ifdef DEBUG_ADDRMAN
|
||||
AssertLockHeld(cs);
|
||||
const int err = Check_();
|
||||
if (err) {
|
||||
LogPrintf("ADDRMAN CONSISTENCY CHECK FAILED!!! err=%i\n", err);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef DEBUG_ADDRMAN
|
||||
//! Perform consistency check. Returns an error code or zero.
|
||||
int Check_() EXCLUSIVE_LOCKS_REQUIRED(cs);
|
||||
|
@ -76,9 +76,9 @@ public:
|
||||
// Simulates connection failure so that we can test eviction of offline nodes
|
||||
void SimConnFail(const CService& addr)
|
||||
{
|
||||
LOCK(cs);
|
||||
int64_t nLastSuccess = 1;
|
||||
Good_(addr, true, nLastSuccess); // Set last good connection in the deep past.
|
||||
// Set last good connection in the deep past.
|
||||
Good(addr, true, nLastSuccess);
|
||||
|
||||
bool count_failure = false;
|
||||
int64_t nLastTry = GetAdjustedTime()-61;
|
||||
|
@ -120,9 +120,6 @@ FUZZ_TARGET_INIT(addrman, initialize_addrman)
|
||||
if (opt_service) {
|
||||
addr_man.SetServices(*opt_service, ServiceFlags{fuzzed_data_provider.ConsumeIntegral<uint64_t>()});
|
||||
}
|
||||
},
|
||||
[&] {
|
||||
(void)addr_man.Check();
|
||||
});
|
||||
}
|
||||
(void)addr_man.size();
|
||||
|
Loading…
Reference in New Issue
Block a user