Mercurial > octave
diff libinterp/corefcn/sighandlers.cc @ 31846:5f0b8101234e
Remove several race conditions with signal handler (bug #61370).
This patch removes several race conditions between the interpreter and the
Ctrl-C signal handler, as described in more detail in bug #61370.
* libinterp/corefcn/sighandlers.h: Make can_interrupt atomic.
* libinterp/corefcn/sighandlers.cc: Make can_interrupt, signals_caught atomic,
use atomic value read for signals_caught, octave_interrupt_state,
change 1 to true.
* liboctave/util/quit.h: Move octave_interrupt_state and octave_signal_caught
to C++ only code, rewrite octave_quit() function, rewrite OCTAVE_QUIT macro
to use octave_quit_c() function.
* liboctave/util/quit.cc: Make octave_interrupt_state and octave_signal_caught
atomic, add new wrapper function octave_quit_c().
* libinterp/corefcn/interpreter.h: Make octave_initialized atomic.
* libinterp/corefcn/interpreter.cc: Make octave_initialized atomic,
change 0 to false.
* liboctave/util/action-container.h: New namespace "util", make m_val atomic.
* liboctave/util/oct-atomic.c: Reorder preprocessor if-elif-else ladder.
* liboctave/util/cmd-edit.cc: Change 0 to false.
author | Reinhard Resch <r_resch@a1.net> |
---|---|
date | Tue, 21 Feb 2023 17:45:34 -0500 |
parents | 21f9b34eb893 |
children | 2e484f9f1f18 |
line wrap: on
line diff
--- a/libinterp/corefcn/sighandlers.cc Mon Feb 20 18:06:54 2023 -0800 +++ b/libinterp/corefcn/sighandlers.cc Tue Feb 21 17:45:34 2023 -0500 @@ -27,6 +27,7 @@ # include "config.h" #endif +#include <atomic> #include <csignal> #include <cstdlib> @@ -65,7 +66,7 @@ int pipe_handler_error_count = 0; // TRUE means we can be interrupted. -bool can_interrupt = false; +std::atomic<bool> can_interrupt{false}; // TRUE means we should try to enter the debugger on SIGINT. bool Vdebug_on_interrupt = false; @@ -82,7 +83,7 @@ static bool Vsigterm_dumps_octave_core = true; // List of signals we have caught since last call to signal_handler. -static bool *signals_caught = nullptr; +static std::atomic<bool> *signals_caught = nullptr; static void my_friendly_exit (int sig, bool save_vars = true) @@ -194,10 +195,10 @@ for (int sig = 0; sig < octave_num_signals (); sig++) { - if (signals_caught[sig]) + bool expected = true; + + if (signals_caught[sig].compare_exchange_strong (expected, false)) { - signals_caught[sig] = false; - if ((have_sigchld && sig == sigchld) || (have_sigcld && sig == sigcld)) { @@ -276,7 +277,7 @@ // signal watcher thread so it should probably be more careful about // how it accesses global objects. - octave_signal_caught = 1; + octave_signal_caught = true; signals_caught[sig] = true; @@ -296,7 +297,7 @@ if (can_interrupt) { - octave_signal_caught = 1; + octave_signal_caught = true; octave_interrupt_state++; } } @@ -365,7 +366,7 @@ install_signal_handlers () { if (! signals_caught) - signals_caught = new bool [octave_num_signals ()]; + signals_caught = new std::atomic<bool> [octave_num_signals ()]; for (int i = 0; i < octave_num_signals (); i++) signals_caught[i] = false;