#3963 closed Bugs (fixed)
state_machine<>::post_event is not protected
Reported by: | Owned by: | Andreas Huber | |
---|---|---|---|
Milestone: | Boost 1.43.0 | Component: | statechart |
Version: | Boost 1.42.0 | Severity: | Optimization |
Keywords: | Cc: | boost@… |
Description
According to documentation, the member function state_machine<>::post_event() is protected to ensure that it's only called from within state reactions. However, in the actual code this function is declared public, which allows to call it from outside the state machine with unknown consequences.
Change History (6)
comment:1 by , 13 years ago
Cc: | added |
---|
comment:2 by , 13 years ago
Status: | new → assigned |
---|
comment:3 by , 13 years ago
comment:4 by , 13 years ago
Resolution: | → fixed |
---|---|
Status: | assigned → closed |
(In [61048]) Fixes #3963. post_event() is now protected and forwards to post_event_impl(), which unfortunately must remain public. So, client code can still abuse the class by calling post_event_impl(), but the abuse should now be more obvious. I considered adding an assert to post_event_impl(), so that unauthorized calls from the outside could at least be detected at runtime, but it turned out that an assert requires more additional machinery than expected, which is why it was not implemented.
Thanks for the report!
comment:5 by , 12 years ago
what should i do if i want to connect multiple state machines making them interactive with each other? i used to use process_event(), and sometimes post_event() to make it happen after current state processing. i have code that guarantee all posted event will be flushed/processed later
comment:6 by , 12 years ago
Multiple state machines can interact with each other quite nicely if they derive from asynchronous_state_machine instead of state_machine. Despite the name they may also run in the same thread context or without any separate thread at all. This also avoids the need to deal with possible recursions. I used to use synchronous state machines at first, but switched over to asynchronous state machines due to this. The only disadvantage to me is that it is more difficult to access the state machine from the outside, e.g. to retrieve the current machine state for debugging purposes.
Read the part on asynchronous state machines in the tutorial for further information: http://www.boost.org/doc/libs/1_43_0/libs/statechart/doc/tutorial.html#AsynchronousStateMachines
post_event will be made protected. Unfortunately, it *must* forward to a public implementation function, because that is also called from simple_state<>::post_event and template friend support is spotty in some popular compilers. However, I'll add an assert that catches calls to the implementation function, that are made when no event is currently being processed.