Streams receiving peer reset clear pending send (#238)
Because streams that were being peer reset were not clearing pending send frames / buffered_send_data, they were not being counted towards the concurrency limit.
This commit is contained in:
committed by
Sean McArthur
parent
267789da92
commit
f8baeb7211
@@ -555,6 +555,9 @@ impl Prioritize {
|
||||
while let Some(frame) = stream.pending_send.pop_front(buffer) {
|
||||
trace!("dropping; frame={:?}", frame);
|
||||
}
|
||||
|
||||
stream.buffered_send_data = 0;
|
||||
stream.requested_send_capacity = 0;
|
||||
}
|
||||
|
||||
fn pop_frame<B>(
|
||||
@@ -574,6 +577,14 @@ impl Prioritize {
|
||||
Some(mut stream) => {
|
||||
trace!("pop_frame; stream={:?}", stream.id);
|
||||
|
||||
// If the stream receives a RESET from the peer, it may have
|
||||
// had data buffered to be sent, but all the frames are cleared
|
||||
// in clear_queue(). Instead of doing O(N) traversal through queue
|
||||
// to remove, lets just ignore peer_reset streams here.
|
||||
if stream.state.is_peer_reset() {
|
||||
continue;
|
||||
}
|
||||
|
||||
// It's possible that this stream, besides having data to send,
|
||||
// is also queued to send a reset, and thus is already in the queue
|
||||
// to wait for "some time" after a reset.
|
||||
|
||||
@@ -588,16 +588,12 @@ impl Recv {
|
||||
}
|
||||
|
||||
/// Handle remote sending an explicit RST_STREAM.
|
||||
pub fn recv_reset(
|
||||
&mut self,
|
||||
frame: frame::Reset,
|
||||
stream: &mut Stream,
|
||||
) -> Result<(), RecvError> {
|
||||
pub fn recv_reset(&mut self, frame: frame::Reset, stream: &mut Stream) {
|
||||
// Notify the stream
|
||||
stream.state.recv_reset(frame.reason());
|
||||
|
||||
stream.notify_send();
|
||||
stream.notify_recv();
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Handle a received error
|
||||
|
||||
@@ -283,6 +283,15 @@ impl Send {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn recv_reset<B>(
|
||||
&mut self,
|
||||
buffer: &mut Buffer<Frame<B>>,
|
||||
stream: &mut store::Ptr
|
||||
) {
|
||||
// Clear all pending outbound frames
|
||||
self.prioritize.clear_queue(buffer, stream);
|
||||
}
|
||||
|
||||
pub fn recv_err<B>(
|
||||
&mut self,
|
||||
buffer: &mut Buffer<Frame<B>>,
|
||||
|
||||
@@ -301,6 +301,13 @@ impl State {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn is_peer_reset(&self) -> bool {
|
||||
match self.inner {
|
||||
Closed(Cause::Proto(_)) => true,
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns true if the stream is already reset.
|
||||
pub fn is_reset(&self) -> bool {
|
||||
match self.inner {
|
||||
|
||||
@@ -255,10 +255,14 @@ where
|
||||
},
|
||||
};
|
||||
|
||||
let mut send_buffer = self.send_buffer.inner.lock().unwrap();
|
||||
let send_buffer = &mut *send_buffer;
|
||||
|
||||
let actions = &mut me.actions;
|
||||
|
||||
me.counts.transition(stream, |_, stream| {
|
||||
actions.recv.recv_reset(frame, stream)?;
|
||||
actions.recv.recv_reset(frame, stream);
|
||||
actions.send.recv_reset(send_buffer, stream);
|
||||
assert!(stream.state.is_closed());
|
||||
Ok(())
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user