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 fn write(&self, p: &Bytes) -> Result<usize> { 273 self.write_sctp(p, self.default_payload_type.load(Ordering::SeqCst).into()) 274 } 275 276 /// Writes `p` to the DTLS connection with the given Payload Protocol Identifier. 277 /// 278 /// Returns an error if the write half of this stream is shutdown or `p` is too large. 279 pub fn write_sctp(&self, p: &Bytes, ppi: PayloadProtocolIdentifier) -> Result<usize> { 280 if self.write_shutdown.load(Ordering::SeqCst) { 281 return Err(Error::ErrStreamClosed); 282 } 283 284 if p.len() > self.max_message_size.load(Ordering::SeqCst) as usize { 285 return Err(Error::ErrOutboundPacketTooLarge); 286 } 287 288 let state: AssociationState = self.state.load(Ordering::SeqCst).into(); 289 match state { 290 AssociationState::ShutdownSent 291 | AssociationState::ShutdownAckSent 292 | AssociationState::ShutdownPending 293 | AssociationState::ShutdownReceived => return Err(Error::ErrStreamClosed), 294 _ => {} 295 }; 296 297 let chunks = self.packetize(p, ppi); 298 self.send_payload_data(chunks)?; 299 300 Ok(p.len()) 301 } 302 303 fn packetize(&self, raw: &Bytes, ppi: PayloadProtocolIdentifier) -> Vec<ChunkPayloadData> { 304 let mut i = 0; 305 let mut remaining = raw.len(); 306 307 // From draft-ietf-rtcweb-data-protocol-09, section 6: 308 // All Data Channel Establishment Protocol messages MUST be sent using 309 // ordered delivery and reliable transmission. 310 let unordered = 311 ppi != PayloadProtocolIdentifier::Dcep && self.unordered.load(Ordering::SeqCst); 312 313 let mut chunks = vec![]; 314 315 let head_abandoned = Arc::new(AtomicBool::new(false)); 316 let head_all_inflight = Arc::new(AtomicBool::new(false)); 317 while remaining != 0 { 318 let fragment_size = std::cmp::min(self.max_payload_size as usize, remaining); //self.association.max_payload_size 319 320 // Copy the userdata since we'll have to store it until acked 321 // and the caller may re-use the buffer in the mean time 322 let user_data = raw.slice(i..i + fragment_size); 323 324 let chunk = ChunkPayloadData { 325 stream_identifier: self.stream_identifier, 326 user_data, 327 unordered, 328 beginning_fragment: i == 0, 329 ending_fragment: remaining - fragment_size == 0, 330 immediate_sack: false, 331 payload_type: ppi, 332 stream_sequence_number: self.sequence_number.load(Ordering::SeqCst), 333 abandoned: head_abandoned.clone(), // all fragmented chunks use the same abandoned 334 all_inflight: head_all_inflight.clone(), // all fragmented chunks use the same all_inflight 335 ..Default::default() 336 }; 337 338 chunks.push(chunk); 339 340 remaining -= fragment_size; 341 i += fragment_size; 342 } 343 344 // RFC 4960 Sec 6.6 345 // Note: When transmitting ordered and unordered data, an endpoint does 346 // not increment its Stream Sequence Number when transmitting a DATA 347 // chunk with U flag set to 1. 348 if !unordered { 349 self.sequence_number.fetch_add(1, Ordering::SeqCst); 350 } 351 352 let old_value = self.buffered_amount.fetch_add(raw.len(), Ordering::SeqCst); 353 log::trace!("[{}] bufferedAmount = {}", self.name, old_value + raw.len()); 354 355 chunks 356 } 357 358 /// Closes both read and write halves of this stream. 359 /// 360 /// Use [`Stream::shutdown`] instead. 361 #[deprecated] 362 pub async fn close(&self) -> Result<()> { 363 self.shutdown(Shutdown::Both).await 364 } 365 366 /// Shuts down the read, write, or both halves of this stream. 367 /// 368 /// This function will cause all pending and future I/O on the specified portions to return 369 /// immediately with an appropriate value (see the documentation of [`Shutdown`]). 370 /// 371 /// Resets the stream when both halves of this stream are shutdown. 372 pub async fn shutdown(&self, how: Shutdown) -> Result<()> { 373 if self.read_shutdown.load(Ordering::SeqCst) && self.write_shutdown.load(Ordering::SeqCst) { 374 return Ok(()); 375 } 376 377 if how == Shutdown::Write || how == Shutdown::Both { 378 self.write_shutdown.store(true, Ordering::SeqCst); 379 } 380 381 if (how == Shutdown::Read || how == Shutdown::Both) 382 && !self.read_shutdown.swap(true, Ordering::SeqCst) 383 { 384 self.read_notifier.notify_waiters(); 385 } 386 387 if how == Shutdown::Both 388 || (self.read_shutdown.load(Ordering::SeqCst) 389 && self.write_shutdown.load(Ordering::SeqCst)) 390 { 391 // Reset the stream 392 // https://tools.ietf.org/html/rfc6525 393 self.send_reset_request(self.stream_identifier)?; 394 } 395 396 Ok(()) 397 } 398 399 /// buffered_amount returns the number of bytes of data currently queued to be sent over this stream. 400 pub fn buffered_amount(&self) -> usize { 401 self.buffered_amount.load(Ordering::SeqCst) 402 } 403 404 /// buffered_amount_low_threshold returns the number of bytes of buffered outgoing data that is 405 /// considered "low." Defaults to 0. 406 pub fn buffered_amount_low_threshold(&self) -> usize { 407 self.buffered_amount_low.load(Ordering::SeqCst) 408 } 409 410 /// set_buffered_amount_low_threshold is used to update the threshold. 411 /// See buffered_amount_low_threshold(). 412 pub fn set_buffered_amount_low_threshold(&self, th: usize) { 413 self.buffered_amount_low.store(th, Ordering::SeqCst); 414 } 415 416 /// on_buffered_amount_low sets the callback handler which would be called when the number of 417 /// bytes of outgoing data buffered is lower than the threshold. 418 pub fn on_buffered_amount_low(&self, f: OnBufferedAmountLowFn) { 419 self.on_buffered_amount_low 420 .store(Some(Arc::new(Mutex::new(f)))); 421 } 422 423 /// This method is called by association's read_loop (go-)routine to notify this stream 424 /// of the specified amount of outgoing data has been delivered to the peer. 425 pub(crate) async fn on_buffer_released(&self, n_bytes_released: i64) { 426 if n_bytes_released <= 0 { 427 return; 428 } 429 430 let from_amount = self.buffered_amount.load(Ordering::SeqCst); 431 let new_amount = if from_amount < n_bytes_released as usize { 432 self.buffered_amount.store(0, Ordering::SeqCst); 433 log::error!( 434 "[{}] released buffer size {} should be <= {}", 435 self.name, 436 n_bytes_released, 437 0, 438 ); 439 0 440 } else { 441 self.buffered_amount 442 .fetch_sub(n_bytes_released as usize, Ordering::SeqCst); 443 444 from_amount - n_bytes_released as usize 445 }; 446 447 let buffered_amount_low = self.buffered_amount_low.load(Ordering::SeqCst); 448 449 log::trace!( 450 "[{}] bufferedAmount = {}, from_amount = {}, buffered_amount_low = {}", 451 self.name, 452 new_amount, 453 from_amount, 454 buffered_amount_low, 455 ); 456 457 if from_amount > buffered_amount_low && new_amount <= buffered_amount_low { 458 if let Some(handler) = &*self.on_buffered_amount_low.load() { 459 let mut f = handler.lock().await; 460 f().await; 461 } 462 } 463 } 464 465 /// get_num_bytes_in_reassembly_queue returns the number of bytes of data currently queued to 466 /// be read (once chunk is complete). 467 pub(crate) async fn get_num_bytes_in_reassembly_queue(&self) -> usize { 468 // No lock is required as it reads the size with atomic load function. 469 let reassembly_queue = self.reassembly_queue.lock().await; 470 reassembly_queue.get_num_bytes() 471 } 472 473 /// get_state atomically returns the state of the Association. 474 fn get_state(&self) -> AssociationState { 475 self.state.load(Ordering::SeqCst).into() 476 } 477 478 fn awake_write_loop(&self) { 479 //log::debug!("[{}] awake_write_loop_ch.notify_one", self.name); 480 if let Some(awake_write_loop_ch) = &self.awake_write_loop_ch { 481 let _ = awake_write_loop_ch.try_send(()); 482 } 483 } 484 485 fn send_payload_data(&self, chunks: Vec<ChunkPayloadData>) -> Result<()> { 486 let state = self.get_state(); 487 if state != AssociationState::Established { 488 return Err(Error::ErrPayloadDataStateNotExist); 489 } 490 491 // NOTE: append is used here instead of push in order to prevent chunks interlacing. 492 self.pending_queue.append(chunks); 493 494 self.awake_write_loop(); 495 Ok(()) 496 } 497 498 fn send_reset_request(&self, stream_identifier: u16) -> Result<()> { 499 let state = self.get_state(); 500 if state != AssociationState::Established { 501 return Err(Error::ErrResetPacketInStateNotExist); 502 } 503 504 // Create DATA chunk which only contains valid stream identifier with 505 // nil userData and use it as a EOS from the stream. 506 let c = ChunkPayloadData { 507 stream_identifier, 508 beginning_fragment: true, 509 ending_fragment: true, 510 user_data: Bytes::new(), 511 ..Default::default() 512 }; 513 514 self.pending_queue.push(c); 515 516 self.awake_write_loop(); 517 Ok(()) 518 } 519 } 520 521 /// Default capacity of the temporary read buffer used by [`PollStream`]. 522 const DEFAULT_READ_BUF_SIZE: usize = 8192; 523 524 /// State of the read `Future` in [`PollStream`]. 525 enum ReadFut { 526 /// Nothing in progress. 527 Idle, 528 /// Reading data from the underlying stream. 529 Reading(Pin<Box<dyn Future<Output = Result<Vec<u8>>> + Send>>), 530 /// Finished reading, but there's unread data in the temporary buffer. 531 RemainingData(Vec<u8>), 532 } 533 534 impl ReadFut { 535 /// Gets a mutable reference to the future stored inside `Reading(future)`. 536 /// 537 /// # Panics 538 /// 539 /// Panics if `ReadFut` variant is not `Reading`. 540 fn get_reading_mut(&mut self) -> &mut Pin<Box<dyn Future<Output = Result<Vec<u8>>> + Send>> { 541 match self { 542 ReadFut::Reading(ref mut fut) => fut, 543 _ => panic!("expected ReadFut to be Reading"), 544 } 545 } 546 } 547 548 /// A wrapper around around [`Stream`], which implements [`AsyncRead`] and 549 /// [`AsyncWrite`]. 550 /// 551 /// Both `poll_read` and `poll_write` calls allocate temporary buffers, which results in an 552 /// additional overhead. 553 pub struct PollStream { 554 stream: Arc<Stream>, 555 556 read_fut: ReadFut, 557 write_fut: Option<Pin<Box<dyn Future<Output = Result<usize>> + Send>>>, 558 shutdown_fut: Option<Pin<Box<dyn Future<Output = Result<()>> + Send>>>, 559 560 read_buf_cap: usize, 561 } 562 563 impl PollStream { 564 /// Constructs a new `PollStream`. 565 /// 566 /// # Examples 567 /// 568 /// ``` 569 /// use webrtc_sctp::stream::{Stream, PollStream}; 570 /// use std::sync::Arc; 571 /// 572 /// let stream = Arc::new(Stream::default()); 573 /// let poll_stream = PollStream::new(stream); 574 /// ``` 575 pub fn new(stream: Arc<Stream>) -> Self { 576 Self { 577 stream, 578 read_fut: ReadFut::Idle, 579 write_fut: None, 580 shutdown_fut: None, 581 read_buf_cap: DEFAULT_READ_BUF_SIZE, 582 } 583 } 584 585 /// Get back the inner stream. 586 #[must_use] 587 pub fn into_inner(self) -> Arc<Stream> { 588 self.stream 589 } 590 591 /// Obtain a clone of the inner stream. 592 #[must_use] 593 pub fn clone_inner(&self) -> Arc<Stream> { 594 self.stream.clone() 595 } 596 597 /// stream_identifier returns the Stream identifier associated to the stream. 598 pub fn stream_identifier(&self) -> u16 { 599 self.stream.stream_identifier 600 } 601 602 /// buffered_amount returns the number of bytes of data currently queued to be sent over this stream. 603 pub fn buffered_amount(&self) -> usize { 604 self.stream.buffered_amount.load(Ordering::SeqCst) 605 } 606 607 /// buffered_amount_low_threshold returns the number of bytes of buffered outgoing data that is 608 /// considered "low." Defaults to 0. 609 pub fn buffered_amount_low_threshold(&self) -> usize { 610 self.stream.buffered_amount_low.load(Ordering::SeqCst) 611 } 612 613 /// get_num_bytes_in_reassembly_queue returns the number of bytes of data currently queued to 614 /// be read (once chunk is complete). 615 pub(crate) async fn get_num_bytes_in_reassembly_queue(&self) -> usize { 616 // No lock is required as it reads the size with atomic load function. 617 let reassembly_queue = self.stream.reassembly_queue.lock().await; 618 reassembly_queue.get_num_bytes() 619 } 620 621 /// Set the capacity of the temporary read buffer (default: 8192). 622 pub fn set_read_buf_capacity(&mut self, capacity: usize) { 623 self.read_buf_cap = capacity 624 } 625 } 626 627 impl AsyncRead for PollStream { 628 fn poll_read( 629 mut self: Pin<&mut Self>, 630 cx: &mut Context<'_>, 631 buf: &mut ReadBuf<'_>, 632 ) -> Poll<io::Result<()>> { 633 if buf.remaining() == 0 { 634 return Poll::Ready(Ok(())); 635 } 636 637 let fut = match self.read_fut { 638 ReadFut::Idle => { 639 // read into a temporary buffer because `buf` has an unonymous lifetime, which can 640 // be shorter than the lifetime of `read_fut`. 641 let stream = self.stream.clone(); 642 let mut temp_buf = vec![0; self.read_buf_cap]; 643 self.read_fut = ReadFut::Reading(Box::pin(async move { 644 stream.read(temp_buf.as_mut_slice()).await.map(|n| { 645 temp_buf.truncate(n); 646 temp_buf 647 }) 648 })); 649 self.read_fut.get_reading_mut() 650 } 651 ReadFut::Reading(ref mut fut) => fut, 652 ReadFut::RemainingData(ref mut data) => { 653 let remaining = buf.remaining(); 654 let len = std::cmp::min(data.len(), remaining); 655 buf.put_slice(&data[..len]); 656 if data.len() > remaining { 657 // ReadFut remains to be RemainingData 658 data.drain(0..len); 659 } else { 660 self.read_fut = ReadFut::Idle; 661 } 662 return Poll::Ready(Ok(())); 663 } 664 }; 665 666 loop { 667 match fut.as_mut().poll(cx) { 668 Poll::Pending => return Poll::Pending, 669 // retry immediately upon empty data or incomplete chunks 670 // since there's no way to setup a waker. 671 Poll::Ready(Err(Error::ErrTryAgain)) => {} 672 // EOF has been reached => don't touch buf and just return Ok 673 Poll::Ready(Err(Error::ErrEof)) => { 674 self.read_fut = ReadFut::Idle; 675 return Poll::Ready(Ok(())); 676 } 677 Poll::Ready(Err(e)) => { 678 self.read_fut = ReadFut::Idle; 679 return Poll::Ready(Err(e.into())); 680 } 681 Poll::Ready(Ok(mut temp_buf)) => { 682 let remaining = buf.remaining(); 683 let len = std::cmp::min(temp_buf.len(), remaining); 684 buf.put_slice(&temp_buf[..len]); 685 if temp_buf.len() > remaining { 686 temp_buf.drain(0..len); 687 self.read_fut = ReadFut::RemainingData(temp_buf); 688 } else { 689 self.read_fut = ReadFut::Idle; 690 } 691 return Poll::Ready(Ok(())); 692 } 693 } 694 } 695 } 696 } 697 698 impl AsyncWrite for PollStream { 699 fn poll_write( 700 self: Pin<&mut Self>, 701 _cx: &mut Context<'_>, 702 buf: &[u8], 703 ) -> Poll<io::Result<usize>> { 704 let bytes = Bytes::copy_from_slice(buf); 705 match self.stream.write(&bytes) { 706 Ok(n) => Poll::Ready(Ok(n)), 707 Err(e) => Poll::Ready(Err(e.into())), 708 } 709 } 710 711 fn poll_flush(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<io::Result<()>> { 712 match self.write_fut.as_mut() { 713 Some(fut) => match fut.as_mut().poll(cx) { 714 Poll::Pending => Poll::Pending, 715 Poll::Ready(Err(e)) => { 716 self.write_fut = None; 717 Poll::Ready(Err(e.into())) 718 } 719 Poll::Ready(Ok(_)) => { 720 self.write_fut = None; 721 Poll::Ready(Ok(())) 722 } 723 }, 724 None => Poll::Ready(Ok(())), 725 } 726 } 727 728 fn poll_shutdown(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<io::Result<()>> { 729 match self.as_mut().poll_flush(cx) { 730 Poll::Pending => return Poll::Pending, 731 Poll::Ready(_) => {} 732 } 733 734 let fut = match self.shutdown_fut.as_mut() { 735 Some(fut) => fut, 736 None => { 737 let stream = self.stream.clone(); 738 self.shutdown_fut.get_or_insert(Box::pin(async move { 739 stream.shutdown(Shutdown::Write).await 740 })) 741 } 742 }; 743 744 match fut.as_mut().poll(cx) { 745 Poll::Pending => Poll::Pending, 746 Poll::Ready(Err(e)) => { 747 self.shutdown_fut = None; 748 Poll::Ready(Err(e.into())) 749 } 750 Poll::Ready(Ok(_)) => { 751 self.shutdown_fut = None; 752 Poll::Ready(Ok(())) 753 } 754 } 755 } 756 } 757 758 impl Clone for PollStream { 759 fn clone(&self) -> PollStream { 760 PollStream::new(self.clone_inner()) 761 } 762 } 763 764 impl fmt::Debug for PollStream { 765 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { 766 f.debug_struct("PollStream") 767 .field("stream", &self.stream) 768 .field("read_buf_cap", &self.read_buf_cap) 769 .finish() 770 } 771 } 772 773 impl AsRef<Stream> for PollStream { 774 fn as_ref(&self) -> &Stream { 775 &self.stream 776 } 777 } 778