Skip to content

Commit 61ecf6d

Browse files
authored
Introduce the sleep interface (#161)
* Introduce the `sleep` interface * Fix example
1 parent 48c6111 commit 61ecf6d

File tree

8 files changed

+60
-373
lines changed

8 files changed

+60
-373
lines changed

crates/rsqlite-vfs/src/lib.rs

Lines changed: 19 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@
55
#![allow(non_upper_case_globals)]
66
#![allow(non_camel_case_types)]
77
#![allow(non_snake_case)]
8-
#![cfg_attr(target_feature = "atomics", feature(stdarch_wasm_atomic_wait))]
98

109
extern crate alloc;
1110

@@ -25,6 +24,7 @@ use alloc::string::String;
2524
use alloc::vec::Vec;
2625
use alloc::{boxed::Box, ffi::CString};
2726
use alloc::{format, vec};
27+
use core::time::Duration;
2828
use core::{cell::RefCell, ffi::CStr, ops::Deref};
2929

3030
pub mod memvfs;
@@ -464,6 +464,7 @@ pub trait SQLiteVfs<IO: SQLiteIoMethods> {
464464
const VERSION: ::core::ffi::c_int;
465465
const MAX_PATH_SIZE: ::core::ffi::c_int = 1024;
466466

467+
fn sleep(dur: Duration);
467468
fn random(buf: &mut [u8]);
468469
fn epoch_timestamp_in_ms() -> i64;
469470

@@ -487,7 +488,7 @@ pub trait SQLiteVfs<IO: SQLiteIoMethods> {
487488
xDlSym: None,
488489
xDlClose: None,
489490
xRandomness: Some(Self::xRandomness),
490-
xSleep: Some(x_methods_shim::xSleep),
491+
xSleep: Some(Self::xSleep),
491492
xCurrentTime: Some(Self::xCurrentTime),
492493
xGetLastError: Some(Self::xGetLastError),
493494
xCurrentTimeInt64: Some(Self::xCurrentTimeInt64),
@@ -635,32 +636,45 @@ pub trait SQLiteVfs<IO: SQLiteIoMethods> {
635636

636637
/// <https://github.com/sqlite/sqlite/blob/fb9e8e48fd70b463fb7ba6d99e00f2be54df749e/ext/wasm/api/sqlite3-vfs-opfs.c-pp.js#L951>
637638
unsafe extern "C" fn xRandomness(
638-
_pVfs: *mut sqlite3_vfs,
639+
pVfs: *mut sqlite3_vfs,
639640
nByte: ::core::ffi::c_int,
640641
zOut: *mut ::core::ffi::c_char,
641642
) -> ::core::ffi::c_int {
643+
unused!(pVfs);
642644
let slice = core::slice::from_raw_parts_mut(zOut.cast(), nByte as usize);
643645
Self::random(slice);
644646
nByte
645647
}
646648

647649
/// <https://github.com/sqlite/sqlite/blob/fb9e8e48fd70b463fb7ba6d99e00f2be54df749e/ext/wasm/api/sqlite3-vfs-opfs.c-pp.js#L870>
648650
unsafe extern "C" fn xCurrentTime(
649-
_pVfs: *mut sqlite3_vfs,
651+
pVfs: *mut sqlite3_vfs,
650652
pTimeOut: *mut f64,
651653
) -> ::core::ffi::c_int {
654+
unused!(pVfs);
652655
*pTimeOut = 2440587.5 + (Self::epoch_timestamp_in_ms() as f64 / 86400000.0);
653656
SQLITE_OK
654657
}
655658

656659
/// <https://github.com/sqlite/sqlite/blob/fb9e8e48fd70b463fb7ba6d99e00f2be54df749e/ext/wasm/api/sqlite3-vfs-opfs.c-pp.js#L877>
657660
unsafe extern "C" fn xCurrentTimeInt64(
658-
_pVfs: *mut sqlite3_vfs,
661+
pVfs: *mut sqlite3_vfs,
659662
pOut: *mut sqlite3_int64,
660663
) -> ::core::ffi::c_int {
664+
unused!(pVfs);
661665
*pOut = ((2440587.5 * 86400000.0) + Self::epoch_timestamp_in_ms() as f64) as sqlite3_int64;
662666
SQLITE_OK
663667
}
668+
669+
unsafe extern "C" fn xSleep(
670+
pVfs: *mut sqlite3_vfs,
671+
microseconds: ::core::ffi::c_int,
672+
) -> ::core::ffi::c_int {
673+
unused!(pVfs);
674+
let dur = Duration::from_micros(microseconds as u64);
675+
Self::sleep(dur);
676+
SQLITE_OK
677+
}
664678
}
665679

666680
/// A trait that abstracts the `sqlite3_io_methods` struct, allowing for a more idiomatic Rust implementation.
@@ -865,45 +879,6 @@ pub trait SQLiteIoMethods {
865879
}
866880
}
867881

868-
/// A module containing shims for VFS methods that are implemented using JavaScript interoperability.
869-
#[allow(clippy::missing_safety_doc)]
870-
pub mod x_methods_shim {
871-
use super::*;
872-
873-
/// thread::sleep is available when atomics is enabled
874-
#[cfg(target_feature = "atomics")]
875-
pub unsafe extern "C" fn xSleep(
876-
_pVfs: *mut sqlite3_vfs,
877-
microseconds: ::core::ffi::c_int,
878-
) -> ::core::ffi::c_int {
879-
use core::time::Duration;
880-
881-
// Use an atomic wait to block the current thread artificially with a
882-
// timeout listed. Note that we should never be notified (return value
883-
// of 0) or our comparison should never fail (return value of 1) so we
884-
// should always only resume execution through a timeout (return value
885-
// 2).
886-
let dur = Duration::from_micros(microseconds as u64);
887-
let mut nanos = dur.as_nanos();
888-
while nanos > 0 {
889-
let amt = core::cmp::min(i64::MAX as u128, nanos);
890-
let mut x = 0;
891-
let val = unsafe { core::arch::wasm32::memory_atomic_wait32(&mut x, 0, amt as i64) };
892-
debug_assert_eq!(val, 2);
893-
nanos -= amt;
894-
}
895-
SQLITE_OK
896-
}
897-
898-
#[cfg(not(target_feature = "atomics"))]
899-
pub unsafe extern "C" fn xSleep(
900-
_pVfs: *mut sqlite3_vfs,
901-
_microseconds: ::core::ffi::c_int,
902-
) -> ::core::ffi::c_int {
903-
SQLITE_OK
904-
}
905-
}
906-
907882
#[derive(thiserror::Error, Debug)]
908883
pub enum ImportDbError {
909884
#[error("Byte array size is invalid for an SQLite db.")]

crates/rsqlite-vfs/src/memvfs.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ use alloc::{format, vec};
4343
use core::cell::RefCell;
4444
use core::ffi::CStr;
4545
use core::marker::PhantomData;
46+
use core::time::Duration;
4647
use hashbrown::HashMap;
4748

4849
const VFS_NAME: &CStr = c"memvfs";
@@ -99,6 +100,7 @@ impl VfsFile for MemFile {
99100
type MemAppData = RefCell<HashMap<String, MemFile>>;
100101

101102
pub trait OsCallback {
103+
fn sleep(dur: Duration);
102104
fn random(buf: &mut [u8]);
103105
fn epoch_timestamp_in_ms() -> i64;
104106
}
@@ -182,6 +184,10 @@ where
182184
{
183185
const VERSION: ::core::ffi::c_int = 1;
184186

187+
fn sleep(dur: Duration) {
188+
C::sleep(dur);
189+
}
190+
185191
fn random(buf: &mut [u8]) {
186192
C::random(buf);
187193
}

crates/sqlite-wasm-vfs/src/relaxed_idb.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@ use sqlite_wasm_rs::{
5656
SQLITE_IOERR_DELETE, SQLITE_NOTFOUND, SQLITE_OK, SQLITE_OPEN_MAIN_DB,
5757
};
5858
use std::cell::RefCell;
59+
use std::time::Duration;
5960

6061
use indexed_db_futures::database::Database;
6162
use indexed_db_futures::prelude::*;
@@ -721,6 +722,10 @@ struct RelaxedIdbVfs;
721722
impl SQLiteVfs<RelaxedIdbIoMethods> for RelaxedIdbVfs {
722723
const VERSION: ::std::os::raw::c_int = 1;
723724

725+
fn sleep(dur: Duration) {
726+
WasmOsCallback::sleep(dur);
727+
}
728+
724729
fn random(buf: &mut [u8]) {
725730
WasmOsCallback::random(buf);
726731
}

crates/sqlite-wasm-vfs/src/sahpool.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ use sqlite_wasm_rs::{
4545
};
4646
use std::cell::{Cell, RefCell};
4747
use std::collections::{HashMap, HashSet};
48+
use std::time::Duration;
4849

4950
use js_sys::{Array, DataView, IteratorNext, Reflect, Uint8Array};
5051
use wasm_bindgen::{JsCast, JsValue};
@@ -696,6 +697,10 @@ impl SQLiteVfs<SyncAccessHandleIoMethods> for SyncAccessHandleVfs {
696697
ret
697698
}
698699

700+
fn sleep(dur: Duration) {
701+
WasmOsCallback::sleep(dur);
702+
}
703+
699704
fn random(buf: &mut [u8]) {
700705
WasmOsCallback::random(buf);
701706
}

examples/implement-a-vfs/src/lib.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ use sqlite_wasm_rs::{
1010
},
1111
SQLITE_OK, SQLITE_OPEN_CREATE, SQLITE_OPEN_READWRITE,
1212
};
13+
use std::time::Duration;
1314
use std::{cell::RefCell, collections::HashMap};
1415
use wasm_bindgen_test::{console_log, wasm_bindgen_test};
1516

@@ -182,6 +183,10 @@ struct MemVfs;
182183
impl SQLiteVfs<MemIoMethods> for MemVfs {
183184
const VERSION: ::std::os::raw::c_int = 1;
184185

186+
fn sleep(dur: Duration) {
187+
sqlite_wasm_rs::WasmOsCallback::sleep(dur);
188+
}
189+
185190
fn random(buf: &mut [u8]) {
186191
sqlite_wasm_rs::WasmOsCallback::random(buf);
187192
}

src/lib.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,9 @@ pub mod utils {
1717
#[doc(inline)]
1818
pub use rsqlite_vfs::{
1919
bail, check_db_and_page_size, check_import_db, check_option, check_result, random_name,
20-
register_vfs, registered_vfs, x_methods_shim, ImportDbError, MemChunksFile,
21-
RegisterVfsError, SQLiteIoMethods, SQLiteVfs, SQLiteVfsFile, VfsAppData, VfsError, VfsFile,
22-
VfsResult, VfsStore, SQLITE3_HEADER,
20+
register_vfs, registered_vfs, ImportDbError, MemChunksFile, RegisterVfsError,
21+
SQLiteIoMethods, SQLiteVfs, SQLiteVfsFile, VfsAppData, VfsError, VfsFile, VfsResult,
22+
VfsStore, SQLITE3_HEADER,
2323
};
2424

2525
#[doc(hidden)]

0 commit comments

Comments
 (0)