diff --git a/src/librustuv/lib.rs b/src/librustuv/lib.rs index 66abca5924f2..487c00765808 100644 --- a/src/librustuv/lib.rs +++ b/src/librustuv/lib.rs @@ -191,7 +191,6 @@ pub type FsCallback = ~fn(&mut FsRequest, Option); pub type AsyncCallback = ~fn(AsyncWatcher, Option); pub type UdpReceiveCallback = ~fn(UdpWatcher, int, Buf, SocketAddr, uint, Option); pub type UdpSendCallback = ~fn(UdpWatcher, Option); -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, udp_recv_cb: Option, udp_send_cb: Option, - signal_cb: Option, } pub trait WatcherInterop { diff --git a/src/librustuv/process.rs b/src/librustuv/process.rs index 96b08b3f88b6..fd35f9e494e8 100644 --- a/src/librustuv/process.rs +++ b/src/librustuv/process.rs @@ -103,7 +103,6 @@ impl Process { 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()); diff --git a/src/librustuv/signal.rs b/src/librustuv/signal.rs index d5774b5aaab3..c195f4802273 100644 --- a/src/librustuv/signal.rs +++ b/src/librustuv/signal.rs @@ -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, + 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) -> Result<~SignalWatcher, UvError> { + let handle = UvHandle::alloc(None::, 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); +} - fn native_handle(&self) -> *uvll::uv_signal_t { - match self { &SignalWatcher(ptr) => ptr } +impl HomingIO for SignalWatcher { + fn home<'r>(&'r mut self) -> &'r mut SchedHandle { &mut self.home } +} + +impl UvHandle 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_(); + } } } diff --git a/src/librustuv/timer.rs b/src/librustuv/timer.rs index f4f2563f0b9e..956699c5c2e8 100644 --- a/src/librustuv/timer.rs +++ b/src/librustuv/timer.rs @@ -102,8 +102,7 @@ impl RtioTimer for TimerWatcher { } 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) => { diff --git a/src/librustuv/uvio.rs b/src/librustuv/uvio.rs index 226507ff09a4..dc8793c285b8 100644 --- a/src/librustuv/uvio.rs +++ b/src/librustuv/uvio.rs @@ -13,8 +13,8 @@ use std::cast::transmute; 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 @@ impl IoFactory for UvIoFactory { fn signal(&mut self, signum: Signum, channel: SharedChan) -> 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 @@ impl RtioUnixAcceptor for UvUnixAcceptor { } } -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| {