Fix flow control bug (#177)
This patch fixes a bug that prevents sent data from being flushed to the socket. When data is sent, the task managing the connection must be notified. A guard exists that prevents unnecessary notification of the connection when the stream does not have any send capacity. However, this guard was buggy. Instead of notifying the connection if *any* data can be sent, it notified the connection only when *all* data could be sent. This patch fixes the check as well as adds some tests that ensure the connection task is notified.
This commit is contained in:
@@ -52,6 +52,7 @@ pub mod raw;
|
||||
pub mod frames;
|
||||
pub mod prelude;
|
||||
pub mod mock;
|
||||
pub mod notify;
|
||||
pub mod util;
|
||||
|
||||
mod future_ext;
|
||||
|
||||
55
tests/support/notify.rs
Normal file
55
tests/support/notify.rs
Normal file
@@ -0,0 +1,55 @@
|
||||
use futures::executor::{self, Notify};
|
||||
|
||||
use std::sync::Arc;
|
||||
use std::sync::atomic::AtomicBool;
|
||||
use std::sync::atomic::Ordering::SeqCst;
|
||||
|
||||
pub struct MockNotify {
|
||||
inner: Arc<Inner>,
|
||||
}
|
||||
|
||||
struct Inner {
|
||||
notified: AtomicBool,
|
||||
}
|
||||
|
||||
impl MockNotify {
|
||||
pub fn new() -> Self {
|
||||
MockNotify {
|
||||
inner: Arc::new(Inner {
|
||||
notified: AtomicBool::new(false),
|
||||
}),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn with<F: FnOnce() -> R, R>(&self, f: F) -> R {
|
||||
use futures::Async::Ready;
|
||||
use futures::future::poll_fn;
|
||||
|
||||
self.clear();
|
||||
|
||||
let mut f = Some(f);
|
||||
|
||||
let res = executor::spawn(poll_fn(move || {
|
||||
Ok::<_, ()>(Ready(f.take().unwrap()()))
|
||||
})).poll_future_notify(&self.inner, 0);
|
||||
|
||||
match res {
|
||||
Ok(Ready(v)) => v,
|
||||
_ => unreachable!(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn clear(&self) {
|
||||
self.inner.notified.store(false, SeqCst);
|
||||
}
|
||||
|
||||
pub fn is_notified(&self) -> bool {
|
||||
self.inner.notified.load(SeqCst)
|
||||
}
|
||||
}
|
||||
|
||||
impl Notify for Inner {
|
||||
fn notify(&self, _: usize) {
|
||||
self.notified.store(true, SeqCst);
|
||||
}
|
||||
}
|
||||
@@ -13,6 +13,9 @@ pub use super::mock::{self, HandleFutureExt};
|
||||
// Re-export frames helpers
|
||||
pub use super::frames;
|
||||
|
||||
// Re-export mock notify
|
||||
pub use super::notify::MockNotify;
|
||||
|
||||
// Re-export utility mod
|
||||
pub use super::util;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user