Skip to content

Commit 60b42b6

Browse files
cleanup transaction hooks on close
1 parent 70340d5 commit 60b42b6

6 files changed

+31
-12
lines changed

cpp/ConnectionPool.cpp

+3-3
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ ConnectionPool::ConnectionPool(std::string dbName, std::string docPath,
1919

2020
onContextCallback = nullptr;
2121
isConcurrencyEnabled = maxReads > 0;
22+
isClosed = false;
2223

2324
readConnections = new ConnectionState *[maxReads];
2425
// Open the read connections
@@ -169,9 +170,8 @@ void ConnectionPool::closeContext(ConnectionLockId contextId) {
169170
}
170171

171172
void ConnectionPool::closeAll() {
172-
// Prevent this pointer from being used if closed
173-
rollbackPayload.dbName = NULL;
174-
commitPayload.dbName = NULL;
173+
isClosed = true;
174+
// Stop any callbacks
175175
sqlite3_commit_hook(writeConnection.connection,
176176
NULL, NULL);
177177
sqlite3_rollback_hook(writeConnection.connection,

cpp/ConnectionPool.h

+4-2
Original file line numberDiff line numberDiff line change
@@ -66,15 +66,17 @@ class ConnectionPool {
6666
std::vector<ConnectionLockId> writeQueue;
6767

6868
// Cached constant payloads for c style commit/rollback callbacks
69-
TransactionCallbackPayload commitPayload;
70-
TransactionCallbackPayload rollbackPayload;
69+
const TransactionCallbackPayload commitPayload;
70+
const TransactionCallbackPayload rollbackPayload;
7171

7272
void (*onContextCallback)(std::string, ConnectionLockId);
7373
void (*onCommitCallback)(const TransactionCallbackPayload *);
7474

7575
bool isConcurrencyEnabled;
7676

7777
public:
78+
bool isClosed;
79+
7880
ConnectionPool(std::string dbName, std::string docPath,
7981
unsigned int numReadConnections);
8082
~ConnectionPool();

cpp/ConnectionState.cpp

-1
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,6 @@ std::future<void> ConnectionState::refreshSchema() {
5959

6060
void ConnectionState::close() {
6161
{
62-
// Now signal the thread to stop and notify it
6362
std::unique_lock<std::mutex> g(workQueueMutex);
6463
// prevent any new work from being queued
6564
isClosed = true;

cpp/bindings.cpp

+12-6
Original file line numberDiff line numberDiff line change
@@ -77,19 +77,25 @@ void transactionFinalizerHandler(const TransactionCallbackPayload *payload) {
7777
* This function triggers an async invocation to call watch callbacks,
7878
* avoiding holding SQLite up.
7979
*/
80-
invoker->invokeAsync([payload] {
80+
81+
// Make a copy of the payload data, this avoids a potential race condition
82+
// where the async invocation might occur after closing a connection
83+
auto dbName = std::make_shared<std::string>(*payload->dbName);
84+
int event = payload->event;
85+
invoker->invokeAsync([dbName, event] {
8186
try {
82-
// Prevent trying to create a JSI string for a potentially closed DB
83-
if (payload == NULL || payload->dbName == NULL) {
87+
88+
ConnectionPool* connection = getConnection(*dbName);
89+
if (connection == nullptr || connection->isClosed) {
8490
return;
8591
}
86-
92+
8793
auto global = runtime->global();
8894
jsi::Function handlerFunction = global.getPropertyAsFunction(
8995
*runtime, "triggerTransactionFinalizerHook");
9096

91-
auto jsiDbName = jsi::String::createFromAscii(*runtime, *payload->dbName);
92-
auto jsiEventType = jsi::Value((int)payload->event);
97+
auto jsiDbName = jsi::String::createFromAscii(*runtime, *dbName);
98+
auto jsiEventType = jsi::Value(event);
9399
handlerFunction.call(*runtime, move(jsiDbName), move(jsiEventType));
94100
} catch (jsi::JSINativeException e) {
95101
std::cout << e.what() << std::endl;

cpp/sqliteBridge.cpp

+10
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,16 @@ SQLiteOPResult generateNotOpenResult(std::string const &dbName) {
3232
};
3333
}
3434

35+
ConnectionPool *getConnection(std::string const dbName) {
36+
if (dbMap.count(dbName) == 0) {
37+
// Connection is already closed
38+
return nullptr;
39+
}
40+
41+
return dbMap[dbName];
42+
}
43+
44+
3545
/**
3646
* Opens SQL database with default settings
3747
*/

cpp/sqliteBridge.h

+2
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,8 @@ SQLiteOPResult sqliteCloseDb(string const dbName);
4040

4141
void sqliteCloseAll();
4242

43+
ConnectionPool *getConnection(std::string const dbName);
44+
4345
SQLiteOPResult sqliteRemoveDb(string const dbName, string const docPath);
4446

4547
/**

0 commit comments

Comments
 (0)