diff options
author | Björn-Egil Dahlberg <[email protected]> | 2017-03-21 14:37:03 +0100 |
---|---|---|
committer | Björn-Egil Dahlberg <[email protected]> | 2017-03-21 14:49:55 +0100 |
commit | f92d862c1af230a873c2b2d30fea575ff3dafd56 (patch) | |
tree | de8a3dac88e62cd9ff2820ba7404bf21d1e08903 | |
parent | a748cafdc7063d9f181ba12088db6458793ced2f (diff) | |
download | otp-f92d862c1af230a873c2b2d30fea575ff3dafd56.tar.gz otp-f92d862c1af230a873c2b2d30fea575ff3dafd56.tar.bz2 otp-f92d862c1af230a873c2b2d30fea575ff3dafd56.zip |
erts: Make sigterm signal safe for non-smp beam
The signal handler will now schedule a sigterm message instead of sending
the message in the signal handler. The signal handler must refrain from
memory allocations and thus the event is scheduled.
-rw-r--r-- | erts/emulator/beam/sys.h | 6 | ||||
-rw-r--r-- | erts/emulator/sys/common/erl_check_io.c | 10 | ||||
-rw-r--r-- | erts/emulator/sys/unix/sys.c | 20 |
3 files changed, 33 insertions, 3 deletions
diff --git a/erts/emulator/beam/sys.h b/erts/emulator/beam/sys.h index d49edad6dc..dd4f05686b 100644 --- a/erts/emulator/beam/sys.h +++ b/erts/emulator/beam/sys.h @@ -481,6 +481,12 @@ extern volatile int erts_break_requested; void erts_do_break_handling(void); #endif +#if !defined(ERTS_SMP) && !defined(__WIN32__) +extern volatile Uint erts_signal_sigterm; +#define ERTS_SIGNAL_SIGTERM erts_signal_sigterm +void erts_handle_signal_sigterm(void); +#endif + #ifdef ERTS_WANT_GOT_SIGUSR1 # ifndef UNIX # define ERTS_GOT_SIGUSR1 0 diff --git a/erts/emulator/sys/common/erl_check_io.c b/erts/emulator/sys/common/erl_check_io.c index 44a77f3ea5..8f2f1f9521 100644 --- a/erts/emulator/sys/common/erl_check_io.c +++ b/erts/emulator/sys/common/erl_check_io.c @@ -1617,6 +1617,11 @@ ERTS_CIO_EXPORT(erts_check_io)(int do_wait) erts_do_break_handling(); #endif +#ifdef ERTS_SIGNAL_SIGTERM + if (ERTS_SIGNAL_SIGTERM) + erts_handle_signal_sigterm(); +#endif + /* Figure out timeout value */ timeout_time = (do_wait ? erts_check_next_timeout_time(esdp) @@ -1654,6 +1659,11 @@ ERTS_CIO_EXPORT(erts_check_io)(int do_wait) erts_do_break_handling(); #endif +#ifdef ERTS_SIGNAL_SIGTERM + if (ERTS_SIGNAL_SIGTERM) + erts_handle_signal_sigterm(); +#endif + if (poll_ret != 0) { erts_smp_atomic_set_nob(&pollset.in_poll_wait, 0); forget_removed(&pollset); diff --git a/erts/emulator/sys/unix/sys.c b/erts/emulator/sys/unix/sys.c index 6459fa064b..55411f83d0 100644 --- a/erts/emulator/sys/unix/sys.c +++ b/erts/emulator/sys/unix/sys.c @@ -148,11 +148,18 @@ volatile int erts_break_requested = 0; #define ERTS_SET_BREAK_REQUESTED (erts_break_requested = 1) #define ERTS_UNSET_BREAK_REQUESTED (erts_break_requested = 0) #endif + +#ifndef ERTS_SMP +volatile Uint erts_signal_sigterm = 0; +#define ERTS_SET_SIGNAL_SIGTERM (erts_signal_sigterm = 1) +#define ERTS_CLEAR_SIGNAL_SIGTERM (erts_signal_sigterm = 0) +#endif + /* set early so the break handler has access to initial mode */ static struct termios initial_tty_mode; static int replace_intr = 0; /* assume yes initially, ttsl_init will clear it */ -int using_oldshell = 1; +int using_oldshell = 1; #ifdef ERTS_ENABLE_KERNEL_POLL @@ -684,11 +691,11 @@ static RETSIGTYPE request_stop(int signum) #ifdef ERTS_SMP smp_sig_notify('S'); #else - stop_requested(); + ERTS_SET_SIGNAL_SIGTERM; + ERTS_CHK_IO_AS_INTR(); #endif } - static ERTS_INLINE void sigusr1_exit(void) { @@ -958,6 +965,13 @@ void erts_do_break_handling(void) erts_smp_thr_progress_unblock(); } +#ifdef ERTS_SIGNAL_SIGTERM +void erts_handle_signal_sigterm(void) { + ERTS_CLEAR_SIGNAL_SIGTERM; + stop_requested(); +} +#endif + /* Fills in the systems representation of the jam/beam process identifier. ** The Pid is put in STRING representation in the supplied buffer, ** no interpretatione of this should be done by the rest of the |