xref: /webrtc/sctp/src/stream/mod.rs (revision 7ceeeeb0)
1 #[cfg(test)]
2 mod stream_test;
3 
4 use crate::association::AssociationState;
5 use crate::chunk::chunk_payload_data::{ChunkPayloadData, PayloadProtocolIdentifier};
6 use crate::error::{Error, Result};
7 use crate::queue::reassembly_queue::ReassemblyQueue;
8 
9 use crate::queue::pending_queue::PendingQueue;
10 
11 use bytes::Bytes;
12 use std::fmt;
13 use std::future::Future;
14 use std::io;
15 use std::net::Shutdown;
16 use std::pin::Pin;
17 use std::sync::atomic::{AtomicBool, AtomicU16, AtomicU32, AtomicU8, AtomicUsize, Ordering};
18 use std::sync::Arc;
19 use std::task::{Context, Poll};
20 use tokio::io::{AsyncRead, AsyncWrite, ReadBuf};
21 use tokio::sync::{mpsc, Mutex, Notify};
22 
23 #[derive(Debug, Copy, Clone, PartialEq, Eq)]
24 #[repr(C)]
25 pub enum ReliabilityType {
26     /// ReliabilityTypeReliable is used for reliable transmission
27     Reliable = 0,
28     /// ReliabilityTypeRexmit is used for partial reliability by retransmission count
29     Rexmit = 1,
30     /// ReliabilityTypeTimed is used for partial reliability by retransmission duration
31     Timed = 2,
32 }
33 
34 impl Default for ReliabilityType {
35     fn default() -> Self {
36         ReliabilityType::Reliable
37     }
38 }
39 
40 impl fmt::Display for ReliabilityType {
41     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
42         let s = match *self {
43             ReliabilityType::Reliable => "Reliable",
44             ReliabilityType::Rexmit => "Rexmit",
45             ReliabilityType::Timed => "Timed",
46         };
47         write!(f, "{}", s)
48     }
49 }
50 
51 impl From<u8> for ReliabilityType {
52     fn from(v: u8) -> ReliabilityType {
53         match v {
54             1 => ReliabilityType::Rexmit,
55             2 => ReliabilityType::Timed,
56             _ => ReliabilityType::Reliable,
57         }
58     }
59 }
60 
61 pub type OnBufferedAmountLowFn =
62     Box<dyn (FnMut() -> Pin<Box<dyn Future<Output = ()> + Send + 'static>>) + Send + Sync>;
63 
64 // TODO: benchmark performance between multiple Atomic+Mutex vs one Mutex<StreamInternal>
65 
66 /// Stream represents an SCTP stream
67 #[derive(Default)]
68 pub struct Stream {
69     pub(crate) max_payload_size: u32,
70     pub(crate) max_message_size: Arc<AtomicU32>, // clone from association
71     pub(crate) state: Arc<AtomicU8>,             // clone from association
72     pub(crate) awake_write_loop_ch: Option<Arc<mpsc::Sender<()>>>,
73     pub(crate) pending_queue: Arc<PendingQueue>,
74 
75     pub(crate) stream_identifier: u16,
76     pub(crate) default_payload_type: AtomicU32, //PayloadProtocolIdentifier,
77     pub(crate) reassembly_queue: Mutex<ReassemblyQueue>,
78     pub(crate) sequence_number: AtomicU16,
79     pub(crate) read_notifier: Notify,
80     pub(crate) read_shutdown: AtomicBool,
81     pub(crate) write_shutdown: AtomicBool,
82     pub(crate) unordered: AtomicBool,
83     pub(crate) reliability_type: AtomicU8, //ReliabilityType,
84     pub(crate) reliability_value: AtomicU32,
85     pub(crate) buffered_amount: AtomicUsize,
86     pub(crate) buffered_amount_low: AtomicUsize,
87     pub(crate) on_buffered_amount_low: Mutex<Option<OnBufferedAmountLowFn>>,
88     pub(crate) name: String,
89 }
90 
91 impl fmt::Debug for Stream {
92     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
93         f.debug_struct("Stream")
94             .field("max_payload_size", &self.max_payload_size)
95             .field("max_message_size", &self.max_message_size)
96             .field("state", &self.state)
97             .field("awake_write_loop_ch", &self.awake_write_loop_ch)
98             .field("stream_identifier", &self.stream_identifier)
99             .field("default_payload_type", &self.default_payload_type)
100             .field("reassembly_queue", &self.reassembly_queue)
101             .field("sequence_number", &self.sequence_number)
102             .field("read_shutdown", &self.read_shutdown)
103             .field("write_shutdown", &self.write_shutdown)
104             .field("unordered", &self.unordered)
105             .field("reliability_type", &self.reliability_type)
106             .field("reliability_value", &self.reliability_value)
107             .field("buffered_amount", &self.buffered_amount)
108             .field("buffered_amount_low", &self.buffered_amount_low)
109             .field("name", &self.name)
110             .finish()
111     }
112 }
113 
114 impl Stream {
115     pub(crate) fn new(
116         name: String,
117         stream_identifier: u16,
118         max_payload_size: u32,
119         max_message_size: Arc<AtomicU32>,
120         state: Arc<AtomicU8>,
121         awake_write_loop_ch: Option<Arc<mpsc::Sender<()>>>,
122         pending_queue: Arc<PendingQueue>,
123     ) -> Self {
124         Stream {
125             max_payload_size,
126             max_message_size,
127             state,
128             awake_write_loop_ch,
129             pending_queue,
130 
131             stream_identifier,
132             default_payload_type: AtomicU32::new(0), //PayloadProtocolIdentifier::Unknown,
133             reassembly_queue: Mutex::new(ReassemblyQueue::new(stream_identifier)),
134             sequence_number: AtomicU16::new(0),
135             read_notifier: Notify::new(),
136             read_shutdown: AtomicBool::new(false),
137             write_shutdown: AtomicBool::new(false),
138             unordered: AtomicBool::new(false),
139             reliability_type: AtomicU8::new(0), //ReliabilityType::Reliable,
140             reliability_value: AtomicU32::new(0),
141             buffered_amount: AtomicUsize::new(0),
142             buffered_amount_low: AtomicUsize::new(0),
143             on_buffered_amount_low: Mutex::new(None),
144             name,
145         }
146     }
147 
148     /// stream_identifier returns the Stream identifier associated to the stream.
149     pub fn stream_identifier(&self) -> u16 {
150         self.stream_identifier
151     }
152 
153     /// set_default_payload_type sets the default payload type used by write.
154     pub fn set_default_payload_type(&self, default_payload_type: PayloadProtocolIdentifier) {
155         self.default_payload_type
156             .store(default_payload_type as u32, Ordering::SeqCst);
157     }
158 
159     /// set_reliability_params sets reliability parameters for this stream.
160     pub fn set_reliability_params(&self, unordered: bool, rel_type: ReliabilityType, rel_val: u32) {
161         log::debug!(
162             "[{}] reliability params: ordered={} type={} value={}",
163             self.name,
164             !unordered,
165             rel_type,
166             rel_val
167         );
168         self.unordered.store(unordered, Ordering::SeqCst);
169         self.reliability_type
170             .store(rel_type as u8, Ordering::SeqCst);
171         self.reliability_value.store(rel_val, Ordering::SeqCst);
172     }
173 
174     /// Reads a packet of len(p) bytes, dropping the Payload Protocol Identifier.
175     ///
176     /// Returns `Error::ErrShortBuffer` if `p` is too short.
177     /// Returns `0` if the reading half of this stream is shutdown or it (the stream) was reset.
178     pub async fn read(&self, p: &mut [u8]) -> Result<usize> {
179         let (n, _) = self.read_sctp(p).await?;
180         Ok(n)
181     }
182 
183     /// Reads a packet of len(p) bytes and returns the associated Payload Protocol Identifier.
184     ///
185     /// Returns `Error::ErrShortBuffer` if `p` is too short.
186     /// Returns `(0, PayloadProtocolIdentifier::Unknown)` if the reading half of this stream is shutdown or it (the stream) was reset.
187     pub async fn read_sctp(&self, p: &mut [u8]) -> Result<(usize, PayloadProtocolIdentifier)> {
188         loop {
189             if self.read_shutdown.load(Ordering::SeqCst) {
190                 return Ok((0, PayloadProtocolIdentifier::Unknown));
191             }
192 
193             let result = {
194                 let mut reassembly_queue = self.reassembly_queue.lock().await;
195                 reassembly_queue.read(p)
196             };
197 
198             match result {
199                 Ok(_) | Err(Error::ErrShortBuffer) => return result,
200                 Err(_) => {
201                     // wait for the next chunk to become available
202                     self.read_notifier.notified().await;
203                 }
204             }
205         }
206     }
207 
208     pub(crate) async fn handle_data(&self, pd: ChunkPayloadData) {
209         let readable = {
210             let mut reassembly_queue = self.reassembly_queue.lock().await;
211             if reassembly_queue.push(pd) {
212                 let readable = reassembly_queue.is_readable();
213                 log::debug!("[{}] reassemblyQueue readable={}", self.name, readable);
214                 readable
215             } else {
216                 false
217             }
218         };
219 
220         if readable {
221             log::debug!("[{}] readNotifier.signal()", self.name);
222             self.read_notifier.notify_one();
223             log::debug!("[{}] readNotifier.signal() done", self.name);
224         }
225     }
226 
227     pub(crate) async fn handle_forward_tsn_for_ordered(&self, ssn: u16) {
228         if self.unordered.load(Ordering::SeqCst) {
229             return; // unordered chunks are handled by handleForwardUnordered method
230         }
231 
232         // Remove all chunks older than or equal to the new TSN from
233         // the reassembly_queue.
234         let readable = {
235             let mut reassembly_queue = self.reassembly_queue.lock().await;
236             reassembly_queue.forward_tsn_for_ordered(ssn);
237             reassembly_queue.is_readable()
238         };
239 
240         // Notify the reader asynchronously if there's a data chunk to read.
241         if readable {
242             self.read_notifier.notify_one();
243         }
244     }
245 
246     pub(crate) async fn handle_forward_tsn_for_unordered(&self, new_cumulative_tsn: u32) {
247         if !self.unordered.load(Ordering::SeqCst) {
248             return; // ordered chunks are handled by handleForwardTSNOrdered method
249         }
250 
251         // Remove all chunks older than or equal to the new TSN from
252         // the reassembly_queue.
253         let readable = {
254             let mut reassembly_queue = self.reassembly_queue.lock().await;
255             reassembly_queue.forward_tsn_for_unordered(new_cumulative_tsn);
256             reassembly_queue.is_readable()
257         };
258 
259         // Notify the reader asynchronously if there's a data chunk to read.
260         if readable {
261             self.read_notifier.notify_one();
262         }
263     }
264 
265     /// Writes `p` to the DTLS connection with the default Payload Protocol Identifier.
266     ///
267     /// Returns an error if the write half of this stream is shutdown or `p` is too large.
268     pub async fn write(&self, p: &Bytes) -> Result<usize> {
269         self.write_sctp(p, self.default_payload_type.load(Ordering::SeqCst).into())
270             .await
271     }
272 
273     /// Writes `p` to the DTLS connection with the given Payload Protocol Identifier.
274     ///
275     /// Returns an error if the write half of this stream is shutdown or `p` is too large.
276     pub async fn write_sctp(&self, p: &Bytes, ppi: PayloadProtocolIdentifier) -> Result<usize> {
277         if self.write_shutdown.load(Ordering::SeqCst) {
278             return Err(Error::ErrStreamClosed);
279         }
280 
281         if p.len() > self.max_message_size.load(Ordering::SeqCst) as usize {
282             return Err(Error::ErrOutboundPacketTooLarge);
283         }
284 
285         let state: AssociationState = self.state.load(Ordering::SeqCst).into();
286         match state {
287             AssociationState::ShutdownSent
288             | AssociationState::ShutdownAckSent
289             | AssociationState::ShutdownPending
290             | AssociationState::ShutdownReceived => return Err(Error::ErrStreamClosed),
291             _ => {}
292         };
293 
294         let chunks = self.packetize(p, ppi);
295         self.send_payload_data(chunks).await?;
296 
297         Ok(p.len())
298     }
299 
300     fn packetize(&self, raw: &Bytes, ppi: PayloadProtocolIdentifier) -> Vec<ChunkPayloadData> {
301         let mut i = 0;
302         let mut remaining = raw.len();
303 
304         // From draft-ietf-rtcweb-data-protocol-09, section 6:
305         //   All Data Channel Establishment Protocol messages MUST be sent using
306         //   ordered delivery and reliable transmission.
307         let unordered =
308             ppi != PayloadProtocolIdentifier::Dcep && self.unordered.load(Ordering::SeqCst);
309 
310         let mut chunks = vec![];
311 
312         let head_abandoned = Arc::new(AtomicBool::new(false));
313         let head_all_inflight = Arc::new(AtomicBool::new(false));
314         while remaining != 0 {
315             let fragment_size = std::cmp::min(self.max_payload_size as usize, remaining); //self.association.max_payload_size
316 
317             // Copy the userdata since we'll have to store it until acked
318             // and the caller may re-use the buffer in the mean time
319             let user_data = raw.slice(i..i + fragment_size);
320 
321             let chunk = ChunkPayloadData {
322                 stream_identifier: self.stream_identifier,
323                 user_data,
324                 unordered,
325                 beginning_fragment: i == 0,
326                 ending_fragment: remaining - fragment_size == 0,
327                 immediate_sack: false,
328                 payload_type: ppi,
329                 stream_sequence_number: self.sequence_number.load(Ordering::SeqCst),
330                 abandoned: head_abandoned.clone(), // all fragmented chunks use the same abandoned
331                 all_inflight: head_all_inflight.clone(), // all fragmented chunks use the same all_inflight
332                 ..Default::default()
333             };
334 
335             chunks.push(chunk);
336 
337             remaining -= fragment_size;
338             i += fragment_size;
339         }
340 
341         // RFC 4960 Sec 6.6
342         // Note: When transmitting ordered and unordered data, an endpoint does
343         // not increment its Stream Sequence Number when transmitting a DATA
344         // chunk with U flag set to 1.
345         if !unordered {
346             self.sequence_number.fetch_add(1, Ordering::SeqCst);
347         }
348 
349         let old_value = self.buffered_amount.fetch_add(raw.len(), Ordering::SeqCst);
350         log::trace!("[{}] bufferedAmount = {}", self.name, old_value + raw.len());
351 
352         chunks
353     }
354 
355     /// Closes both read and write halves of this stream.
356     ///
357     /// Use [`Stream::shutdown`] instead.
358     #[deprecated]
359     pub async fn close(&self) -> Result<()> {
360         self.shutdown(Shutdown::Both).await
361     }
362 
363     /// Shuts down the read, write, or both halves of this stream.
364     ///
365     /// This function will cause all pending and future I/O on the specified portions to return
366     /// immediately with an appropriate value (see the documentation of [`Shutdown`]).
367     ///
368     /// Resets the stream when both halves of this stream are shutdown.
369     pub async fn shutdown(&self, how: Shutdown) -> Result<()> {
370         if self.read_shutdown.load(Ordering::SeqCst) && self.write_shutdown.load(Ordering::SeqCst) {
371             return Ok(());
372         }
373 
374         if how == Shutdown::Write || how == Shutdown::Both {
375             self.write_shutdown.store(true, Ordering::SeqCst);
376         }
377 
378         if (how == Shutdown::Read || how == Shutdown::Both)
379             && !self.read_shutdown.swap(true, Ordering::SeqCst)
380         {
381             self.read_notifier.notify_waiters();
382         }
383 
384         if how == Shutdown::Both
385             || (self.read_shutdown.load(Ordering::SeqCst)
386                 && self.write_shutdown.load(Ordering::SeqCst))
387         {
388             // Reset the stream
389             // https://tools.ietf.org/html/rfc6525
390             self.send_reset_request(self.stream_identifier).await?;
391         }
392 
393         Ok(())
394     }
395 
396     /// buffered_amount returns the number of bytes of data currently queued to be sent over this stream.
397     pub fn buffered_amount(&self) -> usize {
398         self.buffered_amount.load(Ordering::SeqCst)
399     }
400 
401     /// buffered_amount_low_threshold returns the number of bytes of buffered outgoing data that is
402     /// considered "low." Defaults to 0.
403     pub fn buffered_amount_low_threshold(&self) -> usize {
404         self.buffered_amount_low.load(Ordering::SeqCst)
405     }
406 
407     /// set_buffered_amount_low_threshold is used to update the threshold.
408     /// See buffered_amount_low_threshold().
409     pub fn set_buffered_amount_low_threshold(&self, th: usize) {
410         self.buffered_amount_low.store(th, Ordering::SeqCst);
411     }
412 
413     /// on_buffered_amount_low sets the callback handler which would be called when the number of
414     /// bytes of outgoing data buffered is lower than the threshold.
415     pub async fn on_buffered_amount_low(&self, f: OnBufferedAmountLowFn) {
416         let mut on_buffered_amount_low = self.on_buffered_amount_low.lock().await;
417         *on_buffered_amount_low = Some(f);
418     }
419 
420     /// This method is called by association's read_loop (go-)routine to notify this stream
421     /// of the specified amount of outgoing data has been delivered to the peer.
422     pub(crate) async fn on_buffer_released(&self, n_bytes_released: i64) {
423         if n_bytes_released <= 0 {
424             return;
425         }
426 
427         let from_amount = self.buffered_amount.load(Ordering::SeqCst);
428         let new_amount = if from_amount < n_bytes_released as usize {
429             self.buffered_amount.store(0, Ordering::SeqCst);
430             log::error!(
431                 "[{}] released buffer size {} should be <= {}",
432                 self.name,
433                 n_bytes_released,
434                 0,
435             );
436             0
437         } else {
438             self.buffered_amount
439                 .fetch_sub(n_bytes_released as usize, Ordering::SeqCst);
440 
441             from_amount - n_bytes_released as usize
442         };
443 
444         let buffered_amount_low = self.buffered_amount_low.load(Ordering::SeqCst);
445 
446         log::trace!(
447             "[{}] bufferedAmount = {}, from_amount = {}, buffered_amount_low = {}",
448             self.name,
449             new_amount,
450             from_amount,
451             buffered_amount_low,
452         );
453 
454         if from_amount > buffered_amount_low && new_amount <= buffered_amount_low {
455             let mut handler = self.on_buffered_amount_low.lock().await;
456             if let Some(f) = &mut *handler {
457                 f().await;
458             }
459         }
460     }
461 
462     /// get_num_bytes_in_reassembly_queue returns the number of bytes of data currently queued to
463     /// be read (once chunk is complete).
464     pub(crate) async fn get_num_bytes_in_reassembly_queue(&self) -> usize {
465         // No lock is required as it reads the size with atomic load function.
466         let reassembly_queue = self.reassembly_queue.lock().await;
467         reassembly_queue.get_num_bytes()
468     }
469 
470     /// get_state atomically returns the state of the Association.
471     fn get_state(&self) -> AssociationState {
472         self.state.load(Ordering::SeqCst).into()
473     }
474 
475     fn awake_write_loop(&self) {
476         //log::debug!("[{}] awake_write_loop_ch.notify_one", self.name);
477         if let Some(awake_write_loop_ch) = &self.awake_write_loop_ch {
478             let _ = awake_write_loop_ch.try_send(());
479         }
480     }
481 
482     async fn send_payload_data(&self, chunks: Vec<ChunkPayloadData>) -> Result<()> {
483         let state = self.get_state();
484         if state != AssociationState::Established {
485             return Err(Error::ErrPayloadDataStateNotExist);
486         }
487 
488         // Push the chunks into the pending queue first.
489         for c in chunks {
490             self.pending_queue.push(c).await;
491         }
492 
493         self.awake_write_loop();
494         Ok(())
495     }
496 
497     async fn send_reset_request(&self, stream_identifier: u16) -> Result<()> {
498         let state = self.get_state();
499         if state != AssociationState::Established {
500             return Err(Error::ErrResetPacketInStateNotExist);
501         }
502 
503         // Create DATA chunk which only contains valid stream identifier with
504         // nil userData and use it as a EOS from the stream.
505         let c = ChunkPayloadData {
506             stream_identifier,
507             beginning_fragment: true,
508             ending_fragment: true,
509             user_data: Bytes::new(),
510             ..Default::default()
511         };
512 
513         self.pending_queue.push(c).await;
514 
515         self.awake_write_loop();
516         Ok(())
517     }
518 }
519 
520 /// Default capacity of the temporary read buffer used by [`PollStream`].
521 const DEFAULT_READ_BUF_SIZE: usize = 8192;
522 
523 /// State of the read `Future` in [`PollStream`].
524 enum ReadFut {
525     /// Nothing in progress.
526     Idle,
527     /// Reading data from the underlying stream.
528     Reading(Pin<Box<dyn Future<Output = Result<Vec<u8>>> + Send>>),
529     /// Finished reading, but there's unread data in the temporary buffer.
530     RemainingData(Vec<u8>),
531 }
532 
533 impl ReadFut {
534     /// Gets a mutable reference to the future stored inside `Reading(future)`.
535     ///
536     /// # Panics
537     ///
538     /// Panics if `ReadFut` variant is not `Reading`.
539     fn get_reading_mut(&mut self) -> &mut Pin<Box<dyn Future<Output = Result<Vec<u8>>> + Send>> {
540         match self {
541             ReadFut::Reading(ref mut fut) => fut,
542             _ => panic!("expected ReadFut to be Reading"),
543         }
544     }
545 }
546 
547 /// A wrapper around around [`Stream`], which implements [`AsyncRead`] and
548 /// [`AsyncWrite`].
549 ///
550 /// Both `poll_read` and `poll_write` calls allocate temporary buffers, which results in an
551 /// additional overhead.
552 pub struct PollStream {
553     stream: Arc<Stream>,
554 
555     read_fut: ReadFut,
556     write_fut: Option<Pin<Box<dyn Future<Output = Result<usize>> + Send>>>,
557     shutdown_fut: Option<Pin<Box<dyn Future<Output = Result<()>> + Send>>>,
558 
559     read_buf_cap: usize,
560 }
561 
562 impl PollStream {
563     /// Constructs a new `PollStream`.
564     ///
565     /// # Examples
566     ///
567     /// ```
568     /// use webrtc_sctp::stream::{Stream, PollStream};
569     /// use std::sync::Arc;
570     ///
571     /// let stream = Arc::new(Stream::default());
572     /// let poll_stream = PollStream::new(stream);
573     /// ```
574     pub fn new(stream: Arc<Stream>) -> Self {
575         Self {
576             stream,
577             read_fut: ReadFut::Idle,
578             write_fut: None,
579             shutdown_fut: None,
580             read_buf_cap: DEFAULT_READ_BUF_SIZE,
581         }
582     }
583 
584     /// Get back the inner stream.
585     #[must_use]
586     pub fn into_inner(self) -> Arc<Stream> {
587         self.stream
588     }
589 
590     /// Obtain a clone of the inner stream.
591     #[must_use]
592     pub fn clone_inner(&self) -> Arc<Stream> {
593         self.stream.clone()
594     }
595 
596     /// stream_identifier returns the Stream identifier associated to the stream.
597     pub fn stream_identifier(&self) -> u16 {
598         self.stream.stream_identifier
599     }
600 
601     /// buffered_amount returns the number of bytes of data currently queued to be sent over this stream.
602     pub fn buffered_amount(&self) -> usize {
603         self.stream.buffered_amount.load(Ordering::SeqCst)
604     }
605 
606     /// buffered_amount_low_threshold returns the number of bytes of buffered outgoing data that is
607     /// considered "low." Defaults to 0.
608     pub fn buffered_amount_low_threshold(&self) -> usize {
609         self.stream.buffered_amount_low.load(Ordering::SeqCst)
610     }
611 
612     /// get_num_bytes_in_reassembly_queue returns the number of bytes of data currently queued to
613     /// be read (once chunk is complete).
614     pub(crate) async fn get_num_bytes_in_reassembly_queue(&self) -> usize {
615         // No lock is required as it reads the size with atomic load function.
616         let reassembly_queue = self.stream.reassembly_queue.lock().await;
617         reassembly_queue.get_num_bytes()
618     }
619 
620     /// Set the capacity of the temporary read buffer (default: 8192).
621     pub fn set_read_buf_capacity(&mut self, capacity: usize) {
622         self.read_buf_cap = capacity
623     }
624 }
625 
626 impl AsyncRead for PollStream {
627     fn poll_read(
628         mut self: Pin<&mut Self>,
629         cx: &mut Context<'_>,
630         buf: &mut ReadBuf<'_>,
631     ) -> Poll<io::Result<()>> {
632         if buf.remaining() == 0 {
633             return Poll::Ready(Ok(()));
634         }
635 
636         let fut = match self.read_fut {
637             ReadFut::Idle => {
638                 // read into a temporary buffer because `buf` has an unonymous lifetime, which can
639                 // be shorter than the lifetime of `read_fut`.
640                 let stream = self.stream.clone();
641                 let mut temp_buf = vec![0; self.read_buf_cap];
642                 self.read_fut = ReadFut::Reading(Box::pin(async move {
643                     stream.read(temp_buf.as_mut_slice()).await.map(|n| {
644                         temp_buf.truncate(n);
645                         temp_buf
646                     })
647                 }));
648                 self.read_fut.get_reading_mut()
649             }
650             ReadFut::Reading(ref mut fut) => fut,
651             ReadFut::RemainingData(ref mut data) => {
652                 let remaining = buf.remaining();
653                 let len = std::cmp::min(data.len(), remaining);
654                 buf.put_slice(&data[..len]);
655                 if data.len() > remaining {
656                     // ReadFut remains to be RemainingData
657                     data.drain(0..len);
658                 } else {
659                     self.read_fut = ReadFut::Idle;
660                 }
661                 return Poll::Ready(Ok(()));
662             }
663         };
664 
665         loop {
666             match fut.as_mut().poll(cx) {
667                 Poll::Pending => return Poll::Pending,
668                 // retry immediately upon empty data or incomplete chunks
669                 // since there's no way to setup a waker.
670                 Poll::Ready(Err(Error::ErrTryAgain)) => {}
671                 // EOF has been reached => don't touch buf and just return Ok
672                 Poll::Ready(Err(Error::ErrEof)) => {
673                     self.read_fut = ReadFut::Idle;
674                     return Poll::Ready(Ok(()));
675                 }
676                 Poll::Ready(Err(e)) => {
677                     self.read_fut = ReadFut::Idle;
678                     return Poll::Ready(Err(e.into()));
679                 }
680                 Poll::Ready(Ok(mut temp_buf)) => {
681                     let remaining = buf.remaining();
682                     let len = std::cmp::min(temp_buf.len(), remaining);
683                     buf.put_slice(&temp_buf[..len]);
684                     if temp_buf.len() > remaining {
685                         temp_buf.drain(0..len);
686                         self.read_fut = ReadFut::RemainingData(temp_buf);
687                     } else {
688                         self.read_fut = ReadFut::Idle;
689                     }
690                     return Poll::Ready(Ok(()));
691                 }
692             }
693         }
694     }
695 }
696 
697 impl AsyncWrite for PollStream {
698     fn poll_write(
699         mut self: Pin<&mut Self>,
700         cx: &mut Context<'_>,
701         buf: &[u8],
702     ) -> Poll<io::Result<usize>> {
703         let (fut, fut_is_new) = match self.write_fut.as_mut() {
704             Some(fut) => (fut, false),
705             None => {
706                 let stream = self.stream.clone();
707                 let bytes = Bytes::copy_from_slice(buf);
708                 (
709                     self.write_fut
710                         .get_or_insert(Box::pin(async move { stream.write(&bytes).await })),
711                     true,
712                 )
713             }
714         };
715 
716         match fut.as_mut().poll(cx) {
717             Poll::Pending => {
718                 // If it's the first time we're polling the future, `Poll::Pending` can't be
719                 // returned because that would mean the `PollStream` is not ready for writing. And
720                 // this is not true since we've just created a future, which is going to write the
721                 // buf to the underlying stream.
722                 //
723                 // It's okay to return `Poll::Ready` if the data is buffered (this is what the
724                 // buffered writer and `File` do).
725                 if fut_is_new {
726                     Poll::Ready(Ok(buf.len()))
727                 } else {
728                     // If it's the subsequent poll, it's okay to return `Poll::Pending` as it
729                     // indicates that the `PollStream` is not ready for writing. Only one future
730                     // can be in progress at the time.
731                     Poll::Pending
732                 }
733             }
734             Poll::Ready(Err(e)) => {
735                 self.write_fut = None;
736                 Poll::Ready(Err(e.into()))
737             }
738             Poll::Ready(Ok(n)) => {
739                 self.write_fut = None;
740                 Poll::Ready(Ok(n))
741             }
742         }
743     }
744 
745     fn poll_flush(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<io::Result<()>> {
746         match self.write_fut.as_mut() {
747             Some(fut) => match fut.as_mut().poll(cx) {
748                 Poll::Pending => Poll::Pending,
749                 Poll::Ready(Err(e)) => {
750                     self.write_fut = None;
751                     Poll::Ready(Err(e.into()))
752                 }
753                 Poll::Ready(Ok(_)) => {
754                     self.write_fut = None;
755                     Poll::Ready(Ok(()))
756                 }
757             },
758             None => Poll::Ready(Ok(())),
759         }
760     }
761 
762     fn poll_shutdown(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<io::Result<()>> {
763         let fut = match self.shutdown_fut.as_mut() {
764             Some(fut) => fut,
765             None => {
766                 let stream = self.stream.clone();
767                 self.shutdown_fut.get_or_insert(Box::pin(async move {
768                     stream.shutdown(Shutdown::Write).await
769                 }))
770             }
771         };
772 
773         match fut.as_mut().poll(cx) {
774             Poll::Pending => Poll::Pending,
775             Poll::Ready(Err(e)) => {
776                 self.shutdown_fut = None;
777                 Poll::Ready(Err(e.into()))
778             }
779             Poll::Ready(Ok(_)) => {
780                 self.shutdown_fut = None;
781                 Poll::Ready(Ok(()))
782             }
783         }
784     }
785 }
786 
787 impl Clone for PollStream {
788     fn clone(&self) -> PollStream {
789         PollStream::new(self.clone_inner())
790     }
791 }
792 
793 impl fmt::Debug for PollStream {
794     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
795         f.debug_struct("PollStream")
796             .field("stream", &self.stream)
797             .field("read_buf_cap", &self.read_buf_cap)
798             .finish()
799     }
800 }
801 
802 impl AsRef<Stream> for PollStream {
803     fn as_ref(&self) -> &Stream {
804         &self.stream
805     }
806 }
807