@@ -2,37 +2,58 @@ use std::future::Future;
2
2
use std:: pin:: Pin ;
3
3
use std:: task:: { Context , Poll } ;
4
4
5
- cfg_rt ! {
6
- /// Yields execution back to the Tokio runtime.
7
- ///
8
- /// A task yields by awaiting on `yield_now()`, and may resume when that
9
- /// future completes (with no output.) The current task will be re-added as
10
- /// a pending task at the _back_ of the pending queue. Any other pending
11
- /// tasks will be scheduled. No other waking is required for the task to
12
- /// continue.
13
- ///
14
- /// See also the usage example in the [task module](index.html#yield_now).
15
- #[ must_use = "yield_now does nothing unless polled/`await`-ed" ]
16
- pub async fn yield_now( ) {
17
- /// Yield implementation
18
- struct YieldNow {
19
- yielded: bool ,
20
- }
21
-
22
- impl Future for YieldNow {
23
- type Output = ( ) ;
5
+ /// Yields execution back to the Tokio runtime.
6
+ ///
7
+ /// A task yields by awaiting on `yield_now()`, and may resume when that future
8
+ /// completes (with no output.) The current task will be re-added as a pending
9
+ /// task at the _back_ of the pending queue. Any other pending tasks will be
10
+ /// scheduled. No other waking is required for the task to continue.
11
+ ///
12
+ /// See also the usage example in the [task module](index.html#yield_now).
13
+ ///
14
+ /// ## Non-guarantees
15
+ ///
16
+ /// This function may not yield all the way up to the executor if there are any
17
+ /// special combinators above it in the call stack. For example, if a
18
+ /// [`tokio::select!`] has another branch complete during the same poll as the
19
+ /// `yield_now()`, then the yield is not propagated all the way up to the
20
+ /// runtime.
21
+ ///
22
+ /// It is generally not guaranteed that the runtime behaves like you expect it
23
+ /// to when deciding which task to schedule next after a call to `yield_now()`.
24
+ /// In particular, the runtime may choose to poll the task that just ran
25
+ /// `yield_now()` again immediately without polling any other tasks first. For
26
+ /// example, the runtime will not drive the IO driver between every poll of a
27
+ /// task, and this could result in the runtime polling the current task again
28
+ /// immediately even if there is another task that could make progress if that
29
+ /// other task is waiting for a notification from the IO driver.
30
+ ///
31
+ /// In general, changes to the order in which the runtime polls tasks is not
32
+ /// considered a breaking change, and your program should be correct no matter
33
+ /// which order the runtime polls your tasks in.
34
+ ///
35
+ /// [`tokio::select!`]: macro@crate::select
36
+ #[ must_use = "yield_now does nothing unless polled/`await`-ed" ]
37
+ #[ cfg_attr( docsrs, doc( cfg( feature = "rt" ) ) ) ]
38
+ pub async fn yield_now ( ) {
39
+ /// Yield implementation
40
+ struct YieldNow {
41
+ yielded : bool ,
42
+ }
24
43
25
- fn poll( mut self : Pin <& mut Self >, cx: & mut Context <' _>) -> Poll <( ) > {
26
- if self . yielded {
27
- return Poll :: Ready ( ( ) ) ;
28
- }
44
+ impl Future for YieldNow {
45
+ type Output = ( ) ;
29
46
30
- self . yielded = true ;
31
- cx . waker ( ) . wake_by_ref ( ) ;
32
- Poll :: Pending
47
+ fn poll ( mut self : Pin < & mut Self > , cx : & mut Context < ' _ > ) -> Poll < ( ) > {
48
+ if self . yielded {
49
+ return Poll :: Ready ( ( ) ) ;
33
50
}
34
- }
35
51
36
- YieldNow { yielded: false } . await
52
+ self . yielded = true ;
53
+ cx. waker ( ) . wake_by_ref ( ) ;
54
+ Poll :: Pending
55
+ }
37
56
}
57
+
58
+ YieldNow { yielded : false } . await
38
59
}
0 commit comments