Merge bitcoin/bitcoin#25491: wallet: use Mutex for g_sqlite_mutex instead of GlobalMutex

4163093d63 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 4163093d63
  hebasto:
    re-ACK 4163093d63
  TheCharlatan:
    ACK 4163093d63

Tree-SHA512: 4913bcb8437ecf0e6b6cb781d02a6d24ffb4bf3e2e1899fa60785eab41c4c65dbdd9600bcb696290c873661b873ad61e5a4c4f205b7e66fdef2ae17c676cd12f
This commit is contained in:
Andrew Chow 2023-03-06 10:42:17 -05:00
commit dddc936d83
No known key found for this signature in database
GPG key ID: 17565732E08E5E41
2 changed files with 16 additions and 4 deletions

View file

@ -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);

View file

@ -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;