diff options
author | Sverker Eriksson <[email protected]> | 2018-06-05 16:02:31 +0200 |
---|---|---|
committer | Sverker Eriksson <[email protected]> | 2018-06-05 16:02:31 +0200 |
commit | 9ae2044073e6433030ce30756658b103ce67c3c1 (patch) | |
tree | b95d6464b029483f4c666f11b4dcb7454049c141 /erts/emulator/beam | |
parent | 3836f8a1e757e6dff8316ab9938095b9611c75e6 (diff) | |
parent | 1f5e17c5ce10982c45a7071b0c6b52f419b99402 (diff) | |
download | otp-9ae2044073e6433030ce30756658b103ce67c3c1.tar.gz otp-9ae2044073e6433030ce30756658b103ce67c3c1.tar.bz2 otp-9ae2044073e6433030ce30756658b103ce67c3c1.zip |
Merge branch 'sverker/broken-sig-queue'
* sverker/broken-sig-queue:
erts: Cleanup in proc_queue_signal
erts: Fix broken signal queue
Diffstat (limited to 'erts/emulator/beam')
-rw-r--r-- | erts/emulator/beam/erl_proc_sig_queue.c | 22 |
1 files changed, 10 insertions, 12 deletions
diff --git a/erts/emulator/beam/erl_proc_sig_queue.c b/erts/emulator/beam/erl_proc_sig_queue.c index e9b41ad298..1aa390d94d 100644 --- a/erts/emulator/beam/erl_proc_sig_queue.c +++ b/erts/emulator/beam/erl_proc_sig_queue.c @@ -423,13 +423,13 @@ sig_enqueue_trace(Process *c_p, ErtsMessage **sigp, int op, } static void -sig_enqueue_trace_cleanup(ErtsMessage *first, ErtsSignal *sig, ErtsMessage *last) +sig_enqueue_trace_cleanup(ErtsMessage *first, ErtsSignal *sig) { ErtsMessage *tmp; /* The usual case; no tracing signals... */ - if (sig == (ErtsSignal *) first && sig == (ErtsSignal *) last) { - sig->common.next = NULL; + if (sig == (ErtsSignal *) first) { + ASSERT(sig->common.next == NULL); return; } @@ -445,6 +445,8 @@ sig_enqueue_trace_cleanup(ErtsMessage *first, ErtsSignal *sig, ErtsMessage *last case ERTS_SIG_Q_OP_TRACE_CHANGE_STATE: destroy_trace_info((ErtsSigTraceInfo *) tmp_free); break; + case ERTS_SIG_Q_OP_MONITOR: + break; /* ignore flushed pending signal */ default: ERTS_INTERNAL_ERROR("Unexpected signal op"); break; @@ -667,7 +669,7 @@ proc_queue_signal(Process *c_p, Eterm pid, ErtsSignal *sig, int op) first_last_done: sig->common.specific.next = NULL; - /* may add signals before and/or after sig */ + /* may add signals before sig */ sig_enqueue_trace(c_p, sigp, op, rp, &last_next); last->next = NULL; @@ -688,22 +690,18 @@ first_last_done: erts_proc_unlock(rp, ERTS_PROC_LOCK_MSGQ); if (res == 0) { + sig_enqueue_trace_cleanup(first, sig); if (pend_sig) { + erts_proc_sig_send_monitor_down((ErtsMonitor*)pend_sig, am_noproc); if (sig == pend_sig) { /* We did a switch, callers signal is now pending (still ok) */ ASSERT(esdp->pending_signal.sig); res = 1; } - else { - ASSERT(first == (ErtsMessage*)pend_sig); - first = first->next; - } - erts_proc_sig_send_monitor_down((ErtsMonitor*)pend_sig, am_noproc); } - sig_enqueue_trace_cleanup(first, sig, last); } - - erts_proc_notify_new_sig(rp, state, 0); + else + erts_proc_notify_new_sig(rp, state, 0); if (!is_normal_sched) erts_proc_dec_refc(rp); |