Skip to content

Commit

Permalink
Add missing locks and locking annotations for CAddrMan
Browse files Browse the repository at this point in the history
  • Loading branch information
practicalswift committed Oct 8, 2018
1 parent 3315007 commit 3e9f6c8
Show file tree
Hide file tree
Showing 2 changed files with 31 additions and 26 deletions.
53 changes: 27 additions & 26 deletions src/addrman.h
Original file line number Diff line number Diff line change
Expand Up @@ -187,36 +187,37 @@ class CAddrInfo : public CAddress
*/
class CAddrMan
{
private:
protected:
//! critical section to protect the inner data structures
mutable CCriticalSection cs;

private:
//! last used nId
int nIdCount;
int nIdCount GUARDED_BY(cs);

//! table with information about all nIds
std::map<int, CAddrInfo> mapInfo;
std::map<int, CAddrInfo> mapInfo GUARDED_BY(cs);

//! find an nId based on its network address
std::map<CNetAddr, int> mapAddr;
std::map<CNetAddr, int> mapAddr GUARDED_BY(cs);

//! randomly-ordered vector of all nIds
std::vector<int> vRandom;
std::vector<int> vRandom GUARDED_BY(cs);

// number of "tried" entries
int nTried;
int nTried GUARDED_BY(cs);

//! list of "tried" buckets
int vvTried[ADDRMAN_TRIED_BUCKET_COUNT][ADDRMAN_BUCKET_SIZE];
int vvTried[ADDRMAN_TRIED_BUCKET_COUNT][ADDRMAN_BUCKET_SIZE] GUARDED_BY(cs);

//! number of (unique) "new" entries
int nNew;
int nNew GUARDED_BY(cs);

//! list of "new" buckets
int vvNew[ADDRMAN_NEW_BUCKET_COUNT][ADDRMAN_BUCKET_SIZE];
int vvNew[ADDRMAN_NEW_BUCKET_COUNT][ADDRMAN_BUCKET_SIZE] GUARDED_BY(cs);

//! last time Good was called (memory only)
int64_t nLastGood;
int64_t nLastGood GUARDED_BY(cs);

//! Holds addrs inserted into tried table that collide with existing entries. Test-before-evict discipline used to resolve these collisions.
std::set<int> m_tried_collisions;
Expand All @@ -229,58 +230,58 @@ class CAddrMan
FastRandomContext insecure_rand;

//! Find an entry.
CAddrInfo* Find(const CNetAddr& addr, int *pnId = nullptr);
CAddrInfo* Find(const CNetAddr& addr, int *pnId = nullptr) EXCLUSIVE_LOCKS_REQUIRED(cs);

//! find an entry, creating it if necessary.
//! nTime and nServices of the found node are updated, if necessary.
CAddrInfo* Create(const CAddress &addr, const CNetAddr &addrSource, int *pnId = nullptr);
CAddrInfo* Create(const CAddress &addr, const CNetAddr &addrSource, int *pnId = nullptr) EXCLUSIVE_LOCKS_REQUIRED(cs);

//! Swap two elements in vRandom.
void SwapRandom(unsigned int nRandomPos1, unsigned int nRandomPos2);
void SwapRandom(unsigned int nRandomPos1, unsigned int nRandomPos2) EXCLUSIVE_LOCKS_REQUIRED(cs);

//! Move an entry from the "new" table(s) to the "tried" table
void MakeTried(CAddrInfo& info, int nId);
void MakeTried(CAddrInfo& info, int nId) EXCLUSIVE_LOCKS_REQUIRED(cs);

//! Delete an entry. It must not be in tried, and have refcount 0.
void Delete(int nId);
void Delete(int nId) EXCLUSIVE_LOCKS_REQUIRED(cs);

//! Clear a position in a "new" table. This is the only place where entries are actually deleted.
void ClearNew(int nUBucket, int nUBucketPos);
void ClearNew(int nUBucket, int nUBucketPos) EXCLUSIVE_LOCKS_REQUIRED(cs);

//! Mark an entry "good", possibly moving it from "new" to "tried".
void Good_(const CService &addr, bool test_before_evict, int64_t time);
void Good_(const CService &addr, bool test_before_evict, int64_t time) EXCLUSIVE_LOCKS_REQUIRED(cs);

//! Add an entry to the "new" table.
bool Add_(const CAddress &addr, const CNetAddr& source, int64_t nTimePenalty);
bool Add_(const CAddress &addr, const CNetAddr& source, int64_t nTimePenalty) EXCLUSIVE_LOCKS_REQUIRED(cs);

//! Mark an entry as attempted to connect.
void Attempt_(const CService &addr, bool fCountFailure, int64_t nTime);
void Attempt_(const CService &addr, bool fCountFailure, int64_t nTime) EXCLUSIVE_LOCKS_REQUIRED(cs);

//! Select an address to connect to, if newOnly is set to true, only the new table is selected from.
CAddrInfo Select_(bool newOnly);
CAddrInfo Select_(bool newOnly) EXCLUSIVE_LOCKS_REQUIRED(cs);

//! See if any to-be-evicted tried table entries have been tested and if so resolve the collisions.
void ResolveCollisions_();
void ResolveCollisions_() EXCLUSIVE_LOCKS_REQUIRED(cs);

//! Return a random to-be-evicted tried table address.
CAddrInfo SelectTriedCollision_();
CAddrInfo SelectTriedCollision_() EXCLUSIVE_LOCKS_REQUIRED(cs);

//! Wraps GetRandInt to allow tests to override RandomInt and make it determinismistic.
virtual int RandomInt(int nMax);

#ifdef DEBUG_ADDRMAN
//! Perform consistency check. Returns an error code or zero.
int Check_();
int Check_() EXCLUSIVE_LOCKS_REQUIRED(cs);
#endif

//! Select several addresses at once.
void GetAddr_(std::vector<CAddress> &vAddr);
void GetAddr_(std::vector<CAddress> &vAddr) EXCLUSIVE_LOCKS_REQUIRED(cs);

//! Mark an entry as currently-connected-to.
void Connected_(const CService &addr, int64_t nTime);
void Connected_(const CService &addr, int64_t nTime) EXCLUSIVE_LOCKS_REQUIRED(cs);

//! Update an entry's service bits.
void SetServices_(const CService &addr, ServiceFlags nServices);
void SetServices_(const CService &addr, ServiceFlags nServices) EXCLUSIVE_LOCKS_REQUIRED(cs);

public:
/**
Expand Down
4 changes: 4 additions & 0 deletions src/test/addrman_tests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -40,22 +40,26 @@ class CAddrManTest : public CAddrMan

CAddrInfo* Find(const CNetAddr& addr, int* pnId = nullptr)
{
LOCK(cs);
return CAddrMan::Find(addr, pnId);
}

CAddrInfo* Create(const CAddress& addr, const CNetAddr& addrSource, int* pnId = nullptr)
{
LOCK(cs);
return CAddrMan::Create(addr, addrSource, pnId);
}

void Delete(int nId)
{
LOCK(cs);
CAddrMan::Delete(nId);
}

// Simulates connection failure so that we can test eviction of offline nodes
void SimConnFail(CService& addr)
{
LOCK(cs);
int64_t nLastSuccess = 1;
Good_(addr, true, nLastSuccess); // Set last good connection in the deep past.

Expand Down

0 comments on commit 3e9f6c8

Please sign in to comment.