Page Menu
Home
Phabricator
Search
Configure Global Search
Log In
Files
F13115612
D7699.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Flag For Later
Size
10 KB
Subscribers
None
D7699.diff
View Options
diff --git a/src/dummywallet.cpp b/src/dummywallet.cpp
--- a/src/dummywallet.cpp
+++ b/src/dummywallet.cpp
@@ -13,7 +13,9 @@
namespace interfaces {
class Chain;
-}
+class Handler;
+class Wallet;
+} // namespace interfaces
class DummyWalletInit : public WalletInitInterface {
public:
@@ -68,9 +70,14 @@
throw std::logic_error("Wallet function called in non-wallet build.");
}
-namespace interfaces {
+using LoadWalletFn =
+ std::function<void(std::unique_ptr<interfaces::Wallet> wallet)>;
+std::unique_ptr<interfaces::Handler>
+HandleLoadWallet(LoadWalletFn load_wallet) {
+ throw std::logic_error("Wallet function called in non-wallet build.");
+}
-class Wallet;
+namespace interfaces {
std::unique_ptr<Wallet> MakeWallet(const std::shared_ptr<CWallet> &wallet) {
throw std::logic_error("Wallet function called in non-wallet build.");
diff --git a/src/interfaces/chain.h b/src/interfaces/chain.h
--- a/src/interfaces/chain.h
+++ b/src/interfaces/chain.h
@@ -49,7 +49,7 @@
//! asynchronously
//! (https://github.com/bitcoin/bitcoin/pull/10973#issuecomment-380101269).
//!
-//! * The initMessages() and loadWallet() methods which the wallet uses to send
+//! * The initMessage() and showProgress() methods which the wallet uses to send
//! notifications to the GUI should go away when GUI and wallet can directly
//! communicate with each other without going through the node
//! (https://github.com/bitcoin/bitcoin/pull/15288#discussion_r253321096).
@@ -215,9 +215,6 @@
//! Send init error.
virtual void initError(const std::string &message) = 0;
- //! Send wallet load notification to the GUI.
- virtual void loadWallet(std::unique_ptr<Wallet> wallet) = 0;
-
//! Send progress indicator.
virtual void showProgress(const std::string &title, int progress,
bool resume_possible) = 0;
diff --git a/src/interfaces/chain.cpp b/src/interfaces/chain.cpp
--- a/src/interfaces/chain.cpp
+++ b/src/interfaces/chain.cpp
@@ -366,9 +366,6 @@
void initError(const std::string &message) override {
InitError(message);
}
- void loadWallet(std::unique_ptr<Wallet> wallet) override {
- ::uiInterface.LoadWallet(wallet);
- }
void showProgress(const std::string &title, int progress,
bool resume_possible) override {
::uiInterface.ShowProgress(title, progress, resume_possible);
diff --git a/src/interfaces/handler.h b/src/interfaces/handler.h
--- a/src/interfaces/handler.h
+++ b/src/interfaces/handler.h
@@ -5,6 +5,7 @@
#ifndef BITCOIN_INTERFACES_HANDLER_H
#define BITCOIN_INTERFACES_HANDLER_H
+#include <functional>
#include <memory>
namespace boost {
@@ -29,6 +30,9 @@
//! Return handler wrapping a boost signal connection.
std::unique_ptr<Handler> MakeHandler(boost::signals2::connection connection);
+//! Return handler wrapping a cleanup function.
+std::unique_ptr<Handler> MakeHandler(std::function<void()> cleanup);
+
} // namespace interfaces
#endif // BITCOIN_INTERFACES_HANDLER_H
diff --git a/src/interfaces/handler.cpp b/src/interfaces/handler.cpp
--- a/src/interfaces/handler.cpp
+++ b/src/interfaces/handler.cpp
@@ -22,10 +22,35 @@
boost::signals2::scoped_connection m_connection;
};
+ class CleanupHandler : public Handler {
+ public:
+ explicit CleanupHandler(std::function<void()> cleanup)
+ : m_cleanup(std::move(cleanup)) {}
+ ~CleanupHandler() override {
+ if (!m_cleanup) {
+ return;
+ }
+ m_cleanup();
+ m_cleanup = nullptr;
+ }
+ void disconnect() override {
+ if (!m_cleanup) {
+ return;
+ }
+ m_cleanup();
+ m_cleanup = nullptr;
+ }
+ std::function<void()> m_cleanup;
+ };
+
} // namespace
std::unique_ptr<Handler> MakeHandler(boost::signals2::connection connection) {
return std::make_unique<HandlerImpl>(std::move(connection));
}
+std::unique_ptr<Handler> MakeHandler(std::function<void()> cleanup) {
+ return std::make_unique<CleanupHandler>(std::move(cleanup));
+}
+
} // namespace interfaces
diff --git a/src/interfaces/node.cpp b/src/interfaces/node.cpp
--- a/src/interfaces/node.cpp
+++ b/src/interfaces/node.cpp
@@ -53,11 +53,11 @@
const std::string &name, std::string &error,
std::vector<std::string> &warnings,
std::shared_ptr<CWallet> &result);
+std::unique_ptr<interfaces::Handler>
+HandleLoadWallet(interfaces::Node::LoadWalletFn load_wallet);
namespace interfaces {
-class Wallet;
-
namespace {
class NodeImpl : public Node {
@@ -312,10 +312,7 @@
return MakeHandler(::uiInterface.ShowProgress_connect(fn));
}
std::unique_ptr<Handler> handleLoadWallet(LoadWalletFn fn) override {
- return MakeHandler(::uiInterface.LoadWallet_connect(
- [fn](std::unique_ptr<Wallet> &wallet) {
- fn(std::move(wallet));
- }));
+ return HandleLoadWallet(std::move(fn));
}
std::unique_ptr<Handler> handleNotifyNumConnectionsChanged(
NotifyNumConnectionsChangedFn fn) override {
diff --git a/src/qt/bitcoingui.cpp b/src/qt/bitcoingui.cpp
--- a/src/qt/bitcoingui.cpp
+++ b/src/qt/bitcoingui.cpp
@@ -685,10 +685,12 @@
if (!walletFrame) {
return;
}
+ if (!walletFrame->addWallet(walletModel)) {
+ return;
+ }
const QString display_name = walletModel->getDisplayName();
setWalletActionsEnabled(true);
rpcConsole->addWallet(walletModel);
- walletFrame->addWallet(walletModel);
m_wallet_selector->addItem(display_name, QVariant::fromValue(walletModel));
if (m_wallet_selector->count() == 2) {
m_wallet_selector_label_action->setVisible(true);
diff --git a/src/ui_interface.h b/src/ui_interface.h
--- a/src/ui_interface.h
+++ b/src/ui_interface.h
@@ -17,10 +17,6 @@
}
} // namespace boost
-namespace interfaces {
-class Wallet;
-} // namespace interfaces
-
/** General change type (added, updated, removed). */
enum ChangeType { CT_NEW, CT_UPDATED, CT_DELETED };
@@ -118,10 +114,6 @@
*/
ADD_SIGNALS_DECL_WRAPPER(NotifyAlertChanged, void, );
- /** A wallet has been loaded. */
- ADD_SIGNALS_DECL_WRAPPER(LoadWallet, void,
- std::unique_ptr<interfaces::Wallet> &wallet);
-
/**
* Show progress e.g. for verifychain.
* resume_possible indicates shutting down now will result in the current
diff --git a/src/ui_interface.cpp b/src/ui_interface.cpp
--- a/src/ui_interface.cpp
+++ b/src/ui_interface.cpp
@@ -23,7 +23,6 @@
NotifyNetworkActiveChanged;
boost::signals2::signal<CClientUIInterface::NotifyAlertChangedSig>
NotifyAlertChanged;
- boost::signals2::signal<CClientUIInterface::LoadWalletSig> LoadWallet;
boost::signals2::signal<CClientUIInterface::ShowProgressSig> ShowProgress;
boost::signals2::signal<CClientUIInterface::NotifyBlockTipSig>
NotifyBlockTip;
@@ -46,7 +45,6 @@
ADD_SIGNALS_IMPL_WRAPPER(NotifyNumConnectionsChanged);
ADD_SIGNALS_IMPL_WRAPPER(NotifyNetworkActiveChanged);
ADD_SIGNALS_IMPL_WRAPPER(NotifyAlertChanged);
-ADD_SIGNALS_IMPL_WRAPPER(LoadWallet);
ADD_SIGNALS_IMPL_WRAPPER(ShowProgress);
ADD_SIGNALS_IMPL_WRAPPER(NotifyBlockTip);
ADD_SIGNALS_IMPL_WRAPPER(NotifyHeaderTip);
@@ -75,10 +73,6 @@
void CClientUIInterface::NotifyAlertChanged() {
return g_ui_signals.NotifyAlertChanged();
}
-void CClientUIInterface::LoadWallet(
- std::unique_ptr<interfaces::Wallet> &wallet) {
- return g_ui_signals.LoadWallet(wallet);
-}
void CClientUIInterface::ShowProgress(const std::string &title, int nProgress,
bool resume_possible) {
return g_ui_signals.ShowProgress(title, nProgress, resume_possible);
diff --git a/src/wallet/wallet.h b/src/wallet/wallet.h
--- a/src/wallet/wallet.h
+++ b/src/wallet/wallet.h
@@ -37,6 +37,9 @@
#include <boost/signals2/signal.hpp>
+using LoadWalletFn =
+ std::function<void(std::unique_ptr<interfaces::Wallet> wallet)>;
+
//! Explicitly unload and delete the wallet.
//! Blocks the current thread after signaling the unload intent so that all
//! wallet clients release the wallet.
@@ -54,6 +57,7 @@
const WalletLocation &location,
std::string &error,
std::vector<std::string> &warnings);
+std::unique_ptr<interfaces::Handler> HandleLoadWallet(LoadWalletFn load_wallet);
enum class WalletCreationStatus { SUCCESS, CREATION_FAILED, ENCRYPTION_FAILED };
@@ -64,7 +68,6 @@
const std::string &name, std::string &error,
std::vector<std::string> &warnings,
std::shared_ptr<CWallet> &result);
-
//! -paytxfee default
constexpr Amount DEFAULT_PAY_TX_FEE = Amount::zero();
//! -fallbackfee default
diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp
--- a/src/wallet/wallet.cpp
+++ b/src/wallet/wallet.cpp
@@ -45,6 +45,7 @@
static RecursiveMutex cs_wallets;
static std::vector<std::shared_ptr<CWallet>> vpwallets GUARDED_BY(cs_wallets);
+static std::list<LoadWalletFn> g_load_wallet_fns GUARDED_BY(cs_wallets);
bool AddWallet(const std::shared_ptr<CWallet> &wallet) {
LOCK(cs_wallets);
@@ -92,6 +93,17 @@
return nullptr;
}
+std::unique_ptr<interfaces::Handler>
+HandleLoadWallet(LoadWalletFn load_wallet) {
+ LOCK(cs_wallets);
+ auto it = g_load_wallet_fns.emplace(g_load_wallet_fns.end(),
+ std::move(load_wallet));
+ return interfaces::MakeHandler([it] {
+ LOCK(cs_wallets);
+ g_load_wallet_fns.erase(it);
+ });
+}
+
static Mutex g_wallet_release_mutex;
static std::condition_variable g_wallet_release_cv;
static std::set<std::string> g_unloading_wallet_set;
@@ -4370,7 +4382,12 @@
}
}
- chain.loadWallet(interfaces::MakeWallet(walletInstance));
+ {
+ LOCK(cs_wallets);
+ for (auto &load_wallet : g_load_wallet_fns) {
+ load_wallet(interfaces::MakeWallet(walletInstance));
+ }
+ }
// Register with the validation interface. It's ok to do this after rescan
// since we're still holding locked_chain.
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Sat, Mar 1, 11:33 (8 h, 42 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
5187628
Default Alt Text
D7699.diff (10 KB)
Attached To
D7699: wallet: Fix unique_ptr usage in boost::signals2
Event Timeline
Log In to Comment