1515use marker:: Unpin ;
1616use ops;
1717use 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
99112impl < ' 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}
0 commit comments