diff options
author | Sverker Eriksson <sverker@erlang.org> | 2019-04-29 20:24:04 +0200 |
---|---|---|
committer | Rickard Green <rickard@erlang.org> | 2021-03-04 23:11:48 +0100 |
commit | ec5357bb04f13ef3e3206816dd477c54febd7c7d (patch) | |
tree | 2092e5e970a407932585a6961625876b11d041f0 | |
parent | d01ee674e0b7de26969477418b69b1bdcdfdf892 (diff) | |
download | erlang-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.c | 6 |
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) { |