Boost logo

Boost Users :

From: jono (jp_at_[hidden])
Date: 2007-06-25 20:21:14


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 );
  }
}
         .
         .
         .
============================
============================
============================
============================


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