mirror of
https://github.com/bitcoin/bitcoin.git
synced 2026-06-03 17:54:19 +02:00
Merge #18338: Fix wallet unload race condition
41b0baf43cgui: Handle WalletModel::unload asynchronous (João Barbosa)ab31b9d6feFix wallet unload race condition (Russell Yanofsky) Pull request description: This PR consists in two fixes. The first fixes a concurrency issues with `boost::signals2`. The second fixes a wallet model destruction while it's being used. From boost signal documentation at https://www.boost.org/doc/libs/1_72_0/doc/html/signals2/thread-safety.html: > When a signal is invoked by calling signal::operator(), the invocation first acquires a lock on the signal's mutex. Then it obtains a handle to the signal's slot list and combiner. Next it releases the signal's mutex, before invoking the combiner to iterate through the slot list. This means that `UnregisterValidationInterface` doesn't prevent more calls to that interface. The fix consists in capturing the `shared_ptr<CValidationInterface>` in each internal slot. The GUI bug is fixed by using a `Qt::QueuedConnection` in the `WalletModel::unload` connection. ACKs for top commit: ryanofsky: Code review ACK41b0baf43c. Only change is moving assert as suggested hebasto: ACK41b0baf43c, tested on Linux Mint 19.3. Tree-SHA512: 4f712d8de65bc1214411831250de5dc0a9fd505fb84da5baf9f2cc4d551bc3abffc061616f00afe43dba7525af2cd96c9b54aeead9383145e3b8801f25d85f50
This commit is contained in:
@@ -116,7 +116,7 @@ WalletModel* WalletController::getOrCreateWallet(std::unique_ptr<interfaces::Wal
|
||||
const bool called = QMetaObject::invokeMethod(wallet_model, "startPollBalance");
|
||||
assert(called);
|
||||
|
||||
connect(wallet_model, &WalletModel::unload, [this, wallet_model] {
|
||||
connect(wallet_model, &WalletModel::unload, this, [this, wallet_model] {
|
||||
// Defer removeAndDeleteWallet when no modal widget is active.
|
||||
// TODO: remove this workaround by removing usage of QDiallog::exec.
|
||||
if (QApplication::activeModalWidget()) {
|
||||
@@ -128,7 +128,7 @@ WalletModel* WalletController::getOrCreateWallet(std::unique_ptr<interfaces::Wal
|
||||
} else {
|
||||
removeAndDeleteWallet(wallet_model);
|
||||
}
|
||||
});
|
||||
}, Qt::QueuedConnection);
|
||||
|
||||
// Re-emit coinsSent signal from wallet model.
|
||||
connect(wallet_model, &WalletModel::coinsSent, this, &WalletController::coinsSent);
|
||||
|
||||
Reference in New Issue
Block a user