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.
56 lines
1.1 KiB
Rust
56 lines
1.1 KiB
Rust
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);
|
|
}
|
|
}
|