diff options
| author | Gavin Andresen <[email protected]> | 2011-09-07 07:29:44 -0700 |
|---|---|---|
| committer | Gavin Andresen <[email protected]> | 2011-09-07 07:29:44 -0700 |
| commit | f92f022edaa2f14951b9ce8304a304ff9693ae16 (patch) | |
| tree | 650072e5abedce59e306ccca421398a0fca3a9b3 /src/net.cpp | |
| parent | Merge branch 'master' of git://github.com/bitcoin/bitcoin (diff) | |
| parent | Fix AddAddress cs_mapaddresses/db transaction deadlock (diff) | |
| download | discoin-f92f022edaa2f14951b9ce8304a304ff9693ae16.tar.xz discoin-f92f022edaa2f14951b9ce8304a304ff9693ae16.zip | |
Merge pull request #500 from gavinandresen/txndeadlock
Fix AddAddress cs_mapaddresses/db transaction deadlock
Diffstat (limited to 'src/net.cpp')
| -rw-r--r-- | src/net.cpp | 36 |
1 files changed, 21 insertions, 15 deletions
diff --git a/src/net.cpp b/src/net.cpp index 5fca17aa4..509d8905f 100644 --- a/src/net.cpp +++ b/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) |