1use std::io;
2use std::sync::atomic::{AtomicBool, Ordering};
3use std::sync::Arc;
4use std::thread;
5use std::time;
6
7use super::clock::*;
8use super::instant::*;
9
10#[derive(Debug)]
12pub struct Updater {
13 period: time::Duration,
14 running: Arc<AtomicBool>,
15 th: Option<thread::JoinHandle<()>>,
16}
17
18impl Updater {
19 pub fn start(mut self) -> Result<Self, io::Error> {
21 let period = self.period;
22 let running = self.running.clone();
23 running.store(true, Ordering::Relaxed);
24 let th: thread::JoinHandle<()> = thread::Builder::new()
25 .name("coarsetime".to_string())
26 .spawn(move || {
27 while running.load(Ordering::Relaxed) {
28 thread::sleep(period);
29 Instant::update();
30 Clock::update();
31 }
32 })?;
33 self.th = Some(th);
34 Instant::update();
35 Clock::update();
36 Ok(self)
37 }
38
39 pub fn stop(mut self) -> Result<(), io::Error> {
41 self.running.store(false, Ordering::Relaxed);
42 self.th
43 .take()
44 .expect("updater is not running")
45 .join()
46 .map_err(|_| {
47 io::Error::new(io::ErrorKind::Other, "failed to properly stop the updater")
48 })
49 }
50
51 pub fn new(period_millis: u64) -> Updater {
54 Updater {
55 period: time::Duration::from_millis(period_millis),
56 running: Arc::new(AtomicBool::new(false)),
57 th: None,
58 }
59 }
60}