Merge #9225: Fix some benign races

dfed983 Fix unlocked access to vNodes.size() (Matt Corallo)
3033522 Remove double brackets in addrman (Matt Corallo)
dbfaade Fix AddrMan locking (Matt Corallo)
047ea10 Make fImporting an std::atomic (Matt Corallo)
42071ca Make fDisconnect an std::atomic (Matt Corallo)
This commit is contained in:
Wladimir J. van der Laan 2016-11-29 12:38:12 +01:00
commit 5488514b90
No known key found for this signature in database
GPG key ID: 74810B012346C9A6
5 changed files with 32 additions and 36 deletions

View file

@ -482,6 +482,7 @@ public:
//! Return the number of (unique) addresses in all tables. //! Return the number of (unique) addresses in all tables.
size_t size() const size_t size() const
{ {
LOCK(cs); // TODO: Cache this in an atomic to avoid this overhead
return vRandom.size(); return vRandom.size();
} }
@ -500,14 +501,12 @@ public:
//! Add a single address. //! Add a single address.
bool Add(const CAddress &addr, const CNetAddr& source, int64_t nTimePenalty = 0) bool Add(const CAddress &addr, const CNetAddr& source, int64_t nTimePenalty = 0)
{
bool fRet = false;
{ {
LOCK(cs); LOCK(cs);
bool fRet = false;
Check(); Check();
fRet |= Add_(addr, source, nTimePenalty); fRet |= Add_(addr, source, nTimePenalty);
Check(); Check();
}
if (fRet) if (fRet)
LogPrint("addrman", "Added %s from %s: %i tried, %i new\n", addr.ToStringIPPort(), source.ToString(), nTried, nNew); LogPrint("addrman", "Added %s from %s: %i tried, %i new\n", addr.ToStringIPPort(), source.ToString(), nTried, nNew);
return fRet; return fRet;
@ -515,15 +514,13 @@ public:
//! Add multiple addresses. //! Add multiple addresses.
bool Add(const std::vector<CAddress> &vAddr, const CNetAddr& source, int64_t nTimePenalty = 0) bool Add(const std::vector<CAddress> &vAddr, const CNetAddr& source, int64_t nTimePenalty = 0)
{
int nAdd = 0;
{ {
LOCK(cs); LOCK(cs);
int nAdd = 0;
Check(); Check();
for (std::vector<CAddress>::const_iterator it = vAddr.begin(); it != vAddr.end(); it++) for (std::vector<CAddress>::const_iterator it = vAddr.begin(); it != vAddr.end(); it++)
nAdd += Add_(*it, source, nTimePenalty) ? 1 : 0; nAdd += Add_(*it, source, nTimePenalty) ? 1 : 0;
Check(); Check();
}
if (nAdd) if (nAdd)
LogPrint("addrman", "Added %i addresses from %s: %i tried, %i new\n", nAdd, source.ToString(), nTried, nNew); LogPrint("addrman", "Added %i addresses from %s: %i tried, %i new\n", nAdd, source.ToString(), nTried, nNew);
return nAdd > 0; return nAdd > 0;
@ -531,25 +528,21 @@ public:
//! Mark an entry as accessible. //! Mark an entry as accessible.
void Good(const CService &addr, int64_t nTime = GetAdjustedTime()) void Good(const CService &addr, int64_t nTime = GetAdjustedTime())
{
{ {
LOCK(cs); LOCK(cs);
Check(); Check();
Good_(addr, nTime); Good_(addr, nTime);
Check(); Check();
} }
}
//! Mark an entry as connection attempted to. //! Mark an entry as connection attempted to.
void Attempt(const CService &addr, bool fCountFailure, int64_t nTime = GetAdjustedTime()) void Attempt(const CService &addr, bool fCountFailure, int64_t nTime = GetAdjustedTime())
{
{ {
LOCK(cs); LOCK(cs);
Check(); Check();
Attempt_(addr, fCountFailure, nTime); Attempt_(addr, fCountFailure, nTime);
Check(); Check();
} }
}
/** /**
* Choose an address to connect to. * Choose an address to connect to.
@ -581,14 +574,12 @@ public:
//! Mark an entry as currently-connected-to. //! Mark an entry as currently-connected-to.
void Connected(const CService &addr, int64_t nTime = GetAdjustedTime()) void Connected(const CService &addr, int64_t nTime = GetAdjustedTime())
{
{ {
LOCK(cs); LOCK(cs);
Check(); Check();
Connected_(addr, nTime); Connected_(addr, nTime);
Check(); Check();
} }
}
void SetServices(const CService &addr, ServiceFlags nServices) void SetServices(const CService &addr, ServiceFlags nServices)
{ {

View file

@ -69,7 +69,7 @@ int64_t nTimeBestReceived = 0; // Used only to inform the wallet of when we last
CWaitableCriticalSection csBestBlock; CWaitableCriticalSection csBestBlock;
CConditionVariable cvBlockChange; CConditionVariable cvBlockChange;
int nScriptCheckThreads = 0; int nScriptCheckThreads = 0;
bool fImporting = false; std::atomic_bool fImporting(false);
bool fReindex = false; bool fReindex = false;
bool fTxIndex = false; bool fTxIndex = false;
bool fHavePruned = false; bool fHavePruned = false;

View file

@ -165,7 +165,7 @@ extern uint64_t nLastBlockWeight;
extern const std::string strMessageMagic; extern const std::string strMessageMagic;
extern CWaitableCriticalSection csBestBlock; extern CWaitableCriticalSection csBestBlock;
extern CConditionVariable cvBlockChange; extern CConditionVariable cvBlockChange;
extern bool fImporting; extern std::atomic_bool fImporting;
extern bool fReindex; extern bool fReindex;
extern int nScriptCheckThreads; extern int nScriptCheckThreads;
extern bool fTxIndex; extern bool fTxIndex;

View file

@ -1103,8 +1103,13 @@ void CConnman::ThreadSocketHandler()
} }
} }
} }
if(vNodes.size() != nPrevNodeCount) { size_t vNodesSize;
nPrevNodeCount = vNodes.size(); {
LOCK(cs_vNodes);
vNodesSize = vNodes.size();
}
if(vNodesSize != nPrevNodeCount) {
nPrevNodeCount = vNodesSize;
if(clientInterface) if(clientInterface)
clientInterface->NotifyNumConnectionsChanged(nPrevNodeCount); clientInterface->NotifyNumConnectionsChanged(nPrevNodeCount);
} }

View file

@ -615,7 +615,7 @@ public:
const bool fInbound; const bool fInbound;
bool fNetworkNode; bool fNetworkNode;
bool fSuccessfullyConnected; bool fSuccessfullyConnected;
bool fDisconnect; std::atomic_bool fDisconnect;
// We use fRelayTxes for two purposes - // We use fRelayTxes for two purposes -
// a) it allows us to not relay tx invs before receiving the peer's version message // a) it allows us to not relay tx invs before receiving the peer's version message
// b) the peer may tell us in its version message that we should not relay tx invs // b) the peer may tell us in its version message that we should not relay tx invs