ringbuf/rb/
local.rs
1use super::{macros::rb_impl_init, utils::ranges};
2#[cfg(feature = "alloc")]
3use crate::traits::Split;
4use crate::{
5 storage::Storage,
6 traits::{
7 consumer::{impl_consumer_traits, Consumer},
8 producer::{impl_producer_traits, Producer},
9 Observer, RingBuffer, SplitRef,
10 },
11 wrap::{Cons, Prod},
12};
13#[cfg(feature = "alloc")]
14use alloc::{boxed::Box, rc::Rc};
15use core::{
16 cell::Cell,
17 mem::{ManuallyDrop, MaybeUninit},
18 num::NonZeroUsize,
19 ptr,
20};
21
22struct End {
23 index: Cell<usize>,
24 held: Cell<bool>,
25}
26
27impl End {
28 fn new(index: usize) -> Self {
29 Self {
30 index: Cell::new(index),
31 held: Cell::new(false),
32 }
33 }
34}
35
36pub struct LocalRb<S: Storage + ?Sized> {
40 read: End,
41 write: End,
42 storage: S,
43}
44
45impl<S: Storage> LocalRb<S> {
46 pub unsafe fn from_raw_parts(storage: S, read: usize, write: usize) -> Self {
53 assert!(!storage.is_empty());
54 Self {
55 storage,
56 read: End::new(read),
57 write: End::new(write),
58 }
59 }
60 pub unsafe fn into_raw_parts(self) -> (S, usize, usize) {
66 let this = ManuallyDrop::new(self);
67 (ptr::read(&this.storage), this.read_index(), this.write_index())
68 }
69}
70
71impl<S: Storage + ?Sized> Observer for LocalRb<S> {
72 type Item = S::Item;
73
74 #[inline]
75 fn capacity(&self) -> NonZeroUsize {
76 unsafe { NonZeroUsize::new_unchecked(self.storage.len()) }
77 }
78
79 #[inline]
80 fn read_index(&self) -> usize {
81 self.read.index.get()
82 }
83 #[inline]
84 fn write_index(&self) -> usize {
85 self.write.index.get()
86 }
87
88 unsafe fn unsafe_slices(&self, start: usize, end: usize) -> (&[MaybeUninit<S::Item>], &[MaybeUninit<S::Item>]) {
89 let (first, second) = ranges(self.capacity(), start, end);
90 (self.storage.slice(first), self.storage.slice(second))
91 }
92 unsafe fn unsafe_slices_mut(&self, start: usize, end: usize) -> (&mut [MaybeUninit<S::Item>], &mut [MaybeUninit<S::Item>]) {
93 let (first, second) = ranges(self.capacity(), start, end);
94 (self.storage.slice_mut(first), self.storage.slice_mut(second))
95 }
96
97 #[inline]
98 fn read_is_held(&self) -> bool {
99 self.read.held.get()
100 }
101 #[inline]
102 fn write_is_held(&self) -> bool {
103 self.write.held.get()
104 }
105}
106
107impl<S: Storage + ?Sized> Producer for LocalRb<S> {
108 #[inline]
109 unsafe fn set_write_index(&self, value: usize) {
110 self.write.index.set(value);
111 }
112}
113
114impl<S: Storage + ?Sized> Consumer for LocalRb<S> {
115 #[inline]
116 unsafe fn set_read_index(&self, value: usize) {
117 self.read.index.set(value);
118 }
119}
120
121impl<S: Storage + ?Sized> RingBuffer for LocalRb<S> {
122 #[inline]
123 unsafe fn hold_read(&self, flag: bool) -> bool {
124 self.read.held.replace(flag)
125 }
126 #[inline]
127 unsafe fn hold_write(&self, flag: bool) -> bool {
128 self.write.held.replace(flag)
129 }
130}
131
132impl<S: Storage + ?Sized> Drop for LocalRb<S> {
133 fn drop(&mut self) {
134 self.clear();
135 }
136}
137
138#[cfg(feature = "alloc")]
139impl<S: Storage> Split for LocalRb<S> {
140 type Prod = Prod<Rc<Self>>;
141 type Cons = Cons<Rc<Self>>;
142
143 fn split(self) -> (Self::Prod, Self::Cons) {
144 Rc::new(self).split()
145 }
146}
147#[cfg(feature = "alloc")]
148impl<S: Storage + ?Sized> Split for Rc<LocalRb<S>> {
149 type Prod = Prod<Self>;
150 type Cons = Cons<Self>;
151
152 fn split(self) -> (Self::Prod, Self::Cons) {
153 (Prod::new(self.clone()), Cons::new(self))
154 }
155}
156#[cfg(feature = "alloc")]
157impl<S: Storage + ?Sized> Split for Box<LocalRb<S>> {
158 type Prod = Prod<Rc<LocalRb<S>>>;
159 type Cons = Cons<Rc<LocalRb<S>>>;
160
161 fn split(self) -> (Self::Prod, Self::Cons) {
162 Rc::<LocalRb<S>>::from(self).split()
163 }
164}
165impl<S: Storage + ?Sized> SplitRef for LocalRb<S> {
166 type RefProd<'a> = Prod<&'a Self> where Self: 'a;
167 type RefCons<'a> = Cons<&'a Self> where Self: 'a;
168
169 fn split_ref(&mut self) -> (Self::RefProd<'_>, Self::RefCons<'_>) {
170 (Prod::new(self), Cons::new(self))
171 }
172}
173
174rb_impl_init!(LocalRb);
175
176impl_producer_traits!(LocalRb<S: Storage>);
177impl_consumer_traits!(LocalRb<S: Storage>);
178
179impl<S: Storage + ?Sized> AsRef<Self> for LocalRb<S> {
180 fn as_ref(&self) -> &Self {
181 self
182 }
183}
184impl<S: Storage + ?Sized> AsMut<Self> for LocalRb<S> {
185 fn as_mut(&mut self) -> &mut Self {
186 self
187 }
188}