1use core::pin::Pin;
13use core::task::{Context, Poll};
14use std::io;
15use std::sync::Arc;
16
17use futures_io::{AsyncRead, AsyncWrite};
18
19use crate::sync::atomic_waker::AtomicWaker;
20use crate::sync::internal::{AtomicBool, AtomicUsize, Ordering};
21
22struct Pipe {
25 ring: Box<[core::cell::UnsafeCell<u8>]>,
26 written: AtomicUsize,
28 read: AtomicUsize,
30 reader: AtomicWaker,
31 writer: AtomicWaker,
32 write_closed: AtomicBool,
34 read_closed: AtomicBool,
36}
37
38unsafe impl Send for Pipe {}
42unsafe impl Sync for Pipe {}
44
45impl Pipe {
46 fn new(capacity: usize) -> Arc<Self> {
47 let capacity = capacity.max(1);
48 Arc::new(Self {
49 ring: (0..capacity)
50 .map(|_| core::cell::UnsafeCell::new(0))
51 .collect(),
52 written: AtomicUsize::new(0),
53 read: AtomicUsize::new(0),
54 reader: AtomicWaker::new(),
55 writer: AtomicWaker::new(),
56 write_closed: AtomicBool::new(false),
57 read_closed: AtomicBool::new(false),
58 })
59 }
60
61 fn base(&self) -> *mut u8 {
62 core::cell::UnsafeCell::raw_get(self.ring.as_ptr())
63 }
64
65 fn poll_read(&self, cx: &mut Context<'_>, out: &mut [u8]) -> Poll<io::Result<usize>> {
68 if out.is_empty() {
69 return Poll::Ready(Ok(0));
70 }
71 let read = self.read.load(Ordering::Relaxed);
72 let mut written = self.written.load(Ordering::Acquire);
73 if written == read {
74 if self.write_closed.load(Ordering::Acquire) {
75 return Poll::Ready(Ok(0));
76 }
77 self.reader.register(cx.waker());
78 written = self.written.load(Ordering::SeqCst);
79 if written == read {
80 if self.write_closed.load(Ordering::SeqCst) {
82 return Poll::Ready(Ok(0));
83 }
84 return Poll::Pending;
85 }
86 }
87 let n = (written - read).min(out.len());
88 let cap = self.ring.len();
89 let at = read % cap;
90 let first = n.min(cap - at);
91 unsafe {
95 core::ptr::copy_nonoverlapping(self.base().add(at), out.as_mut_ptr(), first);
96 core::ptr::copy_nonoverlapping(self.base(), out.as_mut_ptr().add(first), n - first);
97 }
98 self.read.store(read + n, Ordering::Release);
99 self.writer.wake();
100 Poll::Ready(Ok(n))
101 }
102
103 fn poll_write(&self, cx: &mut Context<'_>, input: &[u8]) -> Poll<io::Result<usize>> {
106 if self.read_closed.load(Ordering::Acquire) || self.write_closed.load(Ordering::Relaxed) {
107 return Poll::Ready(Err(io::ErrorKind::BrokenPipe.into()));
108 }
109 if input.is_empty() {
110 return Poll::Ready(Ok(0));
111 }
112 let cap = self.ring.len();
113 let written = self.written.load(Ordering::Relaxed);
114 let mut read = self.read.load(Ordering::Acquire);
115 if written - read == cap {
116 self.writer.register(cx.waker());
117 read = self.read.load(Ordering::SeqCst);
118 if written - read == cap {
119 if self.read_closed.load(Ordering::SeqCst) {
120 return Poll::Ready(Err(io::ErrorKind::BrokenPipe.into()));
121 }
122 return Poll::Pending;
123 }
124 }
125 let n = (cap - (written - read)).min(input.len());
126 let at = written % cap;
127 let first = n.min(cap - at);
128 unsafe {
132 core::ptr::copy_nonoverlapping(input.as_ptr(), self.base().add(at), first);
133 core::ptr::copy_nonoverlapping(input.as_ptr().add(first), self.base(), n - first);
134 }
135 self.written.store(written + n, Ordering::Release);
136 self.reader.wake();
137 Poll::Ready(Ok(n))
138 }
139
140 fn close_write(&self) {
142 self.write_closed.store(true, Ordering::SeqCst);
143 self.reader.wake();
144 }
145
146 fn close_read(&self) {
148 self.read_closed.store(true, Ordering::SeqCst);
149 self.writer.wake();
150 }
151}
152
153pub struct DuplexStream {
157 read: Arc<Pipe>,
158 write: Arc<Pipe>,
159}
160
161pub fn duplex(max_buf_size: usize) -> (DuplexStream, DuplexStream) {
176 let (ab, ba) = (Pipe::new(max_buf_size), Pipe::new(max_buf_size));
177 (
178 DuplexStream {
179 read: Arc::clone(&ba),
180 write: Arc::clone(&ab),
181 },
182 DuplexStream {
183 read: ab,
184 write: ba,
185 },
186 )
187}
188
189impl AsyncRead for DuplexStream {
190 fn poll_read(
191 self: Pin<&mut Self>,
192 cx: &mut Context<'_>,
193 buf: &mut [u8],
194 ) -> Poll<io::Result<usize>> {
195 crate::coop::poll_budget(cx, |cx| self.read.poll_read(cx, buf))
196 }
197}
198
199impl AsyncWrite for DuplexStream {
200 fn poll_write(
201 self: Pin<&mut Self>,
202 cx: &mut Context<'_>,
203 buf: &[u8],
204 ) -> Poll<io::Result<usize>> {
205 crate::coop::poll_budget(cx, |cx| self.write.poll_write(cx, buf))
206 }
207
208 fn poll_flush(self: Pin<&mut Self>, _: &mut Context<'_>) -> Poll<io::Result<()>> {
209 Poll::Ready(Ok(()))
210 }
211
212 fn poll_close(self: Pin<&mut Self>, _: &mut Context<'_>) -> Poll<io::Result<()>> {
213 self.write.close_write();
214 Poll::Ready(Ok(()))
215 }
216}
217
218impl Drop for DuplexStream {
219 fn drop(&mut self) {
220 self.write.close_write();
221 self.read.close_read();
222 }
223}
224
225impl core::fmt::Debug for DuplexStream {
226 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
227 f.debug_struct("DuplexStream").finish_non_exhaustive()
228 }
229}
230
231pub struct SimplexReader {
234 pipe: Arc<Pipe>,
235}
236
237pub struct SimplexWriter {
240 pipe: Arc<Pipe>,
241}
242
243pub fn simplex(max_buf_size: usize) -> (SimplexReader, SimplexWriter) {
246 let pipe = Pipe::new(max_buf_size);
247 (
248 SimplexReader {
249 pipe: Arc::clone(&pipe),
250 },
251 SimplexWriter { pipe },
252 )
253}
254
255impl AsyncRead for SimplexReader {
256 fn poll_read(
257 self: Pin<&mut Self>,
258 cx: &mut Context<'_>,
259 buf: &mut [u8],
260 ) -> Poll<io::Result<usize>> {
261 crate::coop::poll_budget(cx, |cx| self.pipe.poll_read(cx, buf))
262 }
263}
264
265impl AsyncWrite for SimplexWriter {
266 fn poll_write(
267 self: Pin<&mut Self>,
268 cx: &mut Context<'_>,
269 buf: &[u8],
270 ) -> Poll<io::Result<usize>> {
271 crate::coop::poll_budget(cx, |cx| self.pipe.poll_write(cx, buf))
272 }
273
274 fn poll_flush(self: Pin<&mut Self>, _: &mut Context<'_>) -> Poll<io::Result<()>> {
275 Poll::Ready(Ok(()))
276 }
277
278 fn poll_close(self: Pin<&mut Self>, _: &mut Context<'_>) -> Poll<io::Result<()>> {
279 self.pipe.close_write();
280 Poll::Ready(Ok(()))
281 }
282}
283
284impl Drop for SimplexReader {
285 fn drop(&mut self) {
286 self.pipe.close_read();
287 }
288}
289
290impl Drop for SimplexWriter {
291 fn drop(&mut self) {
292 self.pipe.close_write();
293 }
294}
295
296impl core::fmt::Debug for SimplexReader {
297 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
298 f.debug_struct("SimplexReader").finish_non_exhaustive()
299 }
300}
301
302impl core::fmt::Debug for SimplexWriter {
303 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
304 f.debug_struct("SimplexWriter").finish_non_exhaustive()
305 }
306}