[SCXML] Execution order of onexit and cancelInvoke

Hi all,

I'd like to know if it is intended, and if so why, that first all onexit
handlers are executed and then the invoked sessions are cancelled, when
exiting a state.

The SCXML spec says:
> https://www.w3.org/TR/scxml/

> 6.4.2 Children
> ...
> If the invoking session takes a transition out of the state containing the <invoke> before it receives the 'done.invoke.id' event, the SCXML Processor MUST automatically cancel the invoked component and stop its processing. The cancel operation MUST act as if it were the final <onexit> handler in the invoking state.

and

> procedure exitStates(enabledTransitions)
> ...
> Again for each state s in the list, first execute any onexit handlers, then cancel any ongoing invocations, and finally remove s from the current configuration.
> ...
>     for s in statesToExit:
>         for content in s.onexit.sort(documentOrder):
>             executeContent(content)
>         for inv in s.invoke:
>             cancelInvoke(inv)
>         configuration.delete(s)

This seems unintuitive and error prone to me. Consider the following
example:
A state S consists of an onentry behaviour, invoke, and onexit behaviour.
o onentry: a file is opened and the file descriptor is passed on
           the invoked session
o invoke:  chunks of data are written to the file in a loop
           before each chunk, the "thread" checks if the invoked
           session should be terminated or can continue running
o onexit:  the file descriptor is closed

When entering the state, all onentry handlers are executed to completion
and (when there are no empty outgoing transitions), the new session is
invoked. When exiting, first the onexit handler is executed and then the
invoked "thread" is notified to terminate/cancel. However, it might
already fail before this because the write to file is executed on an
invalid (already closed) file descriptor.

Is this intended beavior? Shouldn't onentry/onexit "wrap" the invoked
session and onexit be only executed when the invoked session
terminated/the thread was joined?


Looking at the similar but different specification for UML state charts,
this is the case:

UML 2.2 spec (2009):
> http://www.omg.org/cgi-bin/doc.cgi?formal/2009-02-02.pdf

> doActivity: Behavior[0..1]
> An optional behavior that is executed while being in the state. The
> execution starts when this state is entered, and stops either by
> itself or when the state is exited whichever comes first.

> exit: Behavior[0..1]
> An optional behavior that is executed whenever this state is exited
> regardless of which transition was taken out of the state. If defined,
> exit actions are always executed to completion only after all internal
> activities and transition actions have completed execution.

and UML 2.5 is even more explicit:

UML 2.5 spec (2015):
> http://www.omg.org/cgi-bin/doc?formal/15-03-01.pdf

> 14.2.3.4.6  Exiting a State
> When exiting a State, regardless of whether it is simple or composite,
> the final step involved in the exit, after all other Behaviors
> associated with the exit are completed, is the execution of
> the exit Behavior of that State. If the State has a doActivity
> Behavior that is still executing when the State is exited, that
> Behavior is aborted before the exit Behavior commences execution.

Isn't this a more intuitive and expected behavior?

Thanks for any insights,

  panic

Received on Monday, 11 September 2017 14:06:19 UTC