From 81a40587cbbe01c85a74efa2e56f1a6125a7cc55 Mon Sep 17 00:00:00 2001 From: Avril Date: Sun, 27 Dec 2020 16:56:01 +0000 Subject: [PATCH] Maybe okay state --- src/job.rs | 13 ++++++++++++- src/map.rs | 11 +++++++++-- src/state.rs | 46 +++++++++++++++++++++++++++++++++++++++++++++- 3 files changed, 66 insertions(+), 4 deletions(-) diff --git a/src/job.rs b/src/job.rs index 7d19477..7af98ca 100644 --- a/src/job.rs +++ b/src/job.rs @@ -1,7 +1,18 @@ use super::*; +use std::fs::{ + File, Metadata, +}; #[derive(Debug)] pub struct Job { - //todo + fd: File, + stat: Metadata, + + /// We grab the slice of memory we write to from here + state: state::State, + /// From this offset + offset: usize, } + +//TODO: job's work :^) diff --git a/src/map.rs b/src/map.rs index ce9b8b0..0edd4ee 100644 --- a/src/map.rs +++ b/src/map.rs @@ -2,7 +2,7 @@ use std::ops::RangeBounds; use std::slice::SliceIndex; use std::{fs,io}; use std::path::Path; - +use std::ops::Drop; use memmap::MmapMut; #[derive(Debug)] @@ -12,6 +12,14 @@ pub struct MemoryMapMut map: MmapMut, } +impl Drop for MemoryMapMut +{ + fn drop(&mut self) + { + let _ = self.map.flush(); + } +} + impl AsRef<[u8]> for MemoryMapMut { fn as_ref(&self) -> &[u8] @@ -28,7 +36,6 @@ impl AsMut<[u8]> for MemoryMapMut } } - impl MemoryMapMut { #[inline] pub fn as_slice_mut(&mut self) -> &mut [u8] diff --git a/src/state.rs b/src/state.rs index 461e804..341982b 100644 --- a/src/state.rs +++ b/src/state.rs @@ -2,11 +2,55 @@ use std::sync::{ mpsc, Mutex, Arc, - + PoisonError, }; use std::fmt; use std::error; +use std::cell::UnsafeCell; +use std::{slice::SliceIndex, ops::RangeBounds}; + +#[derive(Debug)] +#[repr(transparent)] +struct StateInner +{ + map: UnsafeCell, +} + +// SAFETY: The whole point of this is internal mutablility across thread boundaries. +unsafe impl Sync for StateInner{} + +#[derive(Debug, Clone)] +pub struct State(Arc); + +impl State +{ + /// Create a new state from this map + #[inline] pub fn new(map: super::map::MemoryMapMut) -> Self + { + Self(Arc::new(StateInner{map: UnsafeCell::new(map)})) + } + + /// Try to consume this instance into its map. This will only succeed if there are no more references to the state than this one. + #[inline] pub fn try_into_inner(self) -> Result + { + match Arc::try_unwrap(self.0) { + Ok(v) => Ok(v.map.into_inner()), + Err(e) => Err(Self(e)), + } + } + + /// Slice the map directly. + /// + /// # Safety + /// The caller must make sure *no* slices of this map overlap with eachother. + // SAFETY: The map structure itself is never mutated, only its backing memory is accessed. This is fine, I think. If not, we can switch to using raw pointers and volatile writes. The backing memory itself is flushed to file when the map is dropped. + pub unsafe fn slice + SliceIndex<[u8], Output = [u8]>>(&self, range: R) -> &mut [u8] + { + let slice = (*(self.0.map.get())).as_slice_mut(); + &mut slice[range] + } +} /// A multi-consumer message receiver #[derive(Debug)]