summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSverker Eriksson <sverker@erlang.org>2019-04-29 20:24:04 +0200
committerRickard Green <rickard@erlang.org>2021-03-04 23:11:48 +0100
commitec5357bb04f13ef3e3206816dd477c54febd7c7d (patch)
tree2092e5e970a407932585a6961625876b11d041f0
parentd01ee674e0b7de26969477418b69b1bdcdfdf892 (diff)
downloaderlang-ec5357bb04f13ef3e3206816dd477c54febd7c7d.tar.gz
erts: Fix bug in timer wheel at cancel during bump yield
Symptom: Failed debug assert in find_next_timeout ERTS_TW_ASSERT(tiw->yield_slot == ERTS_TW_SLOT_INACTIVE); Problem: If remove_timer() was called in between yielding erts_bump_timers() tiw->true_next_timeout_time could be set to 0 leading to find_next_timeout() being called before all bumping is done. Solution: Don't clear tiw->true_next_timeout_time in remove_timer() if tiw->yield_slot is active. Does not seem this bug could cause other more harmful symptoms, but not sure.
-rw-r--r--erts/emulator/beam/time.c6
1 files changed, 4 insertions, 2 deletions
diff --git a/erts/emulator/beam/time.c b/erts/emulator/beam/time.c
index ee34d0036a..73538dc375 100644
--- a/erts/emulator/beam/time.c
+++ b/erts/emulator/beam/time.c
@@ -703,7 +703,8 @@ remove_timer(ErtsTimerWheel *tiw, ErtsTWheelTimer *p)
if (slot < ERTS_TW_SOON_WHEEL_END_SLOT) {
if (empty_slot
&& tiw->true_next_timeout_time
- && p->timeout_pos == tiw->next_timeout_pos) {
+ && p->timeout_pos == tiw->next_timeout_pos
+ && tiw->yield_slot == ERTS_TW_SLOT_INACTIVE) {
tiw->true_next_timeout_time = 0;
}
if (--tiw->soon.nto == 0)
@@ -716,7 +717,8 @@ remove_timer(ErtsTimerWheel *tiw, ErtsTWheelTimer *p)
ErtsMonotonicTime tpos = tiw->later.min_tpos;
tpos &= ERTS_TW_LATER_WHEEL_POS_MASK;
tpos -= ERTS_TW_LATER_WHEEL_SLOT_SIZE;
- if (tpos == tiw->next_timeout_pos)
+ if (tpos == tiw->next_timeout_pos
+ && tiw->yield_slot == ERTS_TW_SLOT_INACTIVE)
tiw->true_next_timeout_time = 0;
}
if (--tiw->later.nto == 0) {