Introduce is_locked

This commit is contained in:
gwenn 2018-03-31 10:22:19 +02:00
parent cccdf9735f
commit a0151f9073
3 changed files with 23 additions and 11 deletions

View File

@ -875,7 +875,10 @@ impl InnerConnection {
&mut c_stmt, &mut c_stmt,
ptr::null_mut(), ptr::null_mut(),
); );
rc = unlock_notify::wait_for_unlock_notify(self.db, rc); if !unlock_notify::is_locked(self.db, rc) {
break;
}
rc = unlock_notify::wait_for_unlock_notify(self.db);
if rc != ffi::SQLITE_OK { if rc != ffi::SQLITE_OK {
break; break;
} }

View File

@ -34,7 +34,10 @@ impl RawStatement {
let mut rc; let mut rc;
loop { loop {
rc = unsafe { ffi::sqlite3_step(self.0) }; rc = unsafe { ffi::sqlite3_step(self.0) };
rc = unlock_notify::wait_for_unlock_notify(self.1, rc); if !unlock_notify::is_locked(self.1, rc) {
break;
}
rc = unlock_notify::wait_for_unlock_notify(self.1);
if rc != ffi::SQLITE_OK { if rc != ffi::SQLITE_OK {
break; break;
} }

View File

@ -48,6 +48,14 @@ unsafe extern "C" fn unlock_notify_cb(ap_arg: *mut *mut c_void, n_arg: c_int) {
} }
} }
#[cfg(feature = "unlock_notify")]
pub fn is_locked(db: *mut ffi::sqlite3, rc: c_int) -> bool {
return rc == ffi::SQLITE_LOCKED_SHAREDCACHE || (rc & 0xFF) == ffi::SQLITE_LOCKED && unsafe {
ffi::sqlite3_extended_errcode(db)
}
== ffi::SQLITE_LOCKED_SHAREDCACHE;
}
/// This function assumes that an SQLite API call (either `sqlite3_prepare_v2()` /// This function assumes that an SQLite API call (either `sqlite3_prepare_v2()`
/// or `sqlite3_step()`) has just returned `SQLITE_LOCKED`. The argument is the /// or `sqlite3_step()`) has just returned `SQLITE_LOCKED`. The argument is the
/// associated database connection. /// associated database connection.
@ -61,14 +69,7 @@ unsafe extern "C" fn unlock_notify_cb(ap_arg: *mut *mut c_void, n_arg: c_int) {
/// this case the caller should not retry the operation and should roll /// this case the caller should not retry the operation and should roll
/// back the current transaction (if any). /// back the current transaction (if any).
#[cfg(feature = "unlock_notify")] #[cfg(feature = "unlock_notify")]
pub fn wait_for_unlock_notify(db: *mut ffi::sqlite3, rc: c_int) -> c_int { pub fn wait_for_unlock_notify(db: *mut ffi::sqlite3) -> c_int {
if rc == ffi::SQLITE_LOCKED {
if unsafe { ffi::sqlite3_extended_errcode(self.1) } != ffi::SQLITE_LOCKED_SHAREDCACHE {
return rc;
}
} else if rc != ffi::SQLITE_LOCKED_SHAREDCACHE {
return rc;
}
let mut un = UnlockNotification::new(); let mut un = UnlockNotification::new();
/* Register for an unlock-notify callback. */ /* Register for an unlock-notify callback. */
let rc = unsafe { let rc = unsafe {
@ -88,7 +89,12 @@ pub fn wait_for_unlock_notify(db: *mut ffi::sqlite3, rc: c_int) -> c_int {
} }
#[cfg(not(feature = "unlock_notify"))] #[cfg(not(feature = "unlock_notify"))]
pub fn wait_for_unlock_notify(_db: *mut ffi::sqlite3, _code: c_int) -> c_int { pub fn is_locked(_db: *mut ffi::sqlite3, _rc: c_int) -> bool {
unreachable!()
}
#[cfg(not(feature = "unlock_notify"))]
pub fn wait_for_unlock_notify(_db: *mut ffi::sqlite3) -> c_int {
unreachable!() unreachable!()
} }