Fwd: Re: timeout events in Boost.Statechart
Hi Chris,
I ended up implementing timeout support with a WM_TIMER handler in the parent of the state machine class. States that can have a timeout event just pass their timeout duration to the state machine via context<>, which in turn calls SetTimer in the parent class. The WM_TIMER handler adds a timeout event to the state machine's queue.
Does the WM_TIMER handler really add the event to the queue of the state_machine subclass object? If so, then you might have introduced a race condition. WM_TIMER handlers are called in a dedicated thread, right?
Just to comment on the design, it requires that I declare state classes with "state" base class instead of simple_state, as I have to perform the context<> cast in the constructor/entry of the new state in order to set up a timeout.
Correct.
Also, like the Camera example, I implemented a post_event in the constructor/entry of some states, which also requires derivation from state,
Correct.
and awkward instancing of the event.
I don't understand. You mean the special constructor you have to add to the state, right?
Unfortunately, I'm in feasibility testing, and haven't had an opportunity to closely examine the implementation. If you think there's something I'm missing, please let me know.
See above, WM_TIMER should probably not call state_machine.process_event. Instead you should use asynchronous_machine and queue the event through the scheduler, which is thread-safe.
Would using methods (Entry/Exit) instead of the constructor/destructor ease some of these problems?
This is a somewhat controversical topic. During formal review there
were a few people who favored entry() and exit() functions over the
current ctor/dtor design.
This is related to the debate whether one should initialize
everything in the constructor or do (almost) nothing in the
constructor and have the client call Init() right after construction.
Sure, in our case entry() would be automatically called by the
library immediately after construction but it still runs counter to
established C++ practice. The problem with entry() is that it forces
you to losen your class invariants, e.g. timerId below can no longer
be const, since context<Machine>.StartTimer() could no longer be
called in the ctor (where access via context would be impossible) but
only in entry().
struct MyState : sc::state
On 8/3/07, Andreas Huber
wrote: Hi Chris
Since timeouts are so common in state machine applications, do
you
think it would make sense to support them as a specific reaction type?
The necessary infrastructure for time events is quite significant, see
http://www.boost.org/libs/statechart/doc/uml_mapping.html#TimeEvent
You basically either need an OS that supports timed callbacks, or need to implement your own scheduler, which supports the passing
of a
time at which a given event must be dispatched. Given the lacking primitives in C++, both options require significant platform abstraction effort. I always had the hope that either Boost.Thread or a futures library would provide such primitives but to my knowledge nothing has so far materialized. I *guess* Asio does offer such primitives but I have a hard time to justify that dependency just for a time event implementation.
To cut a long story short, for now you need to implement time event support yourself :-/.
HTH,
Andreas
P.S. I think this information is also interesting for other boost users, so unless you object I'll post this message on the Boost.Users list tomorrow.
participants (1)
-
Andreas Huber