(index<- )        ./libstd/rt/uv/idle.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_int;
  12  use option::Some;
  13  use rt::uv::uvll;
  14  use rt::uv::{Watcher, Loop, NativeHandle, IdleCallback, NullCallback};
  15  use rt::uv::status_to_maybe_uv_error;
  16  
  17  pub struct IdleWatcher(*uvll::uv_idle_t);
  18  impl Watcher for IdleWatcher { }
  19  
  20  impl IdleWatcher {
  21      pub fn new(loop_&mut Loop) -> IdleWatcher {
  22          unsafe {
  23              let handle = uvll::idle_new();
  24              assert!(handle.is_not_null());
  25              assert!(0 == uvll::idle_init(loop_.native_handle(), handle));
  26              let mut watcherIdleWatcher = NativeHandle::from_native_handle(handle);
  27              watcher.install_watcher_data();
  28              return watcher
  29          }
  30      }
  31  
  32      pub fn start(&mut self, cbIdleCallback) {
  33          {
  34              let data = self.get_watcher_data();
  35              data.idle_cb = Some(cb);
  36          }
  37  
  38          unsafe {
  39              assert!(0 == uvll::idle_start(self.native_handle(), idle_cb))
  40          };
  41  
  42          extern fn idle_cb(handle*uvll::uv_idle_t, statusc_int) {
  43              let mut idle_watcherIdleWatcher = NativeHandle::from_native_handle(handle);
  44              let data = idle_watcher.get_watcher_data();
  45              let cb&IdleCallback = data.idle_cb.get_ref();
  46              let status = status_to_maybe_uv_error(status);
  47              (*cb)(idle_watcher, status);
  48          }
  49      }
  50  
  51      pub fn restart(&mut self) {
  52          unsafe {
  53              assert!(0 == uvll::idle_start(self.native_handle(), idle_cb))
  54          };
  55  
  56          extern fn idle_cb(handle*uvll::uv_idle_t, statusc_int) {
  57              let mut idle_watcherIdleWatcher = NativeHandle::from_native_handle(handle);
  58              let data = idle_watcher.get_watcher_data();
  59              let cb&IdleCallback = data.idle_cb.get_ref();
  60              let status = status_to_maybe_uv_error(status);
  61              (*cb)(idle_watcher, status);
  62          }
  63      }
  64  
  65      pub fn stop(&mut self) {
  66          // NB: Not resetting the Rust idle_cb to None here because `stop` is
  67          // likely called from *within* the idle callback, causing a use after
  68          // free
  69  
  70          unsafe {
  71              assert!(0 == uvll::idle_stop(self.native_handle()));
  72          }
  73      }
  74  
  75      pub fn close(self, cbNullCallback) {
  76          {
  77              let mut this = self;
  78              let data = this.get_watcher_data();
  79              assert!(data.close_cb.is_none());
  80              data.close_cb = Some(cb);
  81          }
  82  
  83          unsafe { uvll::close(self.native_handle(), close_cb) };
  84  
  85          extern fn close_cb(handle*uvll::uv_idle_t) {
  86              unsafe {
  87                  let mut idle_watcherIdleWatcher = NativeHandle::from_native_handle(handle);
  88                  {
  89                      let data = idle_watcher.get_watcher_data();
  90                      data.close_cb.take_unwrap()();
  91                  }
  92                  idle_watcher.drop_watcher_data();
  93                  uvll::idle_delete(handle);
  94              }
  95          }
  96      }
  97  }
  98  
  99  impl NativeHandle<*uvll::uv_idle_t> for IdleWatcher {
 100      fn from_native_handle(handle*uvll::uv_idle_t) -> IdleWatcher {
 101          IdleWatcher(handle)
 102      }
 103      fn native_handle(&self) -> *uvll::uv_idle_t {
 104          match self { &IdleWatcher(ptr) => ptr }
 105      }
 106  }
 107  
 108  #[cfg(test)]
 109  mod test {
 110  
 111      use rt::uv::Loop;
 112      use super::*;
 113      use unstable::run_in_bare_thread;
 114  
 115      #[test]
 116      #[ignore(reason = "valgrind - loop destroyed before watcher?")]
 117      fn idle_new_then_close() {
 118          do run_in_bare_thread {
 119              let mut loop_ = Loop::new();
 120              let idle_watcher = { IdleWatcher::new(&mut loop_) };
 121              idle_watcher.close(||());
 122          }
 123      }
 124  
 125      #[test]
 126      fn idle_smoke_test() {
 127          do run_in_bare_thread {
 128              let mut loop_ = Loop::new();
 129              let mut idle_watcher = { IdleWatcher::new(&mut loop_) };
 130              let mut count = 10;
 131              let count_ptr: *mut int = &mut count;
 132              do idle_watcher.start |idle_watcher, status| {
 133                  let mut idle_watcher = idle_watcher;
 134                  assert!(status.is_none());
 135                  if unsafe { *count_ptr == 10 } {
 136                      idle_watcher.stop();
 137                      idle_watcher.close(||());
 138                  } else {
 139                      unsafe { *count_ptr = *count_ptr + 1; }
 140                  }
 141              }
 142              loop_.run();
 143              loop_.close();
 144              assert_eq!(count, 10);
 145          }
 146      }
 147  
 148      #[test]
 149      fn idle_start_stop_start() {
 150          do run_in_bare_thread {
 151              let mut loop_ = Loop::new();
 152              let mut idle_watcher = { IdleWatcher::new(&mut loop_) };
 153              do idle_watcher.start |idle_watcher, status| {
 154                  let mut idle_watcher = idle_watcher;
 155                  assert!(status.is_none());
 156                  idle_watcher.stop();
 157                  do idle_watcher.start |idle_watcher, status| {
 158                      assert!(status.is_none());
 159                      let mut idle_watcher = idle_watcher;
 160                      idle_watcher.stop();
 161                      idle_watcher.close(||());
 162                  }
 163              }
 164              loop_.run();
 165              loop_.close();
 166          }
 167      }
 168  }

libstd/rt/uv/idle.rs:42:8-42:8 -fn- definition:
        extern fn idle_cb(handle: *uvll::uv_idle_t, status: c_int) {
            let mut idle_watcher: IdleWatcher = NativeHandle::from_native_handle(handle);
references:-
39:             assert!(0 == uvll::idle_start(self.native_handle(), idle_cb))


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

pub struct IdleWatcher(*uvll::uv_idle_t);
references:-
21:     pub fn new(loop_: &mut Loop) -> IdleWatcher {
20: impl IdleWatcher {
43:             let mut idle_watcher: IdleWatcher = NativeHandle::from_native_handle(handle);
57:             let mut idle_watcher: IdleWatcher = NativeHandle::from_native_handle(handle);
26:             let mut watcher: IdleWatcher = NativeHandle::from_native_handle(handle);
100:     fn from_native_handle(handle: *uvll::uv_idle_t) -> IdleWatcher {
99: impl NativeHandle<*uvll::uv_idle_t> for IdleWatcher {
18: impl Watcher for IdleWatcher { }
87:                 let mut idle_watcher: IdleWatcher = NativeHandle::from_native_handle(handle);
libstd/rt/uv/mod.rs:
131: pub type IdleCallback = ~fn(IdleWatcher, Option<UvError>);
libstd/rt/uv/uvio.rs:
243:     watcher: IdleWatcher,


libstd/rt/uv/idle.rs:56:8-56:8 -fn- definition:
        extern fn idle_cb(handle: *uvll::uv_idle_t, status: c_int) {
            let mut idle_watcher: IdleWatcher = NativeHandle::from_native_handle(handle);
references:-
53:             assert!(0 == uvll::idle_start(self.native_handle(), idle_cb))


libstd/rt/uv/idle.rs:85:8-85:8 -fn- definition:
        extern fn close_cb(handle: *uvll::uv_idle_t) {
            unsafe {
references:-
83:         unsafe { uvll::close(self.native_handle(), close_cb) };