1#[cfg(feature = "alloc")]
2use crate::alias::Arc;
3#[cfg(feature = "std")]
4use crate::sync::StdSemaphore;
5use crate::{sync::Semaphore, BlockingCons, BlockingProd};
6use core::{mem::MaybeUninit, num::NonZeroUsize};
7#[cfg(feature = "alloc")]
8use ringbuf::traits::Split;
9use ringbuf::{
10 rb::RbRef,
11 storage::Storage,
12 traits::{Consumer, Observer, Producer, RingBuffer, SplitRef},
13 SharedRb,
14};
15
16#[cfg(not(feature = "std"))]
17pub struct BlockingRb<S: Storage, X: Semaphore> {
18 base: SharedRb<S>,
19 pub(crate) read: X,
20 pub(crate) write: X,
21}
22#[cfg(feature = "std")]
23pub struct BlockingRb<S: Storage, X: Semaphore = StdSemaphore> {
24 base: SharedRb<S>,
25 pub(crate) read: X,
26 pub(crate) write: X,
27}
28
29impl<S: Storage, X: Semaphore> BlockingRb<S, X> {
30 pub fn from(base: SharedRb<S>) -> Self {
31 Self {
32 base,
33 read: X::default(),
34 write: X::default(),
35 }
36 }
37}
38
39impl<S: Storage, X: Semaphore> Observer for BlockingRb<S, X> {
40 type Item = S::Item;
41
42 #[inline]
43 fn capacity(&self) -> NonZeroUsize {
44 self.base.capacity()
45 }
46
47 #[inline]
48 fn read_index(&self) -> usize {
49 self.base.read_index()
50 }
51 #[inline]
52 fn write_index(&self) -> usize {
53 self.base.write_index()
54 }
55
56 unsafe fn unsafe_slices(&self, start: usize, end: usize) -> (&[MaybeUninit<S::Item>], &[MaybeUninit<S::Item>]) {
57 self.base.unsafe_slices(start, end)
58 }
59 unsafe fn unsafe_slices_mut(&self, start: usize, end: usize) -> (&mut [MaybeUninit<S::Item>], &mut [MaybeUninit<S::Item>]) {
60 self.base.unsafe_slices_mut(start, end)
61 }
62
63 #[inline]
64 fn read_is_held(&self) -> bool {
65 self.base.read_is_held()
66 }
67 #[inline]
68 fn write_is_held(&self) -> bool {
69 self.base.write_is_held()
70 }
71}
72impl<S: Storage, X: Semaphore> Producer for BlockingRb<S, X> {
73 unsafe fn set_write_index(&self, value: usize) {
74 self.base.set_write_index(value);
75 self.write.give();
76 }
77}
78impl<S: Storage, X: Semaphore> Consumer for BlockingRb<S, X> {
79 unsafe fn set_read_index(&self, value: usize) {
80 self.base.set_read_index(value);
81 self.read.give();
82 }
83}
84impl<S: Storage, X: Semaphore> RingBuffer for BlockingRb<S, X> {
85 unsafe fn hold_read(&self, flag: bool) -> bool {
86 let old = self.base.hold_read(flag);
87 self.read.give();
88 old
89 }
90 unsafe fn hold_write(&self, flag: bool) -> bool {
91 let old = self.base.hold_write(flag);
92 self.write.give();
93 old
94 }
95}
96
97impl<S: Storage, X: Semaphore> SplitRef for BlockingRb<S, X> {
98 type RefProd<'a>
99 = BlockingProd<&'a Self>
100 where
101 Self: 'a;
102 type RefCons<'a>
103 = BlockingCons<&'a Self>
104 where
105 Self: 'a;
106
107 fn split_ref(&mut self) -> (Self::RefProd<'_>, Self::RefCons<'_>) {
108 (BlockingProd::new(self), BlockingCons::new(self))
109 }
110}
111#[cfg(feature = "alloc")]
112impl<S: Storage, X: Semaphore> Split for BlockingRb<S, X> {
113 type Prod = BlockingProd<Arc<Self>>;
114 type Cons = BlockingCons<Arc<Self>>;
115
116 fn split(self) -> (Self::Prod, Self::Cons) {
117 let arc = Arc::new(self);
118 (BlockingProd::new(arc.clone()), BlockingCons::new(arc))
119 }
120}
121
122pub trait BlockingRbRef: RbRef<Rb = BlockingRb<Self::Storage, Self::Semaphore>> {
123 type Storage: Storage;
124 type Semaphore: Semaphore;
125}
126impl<S: Storage, X: Semaphore, R: RbRef<Rb = BlockingRb<S, X>>> BlockingRbRef for R {
127 type Storage = S;
128 type Semaphore = X;
129}
130
131impl<S: Storage, X: Semaphore> AsRef<Self> for BlockingRb<S, X> {
132 fn as_ref(&self) -> &Self {
133 self
134 }
135}
136impl<S: Storage, X: Semaphore> AsMut<Self> for BlockingRb<S, X> {
137 fn as_mut(&mut self) -> &mut Self {
138 self
139 }
140}