diff --git a/src/qt/bitcoin.cpp b/src/qt/bitcoin.cpp --- a/src/qt/bitcoin.cpp +++ b/src/qt/bitcoin.cpp @@ -217,6 +217,8 @@ #ifdef ENABLE_WALLET delete paymentServer; paymentServer = nullptr; + delete m_wallet_controller; + m_wallet_controller = nullptr; #endif delete optionsModel; optionsModel = nullptr; @@ -331,18 +333,20 @@ qDebug() << __func__ << ": Requesting shutdown"; startThread(); window->hide(); + // Must disconnect node signals otherwise current thread can deadlock since + // no event loop is running. + window->unsubscribeFromCoreSignals(); + // Request node shutdown, which can interrupt long operations, like + // rescanning a wallet. + m_node.startShutdown(); + // Unsetting the client model can cause the current thread to wait for node + // to complete an operation, like wait for a RPC execution to complate. window->setClientModel(nullptr); pollShutdownTimer->stop(); -#ifdef ENABLE_WALLET - delete m_wallet_controller; - m_wallet_controller = nullptr; -#endif delete clientModel; clientModel = nullptr; - m_node.startShutdown(); - // Request shutdown from core thread Q_EMIT requestedShutdown(); } diff --git a/src/qt/bitcoingui.h b/src/qt/bitcoingui.h --- a/src/qt/bitcoingui.h +++ b/src/qt/bitcoingui.h @@ -94,6 +94,9 @@ #endif // ENABLE_WALLET bool enableWallet = false; + /** Disconnect core signals from GUI client */ + void unsubscribeFromCoreSignals(); + protected: void changeEvent(QEvent *e) override; void closeEvent(QCloseEvent *event) override; @@ -183,8 +186,6 @@ /** Connect core signals to GUI client */ void subscribeToCoreSignals(); - /** Disconnect core signals from GUI client */ - void unsubscribeFromCoreSignals(); /** Update UI with latest network info from model. */ void updateNetworkState(); diff --git a/src/validationinterface.cpp b/src/validationinterface.cpp --- a/src/validationinterface.cpp +++ b/src/validationinterface.cpp @@ -11,8 +11,8 @@ #include #include #include -#include #include +#include #include @@ -140,7 +140,9 @@ } void UnregisterValidationInterface(CValidationInterface *pwalletIn) { - g_signals.m_internals->m_connMainSignals.erase(pwalletIn); + if (g_signals.m_internals) { + g_signals.m_internals->m_connMainSignals.erase(pwalletIn); + } } void UnregisterAllValidationInterfaces() {