Immediately apply initial window size to streams
The initial window size should be applied to streams once they leave the IDLE state.
This commit is contained in:
@@ -162,6 +162,11 @@ impl<B> Prioritize<B>
|
|||||||
stream: &mut store::Ptr<B>)
|
stream: &mut store::Ptr<B>)
|
||||||
-> Result<(), ConnectionError>
|
-> Result<(), ConnectionError>
|
||||||
{
|
{
|
||||||
|
// Ignore window updates when the stream is not active.
|
||||||
|
if !stream.state.could_send_data() {
|
||||||
|
return Ok(());
|
||||||
|
}
|
||||||
|
|
||||||
// Update the stream level flow control.
|
// Update the stream level flow control.
|
||||||
stream.send_flow.inc_window(inc)?;
|
stream.send_flow.inc_window(inc)?;
|
||||||
|
|
||||||
@@ -219,6 +224,8 @@ impl<B> Prioritize<B>
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// If the stream has requested capacity, then it must be in the
|
||||||
|
// streaming state.
|
||||||
debug_assert!(stream.state.is_send_streaming());
|
debug_assert!(stream.state.is_send_streaming());
|
||||||
|
|
||||||
// The amount of currently available capacity on the connection
|
// The amount of currently available capacity on the connection
|
||||||
|
|||||||
@@ -76,6 +76,11 @@ impl<B> Recv<B> where B: Buf {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Returns the initial receive window size
|
||||||
|
pub fn init_window_sz(&self) -> WindowSize {
|
||||||
|
self.init_window_sz
|
||||||
|
}
|
||||||
|
|
||||||
/// Returns the ID of the last processed stream
|
/// Returns the ID of the last processed stream
|
||||||
pub fn last_processed_id(&self) -> StreamId {
|
pub fn last_processed_id(&self) -> StreamId {
|
||||||
self.last_processed_id
|
self.last_processed_id
|
||||||
@@ -85,7 +90,7 @@ impl<B> Recv<B> where B: Buf {
|
|||||||
///
|
///
|
||||||
/// Returns the stream state if successful. `None` if refused
|
/// Returns the stream state if successful. `None` if refused
|
||||||
pub fn open<P: Peer>(&mut self, id: StreamId)
|
pub fn open<P: Peer>(&mut self, id: StreamId)
|
||||||
-> Result<Option<Stream<B>>, ConnectionError>
|
-> Result<Option<StreamId>, ConnectionError>
|
||||||
{
|
{
|
||||||
assert!(self.refused.is_none());
|
assert!(self.refused.is_none());
|
||||||
|
|
||||||
@@ -96,7 +101,7 @@ impl<B> Recv<B> where B: Buf {
|
|||||||
return Ok(None);
|
return Ok(None);
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(Some(Stream::new(id)))
|
Ok(Some(id))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn take_request(&mut self, stream: &mut store::Ptr<B>)
|
pub fn take_request(&mut self, stream: &mut store::Ptr<B>)
|
||||||
@@ -141,11 +146,6 @@ impl<B> Recv<B> where B: Buf {
|
|||||||
trace!("opening stream; init_window={}", self.init_window_sz);
|
trace!("opening stream; init_window={}", self.init_window_sz);
|
||||||
let is_initial = stream.state.recv_open(frame.is_end_stream())?;
|
let is_initial = stream.state.recv_open(frame.is_end_stream())?;
|
||||||
|
|
||||||
if stream.state.is_recv_streaming() {
|
|
||||||
stream.recv_flow.inc_window(self.init_window_sz)?;
|
|
||||||
stream.recv_flow.assign_capacity(self.init_window_sz);
|
|
||||||
}
|
|
||||||
|
|
||||||
if is_initial {
|
if is_initial {
|
||||||
if !self.can_inc_num_streams() {
|
if !self.can_inc_num_streams() {
|
||||||
unimplemented!();
|
unimplemented!();
|
||||||
@@ -285,6 +285,7 @@ impl<B> Recv<B> where B: Buf {
|
|||||||
|
|
||||||
pub fn recv_push_promise<P: Peer>(&mut self,
|
pub fn recv_push_promise<P: Peer>(&mut self,
|
||||||
frame: frame::PushPromise,
|
frame: frame::PushPromise,
|
||||||
|
send: &Send<B>,
|
||||||
stream: store::Key,
|
stream: store::Key,
|
||||||
store: &mut Store<B>)
|
store: &mut Store<B>)
|
||||||
-> Result<(), ConnectionError>
|
-> Result<(), ConnectionError>
|
||||||
@@ -309,7 +310,11 @@ impl<B> Recv<B> where B: Buf {
|
|||||||
// TODO: All earlier stream IDs should be implicitly closed.
|
// TODO: All earlier stream IDs should be implicitly closed.
|
||||||
|
|
||||||
// Now, create a new entry for the stream
|
// Now, create a new entry for the stream
|
||||||
let mut new_stream = Stream::new(frame.promised_id());
|
let mut new_stream = Stream::new(
|
||||||
|
frame.promised_id(),
|
||||||
|
send.init_window_sz(),
|
||||||
|
self.init_window_sz);
|
||||||
|
|
||||||
new_stream.state.reserve_remote();
|
new_stream.state.reserve_remote();
|
||||||
|
|
||||||
let mut ppp = store[stream].pending_push_promises.take();
|
let mut ppp = store[stream].pending_push_promises.take();
|
||||||
|
|||||||
@@ -47,6 +47,11 @@ impl<B> Send<B> where B: Buf {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Returns the initial send window size
|
||||||
|
pub fn init_window_sz(&self) -> WindowSize {
|
||||||
|
self.init_window_sz
|
||||||
|
}
|
||||||
|
|
||||||
pub fn poll_open_ready<P: Peer>(&mut self) -> Poll<(), ConnectionError> {
|
pub fn poll_open_ready<P: Peer>(&mut self) -> Poll<(), ConnectionError> {
|
||||||
try!(self.ensure_can_open::<P>());
|
try!(self.ensure_can_open::<P>());
|
||||||
|
|
||||||
@@ -64,7 +69,7 @@ impl<B> Send<B> where B: Buf {
|
|||||||
///
|
///
|
||||||
/// Returns the stream state if successful. `None` if refused
|
/// Returns the stream state if successful. `None` if refused
|
||||||
pub fn open<P: Peer>(&mut self)
|
pub fn open<P: Peer>(&mut self)
|
||||||
-> Result<Stream<B>, ConnectionError>
|
-> Result<StreamId, ConnectionError>
|
||||||
{
|
{
|
||||||
try!(self.ensure_can_open::<P>());
|
try!(self.ensure_can_open::<P>());
|
||||||
|
|
||||||
@@ -74,7 +79,7 @@ impl<B> Send<B> where B: Buf {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let ret = Stream::new(self.next_stream_id);
|
let ret = self.next_stream_id;
|
||||||
|
|
||||||
// Increment the number of locally initiated streams
|
// Increment the number of locally initiated streams
|
||||||
self.num_streams += 1;
|
self.num_streams += 1;
|
||||||
@@ -93,10 +98,6 @@ impl<B> Send<B> where B: Buf {
|
|||||||
// Update the state
|
// Update the state
|
||||||
stream.state.send_open(frame.is_end_stream())?;
|
stream.state.send_open(frame.is_end_stream())?;
|
||||||
|
|
||||||
if stream.state.is_send_streaming() {
|
|
||||||
stream.send_flow.inc_window(self.init_window_sz)?;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Queue the frame for sending
|
// Queue the frame for sending
|
||||||
self.prioritize.queue_frame(frame.into(), stream, task);
|
self.prioritize.queue_frame(frame.into(), stream, task);
|
||||||
|
|
||||||
|
|||||||
@@ -266,6 +266,16 @@ impl State {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Returns true if the stream is in a state such that it could send data in
|
||||||
|
/// the future.
|
||||||
|
pub fn could_send_data(&self) -> bool {
|
||||||
|
match self.inner {
|
||||||
|
Open { .. } => true,
|
||||||
|
HalfClosedRemote(_) => true,
|
||||||
|
_ => false,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn is_send_streaming(&self) -> bool {
|
pub fn is_send_streaming(&self) -> bool {
|
||||||
match self.inner {
|
match self.inner {
|
||||||
Open { local: Peer::Streaming, .. } => true,
|
Open { local: Peer::Streaming, .. } => true,
|
||||||
|
|||||||
@@ -83,8 +83,20 @@ pub(super) struct NextSendCapacity;
|
|||||||
pub(super) struct NextWindowUpdate;
|
pub(super) struct NextWindowUpdate;
|
||||||
|
|
||||||
impl<B> Stream<B> {
|
impl<B> Stream<B> {
|
||||||
pub fn new(id: StreamId) -> Stream<B>
|
pub fn new(id: StreamId,
|
||||||
|
init_send_window: WindowSize,
|
||||||
|
init_recv_window: WindowSize) -> Stream<B>
|
||||||
{
|
{
|
||||||
|
let mut send_flow = FlowControl::new();
|
||||||
|
let mut recv_flow = FlowControl::new();
|
||||||
|
|
||||||
|
recv_flow.inc_window(init_recv_window)
|
||||||
|
.ok().expect("invalid initial receive window");
|
||||||
|
recv_flow.assign_capacity(init_recv_window);
|
||||||
|
|
||||||
|
send_flow.inc_window(init_send_window)
|
||||||
|
.ok().expect("invalid initial send window size");
|
||||||
|
|
||||||
Stream {
|
Stream {
|
||||||
id,
|
id,
|
||||||
state: State::default(),
|
state: State::default(),
|
||||||
@@ -93,7 +105,7 @@ impl<B> Stream<B> {
|
|||||||
|
|
||||||
next_pending_send: None,
|
next_pending_send: None,
|
||||||
is_pending_send: false,
|
is_pending_send: false,
|
||||||
send_flow: FlowControl::new(),
|
send_flow: send_flow,
|
||||||
requested_send_capacity: 0,
|
requested_send_capacity: 0,
|
||||||
buffered_send_data: 0,
|
buffered_send_data: 0,
|
||||||
send_task: None,
|
send_task: None,
|
||||||
@@ -106,7 +118,7 @@ impl<B> Stream<B> {
|
|||||||
|
|
||||||
next_pending_accept: None,
|
next_pending_accept: None,
|
||||||
is_pending_accept: false,
|
is_pending_accept: false,
|
||||||
recv_flow: FlowControl::new(),
|
recv_flow: recv_flow,
|
||||||
in_flight_recv_data: 0,
|
in_flight_recv_data: 0,
|
||||||
next_window_update: None,
|
next_window_update: None,
|
||||||
is_pending_window_update: false,
|
is_pending_window_update: false,
|
||||||
|
|||||||
@@ -75,7 +75,14 @@ impl<B> Streams<B>
|
|||||||
}
|
}
|
||||||
|
|
||||||
match try!(me.actions.recv.open::<P>(id)) {
|
match try!(me.actions.recv.open::<P>(id)) {
|
||||||
Some(stream) => e.insert(stream),
|
Some(stream_id) => {
|
||||||
|
let stream = Stream::new(
|
||||||
|
stream_id,
|
||||||
|
me.actions.send.init_window_sz(),
|
||||||
|
me.actions.recv.init_window_sz());
|
||||||
|
|
||||||
|
e.insert(stream)
|
||||||
|
}
|
||||||
None => return Ok(()),
|
None => return Ok(()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -195,7 +202,8 @@ impl<B> Streams<B>
|
|||||||
None => return Err(ProtocolError.into()),
|
None => return Err(ProtocolError.into()),
|
||||||
};
|
};
|
||||||
|
|
||||||
me.actions.recv.recv_push_promise::<P>(frame, stream, &mut me.store)
|
me.actions.recv.recv_push_promise::<P>(
|
||||||
|
frame, &me.actions.send, stream, &mut me.store)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn next_incoming(&mut self) -> Option<StreamRef<B>> {
|
pub fn next_incoming(&mut self) -> Option<StreamRef<B>> {
|
||||||
@@ -273,11 +281,16 @@ impl<B> Streams<B>
|
|||||||
let me = &mut *me;
|
let me = &mut *me;
|
||||||
|
|
||||||
// Initialize a new stream. This fails if the connection is at capacity.
|
// Initialize a new stream. This fails if the connection is at capacity.
|
||||||
let mut stream = me.actions.send.open::<client::Peer>()?;
|
let stream_id = me.actions.send.open::<client::Peer>()?;
|
||||||
|
|
||||||
|
let stream = Stream::new(
|
||||||
|
stream_id,
|
||||||
|
me.actions.send.init_window_sz(),
|
||||||
|
me.actions.recv.init_window_sz());
|
||||||
|
|
||||||
// Convert the message
|
// Convert the message
|
||||||
let headers = client::Peer::convert_send_message(
|
let headers = client::Peer::convert_send_message(
|
||||||
stream.id, request, end_of_stream);
|
stream_id, request, end_of_stream);
|
||||||
|
|
||||||
let mut stream = me.store.insert(stream.id, stream);
|
let mut stream = me.store.insert(stream.id, stream);
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user