sqlx_sqlite/statement/
unlock_notify.rs1use std::ffi::c_void;
2use std::os::raw::c_int;
3use std::slice;
4use std::sync::{Condvar, Mutex};
5
6use libsqlite3_sys::{sqlite3, sqlite3_unlock_notify, SQLITE_OK};
7
8use crate::SqliteError;
9
10pub unsafe fn wait(conn: *mut sqlite3) -> Result<(), SqliteError> {
12 let notify = Notify::new();
13
14 if sqlite3_unlock_notify(
15 conn,
16 Some(unlock_notify_cb),
17 ¬ify as *const Notify as *mut Notify as *mut _,
18 ) != SQLITE_OK
19 {
20 return Err(SqliteError::new(conn));
21 }
22
23 notify.wait();
24
25 Ok(())
26}
27
28unsafe extern "C" fn unlock_notify_cb(ptr: *mut *mut c_void, len: c_int) {
29 let ptr = ptr as *mut &Notify;
30 let slice = slice::from_raw_parts(ptr, usize::try_from(len).unwrap_or(0));
32
33 for notify in slice {
34 notify.fire();
35 }
36}
37
38struct Notify {
39 mutex: Mutex<bool>,
40 condvar: Condvar,
41}
42
43impl Notify {
44 fn new() -> Self {
45 Self {
46 mutex: Mutex::new(false),
47 condvar: Condvar::new(),
48 }
49 }
50
51 fn wait(&self) {
52 #[allow(let_underscore_lock)]
54 let _ = self
55 .condvar
56 .wait_while(self.mutex.lock().unwrap(), |fired| !*fired)
57 .unwrap();
58 }
59
60 fn fire(&self) {
61 let mut lock = self.mutex.lock().unwrap();
62 *lock = true;
63 self.condvar.notify_one();
64 }
65}