Merge pull request #500 from gavinandresen/txndeadlock
Fix AddAddress cs_mapaddresses/db transaction deadlock
This commit is contained in:
commit
f92f022eda
1 changed files with 21 additions and 15 deletions
36
src/net.cpp
36
src/net.cpp
|
@ -443,6 +443,10 @@ bool AddAddress(CAddress addr, int64 nTimePenalty, CAddrDB *pAddrDB)
|
|||
if (addr.ip == addrLocalHost.ip)
|
||||
return false;
|
||||
addr.nTime = max((int64)0, (int64)addr.nTime - nTimePenalty);
|
||||
bool fUpdated = false;
|
||||
bool fNew = false;
|
||||
CAddress addrFound = addr;
|
||||
|
||||
CRITICAL_BLOCK(cs_mapAddresses)
|
||||
{
|
||||
map<vector<unsigned char>, CAddress>::iterator it = mapAddresses.find(addr.GetKey());
|
||||
|
@ -451,16 +455,12 @@ bool AddAddress(CAddress addr, int64 nTimePenalty, CAddrDB *pAddrDB)
|
|||
// New address
|
||||
printf("AddAddress(%s)\n", addr.ToString().c_str());
|
||||
mapAddresses.insert(make_pair(addr.GetKey(), addr));
|
||||
if (pAddrDB)
|
||||
pAddrDB->WriteAddress(addr);
|
||||
else
|
||||
CAddrDB().WriteAddress(addr);
|
||||
return true;
|
||||
fUpdated = true;
|
||||
fNew = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
bool fUpdated = false;
|
||||
CAddress& addrFound = (*it).second;
|
||||
addrFound = (*it).second;
|
||||
if ((addrFound.nServices | addr.nServices) != addrFound.nServices)
|
||||
{
|
||||
// Services have been added
|
||||
|
@ -475,16 +475,22 @@ bool AddAddress(CAddress addr, int64 nTimePenalty, CAddrDB *pAddrDB)
|
|||
addrFound.nTime = addr.nTime;
|
||||
fUpdated = true;
|
||||
}
|
||||
if (fUpdated)
|
||||
{
|
||||
if (pAddrDB)
|
||||
pAddrDB->WriteAddress(addrFound);
|
||||
else
|
||||
CAddrDB().WriteAddress(addrFound);
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
// There is a nasty deadlock bug if this is done inside the cs_mapAddresses
|
||||
// CRITICAL_BLOCK:
|
||||
// Thread 1: begin db transaction (locks inside-db-mutex)
|
||||
// then AddAddress (locks cs_mapAddresses)
|
||||
// Thread 2: AddAddress (locks cs_mapAddresses)
|
||||
// ... then db operation hangs waiting for inside-db-mutex
|
||||
if (fUpdated)
|
||||
{
|
||||
if (pAddrDB)
|
||||
pAddrDB->WriteAddress(addrFound);
|
||||
else
|
||||
CAddrDB().WriteAddress(addrFound);
|
||||
}
|
||||
return fNew;
|
||||
}
|
||||
|
||||
void AddressCurrentlyConnected(const CAddress& addr)
|
||||
|
|
Loading…
Reference in a new issue