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.
async_cb: Option<AsyncCallback>,
udp_recv_cb: Option<UdpReceiveCallback>,
udp_send_cb: Option<UdpSendCallback>,
- signal_cb: Option<SignalCallback>,
}
pub trait WatcherInterop {
// 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_();
+ }
}
}
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;
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)),
}
}
}
}
-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| {