mirror of
https://github.com/bitcoin/bitcoin.git
synced 2025-01-09 11:27:28 -03:00
Compare commits
5 commits
2f7d9aec4d
...
99ecb9a630
Author | SHA1 | Date | |
---|---|---|---|
|
99ecb9a630 | ||
|
f550a8e035 | ||
|
64e736d79e | ||
|
8872b4a6ca | ||
|
5d15485aaf |
7 changed files with 28 additions and 30 deletions
|
@ -42,7 +42,7 @@ static void WalletCreate(benchmark::Bench& bench, bool encrypted)
|
|||
|
||||
// Release wallet
|
||||
RemoveWallet(context, wallet, /*load_on_start=*/ std::nullopt);
|
||||
UnloadWallet(std::move(wallet));
|
||||
WaitForDeleteWallet(std::move(wallet));
|
||||
fs::remove_all(wallet_path);
|
||||
});
|
||||
}
|
||||
|
|
|
@ -178,7 +178,7 @@ void UnloadWallets(WalletContext& context)
|
|||
wallets.pop_back();
|
||||
std::vector<bilingual_str> warnings;
|
||||
RemoveWallet(context, wallet, /* load_on_start= */ std::nullopt, warnings);
|
||||
UnloadWallet(std::move(wallet));
|
||||
WaitForDeleteWallet(std::move(wallet));
|
||||
}
|
||||
}
|
||||
} // namespace wallet
|
||||
|
|
|
@ -495,7 +495,7 @@ static RPCHelpMan unloadwallet()
|
|||
}
|
||||
}
|
||||
|
||||
UnloadWallet(std::move(wallet));
|
||||
WaitForDeleteWallet(std::move(wallet));
|
||||
|
||||
UniValue result(UniValue::VOBJ);
|
||||
PushWarnings(warnings, result);
|
||||
|
|
|
@ -74,7 +74,7 @@ void TestUnloadWallet(std::shared_ptr<CWallet>&& wallet)
|
|||
// Calls SyncWithValidationInterfaceQueue
|
||||
wallet->chain().waitForNotificationsIfTipChanged({});
|
||||
wallet->m_chain_notifications_handler.reset();
|
||||
UnloadWallet(std::move(wallet));
|
||||
WaitForDeleteWallet(std::move(wallet));
|
||||
}
|
||||
|
||||
std::unique_ptr<WalletDatabase> DuplicateMockDatabase(WalletDatabase& database)
|
||||
|
|
|
@ -889,7 +889,7 @@ BOOST_FIXTURE_TEST_CASE(CreateWalletWithoutChain, BasicTestingSetup)
|
|||
context.args = &m_args;
|
||||
auto wallet = TestLoadWallet(context);
|
||||
BOOST_CHECK(wallet);
|
||||
UnloadWallet(std::move(wallet));
|
||||
WaitForDeleteWallet(std::move(wallet));
|
||||
}
|
||||
|
||||
BOOST_FIXTURE_TEST_CASE(RemoveTxs, TestChain100Setup)
|
||||
|
|
|
@ -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);
|
||||
|
@ -223,38 +227,35 @@ static std::set<std::string> g_loading_wallet_set GUARDED_BY(g_loading_wallet_mu
|
|||
static std::set<std::string> g_unloading_wallet_set GUARDED_BY(g_wallet_release_mutex);
|
||||
|
||||
// Custom deleter for shared_ptr<CWallet>.
|
||||
static void ReleaseWallet(CWallet* wallet)
|
||||
static void FlushAndDeleteWallet(CWallet* wallet)
|
||||
{
|
||||
const std::string name = wallet->GetName();
|
||||
wallet->WalletLogPrintf("Releasing wallet\n");
|
||||
wallet->WalletLogPrintf("Releasing wallet %s..\n", name);
|
||||
wallet->Flush();
|
||||
delete wallet;
|
||||
// Wallet is now released, notify UnloadWallet, if any.
|
||||
// Wallet is now released, notify WaitForDeleteWallet, if any.
|
||||
{
|
||||
LOCK(g_wallet_release_mutex);
|
||||
if (g_unloading_wallet_set.erase(name) == 0) {
|
||||
// UnloadWallet was not called for this wallet, all done.
|
||||
// WaitForDeleteWallet was not called for this wallet, all done.
|
||||
return;
|
||||
}
|
||||
}
|
||||
g_wallet_release_cv.notify_all();
|
||||
}
|
||||
|
||||
void UnloadWallet(std::shared_ptr<CWallet>&& wallet)
|
||||
void WaitForDeleteWallet(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);
|
||||
g_unloading_wallet_set.insert(name);
|
||||
// Do not expect to be the only one removing this wallet.
|
||||
// Multiple threads could simultaneously be waiting for deletion.
|
||||
}
|
||||
// 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.
|
||||
// Time to ditch our shared_ptr and wait for FlushAndDeleteWallet call.
|
||||
wallet.reset();
|
||||
{
|
||||
WAIT_LOCK(g_wallet_release_mutex, lock);
|
||||
|
@ -2971,7 +2972,7 @@ std::shared_ptr<CWallet> CWallet::Create(WalletContext& context, const std::stri
|
|||
const auto start{SteadyClock::now()};
|
||||
// TODO: Can't use std::make_shared because we need a custom deleter but
|
||||
// should be possible to use std::allocate_shared.
|
||||
std::shared_ptr<CWallet> walletInstance(new CWallet(chain, name, std::move(database)), ReleaseWallet);
|
||||
std::shared_ptr<CWallet> walletInstance(new CWallet(chain, name, std::move(database)), FlushAndDeleteWallet);
|
||||
walletInstance->m_keypool_size = std::max(args.GetIntArg("-keypool", DEFAULT_KEYPOOL_SIZE), int64_t{1});
|
||||
walletInstance->m_notify_tx_changed_script = args.GetArg("-walletnotify", "");
|
||||
|
||||
|
@ -4387,7 +4388,7 @@ util::Result<MigrationResult> MigrateLegacyToDescriptor(const std::string& walle
|
|||
if (!RemoveWallet(context, wallet, /*load_on_start=*/std::nullopt, warnings)) {
|
||||
return util::Error{_("Unable to unload the wallet before migrating")};
|
||||
}
|
||||
UnloadWallet(std::move(wallet));
|
||||
WaitForDeleteWallet(std::move(wallet));
|
||||
was_loaded = true;
|
||||
} else {
|
||||
// Check if the wallet is BDB
|
||||
|
@ -4531,7 +4532,7 @@ util::Result<MigrationResult> MigrateLegacyToDescriptor(const std::string& walle
|
|||
error += _("\nUnable to cleanup failed migration");
|
||||
return util::Error{error};
|
||||
}
|
||||
UnloadWallet(std::move(w));
|
||||
WaitForDeleteWallet(std::move(w));
|
||||
} else {
|
||||
// Unloading for wallets in local context
|
||||
assert(w.use_count() == 1);
|
||||
|
|
|
@ -83,12 +83,9 @@ struct bilingual_str;
|
|||
namespace wallet {
|
||||
struct WalletContext;
|
||||
|
||||
//! Explicitly unload and delete the wallet.
|
||||
//! Blocks the current thread after signaling the unload intent so that all
|
||||
//! wallet pointer owners release the wallet.
|
||||
//! Note that, when blocking is not required, the wallet is implicitly unloaded
|
||||
//! by the shared pointer deleter.
|
||||
void UnloadWallet(std::shared_ptr<CWallet>&& wallet);
|
||||
//! Explicitly delete the wallet.
|
||||
//! Blocks the current thread until the wallet is destructed.
|
||||
void WaitForDeleteWallet(std::shared_ptr<CWallet>&& wallet);
|
||||
|
||||
bool AddWallet(WalletContext& context, const std::shared_ptr<CWallet>& wallet);
|
||||
bool RemoveWallet(WalletContext& context, const std::shared_ptr<CWallet>& wallet, std::optional<bool> load_on_start, std::vector<bilingual_str>& warnings);
|
||||
|
|
Loading…
Reference in a new issue