1use std::future::Future;
2use std::io;
3use std::pin::Pin;
4use std::sync::Arc;
5use std::sync::atomic::{
6 AtomicBool,
7 Ordering,
8};
9use std::task::{
10 Context,
11 Poll,
12};
13
14use bytes::{
15 Buf,
16 Bytes,
17 BytesMut,
18};
19use tokio::io::{
20 AsyncBufRead,
21 AsyncRead,
22 AsyncWrite,
23 ReadBuf,
24};
25use tokio::sync::mpsc;
26use tokio_util::sync::PollSender;
27
28use crate::error::Error;
29use crate::mux::{
30 MuxCommand,
31 MuxHandle,
32 SendWindow,
33 StreamRegistration,
34};
35
36pub struct Stream {
51 state: StreamState,
52}
53
54enum StreamState {
55 Unopened {
59 error_headers: Vec<(String, String)>,
60 data_headers: Vec<(String, String)>,
61 mux: MuxHandle,
62 data_rx: mpsc::Receiver<Bytes>,
63 error_rx: mpsc::Receiver<Bytes>,
64 pending_data_tx: Option<mpsc::Sender<Bytes>>,
67 pending_error_tx: Option<mpsc::Sender<Bytes>>,
68 max_frame_size: u32,
69 read_buf: Option<Bytes>,
70 read_eof: bool,
71 open_in_progress: Option<LazyOpenFuture>,
76 release_guard: Option<PairReleaseGuard>,
79 },
80 Opened {
81 data_id: u32,
82 data_rx: mpsc::Receiver<Bytes>,
83 error_rx: mpsc::Receiver<Bytes>,
84 mux: MuxHandle,
85 write_tx: PollSender<MuxCommand>,
86 send_window: Arc<SendWindow>,
87 max_frame_size: u32,
88 read_buf: Option<Bytes>,
89 read_eof: bool,
90 graceful_shutdown: Arc<AtomicBool>,
91 guard: StreamGuard,
92 },
93 Transitioning,
96}
97
98type LazyOpenFuture = Pin<Box<dyn Future<Output = Result<OpenedStreamParts, Error>> + Send>>;
100
101struct PairReleaseGuard {
105 mux: MuxHandle,
106 armed: bool,
107}
108
109impl PairReleaseGuard {
110 const fn new(mux: MuxHandle) -> Self {
111 Self { mux, armed: true }
112 }
113
114 const fn disarm(&mut self) {
117 self.armed = false;
118 }
119}
120
121impl Drop for PairReleaseGuard {
122 fn drop(&mut self) {
123 if self.armed {
124 self.mux.release_pair();
125 }
126 }
127}
128
129struct StreamGuard {
133 data_id: u32,
134 error_id: u32,
135 mux: MuxHandle,
136 ctrl_permit_error: Option<mpsc::OwnedPermit<MuxCommand>>,
137 ctrl_permit_data: Option<mpsc::OwnedPermit<MuxCommand>>,
138 close_reg_permit_error: Option<mpsc::OwnedPermit<StreamRegistration>>,
139 close_reg_permit_data: Option<mpsc::OwnedPermit<StreamRegistration>>,
140 graceful_shutdown: Arc<AtomicBool>,
146}
147
148const RST_STATUS_CANCEL: u32 = 5;
150
151impl Drop for StreamGuard {
152 fn drop(&mut self) {
153 let graceful = self.graceful_shutdown.load(Ordering::Acquire);
156
157 let _ = self.ctrl_permit_error.take();
168 if !graceful && let Some(permit) = self.ctrl_permit_data.take() {
169 permit.send(MuxCommand::CloseStream {
170 stream_id: self.data_id,
171 status: RST_STATUS_CANCEL,
172 });
173 }
174
175 if let Some(permit) = self.close_reg_permit_error.take() {
178 permit.send(StreamRegistration::Close {
179 stream_id: self.error_id,
180 });
181 }
182 if let Some(permit) = self.close_reg_permit_data.take() {
183 permit.send(StreamRegistration::Close {
184 stream_id: self.data_id,
185 });
186 }
187
188 self.mux.release_pair();
190 }
191}
192
193pub(crate) struct UnopenedStreamParts {
195 pub error_headers: Vec<(String, String)>,
196 pub data_headers: Vec<(String, String)>,
197 pub mux: MuxHandle,
198 pub data_rx: mpsc::Receiver<Bytes>,
199 pub error_rx: mpsc::Receiver<Bytes>,
200 pub pending_data_tx: mpsc::Sender<Bytes>,
201 pub pending_error_tx: mpsc::Sender<Bytes>,
202 pub max_frame_size: u32,
203}
204
205pub(crate) struct OpenedStreamParts {
208 pub data_id: u32,
209 pub error_id: u32,
210 pub send_window: Arc<SendWindow>,
211 pub ctrl_permit_error: mpsc::OwnedPermit<MuxCommand>,
212 pub ctrl_permit_data: mpsc::OwnedPermit<MuxCommand>,
213 pub close_reg_permit_error: mpsc::OwnedPermit<StreamRegistration>,
214 pub close_reg_permit_data: mpsc::OwnedPermit<StreamRegistration>,
215}
216
217impl Stream {
218 pub(crate) fn new_unopened(parts: UnopenedStreamParts) -> Self {
219 let UnopenedStreamParts {
220 error_headers,
221 data_headers,
222 mux,
223 data_rx,
224 error_rx,
225 pending_data_tx,
226 pending_error_tx,
227 max_frame_size,
228 } = parts;
229 let release_guard = PairReleaseGuard::new(mux.clone());
230 Self {
231 state: StreamState::Unopened {
232 error_headers,
233 data_headers,
234 mux,
235 data_rx,
236 error_rx,
237 pending_data_tx: Some(pending_data_tx),
238 pending_error_tx: Some(pending_error_tx),
239 max_frame_size,
240 read_buf: None,
241 read_eof: false,
242 open_in_progress: None,
243 release_guard: Some(release_guard),
244 },
245 }
246 }
247
248 pub fn is_read_closed(&self) -> bool {
255 match &self.state {
256 StreamState::Unopened {
257 read_eof, data_rx, ..
258 } => *read_eof || data_rx.is_closed(),
259 StreamState::Opened {
260 read_eof, data_rx, ..
261 } => *read_eof || data_rx.is_closed(),
262 StreamState::Transitioning => false,
263 }
264 }
265
266 pub fn split(self) -> (DataStream, ErrorStream) {
272 match self.state {
273 StreamState::Unopened {
274 error_headers,
275 data_headers,
276 mux,
277 data_rx,
278 error_rx,
279 pending_data_tx,
280 pending_error_tx,
281 max_frame_size,
282 read_buf,
283 read_eof,
284 open_in_progress,
285 release_guard,
286 } => {
287 let shared = Arc::new(parking_lot::Mutex::new(SharedSplitState::Unopened(
288 UnopenedShared {
289 error_headers,
290 data_headers,
291 mux,
292 pending_data_tx,
293 pending_error_tx,
294 open_in_progress,
295 release_guard,
296 },
297 )));
298 (
299 DataStream {
300 data_rx,
301 max_frame_size,
302 read_buf,
303 read_eof,
304 shared: Arc::clone(&shared),
305 },
306 ErrorStream {
307 error_rx,
308 error_buf: None,
309 error_eof: false,
310 shared,
311 },
312 )
313 }
314 StreamState::Opened {
315 data_id,
316 data_rx,
317 error_rx,
318 mux,
319 write_tx,
320 send_window,
321 max_frame_size,
322 read_buf,
323 read_eof,
324 graceful_shutdown,
325 guard,
326 } => {
327 let opened = OpenedShared {
328 data_id,
329 mux,
330 write_tx,
331 send_window,
332 graceful_shutdown,
333 guard,
334 };
335 let shared = Arc::new(parking_lot::Mutex::new(SharedSplitState::Opened(opened)));
336 (
337 DataStream {
338 data_rx,
339 max_frame_size,
340 read_buf,
341 read_eof,
342 shared: Arc::clone(&shared),
343 },
344 ErrorStream {
345 error_rx,
346 error_buf: None,
347 error_eof: false,
348 shared,
349 },
350 )
351 }
352 StreamState::Transitioning => {
353 unreachable!("split() called on transitioning stream")
354 }
355 }
356 }
357}
358
359impl Unpin for Stream {}
360
361fn poll_read_channel(
363 rx: &mut mpsc::Receiver<Bytes>, read_buf: &mut Option<Bytes>, read_eof: &mut bool,
364 cx: &mut Context<'_>, buf: &mut ReadBuf<'_>,
365) -> Poll<io::Result<()>> {
366 if *read_eof {
367 return Poll::Ready(Ok(()));
368 }
369
370 if let Some(ref mut remaining) = *read_buf {
372 let to_copy = remaining.len().min(buf.remaining());
373 buf.put_slice(&remaining[..to_copy]);
374 if to_copy >= remaining.len() {
375 *read_buf = None;
376 } else {
377 *remaining = remaining.slice(to_copy..);
378 }
379 return Poll::Ready(Ok(()));
380 }
381
382 match rx.poll_recv(cx) {
384 Poll::Ready(Some(data)) => {
385 let to_copy = data.len().min(buf.remaining());
386 buf.put_slice(&data[..to_copy]);
387 if to_copy < data.len() {
388 *read_buf = Some(data.slice(to_copy..));
389 }
390 Poll::Ready(Ok(()))
391 }
392 Poll::Ready(None) => {
393 *read_eof = true;
394 Poll::Ready(Ok(()))
395 }
396 Poll::Pending => Poll::Pending,
397 }
398}
399
400fn consume_channel_buf(read_buf: &mut Option<Bytes>, amt: usize) {
402 if let Some(ref mut bytes) = *read_buf {
403 let consumed = amt.min(bytes.len());
404 bytes.advance(consumed);
405 if bytes.is_empty() {
406 *read_buf = None;
407 }
408 }
409}
410
411fn poll_fill_buf_channel<'a>(
413 rx: &'a mut mpsc::Receiver<Bytes>, read_buf: &'a mut Option<Bytes>, read_eof: &'a mut bool,
414 cx: &mut Context<'_>,
415) -> Poll<io::Result<&'a [u8]>> {
416 loop {
417 if read_buf.as_ref().is_some_and(|b| !b.is_empty()) {
418 return Poll::Ready(Ok(read_buf.as_deref().unwrap()));
419 }
420 if read_buf.is_some() {
421 *read_buf = None;
422 }
423 if *read_eof {
424 return Poll::Ready(Ok(&[]));
425 }
426 match rx.poll_recv(cx) {
427 Poll::Pending => return Poll::Pending,
428 Poll::Ready(None) => {
429 *read_eof = true;
430 return Poll::Ready(Ok(&[]));
431 }
432 Poll::Ready(Some(b)) => {
433 *read_buf = Some(b);
434 }
435 }
436 }
437}
438
439fn poll_shutdown_opened(
442 graceful_shutdown: &AtomicBool, mux: &MuxHandle, data_id: u32,
443) -> Poll<io::Result<()>> {
444 graceful_shutdown.store(true, Ordering::Release);
445 let _ = mux.send_data_nonblocking(data_id, Bytes::new(), true);
446 Poll::Ready(Ok(()))
447}
448
449fn broken_pipe() -> io::Error {
450 io::Error::new(io::ErrorKind::BrokenPipe, "mux closed")
451}
452
453fn poll_write_via_sender(
472 write_tx: &mut PollSender<MuxCommand>, stream_id: u32, send_window: &SendWindow,
473 max_frame_size: u32, cx: &mut Context<'_>, buf: &[u8],
474) -> Poll<io::Result<usize>> {
475 if send_window.is_closed() {
477 return Poll::Ready(Err(broken_pipe()));
478 }
479
480 match write_tx.poll_reserve(cx) {
482 Poll::Ready(Ok(())) => {}
483 Poll::Ready(Err(_)) => return Poll::Ready(Err(broken_pipe())),
484 Poll::Pending => return Poll::Pending,
485 }
486
487 let max_payload = (max_frame_size as usize).saturating_sub(8);
489 let max_payload = if max_payload == 0 {
490 buf.len()
491 } else {
492 max_payload
493 };
494
495 let stream_avail = send_window.available().max(0) as usize;
497 let mut n = buf.len().min(stream_avail).min(max_payload);
498
499 if n == 0 {
500 send_window.register_waker(cx.waker());
502
503 if send_window.is_closed() {
505 return Poll::Ready(Err(broken_pipe()));
506 }
507 let stream_avail = send_window.available().max(0) as usize;
509 n = buf.len().min(stream_avail).min(max_payload);
510 if n == 0 {
511 return Poll::Pending;
512 }
513 }
514
515 if !send_window.consume(n) {
517 return Poll::Ready(Err(broken_pipe()));
518 }
519
520 let write_buf = &buf[..n];
522 let mut frame = BytesMut::with_capacity(8 + n);
523 frame.extend_from_slice(&(stream_id & 0x7FFF_FFFF).to_be_bytes());
524 let flags_len = (n as u32) & 0x00FF_FFFF;
525 frame.extend_from_slice(&flags_len.to_be_bytes());
526 frame.extend_from_slice(write_buf);
527
528 let cmd = MuxCommand::SendRawFrame {
529 frame: frame.freeze(),
530 };
531 match write_tx.send_item(cmd) {
532 Ok(()) => Poll::Ready(Ok(n)),
533 Err(_) => Poll::Ready(Err(broken_pipe())),
534 }
535}
536
537struct LazyOpenArgs<'a> {
542 error_headers: Vec<(String, String)>,
543 data_headers: Vec<(String, String)>,
544 max_frame_size: u32,
545 mux: &'a MuxHandle,
546 pending_data_tx: &'a mut Option<mpsc::Sender<Bytes>>,
547 pending_error_tx: &'a mut Option<mpsc::Sender<Bytes>>,
548 open_in_progress: &'a mut Option<LazyOpenFuture>,
549}
550
551fn poll_lazy_open(
566 args: LazyOpenArgs<'_>, cx: &mut Context<'_>, buf: &[u8],
567) -> Poll<io::Result<(OpenedStreamParts, usize)>> {
568 let LazyOpenArgs {
569 error_headers,
570 data_headers,
571 max_frame_size,
572 mux,
573 pending_data_tx,
574 pending_error_tx,
575 open_in_progress,
576 } = args;
577 if open_in_progress.is_none() {
578 let (Some(data_tx), Some(error_tx)) = (pending_data_tx.take(), pending_error_tx.take())
582 else {
583 return Poll::Ready(Err(broken_pipe()));
584 };
585 let max_payload = (max_frame_size as usize).saturating_sub(8).max(1);
586 let n = buf.len().min(max_payload);
587 let first_payload = Bytes::copy_from_slice(&buf[..n]);
592 let mux_clone = mux.clone();
593 let fut = async move {
594 mux_clone
595 .realize_stream_pair(
596 error_headers,
597 data_headers,
598 first_payload,
599 data_tx,
600 error_tx,
601 )
602 .await
603 };
604 *open_in_progress = Some(Box::pin(fut));
605 }
606
607 let fut = open_in_progress.as_mut().expect("future just inserted");
608 match fut.as_mut().poll(cx) {
609 Poll::Pending => Poll::Pending,
610 Poll::Ready(Ok(parts)) => {
611 *open_in_progress = None;
612 let max_payload = (max_frame_size as usize).saturating_sub(8).max(1);
613 let n = buf.len().min(max_payload);
614 Poll::Ready(Ok((parts, n)))
615 }
616 Poll::Ready(Err(_)) => {
617 *open_in_progress = None;
618 Poll::Ready(Err(broken_pipe()))
619 }
620 }
621}
622
623impl AsyncRead for Stream {
624 fn poll_read(
625 self: Pin<&mut Self>, cx: &mut Context<'_>, buf: &mut ReadBuf<'_>,
626 ) -> Poll<io::Result<()>> {
627 let this = self.get_mut();
628 match &mut this.state {
629 StreamState::Unopened {
630 data_rx,
631 read_buf,
632 read_eof,
633 ..
634 } => poll_read_channel(data_rx, read_buf, read_eof, cx, buf),
635 StreamState::Opened {
636 data_rx,
637 read_buf,
638 read_eof,
639 ..
640 } => poll_read_channel(data_rx, read_buf, read_eof, cx, buf),
641 StreamState::Transitioning => unreachable!(),
642 }
643 }
644}
645
646impl AsyncBufRead for Stream {
647 fn poll_fill_buf(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<io::Result<&[u8]>> {
648 let this = self.get_mut();
649 match &mut this.state {
650 StreamState::Unopened {
651 data_rx,
652 read_buf,
653 read_eof,
654 ..
655 } => poll_fill_buf_channel(data_rx, read_buf, read_eof, cx),
656 StreamState::Opened {
657 data_rx,
658 read_buf,
659 read_eof,
660 ..
661 } => poll_fill_buf_channel(data_rx, read_buf, read_eof, cx),
662 StreamState::Transitioning => unreachable!(),
663 }
664 }
665
666 fn consume(self: Pin<&mut Self>, amt: usize) {
667 let this = self.get_mut();
668 match &mut this.state {
669 StreamState::Unopened { read_buf, .. } => consume_channel_buf(read_buf, amt),
670 StreamState::Opened { read_buf, .. } => consume_channel_buf(read_buf, amt),
671 StreamState::Transitioning => unreachable!(),
672 }
673 }
674}
675
676impl AsyncWrite for Stream {
677 fn poll_write(
678 self: Pin<&mut Self>, cx: &mut Context<'_>, buf: &[u8],
679 ) -> Poll<io::Result<usize>> {
680 let this = self.get_mut();
681
682 if buf.is_empty() {
684 return Poll::Ready(Ok(0));
685 }
686
687 if matches!(this.state, StreamState::Unopened { .. }) {
690 let (parts, n_consumed) = match &mut this.state {
693 StreamState::Unopened {
694 error_headers,
695 data_headers,
696 mux,
697 pending_data_tx,
698 pending_error_tx,
699 open_in_progress,
700 max_frame_size,
701 ..
702 } => match poll_lazy_open(
703 LazyOpenArgs {
704 error_headers: std::mem::take(error_headers),
705 data_headers: std::mem::take(data_headers),
706 max_frame_size: *max_frame_size,
707 mux,
708 pending_data_tx,
709 pending_error_tx,
710 open_in_progress,
711 },
712 cx,
713 buf,
714 ) {
715 Poll::Ready(Ok(v)) => v,
716 Poll::Ready(Err(e)) => return Poll::Ready(Err(e)),
717 Poll::Pending => return Poll::Pending,
718 },
719 _ => unreachable!(),
720 };
721
722 let old = std::mem::replace(&mut this.state, StreamState::Transitioning);
725 let StreamState::Unopened {
726 mux,
727 data_rx,
728 error_rx,
729 max_frame_size,
730 read_buf,
731 read_eof,
732 mut release_guard,
733 ..
734 } = old
735 else {
736 unreachable!()
737 };
738 if let Some(g) = release_guard.as_mut() {
739 g.disarm();
740 }
741
742 let graceful_shutdown = Arc::new(AtomicBool::new(false));
743 let guard = StreamGuard {
744 data_id: parts.data_id,
745 error_id: parts.error_id,
746 mux: mux.clone(),
747 ctrl_permit_error: Some(parts.ctrl_permit_error),
748 ctrl_permit_data: Some(parts.ctrl_permit_data),
749 close_reg_permit_error: Some(parts.close_reg_permit_error),
750 close_reg_permit_data: Some(parts.close_reg_permit_data),
751 graceful_shutdown: Arc::clone(&graceful_shutdown),
752 };
753 let write_tx = PollSender::new(mux.cmd_sender());
754 this.state = StreamState::Opened {
755 data_id: parts.data_id,
756 data_rx,
757 error_rx,
758 mux,
759 write_tx,
760 send_window: parts.send_window,
761 max_frame_size,
762 read_buf,
763 read_eof,
764 graceful_shutdown,
765 guard,
766 };
767 drop(release_guard);
769 return Poll::Ready(Ok(n_consumed));
770 }
771
772 match &mut this.state {
773 StreamState::Opened {
774 data_id,
775 write_tx,
776 send_window,
777 max_frame_size,
778 ..
779 } => poll_write_via_sender(write_tx, *data_id, send_window, *max_frame_size, cx, buf),
780 StreamState::Unopened { .. } => unreachable!("handled above"),
781 StreamState::Transitioning => unreachable!(),
782 }
783 }
784
785 fn poll_flush(self: Pin<&mut Self>, _cx: &mut Context<'_>) -> Poll<io::Result<()>> {
786 Poll::Ready(Ok(()))
787 }
788
789 fn poll_shutdown(self: Pin<&mut Self>, _cx: &mut Context<'_>) -> Poll<io::Result<()>> {
790 let this = self.get_mut();
791 match &mut this.state {
792 StreamState::Unopened { .. } => Poll::Ready(Ok(())),
796 StreamState::Opened {
797 graceful_shutdown,
798 mux,
799 data_id,
800 ..
801 } => poll_shutdown_opened(graceful_shutdown, mux, *data_id),
802 StreamState::Transitioning => unreachable!(),
803 }
804 }
805}
806
807enum SharedSplitState {
811 Unopened(UnopenedShared),
812 Opened(OpenedShared),
813 Transitioning,
817}
818
819struct UnopenedShared {
820 error_headers: Vec<(String, String)>,
821 data_headers: Vec<(String, String)>,
822 mux: MuxHandle,
823 pending_data_tx: Option<mpsc::Sender<Bytes>>,
824 pending_error_tx: Option<mpsc::Sender<Bytes>>,
825 open_in_progress: Option<LazyOpenFuture>,
826 release_guard: Option<PairReleaseGuard>,
827}
828
829struct OpenedShared {
830 data_id: u32,
831 mux: MuxHandle,
832 write_tx: PollSender<MuxCommand>,
833 send_window: Arc<SendWindow>,
834 graceful_shutdown: Arc<AtomicBool>,
835 #[allow(dead_code)]
838 guard: StreamGuard,
839}
840
841pub struct DataStream {
844 data_rx: mpsc::Receiver<Bytes>,
845 max_frame_size: u32,
846 read_buf: Option<Bytes>,
847 read_eof: bool,
848 shared: Arc<parking_lot::Mutex<SharedSplitState>>,
849}
850
851impl Unpin for DataStream {}
852
853impl AsyncRead for DataStream {
854 fn poll_read(
855 self: Pin<&mut Self>, cx: &mut Context<'_>, buf: &mut ReadBuf<'_>,
856 ) -> Poll<io::Result<()>> {
857 let this = self.get_mut();
858 poll_read_channel(
859 &mut this.data_rx,
860 &mut this.read_buf,
861 &mut this.read_eof,
862 cx,
863 buf,
864 )
865 }
866}
867
868impl AsyncBufRead for DataStream {
869 fn poll_fill_buf(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<io::Result<&[u8]>> {
870 let this = self.get_mut();
871 poll_fill_buf_channel(
872 &mut this.data_rx,
873 &mut this.read_buf,
874 &mut this.read_eof,
875 cx,
876 )
877 }
878
879 fn consume(self: Pin<&mut Self>, amt: usize) {
880 consume_channel_buf(&mut self.get_mut().read_buf, amt);
881 }
882}
883
884impl AsyncWrite for DataStream {
885 fn poll_write(
886 self: Pin<&mut Self>, cx: &mut Context<'_>, buf: &[u8],
887 ) -> Poll<io::Result<usize>> {
888 let this = self.get_mut();
889 if buf.is_empty() {
890 return Poll::Ready(Ok(0));
891 }
892 let mut guard = this.shared.lock();
893 if let SharedSplitState::Unopened(u) = &mut *guard {
894 let res = poll_lazy_open(
895 LazyOpenArgs {
896 error_headers: std::mem::take(&mut u.error_headers),
897 data_headers: std::mem::take(&mut u.data_headers),
898 max_frame_size: this.max_frame_size,
899 mux: &u.mux,
900 pending_data_tx: &mut u.pending_data_tx,
901 pending_error_tx: &mut u.pending_error_tx,
902 open_in_progress: &mut u.open_in_progress,
903 },
904 cx,
905 buf,
906 );
907 match res {
908 Poll::Pending => return Poll::Pending,
909 Poll::Ready(Err(e)) => return Poll::Ready(Err(e)),
910 Poll::Ready(Ok((parts, n_consumed))) => {
911 let old = std::mem::replace(&mut *guard, SharedSplitState::Transitioning);
912 let SharedSplitState::Unopened(mut u) = old else {
913 unreachable!()
914 };
915 if let Some(g) = u.release_guard.as_mut() {
916 g.disarm();
917 }
918 let graceful_shutdown = Arc::new(AtomicBool::new(false));
919 let stream_guard = StreamGuard {
920 data_id: parts.data_id,
921 error_id: parts.error_id,
922 mux: u.mux.clone(),
923 ctrl_permit_error: Some(parts.ctrl_permit_error),
924 ctrl_permit_data: Some(parts.ctrl_permit_data),
925 close_reg_permit_error: Some(parts.close_reg_permit_error),
926 close_reg_permit_data: Some(parts.close_reg_permit_data),
927 graceful_shutdown: Arc::clone(&graceful_shutdown),
928 };
929 let write_tx = PollSender::new(u.mux.cmd_sender());
930 *guard = SharedSplitState::Opened(OpenedShared {
931 data_id: parts.data_id,
932 mux: u.mux,
933 write_tx,
934 send_window: parts.send_window,
935 graceful_shutdown,
936 guard: stream_guard,
937 });
938 drop(u.release_guard);
939 return Poll::Ready(Ok(n_consumed));
940 }
941 }
942 }
943 match &mut *guard {
944 SharedSplitState::Opened(o) => poll_write_via_sender(
945 &mut o.write_tx,
946 o.data_id,
947 &o.send_window,
948 this.max_frame_size,
949 cx,
950 buf,
951 ),
952 SharedSplitState::Unopened(_) => unreachable!("handled above"),
953 SharedSplitState::Transitioning => unreachable!(),
954 }
955 }
956
957 fn poll_flush(self: Pin<&mut Self>, _cx: &mut Context<'_>) -> Poll<io::Result<()>> {
958 Poll::Ready(Ok(()))
959 }
960
961 fn poll_shutdown(self: Pin<&mut Self>, _cx: &mut Context<'_>) -> Poll<io::Result<()>> {
962 let this = self.get_mut();
963 let guard = this.shared.lock();
964 match &*guard {
965 SharedSplitState::Unopened(_) => Poll::Ready(Ok(())),
966 SharedSplitState::Opened(o) => {
967 poll_shutdown_opened(&o.graceful_shutdown, &o.mux, o.data_id)
968 }
969 SharedSplitState::Transitioning => unreachable!(),
970 }
971 }
972}
973
974pub struct ErrorStream {
976 error_rx: mpsc::Receiver<Bytes>,
977 error_buf: Option<Bytes>,
978 error_eof: bool,
979 #[allow(dead_code)] shared: Arc<parking_lot::Mutex<SharedSplitState>>,
981}
982
983impl Unpin for ErrorStream {}
984
985impl AsyncRead for ErrorStream {
986 fn poll_read(
987 self: Pin<&mut Self>, cx: &mut Context<'_>, buf: &mut ReadBuf<'_>,
988 ) -> Poll<io::Result<()>> {
989 let this = self.get_mut();
990 poll_read_channel(
991 &mut this.error_rx,
992 &mut this.error_buf,
993 &mut this.error_eof,
994 cx,
995 buf,
996 )
997 }
998}