diff options
author | Erlang/OTP <[email protected]> | 2016-08-11 16:24:00 +0200 |
---|---|---|
committer | Erlang/OTP <[email protected]> | 2016-08-11 16:24:00 +0200 |
commit | 44b2c3e91509f210c2ad18eb296e34b61e0f52cb (patch) | |
tree | a3357c77e4666919ab6b58489f7d2af921f5448f | |
parent | e7966ef5cb0c2337a674d8cdca7c89802fa01bf6 (diff) | |
parent | 17c838402c6d71aef041548ad36ee66db6f24a56 (diff) | |
download | otp-44b2c3e91509f210c2ad18eb296e34b61e0f52cb.tar.gz otp-44b2c3e91509f210c2ad18eb296e34b61e0f52cb.tar.bz2 otp-44b2c3e91509f210c2ad18eb296e34b61e0f52cb.zip |
Merge branch 'rickard/proc-tmo-bug/OTP-13798' into maint-18
* rickard/proc-tmo-bug/OTP-13798:
Fix race causing lost wakeup on receive-after timeout
-rw-r--r-- | erts/emulator/beam/beam_emu.c | 5 | ||||
-rw-r--r-- | erts/emulator/beam/erl_hl_timer.c | 5 |
2 files changed, 8 insertions, 2 deletions
diff --git a/erts/emulator/beam/beam_emu.c b/erts/emulator/beam/beam_emu.c index 1fe4cc9374..3a15287555 100644 --- a/erts/emulator/beam/beam_emu.c +++ b/erts/emulator/beam/beam_emu.c @@ -2182,7 +2182,10 @@ void process_main(void) c_p->i = (BeamInstr *) Arg(0); /* L1 */ SWAPOUT; c_p->arity = 0; - erts_smp_atomic32_read_band_relb(&c_p->state, ~ERTS_PSFLG_ACTIVE); + + if (!ERTS_PTMR_IS_TIMED_OUT(c_p)) + erts_smp_atomic32_read_band_relb(&c_p->state, + ~ERTS_PSFLG_ACTIVE); ASSERT(!ERTS_PROC_IS_EXITING(c_p)); erts_smp_proc_unlock(c_p, ERTS_PROC_LOCKS_MSG_RECEIVE); c_p->current = NULL; diff --git a/erts/emulator/beam/erl_hl_timer.c b/erts/emulator/beam/erl_hl_timer.c index fb6d249145..fbfde83dba 100644 --- a/erts/emulator/beam/erl_hl_timer.c +++ b/erts/emulator/beam/erl_hl_timer.c @@ -735,7 +735,10 @@ proc_timeout_common(Process *proc, void *tmr) if (tmr == (void *) erts_smp_atomic_cmpxchg_mb(&proc->common.timer, ERTS_PTMR_TIMEDOUT, (erts_aint_t) tmr)) { - erts_aint32_t state = erts_smp_atomic32_read_acqb(&proc->state); + erts_aint32_t state; + erts_smp_proc_lock(proc, ERTS_PROC_LOCKS_MSG_RECEIVE); + state = erts_smp_atomic32_read_acqb(&proc->state); + erts_smp_proc_unlock(proc, ERTS_PROC_LOCKS_MSG_RECEIVE); if (!(state & (ERTS_PSFLG_ACTIVE|ERTS_PSFLG_EXITING))) erts_schedule_process(proc, state, 0); return 1; |