Mercurial > octave
diff liboctave/util/quit.cc @ 31633:d9970470108a stable
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 | Sat, 03 Dec 2022 10:36:59 -0500 |
parents | aac27ad79be6 |
children | 7d3467f8d713 |
line wrap: on
line diff
--- a/liboctave/util/quit.cc Sat Dec 03 13:55:14 2022 +0100 +++ b/liboctave/util/quit.cc Sat Dec 03 10:36:59 2022 -0500 @@ -27,6 +27,7 @@ # include "config.h" #endif +#include <atomic> #include <cstring> #include <ostream> @@ -35,9 +36,9 @@ #include "quit.h" -sig_atomic_t octave_interrupt_state = 0; +std::atomic<sig_atomic_t> octave_interrupt_state{0}; -volatile sig_atomic_t octave_signal_caught = 0; +volatile std::atomic<bool> octave_signal_caught{false}; void (*octave_signal_hook) (void) = nullptr; void (*octave_interrupt_hook) (void) = nullptr; @@ -95,6 +96,11 @@ } } +void octave_quit_c (void) +{ + octave_quit (); +} + OCTAVE_END_NAMESPACE(octave) void @@ -103,10 +109,12 @@ if (octave_signal_hook) octave_signal_hook (); - if (octave_interrupt_state > 0) - { - octave_interrupt_state = -1; + sig_atomic_t curr_interrupt_state = octave_interrupt_state.load (); - throw octave::interrupt_exception (); - } + while (curr_interrupt_state > 0 && + ! octave_interrupt_state.compare_exchange_weak (curr_interrupt_state, -1)) + ; + + if (curr_interrupt_state > 0) + throw octave::interrupt_exception (); }