h2
h2 copied to clipboard
poll_capacity spuriously returns Ready(Some(0))
Sometimes, under active IO poll_capacity returns Poll(Ready(Some(0))). In this situation there is not much caller can do to wait for the capacity becomes available.
It appears to be a concurrency/timing issue - my reconstruction of the events hints that it can happen when wakeup is called from one thread while the outer is sending data on a stream - e.g. -
- thread A - sender called poll_capacity, got 16K and proceeded to send_data
- thread B - connection got a window update and sent out some pending frames. capacity did not increase but wakeup was 3) scheduled and send_capacity_inc set. thread A - sent the data and capacity is now 0, send_capacity_inc set
- thread A - poll_capacity returns 0
One solution is not to wakeup from pop_frame
if capacity has not changed.
It is not quite clear if this would be a robust solution and this is the only situation - because 'if send_capacity_inc is set - capacity > 0' doesn't appear to be an atomic invariant.