mirror of
https://github.com/urbit/ares.git
synced 2024-11-23 00:25:49 +03:00
Add SIGINT handler
This commit is contained in:
parent
0072e09a85
commit
ae674c1372
@ -35,7 +35,7 @@
|
|||||||
:: %mean hint
|
:: %mean hint
|
||||||
~_ [%leaf "I am a %mean hint via ~_ from +wack"]
|
~_ [%leaf "I am a %mean hint via ~_ from +wack"]
|
||||||
:: %hela hint
|
:: %hela hint
|
||||||
:: ~> %hela
|
~> %hela
|
||||||
:: %memo hint
|
:: %memo hint
|
||||||
~+
|
~+
|
||||||
?~ m +(n)
|
?~ m +(n)
|
||||||
@ -47,13 +47,23 @@
|
|||||||
!.
|
!.
|
||||||
|= [m=@ud n=@ud]
|
|= [m=@ud n=@ud]
|
||||||
:: %hela hint
|
:: %hela hint
|
||||||
:: ~> %hela
|
~> %hela
|
||||||
:: %memo hint
|
:: %memo hint
|
||||||
~+
|
~+
|
||||||
?~ m +(n)
|
?~ m +(n)
|
||||||
?~ n
|
?~ n
|
||||||
(wack (dec m) 1)
|
(wack (dec m) 1)
|
||||||
(wack (dec m) $(n (dec n)))
|
(wack (dec m) $(n (dec n)))
|
||||||
|
++ slow
|
||||||
|
|= x=@ud
|
||||||
|
!:
|
||||||
|
(slow-help x 0)
|
||||||
|
++ slow-help
|
||||||
|
|= [x=@ud y=@ud]
|
||||||
|
!.
|
||||||
|
?: .= x y
|
||||||
|
x
|
||||||
|
$(y .+(y))
|
||||||
-- =>
|
-- =>
|
||||||
::
|
::
|
||||||
|%
|
|%
|
||||||
@ -65,19 +75,23 @@
|
|||||||
^- ^
|
^- ^
|
||||||
::
|
::
|
||||||
?. ?=(?(%crud %wack %wyrd) p.card.ovo)
|
?. ?=(?(%crud %wack %wyrd) p.card.ovo)
|
||||||
~> %slog.[0 leaf+(scow %ud (wack 1 1))]
|
~> %slog.[0 leaf+(scow %ud (slow (bex 23)))]
|
||||||
[~ ..poke]
|
[~ ..poke]
|
||||||
::
|
::
|
||||||
=/ buz
|
=/ buz
|
||||||
~> %mean.'pith: bad wasp'
|
~> %mean.'pith: bad wasp'
|
||||||
;;(wasp card.ovo)
|
;;(wasp card.ovo)
|
||||||
?+ -.buz
|
?+ -.buz
|
||||||
~> %slog.[0 leaf+"default $wasp"]
|
~> %slog.[0 leaf+(scow %ud (wack 1 1))]
|
||||||
[~ ..poke]
|
[~ ..poke]
|
||||||
::
|
::
|
||||||
%crud
|
%crud
|
||||||
~> %slog.[0 goof.buz]
|
=/ tang tang.goof.buz
|
||||||
|
|-
|
||||||
|
?~ tang
|
||||||
[~ ..poke]
|
[~ ..poke]
|
||||||
|
~> %slog.[0 -.tang]
|
||||||
|
$(tang +.tang)
|
||||||
==
|
==
|
||||||
--
|
--
|
||||||
::
|
::
|
||||||
|
21
rust/ares/Cargo.lock
generated
21
rust/ares/Cargo.lock
generated
@ -20,11 +20,13 @@ dependencies = [
|
|||||||
"either",
|
"either",
|
||||||
"ibig",
|
"ibig",
|
||||||
"intmap",
|
"intmap",
|
||||||
|
"lazy_static",
|
||||||
"libc",
|
"libc",
|
||||||
"memmap",
|
"memmap",
|
||||||
"murmur3",
|
"murmur3",
|
||||||
"num-derive",
|
"num-derive",
|
||||||
"num-traits",
|
"num-traits",
|
||||||
|
"signal-hook",
|
||||||
"static_assertions",
|
"static_assertions",
|
||||||
]
|
]
|
||||||
|
|
||||||
@ -569,6 +571,25 @@ dependencies = [
|
|||||||
"serde",
|
"serde",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "signal-hook"
|
||||||
|
version = "0.3.17"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "8621587d4798caf8eb44879d42e56b9a93ea5dcd315a6487c357130095b62801"
|
||||||
|
dependencies = [
|
||||||
|
"libc",
|
||||||
|
"signal-hook-registry",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "signal-hook-registry"
|
||||||
|
version = "1.4.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "d8229b473baa5980ac72ef434c4415e70c4b5e71b423043adb4ba059f89c99a1"
|
||||||
|
dependencies = [
|
||||||
|
"libc",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "static_assertions"
|
name = "static_assertions"
|
||||||
version = "1.1.0"
|
version = "1.1.0"
|
||||||
|
@ -11,18 +11,20 @@ edition = "2018"
|
|||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
ares_macros = { path = "../ares_macros" }
|
ares_macros = { path = "../ares_macros" }
|
||||||
bitvec = "1.0.0"
|
|
||||||
either = "1.9.0"
|
|
||||||
libc = "0.2.126"
|
|
||||||
murmur3 = { git = "https://github.com/tloncorp/murmur3", rev = "7878a0f" }
|
|
||||||
memmap = "0.7.0"
|
|
||||||
intmap = "1.1.0"
|
|
||||||
num-traits = "0.2"
|
|
||||||
num-derive = "0.3"
|
|
||||||
criterion = "0.4"
|
|
||||||
static_assertions = "1.1.0"
|
|
||||||
ibig = { path = "../ibig-rs" }
|
|
||||||
assert_no_alloc = "1.1.2"
|
assert_no_alloc = "1.1.2"
|
||||||
|
bitvec = "1.0.0"
|
||||||
|
criterion = "0.4"
|
||||||
|
either = "1.9.0"
|
||||||
|
ibig = { path = "../ibig-rs" }
|
||||||
|
intmap = "1.1.0"
|
||||||
|
lazy_static = "1.4.0"
|
||||||
|
libc = "0.2.126"
|
||||||
|
memmap = "0.7.0"
|
||||||
|
murmur3 = { git = "https://github.com/tloncorp/murmur3", rev = "7878a0f" }
|
||||||
|
num-derive = "0.3"
|
||||||
|
num-traits = "0.2"
|
||||||
|
signal-hook = "0.3"
|
||||||
|
static_assertions = "1.1.0"
|
||||||
|
|
||||||
[build-dependencies]
|
[build-dependencies]
|
||||||
cc = "1.0.79"
|
cc = "1.0.79"
|
||||||
|
@ -7,10 +7,13 @@ use crate::mem::NockStack;
|
|||||||
use crate::newt::Newt;
|
use crate::newt::Newt;
|
||||||
use crate::noun;
|
use crate::noun;
|
||||||
use crate::noun::{tape, Atom, Cell, IndirectAtom, Noun, Slots, D, T};
|
use crate::noun::{tape, Atom, Cell, IndirectAtom, Noun, Slots, D, T};
|
||||||
|
use crate::serf::TERMINATOR;
|
||||||
use ares_macros::tas;
|
use ares_macros::tas;
|
||||||
use assert_no_alloc::assert_no_alloc;
|
use assert_no_alloc::assert_no_alloc;
|
||||||
use bitvec::prelude::{BitSlice, Lsb0};
|
use bitvec::prelude::{BitSlice, Lsb0};
|
||||||
use either::Either::*;
|
use either::Either::*;
|
||||||
|
use std::sync::atomic::Ordering;
|
||||||
|
use std::sync::Arc;
|
||||||
|
|
||||||
crate::gdb!();
|
crate::gdb!();
|
||||||
|
|
||||||
@ -265,10 +268,12 @@ pub fn interpret(
|
|||||||
mut subject: Noun,
|
mut subject: Noun,
|
||||||
formula: Noun,
|
formula: Noun,
|
||||||
) -> Result<Noun, Tone> {
|
) -> Result<Noun, Tone> {
|
||||||
|
let terminator = Arc::clone(&TERMINATOR);
|
||||||
let mut res: Noun = D(0);
|
let mut res: Noun = D(0);
|
||||||
let mut cache = Hamt::<Noun>::new();
|
let mut cache = Hamt::<Noun>::new();
|
||||||
// XX: Should this come after initial frame_push()?
|
// XX: Should this come after initial frame_push()?
|
||||||
let virtual_frame = stack.get_frame_pointer();
|
let virtual_frame = stack.get_frame_pointer();
|
||||||
|
let virtual_trace = stack.get_mean_stack();
|
||||||
|
|
||||||
stack.frame_push(0);
|
stack.frame_push(0);
|
||||||
unsafe {
|
unsafe {
|
||||||
@ -323,6 +328,7 @@ pub fn interpret(
|
|||||||
res = noun;
|
res = noun;
|
||||||
stack.pop::<NockWork>();
|
stack.pop::<NockWork>();
|
||||||
} else {
|
} else {
|
||||||
|
// Axis invalid for input Noun
|
||||||
break Err(NockErr::Deterministic);
|
break Err(NockErr::Deterministic);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -330,7 +336,12 @@ pub fn interpret(
|
|||||||
res = once.noun;
|
res = once.noun;
|
||||||
stack.pop::<NockWork>();
|
stack.pop::<NockWork>();
|
||||||
}
|
}
|
||||||
NockWork::Work2(mut vale) => match vale.todo {
|
NockWork::Work2(mut vale) => {
|
||||||
|
if (*terminator).load(Ordering::Relaxed) {
|
||||||
|
break Err(NockErr::NonDeterministic);
|
||||||
|
}
|
||||||
|
|
||||||
|
match vale.todo {
|
||||||
Todo2::ComputeSubject => {
|
Todo2::ComputeSubject => {
|
||||||
vale.todo = Todo2::ComputeFormula;
|
vale.todo = Todo2::ComputeFormula;
|
||||||
*stack.top() = NockWork::Work2(vale);
|
*stack.top() = NockWork::Work2(vale);
|
||||||
@ -360,7 +371,8 @@ pub fn interpret(
|
|||||||
subject = vale.subject;
|
subject = vale.subject;
|
||||||
stack.pop::<NockWork>();
|
stack.pop::<NockWork>();
|
||||||
}
|
}
|
||||||
},
|
}
|
||||||
|
}
|
||||||
NockWork::Work3(mut thee) => match thee.todo {
|
NockWork::Work3(mut thee) => match thee.todo {
|
||||||
Todo3::ComputeChild => {
|
Todo3::ComputeChild => {
|
||||||
thee.todo = Todo3::ComputeType;
|
thee.todo = Todo3::ComputeType;
|
||||||
@ -481,7 +493,12 @@ pub fn interpret(
|
|||||||
stack.pop::<NockWork>();
|
stack.pop::<NockWork>();
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
NockWork::Work9(mut kale) => match kale.todo {
|
NockWork::Work9(mut kale) => {
|
||||||
|
if (*terminator).load(Ordering::Relaxed) {
|
||||||
|
break Err(NockErr::NonDeterministic);
|
||||||
|
}
|
||||||
|
|
||||||
|
match kale.todo {
|
||||||
Todo9::ComputeCore => {
|
Todo9::ComputeCore => {
|
||||||
kale.todo = Todo9::ComputeResult;
|
kale.todo = Todo9::ComputeResult;
|
||||||
*stack.top() = NockWork::Work9(kale);
|
*stack.top() = NockWork::Work9(kale);
|
||||||
@ -511,7 +528,8 @@ pub fn interpret(
|
|||||||
subject = kale.core;
|
subject = kale.core;
|
||||||
stack.pop::<NockWork>();
|
stack.pop::<NockWork>();
|
||||||
}
|
}
|
||||||
},
|
}
|
||||||
|
}
|
||||||
NockWork::Work10(mut diet) => {
|
NockWork::Work10(mut diet) => {
|
||||||
match diet.todo {
|
match diet.todo {
|
||||||
Todo10::ComputeTree => {
|
Todo10::ComputeTree => {
|
||||||
@ -623,7 +641,13 @@ pub fn interpret(
|
|||||||
|
|
||||||
match nock {
|
match nock {
|
||||||
Ok(res) => Ok(res),
|
Ok(res) => Ok(res),
|
||||||
Err(err) => Err(exit_early(stack, &mut cache, virtual_frame, err)),
|
Err(err) => Err(exit_early(
|
||||||
|
stack,
|
||||||
|
&mut cache,
|
||||||
|
virtual_frame,
|
||||||
|
virtual_trace,
|
||||||
|
err,
|
||||||
|
)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -830,6 +854,7 @@ pub fn exit_early(
|
|||||||
stack: &mut NockStack,
|
stack: &mut NockStack,
|
||||||
cache: &mut Hamt<Noun>,
|
cache: &mut Hamt<Noun>,
|
||||||
virtual_frame: *const u64,
|
virtual_frame: *const u64,
|
||||||
|
virtual_trace: Noun,
|
||||||
error: NockErr,
|
error: NockErr,
|
||||||
) -> Tone {
|
) -> Tone {
|
||||||
let mut trace = stack.get_mean_stack();
|
let mut trace = stack.get_mean_stack();
|
||||||
@ -839,6 +864,9 @@ pub fn exit_early(
|
|||||||
stack.preserve(cache);
|
stack.preserve(cache);
|
||||||
stack.frame_pop();
|
stack.frame_pop();
|
||||||
}
|
}
|
||||||
|
while !stack.get_mean_stack().raw_equals(virtual_trace) {
|
||||||
|
stack.trace_pop();
|
||||||
|
}
|
||||||
};
|
};
|
||||||
Tone::Error(error, trace)
|
Tone::Error(error, trace)
|
||||||
}
|
}
|
||||||
@ -1026,6 +1054,11 @@ fn match_hint_pre_nock(
|
|||||||
Ok(None)
|
Ok(None)
|
||||||
}
|
}
|
||||||
tas!(b"hand") | tas!(b"hunk") | tas!(b"lose") | tas!(b"mean") | tas!(b"spot") => {
|
tas!(b"hand") | tas!(b"hunk") | tas!(b"lose") | tas!(b"mean") | tas!(b"spot") => {
|
||||||
|
let terminator = Arc::clone(&TERMINATOR);
|
||||||
|
if (*terminator).load(Ordering::Relaxed) {
|
||||||
|
return Err(NockErr::NonDeterministic);
|
||||||
|
}
|
||||||
|
|
||||||
let trace = T(stack, &[tag.as_noun(), res.ok_or(NockErr::Deterministic)?]);
|
let trace = T(stack, &[tag.as_noun(), res.ok_or(NockErr::Deterministic)?]);
|
||||||
stack.trace_push(trace);
|
stack.trace_push(trace);
|
||||||
Ok(None)
|
Ok(None)
|
||||||
|
@ -23,6 +23,7 @@ pub fn jet_mink(
|
|||||||
let v_formula = slot(arg, 5)?;
|
let v_formula = slot(arg, 5)?;
|
||||||
let _scry = slot(arg, 3)?;
|
let _scry = slot(arg, 3)?;
|
||||||
|
|
||||||
|
// XX: no partial traces; all of our traces go down to the "home road"
|
||||||
match interpret(stack, newt, v_subject, v_formula) {
|
match interpret(stack, newt, v_subject, v_formula) {
|
||||||
Ok(res) => Ok(T(stack, &[D(0), res])),
|
Ok(res) => Ok(T(stack, &[D(0), res])),
|
||||||
Err(err) => match err {
|
Err(err) => match err {
|
||||||
@ -61,11 +62,6 @@ pub mod util {
|
|||||||
let tag = tone.head().as_direct()?;
|
let tag = tone.head().as_direct()?;
|
||||||
let original_list = tone.tail();
|
let original_list = tone.tail();
|
||||||
|
|
||||||
// if tag.data() < 2 {
|
|
||||||
// return Ok(tone);
|
|
||||||
// } else if tag.data() > 2 {
|
|
||||||
// return Err(JetErr::Deterministic);
|
|
||||||
// }
|
|
||||||
match tag.data() {
|
match tag.data() {
|
||||||
x if x < 2 => return Ok(tone),
|
x if x < 2 => return Ok(tone),
|
||||||
x if x > 2 => return Err(JetErr::Deterministic),
|
x if x > 2 => return Err(JetErr::Deterministic),
|
||||||
@ -260,6 +256,21 @@ pub mod util {
|
|||||||
mod tests {
|
mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
use crate::jets::util::test::{assert_jet, init_stack};
|
use crate::jets::util::test::{assert_jet, init_stack};
|
||||||
|
use crate::serf::TERMINATOR;
|
||||||
|
use std::sync::Arc;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn init() {
|
||||||
|
// This needs to be done because TERMINATOR is lazy allocated, and if you don't
|
||||||
|
// do it before you call the unit tests it'll get allocated on the Rust heap
|
||||||
|
// inside an assert_no_alloc block.
|
||||||
|
//
|
||||||
|
// Also Rust has no primitive for pre-test setup / post-test teardown, so we
|
||||||
|
// do it in a test that we rely on being called before any other in this file,
|
||||||
|
// since we're already using single-threaded test mode to avoid race conditions
|
||||||
|
// (because Rust doesn't support test order dependencies either).
|
||||||
|
let _ = Arc::clone(&TERMINATOR);
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_mink_success() {
|
fn test_mink_success() {
|
||||||
|
@ -1,5 +1,7 @@
|
|||||||
extern crate num_derive;
|
extern crate num_derive;
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
|
extern crate lazy_static;
|
||||||
|
#[macro_use]
|
||||||
extern crate static_assertions;
|
extern crate static_assertions;
|
||||||
pub mod interpreter;
|
pub mod interpreter;
|
||||||
pub mod jets;
|
pub mod jets;
|
||||||
|
@ -7,12 +7,14 @@ use crate::newt::Newt;
|
|||||||
use crate::noun::{Cell, Noun, Slots, D, T};
|
use crate::noun::{Cell, Noun, Slots, D, T};
|
||||||
use crate::snapshot::{self, Snapshot};
|
use crate::snapshot::{self, Snapshot};
|
||||||
use ares_macros::tas;
|
use ares_macros::tas;
|
||||||
|
use signal_hook;
|
||||||
|
use signal_hook::consts::SIGINT;
|
||||||
use std::fs::create_dir_all;
|
use std::fs::create_dir_all;
|
||||||
use std::io;
|
use std::io;
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
use std::result::Result;
|
use std::result::Result;
|
||||||
use std::thread::sleep;
|
use std::sync::atomic::{AtomicBool, Ordering};
|
||||||
use std::time;
|
use std::sync::Arc;
|
||||||
|
|
||||||
crate::gdb!();
|
crate::gdb!();
|
||||||
|
|
||||||
@ -23,12 +25,20 @@ const POKE_AXIS: u64 = 23;
|
|||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
const WISH_AXIS: u64 = 10;
|
const WISH_AXIS: u64 = 10;
|
||||||
|
|
||||||
|
// Necessary because Arc::new is not const
|
||||||
|
lazy_static! {
|
||||||
|
pub static ref TERMINATOR: Arc<AtomicBool> = Arc::new(AtomicBool::new(false));
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This is suitable for talking to the king process. To test, change the arg_c[0] line in
|
* This is suitable for talking to the king process. To test, change the arg_c[0] line in
|
||||||
* u3_lord_init in vere to point at this binary and start vere like normal.
|
* u3_lord_init in vere to point at this binary and start vere like normal.
|
||||||
*/
|
*/
|
||||||
pub fn serf() -> io::Result<()> {
|
pub fn serf() -> io::Result<()> {
|
||||||
sleep(time::Duration::from_secs(0));
|
// Register SIGTERM signal hook to set flag first time, shutdown second time
|
||||||
|
signal_hook::flag::register_conditional_shutdown(SIGINT, 1, Arc::clone(&TERMINATOR))?;
|
||||||
|
signal_hook::flag::register(SIGINT, Arc::clone(&TERMINATOR))?;
|
||||||
|
|
||||||
let snap_path_string = std::env::args()
|
let snap_path_string = std::env::args()
|
||||||
.nth(2)
|
.nth(2)
|
||||||
.ok_or(io::Error::new(io::ErrorKind::Other, "no pier path"))?;
|
.ok_or(io::Error::new(io::ErrorKind::Other, "no pier path"))?;
|
||||||
@ -157,7 +167,9 @@ pub fn serf() -> io::Result<()> {
|
|||||||
// TODO: on decryption failure in aes_siv, should bail as fast as
|
// TODO: on decryption failure in aes_siv, should bail as fast as
|
||||||
// possible, without rendering stack trace or injecting crud event. See
|
// possible, without rendering stack trace or injecting crud event. See
|
||||||
// c3__evil in vere.
|
// c3__evil in vere.
|
||||||
//
|
|
||||||
|
clear_interrupt();
|
||||||
|
|
||||||
// crud = [+(now) [%$ %arvo ~] [%crud goof ovo]]
|
// crud = [+(now) [%$ %arvo ~] [%crud goof ovo]]
|
||||||
let job_cell = job.as_cell().expect("serf: work: job not a cell");
|
let job_cell = job.as_cell().expect("serf: work: job not a cell");
|
||||||
let now = inc(
|
let now = inc(
|
||||||
@ -197,6 +209,8 @@ pub fn serf() -> io::Result<()> {
|
|||||||
}
|
}
|
||||||
_ => panic!("got message with unknown tag {}", tag),
|
_ => panic!("got message with unknown tag {}", tag),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
clear_interrupt();
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
@ -231,8 +245,9 @@ pub fn soft(
|
|||||||
let tang = mook(stack, &mut Some(newt), tone, false)
|
let tang = mook(stack, &mut Some(newt), tone, false)
|
||||||
.expect("serf: soft: +mook crashed on bail")
|
.expect("serf: soft: +mook crashed on bail")
|
||||||
.tail();
|
.tail();
|
||||||
// TODO: shouldn't always be exit, look at the comment by u3m_bail to see how vere
|
// XX: noun::Tone or noun::NockErr should use a bail enum system similar to u3m_bail motes;
|
||||||
// handles this
|
// might be able to replace NockErr with mote and map determinism to individual motes;
|
||||||
|
// for, always set to %exit
|
||||||
let goof = T(stack, &[D(tas!(b"exit")), tang]);
|
let goof = T(stack, &[D(tas!(b"exit")), tang]);
|
||||||
Err(goof)
|
Err(goof)
|
||||||
}
|
}
|
||||||
@ -244,3 +259,7 @@ fn slot(noun: Noun, axis: u64) -> io::Result<Noun> {
|
|||||||
noun.slot(axis)
|
noun.slot(axis)
|
||||||
.map_err(|_e| io::Error::new(io::ErrorKind::InvalidInput, "Bad axis"))
|
.map_err(|_e| io::Error::new(io::ErrorKind::InvalidInput, "Bad axis"))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn clear_interrupt() {
|
||||||
|
(*TERMINATOR).store(false, Ordering::Relaxed);
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user