Skip to content

Commit d32b804

Browse files
author
winters.zc
committed
fix: panic in pop_frame()
We met the panic in our production environment, so handle this panic condition before panic. The stack backtrace: 0: rust_begin_unwind at /rustc/59eed8a2aac0230a8b53e89d4e99d55912ba6b35/library/std/src/panicking.rs:517:5 1: core::panicking::panic_fmt at /rustc/59eed8a2aac0230a8b53e89d4e99d55912ba6b35/library/core/src/panicking.rs:101:14 2: core::panicking::panic at /rustc/59eed8a2aac0230a8b53e89d4e99d55912ba6b35/library/core/src/panicking.rs:50:5 3: h2::proto::streams::flow_control::FlowControl::send_data at /build/vendor/h2/src/proto/streams/flow_control.rs:176:9 4: h2::proto::streams::prioritize::Prioritize::pop_frame::{{closure}} at /build/vendor/h2/src/proto/streams/prioritize.rs:737:33 5: tracing::span::Span::in_scope at /build/vendor/tracing/src/span.rs:982:9 6: h2::proto::streams::prioritize::Prioritize::pop_frame at /build/vendor/h2/src/proto/streams/prioritize.rs:736:29 7: h2::proto::streams::prioritize::Prioritize::poll_complete at /build/vendor/h2/src/proto/streams/prioritize.rs:497:19 8: h2::proto::streams::send::Send::poll_complete at /build/vendor/h2/src/proto/streams/send.rs:297:9 9: h2::proto::streams::streams::Inner::poll_complete at /build/vendor/h2/src/proto/streams/streams.rs:850:16 10: h2::proto::streams::streams::Streams<B,P>::poll_complete at /build/vendor/h2/src/proto/streams/streams.rs:180:9 11: h2::proto::connection::Connection<T,P,B>::poll at /build/vendor/h2/src/proto/connection.rs:253:36 12: <h2::client::Connection<T,B> as core::future::future::Future>::poll 13: ...
1 parent 07d20b1 commit d32b804

File tree

2 files changed

+17
-6
lines changed

2 files changed

+17
-6
lines changed

src/proto/streams/flow_control.rs

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -173,12 +173,15 @@ impl FlowControl {
173173
self.available
174174
);
175175

176-
// Ensure that the argument is correct
177-
assert!(self.window_size >= sz as usize);
178-
179-
// Update values
180-
self.window_size -= sz;
181-
self.available -= sz;
176+
// If send size is zero it's meaningless to update flow control window
177+
if sz > 0 {
178+
// Ensure that the argument is correct
179+
assert!(self.window_size >= sz as usize);
180+
181+
// Update values
182+
self.window_size -= sz;
183+
self.available -= sz;
184+
}
182185
}
183186
}
184187

src/proto/streams/prioritize.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -744,6 +744,14 @@ impl Prioritize {
744744
// capacity at this point.
745745
debug_assert!(len <= self.flow.window_size());
746746

747+
// Check if the stream level window the peer knows is available. In some
748+
// scenarios, maybe the window we know is available but the window which
749+
// peer knows is not.
750+
if len > 0 && len >= stream.send_flow.window_size() {
751+
stream.pending_send.push_front(buffer, frame.into());
752+
continue;
753+
}
754+
747755
tracing::trace!(len, "sending data frame");
748756

749757
// Update the flow control

0 commit comments

Comments
 (0)