Skip to content

Commit b9971ae

Browse files
committed
wallet: Handle concurrent wallet loading
1 parent 09da0e4 commit b9971ae

File tree

1 file changed

+18
-2
lines changed

1 file changed

+18
-2
lines changed

src/wallet/wallet.cpp

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -99,9 +99,11 @@ std::unique_ptr<interfaces::Handler> HandleLoadWallet(LoadWalletFn load_wallet)
9999
return interfaces::MakeHandler([it] { LOCK(cs_wallets); g_load_wallet_fns.erase(it); });
100100
}
101101

102+
static Mutex g_loading_wallet_mutex;
102103
static Mutex g_wallet_release_mutex;
103104
static std::condition_variable g_wallet_release_cv;
104-
static std::set<std::string> g_unloading_wallet_set;
105+
static std::set<std::string> g_loading_wallet_set GUARDED_BY(g_loading_wallet_mutex);
106+
static std::set<std::string> g_unloading_wallet_set GUARDED_BY(g_wallet_release_mutex);
105107

106108
// Custom deleter for shared_ptr<CWallet>.
107109
static void ReleaseWallet(CWallet* wallet)
@@ -145,7 +147,8 @@ void UnloadWallet(std::shared_ptr<CWallet>&& wallet)
145147
}
146148
}
147149

148-
std::shared_ptr<CWallet> LoadWallet(interfaces::Chain& chain, const WalletLocation& location, bilingual_str& error, std::vector<bilingual_str>& warnings)
150+
namespace {
151+
std::shared_ptr<CWallet> LoadWalletInternal(interfaces::Chain& chain, const WalletLocation& location, bilingual_str& error, std::vector<bilingual_str>& warnings)
149152
{
150153
try {
151154
if (!CWallet::Verify(chain, location, error, warnings)) {
@@ -166,6 +169,19 @@ std::shared_ptr<CWallet> LoadWallet(interfaces::Chain& chain, const WalletLocati
166169
return nullptr;
167170
}
168171
}
172+
} // namespace
173+
174+
std::shared_ptr<CWallet> LoadWallet(interfaces::Chain& chain, const WalletLocation& location, bilingual_str& error, std::vector<bilingual_str>& warnings)
175+
{
176+
auto result = WITH_LOCK(g_loading_wallet_mutex, return g_loading_wallet_set.insert(location.GetName()));
177+
if (!result.second) {
178+
error = Untranslated("Wallet already being loading.");
179+
return nullptr;
180+
}
181+
auto wallet = LoadWalletInternal(chain, location, error, warnings);
182+
WITH_LOCK(g_loading_wallet_mutex, g_loading_wallet_set.erase(result.first));
183+
return wallet;
184+
}
169185

170186
std::shared_ptr<CWallet> LoadWallet(interfaces::Chain& chain, const std::string& name, bilingual_str& error, std::vector<bilingual_str>& warnings)
171187
{

0 commit comments

Comments
 (0)