Migrate uv signal handling away from ~fn()
This commit is contained in:
parent
ceab326e82
commit
9286d5113d
@ -191,7 +191,6 @@ pub type FsCallback = ~fn(&mut FsRequest, Option<UvError>);
|
||||
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 {
|
||||
|
@ -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());
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
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<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_();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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) => {
|
||||
|
@ -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<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 @@ 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| {
|
||||
|
Loading…
x
Reference in New Issue
Block a user