Mercurial > octave
comparison 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 |
comparison
equal
deleted
inserted
replaced
31631:ec1f34091635 | 31633:d9970470108a |
---|---|
25 | 25 |
26 #if defined (HAVE_CONFIG_H) | 26 #if defined (HAVE_CONFIG_H) |
27 # include "config.h" | 27 # include "config.h" |
28 #endif | 28 #endif |
29 | 29 |
30 #include <atomic> | |
30 #include <cstring> | 31 #include <cstring> |
31 | 32 |
32 #include <ostream> | 33 #include <ostream> |
33 #include <sstream> | 34 #include <sstream> |
34 #include <new> | 35 #include <new> |
35 | 36 |
36 #include "quit.h" | 37 #include "quit.h" |
37 | 38 |
38 sig_atomic_t octave_interrupt_state = 0; | 39 std::atomic<sig_atomic_t> octave_interrupt_state{0}; |
39 | 40 |
40 volatile sig_atomic_t octave_signal_caught = 0; | 41 volatile std::atomic<bool> octave_signal_caught{false}; |
41 | 42 |
42 void (*octave_signal_hook) (void) = nullptr; | 43 void (*octave_signal_hook) (void) = nullptr; |
43 void (*octave_interrupt_hook) (void) = nullptr; | 44 void (*octave_interrupt_hook) (void) = nullptr; |
44 | 45 |
45 OCTAVE_BEGIN_NAMESPACE(octave) | 46 OCTAVE_BEGIN_NAMESPACE(octave) |
93 os << st; | 94 os << st; |
94 } | 95 } |
95 } | 96 } |
96 } | 97 } |
97 | 98 |
99 void octave_quit_c (void) | |
100 { | |
101 octave_quit (); | |
102 } | |
103 | |
98 OCTAVE_END_NAMESPACE(octave) | 104 OCTAVE_END_NAMESPACE(octave) |
99 | 105 |
100 void | 106 void |
101 octave_handle_signal (void) | 107 octave_handle_signal (void) |
102 { | 108 { |
103 if (octave_signal_hook) | 109 if (octave_signal_hook) |
104 octave_signal_hook (); | 110 octave_signal_hook (); |
105 | 111 |
106 if (octave_interrupt_state > 0) | 112 sig_atomic_t curr_interrupt_state = octave_interrupt_state.load (); |
107 { | |
108 octave_interrupt_state = -1; | |
109 | 113 |
110 throw octave::interrupt_exception (); | 114 while (curr_interrupt_state > 0 && |
111 } | 115 ! octave_interrupt_state.compare_exchange_weak (curr_interrupt_state, -1)) |
116 ; | |
117 | |
118 if (curr_interrupt_state > 0) | |
119 throw octave::interrupt_exception (); | |
112 } | 120 } |