1 //! Prints the elapsed time every 1 second and quits on Ctrl+C.
2 
3 #[cfg(windows)] // signal_hook::iterator does not work on windows
main()4 fn main() {
5     println!("This example does not work on Windows");
6 }
7 
8 #[cfg(not(windows))]
main()9 fn main() {
10     use std::io;
11     use std::thread;
12     use std::time::{Duration, Instant};
13 
14     use crossbeam_channel::{bounded, select, tick, Receiver};
15     use signal_hook::consts::SIGINT;
16     use signal_hook::iterator::Signals;
17 
18     // Creates a channel that gets a message every time `SIGINT` is signalled.
19     fn sigint_notifier() -> io::Result<Receiver<()>> {
20         let (s, r) = bounded(100);
21         let mut signals = Signals::new(&[SIGINT])?;
22 
23         thread::spawn(move || {
24             for _ in signals.forever() {
25                 if s.send(()).is_err() {
26                     break;
27                 }
28             }
29         });
30 
31         Ok(r)
32     }
33 
34     // Prints the elapsed time.
35     fn show(dur: Duration) {
36         println!(
37             "Elapsed: {}.{:03} sec",
38             dur.as_secs(),
39             dur.subsec_nanos() / 1_000_000
40         );
41     }
42 
43     let start = Instant::now();
44     let update = tick(Duration::from_secs(1));
45     let ctrl_c = sigint_notifier().unwrap();
46 
47     loop {
48         select! {
49             recv(update) -> _ => {
50                 show(start.elapsed());
51             }
52             recv(ctrl_c) -> _ => {
53                 println!();
54                 println!("Goodbye!");
55                 show(start.elapsed());
56                 break;
57             }
58         }
59     }
60 }
61