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