wallet: unload, notify GUI as soon as possible

Releases wallet shared pointers prior to doing the
final settings update and prevent GUI races trying
to access a wallet that is no longer loaded.
This commit is contained in:
furszy 2024-08-13 22:33:31 -03:00
parent 1a41e63575
commit 5d15485aaf
No known key found for this signature in database
GPG key ID: 5DD23CCC686AA623

View file

@ -162,10 +162,14 @@ bool RemoveWallet(WalletContext& context, const std::shared_ptr<CWallet>& wallet
// Unregister with the validation interface which also drops shared pointers.
wallet->m_chain_notifications_handler.reset();
LOCK(context.wallets_mutex);
std::vector<std::shared_ptr<CWallet>>::iterator i = std::find(context.wallets.begin(), context.wallets.end(), wallet);
if (i == context.wallets.end()) return false;
context.wallets.erase(i);
{
LOCK(context.wallets_mutex);
std::vector<std::shared_ptr<CWallet>>::iterator i = std::find(context.wallets.begin(), context.wallets.end(), wallet);
if (i == context.wallets.end()) return false;
context.wallets.erase(i);
}
// Notify unload so that upper layers release the shared pointer.
wallet->NotifyUnload();
// Write the wallet setting
UpdateWalletSetting(chain, name, load_on_start, warnings);
@ -249,10 +253,6 @@ void UnloadWallet(std::shared_ptr<CWallet>&& wallet)
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();