summaryrefslogtreecommitdiff
path: root/lib/stdlib/test/gen_statem_SUITE.erl
diff options
context:
space:
mode:
authorRaimo Niskanen <raimo@erlang.org>2020-10-17 01:22:33 +0200
committerRaimo Niskanen <raimo@erlang.org>2020-10-19 14:40:45 +0200
commit6db46e96d5fc3f10d37c6c4ba4f6a211a663d971 (patch)
tree13c8b0ef100bb6db8b4cbe5240ba6ad8f69416b2 /lib/stdlib/test/gen_statem_SUITE.erl
parent4a42e03c796ee23c6f8ce479722653ad82c10a8e (diff)
downloaderlang-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.erl8
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}]}