diff liboctave/util/f77-fcn.h @ 24520:c5c11b07598a

refactor signal handling (bug #52757) Given that any library code may now be multi-threaded it is not likely to be save to jump out of a signal handler when executing a call to a library function. We are almost assured to fail if the call to siglongjmp occurs in a different thread from the corresponding call to sigsetjmp. Similarly, we should avoid calling the interrupt signal handler function in an arbitrary thread. This is already done by default on Windows systems. On Posix systems, we now set up a separate thread to handle asynchronous signals (not just SIGINT). We no longer attempt to jump out of the signal handler. Instead, we only set global status variables and respond to them in octave_quit. This means that some external library functions are no longer interruptible. If that becomes important, then we will need to look for other alternatives such as setting up worker threads that can be canceled when a SIGINT is detected. * sighandlers.cc (interrupt_manager, base_interrupt_manager, w32_interrupt_manager, posix_interrupt_manager): Delete classes and all uses. (respond_to_pending_signals): Rename from signal_handler. Change all uses. Take action on more signals. (generic_sig_handler): Simply record that a signal was caught and add it to the list of caught signals. (deadly_sig_handler): New function. (fpe_sig_handler): Rename from sigfpe_handler. Don't make specific to Alpha systems. Simply warn that an exception has occurred. (sigint_handler): Simply record that an interrupt signal was caught. (sigterm_handler, sigpipe_handler): Delete. (install_signal_handlers): Rework actions for various signals. (Vsigquit_dumps_octave_core): New static variable. (Fsigquit_dumps_octave_core): New function. * io.txi: Document sigquit_dumps_octave_core. * f77-fcn.h, f77-fcn.c (xSTRINGIZE, STRINGIZE, F77_XFCN_ERROR): Delete macros. (F77_XFCN): Don't do setjmp/longjmp exception handling. (f77_exception_encountered): Delete global variable. (XSTOPX): Don't set f77_exception_encountered. If message is empty, report "unknown error in fortran subroutine". * eigs-base.cc, gsvd.cc: Delete all direct uses of f77_exception_encountered. * liboctave/util/f77-extern.cc: Delete file. * liboctave/util/module.mk: Update. * cmd-edit.h, cmd-edit.cc (command_editor::interrupt_exception): New class. (command_editor::handle_interrupt_signal): New static function. (command_editor::do_handle_interrupt_signal): New virtual function. (command_editor::event_hanlder): Call handle_interrupt_signal if octave_interrupt_state is not zero. (command_editor::instance_ok): Set event hook here. (command_editor::add_event_hook): Not here. (command_editor::remove_event_hook): Never remove event hook. (gnu_readline::do_handle_interrupt_signal): New function. (gnu_readline::do_readline): Retry if an interrupt exception occurs inside readline. * oct-rl-edit.h, oct-rl-edit.c (octave_rl_recover_from_interrupt): New function. * quit.h, cquit.c (current_context, octave_save_current_context, octave_restore_current_context, octave_jump_to_enclosing_context, octave_interrupt_immediately, octave_jmp_buf): Delete. * quit.h: Don't include <setjmp.h> (octave_set_current_context): Delete macro. (octave_exit_exception_status, octave_exit_exception_safe_to_return): Mark as deprecated. (BEGIN_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE_1): Delete. (BEGIN_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE_2): Delete. (BEGIN_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE, END_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE): Define to only create a dummy do-while scope. (BEGIN_INTERRUPT_WITH_EXCEPTIONS, END_INTERRUPT_WITH_EXCEPTIONS): Define to only create a dummy scope. * interpreter.cc (interpreter::recover_from_exception): Don't reset octave_interrupt_immediately. * main-cli.cc (main): Call octave_block_async_signals. * main.in.cc (main): Call octave_block_async_signals initially. Only in install signal handlers and unblock signals if starting managed subprocess. * main-window.cc (octave_interpreter::executed): Don't unblock interrupt signals. * signal-wrappers.h, signal-wrappers.c (signal_watcher, octave_async_signals, block_or_unblock_signal_by_name): New static functions. (octave_set_default_signal_handler, octave_set_default_signal_handler_by_name, octave_block_signal_by_name, octave_unblock_signal_by_name, octave_create_interrupt_watcher_thread, octave_block_async_signals, octave_unblock_async_signals): New functions. (octave_block_interrupt_signal, octave_unblock_interrupt_signal): Treat SIGBREAK as an interrupt signal. (octave_block_child): Also handle SIGCLD the same as SIGCHLD. (print_sigset, print_sigmask): New static functions. (octave_show_sigmask): New function.
author John W. Eaton <jwe@octave.org>
date Wed, 03 Jan 2018 07:52:11 -0500
parents 58d56f52d50a
children 194eb4bd202b
line wrap: on
line diff
--- a/liboctave/util/f77-fcn.h	Thu Jan 04 10:09:23 2018 -0500
+++ b/liboctave/util/f77-fcn.h	Wed Jan 03 07:52:11 2018 -0500
@@ -36,55 +36,13 @@
 extern "C" {
 #endif
 
-/* Hack to stringize macro results. */
-#define xSTRINGIZE(x) #x
-#define STRINGIZE(x) xSTRINGIZE(x)
-
-/* How to print an error for the F77_XFCN macro. */
-
-#define F77_XFCN_ERROR(f, F)                            \
-  (*current_liboctave_error_handler)                    \
-    ("exception encountered in Fortran subroutine %s",  \
-     STRINGIZE (F77_FUNC (f, F)))
-
-/* This can be used to call a Fortran subroutine that might call
-   XSTOPX.  XSTOPX will call lonjmp with current_context.  Once back
-   here, we'll restore the previous context and return.  We may also
-   end up here if an interrupt is processed when the Fortran
-   subroutine is called.  In that case, we resotre the context and go
-   to the top level. */
+/* This macro is obsolete.  */
 
-#define F77_XFCN(f, F, args)                                            \
-  do                                                                    \
-    {                                                                   \
-      octave_jmp_buf saved_context;                                     \
-      sig_atomic_t saved_octave_interrupt_immediately = octave_interrupt_immediately; \
-      f77_exception_encountered = 0;                                    \
-      octave_save_current_context (saved_context);                      \
-      if (octave_set_current_context)                                   \
-        {                                                               \
-          octave_interrupt_immediately = saved_octave_interrupt_immediately; \
-          octave_restore_current_context (saved_context);               \
-          if (f77_exception_encountered)                                \
-            F77_XFCN_ERROR (f, F);                                      \
-          else                                                          \
-            octave_rethrow_exception ();                                \
-        }                                                               \
-      else                                                              \
-        {                                                               \
-          octave_interrupt_immediately++;                               \
-          F77_FUNC (f, F) args;                                         \
-          octave_interrupt_immediately--;                               \
-          octave_restore_current_context (saved_context);               \
-        }                                                               \
-    }                                                                   \
-  while (0)
-
-/* So we can check to see if an exception has occurred. */
-OCTAVE_API extern int f77_exception_encountered;
+#define F77_XFCN(f, F, args)                    \
+  F77_FUNC (f, F) args
 
 #if ! defined (F77_FCN)
-#define F77_FCN(f, F) F77_FUNC (f, F)
+#  define F77_FCN(f, F) F77_FUNC (f, F)
 #endif
 
 /*