aboutsummaryrefslogtreecommitdiffstats
path: root/erts/emulator/beam/erl_process.c
diff options
context:
space:
mode:
Diffstat (limited to 'erts/emulator/beam/erl_process.c')
-rw-r--r--erts/emulator/beam/erl_process.c42
1 files changed, 27 insertions, 15 deletions
diff --git a/erts/emulator/beam/erl_process.c b/erts/emulator/beam/erl_process.c
index 374583ec47..0118302eb3 100644
--- a/erts/emulator/beam/erl_process.c
+++ b/erts/emulator/beam/erl_process.c
@@ -10750,7 +10750,6 @@ exit_permanent_prio_elevation(Process *c_p, erts_aint32_t state)
while (1) {
erts_aint32_t aprio, uprio, n, e;
ASSERT(a & ERTS_PSFLG_EXITING);
- ASSERT(!(a & ERTS_PSFLG_FREE));
aprio = ERTS_PSFLGS_GET_ACT_PRIO(a);
uprio = ERTS_PSFLGS_GET_USR_PRIO(a);
if (aprio >= uprio)
@@ -10796,8 +10795,7 @@ erts_execute_dirty_system_task(Process *c_p)
if (c_p->flags & F_DIRTY_GC_HIBERNATE) {
erts_proc_lock(c_p, ERTS_PROC_LOCK_MSGQ|ERTS_PROC_LOCK_STATUS);
- erts_proc_sig_fetch(c_p);
- if (c_p->sig_qs.len)
+ if (erts_proc_sig_fetch(c_p))
c_p->flags &= ~F_DIRTY_GC_HIBERNATE; /* operation aborted... */
else {
erts_proc_unlock(c_p, ERTS_PROC_LOCK_MSGQ|ERTS_PROC_LOCK_STATUS);
@@ -12377,12 +12375,14 @@ erts_proc_exit_handle_monitor(ErtsMonitor *mon, void *vctxt)
case ERTS_MON_TYPE_PORT: {
Port *prt;
ASSERT(is_internal_port(mon->other.item));
+ erts_proc_unlock(c_p, ERTS_PROC_LOCK_MAIN);
prt = erts_id2port(mon->other.item);
if (prt) {
erts_fire_port_monitor(prt, mon);
erts_port_release(prt);
mon = NULL;
}
+ erts_proc_lock(c_p, ERTS_PROC_LOCK_MAIN);
break;
}
case ERTS_MON_TYPE_RESOURCE:
@@ -12461,10 +12461,8 @@ erts_proc_exit_handle_monitor(ErtsMonitor *mon, void *vctxt)
ASSERT(is_internal_port(mon->other.item));
prt = erts_port_lookup_raw(mon->other.item);
if (prt) {
- erts_proc_lock(c_p, ERTS_PROC_LOCK_MAIN);
if (erts_port_demonitor(c_p, prt, mon) != ERTS_PORT_OP_DROPPED)
mon = NULL;
- erts_proc_unlock(c_p, ERTS_PROC_LOCK_MAIN);
}
break;
}
@@ -12567,7 +12565,6 @@ erts_proc_exit_handle_link(ErtsLink *lnk, void *vctxt)
if (!erts_link_dist_delete(dlnk))
ldp = NULL;
- erts_proc_lock(c_p, ERTS_PROC_LOCK_MAIN);
code = erts_dsig_prepare(&dsd, dep, c_p, 0, ERTS_DSP_NO_LOCK, 0, 0);
switch (code) {
case ERTS_DSIG_PREP_CONNECTED:
@@ -12581,7 +12578,6 @@ erts_proc_exit_handle_link(ErtsLink *lnk, void *vctxt)
ASSERT(code == ERTS_DSIG_SEND_OK);
}
}
- erts_proc_unlock(c_p, ERTS_PROC_LOCK_MAIN);
break;
}
default:
@@ -12643,8 +12639,6 @@ erts_do_exit_process(Process* p, Eterm reason)
cancel_suspend_of_suspendee(p, ERTS_PROC_LOCKS_ALL);
- erts_proc_sig_fetch(p);
-
if (IS_TRACED(p)) {
if (IS_TRACED_FL(p, F_TRACE_CALLS))
erts_schedule_time_break(p, ERTS_BP_CALL_TIME_SCHEDULE_EXITING);
@@ -12911,6 +12905,12 @@ erts_continue_exit_process(Process *p)
pectxt.c_p = p;
pectxt.reason = reason;
+ erts_proc_lock(p, ERTS_PROC_LOCK_MAIN|ERTS_PROC_LOCK_MSGQ);
+
+ erts_proc_sig_fetch(p);
+
+ erts_proc_unlock(p, ERTS_PROC_LOCK_MSGQ);
+
if (links) {
erts_link_tree_foreach_delete(&links,
erts_proc_exit_handle_link,
@@ -12932,7 +12932,6 @@ erts_continue_exit_process(Process *p)
ASSERT(!lt_monitors);
}
- erts_proc_sig_fetch(p);
/*
* erts_proc_sig_handle_exit() implements yielding.
* However, this function cannot handle it yet... loop
@@ -12944,7 +12943,6 @@ erts_continue_exit_process(Process *p)
break;
}
- erts_proc_lock(p, ERTS_PROC_LOCK_MAIN);
ERTS_CHK_HAVE_ONLY_MAIN_PROC_LOCK(p);
erts_flush_trace_messages(p, ERTS_PROC_LOCK_MAIN);
@@ -12981,27 +12979,41 @@ erts_continue_exit_process(Process *p)
}
Process *
-erts_try_lock_sig_free_proc(Eterm pid, ErtsProcLocks locks)
+erts_try_lock_sig_free_proc(Eterm pid, ErtsProcLocks locks,
+ erts_aint32_t *statep)
{
Process *rp = erts_proc_lookup_raw(pid);
erts_aint32_t state;
- if (!rp)
+ if (!rp) {
+ if (statep)
+ *statep = ERTS_PSFLG_EXITING|ERTS_PSFLG_FREE;
return NULL;
+ }
ERTS_LC_ASSERT(!erts_proc_lc_my_proc_locks(rp));
state = erts_atomic32_read_nob(&rp->state);
- if (state & ERTS_PSFLG_EXITING)
+ if (statep)
+ *statep = state;
+
+ if (state & ERTS_PSFLG_FREE)
return NULL;
if (state & (ERTS_PSFLG_SIG_IN_Q|ERTS_PSFLG_SIG_Q))
return ERTS_PROC_LOCK_BUSY;
+
+ if (!locks)
+ return rp;
+
if (erts_proc_trylock(rp, locks) == EBUSY)
return ERTS_PROC_LOCK_BUSY;
state = erts_atomic32_read_nob(&rp->state);
- if (state & ERTS_PSFLG_EXITING) {
+ if (statep)
+ *statep = state;
+
+ if (state & ERTS_PSFLG_FREE) {
erts_proc_unlock(rp, locks);
return NULL;
}