11extern crate alloc;
22
3- use core:: ptr:: null_mut;
3+ use core:: ptr:: { self , null_mut} ;
44
55use alloc:: format;
66use alloc:: string:: String ;
77
88use lock_api:: { GuardSend , Mutex as MutexApi , RawMutex } ;
99use serde:: de:: Visitor ;
1010use 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
1613use crate :: error:: SQLiteError ;
17- #[ cfg( feature = "getrandom" ) ]
1814use crate :: sqlite;
1915use 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+
121123impl 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
147168impl 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
0 commit comments