···11-use core::{cell::UnsafeCell, hint::unreachable_unchecked, sync::atomic::AtomicU8};
11+use core::{
22+ cell::UnsafeCell, hint::unreachable_unchecked, mem::MaybeUninit, sync::atomic::{self, AtomicU8, Ordering}
33+};
2435#[derive(PartialEq, Eq, Clone, Copy, Debug)]
46pub(crate) enum Ptr {
···2325 _ => unsafe { unreachable_unchecked() },
2426 }
2527 }
2626-2727- /// ignores potentially set read bits.
2828- /// SAFETY: no bits except the for bottom three can be set
2929- pub(crate) unsafe fn from_u8_ignore_read(value: u8) -> Self {
3030- match value & 0b100 {
3131- 0b000 => Self::Value1,
3232- 0b100 => Self::Value2,
3333- // SAFETY: unsafe fn. communicated in docs
3434- _ => unsafe { unreachable_unchecked() },
3535- }
3636- }
3728}
38293930#[derive(Debug)]
···5243 }
5344 }
54455555- /// SAFETY: only the read state bits are set
4646+ /// SAFETY: needs to be the internal state u8.
5647 pub(crate) unsafe fn from_u8_ignore_ptr(value: u8) -> Self {
5748 match value & 0b011 {
5849 0b00 => Self::None,
···7970 /// bit 1: is value 2 being read
8071 /// bit 3: which value should be read next (0: value 1, 1: value 2)
8172 pub state: AtomicU8,
7373+ pub access_count: AtomicU8,
8274}
83758484-/// SAFETY: Shared not public. Reader and Writer make it safe to use. Same restrictions as RwLock, which allows similar access
8585-unsafe impl<T: Send> Send for Shared<T> {}
8686-8787-/// SAFETY: Shared not public. Reader and Writer make it safe to use. Same restrictions as RwLock, which allows similar access
8888-unsafe impl<T: Send + Sync> Sync for Shared<T> {}
8989-9076impl<T> Shared<T> {
7777+ /// initializes everything except for both values.
7878+ pub(crate) fn initialize_state(this: &mut MaybeUninit<Self>) {
7979+ // SAFETY: takes &mut self, so no writing is okay
8080+ unsafe {
8181+ (&raw mut (*this.as_mut_ptr()).access_count).write(AtomicU8::new(1));
8282+ (&raw mut (*this.as_mut_ptr()).state).write(AtomicU8::new(0b000));
8383+ }
8484+ }
8585+9186 pub(crate) fn get_value(&self, ptr: Ptr) -> &UnsafeCell<T> {
9287 match ptr {
9388 Ptr::Value1 => &self.value_1,
9489 Ptr::Value2 => &self.value_2,
9590 }
9191+ }
9292+9393+ /// If self is unique increase the count and returns true.
9494+ /// Otherwise returns false.
9595+ ///
9696+ /// If this returns true another smart pointer has to be created otherwise memory will be leaked
9797+ pub(crate) unsafe fn is_unique_with_increase(&self) -> bool {
9898+ // Relaxed taken from std Arc
9999+ let old_access = self.access_count.load(Ordering::Acquire);
100100+ debug_assert!(
101101+ old_access <= 2,
102102+ "at maximum there is one Reader and one Writer"
103103+ );
104104+ if old_access == 1 {
105105+ self.access_count.fetch_add(1, Ordering::Relaxed);
106106+ true
107107+ } else {
108108+ false
109109+ }
110110+ }
111111+112112+ /// decreases the access_count and returns if self should now be dropped.
113113+ ///
114114+ /// | return | needed reaction
115115+ /// |---|---|
116116+ /// | true | self needs to be dropped or memory is leaked |
117117+ /// | false | this ptr to self could now become dangling at any time |
118118+ ///
119119+ /// dropping self when this returns true is safe and needed synchronisation has been done.
120120+ pub(crate) unsafe fn should_drop(&self) -> bool {
121121+ let old_access = self.access_count.fetch_sub(1, Ordering::Release);
122122+ debug_assert!(
123123+ old_access <= 2,
124124+ "at maximum there is one Reader and one Writer"
125125+ );
126126+ if old_access != 1 {
127127+ return false;
128128+ }
129129+ // see std Arc
130130+ atomic::fence(Ordering::Acquire);
131131+ true
132132+ }
133133+134134+ pub(crate) fn is_unique(&self) -> bool {
135135+ let access = self.access_count.load(Ordering::Acquire);
136136+ debug_assert!(access <= 2, "at maximum there is one Reader and one Writer");
137137+ access == 1
96138 }
97139}
+236-155
simple-left-right/src/lib.rs
···3131use std::thread;
32323333use core::{
3434- cell::UnsafeCell,
3535- marker::PhantomData,
3636- mem::MaybeUninit,
3737- ops::Deref,
3838- sync::atomic::{fence, AtomicU8, Ordering},
3434+ cell::UnsafeCell, marker::PhantomData, mem::MaybeUninit, ops::Deref, ptr::NonNull, sync::atomic::{fence, AtomicU8, Ordering}
3935};
40364141-use alloc::{collections::vec_deque::VecDeque, sync::Arc};
3737+use alloc::{collections::vec_deque::VecDeque, boxed::Box};
42384339mod inner;
4440···5046 fn absorb(&mut self, operation: O);
5147}
52485353-/// Data won't change while holding the Guard. This also means the Writer can only issue one swap, while Guard is being held
5454-#[derive(Debug)]
5555-pub struct ReadGuard<'a, T> {
5656- data: &'a T,
5757- state: &'a AtomicU8,
5858- // PhantomData makes the borrow checker prove that there only ever is one ReadGuard
5959- //
6060- // This is needed because setting the ReadState can only be reset when no ReadGuard exists
6161- // and that would mean some kind of counter
6262- reader: PhantomData<&'a mut Reader<T>>,
6363-}
6464-6565-// only struct that should have this impl, as it doesn't have any methods
6666-impl<'a, T> Deref for ReadGuard<'a, T> {
6767- type Target = T;
6868-6969- fn deref(&self) -> &Self::Target {
7070- self.data
7171- }
7272-}
7373-7474-impl<T, E> AsRef<E> for ReadGuard<'_, T>
7575-where
7676- E: ?Sized,
7777- T: AsRef<E>,
7878-{
7979- fn as_ref(&self) -> &E {
8080- self.deref().as_ref()
8181- }
8282-}
8383-8484-impl<T> Drop for ReadGuard<'_, T> {
8585- fn drop(&mut self) {
8686- // release the read lock
8787- self.state.fetch_and(0b100, Ordering::Release);
8888- }
8989-}
9090-9149/// Dropping the Reader isn't realtime safe, because if dropped after the Writer, it deallocates.
9250/// Should only get dropped, when closing the real-time thread
9351///
9452/// Reader will be able to read data even if Writer has been dropped. Obviously that data won't change anymore
9595-/// When there is no Reader the Writer is able to create a new one. The other way around doesn't work
5353+/// When there is no Reader the Writer is able to create a new one. The other way around doesn't work.
5454+///
5555+/// Isn't Sync as there is no methos that takes &self, so it is useless anyways.
9656#[derive(Debug)]
9757pub struct Reader<T> {
9898- inner: Arc<Shared<T>>,
5858+ shared: NonNull<Shared<T>>,
5959+ /// for drop check
6060+ _own: PhantomData<Shared<T>>,
9961}
1006210163impl<T> Reader<T> {
6464+ const fn shared_ref(&self) -> &Shared<T> {
6565+ // SAFETY: Reader always has a valid Shared<T>, a mut ref to a shared is never created,
6666+ // only to the UnsafeCell<T>s inside of it
6767+ unsafe { self.shared.as_ref() }
6868+ }
6969+10270 /// this function never blocks. (`fetch_update` loop doesn't count)
10371 pub fn lock(&mut self) -> ReadGuard<'_, T> {
7272+ let inner_ref = self.shared_ref();
10473 // sets the corresponding read bit to the write ptr bit
10574 // happens as a single atomic operation so the 'double read' state isn't needed
10675 // ptr bit doesnt get changed
10776 // always Ok, as the passed closure never returns None
10877 let update_result =
109109- self.inner
7878+ inner_ref
11079 .state
11180 .fetch_update(Ordering::Relaxed, Ordering::Acquire, |value| {
11281 // SAFETY: At this point no Read bit is set, as creating a ReadGuard requires a &mut Reader and the Guard holds the &mut Reader
···12291 // we continue working with the state that we set.
1239212493 // SAFETY: the passed closure always returns Some, so fetch_update never returns Err
125125- let ptr = unsafe {
126126- // here it doesn't matter if we create the Ptr from the read bits or from the ptr bit, as they match
127127- Ptr::from_u8_ignore_read(update_result.unwrap_unchecked())
128128- };
9494+ let ptr = unsafe { Ptr::from_u8_no_read(update_result.unwrap_unchecked()) };
1299513096 // SAFETY: the Writer allowed the read on this value because the ptr bit was set. The read bit has been set
131131- let data = unsafe { self.inner.get_value(ptr).get().as_ref().unwrap_unchecked() };
9797+ let data = unsafe { inner_ref.get_value(ptr).get().as_ref().unwrap_unchecked() };
1329813399 ReadGuard {
134100 data,
135135- state: &self.inner.state,
101101+ state: &inner_ref.state,
136102 reader: PhantomData,
137103 }
138104 }
139105}
140106141141-// Don't ever create a WriteGuard directly
142142-/// Can be used to write to the Data structure.
143143-///
144144-/// When this structure exists the Reader already switched to the other value
145145-///
146146-/// Dropping this makes all changes available to the Reader
147147-#[derive(Debug)]
148148-pub struct WriteGuard<'a, T, O> {
149149- writer: &'a mut Writer<T, O>,
150150-}
107107+/// SAFETY: Owns a T
108108+unsafe impl<T: Send> Send for Reader<T> {}
151109152152-impl<T, O> WriteGuard<'_, T, O> {
153153- /// Makes the changes available to the reader.
154154- pub fn swap(self) {}
155155-156156- /// Gets the value currently being written to.
157157- pub fn read(&self) -> &T {
158158- self.writer.read()
159159- }
160160-161161- /// Isn't public as this could easily create disconnects between the two versions.
162162- /// While that wouldn't lead to UB it goes against the purpose of this library
163163- fn get_data_mut(&mut self) -> &mut T {
164164- // SAFETY: When creating the writeguad it is checked that the reader doesnt have access to the same data
165165- // This function requires &mut self so there also isn't any ref created by writeguard.
166166- // SAFETY: the ptr is never null, therefore unwrap_unchecked
110110+impl<T> Drop for Reader<T> {
111111+ fn drop(&mut self) {
112112+ // SAFETY: Shared.should_drop() is called. on true object really is dropped. on false it isnt.
113113+ // This is the last use of self and therefore also of Shared
167114 unsafe {
168168- self.writer
169169- .shared
170170- .get_value(self.writer.write_ptr)
171171- .get()
172172- .as_mut()
173173- .unwrap_unchecked()
115115+ let should_drop = self.shared_ref().should_drop();
116116+ if should_drop {
117117+ _ = Box::from_raw(self.shared.as_ptr());
118118+ }
174119 }
175120 }
176121}
177122178178-impl<'a, T: Absorb<O>, O> WriteGuard<'a, T, O> {
179179- /// created a new `WriteGuard` and syncs the two values if needed.
180180- ///
181181- /// ### SAFETY
182182- /// No `ReadGuard` is allowed to exist to the same value the `Writer.write_ptr` points to
183183- ///
184184- /// Assuming a correct `Reader` & `ReadGuard` implementation:
185185- /// If Inner.read_state.can_write(Writer.write_ptr) == true this function is fine to call
186186- unsafe fn new(writer: &'a mut Writer<T, O>) -> Self {
187187- let mut guard = Self { writer };
188188- while let Some(operation) = guard.writer.op_buffer.pop_front() {
189189- guard.get_data_mut().absorb(operation);
190190- }
191191- guard
123123+/// Data won't change while holding the Guard. This also means the Writer can only issue one swap, while Guard is being held
124124+/// If T: !Sync this is guaranteed to be the only ref to this T
125125+///
126126+/// Doesn't implement Clone as that would require refcounting to know when to unlock.
127127+#[derive(Debug)]
128128+pub struct ReadGuard<'a, T> {
129129+ data: &'a T,
130130+ state: &'a AtomicU8,
131131+ /// PhantomData makes the borrow checker prove that there only ever is one ReadGuard.
132132+ /// This allows resetting the readstate without some kind of counter
133133+ reader: PhantomData<&'a mut Reader<T>>,
134134+}
135135+136136+impl<'a, T> Deref for ReadGuard<'a, T> {
137137+ type Target = T;
138138+139139+ fn deref(&self) -> &Self::Target {
140140+ self.data
192141 }
193142}
194143195195-impl<T: Absorb<O>, O: Clone> WriteGuard<'_, T, O> {
196196- /// applies operation to the current write Value and stores it to apply to the other later.
197197- /// If there is no reader the operation is applied to both values immediately and not stored.
198198- pub fn apply_op(&mut self, operation: O) {
199199- if let Some(inner) = Arc::get_mut(&mut self.writer.shared) {
200200- inner.value_1.get_mut().absorb(operation.clone());
201201- inner.value_2.get_mut().absorb(operation);
202202- } else {
203203- self.writer.op_buffer.push_back(operation.clone());
204204- self.get_data_mut().absorb(operation);
205205- }
144144+impl<T, E> AsRef<E> for ReadGuard<'_, T>
145145+where
146146+ E: ?Sized,
147147+ T: AsRef<E>,
148148+{
149149+ fn as_ref(&self) -> &E {
150150+ self.deref().as_ref()
206151 }
207152}
208153209209-impl<T, O> Drop for WriteGuard<'_, T, O> {
154154+/// SAFETY: behaves like a ref to T. https://doc.rust-lang.org/std/marker/trait.Sync.html
155155+unsafe impl<T: Sync> Send for ReadGuard<'_, T> {}
156156+/// SAFETY: behaves like a ref to T. https://doc.rust-lang.org/std/marker/trait.Sync.html
157157+unsafe impl<T: Sync> Sync for ReadGuard<'_, T> {}
158158+159159+impl<T> Drop for ReadGuard<'_, T> {
210160 fn drop(&mut self) {
211211- self.writer.swap();
161161+ // release the read lock
162162+ self.state.fetch_and(0b100, Ordering::Release);
212163 }
213164}
214165215215-/// Not realtime safe Object which can change the internal T value
166166+/// Not realtime safe object which can change the internal T value.
216167#[derive(Debug)]
217168pub struct Writer<T, O> {
218218- shared: Arc<Shared<T>>,
169169+ shared: NonNull<Shared<T>>,
219170 // sets which buffer the next write is applied to
220171 // write_ptr doesn't need to be Atomics as it only changes, when the Writer itself swaps
221172 write_ptr: Ptr,
222173 // buffer is pushed at the back and popped at the front.
223174 op_buffer: VecDeque<O>,
175175+ // needed for drop_check
176176+ _own: PhantomData<Shared<T>>,
224177}
225178226179impl<T, O> Writer<T, O> {
180180+ const fn shared_ref(&self) -> &Shared<T> {
181181+ // SAFETY: Reader always has a valid Shared<T>, a mut ref to a shared is never created,
182182+ // only to the UnsafeCell<T>s inside of it
183183+ unsafe { self.shared.as_ref() }
184184+ }
185185+227186 /// swaps the read and write values. If no changes were made since the last swap nothing happens. Never blocks
228228- /// not public as swapping without creating a `WriteGuard` is pretty
187187+ /// not public as swapping without creating a before `WriteGuard` is pretty useless
229188 fn swap(&mut self) {
230189 if self.op_buffer.is_empty() {
231190 return;
232191 }
233192234193 match self.write_ptr {
235235- Ptr::Value1 => self.shared.state.fetch_and(0b011, Ordering::Release),
236236- Ptr::Value2 => self.shared.state.fetch_or(0b100, Ordering::Release),
194194+ Ptr::Value1 => self.shared_ref().state.fetch_and(0b011, Ordering::Release),
195195+ Ptr::Value2 => self.shared_ref().state.fetch_or(0b100, Ordering::Release),
237196 };
238197239198 self.write_ptr.switch();
···241200242201 /// get a Reader if none exists
243202 pub fn build_reader(&mut self) -> Option<Reader<T>> {
244244- if Arc::get_mut(&mut self.shared).is_some() {
245245- Some(Reader {
246246- inner: self.shared.clone(),
247247- })
248248- } else {
249249- None
250250- }
251251- }
252252-253253- /// The Value returned may be newer than the version the reader is currently seeing.
254254- /// This value will be written to next.
255255- #[must_use]
256256- pub fn read(&self) -> &T {
257257- // SAFETY: Only the WriteGuard can write to the values / create mut refs to them.
258258- // The WriteGuard holds a mut ref to the writer so this function can't be called while a writeguard exists
259259- // This means that reading them / creating refs is safe to do
203203+ // SAFETY: all is_unique_with_increase requirements are satisfied.
260204 unsafe {
261261- self.shared
262262- .get_value(self.write_ptr)
263263- .get()
264264- .as_ref()
265265- .unwrap_unchecked()
205205+ if self.shared_ref().is_unique_with_increase() {
206206+ Some(Reader {
207207+ shared: self.shared,
208208+ _own: PhantomData,
209209+ })
210210+ } else {
211211+ None
212212+ }
266213 }
267214 }
268215}
···276223277224 loop {
278225 // operation has to be aquire, but only the time it breaks the loop
279279- let state = self.shared.state.load(Ordering::Relaxed);
226226+ let state = self.shared_ref().state.load(Ordering::Relaxed);
280227281228 // SAFETY: is in state internal only value which is only set by library code
282229 let state = unsafe { ReadState::from_u8_ignore_ptr(state) };
···306253307254 loop {
308255 // operation has to be aquire, but only the time it breaks the loop
309309- let state = self.shared.state.load(Ordering::Relaxed);
256256+ let state = self.shared_ref().state.load(Ordering::Relaxed);
310257311258 // SAFETY: is in state internal only value which is only set by library code
312259 let state = unsafe { ReadState::from_u8_ignore_ptr(state) };
···338285339286 loop {
340287 // operation has to be aquire, but only the time it breaks the loop
341341- let state = self.shared.state.load(Ordering::Relaxed);
288288+ let state = self.shared_ref().state.load(Ordering::Relaxed);
342289343290 // SAFETY: is in state internal only value which is only set by library code
344291 let state = unsafe { ReadState::from_u8_ignore_ptr(state) };
···365312366313 /// doesn't block. Returns None if the Reader has a `ReadGuard` pointing to the old value
367314 pub fn try_lock(&mut self) -> Option<WriteGuard<'_, T, O>> {
368368- let state = self.shared.state.load(Ordering::Acquire);
315315+ let state = self.shared_ref().state.load(Ordering::Acquire);
369316370317 // SAFETY: is in state internal only value which is only set by library code
371318 let state = unsafe { ReadState::from_u8_ignore_ptr(state) };
···382329impl<T: Clone, O> Writer<T, O> {
383330 /// Creates a new Writer by cloning the value once to get two values
384331 pub fn new(value: T) -> Self {
385385- let mut shared: Arc<MaybeUninit<Shared<T>>> = Arc::new_uninit();
332332+ // SAFETY: ptr was just alloced, so is valid and unique.
333333+ let mut shared: Box<MaybeUninit<Shared<T>>> = Box::new_uninit();
334334+ Shared::initialize_state(&mut shared);
335335+ let shared_ptr = shared.as_mut_ptr();
386336387387- // SAFETY: Arc was just created, therefore no one has acces to it.
388388- // Every field gets initialized
337337+ // SAFETY: Every field gets initialized, ptr is valid and doesn't alias
389338 let shared = unsafe {
390390- let shared_ptr = Arc::get_mut(&mut shared).unwrap_unchecked().as_mut_ptr();
391391- (&raw mut (*shared_ptr).state).write(AtomicU8::new(0b000));
392339 UnsafeCell::raw_get(&raw const (*shared_ptr).value_1).write(value.clone());
393393- UnsafeCell::raw_get(&raw const (*shared_ptr).value_1).write(value);
394394- shared.assume_init()
340340+ UnsafeCell::raw_get(&raw const (*shared_ptr).value_2).write(value);
341341+ // consumes the Box<MaybeUninit> and creates the NonNull with an initialized value
342342+ NonNull::new_unchecked(Box::into_raw(shared.assume_init()))
395343 };
396344397345 Writer {
398346 shared,
399347 write_ptr: Ptr::Value2,
400348 op_buffer: VecDeque::new(),
349349+ _own: PhantomData,
401350 }
402351 }
403352}
···409358 ///
410359 /// Could leak a T object if T::default() panics.
411360 fn default() -> Self {
412412- let mut shared: Arc<MaybeUninit<Shared<T>>> = Arc::new_uninit();
361361+ // SAFETY: ptr was just alloced, so is valid and unique.
362362+ let mut shared: Box<MaybeUninit<Shared<T>>> = Box::new_uninit();
363363+ Shared::initialize_state(&mut shared);
364364+ let shared_ptr = shared.as_mut_ptr();
413365414414- // SAFETY: Arc was just created, therefore no one has acces to it.
415415- // Every field gets initialized
366366+ // SAFETY: Every field gets initialized, ptr is valid and doesn't alias
416367 let shared = unsafe {
417417- let shared_ptr = Arc::get_mut(&mut shared).unwrap_unchecked().as_mut_ptr();
418418- (&raw mut (*shared_ptr).state).write(AtomicU8::new(0b000));
419368 UnsafeCell::raw_get(&raw const (*shared_ptr).value_1).write(T::default());
420420- UnsafeCell::raw_get(&raw const (*shared_ptr).value_1).write(T::default());
421421- shared.assume_init()
369369+ UnsafeCell::raw_get(&raw const (*shared_ptr).value_2).write(T::default());
370370+ // consumes the Box<MaybeUninit> and creates the NonNull with an initialized value
371371+ NonNull::new_unchecked(Box::into_raw(shared.assume_init()))
422372 };
423373424374 Writer {
425375 shared,
426376 write_ptr: Ptr::Value2,
427377 op_buffer: VecDeque::new(),
378378+ _own: PhantomData,
428379 }
429380 }
430381}
382382+383383+impl<T: Sync, O> Writer<T, O> {
384384+ /// The Value returned may be newer than the version the reader is currently seeing.
385385+ /// This value will be written to next.
386386+ ///
387387+ /// Needs T: Sync because maybe this is the value the reader is curently reading
388388+ pub fn read(&self) -> &T {
389389+ // SAFETY: Only the WriteGuard can write to the values / create mut refs to them.
390390+ // The WriteGuard holds a mut ref to the writer so this function can't be called while a writeguard exists
391391+ // This means that reading them / creating refs is safe to do
392392+ unsafe {
393393+ self.shared_ref()
394394+ .get_value(self.write_ptr)
395395+ .get()
396396+ .as_ref()
397397+ .unwrap_unchecked()
398398+ }
399399+ }
400400+}
401401+402402+/// SAFETY: owns T and O
403403+unsafe impl<T: Send, O: Send> Send for Writer<T, O> {}
404404+/// SAFETY: &self fn can only create a &T and doesn't allow access to O
405405+unsafe impl<T: Sync, O> Sync for Writer<T, O> {}
406406+407407+impl<T, O> Drop for Writer<T, O> {
408408+ fn drop(&mut self) {
409409+ // SAFETY: Shared.should_drop() is called. on true object really is dropped. on false it isnt.
410410+ // This is the last use of self and therefore also of Shared
411411+ unsafe {
412412+ let should_drop = self.shared_ref().should_drop();
413413+ if should_drop {
414414+ _ = Box::from_raw(self.shared.as_ptr());
415415+ }
416416+ }
417417+ }
418418+}
419419+420420+// Don't create a WriteGuard directly, as that wouldn't sync with old Operations
421421+/// Can be used to write to the Data structure.
422422+///
423423+/// When this structure exists the Reader already switched to the other value
424424+///
425425+/// Dropping this makes all changes available to the Reader.
426426+#[derive(Debug)]
427427+pub struct WriteGuard<'a, T, O> {
428428+ writer: &'a mut Writer<T, O>,
429429+}
430430+431431+impl<T, O> WriteGuard<'_, T, O> {
432432+ /// Makes the changes available to the reader. Equivalent to std::mem::drop(self)
433433+ pub fn swap(self) {}
434434+435435+ /// Gets the value currently being written to.
436436+ pub fn read(&self) -> &T {
437437+ // SAFETY: Only the WriteGuard can write to the values / create mut refs to them.
438438+ // The WriteGuard holds a mut ref to the writer so this function can't be called while a writeguard exists
439439+ // This means that reading them / creating refs is safe to do
440440+ unsafe {
441441+ self.writer.shared_ref()
442442+ .get_value(self.writer.write_ptr)
443443+ .get()
444444+ .as_ref()
445445+ .unwrap_unchecked()
446446+ }
447447+ }
448448+449449+ /// Isn't public as this could easily create disconnects between the two versions.
450450+ /// While that wouldn't lead to UB it goes against the purpose of this library
451451+ fn get_data_mut(&mut self) -> &mut T {
452452+ // SAFETY: When creating the writeguad it is checked that the reader doesnt have access to the same data
453453+ // This function requires &mut self so there also isn't any ref created by writeguard.
454454+ // SAFETY: the ptr is never null, therefore unwrap_unchecked
455455+ unsafe {
456456+ self.writer
457457+ .shared_ref()
458458+ .get_value(self.writer.write_ptr)
459459+ .get()
460460+ .as_mut()
461461+ .unwrap_unchecked()
462462+ }
463463+ }
464464+}
465465+466466+impl<'a, T: Absorb<O>, O> WriteGuard<'a, T, O> {
467467+ /// created a new `WriteGuard` and syncs the two values if needed.
468468+ ///
469469+ /// ### SAFETY
470470+ /// No `ReadGuard` is allowed to exist to the same value the `Writer.write_ptr` points to
471471+ ///
472472+ /// Assuming a correct `Reader` & `ReadGuard` implementation:
473473+ /// If Inner.read_state.can_write(Writer.write_ptr) == true this function is fine to call
474474+ unsafe fn new(writer: &'a mut Writer<T, O>) -> Self {
475475+ let mut guard = Self { writer };
476476+ while let Some(operation) = guard.writer.op_buffer.pop_front() {
477477+ guard.get_data_mut().absorb(operation);
478478+ }
479479+ guard
480480+ }
481481+}
482482+483483+impl<T: Absorb<O>, O: Clone> WriteGuard<'_, T, O> {
484484+ /// applies operation to the current write Value and stores it to apply to the other later.
485485+ /// If there is no reader the operation is applied to both values immediately and not stored.
486486+ pub fn apply_op(&mut self, operation: O) {
487487+ if self.writer.shared_ref().is_unique() {
488488+ let shared_ref = self.writer.shared_ref();
489489+ // SAFETY: is_unique checked that no Reader exists. I am the only one with access to Shared<T>, so i can modify whatever i want.
490490+ unsafe {
491491+ (*shared_ref.value_1.get()).absorb(operation.clone());
492492+ (*shared_ref.value_2.get()).absorb(operation);
493493+ }
494494+ } else {
495495+ self.writer.op_buffer.push_back(operation.clone());
496496+ self.get_data_mut().absorb(operation);
497497+ }
498498+ }
499499+}
500500+501501+/// SAFETY: behaves like a &mut T and &mut Vec<O>. https://doc.rust-lang.org/stable/std/marker/trait.Sync.html
502502+unsafe impl<T: Send, O: Send> Send for WriteGuard<'_, T, O> {}
503503+504504+/// Safety: can only create shared refs to T, not to O. https://doc.rust-lang.org/stable/std/marker/trait.Sync.html
505505+unsafe impl<T: Sync, O> Sync for WriteGuard<'_, T, O> {}
506506+507507+impl<T, O> Drop for WriteGuard<'_, T, O> {
508508+ fn drop(&mut self) {
509509+ self.writer.swap();
510510+ }
511511+}