UnlockNotification should hold mutex when calling condvar

This commit is contained in:
Thom Chiovoloni 2020-04-15 12:05:31 -07:00 committed by Thom Chiovoloni
parent c9ef5bd63c
commit 45fd77ee43

View File

@ -26,12 +26,13 @@ impl UnlockNotification {
} }
} }
fn fired(&mut self) { fn fired(&self) {
*self.mutex.lock().unwrap() = true; let mut flag = self.mutex.lock().unwrap();
*flag = true;
self.cond.notify_one(); self.cond.notify_one();
} }
fn wait(&mut self) { fn wait(&self) {
let mut fired = self.mutex.lock().unwrap(); let mut fired = self.mutex.lock().unwrap();
while !*fired { while !*fired {
fired = self.cond.wait(fired).unwrap(); fired = self.cond.wait(fired).unwrap();
@ -43,12 +44,9 @@ impl UnlockNotification {
#[cfg(feature = "unlock_notify")] #[cfg(feature = "unlock_notify")]
unsafe extern "C" fn unlock_notify_cb(ap_arg: *mut *mut c_void, n_arg: c_int) { unsafe extern "C" fn unlock_notify_cb(ap_arg: *mut *mut c_void, n_arg: c_int) {
use std::slice::from_raw_parts; use std::slice::from_raw_parts;
let args = from_raw_parts(ap_arg, n_arg as usize); let args = from_raw_parts(ap_arg as *const &UnlockNotification, n_arg as usize);
for arg in args { for un in args {
let _ = catch_unwind(|| { let _ = catch_unwind(std::panic::AssertUnwindSafe(|| un.fired()));
let un: &mut UnlockNotification = &mut *(*arg as *mut UnlockNotification);
un.fired()
});
} }
} }
@ -73,12 +71,12 @@ pub unsafe fn is_locked(db: *mut ffi::sqlite3, rc: c_int) -> bool {
/// back the current transaction (if any). /// back the current transaction (if any).
#[cfg(feature = "unlock_notify")] #[cfg(feature = "unlock_notify")]
pub unsafe fn wait_for_unlock_notify(db: *mut ffi::sqlite3) -> c_int { pub unsafe fn wait_for_unlock_notify(db: *mut ffi::sqlite3) -> c_int {
let mut un = UnlockNotification::new(); let un = UnlockNotification::new();
/* Register for an unlock-notify callback. */ /* Register for an unlock-notify callback. */
let rc = ffi::sqlite3_unlock_notify( let rc = ffi::sqlite3_unlock_notify(
db, db,
Some(unlock_notify_cb), Some(unlock_notify_cb),
&mut un as *mut UnlockNotification as *mut c_void, &un as *const UnlockNotification as *mut c_void,
); );
debug_assert!( debug_assert!(
rc == ffi::SQLITE_LOCKED || rc == ffi::SQLITE_LOCKED_SHAREDCACHE || rc == ffi::SQLITE_OK rc == ffi::SQLITE_LOCKED || rc == ffi::SQLITE_LOCKED_SHAREDCACHE || rc == ffi::SQLITE_OK