aboutsummaryrefslogtreecommitdiffstats
path: root/erts/emulator
diff options
context:
space:
mode:
authorBjörn-Egil Dahlberg <[email protected]>2015-04-13 18:03:33 +0200
committerBjörn-Egil Dahlberg <[email protected]>2017-01-05 10:29:45 +0100
commitc9060f9b4289bf9a669ac651a1a7aeb97a28652c (patch)
tree82fba1108c2c149ea9ecbb10f10b85b53261ee1d /erts/emulator
parentdc72c879b68fdf96edfec360e8c311ff7389ecc6 (diff)
downloadotp-c9060f9b4289bf9a669ac651a1a7aeb97a28652c.tar.gz
otp-c9060f9b4289bf9a669ac651a1a7aeb97a28652c.tar.bz2
otp-c9060f9b4289bf9a669ac651a1a7aeb97a28652c.zip
erts: Add SIGHUP signal handler
A received SIGHUP signal to beam will generate a '{notify, sighup}' message to the registered process 'erl_signal_server'. 'erl_signal_server' is a gen_event process.
Diffstat (limited to 'erts/emulator')
-rw-r--r--erts/emulator/beam/atom.names2
-rw-r--r--erts/emulator/beam/register.c12
-rw-r--r--erts/emulator/sys/unix/sys.c41
3 files changed, 49 insertions, 6 deletions
diff --git a/erts/emulator/beam/atom.names b/erts/emulator/beam/atom.names
index b1aeed7889..363b17e27c 100644
--- a/erts/emulator/beam/atom.names
+++ b/erts/emulator/beam/atom.names
@@ -239,6 +239,7 @@ atom Eq='=:='
atom Eqeq='=='
atom erl_tracer
atom erlang
+atom erl_signal_server
atom ERROR='ERROR'
atom error_handler
atom error_logger
@@ -590,6 +591,7 @@ atom set_tcw
atom set_tcw_fake
atom separate
atom shared
+atom sighup
atom silent
atom size
atom sl_alloc
diff --git a/erts/emulator/beam/register.c b/erts/emulator/beam/register.c
index acda51c9fc..7f60710124 100644
--- a/erts/emulator/beam/register.c
+++ b/erts/emulator/beam/register.c
@@ -272,13 +272,13 @@ erts_whereis_name_to_id(Process *c_p, Eterm name)
int ix;
HashBucket* b;
#ifdef ERTS_SMP
- ErtsProcLocks c_p_locks = c_p ? ERTS_PROC_LOCK_MAIN : 0;
-
-#ifdef ERTS_ENABLE_LOCK_CHECK
- if (c_p) ERTS_SMP_CHK_HAVE_ONLY_MAIN_PROC_LOCK(c_p);
-#endif
-
+ ErtsProcLocks c_p_locks = 0;
+ if (c_p) {
+ c_p_locks = ERTS_PROC_LOCK_MAIN;
+ ERTS_SMP_CHK_HAVE_ONLY_MAIN_PROC_LOCK(c_p);
+ }
reg_safe_read_lock(c_p, &c_p_locks);
+
if (c_p && !c_p_locks)
erts_smp_proc_lock(c_p, ERTS_PROC_LOCK_MAIN);
#endif
diff --git a/erts/emulator/sys/unix/sys.c b/erts/emulator/sys/unix/sys.c
index 2ce0d56dde..a099662b16 100644
--- a/erts/emulator/sys/unix/sys.c
+++ b/erts/emulator/sys/unix/sys.c
@@ -408,6 +408,7 @@ erts_sys_pre_init(void)
sigemptyset(&thr_create_sigmask);
sigaddset(&thr_create_sigmask, SIGINT); /* block interrupt */
sigaddset(&thr_create_sigmask, SIGTERM); /* block terminate signal */
+ sigaddset(&thr_create_sigmask, SIGHUP); /* block sighups */
sigaddset(&thr_create_sigmask, SIGUSR1); /* block user defined signal */
#endif
@@ -625,6 +626,28 @@ int erts_sys_prepare_crash_dump(int secs)
return prepare_crash_dump(secs);
}
+static void signal_notify_requested(Eterm type) {
+ Process* p = NULL;
+ Eterm msg, *hp;
+ ErtsProcLocks locks = 0;
+ ErlOffHeap *ohp;
+
+ Eterm id = erts_whereis_name_to_id(NULL, am_erl_signal_server);
+
+ if ((p = (erts_pid2proc_opt(NULL, 0, id, 0, ERTS_P2P_FLG_INC_REFC))) != NULL) {
+ ErtsMessage *msgp = erts_alloc_message_heap(p, &locks, 3, &hp, &ohp);
+
+ /* erl_signal_server ! {notify, sighup} */
+ msg = TUPLE2(hp, am_notify, type);
+ erts_queue_message(p, locks, msgp, msg, am_system);
+
+ if (locks)
+ erts_smp_proc_unlock(p, locks);
+ erts_proc_dec_refc(p);
+ }
+}
+
+
static ERTS_INLINE void
break_requested(void)
{
@@ -783,10 +806,24 @@ static RETSIGTYPE do_quit(int signum)
#endif
}
+#if (defined(SIG_SIGSET) || defined(SIG_SIGNAL))
+static RETSIGTYPE request_sighup(void)
+#else
+static RETSIGTYPE request_sighup(int signum)
+#endif
+{
+#ifdef ERTS_SMP
+ smp_sig_notify('H');
+#else
+ signal_notify_requested(am_sighup);
+#endif
+}
+
/* Disable break */
void erts_set_ignore_break(void) {
sys_signal(SIGINT, SIG_IGN);
sys_signal(SIGTERM, SIG_IGN);
+ sys_signal(SIGHUP, SIG_IGN);
sys_signal(SIGQUIT, SIG_IGN);
sys_signal(SIGTSTP, SIG_IGN);
}
@@ -813,6 +850,7 @@ void init_break_handler(void)
{
sys_signal(SIGINT, request_break);
sys_signal(SIGTERM, request_stop);
+ sys_signal(SIGHUP, request_sighup);
#ifndef ETHR_UNUSABLE_SIGUSRX
sys_signal(SIGUSR1, user_signal1);
#endif /* #ifndef ETHR_UNUSABLE_SIGUSRX */
@@ -1289,6 +1327,9 @@ signal_dispatcher_thread_func(void *unused)
switch (buf[i]) {
case 0: /* Emulator initialized */
break;
+ case 'H': /* SIGHUP */
+ signal_notify_requested(am_sighup);
+ break;
case 'S': /* SIGTERM */
stop_requested();
break;