Skip to content

Commit 2287a7a

Browse files
committed
Auto merge of #54339 - cramertj:no-cx, r=aturon
Remove spawning from task::Context r? @aturon cc rustasync/team#56
2 parents 317ae05 + 1b00f0b commit 2287a7a

File tree

13 files changed

+93
-568
lines changed

13 files changed

+93
-568
lines changed

src/liballoc/boxed.rs

+4-67
Original file line numberDiff line numberDiff line change
@@ -60,15 +60,15 @@ use core::borrow;
6060
use core::cmp::Ordering;
6161
use core::convert::From;
6262
use core::fmt;
63-
use core::future::{Future, FutureObj, LocalFutureObj, UnsafeFutureObj};
63+
use core::future::Future;
6464
use core::hash::{Hash, Hasher};
6565
use core::iter::FusedIterator;
6666
use core::marker::{Unpin, Unsize};
6767
use core::mem;
6868
use core::pin::Pin;
6969
use core::ops::{CoerceUnsized, Deref, DerefMut, Generator, GeneratorState};
7070
use core::ptr::{self, NonNull, Unique};
71-
use core::task::{Context, Poll, Spawn, SpawnErrorKind, SpawnObjError};
71+
use core::task::{LocalWaker, Poll};
7272

7373
use raw_vec::RawVec;
7474
use str::from_boxed_utf8_unchecked;
@@ -804,70 +804,7 @@ impl<T> Generator for Box<T>
804804
impl<F: ?Sized + Future + Unpin> Future for Box<F> {
805805
type Output = F::Output;
806806

807-
fn poll(mut self: Pin<&mut Self>, cx: &mut Context) -> Poll<Self::Output> {
808-
F::poll(Pin::new(&mut *self), cx)
809-
}
810-
}
811-
812-
#[unstable(feature = "futures_api", issue = "50547")]
813-
unsafe impl<'a, T, F> UnsafeFutureObj<'a, T> for Box<F>
814-
where F: Future<Output = T> + 'a
815-
{
816-
fn into_raw(self) -> *mut () {
817-
Box::into_raw(self) as *mut ()
818-
}
819-
820-
unsafe fn poll(ptr: *mut (), cx: &mut Context) -> Poll<T> {
821-
let ptr = ptr as *mut F;
822-
let pin: Pin<&mut F> = Pin::new_unchecked(&mut *ptr);
823-
F::poll(pin, cx)
824-
}
825-
826-
unsafe fn drop(ptr: *mut ()) {
827-
drop(Box::from_raw(ptr as *mut F))
828-
}
829-
}
830-
831-
#[unstable(feature = "futures_api", issue = "50547")]
832-
impl<Sp> Spawn for Box<Sp>
833-
where Sp: Spawn + ?Sized
834-
{
835-
fn spawn_obj(
836-
&mut self,
837-
future: FutureObj<'static, ()>,
838-
) -> Result<(), SpawnObjError> {
839-
(**self).spawn_obj(future)
840-
}
841-
842-
fn status(&self) -> Result<(), SpawnErrorKind> {
843-
(**self).status()
844-
}
845-
}
846-
847-
#[unstable(feature = "futures_api", issue = "50547")]
848-
impl<'a, F: Future<Output = ()> + Send + 'a> From<Box<F>> for FutureObj<'a, ()> {
849-
fn from(boxed: Box<F>) -> Self {
850-
FutureObj::new(boxed)
851-
}
852-
}
853-
854-
#[unstable(feature = "futures_api", issue = "50547")]
855-
impl<'a, F: Future<Output = ()> + 'a> From<Box<F>> for LocalFutureObj<'a, ()> {
856-
fn from(boxed: Box<F>) -> Self {
857-
LocalFutureObj::new(boxed)
858-
}
859-
}
860-
861-
#[unstable(feature = "futures_api", issue = "50547")]
862-
impl<'a, F: Future<Output = ()> + Send + 'a> From<Pin<Box<F>>> for FutureObj<'a, ()> {
863-
fn from(boxed: Pin<Box<F>>) -> Self {
864-
FutureObj::new(boxed)
865-
}
866-
}
867-
868-
#[unstable(feature = "futures_api", issue = "50547")]
869-
impl<'a, F: Future<Output = ()> + 'a> From<Pin<Box<F>>> for LocalFutureObj<'a, ()> {
870-
fn from(boxed: Pin<Box<F>>) -> Self {
871-
LocalFutureObj::new(boxed)
807+
fn poll(mut self: Pin<&mut Self>, lw: &LocalWaker) -> Poll<Self::Output> {
808+
F::poll(Pin::new(&mut *self), lw)
872809
}
873810
}

src/libcore/future/future.rs

+34-21
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
use marker::Unpin;
1616
use ops;
1717
use pin::Pin;
18-
use task::{self, Poll};
18+
use task::{Poll, LocalWaker};
1919

2020
/// A future represents an asychronous computation.
2121
///
@@ -50,28 +50,28 @@ pub trait Future {
5050
///
5151
/// Once a future has finished, clients should not `poll` it again.
5252
///
53-
/// When a future is not ready yet, `poll` returns
54-
/// `Poll::Pending`. The future will *also* register the
55-
/// interest of the current task in the value being produced. For example,
56-
/// if the future represents the availability of data on a socket, then the
57-
/// task is recorded so that when data arrives, it is woken up (via
58-
/// [`cx.waker()`]). Once a task has been woken up,
59-
/// it should attempt to `poll` the future again, which may or may not
60-
/// produce a final value.
53+
/// When a future is not ready yet, `poll` returns `Poll::Pending` and
54+
/// stores a clone of the [`LocalWaker`] to be woken once the future can
55+
/// make progress. For example, a future waiting for a socket to become
56+
/// readable would call `.clone()` on the [`LocalWaker`] and store it.
57+
/// When a signal arrives elsewhere indicating that the socket is readable,
58+
/// `[LocalWaker::wake]` is called and the socket future's task is awoken.
59+
/// Once a task has been woken up, it should attempt to `poll` the future
60+
/// again, which may or may not produce a final value.
6161
///
62-
/// Note that if `Pending` is returned it only means that the *current* task
63-
/// (represented by the argument `cx`) will receive a notification. Tasks
64-
/// from previous calls to `poll` will *not* receive notifications.
62+
/// Note that on multiple calls to `poll`, only the most recent
63+
/// [`LocalWaker`] passed to `poll` should be scheduled to receive a
64+
/// wakeup.
6565
///
6666
/// # Runtime characteristics
6767
///
6868
/// Futures alone are *inert*; they must be *actively* `poll`ed to make
6969
/// progress, meaning that each time the current task is woken up, it should
7070
/// actively re-`poll` pending futures that it still has an interest in.
7171
///
72-
/// The `poll` function is not called repeatedly in a tight loop for
73-
/// futures, but only whenever the future itself is ready, as signaled via
74-
/// the `Waker` inside `task::Context`. If you're familiar with the
72+
/// The `poll` function is not called repeatedly in a tight loop-- instead,
73+
/// it should only be called when the future indicates that it is ready to
74+
/// make progress (by calling `wake()`). If you're familiar with the
7575
/// `poll(2)` or `select(2)` syscalls on Unix it's worth noting that futures
7676
/// typically do *not* suffer the same problems of "all wakeups must poll
7777
/// all events"; they are more like `epoll(4)`.
@@ -83,6 +83,16 @@ pub trait Future {
8383
/// thread pool (or something similar) to ensure that `poll` can return
8484
/// quickly.
8585
///
86+
/// # [`LocalWaker`], [`Waker`] and thread-safety
87+
///
88+
/// The `poll` function takes a [`LocalWaker`], an object which knows how to
89+
/// awaken the current task. [`LocalWaker`] is not `Send` nor `Sync`, so in
90+
/// order to make thread-safe futures the [`LocalWaker::into_waker`] method
91+
/// should be used to convert the [`LocalWaker`] into a thread-safe version.
92+
/// [`LocalWaker::wake`] implementations have the ability to be more
93+
/// efficient, however, so when thread safety is not necessary,
94+
/// [`LocalWaker`] should be preferred.
95+
///
8696
/// # Panics
8797
///
8898
/// Once a future has completed (returned `Ready` from `poll`),
@@ -92,15 +102,18 @@ pub trait Future {
92102
///
93103
/// [`Poll::Pending`]: ../task/enum.Poll.html#variant.Pending
94104
/// [`Poll::Ready(val)`]: ../task/enum.Poll.html#variant.Ready
95-
/// [`cx.waker()`]: ../task/struct.Context.html#method.waker
96-
fn poll(self: Pin<&mut Self>, cx: &mut task::Context) -> Poll<Self::Output>;
105+
/// [`LocalWaker`]: ../task/struct.LocalWaker.html
106+
/// [`LocalWaker::into_waker`]: ../task/struct.LocalWaker.html#method.into_waker
107+
/// [`LocalWaker::wake`]: ../task/struct.LocalWaker.html#method.wake
108+
/// [`Waker`]: ../task/struct.Waker.html
109+
fn poll(self: Pin<&mut Self>, lw: &LocalWaker) -> Poll<Self::Output>;
97110
}
98111

99112
impl<'a, F: ?Sized + Future + Unpin> Future for &'a mut F {
100113
type Output = F::Output;
101114

102-
fn poll(mut self: Pin<&mut Self>, cx: &mut task::Context) -> Poll<Self::Output> {
103-
F::poll(Pin::new(&mut **self), cx)
115+
fn poll(mut self: Pin<&mut Self>, lw: &LocalWaker) -> Poll<Self::Output> {
116+
F::poll(Pin::new(&mut **self), lw)
104117
}
105118
}
106119

@@ -111,7 +124,7 @@ where
111124
{
112125
type Output = <<P as ops::Deref>::Target as Future>::Output;
113126

114-
fn poll(self: Pin<&mut Self>, cx: &mut task::Context) -> Poll<Self::Output> {
115-
Pin::get_mut(self).as_mut().poll(cx)
127+
fn poll(self: Pin<&mut Self>, lw: &LocalWaker) -> Poll<Self::Output> {
128+
Pin::get_mut(self).as_mut().poll(lw)
116129
}
117130
}

src/libcore/future/future_obj.rs

-203
This file was deleted.

0 commit comments

Comments
 (0)