diff options
author | Raimo Niskanen <raimo@erlang.org> | 2020-10-17 01:22:33 +0200 |
---|---|---|
committer | Raimo Niskanen <raimo@erlang.org> | 2020-10-19 14:40:45 +0200 |
commit | 6db46e96d5fc3f10d37c6c4ba4f6a211a663d971 (patch) | |
tree | 13c8b0ef100bb6db8b4cbe5240ba6ad8f69416b2 /lib/stdlib/test/gen_statem_SUITE.erl | |
parent | 4a42e03c796ee23c6f8ce479722653ad82c10a8e (diff) | |
download | erlang-6db46e96d5fc3f10d37c6c4ba4f6a211a663d971.tar.gz |
Implement zero time-outs with dedicated queue
The previous solution was flawed because it immediately inserted
a zero time-out in the event queue, and tried to compensate for
when and how they would not fire due to state changes and other
events.
That implementation did not cut it e.g when combining a state
time-out with inserting an event, and in the new state, with
the state time-out, changing states. Then the state time-out
was not cancelled because it was already in the event queue,
and it arrived in a later state.
This commit changes the implementation into having a dedicated
queue for zero time-outs, from which events are extracted
as from the process mailbox, but before the process mailbox.
Now when cancelling a time-out, for any reason, automatic
or explicit, a zero time-out can be removed from this queue
as it would have been from the process mailbox for time > 0.
With this implementation it should be guaranteed that
a state time-out is delivered only in the state for which
it was started. A state change can always cancel it when it
is in the dedicated queue.
The queue is stored in the Timers map, with the specical key 't0q',
that does not collide with any timeout_event_type(), but needs to
be handled in a few places to protect form abuse and to correct
the time-out count. Having it here allows for cancel_timeout/2,3
to still operate on only the Timers map, and does not cause
unnecessary rebuild of terms when updating timers
and not having any zero time-outs.
Diffstat (limited to 'lib/stdlib/test/gen_statem_SUITE.erl')
-rw-r--r-- | lib/stdlib/test/gen_statem_SUITE.erl | 8 |
1 files changed, 3 insertions, 5 deletions
diff --git a/lib/stdlib/test/gen_statem_SUITE.erl b/lib/stdlib/test/gen_statem_SUITE.erl index 76dee868e9..d656dcd048 100644 --- a/lib/stdlib/test/gen_statem_SUITE.erl +++ b/lib/stdlib/test/gen_statem_SUITE.erl @@ -931,13 +931,11 @@ state_timeout(_Config) -> [{timeout,0,4},{state_timeout,0,5}]}; (timeout, 4, {ok,3,Data}) -> %% Verify that timeout 0 is cancelled by - %% enqueued state_timeout 0 and that - %% multiple state_timeout 0 can be enqueued + %% a state_timeout 0 event and that + %% state_timeout 0 can be restarted {keep_state, {ok,4,Data}, [{state_timeout,0,6},{timeout,0,7}]}; - (state_timeout, 5, {ok,4,Data}) -> - {keep_state, {ok,5,Data}}; - (state_timeout, 6, {ok,5,{Time,From}}) -> + (state_timeout, 6, {ok,4,{Time,From}}) -> {next_state, state3, 6, [{reply,From,ok}, {state_timeout,Time,8}]} |