Skip to content

Commit 35cb11e

Browse files
committed
Merge branch 'master' into add_stdin_lock
2 parents 59615a6 + 1175a37 commit 35cb11e

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

56 files changed

+1080
-83
lines changed

.github/workflows/ci.yml

Lines changed: 9 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,13 @@ on:
77
- staging
88
- trying
99

10+
env:
11+
RUSTFLAGS: -Dwarnings
12+
1013
jobs:
1114
build_and_test:
1215
name: Build and test
1316
runs-on: ${{ matrix.os }}
14-
env:
15-
RUSTFLAGS: -Dwarnings
1617
strategy:
1718
matrix:
1819
os: [ubuntu-latest, windows-latest, macOS-latest]
@@ -48,8 +49,6 @@ jobs:
4849
check_fmt_and_docs:
4950
name: Checking fmt and docs
5051
runs-on: ubuntu-latest
51-
env:
52-
RUSTFLAGS: -Dwarnings
5352
steps:
5453
- uses: actions/checkout@master
5554

@@ -81,20 +80,11 @@ jobs:
8180
clippy_check:
8281
name: Clippy check
8382
runs-on: ubuntu-latest
84-
# TODO: There is a lot of warnings
85-
# env:
86-
# RUSTFLAGS: -Dwarnings
8783
steps:
8884
- uses: actions/checkout@v1
89-
- id: component
90-
uses: actions-rs/components-nightly@v1
91-
with:
92-
component: clippy
93-
- uses: actions-rs/toolchain@v1
94-
with:
95-
toolchain: ${{ steps.component.outputs.toolchain }}
96-
override: true
97-
- run: rustup component add clippy
98-
- uses: actions-rs/clippy-check@v1
99-
with:
100-
token: ${{ secrets.GITHUB_TOKEN }}
85+
- name: Install rust
86+
run: rustup update beta && rustup default beta
87+
- name: Install clippy
88+
run: rustup component add clippy
89+
- name: clippy
90+
run: cargo clippy --all --features unstable

Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ authors = [
99
edition = "2018"
1010
license = "Apache-2.0/MIT"
1111
repository = "https://github.com/async-rs/async-std"
12-
homepage = "https://github.com/async-rs/async-std"
12+
homepage = "https://async.rs"
1313
documentation = "https://docs.rs/async-std"
1414
description = "Async version of the Rust standard library"
1515
keywords = ["async", "await", "future", "std", "task"]

docs/src/concepts/futures.md

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -24,11 +24,7 @@ To sum up: Rust gives us the ability to safely abstract over important propertie
2424

2525
## An easy view of computation
2626

27-
While computation is a subject to write a whole [book](https://computationbook.com/) about, a very simplified view suffices for us:
28-
29-
- computation is a sequence of composable operations
30-
- they can branch based on a decision
31-
- they either run to succession and yield a result, or they can yield an error
27+
While computation is a subject to write a whole [book](https://computationbook.com/) about, a very simplified view suffices for us: A sequence of composable operations which can branch based on a decision, run to succession and yield a result or yield an error
3228

3329
## Deferring computation
3430

@@ -136,11 +132,11 @@ When executing 2 or more of these functions at the same time, our runtime system
136132

137133
## Conclusion
138134

139-
Working from values, we searched for something that expresses *working towards a value available sometime later*. From there, we talked about the concept of polling.
135+
Working from values, we searched for something that expresses *working towards a value available later*. From there, we talked about the concept of polling.
140136

141137
A `Future` is any data type that does not represent a value, but the ability to *produce a value at some point in the future*. Implementations of this are very varied and detailed depending on use-case, but the interface is simple.
142138

143-
Next, we will introduce you to `tasks`, which we need to actually *run* Futures.
139+
Next, we will introduce you to `tasks`, which we will use to actually *run* Futures.
144140

145141
[^1]: Two parties reading while it is guaranteed that no one is writing is always safe.
146142

docs/src/concepts/tasks.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,7 @@ Tasks in `async_std` are one of the core abstractions. Much like Rust's `thread`
8080

8181
## Blocking
8282

83-
`Task`s are assumed to run _concurrently_, potentially by sharing a thread of execution. This means that operations blocking an _operating system thread_, such as `std::thread::sleep` or io function from Rust's `std` library will _stop execution of all tasks sharing this thread_. Other libraries (such as database drivers) have similar behaviour. Note that _blocking the current thread_ is not in and by itself bad behaviour, just something that does not mix well with the concurrent execution model of `async-std`. Essentially, never do this:
83+
`Task`s are assumed to run _concurrently_, potentially by sharing a thread of execution. This means that operations blocking an _operating system thread_, such as `std::thread::sleep` or io function from Rust's `std` library will _stop execution of all tasks sharing this thread_. Other libraries (such as database drivers) have similar behaviour. Note that _blocking the current thread_ is not in and of itself bad behaviour, just something that does not mix well with the concurrent execution model of `async-std`. Essentially, never do this:
8484

8585
```rust,edition2018
8686
# extern crate async_std;

docs/src/overview/async-std.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,4 +4,4 @@
44

55
`async-std` provides an interface to all important primitives: filesystem operations, network operations and concurrency basics like timers. It also exposes a `task` in a model similar to the `thread` module found in the Rust standard lib. But it does not only include I/O primitives, but also `async/await` compatible versions of primitives like `Mutex`.
66

7-
[organization]: https://github.com/async-rs/async-std
7+
[organization]: https://github.com/async-rs

docs/src/overview/stability-guarantees.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ In general, this crate will be conservative with respect to the minimum supporte
3131

3232
## Security fixes
3333

34-
Security fixes will be applied to _all_ minor branches of this library in all _supported_ major revisions. This policy might change in the future, in which case we give at least _3 month_ of ahead notice.
34+
Security fixes will be applied to _all_ minor branches of this library in all _supported_ major revisions. This policy might change in the future, in which case we give a notice at least _3 months_ ahead.
3535

3636
## Credits
3737

examples/a-chat/main.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,6 @@ fn main() -> Result<()> {
88
match (args.nth(1).as_ref().map(String::as_str), args.next()) {
99
(Some("client"), None) => client::main(),
1010
(Some("server"), None) => server::main(),
11-
_ => Err("Usage: a-chat [client|server]")?,
11+
_ => Err("Usage: a-chat [client|server]".into()),
1212
}
1313
}

examples/a-chat/server.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ async fn connection_loop(mut broker: Sender<Event>, stream: TcpStream) -> Result
4545
let mut lines = reader.lines();
4646

4747
let name = match lines.next().await {
48-
None => Err("peer disconnected immediately")?,
48+
None => return Err("peer disconnected immediately".into()),
4949
Some(line) => line?,
5050
};
5151
let (_shutdown_sender, shutdown_receiver) = mpsc::unbounded::<Void>();

src/fs/file.rs

Lines changed: 20 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,23 @@ pub struct File {
6666
}
6767

6868
impl File {
69+
/// Creates an async file handle.
70+
pub(crate) fn new(file: std::fs::File, is_flushed: bool) -> File {
71+
let file = Arc::new(file);
72+
73+
File {
74+
file: file.clone(),
75+
lock: Lock::new(State {
76+
file,
77+
mode: Mode::Idle,
78+
cache: Vec::new(),
79+
is_flushed,
80+
last_read_err: None,
81+
last_write_err: None,
82+
}),
83+
}
84+
}
85+
6986
/// Opens a file in read-only mode.
7087
///
7188
/// See the [`OpenOptions::open`] function for more options.
@@ -96,7 +113,7 @@ impl File {
96113
pub async fn open<P: AsRef<Path>>(path: P) -> io::Result<File> {
97114
let path = path.as_ref().to_owned();
98115
let file = blocking::spawn(move || std::fs::File::open(&path)).await?;
99-
Ok(file.into())
116+
Ok(File::new(file, true))
100117
}
101118

102119
/// Opens a file in write-only mode.
@@ -131,7 +148,7 @@ impl File {
131148
pub async fn create<P: AsRef<Path>>(path: P) -> io::Result<File> {
132149
let path = path.as_ref().to_owned();
133150
let file = blocking::spawn(move || std::fs::File::create(&path)).await?;
134-
Ok(file.into())
151+
Ok(File::new(file, true))
135152
}
136153

137154
/// Synchronizes OS-internal buffered contents and metadata to disk.
@@ -383,19 +400,7 @@ impl Seek for &File {
383400

384401
impl From<std::fs::File> for File {
385402
fn from(file: std::fs::File) -> File {
386-
let file = Arc::new(file);
387-
388-
File {
389-
file: file.clone(),
390-
lock: Lock::new(State {
391-
file,
392-
mode: Mode::Idle,
393-
cache: Vec::new(),
394-
is_flushed: false,
395-
last_read_err: None,
396-
last_write_err: None,
397-
}),
398-
}
403+
File::new(file, false)
399404
}
400405
}
401406

src/fs/open_options.rs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -284,7 +284,10 @@ impl OpenOptions {
284284
pub fn open<P: AsRef<Path>>(&self, path: P) -> impl Future<Output = io::Result<File>> {
285285
let path = path.as_ref().to_owned();
286286
let options = self.0.clone();
287-
async move { blocking::spawn(move || options.open(path).map(|f| f.into())).await }
287+
async move {
288+
let file = blocking::spawn(move || options.open(path)).await?;
289+
Ok(File::new(file, true))
290+
}
288291
}
289292
}
290293

src/future/future.rs

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,11 @@
1+
cfg_unstable! {
2+
mod delay;
3+
4+
use std::time::Duration;
5+
6+
use delay::DelayFuture;
7+
}
8+
19
extension_trait! {
210
use std::pin::Pin;
311
use std::ops::{Deref, DerefMut};
@@ -99,6 +107,28 @@ extension_trait! {
99107
}
100108

101109
pub trait FutureExt: std::future::Future {
110+
/// Returns a Future that delays execution for a specified time.
111+
///
112+
/// # Examples
113+
///
114+
/// ```
115+
/// # async_std::task::block_on(async {
116+
/// use async_std::prelude::*;
117+
/// use async_std::future;
118+
/// use std::time::Duration;
119+
///
120+
/// let a = future::ready(1).delay(Duration::from_millis(2000));
121+
/// dbg!(a.await);
122+
/// # })
123+
/// ```
124+
#[cfg_attr(feature = "docs", doc(cfg(unstable)))]
125+
#[cfg(any(feature = "unstable", feature = "docs"))]
126+
fn delay(self, dur: Duration) -> impl Future<Output = Self::Output> [DelayFuture<Self>]
127+
where
128+
Self: Future + Sized
129+
{
130+
DelayFuture::new(self, dur)
131+
}
102132
}
103133

104134
impl<F: Future + Unpin + ?Sized> Future for Box<F> {

src/future/future/delay.rs

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
use std::pin::Pin;
2+
use std::time::Duration;
3+
4+
use futures_timer::Delay;
5+
use pin_project_lite::pin_project;
6+
7+
use crate::future::Future;
8+
use crate::task::{Context, Poll};
9+
10+
pin_project! {
11+
#[doc(hidden)]
12+
#[derive(Debug)]
13+
pub struct DelayFuture<F> {
14+
#[pin]
15+
future: F,
16+
#[pin]
17+
delay: Delay,
18+
}
19+
}
20+
21+
impl<F> DelayFuture<F> {
22+
pub fn new(future: F, dur: Duration) -> DelayFuture<F> {
23+
let delay = Delay::new(dur);
24+
25+
DelayFuture { future, delay }
26+
}
27+
}
28+
29+
impl<F: Future> Future for DelayFuture<F> {
30+
type Output = F::Output;
31+
32+
fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
33+
let this = self.project();
34+
35+
match this.delay.poll(cx) {
36+
Poll::Pending => Poll::Pending,
37+
Poll::Ready(_) => match this.future.poll(cx) {
38+
Poll::Ready(v) => Poll::Ready(v),
39+
Poll::Pending => Poll::Pending,
40+
},
41+
}
42+
}
43+
}

src/io/empty.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,9 +28,10 @@ pub fn empty() -> Empty {
2828

2929
/// A reader that contains no data.
3030
///
31-
/// This reader is constructed by the [`sink`] function.
31+
/// This reader is created by the [`empty`] function. See its
32+
/// documentation for more.
3233
///
33-
/// [`sink`]: fn.sink.html
34+
/// [`empty`]: fn.empty.html
3435
pub struct Empty {
3536
_private: (),
3637
}

src/io/repeat.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,8 @@ pub fn repeat(byte: u8) -> Repeat {
2929

3030
/// A reader which yields one byte over and over and over and over and over and...
3131
///
32-
/// This reader is constructed by the [`repeat`] function.
32+
/// This reader is created by the [`repeat`] function. See its
33+
/// documentation for more.
3334
///
3435
/// [`repeat`]: fn.repeat.html
3536
pub struct Repeat {

src/io/sink.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,8 @@ pub fn sink() -> Sink {
2525

2626
/// A writer that consumes and drops all data.
2727
///
28-
/// This writer is constructed by the [`sink`] function.
28+
/// This writer is constructed by the [`sink`] function. See its documentation
29+
/// for more.
2930
///
3031
/// [`sink`]: fn.sink.html
3132
pub struct Sink {

src/io/stderr.rs

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,12 @@ use crate::task::{blocking, Context, JoinHandle, Poll};
1212
///
1313
/// [`std::io::stderr`]: https://doc.rust-lang.org/std/io/fn.stderr.html
1414
///
15+
/// ### Note: Windows Portability Consideration
16+
///
17+
/// When operating in a console, the Windows implementation of this stream does not support
18+
/// non-UTF-8 byte sequences. Attempting to write bytes that are not valid UTF-8 will return
19+
/// an error.
20+
///
1521
/// # Examples
1622
///
1723
/// ```no_run
@@ -35,12 +41,16 @@ pub fn stderr() -> Stderr {
3541

3642
/// A handle to the standard error of the current process.
3743
///
38-
/// Created by the [`stderr`] function.
44+
/// This writer is created by the [`stderr`] function. See its documentation for
45+
/// more.
46+
///
47+
/// ### Note: Windows Portability Consideration
3948
///
40-
/// This type is an async version of [`std::io::Stderr`].
49+
/// When operating in a console, the Windows implementation of this stream does not support
50+
/// non-UTF-8 byte sequences. Attempting to write bytes that are not valid UTF-8 will return
51+
/// an error.
4152
///
4253
/// [`stderr`]: fn.stderr.html
43-
/// [`std::io::Stderr`]: https://doc.rust-lang.org/std/io/struct.Stderr.html
4454
#[derive(Debug)]
4555
pub struct Stderr(Mutex<State>);
4656

src/io/stdin.rs

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,12 @@ use crate::task::{blocking, Context, JoinHandle, Poll};
1212
///
1313
/// [`std::io::stdin`]: https://doc.rust-lang.org/std/io/fn.stdin.html
1414
///
15+
/// ### Note: Windows Portability Consideration
16+
///
17+
/// When operating in a console, the Windows implementation of this stream does not support
18+
/// non-UTF-8 byte sequences. Attempting to write bytes that are not valid UTF-8 will return
19+
/// an error.
20+
///
1521
/// # Examples
1622
///
1723
/// ```no_run
@@ -36,12 +42,16 @@ pub fn stdin() -> Stdin {
3642

3743
/// A handle to the standard input of the current process.
3844
///
39-
/// Created by the [`stdin`] function.
45+
/// This reader is created by the [`stdin`] function. See its documentation for
46+
/// more.
47+
///
48+
/// ### Note: Windows Portability Consideration
4049
///
41-
/// This type is an async version of [`std::io::Stdin`].
50+
/// When operating in a console, the Windows implementation of this stream does not support
51+
/// non-UTF-8 byte sequences. Attempting to write bytes that are not valid UTF-8 will return
52+
/// an error.
4253
///
4354
/// [`stdin`]: fn.stdin.html
44-
/// [`std::io::Stdin`]: https://doc.rust-lang.org/std/io/struct.Stdin.html
4555
#[derive(Debug)]
4656
pub struct Stdin(Mutex<State>);
4757

0 commit comments

Comments
 (0)