Fix AddAddress cs_mapaddresses/db transaction deadlock
This commit is contained in:
parent
e39f925655
commit
9406696578
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)
|
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,16 +475,22 @@ bool AddAddress(CAddress addr, int64 nTimePenalty, CAddrDB *pAddrDB)
|
||||||
addrFound.nTime = addr.nTime;
|
addrFound.nTime = addr.nTime;
|
||||||
fUpdated = true;
|
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)
|
void AddressCurrentlyConnected(const CAddress& addr)
|
||||||
|
|
Loading…
Reference in a new issue