Skip to content

Commit 3123bad

Browse files
committed
Don't use mutex routines if unavailable
1 parent f39acd1 commit 3123bad

File tree

5 files changed

+43
-21
lines changed

5 files changed

+43
-21
lines changed

crates/core/src/lib.rs

+2
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ use core::ffi::{c_char, c_int};
1111

1212
use sqlite::ResultCode;
1313
use sqlite_nostd as sqlite;
14+
use util::SQLITE3_API;
1415

1516
mod bson;
1617
mod checkpoint;
@@ -43,6 +44,7 @@ pub extern "C" fn sqlite3_powersync_init(
4344
api: *mut sqlite::api_routines,
4445
) -> c_int {
4546
sqlite::EXTENSION_INIT2(api);
47+
unsafe { SQLITE3_API = api };
4648

4749
let result = init_extension(db);
4850

crates/core/src/sync/streaming_sync.rs

+4-8
Original file line numberDiff line numberDiff line change
@@ -237,7 +237,7 @@ impl StreamingSyncIteration {
237237
.into(),
238238
});
239239

240-
self.handle_checkpoint_applied(&checkpoint, event)?;
240+
self.handle_checkpoint_applied(event)?;
241241
}
242242
_ => {
243243
event.instructions.push(Instruction::LogLine {
@@ -331,7 +331,7 @@ impl StreamingSyncIteration {
331331
severity: LogSeverity::DEBUG,
332332
line: "Validated and applied checkpoint".into(),
333333
});
334-
self.handle_checkpoint_applied(target, event)?;
334+
self.handle_checkpoint_applied(event)?;
335335
}
336336
}
337337
}
@@ -438,16 +438,12 @@ impl StreamingSyncIteration {
438438
Ok(local_bucket_names)
439439
}
440440

441-
fn handle_checkpoint_applied(
442-
&mut self,
443-
target: &OwnedCheckpoint,
444-
event: &mut ActiveEvent,
445-
) -> Result<(), ResultCode> {
441+
fn handle_checkpoint_applied(&mut self, event: &mut ActiveEvent) -> Result<(), ResultCode> {
446442
event.instructions.push(Instruction::DidCompleteSync {});
447443

448444
let now = self.adapter.now()?;
449445
self.status.update(
450-
|status| status.applied_checkpoint(target, now),
446+
|status| status.applied_checkpoint(now),
451447
&mut event.instructions,
452448
);
453449

crates/core/src/sync/sync_status.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ impl DownloadSyncStatus {
6969
self.debug_assert_priority_status_is_sorted();
7070
}
7171

72-
pub fn applied_checkpoint(&mut self, applied: &OwnedCheckpoint, now: Timestamp) {
72+
pub fn applied_checkpoint(&mut self, now: Timestamp) {
7373
self.downloading = None;
7474
self.priority_status.clear();
7575

crates/core/src/util.rs

+34-11
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,16 @@
11
extern crate alloc;
22

3-
use core::ptr::null_mut;
3+
use core::ptr::{self, null_mut};
44

55
use alloc::format;
66
use alloc::string::String;
77

88
use lock_api::{GuardSend, Mutex as MutexApi, RawMutex};
99
use serde::de::Visitor;
1010
use sqlite_nostd::bindings::SQLITE_MUTEX_FAST;
11-
use sqlite_nostd::{
12-
sqlite3_mutex_alloc, sqlite3_mutex_enter, sqlite3_mutex_free, sqlite3_mutex_leave,
13-
sqlite3_mutex_try, Connection, Context,
14-
};
11+
use sqlite_nostd::{api_routines, Connection, Context};
1512

1613
use crate::error::SQLiteError;
17-
#[cfg(feature = "getrandom")]
1814
use crate::sqlite;
1915
use crate::sqlite::bindings::sqlite3_mutex;
2016

@@ -118,10 +114,21 @@ pub struct SqliteMutex {
118114
ptr: *mut sqlite3_mutex,
119115
}
120116

117+
// We always invoke mutex APIs through the api routines, even when we link the rest of SQLite
118+
// statically.
119+
// The reason is that it's possible to omit the mutex code (in which case we don't want to link
120+
// undefined symbols).
121+
pub(crate) static mut SQLITE3_API: *mut api_routines = ptr::null_mut();
122+
121123
impl SqliteMutex {
122124
pub fn new() -> Self {
125+
let native_alloc = unsafe { (*SQLITE3_API).mutex_alloc };
126+
123127
Self {
124-
ptr: sqlite3_mutex_alloc(SQLITE_MUTEX_FAST as i32),
128+
ptr: match native_alloc {
129+
None => null_mut(),
130+
Some(mutex_alloc) => unsafe { mutex_alloc(SQLITE_MUTEX_FAST as i32) },
131+
},
125132
}
126133
}
127134
}
@@ -132,21 +139,37 @@ unsafe impl RawMutex for SqliteMutex {
132139
type GuardMarker = GuardSend;
133140

134141
fn lock(&self) {
135-
sqlite3_mutex_enter(self.ptr);
142+
if self.ptr.is_null() {
143+
// Disable mutex code
144+
} else {
145+
unsafe { (*SQLITE3_API).mutex_enter.unwrap_unchecked()(self.ptr) }
146+
}
136147
}
137148

138149
fn try_lock(&self) -> bool {
139-
sqlite3_mutex_try(self.ptr) == 0
150+
if self.ptr.is_null() {
151+
// Disable mutex code
152+
true
153+
} else {
154+
let res = unsafe { (*SQLITE3_API).mutex_try.unwrap_unchecked()(self.ptr) };
155+
res == 0
156+
}
140157
}
141158

142159
unsafe fn unlock(&self) {
143-
sqlite3_mutex_leave(self.ptr);
160+
if self.ptr.is_null() {
161+
// Disable mutex code
162+
} else {
163+
unsafe { (*SQLITE3_API).mutex_leave.unwrap_unchecked()(self.ptr) }
164+
}
144165
}
145166
}
146167

147168
impl Drop for SqliteMutex {
148169
fn drop(&mut self) {
149-
sqlite3_mutex_free(self.ptr);
170+
if !self.ptr.is_null() {
171+
unsafe { (*SQLITE3_API).mutex_free.unwrap_unchecked()(self.ptr) };
172+
}
150173
}
151174
}
152175

crates/shell/build.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
12
fn main() {
23
let mut cfg = cc::Build::new();
34

@@ -7,7 +8,7 @@ fn main() {
78
cfg.include("../sqlite/sqlite");
89

910
// General SQLite options
10-
cfg.define("SQLITE_THREADSAFE", Some("1"));
11+
cfg.define("SQLITE_THREADSAFE", Some("0"));
1112
cfg.define("SQLITE_ENABLE_BYTECODE_VTAB", Some("1"));
1213

1314
// Call core_init() in main.rs

0 commit comments

Comments
 (0)