Skip to content

Commit e4470d3

Browse files
committed
block-on: Add example from Chapter 20, Asynchronous Programming.
1 parent 083e5ec commit e4470d3

File tree

3 files changed

+61
-0
lines changed

3 files changed

+61
-0
lines changed

block-on/.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
/target/
2+
Cargo.lock

block-on/Cargo.toml

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
[package]
2+
name = "block-on"
3+
version = "0.1.0"
4+
authors = ["You <[email protected]>"]
5+
edition = "2018"
6+
7+
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
8+
9+
[dependencies]
10+
waker-fn = "1.1"
11+
futures-lite = "1.11"
12+
crossbeam = "0.8"
13+
14+
[dev-dependencies]
15+
async-std = "1.7"

block-on/src/lib.rs

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
use waker_fn::waker_fn; // Cargo.toml: waker-fn = "1.1"
2+
use futures_lite::pin; // Cargo.toml: futures-lite = "1.11"
3+
use crossbeam::sync::Parker; // Cargo.toml: crossbeam = "0.8"
4+
use std::future::Future;
5+
use std::task::{Context, Poll};
6+
7+
pub fn block_on<F: Future>(future: F) -> F::Output {
8+
let parker = Parker::new();
9+
let unparker = parker.unparker().clone();
10+
let waker = waker_fn(move || unparker.unpark());
11+
let mut context = Context::from_waker(&waker);
12+
13+
pin!(future);
14+
15+
loop {
16+
match future.as_mut().poll(&mut context) {
17+
Poll::Ready(value) => return value,
18+
Poll::Pending => parker.park(),
19+
}
20+
}
21+
}
22+
23+
#[test]
24+
fn test() {
25+
assert_eq!(block_on(std::future::ready(42)), 42);
26+
27+
use async_std::task::{spawn, sleep};
28+
use futures_lite::FutureExt;
29+
use std::time::Duration;
30+
31+
assert_eq!(
32+
block_on({
33+
let one_sec = async {
34+
sleep(Duration::from_secs(1)).await;
35+
43
36+
};
37+
let half_sec = async {
38+
sleep(Duration::from_millis(500)).await;
39+
44
40+
};
41+
spawn(one_sec.race(half_sec))
42+
}),
43+
44);
44+
}

0 commit comments

Comments
 (0)