[erlang-questions] gen_statem next_event queue question

Raimo Niskanen <>
Mon Sep 12 15:52:16 CEST 2016

On Mon, Sep 12, 2016 at 04:23:10AM -0700, Kenneth Lakin wrote:
> On 09/12/2016 03:07 AM, Ingela Andin wrote:
> > If you send an event to yourself (gen_statem:call/cast or !) it will end up
> > last in in the queue.
> Sorry, I should have been more clear in my initial message.
> It seems to me that -conceptually- gen_statem has three queues:
> * The next_event queue (which actually seems to behave like a stack)
> * The "postpone" queue (which -I think- gets put at the front of the
> next_event queue (but _after_ any {next_event...} actions passed along
> in the state transition tuple) on state machine state change)
> * The regular process mailbox
> Is this wildly incorrect?

No, it is fairly correct.  Apart from the normal process mailbox it has got
one queue (the postponed queue) but keeps track of the current position
in that queue, so that could be counted as two queues :-/

But you can only insert events at the current position (if you do not
change states) or at the queue head (if you change states).  There is also
the special case of a timeout 0 action that inserts an event at the tail of
the queue.

> If my understanding is correct, then call/cast/! will put the message at
> the tail of the process mailbox, yes? Additionally, does gen_statem

That is correct.  It is probably not what you want.

> provide the tools to put a message at the tail of the next_event queue,
> rather than the head? Or are we only provided with the means to add
> events to the head of the next_event queue?

Adding events to the tail of the next_event queue is a missing feature,
partly because there is no next_event queue.  Events can now only be added to
the current position in the postponed queue which could be described as the
head of the next_event queue.

If we would add events to the tail of the postponed queue they would be
inserted before all messages in the process mailbox, but after all postponed
events.  This is what a timeout 0 action does.

It was deemed that adding events as the immediately next to process was the
most useful.  And since there is only one event queue there is no defined
position of after all next_event events; they can not be distinguished when
they are in the queue...

So if you are sure to not have any postponed events you might use the
timeout 0 action as an ugly workaround.  It seems you have a really tricky
problem; can you rewrite to use additional states, or set a state variable
to remember what to do at the last inserted event?

Best Regards

/ Raimo Niskanen, Erlang/OTP, Ericsson AB

More information about the erlang-questions mailing list