Skip to content

Instantly share code, notes, and snippets.

@srishanbhattarai
Last active March 8, 2020 00:10
Show Gist options
  • Save srishanbhattarai/0b61c8bafb35563b07d96b1055728211 to your computer and use it in GitHub Desktop.
Save srishanbhattarai/0b61c8bafb35563b07d96b1055728211 to your computer and use it in GitHub Desktop.
Futures example with a simple counter
use std::sync::Arc;
use std::pin::Pin;
use std::sync::atomic::{AtomicBool, AtomicU32, Ordering};
use std::task::{Context, Poll};
use std::thread;
use std::future::Future;
use futures::future::join;
struct Counter {
id: u8,
done: Arc<AtomicBool>,
value: Arc<AtomicU32>,
}
impl Counter {
fn new(id: u8) -> Self {
Counter {
id,
value: Arc::new(AtomicU32::new(0)),
done: Arc::new(AtomicBool::new(false))
}
}
}
impl Future for Counter {
type Output = u32;
fn poll(self: Pin<&mut Self>, cx: &mut Context) -> Poll<Self::Output> {
let curr = self.value.fetch_add(1, Ordering::SeqCst);
println!("[{}] {}", self.id, curr);
if self.done.load(Ordering::SeqCst) {
println!("[{}] Done!", self.id);
return Poll::Ready(self.value.load(Ordering::SeqCst));
}
let waker = cx.waker().clone();
let value = self.value.clone();
let done = self.done.clone();
// Simulation for some *real* async work like waiting for epoll to give you a value
thread::spawn(move || {
thread::sleep_ms(10);
if value.load(Ordering::SeqCst) >= 100 {
done.store(true, Ordering::SeqCst);
}
waker.wake();
});
Poll::Pending
}
}
fn main() {
let mut rt = tokio::runtime::Runtime::new().expect("Could not create tokio runtime");
rt.block_on(async {
let c = Counter::new(1);
let c1 = Counter::new(2);
(join(c, c1)).await;
});
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment