(index<- )        ./libstd/rt/uv/timer.rs

   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.
   4  //
   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.
  10  
  11  use libc::{c_void, c_int};
  12  use option::Some;
  13  use rt::uv::uvll;
  14  use rt::uv::{Watcher, Loop, NativeHandle, TimerCallback, NullCallback};
  15  use rt::uv::status_to_maybe_uv_error;
  16  
  17  pub struct TimerWatcher(*uvll::uv_timer_t);
  18  impl Watcher for TimerWatcher { }
  19  
  20  impl TimerWatcher {
  21      pub fn new(loop_&mut Loop) -> TimerWatcher {
  22          unsafe {
  23              let handle = uvll::malloc_handle(uvll::UV_TIMER);
  24              assert!(handle.is_not_null());
  25              assert!(0 == uvll::timer_init(loop_.native_handle(), handle));
  26              let mut watcherTimerWatcher = NativeHandle::from_native_handle(handle);
  27              watcher.install_watcher_data();
  28              return watcher;
  29          }
  30      }
  31  
  32      pub fn start(&mut self, timeoutu64, repeatu64, cbTimerCallback) {
  33          {
  34              let data = self.get_watcher_data();
  35              data.timer_cb = Some(cb);
  36          }
  37  
  38          unsafe {
  39              uvll::timer_start(self.native_handle(), timer_cb, timeout, repeat);
  40          }
  41  
  42          extern fn timer_cb(handle*uvll::uv_timer_t, statusc_int) {
  43              let mut watcherTimerWatcher = NativeHandle::from_native_handle(handle);
  44              let data = watcher.get_watcher_data();
  45              let cb = data.timer_cb.get_ref();
  46              let status = status_to_maybe_uv_error(status);
  47              (*cb)(watcher, status);
  48          }
  49      }
  50  
  51      pub fn stop(&mut self) {
  52          unsafe {
  53              uvll::timer_stop(self.native_handle());
  54          }
  55      }
  56  
  57      pub fn close(self, cbNullCallback) {
  58          let mut watcher = self;
  59          {
  60              let data = watcher.get_watcher_data();
  61              assert!(data.close_cb.is_none());
  62              data.close_cb = Some(cb);
  63          }
  64  
  65          unsafe {
  66              uvll::close(watcher.native_handle(), close_cb);
  67          }
  68  
  69          extern fn close_cb(handle*uvll::uv_timer_t) {
  70              let mut watcherTimerWatcher = NativeHandle::from_native_handle(handle);
  71              {
  72                  let data = watcher.get_watcher_data();
  73                  data.close_cb.take_unwrap()();
  74              }
  75              watcher.drop_watcher_data();
  76              unsafe {
  77                  uvll::free_handle(handle as *c_void);
  78              }
  79          }
  80      }
  81  }
  82  
  83  impl NativeHandle<*uvll::uv_timer_t> for TimerWatcher {
  84      fn from_native_handle(handle*uvll::uv_timer_t) -> TimerWatcher {
  85          TimerWatcher(handle)
  86      }
  87      fn native_handle(&self) -> *uvll::uv_idle_t {
  88          match self { &TimerWatcher(ptr) => ptr }
  89      }
  90  }
  91  
  92  #[cfg(test)]
  93  mod test {
  94      use super::*;
  95      use rt::uv::Loop;
  96      use unstable::run_in_bare_thread;
  97  
  98      #[test]
  99      fn smoke_test() {
 100          do run_in_bare_thread {
 101              let mut count = 0;
 102              let count_ptr: *mut int = &mut count;
 103              let mut loop_ = Loop::new();
 104              let mut timer = TimerWatcher::new(&mut loop_);
 105              do timer.start(10, 0) |timer, status| {
 106                  assert!(status.is_none());
 107                  unsafe { *count_ptr += 1 };
 108                  timer.close(||());
 109              }
 110              loop_.run();
 111              loop_.close();
 112              assert!(count == 1);
 113          }
 114      }
 115  
 116      #[test]
 117      fn start_twice() {
 118          do run_in_bare_thread {
 119              let mut count = 0;
 120              let count_ptr: *mut int = &mut count;
 121              let mut loop_ = Loop::new();
 122              let mut timer = TimerWatcher::new(&mut loop_);
 123              do timer.start(10, 0) |timer, status| {
 124                  let mut timer = timer;
 125                  assert!(status.is_none());
 126                  unsafe { *count_ptr += 1 };
 127                  do timer.start(10, 0) |timer, status| {
 128                      assert!(status.is_none());
 129                      unsafe { *count_ptr += 1 };
 130                      timer.close(||());
 131                  }
 132              }
 133              loop_.run();
 134              loop_.close();
 135              assert!(count == 2);
 136          }
 137      }
 138  
 139      #[test]
 140      fn repeat_stop() {
 141          do run_in_bare_thread {
 142              let mut count = 0;
 143              let count_ptr: *mut int = &mut count;
 144              let mut loop_ = Loop::new();
 145              let mut timer = TimerWatcher::new(&mut loop_);
 146              do timer.start(1, 2) |timer, status| {
 147                  assert!(status.is_none());
 148                  unsafe {
 149                      *count_ptr += 1;
 150  
 151                      if *count_ptr == 10 {
 152  
 153                          // Stop the timer and do something else
 154                          let mut timer = timer;
 155                          timer.stop();
 156                          // Freeze timer so it can be captured
 157                          let timer = timer;
 158  
 159                          let mut loop_ = timer.event_loop();
 160                          let mut timer2 = TimerWatcher::new(&mut loop_);
 161                          do timer2.start(10, 0) |timer2, _| {
 162  
 163                              *count_ptr += 1;
 164  
 165                              timer2.close(||());
 166  
 167                              // Restart the original timer
 168                              let mut timer = timer;
 169                              do timer.start(1, 0) |timer, _| {
 170                                  *count_ptr += 1;
 171                                  timer.close(||());
 172                              }
 173                          }
 174                      }
 175                  };
 176              }
 177              loop_.run();
 178              loop_.close();
 179              assert!(count == 12);
 180          }
 181      }
 182  
 183  }

libstd/rt/uv/timer.rs:42:8-42:8 -fn- definition:
        extern fn timer_cb(handle: *uvll::uv_timer_t, status: c_int) {
            let mut watcher: TimerWatcher = NativeHandle::from_native_handle(handle);
references:-
39:             uvll::timer_start(self.native_handle(), timer_cb, timeout, repeat);


libstd/rt/uv/timer.rs:16:1-16:1 -struct- definition:

pub struct TimerWatcher(*uvll::uv_timer_t);
references:-
70:             let mut watcher: TimerWatcher = NativeHandle::from_native_handle(handle);
26:             let mut watcher: TimerWatcher = NativeHandle::from_native_handle(handle);
21:     pub fn new(loop_: &mut Loop) -> TimerWatcher {
43:             let mut watcher: TimerWatcher = NativeHandle::from_native_handle(handle);
83: impl NativeHandle<*uvll::uv_timer_t> for TimerWatcher {
18: impl Watcher for TimerWatcher { }
84:     fn from_native_handle(handle: *uvll::uv_timer_t) -> TimerWatcher {
20: impl TimerWatcher {
libstd/rt/uv/mod.rs:
136: pub type TimerCallback = ~fn(TimerWatcher, Option<UvError>);
libstd/rt/uv/uvio.rs:
1362:     fn new(w: timer::TimerWatcher, home: SchedHandle) -> UvTimer {
1353:     watcher: timer::TimerWatcher,


libstd/rt/uv/timer.rs:69:8-69:8 -fn- definition:
        extern fn close_cb(handle: *uvll::uv_timer_t) {
            let mut watcher: TimerWatcher = NativeHandle::from_native_handle(handle);
references:-
66:             uvll::close(watcher.native_handle(), close_cb);