Skip to content

Commit dddc936

Browse files
committed
Merge bitcoin/bitcoin#25491: wallet: use Mutex for g_sqlite_mutex instead of GlobalMutex
4163093 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 4163093 hebasto: re-ACK 4163093 TheCharlatan: ACK 4163093 Tree-SHA512: 4913bcb8437ecf0e6b6cb781d02a6d24ffb4bf3e2e1899fa60785eab41c4c65dbdd9600bcb696290c873661b873ad61e5a4c4f205b7e66fdef2ae17c676cd12f
2 parents 2a0c05d + 4163093 commit dddc936

File tree

2 files changed

+16
-4
lines changed

2 files changed

+16
-4
lines changed

src/wallet/sqlite.cpp

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,9 +23,6 @@
2323
namespace wallet {
2424
static constexpr int32_t WALLET_SCHEMA_VERSION = 0;
2525

26-
static GlobalMutex g_sqlite_mutex;
27-
static int g_sqlite_count GUARDED_BY(g_sqlite_mutex) = 0;
28-
2926
static void ErrorLogCallback(void* arg, int code, const char* msg)
3027
{
3128
// 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
8380
}
8481
}
8582

83+
Mutex SQLiteDatabase::g_sqlite_mutex;
84+
int SQLiteDatabase::g_sqlite_count = 0;
85+
8686
SQLiteDatabase::SQLiteDatabase(const fs::path& dir_path, const fs::path& file_path, const DatabaseOptions& options, bool mock)
8787
: 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)
8888
{
@@ -145,6 +145,8 @@ SQLiteDatabase::~SQLiteDatabase()
145145

146146
void SQLiteDatabase::Cleanup() noexcept
147147
{
148+
AssertLockNotHeld(g_sqlite_mutex);
149+
148150
Close();
149151

150152
LOCK(g_sqlite_mutex);

src/wallet/sqlite.h

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
#ifndef BITCOIN_WALLET_SQLITE_H
66
#define BITCOIN_WALLET_SQLITE_H
77

8+
#include <sync.h>
89
#include <wallet/db.h>
910

1011
#include <sqlite3.h>
@@ -69,7 +70,16 @@ class SQLiteDatabase : public WalletDatabase
6970

7071
const std::string m_file_path;
7172

72-
void Cleanup() noexcept;
73+
/**
74+
* This mutex protects SQLite initialization and shutdown.
75+
* sqlite3_config() and sqlite3_shutdown() are not thread-safe (sqlite3_initialize() is).
76+
* Concurrent threads that execute SQLiteDatabase::SQLiteDatabase() should have just one
77+
* of them do the init and the rest wait for it to complete before all can proceed.
78+
*/
79+
static Mutex g_sqlite_mutex;
80+
static int g_sqlite_count GUARDED_BY(g_sqlite_mutex);
81+
82+
void Cleanup() noexcept EXCLUSIVE_LOCKS_REQUIRED(!g_sqlite_mutex);
7383

7484
public:
7585
SQLiteDatabase() = delete;

0 commit comments

Comments
 (0)