]> git.lizzy.rs Git - rust.git/commitdiff
Migrate uv signal handling away from ~fn()
authorAlex Crichton <alex@alexcrichton.com>
Fri, 1 Nov 2013 18:13:22 +0000 (11:13 -0700)
committerAlex Crichton <alex@alexcrichton.com>
Sun, 10 Nov 2013 09:37:10 +0000 (01:37 -0800)
src/librustuv/lib.rs
src/librustuv/process.rs
src/librustuv/signal.rs
src/librustuv/timer.rs
src/librustuv/uvio.rs

index 66abca5924f2f2c14a6133eca6a3240837988543..487c007658083f3bb7988cca01f011c8b5233f47 100644 (file)
@@ -191,7 +191,6 @@ fn native_handle(&self) -> *uvll::uv_loop_t {
 pub type AsyncCallback = ~fn(AsyncWatcher, Option<UvError>);
 pub type UdpReceiveCallback = ~fn(UdpWatcher, int, Buf, SocketAddr, uint, Option<UvError>);
 pub type UdpSendCallback = ~fn(UdpWatcher, Option<UvError>);
-pub type SignalCallback = ~fn(SignalWatcher, Signum);
 
 
 /// Callbacks used by StreamWatchers, set as custom data on the foreign handle.
@@ -206,7 +205,6 @@ struct WatcherData {
     async_cb: Option<AsyncCallback>,
     udp_recv_cb: Option<UdpReceiveCallback>,
     udp_send_cb: Option<UdpSendCallback>,
-    signal_cb: Option<SignalCallback>,
 }
 
 pub trait WatcherInterop {
index 96b08b3f88b6e56703f50b3834d4f0e4992a9cab..fd35f9e494e873b4db4a2dafe196ba50b16e60bb 100644 (file)
@@ -103,7 +103,6 @@ pub fn spawn(loop_: &Loop, config: ProcessConfig)
 extern fn on_exit(handle: *uvll::uv_process_t,
                   exit_status: libc::c_int,
                   term_signal: libc::c_int) {
-    let handle = handle as *uvll::uv_handle_t;
     let p: &mut Process = unsafe { UvHandle::from_uv_handle(&handle) };
 
     assert!(p.exit_status.is_none());
index d5774b5aaab35d828e89168005e6951820b3a5d9..c195f48022735a3189bc8f225febb1c1367b87c4 100644 (file)
@@ -8,65 +8,72 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-use std::cast;
 use std::libc::c_int;
 use std::rt::io::signal::Signum;
+use std::rt::sched::{SchedHandle, Scheduler};
+use std::comm::{SharedChan, SendDeferred};
+use std::rt::local::Local;
+use std::rt::rtio::RtioSignal;
 
-use super::{Loop, NativeHandle, SignalCallback, UvError, Watcher};
+use super::{Loop, UvError, UvHandle};
 use uvll;
+use uvio::HomingIO;
 
-pub struct SignalWatcher(*uvll::uv_signal_t);
+pub struct SignalWatcher {
+    handle: *uvll::uv_signal_t,
+    home: SchedHandle,
 
-impl Watcher for SignalWatcher { }
+    channel: SharedChan<Signum>,
+    signal: Signum,
+}
 
 impl SignalWatcher {
-    pub fn new(loop_: &mut Loop) -> SignalWatcher {
-        unsafe {
-            let handle = uvll::malloc_handle(uvll::UV_SIGNAL);
-            assert!(handle.is_not_null());
-            assert!(0 == uvll::uv_signal_init(loop_.native_handle(), handle));
-            let mut watcher: SignalWatcher = NativeHandle::from_native_handle(handle);
-            watcher.install_watcher_data();
-            return watcher;
-        }
-    }
+    pub fn new(loop_: &mut Loop, signum: Signum,
+               channel: SharedChan<Signum>) -> Result<~SignalWatcher, UvError> {
+        let handle = UvHandle::alloc(None::<SignalWatcher>, uvll::UV_SIGNAL);
+        assert_eq!(unsafe {
+            uvll::signal_init(loop_.native_handle(), handle)
+        }, 0);
 
-    pub fn start(&mut self, signum: Signum, callback: SignalCallback)
-            -> Result<(), UvError>
-    {
-        return unsafe {
-            match uvll::uv_signal_start(self.native_handle(), signal_cb,
-                                        signum as c_int) {
-                0 => {
-                    let data = self.get_watcher_data();
-                    data.signal_cb = Some(callback);
-                    Ok(())
-                }
-                n => Err(UvError(n)),
+        match unsafe { uvll::signal_start(handle, signal_cb, signum as c_int) } {
+            0 => {
+                let s = ~SignalWatcher {
+                    handle: handle,
+                    home: get_handle_to_current_scheduler!(),
+                    channel: channel,
+                    signal: signum,
+                };
+                Ok(s.install())
+            }
+            n => {
+                unsafe { uvll::free_handle(handle) }
+                Err(UvError(n))
             }
-        };
-
-        extern fn signal_cb(handle: *uvll::uv_signal_t, signum: c_int) {
-            let mut watcher: SignalWatcher = NativeHandle::from_native_handle(handle);
-            let data = watcher.get_watcher_data();
-            let cb = data.signal_cb.get_ref();
-            (*cb)(watcher, unsafe { cast::transmute(signum as int) });
         }
-    }
 
-    pub fn stop(&mut self) {
-        unsafe {
-            uvll::uv_signal_stop(self.native_handle());
-        }
     }
 }
 
-impl NativeHandle<*uvll::uv_signal_t> for SignalWatcher {
-    fn from_native_handle(handle: *uvll::uv_signal_t) -> SignalWatcher {
-        SignalWatcher(handle)
-    }
+extern fn signal_cb(handle: *uvll::uv_signal_t, signum: c_int) {
+    let s: &mut SignalWatcher = unsafe { UvHandle::from_uv_handle(&handle) };
+    assert_eq!(signum as int, s.signal as int);
+    s.channel.send_deferred(s.signal);
+}
+
+impl HomingIO for SignalWatcher {
+    fn home<'r>(&'r mut self) -> &'r mut SchedHandle { &mut self.home }
+}
 
-    fn native_handle(&self) -> *uvll::uv_signal_t {
-        match self { &SignalWatcher(ptr) => ptr }
+impl UvHandle<uvll::uv_signal_t> for SignalWatcher {
+    fn uv_handle(&self) -> *uvll::uv_signal_t { self.handle }
+}
+
+impl RtioSignal for SignalWatcher {}
+
+impl Drop for SignalWatcher {
+    fn drop(&mut self) {
+        do self.home_for_io |self_| {
+            self_.close_async_();
+        }
     }
 }
index f4f2563f0b9e82625e8ce11e17b66f996a28d716..956699c5c2e89060628eacb815b8e7b1f82ab098 100644 (file)
@@ -102,8 +102,7 @@ fn period(&mut self, msecs: u64) -> Port<()> {
 }
 
 extern fn timer_cb(handle: *uvll::uv_timer_t, _status: c_int) {
-    let handle = handle as *uvll::uv_handle_t;
-    let timer : &mut TimerWatcher = unsafe { UvHandle::from_uv_handle(&handle) };
+    let timer: &mut TimerWatcher = unsafe { UvHandle::from_uv_handle(&handle) };
 
     match timer.action.take_unwrap() {
         WakeTask(task) => {
index 226507ff09a438f3f931d6ee8a0916a3db812205..dc8793c285b800b14f4fe389eda368ae902f5787 100644 (file)
@@ -13,8 +13,8 @@
 use std::cast;
 use std::cell::Cell;
 use std::clone::Clone;
-use std::comm::{SendDeferred, SharedChan, GenericChan};
-use std::libc::{c_int, c_uint, c_void, pid_t};
+use std::comm::{SharedChan, GenericChan};
+use std::libc::{c_int, c_uint, c_void};
 use std::ptr;
 use std::str;
 use std::rt::io;
@@ -841,11 +841,8 @@ fn pipe_open(&mut self, fd: c_int) -> Result<~RtioPipe, IoError> {
 
     fn signal(&mut self, signum: Signum, channel: SharedChan<Signum>)
         -> Result<~RtioSignal, IoError> {
-        let watcher = SignalWatcher::new(self.uv_loop());
-        let home = get_handle_to_current_scheduler!();
-        let mut signal = ~UvSignal::new(watcher, home);
-        match signal.watcher.start(signum, |_, _| channel.send_deferred(signum)) {
-            Ok(()) => Ok(signal as ~RtioSignal),
+        match SignalWatcher::new(self.uv_loop(), signum, channel) {
+            Ok(s) => Ok(s as ~RtioSignal),
             Err(e) => Err(uv_error_to_io_error(e)),
         }
     }
@@ -1591,37 +1588,6 @@ fn dont_accept_simultaneously(&mut self) -> Result<(), IoError> {
     }
 }
 
-pub struct UvSignal {
-    watcher: signal::SignalWatcher,
-    home: SchedHandle,
-}
-
-impl HomingIO for UvSignal {
-    fn home<'r>(&'r mut self) -> &'r mut SchedHandle { &mut self.home }
-}
-
-impl UvSignal {
-    fn new(w: signal::SignalWatcher, home: SchedHandle) -> UvSignal {
-        UvSignal { watcher: w, home: home }
-    }
-}
-
-impl RtioSignal for UvSignal {}
-
-impl Drop for UvSignal {
-    fn drop(&mut self) {
-        let (_m, scheduler) = self.fire_homing_missile_sched();
-        uvdebug!("closing UvSignal");
-        do scheduler.deschedule_running_task_and_then |_, task| {
-            let task_cell = Cell::new(task);
-            do self.watcher.close {
-                let scheduler: ~Scheduler = Local::take();
-                scheduler.resume_blocked_task_immediately(task_cell.take());
-            }
-        }
-    }
-}
-
 // this function is full of lies
 unsafe fn local_io() -> &'static mut IoFactory {
     do Local::borrow |sched: &mut Scheduler| {