extern crate libuv;
use libuv::prelude::*;
use libuv::{SignalHandle, WorkReq};
use libuv_sys2::SIGINT;
const FIB_UNTIL: usize = 25;
fn fib(i: usize) {
fn fib_(i: u64) -> u64 {
if i == 0 || i == 1 {
return 1;
}
fib_(i - 1) + fib_(i - 2)
}
if rand::random() {
std::thread::sleep(std::time::Duration::from_secs(1));
} else {
std::thread::sleep(std::time::Duration::from_secs(3));
}
let fib = fib_(i as _);
println!("{}th fibonacci is {}", i, fib);
}
fn after_fib(i: usize, status: libuv::Result<u32>) {
match status {
Ok(_) => println!("Done calculating {}th fibonacci", i),
Err(libuv::Error::ECANCELED) => eprintln!("Calculation of {} cancelled.", i),
Err(e) => eprintln!("Error {}", e),
}
}
fn signal_handler(mut sig: SignalHandle, reqs: &mut [WorkReq]) {
println!("Signal received");
for req in reqs.iter_mut() {
let _ = req.cancel();
}
if let Err(e) = sig.stop() {
eprintln!("Could not stop signal handler {}", e);
}
}
fn main() -> Result<(), Box<dyn std::error::Error>> {
let mut r#loop = Loop::default()?;
let mut reqs = (0..FIB_UNTIL)
.map(|i| r#loop.queue_work(move |_| fib(i), move |_, status| after_fib(i, status)))
.collect::<libuv::Result<Vec<WorkReq>>>()?;
let mut sig = r#loop.signal()?;
sig.start(
move |handle, _| signal_handler(handle, &mut reqs),
SIGINT as _,
)?;
r#loop.run(RunMode::Default)?;
Ok(())
}