hi all. i'm using boost::state_chart in a serial protocol handler. i have some code that collects characters in each state object by calling Protocol::input(byte) on the state machine, which then dispatches events in response to control bytes and for all other bytes, calls ICharacterInput .... . . state_cast< const ICharacterInput & >().input(c); . . ... which stores the new character in the base class ICharacterInput. i then process the stored characters in the the state's destructor. i've used very similar boost code in a number of protocol handlers and it works great. ...but.. this handler intermittently throws exceptions in boost/statechart/simple_state.hpp when it tries to downcast and delete a pointer to the state. does anybody have any suggestions where i should look to see what's going on? in particular, is the downcast/delete sequence going to be calling any code in my own base class destructors? the destructor in which the exception is thrown (and caught) seems to complete its own instructions without problems. this protocol only uses the EvStartOfHeader and EvEndOfText events. cheers jono poff ==================================================== ==================================================== ===================================== my header file ... struct EvStartOfHeader : sc::event< EvStartOfHeader > {}; struct EvStartOfText : sc::event< EvStartOfText > {}; struct EvEndOfText : sc::event< EvEndOfText > {}; struct EvEndOfTransmission : sc::event< EvEndOfTransmission > {}; struct EvReset : sc::event< EvReset > {}; struct Waiting; struct Decoding; struct Reset; struct RcvHeader; struct RcvText; struct Protocol: sc::state_machine< Protocol, Waiting > , IProtocol { Protocol(); ~Protocol(); virtual const char **input(byte c); }; struct Waiting : ICharacterInput, sc::state< Waiting, Protocol> { Waiting( my_context ctx ); ~Waiting(); typedef sc::transition< EvStartOfHeader, Decoding > reactions; }; struct Decoding: ICharacterInput, sc::state< Decoding, Protocol, RcvText> { Decoding( my_context ctx ); ~Decoding(); typedef sc::transition< EvReset, Waiting > reactions; }; struct RcvHeader : ICharacterInput, sc::state< RcvHeader, Decoding> { RcvHeader( my_context ctx ); ~RcvHeader(); typedef sc::transition< EvStartOfText, RcvText > reactions; }; struct RcvText : ICharacterInput, sc::state< RcvText, Decoding> { RcvText( my_context ctx ); ~RcvText(); typedef sc::transition< EvEndOfText, Waiting > reactions; }; ======================================================= ======================================================= ======================================================= ======================================================= ======== so what happens is: ======== in my dispatch code ... . . case ETX:// End of Text process_event( EvEndOfText() ); . . ======== results in ... . . =========================================== =========================================== == in boost/statechart/simple_state.hpp ... ======== ======== ======== a call to simple_state::exit_impl() {...} ======== results in call to .... . . intrusive_ptr & operator=(T * rhs) { this_type(rhs).swap(*this); return *this; } . . ======== with rhs == 0 ======== then delete throws here ... . . . template< class MostDerived, class Context, class InnerInitial, history_mode historyMode > inline void intrusive_ptr_release( const ::boost::statechart::simple_state< MostDerived, Context, InnerInitial, historyMode > * pBase ) { if ( pBase->release() ) { // The cast is necessary because the simple_state destructor is non- // virtual (and inaccessible from this context) delete polymorphic_downcast< const MostDerived * >( pBase ); } } . . . ============================ ============================ ============================ ============================
participants (1)
-
jono