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