1#![deny(missing_docs)]
2
3extern crate tokio_timer;
9extern crate futures;
10
11
12use tokio_timer::Delay;
13use futures::Future;
14use futures::Async;
15
16use std::sync::Arc;
17use std::sync::Mutex;
18
19use std::time::{Duration, Instant};
20
21struct Impl {
22 del : Option<Delay>,
24 dur : Duration,
26 ins : Instant,
28}
29
30type H = Arc<Mutex<Impl>>;
31pub struct Watchdog(H);
37
38impl Watchdog {
39 pub fn new(dur: Duration) -> Self {
41 let ins = Instant::now() + dur;
42 let del = Delay::new(ins);
43 let i = Impl { del:Some(del), dur, ins };
44 Watchdog(Arc::new(Mutex::new(i)))
45 }
46 pub fn duration(&self) -> Duration {
48 if let Ok(g) = self.0.lock() {
49 g.dur
50 } else {
51 Duration::from_secs(0)
52 }
53 }
54 pub fn set_duration(&mut self, dur: Duration) {
56 if let Ok(mut g) = self.0.lock() {
57 g.ins = g.ins - g.dur + dur;
58 g.dur = dur;
59 let i = g.ins;
60 if let Some(ref mut d) = g.del {
61 d.reset(i);
62 }
63 }
64 }
65 pub fn handle(&self) -> Pet {
67 self.into()
68 }
69}
70
71#[derive(Clone)]
73pub struct Pet(H);
74impl Pet {
75 pub fn pet(&self) {
79 if let Ok(mut g) = self.0.lock() {
80 let i = Instant::now() + g.dur;
81 g.ins = i;
82 if let Some(ref mut x) = g.del {
83 x.reset(i);
84 }
85 } else {
86 }
89 }
90
91 pub fn get_remaining_time(&self) -> Option<Duration> {
97 if let Ok(g) = self.0.lock() {
98 let now = Instant::now();
99 let i = g.ins;
100 if now > i {
101 None
102 } else {
103 Some(i - now)
104 }
105 } else {
106 Some(Duration::from_secs(0))
107 }
108 }
109}
110
111impl<'a> From<&'a Watchdog> for Pet {
112 fn from(w : &'a Watchdog) -> Pet {
113 Pet(w.0.clone())
114 }
115}
116
117pub struct Rearm(H);
121impl Rearm {
122 pub fn rearm(self) -> Watchdog {
124 Watchdog(self.0)
125 }
126
127 pub fn rearm_with_duration(self, dur: Duration) -> Watchdog {
129 let mut w = Watchdog(self.0);
130 w.set_duration(dur);
131 w
132 }
133}
134
135impl Future for Watchdog {
136 type Item = Rearm;
137 type Error = tokio_timer::Error;
139
140 fn poll(&mut self) -> futures::Poll<Rearm, tokio_timer::Error> {
141 if let Ok(mut g) = self.0.lock() {
142 if let Some(ref mut d) = g.del {
143 match d.poll() {
144 Ok(Async::Ready(())) => Ok(Async::Ready(
145 Rearm(self.0.clone())
146 )),
147 Ok(Async::NotReady) => Ok(Async::NotReady),
148 Err(x) => Err(x),
149 }
150 } else {
151 Ok(Async::Ready(Rearm(self.0.clone())))
152 }
153 } else {
154 Err(tokio_timer::Error::at_capacity())
156 }
157 }
158}
159
160#[cfg(test)]
161mod tests {
162 #[test]
163 fn it_works() {
164 }
165}