]> Repositorios git - scryer-prolog.git/commitdiff
return to toplevel from a long running query after receiving Ctrl-C
authorMark Thom <[email protected]>
Mon, 30 Sep 2019 19:27:22 +0000 (13:27 -0600)
committerMark Thom <[email protected]>
Mon, 30 Sep 2019 19:27:22 +0000 (13:27 -0600)
Cargo.toml
src/main.rs
src/prolog/machine/machine_state_impl.rs
src/prolog/machine/mod.rs

index cf68711d1438bb8a624c794d5cb157b54cde86e9..b9d6df859778f1fa7940310d1a93b44d6907ab2c 100644 (file)
@@ -14,6 +14,9 @@ indexmap = "1.0.2"
 dirs = "2.0.2"
 downcast = "0.10.0"
 indexmap = "1.0.2"
+lazy_static = "1.4.0"
+libc = "0.2.62"
+nix = "0.15.0"
 ordered-float = "0.5.0"
 prolog_parser = "0.8.30"
 ref_thread_local = "0.0.0"
index 4530d63b61501c9492b8598fc5569770a16c3659..304c7e8925a3a06c51e2e4bfcf51d2b168d7ac4f 100644 (file)
@@ -2,20 +2,38 @@
 extern crate downcast;
 extern crate indexmap;
 #[macro_use]
+extern crate lazy_static;
+extern crate libc;
+extern crate nix;
+#[macro_use]
 extern crate prolog_parser;
 #[macro_use]
 extern crate ref_thread_local;
 extern crate termion;
 
+use nix::sys::signal;
+
 mod prolog;
 
 use prolog::machine::*;
 use prolog::read::*;
 
+use std::sync::atomic::Ordering;
+
 #[cfg(test)]
 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() {
-    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();
 }
index ac737a7e3b4ee3b4f10e96dfb39525f2b3de884f..836742bb0f59f2c04ac66f002aab1d360e2f5e9d 100644 (file)
@@ -8,6 +8,7 @@ use prolog::forms::*;
 use prolog::heap_iter::*;
 use prolog::heap_print::*;
 use prolog::instructions::*;
+use prolog::machine::INTERRUPT;
 use prolog::machine::and_stack::*;
 use prolog::machine::attributed_variables::*;
 use prolog::machine::code_repo::CodeRepo;
@@ -3176,6 +3177,13 @@ impl MachineState {
         lco: 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 call_policy = if use_default_cp {
             &mut default_call_policy
index a1a228faeaa93d118d62e6385a0f7b7736cb9146..ece7bbea50a84d75aadca0def5b67f4014cf34cb 100644 (file)
@@ -46,6 +46,7 @@ use std::io::{stdout, Read, Write};
 use std::mem;
 use std::ops::Index;
 use std::rc::Rc;
+use std::sync::atomic::AtomicBool;
 
 use termion::raw::IntoRawMode;
 
@@ -54,6 +55,10 @@ pub struct MachinePolicies {
     cut_policy: Box<CutPolicy>,
 }
 
+lazy_static! {
+    pub static ref INTERRUPT: AtomicBool = AtomicBool::new(false);
+}
+
 impl MachinePolicies {
     #[inline]
     fn new() -> Self {