1- use crate :: flags:: { AccessFlags , LockLevel , OpenOpts } ;
1+ use crate :: flags:: { AccessFlags , LockLevel , OpenOpts , ShmLockMode } ;
22use crate :: logger:: SqliteLogger ;
33use crate :: vars:: SQLITE_ERROR ;
44use crate :: { ffi, vars} ;
@@ -11,7 +11,7 @@ use core::mem::{ManuallyDrop, size_of};
1111use core:: slice;
1212use core:: {
1313 ffi:: { CStr , c_char, c_int, c_void} ,
14- ptr:: null_mut,
14+ ptr:: { NonNull , null_mut} ,
1515} ;
1616
1717/// The minimim supported `SQLite` version.
@@ -186,6 +186,32 @@ pub trait Vfs: Send + Sync {
186186 fn device_characteristics ( & self , handle : & mut Self :: Handle ) -> VfsResult < i32 > {
187187 Ok ( DEFAULT_DEVICE_CHARACTERISTICS )
188188 }
189+
190+ fn shm_map (
191+ & self ,
192+ handle : & mut Self :: Handle ,
193+ region_idx : usize ,
194+ region_size : usize ,
195+ extend : bool ,
196+ ) -> VfsResult < Option < NonNull < u8 > > > {
197+ Err ( vars:: SQLITE_READONLY_CANTINIT )
198+ }
199+
200+ fn shm_lock (
201+ & self ,
202+ handle : & mut Self :: Handle ,
203+ offset : u32 ,
204+ count : u32 ,
205+ mode : ShmLockMode ,
206+ ) -> VfsResult < ( ) > {
207+ Err ( vars:: SQLITE_IOERR )
208+ }
209+
210+ fn shm_barrier ( & self , handle : & mut Self :: Handle ) { }
211+
212+ fn shm_unmap ( & self , handle : & mut Self :: Handle , delete : bool ) -> VfsResult < ( ) > {
213+ Err ( vars:: SQLITE_IOERR )
214+ }
189215}
190216
191217#[ derive( Clone ) ]
@@ -300,10 +326,10 @@ fn register_inner<T: Vfs>(
300326 xFileControl : Some ( x_file_control :: < T > ) ,
301327 xSectorSize : Some ( x_sector_size :: < T > ) ,
302328 xDeviceCharacteristics : Some ( x_device_characteristics :: < T > ) ,
303- xShmMap : None ,
304- xShmLock : None ,
305- xShmBarrier : None ,
306- xShmUnmap : None ,
329+ xShmMap : Some ( x_shm_map :: < T > ) ,
330+ xShmLock : Some ( x_shm_lock :: < T > ) ,
331+ xShmBarrier : Some ( x_shm_barrier :: < T > ) ,
332+ xShmUnmap : Some ( x_shm_unmap :: < T > ) ,
307333 xFetch : None ,
308334 xUnfetch : None ,
309335 } ;
@@ -657,6 +683,69 @@ unsafe extern "C" fn x_device_characteristics<T: Vfs>(p_file: *mut ffi::sqlite3_
657683 } )
658684}
659685
686+ unsafe extern "C" fn x_shm_map < T : Vfs > (
687+ p_file : * mut ffi:: sqlite3_file ,
688+ pg : c_int ,
689+ pgsz : c_int ,
690+ extend : c_int ,
691+ p_page : * mut * mut c_void ,
692+ ) -> c_int {
693+ fallible ( || {
694+ let file = unwrap_file ! ( p_file, T ) ?;
695+ let vfs = unwrap_vfs ! ( file. vfs, T ) ?;
696+ if let Some ( region) = vfs. shm_map (
697+ & mut file. handle ,
698+ pg. try_into ( ) . map_err ( |_| vars:: SQLITE_IOERR ) ?,
699+ pgsz. try_into ( ) . map_err ( |_| vars:: SQLITE_IOERR ) ?,
700+ extend != 0 ,
701+ ) ? {
702+ unsafe { * p_page = region. as_ptr ( ) as * mut c_void }
703+ } else {
704+ unsafe { * p_page = null_mut ( ) }
705+ }
706+ Ok ( vars:: SQLITE_OK )
707+ } )
708+ }
709+
710+ unsafe extern "C" fn x_shm_lock < T : Vfs > (
711+ p_file : * mut ffi:: sqlite3_file ,
712+ offset : c_int ,
713+ n : c_int ,
714+ flags : c_int ,
715+ ) -> c_int {
716+ fallible ( || {
717+ let file = unwrap_file ! ( p_file, T ) ?;
718+ let vfs = unwrap_vfs ! ( file. vfs, T ) ?;
719+ vfs. shm_lock (
720+ & mut file. handle ,
721+ offset. try_into ( ) . map_err ( |_| vars:: SQLITE_IOERR ) ?,
722+ n. try_into ( ) . map_err ( |_| vars:: SQLITE_IOERR ) ?,
723+ ShmLockMode :: try_from ( flags) ?,
724+ ) ?;
725+ Ok ( vars:: SQLITE_OK )
726+ } )
727+ }
728+
729+ unsafe extern "C" fn x_shm_barrier < T : Vfs > ( p_file : * mut ffi:: sqlite3_file ) {
730+ if let Ok ( file) = unwrap_file ! ( p_file, T ) {
731+ if let Ok ( vfs) = unwrap_vfs ! ( file. vfs, T ) {
732+ vfs. shm_barrier ( & mut file. handle )
733+ }
734+ }
735+ }
736+
737+ unsafe extern "C" fn x_shm_unmap < T : Vfs > (
738+ p_file : * mut ffi:: sqlite3_file ,
739+ delete_flag : c_int ,
740+ ) -> c_int {
741+ fallible ( || {
742+ let file = unwrap_file ! ( p_file, T ) ?;
743+ let vfs = unwrap_vfs ! ( file. vfs, T ) ?;
744+ vfs. shm_unmap ( & mut file. handle , delete_flag != 0 ) ?;
745+ Ok ( vars:: SQLITE_OK )
746+ } )
747+ }
748+
660749// the following functions are wrappers around the base vfs functions
661750
662751unsafe extern "C" fn x_dlopen < T : Vfs > (
0 commit comments