Browse Source

Fix AddAddress cs_mapaddresses/db transaction deadlock

miguelfreitas
Gavin Andresen 13 years ago
parent
commit
9406696578
  1. 26
      src/net.cpp

26
src/net.cpp

@ -443,6 +443,10 @@ bool AddAddress(CAddress addr, int64 nTimePenalty, CAddrDB *pAddrDB)
if (addr.ip == addrLocalHost.ip) if (addr.ip == addrLocalHost.ip)
return false; return false;
addr.nTime = max((int64)0, (int64)addr.nTime - nTimePenalty); addr.nTime = max((int64)0, (int64)addr.nTime - nTimePenalty);
bool fUpdated = false;
bool fNew = false;
CAddress addrFound = addr;
CRITICAL_BLOCK(cs_mapAddresses) CRITICAL_BLOCK(cs_mapAddresses)
{ {
map<vector<unsigned char>, CAddress>::iterator it = mapAddresses.find(addr.GetKey()); 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 // New address
printf("AddAddress(%s)\n", addr.ToString().c_str()); printf("AddAddress(%s)\n", addr.ToString().c_str());
mapAddresses.insert(make_pair(addr.GetKey(), addr)); mapAddresses.insert(make_pair(addr.GetKey(), addr));
if (pAddrDB) fUpdated = true;
pAddrDB->WriteAddress(addr); fNew = true;
else
CAddrDB().WriteAddress(addr);
return true;
} }
else else
{ {
bool fUpdated = false; addrFound = (*it).second;
CAddress& addrFound = (*it).second;
if ((addrFound.nServices | addr.nServices) != addrFound.nServices) if ((addrFound.nServices | addr.nServices) != addrFound.nServices)
{ {
// Services have been added // Services have been added
@ -475,6 +475,14 @@ bool AddAddress(CAddress addr, int64 nTimePenalty, CAddrDB *pAddrDB)
addrFound.nTime = addr.nTime; addrFound.nTime = addr.nTime;
fUpdated = true; fUpdated = true;
} }
}
}
// 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 (fUpdated)
{ {
if (pAddrDB) if (pAddrDB)
@ -482,9 +490,7 @@ bool AddAddress(CAddress addr, int64 nTimePenalty, CAddrDB *pAddrDB)
else else
CAddrDB().WriteAddress(addrFound); CAddrDB().WriteAddress(addrFound);
} }
} return fNew;
}
return false;
} }
void AddressCurrentlyConnected(const CAddress& addr) void AddressCurrentlyConnected(const CAddress& addr)

Loading…
Cancel
Save