aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorErlang/OTP <[email protected]>2017-08-25 09:35:58 +0200
committerErlang/OTP <[email protected]>2017-08-25 09:35:58 +0200
commitf4def22e9a7c8b83d3bba4032b3d48571086224e (patch)
treeec03e7a2c211751197cc5ebecf8595330956b47f
parent8af27d1ffdda3e061ebc21eaa22ee8e49372e6b5 (diff)
parenta4a05420aef591bbec457b1762b7aa54666c3ad5 (diff)
downloadotp-f4def22e9a7c8b83d3bba4032b3d48571086224e.tar.gz
otp-f4def22e9a7c8b83d3bba4032b3d48571086224e.tar.bz2
otp-f4def22e9a7c8b83d3bba4032b3d48571086224e.zip
Merge branch 'rickard/btm-auto-cleanup-bug/OTP-14554' into maint-20
* rickard/btm-auto-cleanup-bug/OTP-14554: Fix BIF timer race between timeout and auto cleanup
-rw-r--r--erts/emulator/beam/erl_hl_timer.c21
1 files changed, 11 insertions, 10 deletions
diff --git a/erts/emulator/beam/erl_hl_timer.c b/erts/emulator/beam/erl_hl_timer.c
index af1cc6b933..6e5cc7b801 100644
--- a/erts/emulator/beam/erl_hl_timer.c
+++ b/erts/emulator/beam/erl_hl_timer.c
@@ -1273,14 +1273,15 @@ bif_timer_timeout(ErtsHLTimerService *srv,
ERTS_HLT_ASSERT(proc);
}
if (proc) {
+ int dec_refc = 0;
+ ErtsMessage *mp = erts_alloc_message(0, NULL);
+ mp->data.heap_frag = tmr->btm.bp;
+ tmr->btm.bp = NULL;
+ erts_queue_message(proc, 0, mp, tmr->btm.message,
+ am_clock_service);
+ erts_smp_proc_lock(proc, ERTS_PROC_LOCK_BTM);
+ /* If the process is exiting do not disturb the cleanup... */
if (!ERTS_PROC_IS_EXITING(proc)) {
- int dec_refc = 0;
- ErtsMessage *mp = erts_alloc_message(0, NULL);
- mp->data.heap_frag = tmr->btm.bp;
- tmr->btm.bp = NULL;
- erts_queue_message(proc, 0, mp, tmr->btm.message,
- am_clock_service);
- erts_smp_proc_lock(proc, ERTS_PROC_LOCK_BTM);
#ifdef ERTS_MAGIC_REF_BIF_TIMERS
if (tmr->btm.proc_list.next) {
proc_btm_list_delete(&proc->bif_timers, tmr);
@@ -1293,10 +1294,10 @@ bif_timer_timeout(ErtsHLTimerService *srv,
dec_refc = 1;
}
#endif
- erts_smp_proc_unlock(proc, ERTS_PROC_LOCK_BTM);
- if (dec_refc)
- timer_pre_dec_refc((ErtsTimer *) tmr);
}
+ erts_smp_proc_unlock(proc, ERTS_PROC_LOCK_BTM);
+ if (dec_refc)
+ timer_pre_dec_refc((ErtsTimer *) tmr);
}
if (tmr->btm.bp)
free_message_buffer(tmr->btm.bp);