Boost logo

Boost Users :

Subject: Re: [Boost-users] [MSM] stack overflow happens when there is a false-guard anonymous transition
From: Michael Caisse (boost_at_[hidden])
Date: 2010-09-06 17:44:04


  On 9/6/2010 11:54 AM, Christophe Henry wrote:
>
>> Personally, the least surprising thing (imnsho) would be that:
>>
>> 1. event is dispatched
>> 2. internal transitions are evaluated for current state
>> 3. external transitions are evaluated for current state
>> 4. hierarchy is followed up and 2/3 repeated
>> 5. if top is reached without satisfying event ... an error has
>> occurred and is acted upon as normal
> This is what is implemented for all events except for what the
> standard calls "Completion Events" (also called anonymous transitions
> in an UML book from the Booch/Rumbaugh collection).
>
>> I do not think whether a trigger is defined or not for a transition will
>> affect this behavior. Transitions without a trigger are simply
>> candidates for any event. The steps outlined above are those used for
>> transitions with triggers, no?
> I agree on the first part and disagree on the second. So, I took from
> the standard:
>
>

<snip completion transition description 15.3.14>

> So you are right and I should handle them like any other event. OTOH,
> the standard does not see them as a candidate for any event but as an
> implicit event which I have to trigger after the target state entry
> behavior. If a transition without an explicit trigger (event) is
> defined, it fires.
> And I should generate it only once, thus avoiding the overflow.
> What you suggest is a kind of an "any" take-all event, which I also
> find a good idea (I do not remember seeing it in the standard, but a
> good idea should be implemented if possible).
>
> The part of the standard which I find unpracticable is, if the guard
> rejects the completion event, how do we move out of this case? If I
> follow the standard, we would need to reenter a state, which means we
> would need a dummy event (not nice). This is why I suggest a
> process_completion() which would simply resend a completion event.
> Ok?
>
> Thanks for your (as usual) helpful insights,
>
> Christophe
>
> PS: reading again, I see that there is another implementation error in
> the current implementation, completion events have a lower priority
> than the event queue, I will change this on the way too.
> _______________________________________________

Thanks for getting me on the same page. I think completion events are
peculiar only in the sense that their event is implicitly generated.
Run-to-completion step semantics must still be obeyed as well as guards
must be evaluated only once.

If the completion event has been dispatched and it fails to take a
transition I believe the state is now quiescent (for reasons articulated
earlier).

So... how do we exit? The *only* way to exit via the completion
transition is for a completion event to be dispatched again. How can
this happen? Via a self transition (or compound transition that returns)
or via hierarchical search and a return to history.

             ----------- -----------
       ----->| | [g] | |
             | S1 |--------->| S2 |
          -->| entry/F1 | | |
          | | exit/F2 | | |
          | |__________| |_________|
          |____|
                E

So, in the example above... we enter S1 via some transition. After entry
F1 is executed the completion event is dispatched. If g evaluates as
false then we remain in S1. We cannot re-evaluate g unless the
completion event is dispatched again and we cannot dispatch the
completion event unless we meet the requirements of entering the state
and completing entry actions and "do" activities. The only way for that
to occur with the above example is taking E. Event E occurs, exit F2 is
executed, E transition code is executed, entry F1 is executed and then a
new completion event is dispatched.

I think executing process_completion is actually a violation of the
model (UML). Completion events occur based on a well defined set of
rules. Failure to take a completion transition because of a guard is by
design or implementation (intentional or a flaw). A new event must be
processed that results in a completion event to be dispatched for the
evaluation to occur again. It also rubs me wrong because
run-to-completion steps are always initiated via an event being
dispatched. process_completion would produce a second "interface" for
injecting behavior.

My recommendation would be to stick with the standard. Typically the
side affects of entry F1 or transition E will result in the evaluation
of g to true. If simply calling process_completion again results in g
becoming true it means significant state changes outside of the state
machine (or in a parallel machine). In my opinion, this would be an
indicator of a bad design. The one place where I do something similar is
when "polling" real hardware; however, I use the above configuration and
trigger E to evaluate g in a predictable manner.

As for the "wildcard" or any trigger, ROOM had this notion and I have
used it extensively over the years. In 13.3.1 you will find
AnyReceiveEvent. A transition trigger can be associated with this
message event which would specify the transition should be triggered by
receipt of any message. I don't think MSM encompasses the Communications
Package models and this may be a stretch to get working.

Thanks for your hard work on this excellent library!
michael

-- 
----------------------------------
Michael Caisse
Object Modeling Designs
www.objectmodelingdesigns.com

Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net