refining what is what in stores

This commit is contained in:
Ulrich Mohr 2024-02-05 22:23:17 +01:00
parent 4460e470b2
commit 3064a5c2e8
2 changed files with 53 additions and 18 deletions

View File

@ -115,7 +115,7 @@ impl<T: Clone + Default + 'static> ReferencedDataset<T> {
}
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::<T>() {
self.actual_data = Some(other_data);
} else {

View File

@ -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<StoreSlot, ()> {
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<StoreSlot, ()> {
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<I>(&self, index: I) -> &mut [u8]
where I: SliceIndex<u8>
{
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) }
}
}