Skip to content

Commit e66a083

Browse files
committed
init FutureExt
Signed-off-by: Yoshua Wuyts <yoshuawuyts@gmail.com>
1 parent 30b5ca5 commit e66a083

File tree

10 files changed

+114
-11
lines changed

10 files changed

+114
-11
lines changed

src/fs/dir_builder.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
1+
use std::future::Future;
12
use std::path::Path;
23

34
use cfg_if::cfg_if;
45

5-
use crate::future::Future;
66
use crate::io;
77
use crate::task::blocking;
88

src/fs/open_options.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
1+
use std::future::Future;
12
use std::path::Path;
23

34
use cfg_if::cfg_if;
45

56
use crate::fs::File;
6-
use crate::future::Future;
77
use crate::io;
88
use crate::task::blocking;
99

src/future/future.rs

Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
use crate::utils::extension_trait;
2+
3+
cfg_if::cfg_if! {
4+
if #[cfg(feature = "docs")] {
5+
use crate::task::{Context, Poll};
6+
use std::pin::Pin;
7+
}
8+
}
9+
10+
extension_trait! {
11+
#[doc = r#"
12+
A future represents an asynchronous computation.
13+
14+
A future is a value that may not have finished computing yet. This kind of
15+
"asynchronous value" makes it possible for a thread to continue doing useful
16+
work while it waits for the value to become available.
17+
18+
# The `poll` method
19+
20+
The core method of future, `poll`, *attempts* to resolve the future into a
21+
final value. This method does not block if the value is not ready. Instead,
22+
the current task is scheduled to be woken up when it's possible to make
23+
further progress by `poll`ing again. The `context` passed to the `poll`
24+
method can provide a [`Waker`], which is a handle for waking up the current
25+
task.
26+
27+
When using a future, you generally won't call `poll` directly, but instead
28+
`.await` the value.
29+
30+
[`Waker`]: ../task/struct.Waker.html
31+
"#]
32+
pub trait Future [FutureExt: std::future::Future] {
33+
#[doc = r#"
34+
The type of value produced on completion.
35+
"#]
36+
type Output;
37+
38+
#[doc = r#"
39+
Attempt to resolve the future to a final value, registering
40+
the current task for wakeup if the value is not yet available.
41+
42+
# Return value
43+
44+
This function returns:
45+
46+
- [`Poll::Pending`] if the future is not ready yet
47+
- [`Poll::Ready(val)`] with the result `val` of this future if it
48+
finished successfully.
49+
50+
Once a future has finished, clients should not `poll` it again.
51+
52+
When a future is not ready yet, `poll` returns `Poll::Pending` and
53+
stores a clone of the [`Waker`] copied from the current [`Context`].
54+
This [`Waker`] is then woken once the future can make progress.
55+
For example, a future waiting for a socket to become
56+
readable would call `.clone()` on the [`Waker`] and store it.
57+
When a signal arrives elsewhere indicating that the socket is readable,
58+
[`Waker::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+
62+
Note that on multiple calls to `poll`, only the [`Waker`] from the
63+
[`Context`] passed to the most recent call should be scheduled to
64+
receive a wakeup.
65+
66+
# Runtime characteristics
67+
68+
Futures alone are *inert*; they must be *actively* `poll`ed to make
69+
progress, meaning that each time the current task is woken up, it should
70+
actively re-`poll` pending futures that it still has an interest in.
71+
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+
`poll(2)` or `select(2)` syscalls on Unix it's worth noting that futures
76+
typically do *not* suffer the same problems of "all wakeups must poll
77+
all events"; they are more like `epoll(4)`.
78+
79+
An implementation of `poll` should strive to return quickly, and should
80+
not block. Returning quickly prevents unnecessarily clogging up
81+
threads or event loops. If it is known ahead of time that a call to
82+
`poll` may end up taking awhile, the work should be offloaded to a
83+
thread pool (or something similar) to ensure that `poll` can return
84+
quickly.
85+
86+
# Panics
87+
88+
Once a future has completed (returned `Ready` from `poll`), calling its
89+
`poll` method again may panic, block forever, or cause other kinds of
90+
problems; the `Future` trait places no requirements on the effects of
91+
such a call. However, as the `poll` method is not marked `unsafe`,
92+
Rust's usual rules apply: calls must never cause undefined behavior
93+
(memory corruption, incorrect use of `unsafe` functions, or the like),
94+
regardless of the future's state.
95+
96+
[`Poll::Pending`]: ../task/enum.Poll.html#variant.Pending
97+
[`Poll::Ready(val)`]: ../task/enum.Poll.html#variant.Ready
98+
[`Context`]: ../task/struct.Context.html
99+
[`Waker`]: ../task/struct.Waker.html
100+
[`Waker::wake`]: ../task/struct.Waker.html#method.wake
101+
"#]
102+
fn poll(self: Pin<&mut Self>, cx: &mut Context) -> Poll<Self::Output>;
103+
}
104+
}

src/future/mod.rs

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -41,19 +41,18 @@
4141
//! | `future::select` | `Result<T, E>` | Return on first value
4242
//! | `future::try_select` | `Result<T, E>` | Return on first `Ok`, reject on last Err
4343
44-
#[doc(inline)]
45-
pub use std::future::Future;
46-
4744
#[doc(inline)]
4845
#[cfg_attr(feature = "docs", doc(cfg(unstable)))]
4946
pub use async_macros::{join, select, try_join, try_select};
5047

5148
use cfg_if::cfg_if;
5249

50+
pub use future::Future;
5351
pub use pending::pending;
5452
pub use poll_fn::poll_fn;
5553
pub use ready::ready;
5654

55+
pub(crate) mod future;
5756
mod pending;
5857
mod poll_fn;
5958
mod ready;

src/stream/stream/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,7 @@ cfg_if! {
8989
if #[cfg(any(feature = "unstable", feature = "docs"))] {
9090
use std::pin::Pin;
9191

92-
use crate::future::Future;
92+
use std::future::Future;
9393
use crate::stream::FromStream;
9494
}
9595
}

src/task/blocking.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
11
//! A thread pool for running blocking functions asynchronously.
22
3+
use std::future::Future;
34
use std::sync::atomic::{AtomicU64, Ordering};
45
use std::thread;
56
use std::time::Duration;
67

78
use crossbeam_channel::{bounded, Receiver, Sender};
89
use lazy_static::lazy_static;
910

10-
use crate::future::Future;
1111
use crate::task::task::{JoinHandle, Tag};
1212
use crate::utils::abort_on_panic;
1313

src/task/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,7 @@ pub(crate) mod blocking;
8181
#[inline]
8282
pub fn blocking<F, R>(future: F) -> task::JoinHandle<R>
8383
where
84-
F: crate::future::Future<Output = R> + Send + 'static,
84+
F: std::future::Future<Output = R> + Send + 'static,
8585
R: Send + 'static,
8686
{
8787
blocking::spawn(future)

src/task/pool.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
use std::future::Future;
12
use std::iter;
23
use std::thread;
34

@@ -10,7 +11,6 @@ use super::task;
1011
use super::task_local;
1112
use super::worker;
1213
use super::{Builder, JoinHandle};
13-
use crate::future::Future;
1414
use crate::utils::abort_on_panic;
1515

1616
/// Spawns a task.

src/task/task.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
use std::fmt;
2+
use std::future::Future;
23
use std::i64;
34
use std::mem;
45
use std::num::NonZeroU64;
@@ -7,7 +8,6 @@ use std::sync::atomic::{AtomicU64, AtomicUsize, Ordering};
78
use std::sync::Arc;
89

910
use super::task_local;
10-
use crate::future::Future;
1111
use crate::task::{Context, Poll};
1212

1313
/// A handle to a task.

src/task/task_local.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,8 @@ use std::sync::Mutex;
77
use lazy_static::lazy_static;
88

99
use super::worker;
10-
use crate::future::Future;
1110
use crate::utils::abort_on_panic;
11+
use std::future::Future;
1212

1313
/// Declares task-local values.
1414
///

0 commit comments

Comments
 (0)