15
15
use marker:: Unpin ;
16
16
use ops;
17
17
use pin:: Pin ;
18
- use task:: { self , Poll } ;
18
+ use task:: { Poll , LocalWaker } ;
19
19
20
20
/// A future represents an asychronous computation.
21
21
///
@@ -50,28 +50,28 @@ pub trait Future {
50
50
///
51
51
/// Once a future has finished, clients should not `poll` it again.
52
52
///
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.
61
61
///
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 .
65
65
///
66
66
/// # Runtime characteristics
67
67
///
68
68
/// Futures alone are *inert*; they must be *actively* `poll`ed to make
69
69
/// progress, meaning that each time the current task is woken up, it should
70
70
/// actively re-`poll` pending futures that it still has an interest in.
71
71
///
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
75
75
/// `poll(2)` or `select(2)` syscalls on Unix it's worth noting that futures
76
76
/// typically do *not* suffer the same problems of "all wakeups must poll
77
77
/// all events"; they are more like `epoll(4)`.
@@ -83,6 +83,16 @@ pub trait Future {
83
83
/// thread pool (or something similar) to ensure that `poll` can return
84
84
/// quickly.
85
85
///
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
+ ///
86
96
/// # Panics
87
97
///
88
98
/// Once a future has completed (returned `Ready` from `poll`),
@@ -92,15 +102,18 @@ pub trait Future {
92
102
///
93
103
/// [`Poll::Pending`]: ../task/enum.Poll.html#variant.Pending
94
104
/// [`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 > ;
97
110
}
98
111
99
112
impl < ' a , F : ?Sized + Future + Unpin > Future for & ' a mut F {
100
113
type Output = F :: Output ;
101
114
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 )
104
117
}
105
118
}
106
119
@@ -111,7 +124,7 @@ where
111
124
{
112
125
type Output = <<P as ops:: Deref >:: Target as Future >:: Output ;
113
126
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 )
116
129
}
117
130
}
0 commit comments