Skip to content

Commit dd404d7

Browse files
posborneoll3
authored andcommitted
Fix and cleanup tokio example using async/await
Signed-off-by: Paul Osborne <[email protected]>
1 parent 174b8c3 commit dd404d7

File tree

2 files changed

+31
-43
lines changed

2 files changed

+31
-43
lines changed

Cargo.toml

+7
Original file line numberDiff line numberDiff line change
@@ -22,3 +22,10 @@ futures = { version = "0.3", optional = true }
2222
nix = "0.22"
2323
mio = { version = "0.7", optional = true, features = ["os-ext"]}
2424
tokio = { version = "1", optional = true, features = ["net"] }
25+
26+
[dev-dependencies]
27+
tokio = { version = "1", features = ["rt-multi-thread", "macros"] }
28+
29+
[[example]]
30+
name = "tokio"
31+
required-features = ["async-tokio"]

examples/tokio.rs

+24-43
Original file line numberDiff line numberDiff line change
@@ -1,63 +1,44 @@
1-
#[cfg(feature = "async-tokio")]
2-
extern crate futures;
3-
#[cfg(feature = "async-tokio")]
4-
extern crate sysfs_gpio;
5-
#[cfg(feature = "async-tokio")]
6-
extern crate tokio;
1+
// Copyright (c) 2020. The sysfs-gpio Authors.
72

8-
#[cfg(feature = "async-tokio")]
3+
use futures::future::join_all;
4+
use futures::StreamExt;
95
use std::env;
10-
11-
#[cfg(feature = "async-tokio")]
12-
use futures::{lazy, Future, Stream};
13-
14-
#[cfg(feature = "async-tokio")]
156
use sysfs_gpio::{Direction, Edge, Pin};
167

17-
#[cfg(feature = "async-tokio")]
18-
fn stream(pin_nums: Vec<u64>) -> sysfs_gpio::Result<()> {
8+
async fn monitor_pin(pin: Pin) -> Result<(), sysfs_gpio::Error> {
9+
pin.export()?;
10+
pin.set_direction(Direction::In)?;
11+
pin.set_edge(Edge::BothEdges)?;
12+
let mut gpio_events = pin.get_value_stream()?;
13+
while let Some(evt) = gpio_events.next().await {
14+
let val = evt.unwrap();
15+
println!("Pin {} changed value to {}", pin.get_pin_num(), val);
16+
}
17+
Ok(())
18+
}
19+
20+
async fn stream(pin_nums: Vec<u64>) {
1921
// NOTE: this currently runs forever and as such if
2022
// the app is stopped (Ctrl-C), no cleanup will happen
2123
// and the GPIO will be left exported. Not much
2224
// can be done about this as Rust signal handling isn't
2325
// really present at the moment. Revisit later.
24-
let pins: Vec<_> = pin_nums.iter().map(|&p| (p, Pin::new(p))).collect();
25-
let task = lazy(move || {
26-
for &(i, ref pin) in pins.iter() {
27-
pin.export().unwrap();
28-
pin.set_direction(Direction::In).unwrap();
29-
pin.set_edge(Edge::BothEdges).unwrap();
30-
tokio::spawn(
31-
pin.get_value_stream()
32-
.unwrap()
33-
.for_each(move |val| {
34-
println!("Pin {} changed value to {}", i, val);
35-
Ok(())
36-
})
37-
.map_err(|_| ()),
38-
);
39-
}
40-
Ok(())
41-
});
42-
tokio::run(task);
43-
44-
Ok(())
26+
join_all(pin_nums.into_iter().map(|p| {
27+
let pin = Pin::new(p);
28+
tokio::task::spawn(monitor_pin(pin))
29+
}))
30+
.await;
4531
}
4632

47-
#[cfg(feature = "async-tokio")]
48-
fn main() {
33+
#[tokio::main]
34+
async fn main() {
4935
let pins: Vec<u64> = env::args()
5036
.skip(1)
5137
.map(|a| a.parse().expect("Pins must be specified as integers"))
5238
.collect();
5339
if pins.is_empty() {
5440
println!("Usage: ./tokio <pin> [pin ...]");
5541
} else {
56-
stream(pins).unwrap();
42+
stream(pins).await;
5743
}
5844
}
59-
60-
#[cfg(not(feature = "async-tokio"))]
61-
fn main() {
62-
println!("This example requires the `tokio` feature to be enabled.");
63-
}

0 commit comments

Comments
 (0)