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!("Elapsed: {}.{:03} sec", dur.as_secs(), dur.subsec_millis());
37     }
38 
39     let start = Instant::now();
40     let update = tick(Duration::from_secs(1));
41     let ctrl_c = sigint_notifier().unwrap();
42 
43     loop {
44         select! {
45             recv(update) -> _ => {
46                 show(start.elapsed());
47             }
48             recv(ctrl_c) -> _ => {
49                 println!();
50                 println!("Goodbye!");
51                 show(start.elapsed());
52                 break;
53             }
54         }
55     }
56 }
57