Auto merge of #54339 - cramertj:no-cx, r=aturon

Remove spawning from task::Context

r? @aturon

cc https://github.com/rust-lang-nursery/wg-net/issues/56
This commit is contained in:
bors 2018-09-23 10:09:22 +00:00
commit 2287a7a6e2
13 changed files with 93 additions and 568 deletions

View file

@ -18,10 +18,8 @@ use std::sync::{
Arc,
atomic::{self, AtomicUsize},
};
use std::future::FutureObj;
use std::task::{
Context, Poll, Wake,
Spawn, SpawnObjError,
LocalWaker, Poll, Wake,
local_waker_from_nonlocal,
};
@ -35,24 +33,17 @@ impl Wake for Counter {
}
}
struct NoopSpawner;
impl Spawn for NoopSpawner {
fn spawn_obj(&mut self, _: FutureObj<'static, ()>) -> Result<(), SpawnObjError> {
Ok(())
}
}
struct WakeOnceThenComplete(bool);
fn wake_and_yield_once() -> WakeOnceThenComplete { WakeOnceThenComplete(false) }
impl Future for WakeOnceThenComplete {
type Output = ();
fn poll(mut self: Pin<&mut Self>, cx: &mut Context) -> Poll<()> {
fn poll(mut self: Pin<&mut Self>, lw: &LocalWaker) -> Poll<()> {
if self.0 {
Poll::Ready(())
} else {
cx.waker().wake();
lw.wake();
self.0 = true;
Poll::Pending
}
@ -150,13 +141,10 @@ where
let mut fut = Box::pinned(f(9));
let counter = Arc::new(Counter { wakes: AtomicUsize::new(0) });
let waker = local_waker_from_nonlocal(counter.clone());
let spawner = &mut NoopSpawner;
let cx = &mut Context::new(&waker, spawner);
assert_eq!(0, counter.wakes.load(atomic::Ordering::SeqCst));
assert_eq!(Poll::Pending, fut.as_mut().poll(cx));
assert_eq!(Poll::Pending, fut.as_mut().poll(&waker));
assert_eq!(1, counter.wakes.load(atomic::Ordering::SeqCst));
assert_eq!(Poll::Ready(9), fut.as_mut().poll(cx));
assert_eq!(Poll::Ready(9), fut.as_mut().poll(&waker));
}
fn main() {

View file

@ -18,11 +18,8 @@ use std::sync::{
Arc,
atomic::{self, AtomicUsize},
};
use std::future::FutureObj;
use std::task::{
Context, Poll,
Wake, Waker, LocalWaker,
Spawn, SpawnObjError,
Poll, Wake, Waker, LocalWaker,
local_waker, local_waker_from_nonlocal,
};
@ -41,24 +38,17 @@ impl Wake for Counter {
}
}
struct NoopSpawner;
impl Spawn for NoopSpawner {
fn spawn_obj(&mut self, _: FutureObj<'static, ()>) -> Result<(), SpawnObjError> {
Ok(())
}
}
struct MyFuture;
impl Future for MyFuture {
type Output = ();
fn poll(self: Pin<&mut Self>, cx: &mut Context) -> Poll<Self::Output> {
// Ensure all the methods work appropriately
cx.waker().wake();
cx.waker().wake();
cx.local_waker().wake();
cx.spawner().spawn_obj(Box::pinned(MyFuture).into()).unwrap();
fn poll(self: Pin<&mut Self>, lw: &LocalWaker) -> Poll<Self::Output> {
// Wake once locally
lw.wake();
// Wake twice non-locally
let waker = lw.clone().into_waker();
waker.wake();
waker.wake();
Poll::Ready(())
}
}
@ -69,9 +59,7 @@ fn test_local_waker() {
nonlocal_wakes: AtomicUsize::new(0),
});
let waker = unsafe { local_waker(counter.clone()) };
let spawner = &mut NoopSpawner;
let cx = &mut Context::new(&waker, spawner);
assert_eq!(Poll::Ready(()), Pin::new(&mut MyFuture).poll(cx));
assert_eq!(Poll::Ready(()), Pin::new(&mut MyFuture).poll(&waker));
assert_eq!(1, counter.local_wakes.load(atomic::Ordering::SeqCst));
assert_eq!(2, counter.nonlocal_wakes.load(atomic::Ordering::SeqCst));
}
@ -82,9 +70,7 @@ fn test_local_as_nonlocal_waker() {
nonlocal_wakes: AtomicUsize::new(0),
});
let waker: LocalWaker = local_waker_from_nonlocal(counter.clone());
let spawner = &mut NoopSpawner;
let cx = &mut Context::new(&waker, spawner);
assert_eq!(Poll::Ready(()), Pin::new(&mut MyFuture).poll(cx));
assert_eq!(Poll::Ready(()), Pin::new(&mut MyFuture).poll(&waker));
assert_eq!(0, counter.local_wakes.load(atomic::Ordering::SeqCst));
assert_eq!(3, counter.nonlocal_wakes.load(atomic::Ordering::SeqCst));
}