2021-01-10 21:59:07 -05:00
|
|
|
// Copyright 2018-2021 the Deno authors. All rights reserved. MIT license.
|
2020-09-14 12:48:57 -04:00
|
|
|
use deno_core::error::AnyError;
|
2021-05-02 19:22:57 -04:00
|
|
|
use deno_core::op_async;
|
|
|
|
use deno_core::op_sync;
|
|
|
|
use deno_core::Extension;
|
2020-09-10 09:57:45 -04:00
|
|
|
use deno_core::OpState;
|
2020-04-23 05:51:07 -04:00
|
|
|
use deno_core::ZeroCopyBuf;
|
2020-09-10 09:57:45 -04:00
|
|
|
use std::cell::RefCell;
|
2020-08-18 12:30:13 -04:00
|
|
|
use std::rc::Rc;
|
2020-01-24 08:15:31 -05:00
|
|
|
|
2020-09-14 12:48:57 -04:00
|
|
|
#[cfg(unix)]
|
|
|
|
use deno_core::error::bad_resource_id;
|
2020-01-24 08:15:31 -05:00
|
|
|
#[cfg(unix)]
|
2020-12-16 11:14:12 -05:00
|
|
|
use deno_core::AsyncRefCell;
|
|
|
|
#[cfg(unix)]
|
|
|
|
use deno_core::CancelFuture;
|
|
|
|
#[cfg(unix)]
|
|
|
|
use deno_core::CancelHandle;
|
|
|
|
#[cfg(unix)]
|
|
|
|
use deno_core::RcRef;
|
|
|
|
#[cfg(unix)]
|
|
|
|
use deno_core::Resource;
|
|
|
|
#[cfg(unix)]
|
2021-04-05 12:40:24 -04:00
|
|
|
use deno_core::ResourceId;
|
2020-09-05 20:34:02 -04:00
|
|
|
#[cfg(unix)]
|
2020-12-16 11:14:12 -05:00
|
|
|
use std::borrow::Cow;
|
2020-01-24 08:15:31 -05:00
|
|
|
#[cfg(unix)]
|
|
|
|
use tokio::signal::unix::{signal, Signal, SignalKind};
|
|
|
|
|
2021-05-02 19:22:57 -04:00
|
|
|
pub fn init() -> Extension {
|
|
|
|
Extension::builder()
|
|
|
|
.ops(vec![
|
|
|
|
("op_signal_bind", op_sync(op_signal_bind)),
|
|
|
|
("op_signal_unbind", op_sync(op_signal_unbind)),
|
|
|
|
("op_signal_poll", op_async(op_signal_poll)),
|
|
|
|
])
|
|
|
|
.build()
|
2020-01-24 08:15:31 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
#[cfg(unix)]
|
|
|
|
/// The resource for signal stream.
|
|
|
|
/// The second element is the waker of polling future.
|
2020-12-16 11:14:12 -05:00
|
|
|
struct SignalStreamResource {
|
|
|
|
signal: AsyncRefCell<Signal>,
|
|
|
|
cancel: CancelHandle,
|
|
|
|
}
|
|
|
|
|
|
|
|
#[cfg(unix)]
|
|
|
|
impl Resource for SignalStreamResource {
|
|
|
|
fn name(&self) -> Cow<str> {
|
|
|
|
"signal".into()
|
|
|
|
}
|
|
|
|
|
|
|
|
fn close(self: Rc<Self>) {
|
|
|
|
self.cancel.cancel();
|
|
|
|
}
|
|
|
|
}
|
2020-01-24 08:15:31 -05:00
|
|
|
|
|
|
|
#[cfg(unix)]
|
2021-03-18 14:42:01 -04:00
|
|
|
#[allow(clippy::unnecessary_wraps)]
|
2020-01-24 08:15:31 -05:00
|
|
|
fn op_signal_bind(
|
2020-09-10 09:57:45 -04:00
|
|
|
state: &mut OpState,
|
2021-04-05 12:40:24 -04:00
|
|
|
signo: i32,
|
2021-04-02 09:47:57 -04:00
|
|
|
_zero_copy: Option<ZeroCopyBuf>,
|
2021-04-05 12:40:24 -04:00
|
|
|
) -> Result<ResourceId, AnyError> {
|
2020-09-26 14:26:51 -04:00
|
|
|
super::check_unstable(state, "Deno.signal");
|
2020-12-16 11:14:12 -05:00
|
|
|
let resource = SignalStreamResource {
|
2021-04-05 12:40:24 -04:00
|
|
|
signal: AsyncRefCell::new(signal(SignalKind::from_raw(signo)).expect("")),
|
2020-12-16 11:14:12 -05:00
|
|
|
cancel: Default::default(),
|
|
|
|
};
|
|
|
|
let rid = state.resource_table.add(resource);
|
2021-04-05 12:40:24 -04:00
|
|
|
Ok(rid)
|
2020-01-24 08:15:31 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
#[cfg(unix)]
|
2020-08-28 11:08:24 -04:00
|
|
|
async fn op_signal_poll(
|
2020-09-10 09:57:45 -04:00
|
|
|
state: Rc<RefCell<OpState>>,
|
2021-04-05 12:40:24 -04:00
|
|
|
rid: ResourceId,
|
2021-04-02 09:47:57 -04:00
|
|
|
_zero_copy: Option<ZeroCopyBuf>,
|
2021-04-05 12:40:24 -04:00
|
|
|
) -> Result<bool, AnyError> {
|
2020-09-26 14:26:51 -04:00
|
|
|
super::check_unstable2(&state, "Deno.signal");
|
2020-01-24 08:15:31 -05:00
|
|
|
|
2020-12-16 11:14:12 -05:00
|
|
|
let resource = state
|
|
|
|
.borrow_mut()
|
|
|
|
.resource_table
|
|
|
|
.get::<SignalStreamResource>(rid)
|
|
|
|
.ok_or_else(bad_resource_id)?;
|
|
|
|
let cancel = RcRef::map(&resource, |r| &r.cancel);
|
|
|
|
let mut signal = RcRef::map(&resource, |r| &r.signal).borrow_mut().await;
|
|
|
|
|
|
|
|
match signal.recv().or_cancel(cancel).await {
|
2021-04-05 12:40:24 -04:00
|
|
|
Ok(result) => Ok(result.is_none()),
|
|
|
|
Err(_) => Ok(true),
|
2020-12-16 11:14:12 -05:00
|
|
|
}
|
2020-01-24 08:15:31 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
#[cfg(unix)]
|
|
|
|
pub fn op_signal_unbind(
|
2020-09-10 09:57:45 -04:00
|
|
|
state: &mut OpState,
|
2021-04-05 12:40:24 -04:00
|
|
|
rid: ResourceId,
|
2021-04-02 09:47:57 -04:00
|
|
|
_zero_copy: Option<ZeroCopyBuf>,
|
2021-04-05 12:40:24 -04:00
|
|
|
) -> Result<(), AnyError> {
|
2020-09-26 14:26:51 -04:00
|
|
|
super::check_unstable(state, "Deno.signal");
|
2020-09-10 09:57:45 -04:00
|
|
|
state
|
|
|
|
.resource_table
|
2020-02-23 14:51:29 -05:00
|
|
|
.close(rid)
|
2020-09-14 12:48:57 -04:00
|
|
|
.ok_or_else(bad_resource_id)?;
|
2021-04-05 12:40:24 -04:00
|
|
|
Ok(())
|
2020-01-24 08:15:31 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
#[cfg(not(unix))]
|
|
|
|
pub fn op_signal_bind(
|
2020-09-10 09:57:45 -04:00
|
|
|
_state: &mut OpState,
|
2021-04-05 12:40:24 -04:00
|
|
|
_args: (),
|
2021-04-02 09:47:57 -04:00
|
|
|
_zero_copy: Option<ZeroCopyBuf>,
|
2021-04-05 12:40:24 -04:00
|
|
|
) -> Result<(), AnyError> {
|
2020-01-24 08:15:31 -05:00
|
|
|
unimplemented!();
|
|
|
|
}
|
|
|
|
|
|
|
|
#[cfg(not(unix))]
|
|
|
|
fn op_signal_unbind(
|
2020-09-10 09:57:45 -04:00
|
|
|
_state: &mut OpState,
|
2021-04-05 12:40:24 -04:00
|
|
|
_args: (),
|
2021-04-02 09:47:57 -04:00
|
|
|
_zero_copy: Option<ZeroCopyBuf>,
|
2021-04-05 12:40:24 -04:00
|
|
|
) -> Result<(), AnyError> {
|
2020-01-24 08:15:31 -05:00
|
|
|
unimplemented!();
|
|
|
|
}
|
|
|
|
|
|
|
|
#[cfg(not(unix))]
|
2020-08-28 11:08:24 -04:00
|
|
|
async fn op_signal_poll(
|
2020-09-10 09:57:45 -04:00
|
|
|
_state: Rc<RefCell<OpState>>,
|
2021-04-05 12:40:24 -04:00
|
|
|
_args: (),
|
2021-04-02 09:47:57 -04:00
|
|
|
_zero_copy: Option<ZeroCopyBuf>,
|
2021-04-05 12:40:24 -04:00
|
|
|
) -> Result<(), AnyError> {
|
2020-01-24 08:15:31 -05:00
|
|
|
unimplemented!();
|
|
|
|
}
|