Fix some flow control bugs. (#152)
* Release stream capacity back to the connection to avoid capacity leaks. * Actually notify waiting tasks when capacity becomes available.
This commit is contained in:
@@ -248,6 +248,8 @@ where
|
||||
where
|
||||
R: Resolve<B, P>,
|
||||
{
|
||||
trace!("assign_connection_capacity; inc={}", inc);
|
||||
|
||||
self.flow.assign_capacity(inc);
|
||||
|
||||
// Assign newly acquired capacity to streams pending capacity.
|
||||
@@ -315,6 +317,8 @@ where
|
||||
// TODO: Should prioritization factor into this?
|
||||
let assign = cmp::min(conn_available, additional);
|
||||
|
||||
trace!(" assigning; num={}", assign);
|
||||
|
||||
// Assign the capacity to the stream
|
||||
stream.assign_capacity(assign);
|
||||
|
||||
|
||||
@@ -214,6 +214,7 @@ where
|
||||
}
|
||||
|
||||
if !stream.send_capacity_inc {
|
||||
stream.wait_send();
|
||||
return Ok(Async::NotReady);
|
||||
}
|
||||
|
||||
@@ -304,13 +305,16 @@ where
|
||||
|
||||
trace!("decrementing all windows; dec={}", dec);
|
||||
|
||||
let mut total_reclaimed = 0;
|
||||
store.for_each(|mut stream| {
|
||||
let stream = &mut *stream;
|
||||
|
||||
stream.send_flow.dec_window(dec);
|
||||
|
||||
let available = stream.send_flow.available().as_size();
|
||||
stream.send_flow.claim_capacity(cmp::min(dec, available));
|
||||
let reclaim = cmp::min(dec, available);
|
||||
stream.send_flow.claim_capacity(reclaim);
|
||||
total_reclaimed += reclaim;
|
||||
|
||||
trace!(
|
||||
"decremented stream window; id={:?}; decr={}; flow={:?}",
|
||||
@@ -319,15 +323,15 @@ where
|
||||
stream.send_flow
|
||||
);
|
||||
|
||||
// TODO: Probably try to assign capacity?
|
||||
|
||||
// TODO: Handle reclaiming connection level window
|
||||
// capacity.
|
||||
|
||||
// TODO: Should this notify the producer?
|
||||
// TODO: Should this notify the producer when the capacity
|
||||
// of a stream is reduced? Maybe it should if the capacity
|
||||
// is reduced to zero, allowing the producer to stop work.
|
||||
|
||||
Ok::<_, RecvError>(())
|
||||
})?;
|
||||
|
||||
self.prioritize
|
||||
.assign_connection_capacity(total_reclaimed, store);
|
||||
} else if val > old_val {
|
||||
let inc = val - old_val;
|
||||
|
||||
|
||||
@@ -229,8 +229,12 @@ where
|
||||
self.send_capacity_inc = true;
|
||||
self.send_flow.assign_capacity(capacity);
|
||||
|
||||
trace!(" assigned capacity to stream; available={}; buffered={}; id={:?}",
|
||||
self.send_flow.available(), self.buffered_send_data, self.id);
|
||||
|
||||
// Only notify if the capacity exceeds the amount of buffered data
|
||||
if self.send_flow.available() > self.buffered_send_data {
|
||||
trace!(" notifying task");
|
||||
self.notify_send();
|
||||
}
|
||||
}
|
||||
@@ -263,6 +267,10 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
pub fn wait_send(&mut self) {
|
||||
self.send_task = Some(task::current());
|
||||
}
|
||||
|
||||
pub fn notify_recv(&mut self) {
|
||||
if let Some(task) = self.recv_task.take() {
|
||||
task.notify();
|
||||
|
||||
Reference in New Issue
Block a user