Opened 13 years ago

Closed 13 years ago

Last modified 12 years ago

#3963 closed Bugs (fixed)

state_machine<>::post_event is not protected

Reported by: Arne Babnik <boost@…> 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 Arne Babnik <boost@…>, 13 years ago

Cc: boost@… added

comment:2 by Andreas Huber, 13 years ago

Status: newassigned

comment:3 by Andreas Huber, 13 years ago

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.

comment:4 by Andreas Huber, 13 years ago

Resolution: fixed
Status: assignedclosed

(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 xuefer@…, 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 boost@…, 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

Note: See TracTickets for help on using tickets.