aboutsummaryrefslogtreecommitdiffstats
path: root/erts/emulator
diff options
context:
space:
mode:
authorSverker Eriksson <[email protected]>2018-06-05 16:02:31 +0200
committerSverker Eriksson <[email protected]>2018-06-05 16:02:31 +0200
commit9ae2044073e6433030ce30756658b103ce67c3c1 (patch)
treeb95d6464b029483f4c666f11b4dcb7454049c141 /erts/emulator
parent3836f8a1e757e6dff8316ab9938095b9611c75e6 (diff)
parent1f5e17c5ce10982c45a7071b0c6b52f419b99402 (diff)
downloadotp-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')
-rw-r--r--erts/emulator/beam/erl_proc_sig_queue.c22
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);