Changeset View
Changeset View
Standalone View
Standalone View
src/wallet/wallet.cpp
Show First 20 Lines • Show All 82 Lines • ▼ Show 20 Lines | std::shared_ptr<CWallet> GetWallet(const std::string &name) { | ||||
for (const std::shared_ptr<CWallet> &wallet : vpwallets) { | for (const std::shared_ptr<CWallet> &wallet : vpwallets) { | ||||
if (wallet->GetName() == name) { | if (wallet->GetName() == name) { | ||||
return wallet; | return wallet; | ||||
} | } | ||||
} | } | ||||
return nullptr; | return nullptr; | ||||
} | } | ||||
static Mutex g_wallet_release_mutex; | |||||
static std::condition_variable g_wallet_release_cv; | |||||
static std::set<std::string> g_unloading_wallet_set; | |||||
// Custom deleter for shared_ptr<CWallet>. | // Custom deleter for shared_ptr<CWallet>. | ||||
static void ReleaseWallet(CWallet *wallet) { | static void ReleaseWallet(CWallet *wallet) { | ||||
// Unregister and delete the wallet right after | |||||
// BlockUntilSyncedToCurrentChain so that it's in sync with the current | |||||
// chainstate. | |||||
const std::string name = wallet->GetName(); | |||||
wallet->WalletLogPrintf("Releasing wallet\n"); | wallet->WalletLogPrintf("Releasing wallet\n"); | ||||
wallet->BlockUntilSyncedToCurrentChain(); | wallet->BlockUntilSyncedToCurrentChain(); | ||||
wallet->Flush(); | wallet->Flush(); | ||||
UnregisterValidationInterface(wallet); | |||||
delete wallet; | delete wallet; | ||||
// Wallet is now released, notify UnloadWallet, if any. | |||||
{ | |||||
LOCK(g_wallet_release_mutex); | |||||
if (g_unloading_wallet_set.erase(name) == 0) { | |||||
// UnloadWallet was not called for this wallet, all done. | |||||
return; | |||||
} | |||||
} | |||||
g_wallet_release_cv.notify_all(); | |||||
} | |||||
void UnloadWallet(std::shared_ptr<CWallet> &&wallet) { | |||||
// Mark wallet for unloading. | |||||
const std::string name = wallet->GetName(); | |||||
{ | |||||
LOCK(g_wallet_release_mutex); | |||||
auto it = g_unloading_wallet_set.insert(name); | |||||
assert(it.second); | |||||
} | |||||
// The wallet can be in use so it's not possible to explicitly unload here. | |||||
// Notify the unload intent so that all remaining shared pointers are | |||||
// released. | |||||
wallet->NotifyUnload(); | |||||
// Time to ditch our shared_ptr and wait for ReleaseWallet call. | |||||
wallet.reset(); | |||||
{ | |||||
WAIT_LOCK(g_wallet_release_mutex, lock); | |||||
while (g_unloading_wallet_set.count(name) == 1) { | |||||
g_wallet_release_cv.wait(lock); | |||||
} | |||||
} | |||||
} | } | ||||
static const size_t OUTPUT_GROUP_MAX_ENTRIES = 10; | static const size_t OUTPUT_GROUP_MAX_ENTRIES = 10; | ||||
const uint32_t BIP32_HARDENED_KEY_LIMIT = 0x80000000; | const uint32_t BIP32_HARDENED_KEY_LIMIT = 0x80000000; | ||||
const BlockHash CMerkleTx::ABANDON_HASH(uint256S( | const BlockHash CMerkleTx::ABANDON_HASH(uint256S( | ||||
"0000000000000000000000000000000000000000000000000000000000000001")); | "0000000000000000000000000000000000000000000000000000000000000001")); | ||||
▲ Show 20 Lines • Show All 4,913 Lines • Show Last 20 Lines |