1 // Copyright 2013 The Rust Project Developers. See the COPYRIGHT
2 // file at the top-level directory of this distribution and at
3 // http://rust-lang.org/COPYRIGHT.
5 // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6 // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8 // option. This file may not be copied, modified, or distributed
9 // except according to those terms.
14 use super::{Watcher, Loop, NativeHandle, TimerCallback, status_to_maybe_uv_error};
16 pub struct TimerWatcher(*uvll::uv_timer_t);
17 impl Watcher for TimerWatcher { }
20 pub fn new(loop_: &mut Loop) -> TimerWatcher {
22 let handle = uvll::malloc_handle(uvll::UV_TIMER);
23 assert!(handle.is_not_null());
24 assert!(0 == uvll::timer_init(loop_.native_handle(), handle));
25 let mut watcher: TimerWatcher = NativeHandle::from_native_handle(handle);
26 watcher.install_watcher_data();
31 pub fn start(&mut self, timeout: u64, repeat: u64, cb: TimerCallback) {
33 let data = self.get_watcher_data();
34 data.timer_cb = Some(cb);
38 uvll::timer_start(self.native_handle(), timer_cb, timeout, repeat);
41 extern fn timer_cb(handle: *uvll::uv_timer_t, status: c_int) {
42 let mut watcher: TimerWatcher = NativeHandle::from_native_handle(handle);
43 let data = watcher.get_watcher_data();
44 let cb = data.timer_cb.get_ref();
45 let status = status_to_maybe_uv_error(status);
46 (*cb)(watcher, status);
50 pub fn stop(&mut self) {
52 uvll::timer_stop(self.native_handle());
57 impl NativeHandle<*uvll::uv_timer_t> for TimerWatcher {
58 fn from_native_handle(handle: *uvll::uv_timer_t) -> TimerWatcher {
61 fn native_handle(&self) -> *uvll::uv_idle_t {
62 match self { &TimerWatcher(ptr) => ptr }
70 use std::unstable::run_in_bare_thread;
74 do run_in_bare_thread {
76 let count_ptr: *mut int = &mut count;
77 let mut loop_ = Loop::new();
78 let mut timer = TimerWatcher::new(&mut loop_);
79 do timer.start(10, 0) |timer, status| {
80 assert!(status.is_none());
81 unsafe { *count_ptr += 1 };
92 do run_in_bare_thread {
94 let count_ptr: *mut int = &mut count;
95 let mut loop_ = Loop::new();
96 let mut timer = TimerWatcher::new(&mut loop_);
97 do timer.start(10, 0) |timer, status| {
98 let mut timer = timer;
99 assert!(status.is_none());
100 unsafe { *count_ptr += 1 };
101 do timer.start(10, 0) |timer, status| {
102 assert!(status.is_none());
103 unsafe { *count_ptr += 1 };
115 do run_in_bare_thread {
117 let count_ptr: *mut int = &mut count;
118 let mut loop_ = Loop::new();
119 let mut timer = TimerWatcher::new(&mut loop_);
120 do timer.start(1, 2) |timer, status| {
121 assert!(status.is_none());
125 if *count_ptr == 10 {
127 // Stop the timer and do something else
128 let mut timer = timer;
130 // Freeze timer so it can be captured
133 let mut loop_ = timer.event_loop();
134 let mut timer2 = TimerWatcher::new(&mut loop_);
135 do timer2.start(10, 0) |timer2, _| {
141 // Restart the original timer
142 let mut timer = timer;
143 do timer.start(1, 0) |timer, _| {
153 assert!(count == 12);