about summary refs log tree commit diff
path: root/src/libstd
diff options
context:
space:
mode:
authorJeff Olson <olson.jeffery@gmail.com>2012-02-25 22:08:52 -0800
committerBrian Anderson <banderson@mozilla.com>2012-02-28 17:56:15 -0800
commitb4c88cdcecbcf40e1b9a123dcb6056970e256e9b (patch)
tree6b88cfaea3f23cb9323cc9402a7729b37d7349b1 /src/libstd
parent0b3a06ab2ca989ab0f0b9fa5fa8aa83a2ec13998 (diff)
downloadrust-b4c88cdcecbcf40e1b9a123dcb6056970e256e9b.tar.gz
rust-b4c88cdcecbcf40e1b9a123dcb6056970e256e9b.zip
add uv::loop_delete()
because of the last change, the loop ptr is no longer cleaned up
when the loop exits. This api call addresses that. Sadly, the loop
ptr is not "reusable" across multiple calls to uv::run().
Diffstat (limited to 'src/libstd')
-rw-r--r--src/libstd/uv.rs97
1 files changed, 67 insertions, 30 deletions
diff --git a/src/libstd/uv.rs b/src/libstd/uv.rs
index 0cc89a441ef..3988bd378d2 100644
--- a/src/libstd/uv.rs
+++ b/src/libstd/uv.rs
@@ -1,5 +1,6 @@
-export loop_new, run, close, run_in_bg, async_init, async_send,
-       timer_init, timer_start, timer_stop;
+export loop_new, loop_delete, run, close, run_in_bg;
+export async_init, async_send;
+export timer_init, timer_start, timer_stop;
 
 // these are processed solely in the
 // process_operation() crust fn below
@@ -44,11 +45,14 @@ type uv_loop_data = {
     rust_loop_chan: comm::chan<uv_msg>
 };
 
-type uv_loop = comm::chan<uv_msg>;
+enum uv_loop {
+    uv_loop_new(comm::chan<uv_msg>, *ctypes::void)
+}
 
 #[nolink]
 native mod rustrt {
     fn rust_uv_loop_new() -> *ctypes::void;
+    fn rust_uv_loop_delete(loop: *ctypes::void);
     fn rust_uv_loop_set_data(
         loop: *ctypes::void,
         data: *uv_loop_data);
@@ -103,7 +107,8 @@ fn loop_new() -> uv_loop unsafe {
         let rust_loop_chan =
             comm::chan::<uv_msg>(rust_loop_port);
         // let the task-spawner return
-        comm::send(ret_recv_chan, copy(rust_loop_chan));
+        let user_uv_loop = uv_loop_new(rust_loop_chan, loop_handle);
+        comm::send(ret_recv_chan, copy(user_uv_loop));
 
         // create our "special" async handle that will
         // allow all operations against libuv to be
@@ -225,7 +230,7 @@ fn loop_new() -> uv_loop unsafe {
                 handles.insert(id, async_handle);
                 let after_cb = after_cbs.get(id);
                 after_cbs.remove(id);
-                let async = uv_async(id, rust_loop_chan);
+                let async = uv_async(id, user_uv_loop);
                 id_to_handle.insert(id, copy(async));
                 task::spawn {||
                     after_cb(async);
@@ -239,7 +244,8 @@ fn loop_new() -> uv_loop unsafe {
               uv_async_send(id) {
                 let async_cb = async_cbs.get(id);
                 task::spawn {||
-                    async_cb(uv_async(id, rust_loop_chan));
+                    let the_loop = user_uv_loop;
+                    async_cb(uv_async(id, the_loop));
                 };
               }
 
@@ -254,7 +260,7 @@ fn loop_new() -> uv_loop unsafe {
                 handles.insert(id, handle);
                 let after_cb = after_cbs.get(id);
                 after_cbs.remove(id);
-                let new_timer = uv_timer(id, rust_loop_chan);
+                let new_timer = uv_timer(id, user_uv_loop);
                 id_to_handle.insert(id, copy(new_timer));
                 task::spawn {||
                     after_cb(new_timer);
@@ -310,15 +316,22 @@ fn loop_new() -> uv_loop unsafe {
     ret comm::recv(ret_recv_port);
 }
 
+fn loop_delete(loop: uv_loop) {
+    let loop_ptr = get_loop_ptr_from_uv_loop(loop);
+    rustrt::rust_uv_loop_delete(loop_ptr);
+}
+
 fn run(loop: uv_loop) {
     let end_port = comm::port::<bool>();
     let end_chan = comm::chan::<bool>(end_port);
-    comm::send(loop, msg_run(end_chan));
+    let loop_chan = get_loop_chan_from_uv_loop(loop);
+    comm::send(loop_chan, msg_run(end_chan));
     comm::recv(end_port);
 }
 
 fn run_in_bg(loop: uv_loop) {
-    comm::send(loop, msg_run_in_bg);
+    let loop_chan = get_loop_chan_from_uv_loop(loop);
+    comm::send(loop_chan, msg_run_in_bg);
 }
 
 fn async_init (
@@ -326,13 +339,15 @@ fn async_init (
     async_cb: fn~(uv_handle),
     after_cb: fn~(uv_handle)) {
     let msg = msg_async_init(async_cb, after_cb);
-    comm::send(loop, msg);
+    let loop_chan = get_loop_chan_from_uv_loop(loop);
+    comm::send(loop_chan, msg);
 }
 
 fn async_send(async: uv_handle) {
     alt async {
       uv_async(id, loop) {
-        comm::send(loop, msg_async_send(id));
+        let loop_chan = get_loop_chan_from_uv_loop(loop);
+        comm::send(loop_chan, msg_async_send(id));
       }
       _ {
         fail "attempting to call async_send() with a" +
@@ -348,14 +363,16 @@ fn close(h: uv_handle, cb: fn~()) {
 
 fn timer_init(loop: uv_loop, after_cb: fn~(uv_handle)) {
     let msg = msg_timer_init(after_cb);
-    comm::send(loop, msg);
+    let loop_chan = get_loop_chan_from_uv_loop(loop);
+    comm::send(loop_chan, msg);
 }
 
 fn timer_start(the_timer: uv_handle, timeout: u32, repeat:u32,
                timer_cb: fn~(uv_handle)) {
     alt the_timer {
-      uv_timer(id, loop_chan) {
+      uv_timer(id, loop) {
         let msg = msg_timer_start(id, timeout, repeat, timer_cb);
+        let loop_chan = get_loop_chan_from_uv_loop(loop);
         comm::send(loop_chan, msg);
       }
       _ {
@@ -367,7 +384,8 @@ fn timer_start(the_timer: uv_handle, timeout: u32, repeat:u32,
 
 fn timer_stop(the_timer: uv_handle, after_cb: fn~(uv_handle)) {
     alt the_timer {
-      uv_timer(id, loop_chan) {
+      uv_timer(id, loop) {
+        let loop_chan = get_loop_chan_from_uv_loop(loop);
         let msg = msg_timer_stop(id, after_cb);
         comm::send(loop_chan, msg);
       }
@@ -397,15 +415,16 @@ fn get_handle_id_from(buf: *u8) -> [u8] unsafe {
 }
 
 fn get_loop_chan_from_data(data: *uv_loop_data)
-        -> uv_loop unsafe {
+        -> comm::chan<uv_msg> unsafe {
     ret (*data).rust_loop_chan;
 }
 
 fn get_loop_chan_from_handle(handle: uv_handle)
-    -> uv_loop {
+    -> comm::chan<uv_msg> {
     alt handle {
       uv_async(id,loop) | uv_timer(id,loop) {
-        ret loop;
+        let loop_chan = get_loop_chan_from_uv_loop(loop);
+        ret loop_chan;
       }
       _ {
         fail "unknown form of uv_handle for get_loop_chan_from "
@@ -414,6 +433,21 @@ fn get_loop_chan_from_handle(handle: uv_handle)
     }
 }
 
+fn get_loop_ptr_from_uv_loop(loop: uv_loop) -> *ctypes::void {
+    alt loop {
+      uv_loop_new(loop_chan, loop_ptr) {
+        ret loop_ptr;
+      }
+    }
+}
+fn get_loop_chan_from_uv_loop(loop: uv_loop) -> comm::chan<uv_msg> {
+    alt loop {
+      uv_loop_new(loop_chan, loop_ptr) {
+        ret loop_chan;
+      }
+    }
+}
+
 fn get_id_from_handle(handle: uv_handle) -> [u8] {
     alt handle {
       uv_async(id,loop) | uv_timer(id,loop) {
@@ -548,41 +582,44 @@ crust fn process_close_timer(
 #[test]
 fn test_uv_new_loop_no_handles() {
     let test_loop = uv::loop_new();
-    run(test_loop); // this should return immediately
+    uv::run(test_loop); // this should return immediately
                     // since there aren't any handles..
+    uv::loop_delete(test_loop);
 }
 
 #[test]
 fn test_uv_simple_async() {
-    let test_loop = loop_new();
+    let test_loop = uv::loop_new();
     let exit_port = comm::port::<bool>();
     let exit_chan = comm::chan::<bool>(exit_port);
-    async_init(test_loop, {|new_async|
-        close(new_async) {||
+    uv::async_init(test_loop, {|new_async|
+        uv::close(new_async) {||
             comm::send(exit_chan, true);
         };
     }, {|new_async|
-        async_send(new_async);
+        uv::async_send(new_async);
     });
-    run(test_loop);
+    uv::run(test_loop);
     let result = comm::recv(exit_port);
     assert result;
+    uv::loop_delete(test_loop);
 }
 
 #[test]
 fn test_uv_timer() {
-    let test_loop = loop_new();
+    let test_loop = uv::loop_new();
     let exit_port = comm::port::<bool>();
     let exit_chan = comm::chan::<bool>(exit_port);
-    timer_init(test_loop) {|new_timer|
-        timer_start(new_timer, 1u32, 0u32) {|started_timer|
-            timer_stop(started_timer) {|stopped_timer|
-                close(stopped_timer) {||
+    uv::timer_init(test_loop) {|new_timer|
+        uv::timer_start(new_timer, 1u32, 0u32) {|started_timer|
+            uv::timer_stop(started_timer) {|stopped_timer|
+                uv::close(stopped_timer) {||
                     comm::send(exit_chan, true);
                 };
             };
         };
     };
-    run(test_loop);
+    uv::run(test_loop);
     assert comm::recv(exit_port);
-}
\ No newline at end of file
+    uv::loop_delete(test_loop);
+}