rpc: Make unloadwallet wait for complete wallet unload

Github-Pull: #14941
Rebased-From: c37851d
This commit is contained in:
João Barbosa 2018-12-12 23:21:19 +00:00 committed by Anthony Fieroni
parent bcb88335ab
commit b42ce5c0de
3 changed files with 30 additions and 0 deletions

View file

@ -286,6 +286,7 @@ void Shutdown(InitInterfaces& interfaces)
LogPrintf("%s: Unable to remove PID file: %s\n", __func__, fsbridge::get_filesystem_error_message(e));
}
interfaces.chain_clients.clear();
g_wallet_init_interface.Close();
UnregisterAllValidationInterfaces();
GetMainSignals().UnregisterBackgroundSignalScheduler();
GetMainSignals().UnregisterWithMempoolSignals(mempool);

View file

@ -135,4 +135,10 @@ void WalletInit::Construct(InitInterfaces& interfaces) const
}
gArgs.SoftSetArg("-wallet", "");
interfaces.chain_clients.emplace_back(interfaces::MakeWalletClient(*interfaces.chain, gArgs.GetArgs("-wallet")));
auto wallets = GetWallets();
while (!wallets.empty()) {
auto wallet = wallets.back();
wallets.pop_back();
RemoveWallet(wallet);
UnloadWallet(std::move(wallet));
}

View file

@ -125,6 +125,29 @@ static void ReleaseWallet(CWallet* wallet)
g_wallet_release_cv.notify_all();
}
void UnloadWallet(std::shared_ptr<CWallet>&& wallet)
{
// Mark wallet for unloading.
CWallet* pwallet = wallet.get();
{
std::lock_guard<std::mutex> lock(g_wallet_release_mutex);
auto it = g_unloading_wallet_set.insert(pwallet);
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.
pwallet->NotifyUnload();
// Time to ditch our shared_ptr and wait for ReleaseWallet call.
wallet.reset();
{
std::unique_lock<std::mutex> lock(g_wallet_release_mutex);
while (g_unloading_wallet_set.count(pwallet) == 1) {
g_wallet_release_cv.wait(lock);
}
}
}
void UnloadWallet(std::shared_ptr<CWallet>&& wallet)
{
// Mark wallet for unloading.