Merge pull request #1052 from sipa/scopedlocks
Use scoped locks instead of CRITICAL_BLOCK
This commit is contained in:
commit
1a275bac2b
19 changed files with 300 additions and 204 deletions
|
@ -266,8 +266,8 @@ public:
|
|||
//
|
||||
// This format is more complex, but significantly smaller (at most 1.5 MiB), and supports
|
||||
// changes to the ADDRMAN_ parameters without breaking the on-disk structure.
|
||||
CRITICAL_BLOCK(cs)
|
||||
{
|
||||
LOCK(cs);
|
||||
unsigned char nVersion = 0;
|
||||
READWRITE(nVersion);
|
||||
READWRITE(nKey);
|
||||
|
@ -398,8 +398,8 @@ public:
|
|||
void Check()
|
||||
{
|
||||
#ifdef DEBUG_ADDRMAN
|
||||
CRITICAL_BLOCK(cs)
|
||||
{
|
||||
LOCK(cs);
|
||||
int err;
|
||||
if ((err=Check_()))
|
||||
printf("ADDRMAN CONSISTENCY CHECK FAILED!!! err=%i\n", err);
|
||||
|
@ -411,8 +411,8 @@ public:
|
|||
bool Add(const CAddress &addr, const CNetAddr& source, int64 nTimePenalty = 0)
|
||||
{
|
||||
bool fRet = false;
|
||||
CRITICAL_BLOCK(cs)
|
||||
{
|
||||
LOCK(cs);
|
||||
Check();
|
||||
fRet |= Add_(addr, source, nTimePenalty);
|
||||
Check();
|
||||
|
@ -426,8 +426,8 @@ public:
|
|||
bool Add(const std::vector<CAddress> &vAddr, const CNetAddr& source, int64 nTimePenalty = 0)
|
||||
{
|
||||
int nAdd = 0;
|
||||
CRITICAL_BLOCK(cs)
|
||||
{
|
||||
LOCK(cs);
|
||||
Check();
|
||||
for (std::vector<CAddress>::const_iterator it = vAddr.begin(); it != vAddr.end(); it++)
|
||||
nAdd += Add_(*it, source, nTimePenalty) ? 1 : 0;
|
||||
|
@ -441,8 +441,8 @@ public:
|
|||
// Mark an entry as accessible.
|
||||
void Good(const CService &addr, int64 nTime = GetAdjustedTime())
|
||||
{
|
||||
CRITICAL_BLOCK(cs)
|
||||
{
|
||||
LOCK(cs);
|
||||
Check();
|
||||
Good_(addr, nTime);
|
||||
Check();
|
||||
|
@ -452,8 +452,8 @@ public:
|
|||
// Mark an entry as connection attempted to.
|
||||
void Attempt(const CService &addr, int64 nTime = GetAdjustedTime())
|
||||
{
|
||||
CRITICAL_BLOCK(cs)
|
||||
{
|
||||
LOCK(cs);
|
||||
Check();
|
||||
Attempt_(addr, nTime);
|
||||
Check();
|
||||
|
@ -465,8 +465,8 @@ public:
|
|||
CAddress Select(int nUnkBias = 50)
|
||||
{
|
||||
CAddress addrRet;
|
||||
CRITICAL_BLOCK(cs)
|
||||
{
|
||||
LOCK(cs);
|
||||
Check();
|
||||
addrRet = Select_(nUnkBias);
|
||||
Check();
|
||||
|
@ -479,8 +479,10 @@ public:
|
|||
{
|
||||
Check();
|
||||
std::vector<CAddress> vAddr;
|
||||
CRITICAL_BLOCK(cs)
|
||||
{
|
||||
LOCK(cs);
|
||||
GetAddr_(vAddr);
|
||||
}
|
||||
Check();
|
||||
return vAddr;
|
||||
}
|
||||
|
@ -488,8 +490,8 @@ public:
|
|||
// Mark an entry as currently-connected-to.
|
||||
void Connected(const CService &addr, int64 nTime = GetAdjustedTime())
|
||||
{
|
||||
CRITICAL_BLOCK(cs)
|
||||
{
|
||||
LOCK(cs);
|
||||
Check();
|
||||
Connected_(addr, nTime);
|
||||
Check();
|
||||
|
|
|
@ -1647,8 +1647,8 @@ Value walletlock(const Array& params, bool fHelp)
|
|||
if (!pwalletMain->IsCrypted())
|
||||
throw JSONRPCError(-15, "Error: running with an unencrypted wallet, but walletlock was called.");
|
||||
|
||||
CRITICAL_BLOCK(cs_nWalletUnlockTime)
|
||||
{
|
||||
LOCK(cs_nWalletUnlockTime);
|
||||
pwalletMain->Lock();
|
||||
nWalletUnlockTime = 0;
|
||||
}
|
||||
|
@ -2500,9 +2500,10 @@ void ThreadRPCServer2(void* parg)
|
|||
{
|
||||
// Execute
|
||||
Value result;
|
||||
CRITICAL_BLOCK(cs_main)
|
||||
CRITICAL_BLOCK(pwalletMain->cs_wallet)
|
||||
{
|
||||
LOCK2(cs_main, pwalletMain->cs_wallet);
|
||||
result = (*(*mi).second)(params, false);
|
||||
}
|
||||
|
||||
// Send reply
|
||||
string strReply = JSONRPCReply(result, Value::null, id);
|
||||
|
|
23
src/db.cpp
23
src/db.cpp
|
@ -72,8 +72,8 @@ CDB::CDB(const char* pszFile, const char* pszMode) : pdb(NULL)
|
|||
if (fCreate)
|
||||
nFlags |= DB_CREATE;
|
||||
|
||||
CRITICAL_BLOCK(cs_db)
|
||||
{
|
||||
LOCK(cs_db);
|
||||
if (!fDbEnvInit)
|
||||
{
|
||||
if (fShutdown)
|
||||
|
@ -128,8 +128,10 @@ CDB::CDB(const char* pszFile, const char* pszMode) : pdb(NULL)
|
|||
{
|
||||
delete pdb;
|
||||
pdb = NULL;
|
||||
CRITICAL_BLOCK(cs_db)
|
||||
{
|
||||
LOCK(cs_db);
|
||||
--mapFileUseCount[strFile];
|
||||
}
|
||||
strFile = "";
|
||||
throw runtime_error(strprintf("CDB() : can't open database file %s, error %d", pszFile, ret));
|
||||
}
|
||||
|
@ -167,14 +169,16 @@ void CDB::Close()
|
|||
|
||||
dbenv.txn_checkpoint(nMinutes ? GetArg("-dblogsize", 100)*1024 : 0, nMinutes, 0);
|
||||
|
||||
CRITICAL_BLOCK(cs_db)
|
||||
{
|
||||
LOCK(cs_db);
|
||||
--mapFileUseCount[strFile];
|
||||
}
|
||||
}
|
||||
|
||||
void static CloseDb(const string& strFile)
|
||||
{
|
||||
CRITICAL_BLOCK(cs_db)
|
||||
{
|
||||
LOCK(cs_db);
|
||||
if (mapDb[strFile] != NULL)
|
||||
{
|
||||
// Close the database handle
|
||||
|
@ -190,8 +194,8 @@ bool CDB::Rewrite(const string& strFile, const char* pszSkip)
|
|||
{
|
||||
while (!fShutdown)
|
||||
{
|
||||
CRITICAL_BLOCK(cs_db)
|
||||
{
|
||||
LOCK(cs_db);
|
||||
if (!mapFileUseCount.count(strFile) || mapFileUseCount[strFile] == 0)
|
||||
{
|
||||
// Flush log data to the dat file
|
||||
|
@ -288,8 +292,8 @@ void DBFlush(bool fShutdown)
|
|||
printf("DBFlush(%s)%s\n", fShutdown ? "true" : "false", fDbEnvInit ? "" : " db not started");
|
||||
if (!fDbEnvInit)
|
||||
return;
|
||||
CRITICAL_BLOCK(cs_db)
|
||||
{
|
||||
LOCK(cs_db);
|
||||
map<string, int>::iterator mi = mapFileUseCount.begin();
|
||||
while (mi != mapFileUseCount.end())
|
||||
{
|
||||
|
@ -879,8 +883,8 @@ int CWalletDB::LoadWallet(CWallet* pwallet)
|
|||
bool fIsEncrypted = false;
|
||||
|
||||
//// todo: shouldn't we catch exceptions and try to recover and continue?
|
||||
CRITICAL_BLOCK(pwallet->cs_wallet)
|
||||
{
|
||||
LOCK(pwallet->cs_wallet);
|
||||
int nMinVersion = 0;
|
||||
if (Read((string)"minversion", nMinVersion))
|
||||
{
|
||||
|
@ -1121,7 +1125,8 @@ void ThreadFlushWalletDB(void* parg)
|
|||
|
||||
if (nLastFlushed != nWalletDBUpdated && GetTime() - nLastWalletUpdate >= 2)
|
||||
{
|
||||
TRY_CRITICAL_BLOCK(cs_db)
|
||||
TRY_LOCK(cs_db,lockDb);
|
||||
if (lockDb)
|
||||
{
|
||||
// Don't do this if any databases are in use
|
||||
int nRefCount = 0;
|
||||
|
@ -1162,8 +1167,8 @@ bool BackupWallet(const CWallet& wallet, const string& strDest)
|
|||
return false;
|
||||
while (!fShutdown)
|
||||
{
|
||||
CRITICAL_BLOCK(cs_db)
|
||||
{
|
||||
LOCK(cs_db);
|
||||
if (!mapFileUseCount.count(wallet.strWalletFile) || mapFileUseCount[wallet.strWalletFile] == 0)
|
||||
{
|
||||
// Flush log data to the dat file
|
||||
|
|
|
@ -40,11 +40,14 @@ void Shutdown(void* parg)
|
|||
static CCriticalSection cs_Shutdown;
|
||||
static bool fTaken;
|
||||
bool fFirstThread = false;
|
||||
TRY_CRITICAL_BLOCK(cs_Shutdown)
|
||||
{
|
||||
TRY_LOCK(cs_Shutdown, lockShutdown);
|
||||
if (lockShutdown)
|
||||
{
|
||||
fFirstThread = !fTaken;
|
||||
fTaken = true;
|
||||
}
|
||||
}
|
||||
static bool fExit;
|
||||
if (fFirstThread)
|
||||
{
|
||||
|
|
|
@ -21,31 +21,37 @@ bool CBasicKeyStore::AddKey(const CKey& key)
|
|||
{
|
||||
bool fCompressed = false;
|
||||
CSecret secret = key.GetSecret(fCompressed);
|
||||
CRITICAL_BLOCK(cs_KeyStore)
|
||||
{
|
||||
LOCK(cs_KeyStore);
|
||||
mapKeys[CBitcoinAddress(key.GetPubKey())] = make_pair(secret, fCompressed);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CBasicKeyStore::AddCScript(const CScript& redeemScript)
|
||||
{
|
||||
CRITICAL_BLOCK(cs_KeyStore)
|
||||
{
|
||||
LOCK(cs_KeyStore);
|
||||
mapScripts[Hash160(redeemScript)] = redeemScript;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CBasicKeyStore::HaveCScript(const uint160& hash) const
|
||||
{
|
||||
bool result;
|
||||
CRITICAL_BLOCK(cs_KeyStore)
|
||||
{
|
||||
LOCK(cs_KeyStore);
|
||||
result = (mapScripts.count(hash) > 0);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
bool CBasicKeyStore::GetCScript(const uint160 &hash, CScript& redeemScriptOut) const
|
||||
{
|
||||
CRITICAL_BLOCK(cs_KeyStore)
|
||||
{
|
||||
LOCK(cs_KeyStore);
|
||||
ScriptMap::const_iterator mi = mapScripts.find(hash);
|
||||
if (mi != mapScripts.end())
|
||||
{
|
||||
|
@ -58,8 +64,8 @@ bool CBasicKeyStore::GetCScript(const uint160 &hash, CScript& redeemScriptOut) c
|
|||
|
||||
bool CCryptoKeyStore::SetCrypted()
|
||||
{
|
||||
CRITICAL_BLOCK(cs_KeyStore)
|
||||
{
|
||||
LOCK(cs_KeyStore);
|
||||
if (fUseCrypto)
|
||||
return true;
|
||||
if (!mapKeys.empty())
|
||||
|
@ -71,8 +77,8 @@ bool CCryptoKeyStore::SetCrypted()
|
|||
|
||||
bool CCryptoKeyStore::Unlock(const CKeyingMaterial& vMasterKeyIn)
|
||||
{
|
||||
CRITICAL_BLOCK(cs_KeyStore)
|
||||
{
|
||||
LOCK(cs_KeyStore);
|
||||
if (!SetCrypted())
|
||||
return false;
|
||||
|
||||
|
@ -100,8 +106,8 @@ bool CCryptoKeyStore::Unlock(const CKeyingMaterial& vMasterKeyIn)
|
|||
|
||||
bool CCryptoKeyStore::AddKey(const CKey& key)
|
||||
{
|
||||
CRITICAL_BLOCK(cs_KeyStore)
|
||||
{
|
||||
LOCK(cs_KeyStore);
|
||||
if (!IsCrypted())
|
||||
return CBasicKeyStore::AddKey(key);
|
||||
|
||||
|
@ -123,8 +129,8 @@ bool CCryptoKeyStore::AddKey(const CKey& key)
|
|||
|
||||
bool CCryptoKeyStore::AddCryptedKey(const std::vector<unsigned char> &vchPubKey, const std::vector<unsigned char> &vchCryptedSecret)
|
||||
{
|
||||
CRITICAL_BLOCK(cs_KeyStore)
|
||||
{
|
||||
LOCK(cs_KeyStore);
|
||||
if (!SetCrypted())
|
||||
return false;
|
||||
|
||||
|
@ -135,8 +141,8 @@ bool CCryptoKeyStore::AddCryptedKey(const std::vector<unsigned char> &vchPubKey,
|
|||
|
||||
bool CCryptoKeyStore::GetKey(const CBitcoinAddress &address, CKey& keyOut) const
|
||||
{
|
||||
CRITICAL_BLOCK(cs_KeyStore)
|
||||
{
|
||||
LOCK(cs_KeyStore);
|
||||
if (!IsCrypted())
|
||||
return CBasicKeyStore::GetKey(address, keyOut);
|
||||
|
||||
|
@ -160,8 +166,8 @@ bool CCryptoKeyStore::GetKey(const CBitcoinAddress &address, CKey& keyOut) const
|
|||
|
||||
bool CCryptoKeyStore::GetPubKey(const CBitcoinAddress &address, std::vector<unsigned char>& vchPubKeyOut) const
|
||||
{
|
||||
CRITICAL_BLOCK(cs_KeyStore)
|
||||
{
|
||||
LOCK(cs_KeyStore);
|
||||
if (!IsCrypted())
|
||||
return CKeyStore::GetPubKey(address, vchPubKeyOut);
|
||||
|
||||
|
@ -177,8 +183,8 @@ bool CCryptoKeyStore::GetPubKey(const CBitcoinAddress &address, std::vector<unsi
|
|||
|
||||
bool CCryptoKeyStore::EncryptKeys(CKeyingMaterial& vMasterKeyIn)
|
||||
{
|
||||
CRITICAL_BLOCK(cs_KeyStore)
|
||||
{
|
||||
LOCK(cs_KeyStore);
|
||||
if (!mapCryptedKeys.empty() || IsCrypted())
|
||||
return false;
|
||||
|
||||
|
|
|
@ -54,15 +54,17 @@ public:
|
|||
bool HaveKey(const CBitcoinAddress &address) const
|
||||
{
|
||||
bool result;
|
||||
CRITICAL_BLOCK(cs_KeyStore)
|
||||
{
|
||||
LOCK(cs_KeyStore);
|
||||
result = (mapKeys.count(address) > 0);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
void GetKeys(std::set<CBitcoinAddress> &setAddress) const
|
||||
{
|
||||
setAddress.clear();
|
||||
CRITICAL_BLOCK(cs_KeyStore)
|
||||
{
|
||||
LOCK(cs_KeyStore);
|
||||
KeyMap::const_iterator mi = mapKeys.begin();
|
||||
while (mi != mapKeys.end())
|
||||
{
|
||||
|
@ -73,8 +75,8 @@ public:
|
|||
}
|
||||
bool GetKey(const CBitcoinAddress &address, CKey &keyOut) const
|
||||
{
|
||||
CRITICAL_BLOCK(cs_KeyStore)
|
||||
{
|
||||
LOCK(cs_KeyStore);
|
||||
KeyMap::const_iterator mi = mapKeys.find(address);
|
||||
if (mi != mapKeys.end())
|
||||
{
|
||||
|
@ -129,8 +131,10 @@ public:
|
|||
if (!IsCrypted())
|
||||
return false;
|
||||
bool result;
|
||||
CRITICAL_BLOCK(cs_KeyStore)
|
||||
{
|
||||
LOCK(cs_KeyStore);
|
||||
result = vMasterKey.empty();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
@ -139,8 +143,10 @@ public:
|
|||
if (!SetCrypted())
|
||||
return false;
|
||||
|
||||
CRITICAL_BLOCK(cs_KeyStore)
|
||||
{
|
||||
LOCK(cs_KeyStore);
|
||||
vMasterKey.clear();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -149,8 +155,8 @@ public:
|
|||
bool AddKey(const CKey& key);
|
||||
bool HaveKey(const CBitcoinAddress &address) const
|
||||
{
|
||||
CRITICAL_BLOCK(cs_KeyStore)
|
||||
{
|
||||
LOCK(cs_KeyStore);
|
||||
if (!IsCrypted())
|
||||
return CBasicKeyStore::HaveKey(address);
|
||||
return mapCryptedKeys.count(address) > 0;
|
||||
|
|
66
src/main.cpp
66
src/main.cpp
|
@ -75,16 +75,16 @@ int64 nTransactionFee = 0;
|
|||
|
||||
void RegisterWallet(CWallet* pwalletIn)
|
||||
{
|
||||
CRITICAL_BLOCK(cs_setpwalletRegistered)
|
||||
{
|
||||
LOCK(cs_setpwalletRegistered);
|
||||
setpwalletRegistered.insert(pwalletIn);
|
||||
}
|
||||
}
|
||||
|
||||
void UnregisterWallet(CWallet* pwalletIn)
|
||||
{
|
||||
CRITICAL_BLOCK(cs_setpwalletRegistered)
|
||||
{
|
||||
LOCK(cs_setpwalletRegistered);
|
||||
setpwalletRegistered.erase(pwalletIn);
|
||||
}
|
||||
}
|
||||
|
@ -478,9 +478,11 @@ bool CTransaction::AcceptToMemoryPool(CTxDB& txdb, bool fCheckInputs, bool* pfMi
|
|||
|
||||
// Do we already have it?
|
||||
uint256 hash = GetHash();
|
||||
CRITICAL_BLOCK(cs_mapTransactions)
|
||||
{
|
||||
LOCK(cs_mapTransactions);
|
||||
if (mapTransactions.count(hash))
|
||||
return false;
|
||||
}
|
||||
if (fCheckInputs)
|
||||
if (txdb.ContainsTx(hash))
|
||||
return false;
|
||||
|
@ -552,8 +554,8 @@ bool CTransaction::AcceptToMemoryPool(CTxDB& txdb, bool fCheckInputs, bool* pfMi
|
|||
static int64 nLastTime;
|
||||
int64 nNow = GetTime();
|
||||
|
||||
CRITICAL_BLOCK(cs)
|
||||
{
|
||||
LOCK(cs);
|
||||
// Use an exponentially decaying ~10-minute window:
|
||||
dFreeCount *= pow(1.0 - 1.0/600.0, (double)(nNow - nLastTime));
|
||||
nLastTime = nNow;
|
||||
|
@ -576,8 +578,8 @@ bool CTransaction::AcceptToMemoryPool(CTxDB& txdb, bool fCheckInputs, bool* pfMi
|
|||
}
|
||||
|
||||
// Store transaction in memory
|
||||
CRITICAL_BLOCK(cs_mapTransactions)
|
||||
{
|
||||
LOCK(cs_mapTransactions);
|
||||
if (ptxOld)
|
||||
{
|
||||
printf("AcceptToMemoryPool() : replacing tx %s with new version\n", ptxOld->GetHash().ToString().c_str());
|
||||
|
@ -608,8 +610,8 @@ bool CTransaction::AddToMemoryPoolUnchecked()
|
|||
printf("AcceptToMemoryPoolUnchecked(): size %lu\n", mapTransactions.size());
|
||||
// Add to memory pool without checking anything. Don't call this directly,
|
||||
// call AcceptToMemoryPool to properly check the transaction first.
|
||||
CRITICAL_BLOCK(cs_mapTransactions)
|
||||
{
|
||||
LOCK(cs_mapTransactions);
|
||||
uint256 hash = GetHash();
|
||||
mapTransactions[hash] = *this;
|
||||
for (int i = 0; i < vin.size(); i++)
|
||||
|
@ -624,8 +626,8 @@ bool CTransaction::AddToMemoryPoolUnchecked()
|
|||
bool CTransaction::RemoveFromMemoryPool()
|
||||
{
|
||||
// Remove transaction from memory pool
|
||||
CRITICAL_BLOCK(cs_mapTransactions)
|
||||
{
|
||||
LOCK(cs_mapTransactions);
|
||||
uint256 hash = GetHash();
|
||||
if (mapTransactions.count(hash))
|
||||
{
|
||||
|
@ -702,8 +704,9 @@ bool CMerkleTx::AcceptToMemoryPool()
|
|||
|
||||
bool CWalletTx::AcceptWalletTransaction(CTxDB& txdb, bool fCheckInputs)
|
||||
{
|
||||
CRITICAL_BLOCK(cs_mapTransactions)
|
||||
|
||||
{
|
||||
LOCK(cs_mapTransactions);
|
||||
// Add previous supporting transactions first
|
||||
BOOST_FOREACH(CMerkleTx& tx, vtxPrev)
|
||||
{
|
||||
|
@ -1024,8 +1027,8 @@ bool CTransaction::FetchInputs(CTxDB& txdb, const map<uint256, CTxIndex>& mapTes
|
|||
if (!fFound || txindex.pos == CDiskTxPos(1,1,1))
|
||||
{
|
||||
// Get prev tx from single transactions in memory
|
||||
CRITICAL_BLOCK(cs_mapTransactions)
|
||||
{
|
||||
LOCK(cs_mapTransactions);
|
||||
if (!mapTransactions.count(prevout.hash))
|
||||
return error("FetchInputs() : %s mapTransactions prev not found %s", GetHash().ToString().substr(0,10).c_str(), prevout.hash.ToString().substr(0,10).c_str());
|
||||
txPrev = mapTransactions[prevout.hash];
|
||||
|
@ -1190,8 +1193,8 @@ bool CTransaction::ClientConnectInputs()
|
|||
return false;
|
||||
|
||||
// Take over previous transactions' spent pointers
|
||||
CRITICAL_BLOCK(cs_mapTransactions)
|
||||
{
|
||||
LOCK(cs_mapTransactions);
|
||||
int64 nValueIn = 0;
|
||||
for (int i = 0; i < vin.size(); i++)
|
||||
{
|
||||
|
@ -1707,10 +1710,12 @@ bool CBlock::AcceptBlock()
|
|||
// Relay inventory, but don't relay old inventory during initial block download
|
||||
int nBlockEstimate = Checkpoints::GetTotalBlocksEstimate();
|
||||
if (hashBestChain == hash)
|
||||
CRITICAL_BLOCK(cs_vNodes)
|
||||
{
|
||||
LOCK(cs_vNodes);
|
||||
BOOST_FOREACH(CNode* pnode, vNodes)
|
||||
if (nBestHeight > (pnode->nStartingHeight != -1 ? pnode->nStartingHeight - 2000 : nBlockEstimate))
|
||||
pnode->PushInventory(CInv(MSG_BLOCK, hash));
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -2052,8 +2057,8 @@ string GetWarnings(string strFor)
|
|||
}
|
||||
|
||||
// Alerts
|
||||
CRITICAL_BLOCK(cs_mapAlerts)
|
||||
{
|
||||
LOCK(cs_mapAlerts);
|
||||
BOOST_FOREACH(PAIRTYPE(const uint256, CAlert)& item, mapAlerts)
|
||||
{
|
||||
const CAlert& alert = item.second;
|
||||
|
@ -2080,8 +2085,8 @@ bool CAlert::ProcessAlert()
|
|||
if (!IsInEffect())
|
||||
return false;
|
||||
|
||||
CRITICAL_BLOCK(cs_mapAlerts)
|
||||
{
|
||||
LOCK(cs_mapAlerts);
|
||||
// Cancel previous alerts
|
||||
for (map<uint256, CAlert>::iterator mi = mapAlerts.begin(); mi != mapAlerts.end();)
|
||||
{
|
||||
|
@ -2260,9 +2265,11 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv)
|
|||
}
|
||||
|
||||
// Relay alerts
|
||||
CRITICAL_BLOCK(cs_mapAlerts)
|
||||
{
|
||||
LOCK(cs_mapAlerts);
|
||||
BOOST_FOREACH(PAIRTYPE(const uint256, CAlert)& item, mapAlerts)
|
||||
item.second.RelayTo(pfrom);
|
||||
}
|
||||
|
||||
pfrom->fSuccessfullyConnected = true;
|
||||
|
||||
|
@ -2316,8 +2323,8 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv)
|
|||
if (addr.nTime > nSince && !pfrom->fGetAddr && vAddr.size() <= 10 && addr.IsRoutable())
|
||||
{
|
||||
// Relay to a limited number of other nodes
|
||||
CRITICAL_BLOCK(cs_vNodes)
|
||||
{
|
||||
LOCK(cs_vNodes);
|
||||
// Use deterministic randomness to send to the same nodes for 24 hours
|
||||
// at a time so the setAddrKnowns of the chosen nodes prevent repeats
|
||||
static uint256 hashSalt;
|
||||
|
@ -2428,8 +2435,8 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv)
|
|||
else if (inv.IsKnownType())
|
||||
{
|
||||
// Send stream from relay memory
|
||||
CRITICAL_BLOCK(cs_mapRelay)
|
||||
{
|
||||
LOCK(cs_mapRelay);
|
||||
map<CInv, CDataStream>::iterator mi = mapRelay.find(inv);
|
||||
if (mi != mapRelay.end())
|
||||
pfrom->PushMessage(inv.GetCommand(), (*mi).second);
|
||||
|
@ -2634,8 +2641,8 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv)
|
|||
vRecv >> hashReply;
|
||||
|
||||
CRequestTracker tracker;
|
||||
CRITICAL_BLOCK(pfrom->cs_mapRequests)
|
||||
{
|
||||
LOCK(pfrom->cs_mapRequests);
|
||||
map<uint256, CRequestTracker>::iterator mi = pfrom->mapRequests.find(hashReply);
|
||||
if (mi != pfrom->mapRequests.end())
|
||||
{
|
||||
|
@ -2662,11 +2669,13 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv)
|
|||
{
|
||||
// Relay
|
||||
pfrom->setKnown.insert(alert.GetHash());
|
||||
CRITICAL_BLOCK(cs_vNodes)
|
||||
{
|
||||
LOCK(cs_vNodes);
|
||||
BOOST_FOREACH(CNode* pnode, vNodes)
|
||||
alert.RelayTo(pnode);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
else
|
||||
|
@ -2763,8 +2772,10 @@ bool ProcessMessages(CNode* pfrom)
|
|||
bool fRet = false;
|
||||
try
|
||||
{
|
||||
CRITICAL_BLOCK(cs_main)
|
||||
{
|
||||
LOCK(cs_main);
|
||||
fRet = ProcessMessage(pfrom, strCommand, vMsg);
|
||||
}
|
||||
if (fShutdown)
|
||||
return true;
|
||||
}
|
||||
|
@ -2802,8 +2813,8 @@ bool ProcessMessages(CNode* pfrom)
|
|||
|
||||
bool SendMessages(CNode* pto, bool fSendTrickle)
|
||||
{
|
||||
CRITICAL_BLOCK(cs_main)
|
||||
{
|
||||
LOCK(cs_main);
|
||||
// Don't send anything until we get their version message
|
||||
if (pto->nVersion == 0)
|
||||
return true;
|
||||
|
@ -2819,8 +2830,8 @@ bool SendMessages(CNode* pto, bool fSendTrickle)
|
|||
static int64 nLastRebroadcast;
|
||||
if (!IsInitialBlockDownload() && (GetTime() - nLastRebroadcast > 24 * 60 * 60))
|
||||
{
|
||||
CRITICAL_BLOCK(cs_vNodes)
|
||||
{
|
||||
LOCK(cs_vNodes);
|
||||
BOOST_FOREACH(CNode* pnode, vNodes)
|
||||
{
|
||||
// Periodically clear setAddrKnown to allow refresh broadcasts
|
||||
|
@ -2871,8 +2882,8 @@ bool SendMessages(CNode* pto, bool fSendTrickle)
|
|||
//
|
||||
vector<CInv> vInv;
|
||||
vector<CInv> vInvWait;
|
||||
CRITICAL_BLOCK(pto->cs_inventory)
|
||||
{
|
||||
LOCK(pto->cs_inventory);
|
||||
vInv.reserve(pto->vInventoryToSend.size());
|
||||
vInvWait.reserve(pto->vInventoryToSend.size());
|
||||
BOOST_FOREACH(const CInv& inv, pto->vInventoryToSend)
|
||||
|
@ -3087,9 +3098,8 @@ CBlock* CreateNewBlock(CReserveKey& reservekey)
|
|||
|
||||
// Collect memory pool transactions into the block
|
||||
int64 nFees = 0;
|
||||
CRITICAL_BLOCK(cs_main)
|
||||
CRITICAL_BLOCK(cs_mapTransactions)
|
||||
{
|
||||
LOCK2(cs_main, cs_mapTransactions);
|
||||
CTxDB txdb("r");
|
||||
|
||||
// Priority order to process transactions
|
||||
|
@ -3317,8 +3327,8 @@ bool CheckWork(CBlock* pblock, CWallet& wallet, CReserveKey& reservekey)
|
|||
printf("generated %s\n", FormatMoney(pblock->vtx[0].vout[0].nValue).c_str());
|
||||
|
||||
// Found a solution
|
||||
CRITICAL_BLOCK(cs_main)
|
||||
{
|
||||
LOCK(cs_main);
|
||||
if (pblock->hashPrevBlock != hashBestChain)
|
||||
return error("BitcoinMiner : generated block is stale");
|
||||
|
||||
|
@ -3326,8 +3336,10 @@ bool CheckWork(CBlock* pblock, CWallet& wallet, CReserveKey& reservekey)
|
|||
reservekey.KeepKey();
|
||||
|
||||
// Track how many getdata requests this block gets
|
||||
CRITICAL_BLOCK(wallet.cs_wallet)
|
||||
{
|
||||
LOCK(wallet.cs_wallet);
|
||||
wallet.mapRequestCount[pblock->GetHash()] = 0;
|
||||
}
|
||||
|
||||
// Process this block the same as if we had received it from another node
|
||||
if (!ProcessBlock(NULL, pblock))
|
||||
|
@ -3443,8 +3455,8 @@ void static BitcoinMiner(CWallet *pwallet)
|
|||
if (GetTimeMillis() - nHPSTimerStart > 4000)
|
||||
{
|
||||
static CCriticalSection cs;
|
||||
CRITICAL_BLOCK(cs)
|
||||
{
|
||||
LOCK(cs);
|
||||
if (GetTimeMillis() - nHPSTimerStart > 4000)
|
||||
{
|
||||
dHashesPerSec = 1000.0 * nHashCounter / (GetTimeMillis() - nHPSTimerStart);
|
||||
|
|
106
src/net.cpp
106
src/net.cpp
|
@ -272,11 +272,13 @@ void ThreadGetMyExternalIP(void* parg)
|
|||
// setAddrKnown automatically filters any duplicate sends.
|
||||
CAddress addr(addrLocalHost);
|
||||
addr.nTime = GetAdjustedTime();
|
||||
CRITICAL_BLOCK(cs_vNodes)
|
||||
{
|
||||
LOCK(cs_vNodes);
|
||||
BOOST_FOREACH(CNode* pnode, vNodes)
|
||||
pnode->PushAddress(addr);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -296,8 +298,8 @@ void AddressCurrentlyConnected(const CService& addr)
|
|||
|
||||
CNode* FindNode(const CNetAddr& ip)
|
||||
{
|
||||
CRITICAL_BLOCK(cs_vNodes)
|
||||
{
|
||||
LOCK(cs_vNodes);
|
||||
BOOST_FOREACH(CNode* pnode, vNodes)
|
||||
if ((CNetAddr)pnode->addr == ip)
|
||||
return (pnode);
|
||||
|
@ -307,8 +309,8 @@ CNode* FindNode(const CNetAddr& ip)
|
|||
|
||||
CNode* FindNode(const CService& addr)
|
||||
{
|
||||
CRITICAL_BLOCK(cs_vNodes)
|
||||
{
|
||||
LOCK(cs_vNodes);
|
||||
BOOST_FOREACH(CNode* pnode, vNodes)
|
||||
if ((CService)pnode->addr == addr)
|
||||
return (pnode);
|
||||
|
@ -362,10 +364,14 @@ CNode* ConnectNode(CAddress addrConnect, int64 nTimeout)
|
|||
pnode->AddRef(nTimeout);
|
||||
else
|
||||
pnode->AddRef();
|
||||
CRITICAL_BLOCK(cs_vNodes)
|
||||
{
|
||||
LOCK(cs_vNodes);
|
||||
vNodes.push_back(pnode);
|
||||
WAITABLE_CRITICAL_BLOCK(csOutbound)
|
||||
}
|
||||
{
|
||||
WAITABLE_LOCK(csOutbound);
|
||||
nOutbound++;
|
||||
}
|
||||
|
||||
pnode->nTimeConnected = GetTime();
|
||||
return pnode;
|
||||
|
@ -421,8 +427,8 @@ void CNode::ClearBanned()
|
|||
bool CNode::IsBanned(CNetAddr ip)
|
||||
{
|
||||
bool fResult = false;
|
||||
CRITICAL_BLOCK(cs_setBanned)
|
||||
{
|
||||
LOCK(cs_setBanned);
|
||||
std::map<CNetAddr, int64>::iterator i = setBanned.find(ip);
|
||||
if (i != setBanned.end())
|
||||
{
|
||||
|
@ -446,9 +452,11 @@ bool CNode::Misbehaving(int howmuch)
|
|||
if (nMisbehavior >= GetArg("-banscore", 100))
|
||||
{
|
||||
int64 banTime = GetTime()+GetArg("-bantime", 60*60*24); // Default 24-hour ban
|
||||
CRITICAL_BLOCK(cs_setBanned)
|
||||
{
|
||||
LOCK(cs_setBanned);
|
||||
if (setBanned[addr] < banTime)
|
||||
setBanned[addr] = banTime;
|
||||
}
|
||||
CloseSocketDisconnect();
|
||||
printf("Disconnected %s for misbehavior (score=%d)\n", addr.ToString().c_str(), nMisbehavior);
|
||||
return true;
|
||||
|
@ -497,8 +505,8 @@ void ThreadSocketHandler2(void* parg)
|
|||
//
|
||||
// Disconnect nodes
|
||||
//
|
||||
CRITICAL_BLOCK(cs_vNodes)
|
||||
{
|
||||
LOCK(cs_vNodes);
|
||||
// Disconnect unused nodes
|
||||
vector<CNode*> vNodesCopy = vNodes;
|
||||
BOOST_FOREACH(CNode* pnode, vNodesCopy)
|
||||
|
@ -510,8 +518,8 @@ void ThreadSocketHandler2(void* parg)
|
|||
vNodes.erase(remove(vNodes.begin(), vNodes.end(), pnode), vNodes.end());
|
||||
|
||||
if (!pnode->fInbound)
|
||||
WAITABLE_CRITICAL_BLOCK(csOutbound)
|
||||
{
|
||||
WAITABLE_LOCK(csOutbound);
|
||||
nOutbound--;
|
||||
|
||||
// Connection slot(s) were removed, notify connection creator(s)
|
||||
|
@ -538,11 +546,23 @@ void ThreadSocketHandler2(void* parg)
|
|||
if (pnode->GetRefCount() <= 0)
|
||||
{
|
||||
bool fDelete = false;
|
||||
TRY_CRITICAL_BLOCK(pnode->cs_vSend)
|
||||
TRY_CRITICAL_BLOCK(pnode->cs_vRecv)
|
||||
TRY_CRITICAL_BLOCK(pnode->cs_mapRequests)
|
||||
TRY_CRITICAL_BLOCK(pnode->cs_inventory)
|
||||
{
|
||||
TRY_LOCK(pnode->cs_vSend, lockSend);
|
||||
if (lockSend)
|
||||
{
|
||||
TRY_LOCK(pnode->cs_vRecv, lockRecv);
|
||||
if (lockRecv)
|
||||
{
|
||||
TRY_LOCK(pnode->cs_mapRequests, lockReq);
|
||||
if (lockReq)
|
||||
{
|
||||
TRY_LOCK(pnode->cs_inventory, lockInv);
|
||||
if (lockInv)
|
||||
fDelete = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (fDelete)
|
||||
{
|
||||
vNodesDisconnected.remove(pnode);
|
||||
|
@ -576,8 +596,8 @@ void ThreadSocketHandler2(void* parg)
|
|||
if(hListenSocket != INVALID_SOCKET)
|
||||
FD_SET(hListenSocket, &fdsetRecv);
|
||||
hSocketMax = max(hSocketMax, hListenSocket);
|
||||
CRITICAL_BLOCK(cs_vNodes)
|
||||
{
|
||||
LOCK(cs_vNodes);
|
||||
BOOST_FOREACH(CNode* pnode, vNodes)
|
||||
{
|
||||
if (pnode->hSocket == INVALID_SOCKET)
|
||||
|
@ -585,11 +605,13 @@ void ThreadSocketHandler2(void* parg)
|
|||
FD_SET(pnode->hSocket, &fdsetRecv);
|
||||
FD_SET(pnode->hSocket, &fdsetError);
|
||||
hSocketMax = max(hSocketMax, pnode->hSocket);
|
||||
TRY_CRITICAL_BLOCK(pnode->cs_vSend)
|
||||
if (!pnode->vSend.empty())
|
||||
{
|
||||
TRY_LOCK(pnode->cs_vSend, lockSend);
|
||||
if (lockSend && !pnode->vSend.empty())
|
||||
FD_SET(pnode->hSocket, &fdsetSend);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
vnThreadsRunning[THREAD_SOCKETHANDLER]--;
|
||||
int nSelect = select(hSocketMax + 1, &fdsetRecv, &fdsetSend, &fdsetError, &timeout);
|
||||
|
@ -625,10 +647,12 @@ void ThreadSocketHandler2(void* parg)
|
|||
if (hSocket != INVALID_SOCKET)
|
||||
addr = CAddress(sockaddr);
|
||||
|
||||
CRITICAL_BLOCK(cs_vNodes)
|
||||
{
|
||||
LOCK(cs_vNodes);
|
||||
BOOST_FOREACH(CNode* pnode, vNodes)
|
||||
if (pnode->fInbound)
|
||||
nInbound++;
|
||||
}
|
||||
|
||||
if (hSocket == INVALID_SOCKET)
|
||||
{
|
||||
|
@ -637,10 +661,12 @@ void ThreadSocketHandler2(void* parg)
|
|||
}
|
||||
else if (nInbound >= GetArg("-maxconnections", 125) - MAX_OUTBOUND_CONNECTIONS)
|
||||
{
|
||||
CRITICAL_BLOCK(cs_setservAddNodeAddresses)
|
||||
{
|
||||
LOCK(cs_setservAddNodeAddresses);
|
||||
if (!setservAddNodeAddresses.count(addr))
|
||||
closesocket(hSocket);
|
||||
}
|
||||
}
|
||||
else if (CNode::IsBanned(addr))
|
||||
{
|
||||
printf("connection from %s dropped (banned)\n", addr.ToString().c_str());
|
||||
|
@ -651,18 +677,20 @@ void ThreadSocketHandler2(void* parg)
|
|||
printf("accepted connection %s\n", addr.ToString().c_str());
|
||||
CNode* pnode = new CNode(hSocket, addr, true);
|
||||
pnode->AddRef();
|
||||
CRITICAL_BLOCK(cs_vNodes)
|
||||
{
|
||||
LOCK(cs_vNodes);
|
||||
vNodes.push_back(pnode);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Service each socket
|
||||
//
|
||||
vector<CNode*> vNodesCopy;
|
||||
CRITICAL_BLOCK(cs_vNodes)
|
||||
{
|
||||
LOCK(cs_vNodes);
|
||||
vNodesCopy = vNodes;
|
||||
BOOST_FOREACH(CNode* pnode, vNodesCopy)
|
||||
pnode->AddRef();
|
||||
|
@ -679,7 +707,8 @@ void ThreadSocketHandler2(void* parg)
|
|||
continue;
|
||||
if (FD_ISSET(pnode->hSocket, &fdsetRecv) || FD_ISSET(pnode->hSocket, &fdsetError))
|
||||
{
|
||||
TRY_CRITICAL_BLOCK(pnode->cs_vRecv)
|
||||
TRY_LOCK(pnode->cs_vRecv, lockRecv);
|
||||
if (lockRecv)
|
||||
{
|
||||
CDataStream& vRecv = pnode->vRecv;
|
||||
unsigned int nPos = vRecv.size();
|
||||
|
@ -728,7 +757,8 @@ void ThreadSocketHandler2(void* parg)
|
|||
continue;
|
||||
if (FD_ISSET(pnode->hSocket, &fdsetSend))
|
||||
{
|
||||
TRY_CRITICAL_BLOCK(pnode->cs_vSend)
|
||||
TRY_LOCK(pnode->cs_vSend, lockSend);
|
||||
if (lockSend)
|
||||
{
|
||||
CDataStream& vSend = pnode->vSend;
|
||||
if (!vSend.empty())
|
||||
|
@ -782,8 +812,8 @@ void ThreadSocketHandler2(void* parg)
|
|||
}
|
||||
}
|
||||
}
|
||||
CRITICAL_BLOCK(cs_vNodes)
|
||||
{
|
||||
LOCK(cs_vNodes);
|
||||
BOOST_FOREACH(CNode* pnode, vNodesCopy)
|
||||
pnode->Release();
|
||||
}
|
||||
|
@ -1195,8 +1225,10 @@ void ThreadOpenConnections2(void* parg)
|
|||
// Limit outbound connections
|
||||
int nMaxOutbound = min(MAX_OUTBOUND_CONNECTIONS, (int)GetArg("-maxconnections", 125));
|
||||
vnThreadsRunning[THREAD_OPENCONNECTIONS]--;
|
||||
WAITABLE_CRITICAL_BLOCK(csOutbound)
|
||||
{
|
||||
WAITABLE_LOCK(csOutbound);
|
||||
WAIT(condOutbound, fShutdown || nOutbound < nMaxOutbound);
|
||||
}
|
||||
vnThreadsRunning[THREAD_OPENCONNECTIONS]++;
|
||||
if (fShutdown)
|
||||
return;
|
||||
|
@ -1233,9 +1265,11 @@ void ThreadOpenConnections2(void* parg)
|
|||
// Only connect to one address per a.b.?.? range.
|
||||
// Do this here so we don't have to critsect vNodes inside mapAddresses critsect.
|
||||
set<vector<unsigned char> > setConnected;
|
||||
CRITICAL_BLOCK(cs_vNodes)
|
||||
{
|
||||
LOCK(cs_vNodes);
|
||||
BOOST_FOREACH(CNode* pnode, vNodes)
|
||||
setConnected.insert(pnode->addr.GetGroup());
|
||||
}
|
||||
|
||||
int64 nANow = GetAdjustedTime();
|
||||
|
||||
|
@ -1301,17 +1335,20 @@ void ThreadOpenAddedConnections2(void* parg)
|
|||
if(Lookup(strAddNode.c_str(), vservNode, GetDefaultPort(), fAllowDNS, 0))
|
||||
{
|
||||
vservAddressesToAdd.push_back(vservNode);
|
||||
CRITICAL_BLOCK(cs_setservAddNodeAddresses)
|
||||
{
|
||||
LOCK(cs_setservAddNodeAddresses);
|
||||
BOOST_FOREACH(CService& serv, vservNode)
|
||||
setservAddNodeAddresses.insert(serv);
|
||||
}
|
||||
}
|
||||
}
|
||||
loop
|
||||
{
|
||||
vector<vector<CService> > vservConnectAddresses = vservAddressesToAdd;
|
||||
// Attempt to connect to each IP for each addnode entry until at least one is successful per addnode entry
|
||||
// (keeping in mind that addnode entries can have many IPs if fAllowDNS)
|
||||
CRITICAL_BLOCK(cs_vNodes)
|
||||
{
|
||||
LOCK(cs_vNodes);
|
||||
BOOST_FOREACH(CNode* pnode, vNodes)
|
||||
for (vector<vector<CService> >::iterator it = vservConnectAddresses.begin(); it != vservConnectAddresses.end(); it++)
|
||||
BOOST_FOREACH(CService& addrNode, *(it))
|
||||
|
@ -1321,6 +1358,7 @@ void ThreadOpenAddedConnections2(void* parg)
|
|||
it--;
|
||||
break;
|
||||
}
|
||||
}
|
||||
BOOST_FOREACH(vector<CService>& vserv, vservConnectAddresses)
|
||||
{
|
||||
OpenNetworkConnection(CAddress(*(vserv.begin())));
|
||||
|
@ -1394,8 +1432,8 @@ void ThreadMessageHandler2(void* parg)
|
|||
while (!fShutdown)
|
||||
{
|
||||
vector<CNode*> vNodesCopy;
|
||||
CRITICAL_BLOCK(cs_vNodes)
|
||||
{
|
||||
LOCK(cs_vNodes);
|
||||
vNodesCopy = vNodes;
|
||||
BOOST_FOREACH(CNode* pnode, vNodesCopy)
|
||||
pnode->AddRef();
|
||||
|
@ -1408,20 +1446,26 @@ void ThreadMessageHandler2(void* parg)
|
|||
BOOST_FOREACH(CNode* pnode, vNodesCopy)
|
||||
{
|
||||
// Receive messages
|
||||
TRY_CRITICAL_BLOCK(pnode->cs_vRecv)
|
||||
{
|
||||
TRY_LOCK(pnode->cs_vRecv, lockRecv);
|
||||
if (lockRecv)
|
||||
ProcessMessages(pnode);
|
||||
}
|
||||
if (fShutdown)
|
||||
return;
|
||||
|
||||
// Send messages
|
||||
TRY_CRITICAL_BLOCK(pnode->cs_vSend)
|
||||
{
|
||||
TRY_LOCK(pnode->cs_vSend, lockSend);
|
||||
if (lockSend)
|
||||
SendMessages(pnode, pnode == pnodeTrickle);
|
||||
}
|
||||
if (fShutdown)
|
||||
return;
|
||||
}
|
||||
|
||||
CRITICAL_BLOCK(cs_vNodes)
|
||||
{
|
||||
LOCK(cs_vNodes);
|
||||
BOOST_FOREACH(CNode* pnode, vNodesCopy)
|
||||
pnode->Release();
|
||||
}
|
||||
|
|
26
src/net.h
26
src/net.h
|
@ -247,16 +247,20 @@ public:
|
|||
|
||||
void AddInventoryKnown(const CInv& inv)
|
||||
{
|
||||
CRITICAL_BLOCK(cs_inventory)
|
||||
{
|
||||
LOCK(cs_inventory);
|
||||
setInventoryKnown.insert(inv);
|
||||
}
|
||||
}
|
||||
|
||||
void PushInventory(const CInv& inv)
|
||||
{
|
||||
CRITICAL_BLOCK(cs_inventory)
|
||||
{
|
||||
LOCK(cs_inventory);
|
||||
if (!setInventoryKnown.count(inv))
|
||||
vInventoryToSend.push_back(inv);
|
||||
}
|
||||
}
|
||||
|
||||
void AskFor(const CInv& inv)
|
||||
{
|
||||
|
@ -519,8 +523,10 @@ public:
|
|||
uint256 hashReply;
|
||||
RAND_bytes((unsigned char*)&hashReply, sizeof(hashReply));
|
||||
|
||||
CRITICAL_BLOCK(cs_mapRequests)
|
||||
{
|
||||
LOCK(cs_mapRequests);
|
||||
mapRequests[hashReply] = CRequestTracker(fn, param1);
|
||||
}
|
||||
|
||||
PushMessage(pszCommand, hashReply);
|
||||
}
|
||||
|
@ -532,8 +538,10 @@ public:
|
|||
uint256 hashReply;
|
||||
RAND_bytes((unsigned char*)&hashReply, sizeof(hashReply));
|
||||
|
||||
CRITICAL_BLOCK(cs_mapRequests)
|
||||
{
|
||||
LOCK(cs_mapRequests);
|
||||
mapRequests[hashReply] = CRequestTracker(fn, param1);
|
||||
}
|
||||
|
||||
PushMessage(pszCommand, hashReply, a1);
|
||||
}
|
||||
|
@ -545,8 +553,10 @@ public:
|
|||
uint256 hashReply;
|
||||
RAND_bytes((unsigned char*)&hashReply, sizeof(hashReply));
|
||||
|
||||
CRITICAL_BLOCK(cs_mapRequests)
|
||||
{
|
||||
LOCK(cs_mapRequests);
|
||||
mapRequests[hashReply] = CRequestTracker(fn, param1);
|
||||
}
|
||||
|
||||
PushMessage(pszCommand, hashReply, a1, a2);
|
||||
}
|
||||
|
@ -592,9 +602,11 @@ public:
|
|||
inline void RelayInventory(const CInv& inv)
|
||||
{
|
||||
// Put on lists to offer to the other nodes
|
||||
CRITICAL_BLOCK(cs_vNodes)
|
||||
{
|
||||
LOCK(cs_vNodes);
|
||||
BOOST_FOREACH(CNode* pnode, vNodes)
|
||||
pnode->PushInventory(inv);
|
||||
}
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
|
@ -609,8 +621,8 @@ void RelayMessage(const CInv& inv, const T& a)
|
|||
template<>
|
||||
inline void RelayMessage<>(const CInv& inv, const CDataStream& ss)
|
||||
{
|
||||
CRITICAL_BLOCK(cs_mapRelay)
|
||||
{
|
||||
LOCK(cs_mapRelay);
|
||||
// Expire old relay messages
|
||||
while (!vRelayExpiration.empty() && vRelayExpiration.front().first < GetTime())
|
||||
{
|
||||
|
|
|
@ -39,8 +39,8 @@ struct AddressTablePriv
|
|||
{
|
||||
cachedAddressTable.clear();
|
||||
|
||||
CRITICAL_BLOCK(wallet->cs_wallet)
|
||||
{
|
||||
LOCK(wallet->cs_wallet);
|
||||
BOOST_FOREACH(const PAIRTYPE(CBitcoinAddress, std::string)& item, wallet->mapAddressBook)
|
||||
{
|
||||
const CBitcoinAddress& address = item.first;
|
||||
|
@ -169,8 +169,8 @@ bool AddressTableModel::setData(const QModelIndex & index, const QVariant & valu
|
|||
// Double-check that we're not overwriting a receiving address
|
||||
if(rec->type == AddressTableEntry::Sending)
|
||||
{
|
||||
CRITICAL_BLOCK(wallet->cs_wallet)
|
||||
{
|
||||
LOCK(wallet->cs_wallet);
|
||||
// Remove old entry
|
||||
wallet->DelAddressBookName(rec->address.toStdString());
|
||||
// Add new entry with new address
|
||||
|
@ -254,8 +254,8 @@ QString AddressTableModel::addRow(const QString &type, const QString &label, con
|
|||
return QString();
|
||||
}
|
||||
// Check for duplicate addresses
|
||||
CRITICAL_BLOCK(wallet->cs_wallet)
|
||||
{
|
||||
LOCK(wallet->cs_wallet);
|
||||
if(wallet->mapAddressBook.count(strAddress))
|
||||
{
|
||||
editStatus = DUPLICATE_ADDRESS;
|
||||
|
@ -286,8 +286,10 @@ QString AddressTableModel::addRow(const QString &type, const QString &label, con
|
|||
return QString();
|
||||
}
|
||||
// Add entry
|
||||
CRITICAL_BLOCK(wallet->cs_wallet)
|
||||
{
|
||||
LOCK(wallet->cs_wallet);
|
||||
wallet->SetAddressBookName(strAddress, strLabel);
|
||||
}
|
||||
return QString::fromStdString(strAddress);
|
||||
}
|
||||
|
||||
|
@ -301,8 +303,8 @@ bool AddressTableModel::removeRows(int row, int count, const QModelIndex & paren
|
|||
// Also refuse to remove receiving addresses.
|
||||
return false;
|
||||
}
|
||||
CRITICAL_BLOCK(wallet->cs_wallet)
|
||||
{
|
||||
LOCK(wallet->cs_wallet);
|
||||
wallet->DelAddressBookName(rec->address.toStdString());
|
||||
}
|
||||
return true;
|
||||
|
@ -312,8 +314,8 @@ bool AddressTableModel::removeRows(int row, int count, const QModelIndex & paren
|
|||
*/
|
||||
QString AddressTableModel::labelForAddress(const QString &address) const
|
||||
{
|
||||
CRITICAL_BLOCK(wallet->cs_wallet)
|
||||
{
|
||||
LOCK(wallet->cs_wallet);
|
||||
CBitcoinAddress address_parsed(address.toStdString());
|
||||
std::map<CBitcoinAddress, std::string>::iterator mi = wallet->mapAddressBook.find(address_parsed);
|
||||
if (mi != wallet->mapAddressBook.end())
|
||||
|
|
|
@ -34,8 +34,9 @@ QString TransactionDesc::FormatTxStatus(const CWalletTx& wtx)
|
|||
QString TransactionDesc::toHTML(CWallet *wallet, CWalletTx &wtx)
|
||||
{
|
||||
QString strHTML;
|
||||
CRITICAL_BLOCK(wallet->cs_wallet)
|
||||
|
||||
{
|
||||
LOCK(wallet->cs_wallet);
|
||||
strHTML.reserve(4000);
|
||||
strHTML += "<html><font face='verdana, arial, helvetica, sans-serif'>";
|
||||
|
||||
|
@ -243,8 +244,9 @@ QString TransactionDesc::toHTML(CWallet *wallet, CWalletTx &wtx)
|
|||
|
||||
strHTML += "<br><b>Inputs:</b>";
|
||||
strHTML += "<ul>";
|
||||
CRITICAL_BLOCK(wallet->cs_wallet)
|
||||
|
||||
{
|
||||
LOCK(wallet->cs_wallet);
|
||||
BOOST_FOREACH(const CTxIn& txin, wtx.vin)
|
||||
{
|
||||
COutPoint prevout = txin.prevout;
|
||||
|
|
|
@ -69,8 +69,8 @@ struct TransactionTablePriv
|
|||
qDebug() << "refreshWallet";
|
||||
#endif
|
||||
cachedWallet.clear();
|
||||
CRITICAL_BLOCK(wallet->cs_wallet)
|
||||
{
|
||||
LOCK(wallet->cs_wallet);
|
||||
for(std::map<uint256, CWalletTx>::iterator it = wallet->mapWallet.begin(); it != wallet->mapWallet.end(); ++it)
|
||||
{
|
||||
cachedWallet.append(TransactionRecord::decomposeTransaction(wallet, it->second));
|
||||
|
@ -95,8 +95,8 @@ struct TransactionTablePriv
|
|||
QList<uint256> updated_sorted = updated;
|
||||
qSort(updated_sorted);
|
||||
|
||||
CRITICAL_BLOCK(wallet->cs_wallet)
|
||||
{
|
||||
LOCK(wallet->cs_wallet);
|
||||
for(int update_idx = updated_sorted.size()-1; update_idx >= 0; --update_idx)
|
||||
{
|
||||
const uint256 &hash = updated_sorted.at(update_idx);
|
||||
|
@ -171,8 +171,8 @@ struct TransactionTablePriv
|
|||
// simply re-use the cached status.
|
||||
if(rec->statusUpdateNeeded())
|
||||
{
|
||||
CRITICAL_BLOCK(wallet->cs_wallet)
|
||||
{
|
||||
LOCK(wallet->cs_wallet);
|
||||
std::map<uint256, CWalletTx>::iterator mi = wallet->mapWallet.find(rec->hash);
|
||||
|
||||
if(mi != wallet->mapWallet.end())
|
||||
|
@ -191,8 +191,8 @@ struct TransactionTablePriv
|
|||
|
||||
QString describe(TransactionRecord *rec)
|
||||
{
|
||||
CRITICAL_BLOCK(wallet->cs_wallet)
|
||||
{
|
||||
LOCK(wallet->cs_wallet);
|
||||
std::map<uint256, CWalletTx>::iterator mi = wallet->mapWallet.find(rec->hash);
|
||||
if(mi != wallet->mapWallet.end())
|
||||
{
|
||||
|
@ -229,9 +229,9 @@ void TransactionTableModel::update()
|
|||
QList<uint256> updated;
|
||||
|
||||
// Check if there are changes to wallet map
|
||||
TRY_CRITICAL_BLOCK(wallet->cs_wallet)
|
||||
{
|
||||
if(!wallet->vWalletUpdated.empty())
|
||||
TRY_LOCK(wallet->cs_wallet, lockWallet);
|
||||
if (lockWallet && !wallet->vWalletUpdated.empty())
|
||||
{
|
||||
BOOST_FOREACH(uint256 hash, wallet->vWalletUpdated)
|
||||
{
|
||||
|
|
|
@ -32,8 +32,8 @@ qint64 WalletModel::getUnconfirmedBalance() const
|
|||
int WalletModel::getNumTransactions() const
|
||||
{
|
||||
int numTransactions = 0;
|
||||
CRITICAL_BLOCK(wallet->cs_wallet)
|
||||
{
|
||||
LOCK(wallet->cs_wallet);
|
||||
numTransactions = wallet->mapWallet.size();
|
||||
}
|
||||
return numTransactions;
|
||||
|
@ -115,9 +115,9 @@ WalletModel::SendCoinsReturn WalletModel::sendCoins(const QList<SendCoinsRecipie
|
|||
return SendCoinsReturn(AmountWithFeeExceedsBalance, nTransactionFee);
|
||||
}
|
||||
|
||||
CRITICAL_BLOCK(cs_main)
|
||||
CRITICAL_BLOCK(wallet->cs_wallet)
|
||||
{
|
||||
LOCK2(cs_main, wallet->cs_wallet);
|
||||
|
||||
// Sendmany
|
||||
std::vector<std::pair<CScript, int64> > vecSend;
|
||||
foreach(const SendCoinsRecipient &rcp, recipients)
|
||||
|
@ -155,8 +155,8 @@ WalletModel::SendCoinsReturn WalletModel::sendCoins(const QList<SendCoinsRecipie
|
|||
foreach(const SendCoinsRecipient &rcp, recipients)
|
||||
{
|
||||
std::string strAddress = rcp.address.toStdString();
|
||||
CRITICAL_BLOCK(wallet->cs_wallet)
|
||||
{
|
||||
LOCK(wallet->cs_wallet);
|
||||
if (!wallet->mapAddressBook.count(strAddress))
|
||||
wallet->SetAddressBookName(strAddress, rcp.label.toStdString());
|
||||
}
|
||||
|
@ -227,8 +227,8 @@ bool WalletModel::setWalletLocked(bool locked, const SecureString &passPhrase)
|
|||
bool WalletModel::changePassphrase(const SecureString &oldPass, const SecureString &newPass)
|
||||
{
|
||||
bool retval;
|
||||
CRITICAL_BLOCK(wallet->cs_wallet)
|
||||
{
|
||||
LOCK(wallet->cs_wallet);
|
||||
wallet->Lock(); // Make sure wallet is locked before attempting pass change
|
||||
retval = wallet->ChangeWalletPassphrase(oldPass, newPass);
|
||||
}
|
||||
|
|
|
@ -60,9 +60,9 @@ Value importprivkey(const Array& params, bool fHelp)
|
|||
key.SetSecret(secret, fCompressed);
|
||||
CBitcoinAddress vchAddress = CBitcoinAddress(key.GetPubKey());
|
||||
|
||||
CRITICAL_BLOCK(cs_main)
|
||||
CRITICAL_BLOCK(pwalletMain->cs_wallet)
|
||||
{
|
||||
LOCK2(cs_main, pwalletMain->cs_wallet);
|
||||
|
||||
pwalletMain->MarkDirty();
|
||||
pwalletMain->SetAddressBookName(vchAddress, strLabel);
|
||||
|
||||
|
|
|
@ -15,14 +15,15 @@ BOOST_AUTO_TEST_CASE(util_criticalsection)
|
|||
CCriticalSection cs;
|
||||
|
||||
do {
|
||||
CRITICAL_BLOCK(cs)
|
||||
LOCK(cs);
|
||||
break;
|
||||
|
||||
BOOST_ERROR("break was swallowed!");
|
||||
} while(0);
|
||||
|
||||
do {
|
||||
TRY_CRITICAL_BLOCK(cs)
|
||||
TRY_LOCK(cs, lockTest);
|
||||
if (lockTest)
|
||||
break;
|
||||
|
||||
BOOST_ERROR("break was swallowed!");
|
||||
|
|
24
src/util.cpp
24
src/util.cpp
|
@ -196,8 +196,8 @@ inline int OutputDebugStringF(const char* pszFormat, ...)
|
|||
static CCriticalSection cs_OutputDebugStringF;
|
||||
|
||||
// accumulate a line at a time
|
||||
CRITICAL_BLOCK(cs_OutputDebugStringF)
|
||||
{
|
||||
LOCK(cs_OutputDebugStringF);
|
||||
static char pszBuffer[50000];
|
||||
static char* pend;
|
||||
if (pend == NULL)
|
||||
|
@ -1120,25 +1120,25 @@ private:
|
|||
int sourceLine;
|
||||
};
|
||||
|
||||
typedef std::vector< std::pair<CCriticalSection*, CLockLocation> > LockStack;
|
||||
typedef std::vector< std::pair<void*, CLockLocation> > LockStack;
|
||||
|
||||
static boost::interprocess::interprocess_mutex dd_mutex;
|
||||
static std::map<std::pair<CCriticalSection*, CCriticalSection*>, LockStack> lockorders;
|
||||
static std::map<std::pair<void*, void*>, LockStack> lockorders;
|
||||
static boost::thread_specific_ptr<LockStack> lockstack;
|
||||
|
||||
|
||||
static void potential_deadlock_detected(const std::pair<CCriticalSection*, CCriticalSection*>& mismatch, const LockStack& s1, const LockStack& s2)
|
||||
static void potential_deadlock_detected(const std::pair<void*, void*>& mismatch, const LockStack& s1, const LockStack& s2)
|
||||
{
|
||||
printf("POTENTIAL DEADLOCK DETECTED\n");
|
||||
printf("Previous lock order was:\n");
|
||||
BOOST_FOREACH(const PAIRTYPE(CCriticalSection*, CLockLocation)& i, s2)
|
||||
BOOST_FOREACH(const PAIRTYPE(void*, CLockLocation)& i, s2)
|
||||
{
|
||||
if (i.first == mismatch.first) printf(" (1)");
|
||||
if (i.first == mismatch.second) printf(" (2)");
|
||||
printf(" %s\n", i.second.ToString().c_str());
|
||||
}
|
||||
printf("Current lock order is:\n");
|
||||
BOOST_FOREACH(const PAIRTYPE(CCriticalSection*, CLockLocation)& i, s1)
|
||||
BOOST_FOREACH(const PAIRTYPE(void*, CLockLocation)& i, s1)
|
||||
{
|
||||
if (i.first == mismatch.first) printf(" (1)");
|
||||
if (i.first == mismatch.second) printf(" (2)");
|
||||
|
@ -1146,7 +1146,7 @@ static void potential_deadlock_detected(const std::pair<CCriticalSection*, CCrit
|
|||
}
|
||||
}
|
||||
|
||||
static void push_lock(CCriticalSection* c, const CLockLocation& locklocation)
|
||||
static void push_lock(void* c, const CLockLocation& locklocation, bool fTry)
|
||||
{
|
||||
bool fOrderOK = true;
|
||||
if (lockstack.get() == NULL)
|
||||
|
@ -1157,16 +1157,16 @@ static void push_lock(CCriticalSection* c, const CLockLocation& locklocation)
|
|||
|
||||
(*lockstack).push_back(std::make_pair(c, locklocation));
|
||||
|
||||
BOOST_FOREACH(const PAIRTYPE(CCriticalSection*, CLockLocation)& i, (*lockstack))
|
||||
if (!fTry) BOOST_FOREACH(const PAIRTYPE(void*, CLockLocation)& i, (*lockstack))
|
||||
{
|
||||
if (i.first == c) break;
|
||||
|
||||
std::pair<CCriticalSection*, CCriticalSection*> p1 = std::make_pair(i.first, c);
|
||||
std::pair<void*, void*> p1 = std::make_pair(i.first, c);
|
||||
if (lockorders.count(p1))
|
||||
continue;
|
||||
lockorders[p1] = (*lockstack);
|
||||
|
||||
std::pair<CCriticalSection*, CCriticalSection*> p2 = std::make_pair(c, i.first);
|
||||
std::pair<void*, void*> p2 = std::make_pair(c, i.first);
|
||||
if (lockorders.count(p2))
|
||||
{
|
||||
potential_deadlock_detected(p1, lockorders[p2], lockorders[p1]);
|
||||
|
@ -1188,9 +1188,9 @@ static void pop_lock()
|
|||
dd_mutex.unlock();
|
||||
}
|
||||
|
||||
void EnterCritical(const char* pszName, const char* pszFile, int nLine, void* cs)
|
||||
void EnterCritical(const char* pszName, const char* pszFile, int nLine, void* cs, bool fTry)
|
||||
{
|
||||
push_lock(cs, CLockLocation(pszName, pszFile, nLine));
|
||||
push_lock(cs, CLockLocation(pszName, pszFile, nLine), fTry);
|
||||
}
|
||||
|
||||
void LeaveCritical()
|
||||
|
|
21
src/util.h
21
src/util.h
|
@ -190,10 +190,10 @@ typedef boost::interprocess::interprocess_recursive_mutex CCriticalSection;
|
|||
typedef boost::interprocess::interprocess_mutex CWaitableCriticalSection;
|
||||
|
||||
#ifdef DEBUG_LOCKORDER
|
||||
void EnterCritical(const char* pszName, const char* pszFile, int nLine, void* cs);
|
||||
void EnterCritical(const char* pszName, const char* pszFile, int nLine, void* cs, bool fTry = false);
|
||||
void LeaveCritical();
|
||||
#else
|
||||
void static inline EnterCritical(const char* pszName, const char* pszFile, int nLine, void* cs) {}
|
||||
void static inline EnterCritical(const char* pszName, const char* pszFile, int nLine, void* cs, bool fTry = false) {}
|
||||
void static inline LeaveCritical() {}
|
||||
#endif
|
||||
|
||||
|
@ -234,7 +234,7 @@ public:
|
|||
{
|
||||
if (!lock.owns())
|
||||
{
|
||||
EnterCritical(pszName, pszFile, nLine, (void*)(lock.mutex()));
|
||||
EnterCritical(pszName, pszFile, nLine, (void*)(lock.mutex()), true);
|
||||
lock.try_lock();
|
||||
if (!lock.owns())
|
||||
LeaveCritical();
|
||||
|
@ -282,13 +282,10 @@ typedef boost::interprocess::interprocess_condition CConditionVariable;
|
|||
#define NOTIFY_ALL(name) \
|
||||
do { (name).notify_all(); } while(0)
|
||||
|
||||
#define CRITICAL_BLOCK(cs) \
|
||||
for (bool fcriticalblockonce=true; fcriticalblockonce; assert(("break caught by CRITICAL_BLOCK!" && !fcriticalblockonce)), fcriticalblockonce=false) \
|
||||
for (CCriticalBlock criticalblock(cs, #cs, __FILE__, __LINE__); fcriticalblockonce; fcriticalblockonce=false)
|
||||
|
||||
#define WAITABLE_CRITICAL_BLOCK(cs) \
|
||||
for (bool fcriticalblockonce=true; fcriticalblockonce; assert(("break caught by WAITABLE_CRITICAL_BLOCK!" && !fcriticalblockonce)), fcriticalblockonce=false) \
|
||||
for (CWaitableCriticalBlock waitablecriticalblock(cs, #cs, __FILE__, __LINE__); fcriticalblockonce; fcriticalblockonce=false)
|
||||
#define LOCK(cs) CCriticalBlock criticalblock(cs, #cs, __FILE__, __LINE__)
|
||||
#define LOCK2(cs1,cs2) CCriticalBlock criticalblock1(cs1, #cs1, __FILE__, __LINE__),criticalblock2(cs2, #cs2, __FILE__, __LINE__)
|
||||
#define TRY_LOCK(cs,name) CCriticalBlock name(cs, #cs, __FILE__, __LINE__, true)
|
||||
#define WAITABLE_LOCK(cs) CWaitableCriticalBlock waitablecriticalblock(cs, #cs, __FILE__, __LINE__)
|
||||
|
||||
#define ENTER_CRITICAL_SECTION(cs) \
|
||||
{ \
|
||||
|
@ -302,10 +299,6 @@ typedef boost::interprocess::interprocess_condition CConditionVariable;
|
|||
LeaveCritical(); \
|
||||
}
|
||||
|
||||
#define TRY_CRITICAL_BLOCK(cs) \
|
||||
for (bool fcriticalblockonce=true; fcriticalblockonce; assert(("break caught by TRY_CRITICAL_BLOCK!" && !fcriticalblockonce)), fcriticalblockonce=false) \
|
||||
for (CCriticalBlock criticalblock(cs, #cs, __FILE__, __LINE__, true); fcriticalblockonce && (fcriticalblockonce = criticalblock); fcriticalblockonce=false)
|
||||
|
||||
|
||||
// This is exactly like std::string, but with a custom allocator.
|
||||
// (secure_allocator<> is defined in serialize.h)
|
||||
|
|
|
@ -49,8 +49,8 @@ bool CWallet::AddCryptedKey(const vector<unsigned char> &vchPubKey, const vector
|
|||
return false;
|
||||
if (!fFileBacked)
|
||||
return true;
|
||||
CRITICAL_BLOCK(cs_wallet)
|
||||
{
|
||||
LOCK(cs_wallet);
|
||||
if (pwalletdbEncryption)
|
||||
return pwalletdbEncryption->WriteCryptedKey(vchPubKey, vchCryptedSecret);
|
||||
else
|
||||
|
@ -76,7 +76,8 @@ bool CWallet::Unlock(const SecureString& strWalletPassphrase)
|
|||
CCrypter crypter;
|
||||
CKeyingMaterial vMasterKey;
|
||||
|
||||
CRITICAL_BLOCK(cs_wallet)
|
||||
{
|
||||
LOCK(cs_wallet);
|
||||
BOOST_FOREACH(const MasterKeyMap::value_type& pMasterKey, mapMasterKeys)
|
||||
{
|
||||
if(!crypter.SetKeyFromPassphrase(strWalletPassphrase, pMasterKey.second.vchSalt, pMasterKey.second.nDeriveIterations, pMasterKey.second.nDerivationMethod))
|
||||
|
@ -86,6 +87,7 @@ bool CWallet::Unlock(const SecureString& strWalletPassphrase)
|
|||
if (CCryptoKeyStore::Unlock(vMasterKey))
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -93,8 +95,8 @@ bool CWallet::ChangeWalletPassphrase(const SecureString& strOldWalletPassphrase,
|
|||
{
|
||||
bool fWasLocked = IsLocked();
|
||||
|
||||
CRITICAL_BLOCK(cs_wallet)
|
||||
{
|
||||
LOCK(cs_wallet);
|
||||
Lock();
|
||||
|
||||
CCrypter crypter;
|
||||
|
@ -228,8 +230,8 @@ bool CWallet::EncryptWallet(const SecureString& strWalletPassphrase)
|
|||
if (!crypter.Encrypt(vMasterKey, kMasterKey.vchCryptedKey))
|
||||
return false;
|
||||
|
||||
CRITICAL_BLOCK(cs_wallet)
|
||||
{
|
||||
LOCK(cs_wallet);
|
||||
mapMasterKeys[++nMasterKeyMaxID] = kMasterKey;
|
||||
if (fFileBacked)
|
||||
{
|
||||
|
@ -275,8 +277,8 @@ void CWallet::WalletUpdateSpent(const CTransaction &tx)
|
|||
// Anytime a signature is successfully verified, it's proof the outpoint is spent.
|
||||
// Update the wallet spent flag if it doesn't know due to wallet.dat being
|
||||
// restored from backup or the user making copies of wallet.dat.
|
||||
CRITICAL_BLOCK(cs_wallet)
|
||||
{
|
||||
LOCK(cs_wallet);
|
||||
BOOST_FOREACH(const CTxIn& txin, tx.vin)
|
||||
{
|
||||
map<uint256, CWalletTx>::iterator mi = mapWallet.find(txin.prevout.hash);
|
||||
|
@ -297,8 +299,8 @@ void CWallet::WalletUpdateSpent(const CTransaction &tx)
|
|||
|
||||
void CWallet::MarkDirty()
|
||||
{
|
||||
CRITICAL_BLOCK(cs_wallet)
|
||||
{
|
||||
LOCK(cs_wallet);
|
||||
BOOST_FOREACH(PAIRTYPE(const uint256, CWalletTx)& item, mapWallet)
|
||||
item.second.MarkDirty();
|
||||
}
|
||||
|
@ -307,8 +309,8 @@ void CWallet::MarkDirty()
|
|||
bool CWallet::AddToWallet(const CWalletTx& wtxIn)
|
||||
{
|
||||
uint256 hash = wtxIn.GetHash();
|
||||
CRITICAL_BLOCK(cs_wallet)
|
||||
{
|
||||
LOCK(cs_wallet);
|
||||
// Inserts only if not already there, returns tx inserted or tx found
|
||||
pair<map<uint256, CWalletTx>::iterator, bool> ret = mapWallet.insert(make_pair(hash, wtxIn));
|
||||
CWalletTx& wtx = (*ret.first).second;
|
||||
|
@ -382,8 +384,8 @@ bool CWallet::AddToWallet(const CWalletTx& wtxIn)
|
|||
bool CWallet::AddToWalletIfInvolvingMe(const CTransaction& tx, const CBlock* pblock, bool fUpdate, bool fFindBlock)
|
||||
{
|
||||
uint256 hash = tx.GetHash();
|
||||
CRITICAL_BLOCK(cs_wallet)
|
||||
{
|
||||
LOCK(cs_wallet);
|
||||
bool fExisted = mapWallet.count(hash);
|
||||
if (fExisted && !fUpdate) return false;
|
||||
if (fExisted || IsMine(tx) || IsFromMe(tx))
|
||||
|
@ -404,8 +406,8 @@ bool CWallet::EraseFromWallet(uint256 hash)
|
|||
{
|
||||
if (!fFileBacked)
|
||||
return false;
|
||||
CRITICAL_BLOCK(cs_wallet)
|
||||
{
|
||||
LOCK(cs_wallet);
|
||||
if (mapWallet.erase(hash))
|
||||
CWalletDB(strWalletFile).EraseTx(hash);
|
||||
}
|
||||
|
@ -415,8 +417,8 @@ bool CWallet::EraseFromWallet(uint256 hash)
|
|||
|
||||
bool CWallet::IsMine(const CTxIn &txin) const
|
||||
{
|
||||
CRITICAL_BLOCK(cs_wallet)
|
||||
{
|
||||
LOCK(cs_wallet);
|
||||
map<uint256, CWalletTx>::const_iterator mi = mapWallet.find(txin.prevout.hash);
|
||||
if (mi != mapWallet.end())
|
||||
{
|
||||
|
@ -431,8 +433,8 @@ bool CWallet::IsMine(const CTxIn &txin) const
|
|||
|
||||
int64 CWallet::GetDebit(const CTxIn &txin) const
|
||||
{
|
||||
CRITICAL_BLOCK(cs_wallet)
|
||||
{
|
||||
LOCK(cs_wallet);
|
||||
map<uint256, CWalletTx>::const_iterator mi = mapWallet.find(txin.prevout.hash);
|
||||
if (mi != mapWallet.end())
|
||||
{
|
||||
|
@ -457,9 +459,11 @@ bool CWallet::IsChange(const CTxOut& txout) const
|
|||
// 'the change' will need to be implemented (maybe extend CWalletTx to remember
|
||||
// which output, if any, was change).
|
||||
if (ExtractAddress(txout.scriptPubKey, address) && HaveKey(address))
|
||||
CRITICAL_BLOCK(cs_wallet)
|
||||
{
|
||||
LOCK(cs_wallet);
|
||||
if (!mapAddressBook.count(address))
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -472,8 +476,8 @@ int CWalletTx::GetRequestCount() const
|
|||
{
|
||||
// Returns -1 if it wasn't being tracked
|
||||
int nRequests = -1;
|
||||
CRITICAL_BLOCK(pwallet->cs_wallet)
|
||||
{
|
||||
LOCK(pwallet->cs_wallet);
|
||||
if (IsCoinBase())
|
||||
{
|
||||
// Generated block
|
||||
|
@ -577,8 +581,8 @@ void CWalletTx::GetAccountAmounts(const string& strAccount, int64& nGenerated, i
|
|||
nSent += s.second;
|
||||
nFee = allFee;
|
||||
}
|
||||
CRITICAL_BLOCK(pwallet->cs_wallet)
|
||||
{
|
||||
LOCK(pwallet->cs_wallet);
|
||||
BOOST_FOREACH(const PAIRTYPE(CBitcoinAddress,int64)& r, listReceived)
|
||||
{
|
||||
if (pwallet->mapAddressBook.count(r.first))
|
||||
|
@ -607,8 +611,8 @@ void CWalletTx::AddSupportingTransactions(CTxDB& txdb)
|
|||
vWorkQueue.push_back(txin.prevout.hash);
|
||||
|
||||
// This critsect is OK because txdb is already open
|
||||
CRITICAL_BLOCK(pwallet->cs_wallet)
|
||||
{
|
||||
LOCK(pwallet->cs_wallet);
|
||||
map<uint256, const CMerkleTx*> mapWalletPrev;
|
||||
set<uint256> setAlreadyDone;
|
||||
for (int i = 0; i < vWorkQueue.size(); i++)
|
||||
|
@ -666,8 +670,8 @@ int CWallet::ScanForWalletTransactions(CBlockIndex* pindexStart, bool fUpdate)
|
|||
int ret = 0;
|
||||
|
||||
CBlockIndex* pindex = pindexStart;
|
||||
CRITICAL_BLOCK(cs_wallet)
|
||||
{
|
||||
LOCK(cs_wallet);
|
||||
while (pindex)
|
||||
{
|
||||
CBlock block;
|
||||
|
@ -696,8 +700,9 @@ void CWallet::ReacceptWalletTransactions()
|
|||
{
|
||||
CTxDB txdb("r");
|
||||
bool fRepeat = true;
|
||||
while (fRepeat) CRITICAL_BLOCK(cs_wallet)
|
||||
while (fRepeat)
|
||||
{
|
||||
LOCK(cs_wallet);
|
||||
fRepeat = false;
|
||||
vector<CDiskTxPos> vMissingTx;
|
||||
BOOST_FOREACH(PAIRTYPE(const uint256, CWalletTx)& item, mapWallet)
|
||||
|
@ -799,8 +804,8 @@ void CWallet::ResendWalletTransactions()
|
|||
// Rebroadcast any of our txes that aren't in a block yet
|
||||
printf("ResendWalletTransactions()\n");
|
||||
CTxDB txdb("r");
|
||||
CRITICAL_BLOCK(cs_wallet)
|
||||
{
|
||||
LOCK(cs_wallet);
|
||||
// Sort them in chronological order
|
||||
multimap<unsigned int, CWalletTx*> mapSorted;
|
||||
BOOST_FOREACH(PAIRTYPE(const uint256, CWalletTx)& item, mapWallet)
|
||||
|
@ -833,8 +838,8 @@ void CWallet::ResendWalletTransactions()
|
|||
int64 CWallet::GetBalance() const
|
||||
{
|
||||
int64 nTotal = 0;
|
||||
CRITICAL_BLOCK(cs_wallet)
|
||||
{
|
||||
LOCK(cs_wallet);
|
||||
for (map<uint256, CWalletTx>::const_iterator it = mapWallet.begin(); it != mapWallet.end(); ++it)
|
||||
{
|
||||
const CWalletTx* pcoin = &(*it).second;
|
||||
|
@ -850,8 +855,8 @@ int64 CWallet::GetBalance() const
|
|||
int64 CWallet::GetUnconfirmedBalance() const
|
||||
{
|
||||
int64 nTotal = 0;
|
||||
CRITICAL_BLOCK(cs_wallet)
|
||||
{
|
||||
LOCK(cs_wallet);
|
||||
for (map<uint256, CWalletTx>::const_iterator it = mapWallet.begin(); it != mapWallet.end(); ++it)
|
||||
{
|
||||
const CWalletTx* pcoin = &(*it).second;
|
||||
|
@ -875,8 +880,8 @@ bool CWallet::SelectCoinsMinConf(int64 nTargetValue, int nConfMine, int nConfThe
|
|||
vector<pair<int64, pair<const CWalletTx*,unsigned int> > > vValue;
|
||||
int64 nTotalLower = 0;
|
||||
|
||||
CRITICAL_BLOCK(cs_wallet)
|
||||
{
|
||||
LOCK(cs_wallet);
|
||||
vector<const CWalletTx*> vCoins;
|
||||
vCoins.reserve(mapWallet.size());
|
||||
for (map<uint256, CWalletTx>::const_iterator it = mapWallet.begin(); it != mapWallet.end(); ++it)
|
||||
|
@ -1032,9 +1037,8 @@ bool CWallet::CreateTransaction(const vector<pair<CScript, int64> >& vecSend, CW
|
|||
|
||||
wtxNew.BindWallet(this);
|
||||
|
||||
CRITICAL_BLOCK(cs_main)
|
||||
CRITICAL_BLOCK(cs_wallet)
|
||||
{
|
||||
LOCK2(cs_main, cs_wallet);
|
||||
// txdb must be opened before the mapWallet lock
|
||||
CTxDB txdb("r");
|
||||
{
|
||||
|
@ -1146,9 +1150,8 @@ bool CWallet::CreateTransaction(CScript scriptPubKey, int64 nValue, CWalletTx& w
|
|||
// Call after CreateTransaction unless you want to abort
|
||||
bool CWallet::CommitTransaction(CWalletTx& wtxNew, CReserveKey& reservekey)
|
||||
{
|
||||
CRITICAL_BLOCK(cs_main)
|
||||
CRITICAL_BLOCK(cs_wallet)
|
||||
{
|
||||
LOCK2(cs_main, cs_wallet);
|
||||
printf("CommitTransaction:\n%s", wtxNew.ToString().c_str());
|
||||
{
|
||||
// This is only to keep the database open to defeat the auto-flush for the
|
||||
|
@ -1297,8 +1300,8 @@ bool CWallet::DelAddressBookName(const CBitcoinAddress& address)
|
|||
|
||||
void CWallet::PrintWallet(const CBlock& block)
|
||||
{
|
||||
CRITICAL_BLOCK(cs_wallet)
|
||||
{
|
||||
LOCK(cs_wallet);
|
||||
if (mapWallet.count(block.vtx[0].GetHash()))
|
||||
{
|
||||
CWalletTx& wtx = mapWallet[block.vtx[0].GetHash()];
|
||||
|
@ -1310,8 +1313,8 @@ void CWallet::PrintWallet(const CBlock& block)
|
|||
|
||||
bool CWallet::GetTransaction(const uint256 &hashTx, CWalletTx& wtx)
|
||||
{
|
||||
CRITICAL_BLOCK(cs_wallet)
|
||||
{
|
||||
LOCK(cs_wallet);
|
||||
map<uint256, CWalletTx>::iterator mi = mapWallet.find(hashTx);
|
||||
if (mi != mapWallet.end())
|
||||
{
|
||||
|
@ -1347,8 +1350,8 @@ bool GetWalletFile(CWallet* pwallet, string &strWalletFileOut)
|
|||
//
|
||||
bool CWallet::NewKeyPool()
|
||||
{
|
||||
CRITICAL_BLOCK(cs_wallet)
|
||||
{
|
||||
LOCK(cs_wallet);
|
||||
CWalletDB walletdb(strWalletFile);
|
||||
BOOST_FOREACH(int64 nIndex, setKeyPool)
|
||||
walletdb.ErasePool(nIndex);
|
||||
|
@ -1371,8 +1374,9 @@ bool CWallet::NewKeyPool()
|
|||
|
||||
bool CWallet::TopUpKeyPool()
|
||||
{
|
||||
CRITICAL_BLOCK(cs_wallet)
|
||||
{
|
||||
LOCK(cs_wallet);
|
||||
|
||||
if (IsLocked())
|
||||
return false;
|
||||
|
||||
|
@ -1398,8 +1402,9 @@ void CWallet::ReserveKeyFromKeyPool(int64& nIndex, CKeyPool& keypool)
|
|||
{
|
||||
nIndex = -1;
|
||||
keypool.vchPubKey.clear();
|
||||
CRITICAL_BLOCK(cs_wallet)
|
||||
{
|
||||
LOCK(cs_wallet);
|
||||
|
||||
if (!IsLocked())
|
||||
TopUpKeyPool();
|
||||
|
||||
|
@ -1422,9 +1427,8 @@ void CWallet::ReserveKeyFromKeyPool(int64& nIndex, CKeyPool& keypool)
|
|||
|
||||
int64 CWallet::AddReserveKey(const CKeyPool& keypool)
|
||||
{
|
||||
CRITICAL_BLOCK(cs_main)
|
||||
CRITICAL_BLOCK(cs_wallet)
|
||||
{
|
||||
LOCK2(cs_main, cs_wallet);
|
||||
CWalletDB walletdb(strWalletFile);
|
||||
|
||||
int64 nIndex = 1 + *(--setKeyPool.end());
|
||||
|
@ -1450,8 +1454,10 @@ void CWallet::KeepKey(int64 nIndex)
|
|||
void CWallet::ReturnKey(int64 nIndex)
|
||||
{
|
||||
// Return to key pool
|
||||
CRITICAL_BLOCK(cs_wallet)
|
||||
{
|
||||
LOCK(cs_wallet);
|
||||
setKeyPool.insert(nIndex);
|
||||
}
|
||||
printf("keypool return %"PRI64d"\n", nIndex);
|
||||
}
|
||||
|
||||
|
@ -1459,8 +1465,8 @@ bool CWallet::GetKeyFromPool(vector<unsigned char>& result, bool fAllowReuse)
|
|||
{
|
||||
int64 nIndex = 0;
|
||||
CKeyPool keypool;
|
||||
CRITICAL_BLOCK(cs_wallet)
|
||||
{
|
||||
LOCK(cs_wallet);
|
||||
ReserveKeyFromKeyPool(nIndex, keypool);
|
||||
if (nIndex == -1)
|
||||
{
|
||||
|
@ -1530,8 +1536,7 @@ void CWallet::GetAllReserveAddresses(set<CBitcoinAddress>& setAddress)
|
|||
|
||||
CWalletDB walletdb(strWalletFile);
|
||||
|
||||
CRITICAL_BLOCK(cs_main)
|
||||
CRITICAL_BLOCK(cs_wallet)
|
||||
LOCK2(cs_main, cs_wallet);
|
||||
BOOST_FOREACH(const int64& id, setKeyPool)
|
||||
{
|
||||
CKeyPool keypool;
|
||||
|
|
|
@ -211,16 +211,18 @@ public:
|
|||
|
||||
void UpdatedTransaction(const uint256 &hashTx)
|
||||
{
|
||||
CRITICAL_BLOCK(cs_wallet)
|
||||
{
|
||||
LOCK(cs_wallet);
|
||||
vWalletUpdated.push_back(hashTx);
|
||||
}
|
||||
}
|
||||
|
||||
void PrintWallet(const CBlock& block);
|
||||
|
||||
void Inventory(const uint256 &hash)
|
||||
{
|
||||
CRITICAL_BLOCK(cs_wallet)
|
||||
{
|
||||
LOCK(cs_wallet);
|
||||
std::map<uint256, int>::iterator mi = mapRequestCount.find(hash);
|
||||
if (mi != mapRequestCount.end())
|
||||
(*mi).second++;
|
||||
|
|
Loading…
Reference in a new issue