]> git.lizzy.rs Git - rust.git/commitdiff
std: add RtioTimer and UvTimer impl atop rt::uv
authorJeff Olson <olson.jeffery@gmail.com>
Fri, 19 Jul 2013 23:02:38 +0000 (16:02 -0700)
committerJeff Olson <olson.jeffery@gmail.com>
Mon, 22 Jul 2013 20:19:04 +0000 (13:19 -0700)
src/libstd/rt/rtio.rs
src/libstd/rt/uv/uvio.rs

index 10eba85188ef0aea153dd80a0809a54ebb4e24c8..aa8b9dc3a944d67342b88847b6f402c135f21bc2 100644 (file)
@@ -23,6 +23,7 @@
 pub type RtioTcpStreamObject = uvio::UvTcpStream;
 pub type RtioTcpListenerObject = uvio::UvTcpListener;
 pub type RtioUdpSocketObject = uvio::UvUdpSocket;
+pub type RtioTimerObject = uvio::UvTimer;
 
 pub trait EventLoop {
     fn run(&mut self);
@@ -46,6 +47,7 @@ pub trait IoFactory {
     fn tcp_connect(&mut self, addr: IpAddr) -> Result<~RtioTcpStreamObject, IoError>;
     fn tcp_bind(&mut self, addr: IpAddr) -> Result<~RtioTcpListenerObject, IoError>;
     fn udp_bind(&mut self, addr: IpAddr) -> Result<~RtioUdpSocketObject, IoError>;
+    fn timer_init(&mut self) -> Result<~RtioTimerObject, IoError>;
 }
 
 pub trait RtioTcpListener : RtioSocket {
@@ -84,3 +86,7 @@ pub trait RtioUdpSocket : RtioSocket {
     fn hear_broadcasts(&mut self);
     fn ignore_broadcasts(&mut self);
 }
+
+pub trait RtioTimer {
+    fn sleep(&self, msecs: u64);
+}
index 9b96c8717346d26186d80dd0719c4b6c413e4522..4ecfa46328422c4976363b1043d36ebcd74290df 100644 (file)
@@ -280,6 +280,10 @@ fn udp_bind(&mut self, addr: IpAddr) -> Result<~RtioUdpSocketObject, IoError> {
             }
         }
     }
+
+    fn timer_init(&mut self) -> Result<~RtioTimerObject, IoError> {
+        Ok(~UvTimer(TimerWatcher::new(self.uv_loop())))
+    }
 }
 
 // FIXME #6090: Prefer newtype structs but Drop doesn't work
@@ -562,6 +566,48 @@ fn sendto(&mut self, buf: &[u8], dst: IpAddr) -> Result<(), IoError> {
     fn ignore_broadcasts(&mut self) { fail!(); }
 }
 
+pub struct UvTimer(timer::TimerWatcher);
+
+impl UvTimer {
+    fn new(w: timer::TimerWatcher) -> UvTimer {
+        UvTimer(w)
+    }
+}
+
+impl Drop for UvTimer {
+    fn drop(&self) {
+        rtdebug!("closing UvTimer");
+        let scheduler = Local::take::<Scheduler>();
+        do scheduler.deschedule_running_task_and_then |_, task| {
+            let task_cell = Cell::new(task);
+            do self.close {
+                let scheduler = Local::take::<Scheduler>();
+                scheduler.resume_task_immediately(task_cell.take());
+            }
+        }
+    }
+}
+
+impl RtioTimer for UvTimer {
+    fn sleep(&self, msecs: u64) {
+        let scheduler = Local::take::<Scheduler>();
+        assert!(scheduler.in_task_context());
+        do scheduler.deschedule_running_task_and_then |sched, task| {
+            rtdebug!("sleep: entered scheduler context");
+            assert!(!sched.in_task_context());
+            let task_cell = Cell::new(task);
+            let mut watcher = **self;
+            do watcher.start(msecs, 0) |_, status| {
+                assert!(status.is_none());
+                let scheduler = Local::take::<Scheduler>();
+                scheduler.resume_task_immediately(task_cell.take());
+            }
+        }
+        let mut w = **self;
+        w.stop();
+    }
+}
+
 #[test]
 fn test_simple_io_no_connect() {
     do run_in_newsched_task {
@@ -832,3 +878,20 @@ fn test_udp_many_read() {
         }
     }
 }
+
+fn test_timer_sleep_simple_impl() {
+    unsafe {
+        let io = Local::unsafe_borrow::<IoFactoryObject>();
+        let timer = (*io).timer_init();
+        match timer {
+            Ok(t) => t.sleep(1),
+            Err(_) => assert!(false)
+        }
+    }
+}
+#[test]
+fn test_timer_sleep_simple() {
+    do run_in_newsched_task {
+        test_timer_sleep_simple_impl();
+    }
+}