mapped_file/ring/
buffer.rs1use super::*;
5use std::{
6 borrow::Borrow,
7 ops,
8 sync,
9 rc,
10};
11
12pub trait TwoBufferProvider<T: ?Sized>
13{
14 type ControlWrapper: Borrow<T>;
15
16 fn as_wrapper(&self) -> &Self::ControlWrapper;
17 fn from_wrapper_boxed(r: &Self::ControlWrapper) -> Box<Self>;
18
19 #[inline(always)]
20 fn from_wrapper(r: &Self::ControlWrapper) -> Self
21 where Self: Sized {
22 *Self::from_wrapper_boxed(r)
23 }
24
25 #[inline(always)]
26 fn inner(&self) -> &T
27 {
28 self.as_wrapper().borrow()
29 }
30
31 fn from_boxed(value: Box<T>) -> Box<Self>;
32
33 #[inline(always)]
34 fn from_value(value: T) -> Self
35 where T: Sized,
36 Self: Sized
37 {
38 *Self::from_boxed(Box::new(value))
39 }
40}
41
42#[derive(Debug)]
44pub struct Shared<T: ?Sized>(sync::Arc<T>);
45
46#[derive(Debug)]
48pub struct Private<T: ?Sized>(rc::Rc<T>);
49
50impl<T: ?Sized> TwoBufferProvider<T> for Shared<T> {
51 type ControlWrapper = sync::Arc<T>;
52
53 #[inline(always)]
54 fn as_wrapper(&self) -> &Self::ControlWrapper {
55 &self.0
56 }
57
58 #[inline]
59 fn from_boxed(value: Box<T>) ->Box<Self> {
60 Box::new(Self(From::from(value)))
61 }
62
63 #[inline(always)]
64 fn from_value(value: T) -> Self
65 where T: Sized,
66 Self: Sized {
67 Self(sync::Arc::new(value))
68 }
69
70 #[inline]
71 fn from_wrapper_boxed(r: &Self::ControlWrapper) -> Box<Self> {
72 Box::new(Self(r.clone()))
73 }
74 #[inline(always)]
75 fn from_wrapper(r: &Self::ControlWrapper) -> Self
76 where Self: Sized {
77 Self(r.clone())
78 }
79}
80
81impl<T: ?Sized + AsRawFd> AsRawFd for Shared<T>
82{
83 #[inline(always)]
84 fn as_raw_fd(&self) -> RawFd {
85 self.as_wrapper().as_raw_fd()
86 }
87}
88
89impl<T: ?Sized> TwoBufferProvider<T> for Private<T> {
90 type ControlWrapper = rc::Rc<T>;
91
92 #[inline(always)]
93 fn as_wrapper(&self) -> &Self::ControlWrapper {
94 &self.0
95 }
96
97 #[inline]
98 fn from_boxed(value: Box<T>) ->Box<Self> {
99 Box::new(Self(From::from(value)))
100 }
101
102 #[inline(always)]
103 fn from_value(value: T) -> Self
104 where T: Sized,
105 Self: Sized {
106 Self(rc::Rc::new(value))
107 }
108
109 #[inline]
110 fn from_wrapper_boxed(r: &Self::ControlWrapper) -> Box<Self> {
111 Box::new(Self(r.clone()))
112 }
113 #[inline(always)]
114 fn from_wrapper(r: &Self::ControlWrapper) -> Self
115 where Self: Sized {
116 Self(r.clone())
117 }
118}
119
120impl<T: ?Sized + AsRawFd> AsRawFd for Private<T>
121{
122 #[inline(always)]
123 fn as_raw_fd(&self) -> RawFd {
124 self.as_wrapper().as_raw_fd()
125 }
126}
127
128impl<T: ?Sized> Shared<T>
129{
130 #[inline]
132 pub fn is_connected(&self) -> bool
133 {
134 sync::Arc::strong_count(&self.0) > 1
135 }
136
137 #[inline]
139 pub fn into_arc(self) -> sync::Arc<T>
140 {
141 self.0
142 }
143
144 #[inline]
146 pub fn inner(&self) -> &T
147 {
148 &self.0
149 }
150}
151impl<T: ?Sized> Private<T>
152{
153 #[inline]
155 pub fn is_connected(&self) -> bool
156 {
157 rc::Rc::strong_count(&self.0) > 1
158 }
159
160 #[inline]
162 pub fn into_rc(self) -> rc::Rc<T>
163 {
164 self.0
165 }
166
167 #[inline]
169 pub fn inner(&self) -> &T
170 {
171 &self.0
172 }
173}
174
175pub trait BufferExt<T>
178{
179 fn detach(txrx: Self) -> (MappedFile<T>, MappedFile<T>);
180}
181
182impl<B, T> BufferExt<T> for (MappedFile<B>, MappedFile<B>)
183where B: TwoBufferProvider<T> + AsRawFd,
184T: FromRawFd,
185{
186 #[inline]
188 fn detach((itx, irx): Self) -> (MappedFile<T>, MappedFile<T>) {
189 #[cold]
190 #[inline(never)]
191 fn _panic_bad_dup(fd: RawFd) -> !
192 {
193 panic!("Failed to dup({fd}): {}", io::Error::last_os_error())
194 }
195 let tx = itx.file.as_raw_fd();
196 let rx = irx.file.as_raw_fd();
197
198 let (f0, f1) = unsafe {
199 let fd1 = libc::dup(tx);
200 if fd1 < 0 {
201 _panic_bad_dup(tx);
202 }
203 let fd2 = libc::dup(rx);
204 if fd2 < 0 {
205 _panic_bad_dup(rx);
206 }
207 (T::from_raw_fd(fd1), T::from_raw_fd(fd2))
208 };
209 (MappedFile {
210 map: itx.map,
211 file: f0,
212 }, MappedFile {
213 map: irx.map,
214 file: f1
215 })
216 }
217}