return to toplevel from a long running query after receiving Ctrl-C

This commit is contained in:
Mark Thom
2019-09-30 13:27:22 -06:00
parent ecb2cc3518
commit b26c5c213e
4 changed files with 35 additions and 1 deletions

View File

@@ -14,6 +14,9 @@ indexmap = "1.0.2"
dirs = "2.0.2" dirs = "2.0.2"
downcast = "0.10.0" downcast = "0.10.0"
indexmap = "1.0.2" indexmap = "1.0.2"
lazy_static = "1.4.0"
libc = "0.2.62"
nix = "0.15.0"
ordered-float = "0.5.0" ordered-float = "0.5.0"
prolog_parser = "0.8.30" prolog_parser = "0.8.30"
ref_thread_local = "0.0.0" ref_thread_local = "0.0.0"

View File

@@ -2,20 +2,38 @@
extern crate downcast; extern crate downcast;
extern crate indexmap; extern crate indexmap;
#[macro_use] #[macro_use]
extern crate lazy_static;
extern crate libc;
extern crate nix;
#[macro_use]
extern crate prolog_parser; extern crate prolog_parser;
#[macro_use] #[macro_use]
extern crate ref_thread_local; extern crate ref_thread_local;
extern crate termion; extern crate termion;
use nix::sys::signal;
mod prolog; mod prolog;
use prolog::machine::*; use prolog::machine::*;
use prolog::read::*; use prolog::read::*;
use std::sync::atomic::Ordering;
#[cfg(test)] #[cfg(test)]
mod tests; mod tests;
extern fn handle_sigint(signal: libc::c_int) {
let signal = signal::Signal::from_c_int(signal).unwrap();
if signal == signal::Signal::SIGINT {
INTERRUPT.store(true, Ordering::Relaxed);
}
}
fn main() { fn main() {
let mut wam = Machine::new(readline::input_stream()); let handler = signal::SigHandler::Handler(handle_sigint);
unsafe { signal::signal(signal::Signal::SIGINT, handler) }.unwrap();
let mut wam = Machine::new(readline::input_stream());
wam.run_top_level(); wam.run_top_level();
} }

View File

@@ -8,6 +8,7 @@ use prolog::forms::*;
use prolog::heap_iter::*; use prolog::heap_iter::*;
use prolog::heap_print::*; use prolog::heap_print::*;
use prolog::instructions::*; use prolog::instructions::*;
use prolog::machine::INTERRUPT;
use prolog::machine::and_stack::*; use prolog::machine::and_stack::*;
use prolog::machine::attributed_variables::*; use prolog::machine::attributed_variables::*;
use prolog::machine::code_repo::CodeRepo; use prolog::machine::code_repo::CodeRepo;
@@ -3176,6 +3177,13 @@ impl MachineState {
lco: bool, lco: bool,
use_default_cp: bool, use_default_cp: bool,
) { ) {
let interrupted = INTERRUPT.load(std::sync::atomic::Ordering::Relaxed);
if INTERRUPT.compare_and_swap(interrupted, false, std::sync::atomic::Ordering::Relaxed) {
self.fail = true;
return;
}
let mut default_call_policy: Box<CallPolicy> = Box::new(DefaultCallPolicy {}); let mut default_call_policy: Box<CallPolicy> = Box::new(DefaultCallPolicy {});
let call_policy = if use_default_cp { let call_policy = if use_default_cp {
&mut default_call_policy &mut default_call_policy

View File

@@ -46,6 +46,7 @@ use std::io::{stdout, Read, Write};
use std::mem; use std::mem;
use std::ops::Index; use std::ops::Index;
use std::rc::Rc; use std::rc::Rc;
use std::sync::atomic::AtomicBool;
use termion::raw::IntoRawMode; use termion::raw::IntoRawMode;
@@ -54,6 +55,10 @@ pub struct MachinePolicies {
cut_policy: Box<CutPolicy>, cut_policy: Box<CutPolicy>,
} }
lazy_static! {
pub static ref INTERRUPT: AtomicBool = AtomicBool::new(false);
}
impl MachinePolicies { impl MachinePolicies {
#[inline] #[inline]
fn new() -> Self { fn new() -> Self {