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#[track_caller]
108#[cfg_attr(docsrs, doc(cfg(feature = "io-util")))]
109pub fn duplex(max_buf_size: usize) -> (DuplexStream, DuplexStream) {
110 let one = Arc::new(Mutex::new(SimplexStream::new_unsplit(max_buf_size)));
111 let two = Arc::new(Mutex::new(SimplexStream::new_unsplit(max_buf_size)));
112
113 (
114 DuplexStream {
115 read: one.clone(),
116 write: two.clone(),
117 },
118 DuplexStream {
119 read: two,
120 write: one,
121 },
122 )
123}
124
125impl AsyncRead for DuplexStream {
126 #[allow(unused_mut)]
132 fn poll_read(
133 mut self: Pin<&mut Self>,
134 cx: &mut task::Context<'_>,
135 buf: &mut ReadBuf<'_>,
136 ) -> Poll<std::io::Result<()>> {
137 let mut wakers = Wakers::default();
138 let ret = Pin::new(&mut *self.read.lock()).poll_read_deferred(cx, buf, &mut wakers);
139 wakers.wake();
140 ret
141 }
142}
143
144impl AsyncWrite for DuplexStream {
145 #[allow(unused_mut)]
146 fn poll_write(
147 mut self: Pin<&mut Self>,
148 cx: &mut task::Context<'_>,
149 buf: &[u8],
150 ) -> Poll<std::io::Result<usize>> {
151 let mut wakers = Wakers::default();
152 let ret = Pin::new(&mut *self.write.lock()).poll_write_deferred(cx, buf, &mut wakers);
153 wakers.wake();
154 ret
155 }
156
157 fn poll_write_vectored(
158 self: Pin<&mut Self>,
159 cx: &mut task::Context<'_>,
160 bufs: &[std::io::IoSlice<'_>],
161 ) -> Poll<Result<usize, std::io::Error>> {
162 let mut wakers = Wakers::default();
163 let ret =
164 Pin::new(&mut *self.write.lock()).poll_write_vectored_deferred(cx, bufs, &mut wakers);
165 wakers.wake();
166 ret
167 }
168
169 fn is_write_vectored(&self) -> bool {
170 true
171 }
172
173 #[allow(unused_mut)]
174 fn poll_flush(
175 mut self: Pin<&mut Self>,
176 cx: &mut task::Context<'_>,
177 ) -> Poll<std::io::Result<()>> {
178 Pin::new(&mut *self.write.lock()).poll_flush(cx)
179 }
180
181 #[allow(unused_mut)]
182 fn poll_shutdown(
183 mut self: Pin<&mut Self>,
184 _: &mut task::Context<'_>,
185 ) -> Poll<std::io::Result<()>> {
186 let read_waker = self.write.lock().close_write();
187 if let Some(waker) = read_waker {
188 waker.wake();
189 }
190 Poll::Ready(Ok(()))
191 }
192}
193
194impl Drop for DuplexStream {
195 fn drop(&mut self) {
196 let read_waker = self.write.lock().close_write();
198 let write_waker = self.read.lock().close_read();
199 if let Some(waker) = read_waker {
201 waker.wake();
202 }
203 if let Some(waker) = write_waker {
204 waker.wake();
205 }
206 }
207}
208
209#[derive(Default)]
216struct Wakers {
217 wake: Option<Waker>,
219 replaced: Option<Waker>,
221}
222
223impl Wakers {
224 fn wake(self) {
225 if let Some(waker) = self.wake {
226 waker.wake();
227 }
228 drop(self.replaced);
229 }
230}
231
232#[track_caller]
264#[cfg_attr(docsrs, doc(cfg(feature = "io-util")))]
265pub fn simplex(max_buf_size: usize) -> (ReadHalf<SimplexStream>, WriteHalf<SimplexStream>) {
266 split(SimplexStream::new_unsplit(max_buf_size))
267}
268
269impl SimplexStream {
270 #[track_caller]
280 #[cfg_attr(docsrs, doc(cfg(feature = "io-util")))]
281 pub fn new_unsplit(max_buf_size: usize) -> SimplexStream {
282 assert!(max_buf_size > 0, "`max_buf_size` must be greater than 0");
283 SimplexStream {
284 buffer: BytesMut::new(),
285 is_closed: false,
286 max_buf_size,
287 read_waker: None,
288 write_waker: None,
289 }
290 }
291
292 #[must_use]
295 fn close_write(&mut self) -> Option<Waker> {
296 self.is_closed = true;
297 self.read_waker.take()
298 }
299
300 #[must_use]
303 fn close_read(&mut self) -> Option<Waker> {
304 self.is_closed = true;
305 self.write_waker.take()
306 }
307
308 fn poll_read_internal(
309 mut self: Pin<&mut Self>,
310 cx: &mut task::Context<'_>,
311 buf: &mut ReadBuf<'_>,
312 wakers: &mut Wakers,
313 ) -> Poll<std::io::Result<()>> {
314 if buf.remaining() == 0 {
315 return Poll::Ready(Ok(()));
316 }
317
318 if self.buffer.has_remaining() {
319 let max = self.buffer.remaining().min(buf.remaining());
320 buf.put_slice(&self.buffer[..max]);
321 self.buffer.advance(max);
322 if max > 0 {
323 wakers.wake = self.write_waker.take();
326 }
327 Poll::Ready(Ok(()))
328 } else if self.is_closed {
329 Poll::Ready(Ok(()))
330 } else {
331 wakers.replaced = self.read_waker.replace(cx.waker().clone());
332 Poll::Pending
333 }
334 }
335
336 fn poll_write_internal(
337 mut self: Pin<&mut Self>,
338 cx: &mut task::Context<'_>,
339 buf: &[u8],
340 wakers: &mut Wakers,
341 ) -> Poll<std::io::Result<usize>> {
342 if self.is_closed {
343 return Poll::Ready(Err(std::io::ErrorKind::BrokenPipe.into()));
344 }
345 if buf.is_empty() {
346 return Poll::Ready(Ok(0));
347 }
348
349 let avail = self.max_buf_size - self.buffer.len();
350 if avail == 0 {
351 wakers.replaced = self.write_waker.replace(cx.waker().clone());
352 return Poll::Pending;
353 }
354
355 let len = buf.len().min(avail);
356 self.buffer.extend_from_slice(&buf[..len]);
357 wakers.wake = self.read_waker.take();
358 Poll::Ready(Ok(len))
359 }
360
361 fn poll_write_vectored_internal(
362 mut self: Pin<&mut Self>,
363 cx: &mut task::Context<'_>,
364 bufs: &[std::io::IoSlice<'_>],
365 wakers: &mut Wakers,
366 ) -> Poll<Result<usize, std::io::Error>> {
367 if self.is_closed {
368 return Poll::Ready(Err(std::io::ErrorKind::BrokenPipe.into()));
369 }
370 if bufs.iter().all(|buf| buf.is_empty()) {
371 return Poll::Ready(Ok(0));
372 }
373
374 let avail = self.max_buf_size - self.buffer.len();
375 if avail == 0 {
376 wakers.replaced = self.write_waker.replace(cx.waker().clone());
377 return Poll::Pending;
378 }
379
380 let mut rem = avail;
381 for buf in bufs {
382 if rem == 0 {
383 break;
384 }
385
386 let len = buf.len().min(rem);
387 self.buffer.extend_from_slice(&buf[..len]);
388 rem -= len;
389 }
390
391 wakers.wake = self.read_waker.take();
392 Poll::Ready(Ok(avail - rem))
393 }
394
395 cfg_coop! {
396 fn poll_read_deferred(
397 self: Pin<&mut Self>,
398 cx: &mut task::Context<'_>,
399 buf: &mut ReadBuf<'_>,
400 wakers: &mut Wakers,
401 ) -> Poll<std::io::Result<()>> {
402 ready!(crate::trace::trace_leaf(cx));
403 let coop = ready!(crate::task::coop::poll_proceed(cx));
404
405 let ret = self.poll_read_internal(cx, buf, wakers);
406 if ret.is_ready() {
407 coop.made_progress();
408 }
409 ret
410 }
411 }
412
413 cfg_not_coop! {
414 fn poll_read_deferred(
415 self: Pin<&mut Self>,
416 cx: &mut task::Context<'_>,
417 buf: &mut ReadBuf<'_>,
418 wakers: &mut Wakers,
419 ) -> Poll<std::io::Result<()>> {
420 ready!(crate::trace::trace_leaf(cx));
421 self.poll_read_internal(cx, buf, wakers)
422 }
423 }
424
425 cfg_coop! {
426 fn poll_write_deferred(
427 self: Pin<&mut Self>,
428 cx: &mut task::Context<'_>,
429 buf: &[u8],
430 wakers: &mut Wakers,
431 ) -> Poll<std::io::Result<usize>> {
432 ready!(crate::trace::trace_leaf(cx));
433 let coop = ready!(crate::task::coop::poll_proceed(cx));
434
435 let ret = self.poll_write_internal(cx, buf, wakers);
436 if ret.is_ready() {
437 coop.made_progress();
438 }
439 ret
440 }
441 }
442
443 cfg_not_coop! {
444 fn poll_write_deferred(
445 self: Pin<&mut Self>,
446 cx: &mut task::Context<'_>,
447 buf: &[u8],
448 wakers: &mut Wakers,
449 ) -> Poll<std::io::Result<usize>> {
450 ready!(crate::trace::trace_leaf(cx));
451 self.poll_write_internal(cx, buf, wakers)
452 }
453 }
454
455 cfg_coop! {
456 fn poll_write_vectored_deferred(
457 self: Pin<&mut Self>,
458 cx: &mut task::Context<'_>,
459 bufs: &[std::io::IoSlice<'_>],
460 wakers: &mut Wakers,
461 ) -> Poll<Result<usize, std::io::Error>> {
462 ready!(crate::trace::trace_leaf(cx));
463 let coop = ready!(crate::task::coop::poll_proceed(cx));
464
465 let ret = self.poll_write_vectored_internal(cx, bufs, wakers);
466 if ret.is_ready() {
467 coop.made_progress();
468 }
469 ret
470 }
471 }
472
473 cfg_not_coop! {
474 fn poll_write_vectored_deferred(
475 self: Pin<&mut Self>,
476 cx: &mut task::Context<'_>,
477 bufs: &[std::io::IoSlice<'_>],
478 wakers: &mut Wakers,
479 ) -> Poll<Result<usize, std::io::Error>> {
480 ready!(crate::trace::trace_leaf(cx));
481 self.poll_write_vectored_internal(cx, bufs, wakers)
482 }
483 }
484}
485
486impl AsyncRead for SimplexStream {
487 fn poll_read(
488 self: Pin<&mut Self>,
489 cx: &mut task::Context<'_>,
490 buf: &mut ReadBuf<'_>,
491 ) -> Poll<std::io::Result<()>> {
492 let mut wakers = Wakers::default();
493 let ret = self.poll_read_deferred(cx, buf, &mut wakers);
494 wakers.wake();
495 ret
496 }
497}
498
499impl AsyncWrite for SimplexStream {
500 fn poll_write(
501 self: Pin<&mut Self>,
502 cx: &mut task::Context<'_>,
503 buf: &[u8],
504 ) -> Poll<std::io::Result<usize>> {
505 let mut wakers = Wakers::default();
506 let ret = self.poll_write_deferred(cx, buf, &mut wakers);
507 wakers.wake();
508 ret
509 }
510
511 fn poll_write_vectored(
512 self: Pin<&mut Self>,
513 cx: &mut task::Context<'_>,
514 bufs: &[std::io::IoSlice<'_>],
515 ) -> Poll<Result<usize, std::io::Error>> {
516 let mut wakers = Wakers::default();
517 let ret = self.poll_write_vectored_deferred(cx, bufs, &mut wakers);
518 wakers.wake();
519 ret
520 }
521
522 fn is_write_vectored(&self) -> bool {
523 true
524 }
525
526 fn poll_flush(self: Pin<&mut Self>, _: &mut task::Context<'_>) -> Poll<std::io::Result<()>> {
527 Poll::Ready(Ok(()))
528 }
529
530 fn poll_shutdown(
531 mut self: Pin<&mut Self>,
532 _: &mut task::Context<'_>,
533 ) -> Poll<std::io::Result<()>> {
534 if let Some(waker) = self.close_write() {
535 waker.wake();
536 }
537 Poll::Ready(Ok(()))
538 }
539}