changeset 29292:eb1e10abe9d5

use method in interpreter class to interrupt interpreter execution in GUI * interpreter.h, interpreter.cc (interpreter::interrupt): New function. * interpreter-qobject.h, interpreter-qobject.cc (interpreter_qobject::interrupt): New function. * octave-qobject.h, octave-qobject.cc (octave_qobject::interpreter_interrupt): New slot. * terminal-dock-widget.h, terminal-dock-widget.cc (): (terminal_dock_widget::terminal_dock_widget): Connect m_terminal interrupt_signal to oct_qobj interpreter_interrupt slot. (terminal_dock_widget::terminal_interrupt): Delete slot. Action is now performed in interpreter::interrupt method. (terminal_dock_widget::interrupt_signal): Delete signal.
author John W. Eaton <jwe@octave.org>
date Tue, 12 Jan 2021 21:01:42 -0500
parents 21ddf8439943
children 8784f20b9b8c
files libgui/src/interpreter-qobject.cc libgui/src/interpreter-qobject.h libgui/src/octave-qobject.cc libgui/src/octave-qobject.h libgui/src/terminal-dock-widget.cc libgui/src/terminal-dock-widget.h libinterp/corefcn/interpreter.cc libinterp/corefcn/interpreter.h
diffstat 8 files changed, 52 insertions(+), 25 deletions(-) [+]
line wrap: on
line diff
--- a/libgui/src/interpreter-qobject.cc	Mon Jan 11 00:46:17 2021 -0500
+++ b/libgui/src/interpreter-qobject.cc	Tue Jan 12 21:01:42 2021 -0500
@@ -142,6 +142,14 @@
     evmgr.post_event (meth);
   }
 
+  void interpreter_qobject::interrupt (void)
+  {
+    if (! m_interpreter)
+      return;
+
+    m_interpreter->interrupt ();
+  }
+
   qt_interpreter_events * interpreter_qobject::qt_link (void)
   {
     return m_octave_qobj.qt_link ();
--- a/libgui/src/interpreter-qobject.h	Mon Jan 11 00:46:17 2021 -0500
+++ b/libgui/src/interpreter-qobject.h	Tue Jan 12 21:01:42 2021 -0500
@@ -52,6 +52,8 @@
 
     void interpreter_event (const meth_callback& meth);
 
+    void interrupt (void);
+
   signals:
 
     void ready (void);
--- a/libgui/src/octave-qobject.cc	Mon Jan 11 00:46:17 2021 -0500
+++ b/libgui/src/octave-qobject.cc	Tue Jan 12 21:01:42 2021 -0500
@@ -362,6 +362,14 @@
     m_interpreter_qobj->interpreter_event (meth);
   }
 
+  void base_qobject::interpreter_interrupt (void)
+  {
+    // The following is a direct function call across threads.  It works
+    // because the it is accessing a thread-safe function.
+
+    m_interpreter_qobj->interrupt ();
+  }
+
   void base_qobject::copy_image_to_clipboard (const QString& file,
                                               bool remove_file)
   {
--- a/libgui/src/octave-qobject.h	Mon Jan 11 00:46:17 2021 -0500
+++ b/libgui/src/octave-qobject.h	Tue Jan 12 21:01:42 2021 -0500
@@ -152,6 +152,8 @@
 
     void interpreter_event (const meth_callback& meth);
 
+    void interpreter_interrupt (void);
+
     void copy_image_to_clipboard (const QString& file, bool remove_file);
 
   protected:
--- a/libgui/src/terminal-dock-widget.cc	Mon Jan 11 00:46:17 2021 -0500
+++ b/libgui/src/terminal-dock-widget.cc	Tue Jan 12 21:01:42 2021 -0500
@@ -56,7 +56,7 @@
     setFocusProxy (m_terminal);
 
     connect (m_terminal, SIGNAL (interrupt_signal (void)),
-             this, SLOT (terminal_interrupt (void)));
+             &oct_qobj, SLOT (interpreter_interrupt (void)));
 
     // Connect the visibility signal to the terminal for dis-/enabling timers
     connect (this, SIGNAL (visibilityChanged (bool)),
@@ -99,20 +99,4 @@
 
     return w->hasFocus ();
   }
-
-  void terminal_dock_widget::terminal_interrupt (void)
-  {
-    // FIXME: Protect with mutex?
-
-    octave_signal_caught = 1;
-    octave_interrupt_state++;
-
-    // Send SIGINT to all other processes in our process group.
-    // This is needed to interrupt calls to system (), for example.
-
-    int sigint;
-    octave_get_sig_number ("SIGINT", &sigint);
-
-    octave_kill_wrapper (0, sigint);
-  }
 }
--- a/libgui/src/terminal-dock-widget.h	Mon Jan 11 00:46:17 2021 -0500
+++ b/libgui/src/terminal-dock-widget.h	Tue Jan 12 21:01:42 2021 -0500
@@ -48,14 +48,6 @@
 
     bool has_focus (void) const;
 
-  signals:
-
-    void interrupt_signal (void);
-
-  protected slots:
-
-    void terminal_interrupt (void);
-
   private:
 
     QTerminal *m_terminal;
--- a/libinterp/corefcn/interpreter.cc	Mon Jan 11 00:46:17 2021 -0500
+++ b/libinterp/corefcn/interpreter.cc	Tue Jan 12 21:01:42 2021 -0500
@@ -42,6 +42,7 @@
 #include "lo-blas-proto.h"
 #include "lo-error.h"
 #include "oct-env.h"
+#include "quit.h"
 #include "str-vec.h"
 #include "signal-wrappers.h"
 #include "unistd-wrappers.h"
@@ -1703,6 +1704,34 @@
     return m_evaluator.autoloaded_functions ();
   }
 
+  // May be used to send an interrupt signal to the the interpreter from
+  // another thread (for example, the GUI).
+
+  void interpreter::interrupt (void)
+  {
+    static int sigint = 0;
+    static bool first = true;
+
+    if (first)
+      {
+        octave_get_sig_number ("SIGINT", &sigint);
+        first = false;
+      }
+
+    // Send SIGINT to all other processes in our process group.  The
+    // signal handler for SIGINT will set a global variable indicating
+    // an interrupt has happened.  That variable is checked in many
+    // places in the Octave interpreter and eventually results in an
+    // interrupt_exception being thrown.  Finally, that exception is
+    // caught and returns control to one of the read-eval-print loops or
+    // to the server loop.  We use a signal instead of just setting the
+    // global variables here so that we will probably send interrupt
+    // signals to any subprocesses as well as interrupt execution of the
+    // interpreter.
+
+    octave_kill_wrapper (0, sigint);
+  }
+
   void interpreter::handle_exception (const execution_exception& ee)
   {
     m_error_system.save_exception (ee);
--- a/libinterp/corefcn/interpreter.h	Mon Jan 11 00:46:17 2021 -0500
+++ b/libinterp/corefcn/interpreter.h	Tue Jan 12 21:01:42 2021 -0500
@@ -467,6 +467,8 @@
 
     std::list<std::string> autoloaded_functions (void) const;
 
+    void interrupt (void);
+
     void handle_exception (const execution_exception& ee);
 
     void recover_from_exception (void);