1use crate::io::{split, AsyncRead, AsyncWrite, ReadBuf, ReadHalf, WriteHalf};
4use crate::loom::sync::Mutex;
5
6use bytes::{Buf, BytesMut};
7use std::{
8 pin::Pin,
9 sync::Arc,
10 task::{self, ready, Poll, Waker},
11};
12
13#[derive(Debug)]
48#[cfg_attr(docsrs, doc(cfg(feature = "io-util")))]
49pub struct DuplexStream {
50 read: Arc<Mutex<SimplexStream>>,
51 write: Arc<Mutex<SimplexStream>>,
52}
53
54#[derive(Debug)]
76#[cfg_attr(docsrs, doc(cfg(feature = "io-util")))]
77pub struct SimplexStream {
78 buffer: BytesMut,
84 is_closed: bool,
86 max_buf_size: usize,
89 read_waker: Option<Waker>,
92 write_waker: Option<Waker>,
95}
96
97#[cfg_attr(docsrs, doc(cfg(feature = "io-util")))]
104pub fn duplex(max_buf_size: usize) -> (DuplexStream, DuplexStream) {
105 let one = Arc::new(Mutex::new(SimplexStream::new_unsplit(max_buf_size)));
106 let two = Arc::new(Mutex::new(SimplexStream::new_unsplit(max_buf_size)));
107
108 (
109 DuplexStream {
110 read: one.clone(),
111 write: two.clone(),
112 },
113 DuplexStream {
114 read: two,
115 write: one,
116 },
117 )
118}
119
120impl AsyncRead for DuplexStream {
121 #[allow(unused_mut)]
127 fn poll_read(
128 mut self: Pin<&mut Self>,
129 cx: &mut task::Context<'_>,
130 buf: &mut ReadBuf<'_>,
131 ) -> Poll<std::io::Result<()>> {
132 let mut wakers = Wakers::default();
133 let ret = Pin::new(&mut *self.read.lock()).poll_read_deferred(cx, buf, &mut wakers);
134 wakers.wake();
135 ret
136 }
137}
138
139impl AsyncWrite for DuplexStream {
140 #[allow(unused_mut)]
141 fn poll_write(
142 mut self: Pin<&mut Self>,
143 cx: &mut task::Context<'_>,
144 buf: &[u8],
145 ) -> Poll<std::io::Result<usize>> {
146 let mut wakers = Wakers::default();
147 let ret = Pin::new(&mut *self.write.lock()).poll_write_deferred(cx, buf, &mut wakers);
148 wakers.wake();
149 ret
150 }
151
152 fn poll_write_vectored(
153 self: Pin<&mut Self>,
154 cx: &mut task::Context<'_>,
155 bufs: &[std::io::IoSlice<'_>],
156 ) -> Poll<Result<usize, std::io::Error>> {
157 let mut wakers = Wakers::default();
158 let ret =
159 Pin::new(&mut *self.write.lock()).poll_write_vectored_deferred(cx, bufs, &mut wakers);
160 wakers.wake();
161 ret
162 }
163
164 fn is_write_vectored(&self) -> bool {
165 true
166 }
167
168 #[allow(unused_mut)]
169 fn poll_flush(
170 mut self: Pin<&mut Self>,
171 cx: &mut task::Context<'_>,
172 ) -> Poll<std::io::Result<()>> {
173 Pin::new(&mut *self.write.lock()).poll_flush(cx)
174 }
175
176 #[allow(unused_mut)]
177 fn poll_shutdown(
178 mut self: Pin<&mut Self>,
179 _: &mut task::Context<'_>,
180 ) -> Poll<std::io::Result<()>> {
181 let read_waker = self.write.lock().close_write();
182 if let Some(waker) = read_waker {
183 waker.wake();
184 }
185 Poll::Ready(Ok(()))
186 }
187}
188
189impl Drop for DuplexStream {
190 fn drop(&mut self) {
191 let read_waker = self.write.lock().close_write();
193 let write_waker = self.read.lock().close_read();
194 if let Some(waker) = read_waker {
196 waker.wake();
197 }
198 if let Some(waker) = write_waker {
199 waker.wake();
200 }
201 }
202}
203
204#[derive(Default)]
211struct Wakers {
212 wake: Option<Waker>,
214 replaced: Option<Waker>,
216}
217
218impl Wakers {
219 fn wake(self) {
220 if let Some(waker) = self.wake {
221 waker.wake();
222 }
223 drop(self.replaced);
224 }
225}
226
227#[cfg_attr(docsrs, doc(cfg(feature = "io-util")))]
255pub fn simplex(max_buf_size: usize) -> (ReadHalf<SimplexStream>, WriteHalf<SimplexStream>) {
256 split(SimplexStream::new_unsplit(max_buf_size))
257}
258
259impl SimplexStream {
260 #[cfg_attr(docsrs, doc(cfg(feature = "io-util")))]
266 pub fn new_unsplit(max_buf_size: usize) -> SimplexStream {
267 SimplexStream {
268 buffer: BytesMut::new(),
269 is_closed: false,
270 max_buf_size,
271 read_waker: None,
272 write_waker: None,
273 }
274 }
275
276 #[must_use]
279 fn close_write(&mut self) -> Option<Waker> {
280 self.is_closed = true;
281 self.read_waker.take()
282 }
283
284 #[must_use]
287 fn close_read(&mut self) -> Option<Waker> {
288 self.is_closed = true;
289 self.write_waker.take()
290 }
291
292 fn poll_read_internal(
293 mut self: Pin<&mut Self>,
294 cx: &mut task::Context<'_>,
295 buf: &mut ReadBuf<'_>,
296 wakers: &mut Wakers,
297 ) -> Poll<std::io::Result<()>> {
298 if self.buffer.has_remaining() {
299 let max = self.buffer.remaining().min(buf.remaining());
300 buf.put_slice(&self.buffer[..max]);
301 self.buffer.advance(max);
302 if max > 0 {
303 wakers.wake = self.write_waker.take();
306 }
307 Poll::Ready(Ok(()))
308 } else if self.is_closed {
309 Poll::Ready(Ok(()))
310 } else {
311 wakers.replaced = self.read_waker.replace(cx.waker().clone());
312 Poll::Pending
313 }
314 }
315
316 fn poll_write_internal(
317 mut self: Pin<&mut Self>,
318 cx: &mut task::Context<'_>,
319 buf: &[u8],
320 wakers: &mut Wakers,
321 ) -> Poll<std::io::Result<usize>> {
322 if self.is_closed {
323 return Poll::Ready(Err(std::io::ErrorKind::BrokenPipe.into()));
324 }
325 let avail = self.max_buf_size - self.buffer.len();
326 if avail == 0 {
327 wakers.replaced = self.write_waker.replace(cx.waker().clone());
328 return Poll::Pending;
329 }
330
331 let len = buf.len().min(avail);
332 self.buffer.extend_from_slice(&buf[..len]);
333 wakers.wake = self.read_waker.take();
334 Poll::Ready(Ok(len))
335 }
336
337 fn poll_write_vectored_internal(
338 mut self: Pin<&mut Self>,
339 cx: &mut task::Context<'_>,
340 bufs: &[std::io::IoSlice<'_>],
341 wakers: &mut Wakers,
342 ) -> Poll<Result<usize, std::io::Error>> {
343 if self.is_closed {
344 return Poll::Ready(Err(std::io::ErrorKind::BrokenPipe.into()));
345 }
346 let avail = self.max_buf_size - self.buffer.len();
347 if avail == 0 {
348 wakers.replaced = self.write_waker.replace(cx.waker().clone());
349 return Poll::Pending;
350 }
351
352 let mut rem = avail;
353 for buf in bufs {
354 if rem == 0 {
355 break;
356 }
357
358 let len = buf.len().min(rem);
359 self.buffer.extend_from_slice(&buf[..len]);
360 rem -= len;
361 }
362
363 wakers.wake = self.read_waker.take();
364 Poll::Ready(Ok(avail - rem))
365 }
366
367 cfg_coop! {
368 fn poll_read_deferred(
369 self: Pin<&mut Self>,
370 cx: &mut task::Context<'_>,
371 buf: &mut ReadBuf<'_>,
372 wakers: &mut Wakers,
373 ) -> Poll<std::io::Result<()>> {
374 ready!(crate::trace::trace_leaf(cx));
375 let coop = ready!(crate::task::coop::poll_proceed(cx));
376
377 let ret = self.poll_read_internal(cx, buf, wakers);
378 if ret.is_ready() {
379 coop.made_progress();
380 }
381 ret
382 }
383 }
384
385 cfg_not_coop! {
386 fn poll_read_deferred(
387 self: Pin<&mut Self>,
388 cx: &mut task::Context<'_>,
389 buf: &mut ReadBuf<'_>,
390 wakers: &mut Wakers,
391 ) -> Poll<std::io::Result<()>> {
392 ready!(crate::trace::trace_leaf(cx));
393 self.poll_read_internal(cx, buf, wakers)
394 }
395 }
396
397 cfg_coop! {
398 fn poll_write_deferred(
399 self: Pin<&mut Self>,
400 cx: &mut task::Context<'_>,
401 buf: &[u8],
402 wakers: &mut Wakers,
403 ) -> Poll<std::io::Result<usize>> {
404 ready!(crate::trace::trace_leaf(cx));
405 let coop = ready!(crate::task::coop::poll_proceed(cx));
406
407 let ret = self.poll_write_internal(cx, buf, wakers);
408 if ret.is_ready() {
409 coop.made_progress();
410 }
411 ret
412 }
413 }
414
415 cfg_not_coop! {
416 fn poll_write_deferred(
417 self: Pin<&mut Self>,
418 cx: &mut task::Context<'_>,
419 buf: &[u8],
420 wakers: &mut Wakers,
421 ) -> Poll<std::io::Result<usize>> {
422 ready!(crate::trace::trace_leaf(cx));
423 self.poll_write_internal(cx, buf, wakers)
424 }
425 }
426
427 cfg_coop! {
428 fn poll_write_vectored_deferred(
429 self: Pin<&mut Self>,
430 cx: &mut task::Context<'_>,
431 bufs: &[std::io::IoSlice<'_>],
432 wakers: &mut Wakers,
433 ) -> Poll<Result<usize, std::io::Error>> {
434 ready!(crate::trace::trace_leaf(cx));
435 let coop = ready!(crate::task::coop::poll_proceed(cx));
436
437 let ret = self.poll_write_vectored_internal(cx, bufs, wakers);
438 if ret.is_ready() {
439 coop.made_progress();
440 }
441 ret
442 }
443 }
444
445 cfg_not_coop! {
446 fn poll_write_vectored_deferred(
447 self: Pin<&mut Self>,
448 cx: &mut task::Context<'_>,
449 bufs: &[std::io::IoSlice<'_>],
450 wakers: &mut Wakers,
451 ) -> Poll<Result<usize, std::io::Error>> {
452 ready!(crate::trace::trace_leaf(cx));
453 self.poll_write_vectored_internal(cx, bufs, wakers)
454 }
455 }
456}
457
458impl AsyncRead for SimplexStream {
459 fn poll_read(
460 self: Pin<&mut Self>,
461 cx: &mut task::Context<'_>,
462 buf: &mut ReadBuf<'_>,
463 ) -> Poll<std::io::Result<()>> {
464 let mut wakers = Wakers::default();
465 let ret = self.poll_read_deferred(cx, buf, &mut wakers);
466 wakers.wake();
467 ret
468 }
469}
470
471impl AsyncWrite for SimplexStream {
472 fn poll_write(
473 self: Pin<&mut Self>,
474 cx: &mut task::Context<'_>,
475 buf: &[u8],
476 ) -> Poll<std::io::Result<usize>> {
477 let mut wakers = Wakers::default();
478 let ret = self.poll_write_deferred(cx, buf, &mut wakers);
479 wakers.wake();
480 ret
481 }
482
483 fn poll_write_vectored(
484 self: Pin<&mut Self>,
485 cx: &mut task::Context<'_>,
486 bufs: &[std::io::IoSlice<'_>],
487 ) -> Poll<Result<usize, std::io::Error>> {
488 let mut wakers = Wakers::default();
489 let ret = self.poll_write_vectored_deferred(cx, bufs, &mut wakers);
490 wakers.wake();
491 ret
492 }
493
494 fn is_write_vectored(&self) -> bool {
495 true
496 }
497
498 fn poll_flush(self: Pin<&mut Self>, _: &mut task::Context<'_>) -> Poll<std::io::Result<()>> {
499 Poll::Ready(Ok(()))
500 }
501
502 fn poll_shutdown(
503 mut self: Pin<&mut Self>,
504 _: &mut task::Context<'_>,
505 ) -> Poll<std::io::Result<()>> {
506 if let Some(waker) = self.close_write() {
507 waker.wake();
508 }
509 Poll::Ready(Ok(()))
510 }
511}