More send flow control
This commit is contained in:
@@ -24,11 +24,17 @@ impl FlowControl {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn has_capacity(&self) -> bool {
|
pub fn has_capacity(&self) -> bool {
|
||||||
self.window_size > 0
|
self.effective_window_size() > 0
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn window_size(&self) -> WindowSize {
|
pub fn effective_window_size(&self) -> WindowSize {
|
||||||
self.window_size
|
let plus = self.window_size + self.next_window_update;
|
||||||
|
|
||||||
|
if self.underflow >= plus {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
plus - self.underflow
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns true iff `claim_window(sz)` would return succeed.
|
/// Returns true iff `claim_window(sz)` would return succeed.
|
||||||
|
|||||||
@@ -32,7 +32,7 @@ impl<B> Prioritize<B>
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn available_window(&self) -> WindowSize {
|
pub fn available_window(&self) -> WindowSize {
|
||||||
let win = self.flow_control.window_size();
|
let win = self.flow_control.effective_window_size();
|
||||||
|
|
||||||
if self.buffered_data >= win as usize {
|
if self.buffered_data >= win as usize {
|
||||||
0
|
0
|
||||||
@@ -109,7 +109,7 @@ impl<B> Prioritize<B>
|
|||||||
Frame::Data(frame) => {
|
Frame::Data(frame) => {
|
||||||
let len = frame.payload().remaining();
|
let len = frame.payload().remaining();
|
||||||
|
|
||||||
if len > self.flow_control.window_size() as usize {
|
if len > self.flow_control.effective_window_size() as usize {
|
||||||
// TODO: This could be smarter...
|
// TODO: This could be smarter...
|
||||||
stream.pending_send.push_front(&mut self.buffer, frame.into());
|
stream.pending_send.push_front(&mut self.buffer, frame.into());
|
||||||
|
|
||||||
|
|||||||
@@ -197,19 +197,37 @@ impl<B> Send<B> where B: Buf {
|
|||||||
stream: &mut store::Ptr<B>)
|
stream: &mut store::Ptr<B>)
|
||||||
-> Result<(), ConnectionError>
|
-> Result<(), ConnectionError>
|
||||||
{
|
{
|
||||||
|
let connection = self.prioritize.available_window();
|
||||||
|
let unadvertised = stream.unadvertised_send_window;
|
||||||
|
|
||||||
|
let effective_window_size = {
|
||||||
|
let mut flow = match stream.state.send_flow_control() {
|
||||||
|
Some(flow) => flow,
|
||||||
|
None => return Ok(()),
|
||||||
|
};
|
||||||
|
|
||||||
|
debug_assert!(unadvertised == 0 || connection == 0);
|
||||||
|
|
||||||
|
// Expand the full window
|
||||||
|
flow.expand_window(frame.size_increment())?;
|
||||||
|
flow.effective_window_size()
|
||||||
|
};
|
||||||
|
|
||||||
|
if connection < effective_window_size {
|
||||||
|
stream.unadvertised_send_window = effective_window_size - connection;
|
||||||
|
|
||||||
|
// TODO: Queue the stream in a pending connection capacity list.
|
||||||
|
}
|
||||||
|
|
||||||
|
if stream.unadvertised_send_window == frame.size_increment() + unadvertised {
|
||||||
|
// The entire window update is unadvertised, no need to do anything
|
||||||
|
// else
|
||||||
|
return Ok(());
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: Notify the send task that there is additional capacity
|
||||||
|
|
||||||
unimplemented!();
|
unimplemented!();
|
||||||
/*
|
|
||||||
if let Some(flow) = stream.send_flow_control() {
|
|
||||||
// TODO: Handle invalid increment
|
|
||||||
flow.expand_window(frame.size_increment());
|
|
||||||
}
|
|
||||||
|
|
||||||
if let Some(task) = self.blocked.take() {
|
|
||||||
task.notify();
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(())
|
|
||||||
*/
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn dec_num_streams(&mut self) {
|
pub fn dec_num_streams(&mut self) {
|
||||||
|
|||||||
@@ -50,10 +50,12 @@ impl<B> Stream<B> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: remove?
|
||||||
pub fn send_flow_control(&mut self) -> Option<&mut FlowControl> {
|
pub fn send_flow_control(&mut self) -> Option<&mut FlowControl> {
|
||||||
self.state.send_flow_control()
|
self.state.send_flow_control()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: remove?
|
||||||
pub fn recv_flow_control(&mut self) -> Option<&mut FlowControl> {
|
pub fn recv_flow_control(&mut self) -> Option<&mut FlowControl> {
|
||||||
self.state.recv_flow_control()
|
self.state.recv_flow_control()
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user