diff options
author | Andrew Chow <github@achow101.com> | 2023-03-06 10:42:17 -0500 |
---|---|---|
committer | Andrew Chow <github@achow101.com> | 2023-03-06 10:50:10 -0500 |
commit | dddc936d838edbb30f877b54b1abd101eff76cad (patch) | |
tree | 15cb5a2aae268df6fcd0c1eaef21c28f8b7b34a8 /src/wallet | |
parent | 2a0c05defd32c37f083fa2cc890e03aecc451555 (diff) | |
parent | 4163093d6374e865dc57e33dbea0e7e359062e0a (diff) |
Merge bitcoin/bitcoin#25491: wallet: use Mutex for g_sqlite_mutex instead of GlobalMutex
4163093d6374e865dc57e33dbea0e7e359062e0a wallet: use Mutex for g_sqlite_mutex instead of GlobalMutex (Vasil Dimov)
Pull request description:
Using `Mutex` provides stronger guarantee than `GlobalMutex` wrt Clang's
thread safety analysis. Thus it is better to reduce the usage of
`GlobalMutex` in favor of `Mutex`.
Using `Mutex` for `g_sqlite_mutex` is ok because its usage is limited in
`wallet/sqlite.cpp` and it does not require propagating the negative
annotations to not relevant code.
ACKs for top commit:
achow101:
ACK 4163093d6374e865dc57e33dbea0e7e359062e0a
hebasto:
re-ACK 4163093d6374e865dc57e33dbea0e7e359062e0a
TheCharlatan:
ACK 4163093d6374e865dc57e33dbea0e7e359062e0a
Tree-SHA512: 4913bcb8437ecf0e6b6cb781d02a6d24ffb4bf3e2e1899fa60785eab41c4c65dbdd9600bcb696290c873661b873ad61e5a4c4f205b7e66fdef2ae17c676cd12f
Diffstat (limited to 'src/wallet')
-rw-r--r-- | src/wallet/sqlite.cpp | 8 | ||||
-rw-r--r-- | src/wallet/sqlite.h | 12 |
2 files changed, 16 insertions, 4 deletions
diff --git a/src/wallet/sqlite.cpp b/src/wallet/sqlite.cpp index 4af49db609..8d8a7ab2a2 100644 --- a/src/wallet/sqlite.cpp +++ b/src/wallet/sqlite.cpp @@ -23,9 +23,6 @@ namespace wallet { static constexpr int32_t WALLET_SCHEMA_VERSION = 0; -static GlobalMutex g_sqlite_mutex; -static int g_sqlite_count GUARDED_BY(g_sqlite_mutex) = 0; - static void ErrorLogCallback(void* arg, int code, const char* msg) { // From sqlite3_config() documentation for the SQLITE_CONFIG_LOG option: @@ -83,6 +80,9 @@ static void SetPragma(sqlite3* db, const std::string& key, const std::string& va } } +Mutex SQLiteDatabase::g_sqlite_mutex; +int SQLiteDatabase::g_sqlite_count = 0; + SQLiteDatabase::SQLiteDatabase(const fs::path& dir_path, const fs::path& file_path, const DatabaseOptions& options, bool mock) : WalletDatabase(), m_mock(mock), m_dir_path(fs::PathToString(dir_path)), m_file_path(fs::PathToString(file_path)), m_use_unsafe_sync(options.use_unsafe_sync) { @@ -145,6 +145,8 @@ SQLiteDatabase::~SQLiteDatabase() void SQLiteDatabase::Cleanup() noexcept { + AssertLockNotHeld(g_sqlite_mutex); + Close(); LOCK(g_sqlite_mutex); diff --git a/src/wallet/sqlite.h b/src/wallet/sqlite.h index c6745d7a7e..5745a1d4cf 100644 --- a/src/wallet/sqlite.h +++ b/src/wallet/sqlite.h @@ -5,6 +5,7 @@ #ifndef BITCOIN_WALLET_SQLITE_H #define BITCOIN_WALLET_SQLITE_H +#include <sync.h> #include <wallet/db.h> #include <sqlite3.h> @@ -69,7 +70,16 @@ private: const std::string m_file_path; - void Cleanup() noexcept; + /** + * This mutex protects SQLite initialization and shutdown. + * sqlite3_config() and sqlite3_shutdown() are not thread-safe (sqlite3_initialize() is). + * Concurrent threads that execute SQLiteDatabase::SQLiteDatabase() should have just one + * of them do the init and the rest wait for it to complete before all can proceed. + */ + static Mutex g_sqlite_mutex; + static int g_sqlite_count GUARDED_BY(g_sqlite_mutex); + + void Cleanup() noexcept EXCLUSIVE_LOCKS_REQUIRED(!g_sqlite_mutex); public: SQLiteDatabase() = delete; |