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>) | ||||
|         -> 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. | ||||
|         stream.send_flow.inc_window(inc)?; | ||||
|  | ||||
| @@ -219,6 +224,8 @@ impl<B> Prioritize<B> | ||||
|             return; | ||||
|         } | ||||
|  | ||||
|         // If the stream has requested capacity, then it must be in the | ||||
|         // streaming state. | ||||
|         debug_assert!(stream.state.is_send_streaming()); | ||||
|  | ||||
|         // 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 | ||||
|     pub fn last_processed_id(&self) -> StreamId { | ||||
|         self.last_processed_id | ||||
| @@ -85,7 +90,7 @@ impl<B> Recv<B> where B: Buf { | ||||
|     /// | ||||
|     /// Returns the stream state if successful. `None` if refused | ||||
|     pub fn open<P: Peer>(&mut self, id: StreamId) | ||||
|         -> Result<Option<Stream<B>>, ConnectionError> | ||||
|         -> Result<Option<StreamId>, ConnectionError> | ||||
|     { | ||||
|         assert!(self.refused.is_none()); | ||||
|  | ||||
| @@ -96,7 +101,7 @@ impl<B> Recv<B> where B: Buf { | ||||
|             return Ok(None); | ||||
|         } | ||||
|  | ||||
|         Ok(Some(Stream::new(id))) | ||||
|         Ok(Some(id)) | ||||
|     } | ||||
|  | ||||
|     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); | ||||
|         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 !self.can_inc_num_streams() { | ||||
|                 unimplemented!(); | ||||
| @@ -285,6 +285,7 @@ impl<B> Recv<B> where B: Buf { | ||||
|  | ||||
|     pub fn recv_push_promise<P: Peer>(&mut self, | ||||
|                                       frame: frame::PushPromise, | ||||
|                                       send: &Send<B>, | ||||
|                                       stream: store::Key, | ||||
|                                       store: &mut Store<B>) | ||||
|         -> Result<(), ConnectionError> | ||||
| @@ -309,7 +310,11 @@ impl<B> Recv<B> where B: Buf { | ||||
|         // TODO: All earlier stream IDs should be implicitly closed. | ||||
|  | ||||
|         // 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(); | ||||
|  | ||||
|         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> { | ||||
|         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 | ||||
|     pub fn open<P: Peer>(&mut self) | ||||
|         -> Result<Stream<B>, ConnectionError> | ||||
|         -> Result<StreamId, ConnectionError> | ||||
|     { | ||||
|         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 | ||||
|         self.num_streams += 1; | ||||
| @@ -93,10 +98,6 @@ impl<B> Send<B> where B: Buf { | ||||
|         // Update the state | ||||
|         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 | ||||
|         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 { | ||||
|         match self.inner { | ||||
|             Open { local: Peer::Streaming, .. } => true, | ||||
|   | ||||
| @@ -83,8 +83,20 @@ pub(super) struct NextSendCapacity; | ||||
| pub(super) struct NextWindowUpdate; | ||||
|  | ||||
| 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 { | ||||
|             id, | ||||
|             state: State::default(), | ||||
| @@ -93,7 +105,7 @@ impl<B> Stream<B> { | ||||
|  | ||||
|             next_pending_send: None, | ||||
|             is_pending_send: false, | ||||
|             send_flow: FlowControl::new(), | ||||
|             send_flow: send_flow, | ||||
|             requested_send_capacity: 0, | ||||
|             buffered_send_data: 0, | ||||
|             send_task: None, | ||||
| @@ -106,7 +118,7 @@ impl<B> Stream<B> { | ||||
|  | ||||
|             next_pending_accept: None, | ||||
|             is_pending_accept: false, | ||||
|             recv_flow: FlowControl::new(), | ||||
|             recv_flow: recv_flow, | ||||
|             in_flight_recv_data: 0, | ||||
|             next_window_update: None, | ||||
|             is_pending_window_update: false, | ||||
|   | ||||
| @@ -75,7 +75,14 @@ impl<B> Streams<B> | ||||
|                 } | ||||
|  | ||||
|                 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(()), | ||||
|                 } | ||||
|             } | ||||
| @@ -195,7 +202,8 @@ impl<B> Streams<B> | ||||
|             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>> { | ||||
| @@ -273,11 +281,16 @@ impl<B> Streams<B> | ||||
|             let me = &mut *me; | ||||
|  | ||||
|             // 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 | ||||
|             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); | ||||
|  | ||||
|   | ||||
		Reference in New Issue
	
	Block a user