diff options
author | Gavin Andresen <gavinandresen@gmail.com> | 2014-02-24 14:39:23 -0500 |
---|---|---|
committer | Gavin Andresen <gavinandresen@gmail.com> | 2014-02-24 14:39:23 -0500 |
commit | a16ad1c0f465935d437bd9ae9875b28be49ec65b (patch) | |
tree | 99166e16a402c3618fbfa32c5578c3c90625950d | |
parent | beabca2be092d0e2a1de26989d4e63a12cce1284 (diff) | |
parent | ca4cf5cff6fb60c9769b62acce2e3a8fcd0e7aae (diff) |
Merge pull request #3704 from gavinandresen/wallet_lock_fixes
Wallet locking fixes for -DDEBUG_LOCKORDER
-rwxr-xr-x | qa/rpc-tests/txnmall.sh | 6 | ||||
-rw-r--r-- | src/sync.cpp | 5 | ||||
-rw-r--r-- | src/wallet.cpp | 41 | ||||
-rw-r--r-- | src/wallet.h | 2 |
4 files changed, 31 insertions, 23 deletions
diff --git a/qa/rpc-tests/txnmall.sh b/qa/rpc-tests/txnmall.sh index 6bf92fce40..06e4f7102d 100755 --- a/qa/rpc-tests/txnmall.sh +++ b/qa/rpc-tests/txnmall.sh @@ -8,6 +8,8 @@ if [ $# -lt 1 ]; then exit 1 fi +set -f + BITCOIND=${1}/bitcoind CLI=${1}/bitcoin-cli @@ -23,13 +25,13 @@ D=$(mktemp -d test.XXXXX) D1=${D}/node1 CreateDataDir $D1 port=11000 rpcport=11001 -B1ARGS="-datadir=$D1 -debug" +B1ARGS="-datadir=$D1" $BITCOIND $B1ARGS & B1PID=$! D2=${D}/node2 CreateDataDir $D2 port=11010 rpcport=11011 -B2ARGS="-datadir=$D2 -debug" +B2ARGS="-datadir=$D2" $BITCOIND $B2ARGS & B2PID=$! diff --git a/src/sync.cpp b/src/sync.cpp index 8f713807f7..e624a9ee84 100644 --- a/src/sync.cpp +++ b/src/sync.cpp @@ -140,8 +140,9 @@ void AssertLockHeldInternal(const char *pszName, const char* pszFile, int nLine, { BOOST_FOREACH(const PAIRTYPE(void*, CLockLocation)&i, *lockstack) if (i.first == cs) return; - LogPrintf("Lock %s not held in %s:%i; locks held:\n%s", pszName, pszFile, nLine, LocksHeld()); - assert(0); + fprintf(stderr, "Assertion failed: lock %s not held in %s:%i; locks held:\n%s", + pszName, pszFile, nLine, LocksHeld().c_str()); + abort(); } #endif /* DEBUG_LOCKORDER */ diff --git a/src/wallet.cpp b/src/wallet.cpp index 2119098595..5e24738b54 100644 --- a/src/wallet.cpp +++ b/src/wallet.cpp @@ -192,7 +192,7 @@ void CWallet::SetBestChain(const CBlockLocator& loc) bool CWallet::SetMinVersion(enum WalletFeature nVersion, CWalletDB* pwalletdbIn, bool fExplicit) { - AssertLockHeld(cs_wallet); // nWalletVersion + LOCK(cs_wallet); // nWalletVersion if (nWalletVersion >= nVersion) return true; @@ -219,7 +219,7 @@ bool CWallet::SetMinVersion(enum WalletFeature nVersion, CWalletDB* pwalletdbIn, bool CWallet::SetMaxVersion(int nVersion) { - AssertLockHeld(cs_wallet); // nWalletVersion, nWalletMaxVersion + LOCK(cs_wallet); // nWalletVersion, nWalletMaxVersion // cannot downgrade below current version if (nWalletVersion > nVersion) return false; @@ -1621,14 +1621,17 @@ DBErrors CWallet::ZapWalletTx() bool CWallet::SetAddressBook(const CTxDestination& address, const string& strName, const string& strPurpose) { - AssertLockHeld(cs_wallet); // mapAddressBook - std::map<CTxDestination, CAddressBookData>::iterator mi = mapAddressBook.find(address); - mapAddressBook[address].name = strName; - if (!strPurpose.empty()) /* update purpose only if requested */ - mapAddressBook[address].purpose = strPurpose; + bool fUpdated = false; + { + LOCK(cs_wallet); // mapAddressBook + std::map<CTxDestination, CAddressBookData>::iterator mi = mapAddressBook.find(address); + fUpdated = mi != mapAddressBook.end(); + mapAddressBook[address].name = strName; + if (!strPurpose.empty()) /* update purpose only if requested */ + mapAddressBook[address].purpose = strPurpose; + } NotifyAddressBookChanged(this, address, strName, ::IsMine(*this, address), - mapAddressBook[address].purpose, - (mi == mapAddressBook.end()) ? CT_NEW : CT_UPDATED); + strPurpose, (fUpdated ? CT_UPDATED : CT_NEW) ); if (!fFileBacked) return false; if (!strPurpose.empty() && !CWalletDB(strWalletFile).WritePurpose(CBitcoinAddress(address).ToString(), strPurpose)) @@ -1638,21 +1641,23 @@ bool CWallet::SetAddressBook(const CTxDestination& address, const string& strNam bool CWallet::DelAddressBook(const CTxDestination& address) { - - AssertLockHeld(cs_wallet); // mapAddressBook - - if(fFileBacked) { - // Delete destdata tuples associated with address - std::string strAddress = CBitcoinAddress(address).ToString(); - BOOST_FOREACH(const PAIRTYPE(string, string) &item, mapAddressBook[address].destdata) + LOCK(cs_wallet); // mapAddressBook + + if(fFileBacked) { - CWalletDB(strWalletFile).EraseDestData(strAddress, item.first); + // Delete destdata tuples associated with address + std::string strAddress = CBitcoinAddress(address).ToString(); + BOOST_FOREACH(const PAIRTYPE(string, string) &item, mapAddressBook[address].destdata) + { + CWalletDB(strWalletFile).EraseDestData(strAddress, item.first); + } } + mapAddressBook.erase(address); } - mapAddressBook.erase(address); NotifyAddressBookChanged(this, address, "", ::IsMine(*this, address), "", CT_DELETED); + if (!fFileBacked) return false; CWalletDB(strWalletFile).ErasePurpose(CBitcoinAddress(address).ToString()); diff --git a/src/wallet.h b/src/wallet.h index 95fb0ee9de..eb192f1ca6 100644 --- a/src/wallet.h +++ b/src/wallet.h @@ -363,7 +363,7 @@ public: bool SetMaxVersion(int nVersion); // get the current wallet format (the oldest client version guaranteed to understand this wallet) - int GetVersion() { AssertLockHeld(cs_wallet); return nWalletVersion; } + int GetVersion() { LOCK(cs_wallet); return nWalletVersion; } // Get wallet transactions that conflict with given transaction (spend same outputs) std::set<uint256> GetConflicts(const uint256& txid) const; |