diff --git a/async/src/rb.rs b/async/src/rb.rs index bed9b25..bdb045b 100644 --- a/async/src/rb.rs +++ b/async/src/rb.rs @@ -82,12 +82,12 @@ impl Consumer for AsyncRb { } impl RingBuffer for AsyncRb { #[inline] - fn hold_read(&self, flag: bool) { + unsafe fn hold_read(&self, flag: bool) { self.base.hold_read(flag); self.read.wake() } #[inline] - fn hold_write(&self, flag: bool) { + unsafe fn hold_write(&self, flag: bool) { self.base.hold_write(flag); self.write.wake() } diff --git a/async/src/wrap/cons.rs b/async/src/wrap/cons.rs index 7ba9935..cb8642f 100644 --- a/async/src/wrap/cons.rs +++ b/async/src/wrap/cons.rs @@ -16,18 +16,18 @@ use std::io; impl Consumer for AsyncCons { #[inline] unsafe fn set_read_index(&self, value: usize) { - self.base.set_read_index(value) + self.base().set_read_index(value) } #[inline] fn try_pop(&mut self) -> Option { - self.base.try_pop() + self.base_mut().try_pop() } #[inline] fn pop_slice(&mut self, elems: &mut [Self::Item]) -> usize where Self::Item: Copy, { - self.base.pop_slice(elems) + self.base_mut().pop_slice(elems) } } @@ -38,7 +38,7 @@ impl AsyncConsumer for AsyncCons { #[inline] fn close(&mut self) { - self.base.close(); + drop(self.base.take()); } } diff --git a/async/src/wrap/mod.rs b/async/src/wrap/mod.rs index 6098fcb..35bce1d 100644 --- a/async/src/wrap/mod.rs +++ b/async/src/wrap/mod.rs @@ -6,7 +6,7 @@ use core::{mem::MaybeUninit, num::NonZeroUsize}; use ringbuf::{rb::traits::ToRbRef, traits::Observer, wrap::caching::Caching, Obs}; pub struct AsyncWrap { - base: Caching, + base: Option>, } pub type AsyncProd = AsyncWrap; @@ -14,21 +14,30 @@ pub type AsyncCons = AsyncWrap; impl AsyncWrap { pub unsafe fn new(rb: R) -> Self { - Self { base: Caching::new(rb) } + Self { + base: Some(Caching::new(rb)), + } + } + + fn base(&self) -> &Caching { + self.base.as_ref().unwrap() + } + fn base_mut(&mut self) -> &mut Caching { + self.base.as_mut().unwrap() } pub fn observe(&self) -> Obs { - self.base.observe() + self.base().observe() } } impl ToRbRef for AsyncWrap { type RbRef = R; fn rb_ref(&self) -> &R { - self.base.rb_ref() + self.base().rb_ref() } fn into_rb_ref(self) -> R { - self.base.into_rb_ref() + self.base.unwrap().into_rb_ref() } } @@ -39,27 +48,27 @@ impl Observer for AsyncWrap NonZeroUsize { - self.base.capacity() + self.base().capacity() } #[inline] fn read_index(&self) -> usize { - self.base.read_index() + self.base().read_index() } #[inline] fn write_index(&self) -> usize { - self.base.write_index() + self.base().write_index() } #[inline] unsafe fn unsafe_slices(&self, start: usize, end: usize) -> (&mut [MaybeUninit], &mut [MaybeUninit]) { - self.base.unsafe_slices(start, end) + self.base().unsafe_slices(start, end) } #[inline] fn read_is_held(&self) -> bool { - self.base.read_is_held() + self.base().read_is_held() } #[inline] fn write_is_held(&self) -> bool { - self.base.write_is_held() + self.base().write_is_held() } } diff --git a/async/src/wrap/prod.rs b/async/src/wrap/prod.rs index bc47174..a50e027 100644 --- a/async/src/wrap/prod.rs +++ b/async/src/wrap/prod.rs @@ -16,23 +16,23 @@ use std::io; impl Producer for AsyncProd { #[inline] unsafe fn set_write_index(&self, value: usize) { - self.base.set_write_index(value) + self.base().set_write_index(value) } #[inline] fn try_push(&mut self, elem: Self::Item) -> Result<(), Self::Item> { - self.base.try_push(elem) + self.base_mut().try_push(elem) } #[inline] fn push_iter>(&mut self, iter: I) -> usize { - self.base.push_iter(iter) + self.base_mut().push_iter(iter) } #[inline] fn push_slice(&mut self, elems: &[Self::Item]) -> usize where Self::Item: Copy, { - self.base.push_slice(elems) + self.base_mut().push_slice(elems) } } @@ -43,7 +43,7 @@ impl AsyncProducer for AsyncProd { #[inline] fn close(&mut self) { - self.base.close(); + drop(self.base.take()); } } diff --git a/src/rb/local.rs b/src/rb/local.rs index af3b7a7..2309fa2 100644 --- a/src/rb/local.rs +++ b/src/rb/local.rs @@ -112,11 +112,11 @@ impl Consumer for LocalRb { impl RingBuffer for LocalRb { #[inline] - fn hold_read(&self, flag: bool) { + unsafe fn hold_read(&self, flag: bool) { self.read.held.set(flag) } #[inline] - fn hold_write(&self, flag: bool) { + unsafe fn hold_write(&self, flag: bool) { self.write.held.set(flag) } } diff --git a/src/rb/shared.rs b/src/rb/shared.rs index 36116a5..5b8dc84 100644 --- a/src/rb/shared.rs +++ b/src/rb/shared.rs @@ -126,11 +126,11 @@ impl Consumer for SharedRb { impl RingBuffer for SharedRb { #[inline] - fn hold_read(&self, flag: bool) { + unsafe fn hold_read(&self, flag: bool) { self.read_held.store(flag, Ordering::Relaxed) } #[inline] - fn hold_write(&self, flag: bool) { + unsafe fn hold_write(&self, flag: bool) { self.write_held.store(flag, Ordering::Relaxed) } } diff --git a/src/traits/ring_buffer.rs b/src/traits/ring_buffer.rs index c3f09e9..1cb6e6b 100644 --- a/src/traits/ring_buffer.rs +++ b/src/traits/ring_buffer.rs @@ -49,6 +49,6 @@ pub trait RingBuffer: Observer + Consumer + Producer { }); } - fn hold_read(&self, flag: bool); - fn hold_write(&self, flag: bool); + unsafe fn hold_read(&self, flag: bool); + unsafe fn hold_write(&self, flag: bool); } diff --git a/src/wrap/caching.rs b/src/wrap/caching.rs index 654f1f8..fe5e9d5 100644 --- a/src/wrap/caching.rs +++ b/src/wrap/caching.rs @@ -31,10 +31,6 @@ impl Caching { pub fn freeze(self) -> Frozen { self.frozen } - - pub fn close(&mut self) { - self.frozen.close(); - } } impl ToRbRef for Caching { diff --git a/src/wrap/direct.rs b/src/wrap/direct.rs index d438b6a..db483a8 100644 --- a/src/wrap/direct.rs +++ b/src/wrap/direct.rs @@ -37,11 +37,11 @@ impl Direct { pub fn new(rb: R) -> Self { if P { assert!(!rb.deref().write_is_held()); - rb.deref().hold_write(true); + unsafe { rb.deref().hold_write(true) }; } if C { assert!(!rb.deref().read_is_held()); - rb.deref().hold_read(true); + unsafe { rb.deref().hold_read(true) }; } Self { rb } } @@ -55,7 +55,10 @@ impl Direct { unsafe { Frozen::new_unchecked(ptr::read(&this.rb)) } } - pub fn close(&mut self) { + /// # Safety + /// + /// Must not be used after this call. + unsafe fn close(&mut self) { if P { self.rb().hold_write(false); } @@ -71,9 +74,11 @@ impl ToRbRef for Direct { &self.rb } fn into_rb_ref(mut self) -> R { - self.close(); - let this = ManuallyDrop::new(self); - unsafe { ptr::read(&this.rb) } + unsafe { + self.close(); + let this = ManuallyDrop::new(self); + ptr::read(&this.rb) + } } } @@ -133,7 +138,7 @@ impl Consumer for Cons { impl Drop for Direct { fn drop(&mut self) { - self.close(); + unsafe { self.close() }; } } diff --git a/src/wrap/frozen.rs b/src/wrap/frozen.rs index 7bb806c..402b21b 100644 --- a/src/wrap/frozen.rs +++ b/src/wrap/frozen.rs @@ -41,11 +41,11 @@ impl Frozen { pub fn new(rb: R) -> Self { if P { assert!(!rb.deref().write_is_held()); - rb.deref().hold_write(true); + unsafe { rb.deref().hold_write(true) }; } if C { assert!(!rb.deref().read_is_held()); - rb.deref().hold_read(true); + unsafe { rb.deref().hold_read(true) }; } unsafe { Self::new_unchecked(rb) } } @@ -62,7 +62,7 @@ impl Frozen { Obs::new(self.rb.clone()) } - pub fn close(&mut self) { + unsafe fn close(&mut self) { if P { self.rb().hold_write(false); } @@ -80,9 +80,11 @@ impl ToRbRef for Frozen { } fn into_rb_ref(mut self) -> R { self.commit(); - self.close(); - let this = ManuallyDrop::new(self); - unsafe { ptr::read(&this.rb) } + unsafe { + self.close(); + let this = ManuallyDrop::new(self); + ptr::read(&this.rb) + } } } @@ -187,7 +189,7 @@ impl Consumer for FrozenCons { impl Drop for Frozen { fn drop(&mut self) { self.commit(); - self.close(); + unsafe { self.close() }; } }