comparison libinterp/corefcn/sighandlers.cc @ 31635:7d3467f8d713 stable

Backed out changeset d9970470108a
author John W. Eaton <jwe@octave.org>
date Sat, 03 Dec 2022 14:43:33 -0500
parents d9970470108a
children 597f3ee61a48
comparison
equal deleted inserted replaced
31633:d9970470108a 31635:7d3467f8d713
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>
31 #include <csignal> 30 #include <csignal>
32 #include <cstdlib> 31 #include <cstdlib>
33 32
34 #include <iostream> 33 #include <iostream>
35 #include <new> 34 #include <new>
64 // Nonzero means we have already printed a message for this series of 63 // Nonzero means we have already printed a message for this series of
65 // SIGPIPES. We assume that the writer will eventually give up. 64 // SIGPIPES. We assume that the writer will eventually give up.
66 int pipe_handler_error_count = 0; 65 int pipe_handler_error_count = 0;
67 66
68 // TRUE means we can be interrupted. 67 // TRUE means we can be interrupted.
69 std::atomic<bool> can_interrupt{false}; 68 bool can_interrupt = false;
70 69
71 // TRUE means we should try to enter the debugger on SIGINT. 70 // TRUE means we should try to enter the debugger on SIGINT.
72 bool Vdebug_on_interrupt = false; 71 bool Vdebug_on_interrupt = false;
73 72
74 // Allow users to avoid writing octave-workspace for SIGHUP (sent by 73 // Allow users to avoid writing octave-workspace for SIGHUP (sent by
81 80
82 // Similar to Vsighup_dumps_octave_core, but for SIGTERM signal. 81 // Similar to Vsighup_dumps_octave_core, but for SIGTERM signal.
83 static bool Vsigterm_dumps_octave_core = true; 82 static bool Vsigterm_dumps_octave_core = true;
84 83
85 // List of signals we have caught since last call to signal_handler. 84 // List of signals we have caught since last call to signal_handler.
86 static std::atomic<bool> *signals_caught = nullptr; 85 static bool *signals_caught = nullptr;
87 86
88 static void 87 static void
89 my_friendly_exit (int sig, bool save_vars = true) 88 my_friendly_exit (int sig, bool save_vars = true)
90 { 89 {
91 std::cerr << "fatal: caught signal " 90 std::cerr << "fatal: caught signal "
193 192
194 child_list& kids = __get_child_list__ (); 193 child_list& kids = __get_child_list__ ();
195 194
196 for (int sig = 0; sig < octave_num_signals (); sig++) 195 for (int sig = 0; sig < octave_num_signals (); sig++)
197 { 196 {
198 bool expected = true; 197 if (signals_caught[sig])
199
200 if (signals_caught[sig].compare_exchange_strong (expected, false))
201 { 198 {
199 signals_caught[sig] = false;
200
202 if ((have_sigchld && sig == sigchld) 201 if ((have_sigchld && sig == sigchld)
203 || (have_sigcld && sig == sigcld)) 202 || (have_sigcld && sig == sigcld))
204 { 203 {
205 // FIXME: should we block or ignore? 204 // FIXME: should we block or ignore?
206 volatile interrupt_handler saved_interrupt_handler 205 volatile interrupt_handler saved_interrupt_handler
222 221
223 // Don't loop forever on account of this. 222 // Don't loop forever on account of this.
224 // FIXME: is this really needed? Does it do anything 223 // FIXME: is this really needed? Does it do anything
225 // useful now? 224 // useful now?
226 225
227 const int curr_pipe_handler_error_count = pipe_handler_error_count++; 226 if (pipe_handler_error_count++ > 100
228 227 && octave_interrupt_state >= 0)
229 if (curr_pipe_handler_error_count > 100) 228 octave_interrupt_state++;
230 {
231 sig_atomic_t curr_interrupt_state
232 = octave_interrupt_state.load();
233
234 sig_atomic_t new_interrupt_state;
235
236 do
237 new_interrupt_state = curr_interrupt_state + 1;
238 while (curr_interrupt_state >= 0 &&
239 ! octave_interrupt_state.compare_exchange_weak
240 (curr_interrupt_state, new_interrupt_state));
241 }
242
243 } 229 }
244 else if (have_sighup && sig == sighup) 230 else if (have_sighup && sig == sighup)
245 my_friendly_exit (sighup, Vsighup_dumps_octave_core); 231 my_friendly_exit (sighup, Vsighup_dumps_octave_core);
246 else if (have_sigquit && sig == sigquit) 232 else if (have_sigquit && sig == sigquit)
247 my_friendly_exit (sigquit, Vsigquit_dumps_octave_core); 233 my_friendly_exit (sigquit, Vsigquit_dumps_octave_core);
288 { 274 {
289 // FIXME: this function may execute in a separate signal handler or 275 // FIXME: this function may execute in a separate signal handler or
290 // signal watcher thread so it should probably be more careful about 276 // signal watcher thread so it should probably be more careful about
291 // how it accesses global objects. 277 // how it accesses global objects.
292 278
293 octave_signal_caught = true; 279 octave_signal_caught = 1;
294 280
295 signals_caught[sig] = true; 281 signals_caught[sig] = true;
296 282
297 static int sigint; 283 static int sigint;
298 static const bool have_sigint 284 static const bool have_sigint
308 if (! octave_initialized) 294 if (! octave_initialized)
309 exit (1); 295 exit (1);
310 296
311 if (can_interrupt) 297 if (can_interrupt)
312 { 298 {
313 octave_signal_caught = true; 299 octave_signal_caught = 1;
314 octave_interrupt_state++; 300 octave_interrupt_state++;
315 } 301 }
316 } 302 }
317 } 303 }
318 304
377 363
378 void 364 void
379 install_signal_handlers (void) 365 install_signal_handlers (void)
380 { 366 {
381 if (! signals_caught) 367 if (! signals_caught)
382 signals_caught = new std::atomic<bool> [octave_num_signals ()]; 368 signals_caught = new bool [octave_num_signals ()];
383 369
384 for (int i = 0; i < octave_num_signals (); i++) 370 for (int i = 0; i < octave_num_signals (); i++)
385 signals_caught[i] = false; 371 signals_caught[i] = false;
386 372
387 // Interrupt signals. 373 // Interrupt signals.