diff --git a/mission_rust/src/fsrc/datasets/mod.rs b/mission_rust/src/fsrc/datasets/mod.rs index 771fbe4..fd12f2a 100644 --- a/mission_rust/src/fsrc/datasets/mod.rs +++ b/mission_rust/src/fsrc/datasets/mod.rs @@ -115,7 +115,7 @@ impl ReferencedDataset { } Some(set) => set, }; - // let's recheck that owner.get_set did not lie about the type_id + // let's recheck that owner.get_set() did not lie about the type_id if let Some(other_data) = other_set.get_actual_data().downcast_ref::() { self.actual_data = Some(other_data); } else { diff --git a/mission_rust/src/fsrc/store.rs b/mission_rust/src/fsrc/store.rs index d3d999d..3950f6b 100644 --- a/mission_rust/src/fsrc/store.rs +++ b/mission_rust/src/fsrc/store.rs @@ -1,36 +1,71 @@ +use core::slice::SliceIndex; + use crate::check_global_threading_available; -struct Store{ - mutex: crate::fsrc::mutex::RawMutex -} - trait StoreBackend { - + fn free_slot(&mut self, length: usize) -> Option<*mut [u8]>; } -struct StoreAccessor { - mutex: crate::fsrc::mutex::RawMutex +struct Store<'a> { + mutex: crate::fsrc::mutex::RawMutex, + backend: &'a mut dyn StoreBackend, } -impl Store { - pub fn get_accessor(&self) -> StoreAccessor { +impl<'a> Store<'a> { + pub fn accessor(&mut self) -> StoreAccessor { check_global_threading_available!(); - StoreAccessor{mutex: self.mutex.clone()} + // holy shit, this is really unsafe, even for us: + // we cast away the lifetime + // this is safe as we only do it in threading + // and the Accessor will only use it while still in threading + // (the accessor is a smart pointer refusing to be smart outside + // of threading) + let static_pointer = unsafe { core::mem::transmute::<*mut Store<'a>, *mut Store<'static>>(self) }; + StoreAccessor { + store: static_pointer, + } + } + + fn free_slot(&mut self, length: usize) -> Result { + if let Ok(_guard) = self.mutex.take() { + if let Some(data) = self.backend.free_slot(length){ + Ok(StoreSlot { data: data }) + } else { + Err(()) + } + } else { + Err(()) + } } } -struct StoreSlot{ - data: *mut [u8] +// A smart pointer to a Store protecting insane (static) pointer usage +// only works during threading, panics otherwise +struct StoreAccessor { + store: *mut Store<'static>, +} + +impl StoreAccessor { + fn free_slot(&self, length: usize) -> Result { + check_global_threading_available!(); + unsafe { (*self.store).free_slot(length) } + } +} + +struct StoreSlot { + data: *mut [u8], } impl StoreSlot { - pub fn get_data(&self) -> &mut [u8] { + pub fn get(&self, index: I) -> &mut [u8] + where I: SliceIndex + { check_global_threading_available!(); - unsafe{&mut (*self.data)} + unsafe { &mut (*self.data) } } - pub fn get_all_data(&self) -> &mut [u8] { + pub fn get_all(&self) -> &mut [u8] { check_global_threading_available!(); - unsafe{&mut (*self.data)} + unsafe { &mut (*self.data) } } -} \ No newline at end of file +}