Boost logo

Boost-Commit :

Subject: [Boost-commit] svn:boost r66490 - in trunk/boost/msm: back front
From: christophe.j.henry_at_[hidden]
Date: 2010-11-10 16:59:28


Author: chenry
Date: 2010-11-10 16:59:19 EST (Wed, 10 Nov 2010)
New Revision: 66490
URL: http://svn.boost.org/trac/boost/changeset/66490

Log:
fixed stack overflow when using Defer
Text files modified:
   trunk/boost/msm/back/state_machine.hpp | 30 +++++++++++++++---------------
   trunk/boost/msm/front/functor_row.hpp | 39 +++++++++++++++++++++++++++++++++------
   trunk/boost/msm/front/internal_row.hpp | 7 +++++--
   trunk/boost/msm/front/row2.hpp | 13 +++++++++----
   trunk/boost/msm/front/state_machine_def.hpp | 13 +++++++++----
   5 files changed, 71 insertions(+), 31 deletions(-)

Modified: trunk/boost/msm/back/state_machine.hpp
==============================================================================
--- trunk/boost/msm/back/state_machine.hpp (original)
+++ trunk/boost/msm/back/state_machine.hpp 2010-11-10 16:59:19 EST (Wed, 10 Nov 2010)
@@ -351,7 +351,7 @@
                 (::boost::fusion::at_key<current_state_type>(fsm.m_substate_list),evt,fsm);
 
             // then call the action method
- ROW::action_call(fsm,evt,
+ HandledEnum res = ROW::action_call(fsm,evt,
                              ::boost::fusion::at_key<current_state_type>(fsm.m_substate_list),
                              ::boost::fusion::at_key<next_state_type>(fsm.m_substate_list),
                              fsm.m_substate_list);
@@ -360,7 +360,7 @@
             convert_event_and_execute_entry<next_state_type,T2>
                 (::boost::fusion::at_key<next_state_type>(fsm.m_substate_list),evt,fsm);
             fsm.m_states[region_index]=next_state;
- return HANDLED_TRUE;
+ return res;
         }
     };
 
@@ -483,7 +483,7 @@
                 (::boost::fusion::at_key<current_state_type>(fsm.m_substate_list),evt,fsm);
 
             // then call the action method
- ROW::action_call(fsm,evt,
+ HandledEnum res = ROW::action_call(fsm,evt,
                             ::boost::fusion::at_key<current_state_type>(fsm.m_substate_list),
                             ::boost::fusion::at_key<next_state_type>(fsm.m_substate_list),
                             fsm.m_substate_list);
@@ -493,7 +493,7 @@
                 (::boost::fusion::at_key<next_state_type>(fsm.m_substate_list),evt,fsm);
 
             fsm.m_states[region_index]=next_state;
- return HANDLED_TRUE;
+ return res;
         }
     };
 
@@ -587,11 +587,11 @@
             }
 
             // call the action method
- ROW::action_call(fsm,evt,
+ HandledEnum res = ROW::action_call(fsm,evt,
                              ::boost::fusion::at_key<current_state_type>(fsm.m_substate_list),
                              ::boost::fusion::at_key<next_state_type>(fsm.m_substate_list),
                              fsm.m_substate_list);
- return HANDLED_TRUE;
+ return res;
         }
     };
 
@@ -651,12 +651,12 @@
             BOOST_ASSERT(state == (current_state));
 
             // call the action method
- ROW::action_call(fsm,evt,
+ HandledEnum res = ROW::action_call(fsm,evt,
                             ::boost::fusion::at_key<current_state_type>(fsm.m_substate_list),
                             ::boost::fusion::at_key<next_state_type>(fsm.m_substate_list),
                             fsm.m_substate_list);
 
- return HANDLED_TRUE;
+ return res;
         }
     };
     // row simply ignoring the event
@@ -710,11 +710,11 @@
             }
 
             // then call the action method
- ROW::action_call(fsm,evt,
+ HandledEnum res = ROW::action_call(fsm,evt,
                 ::boost::fusion::at_key<StateType>(fsm.m_substate_list),
                 ::boost::fusion::at_key<StateType>(fsm.m_substate_list),
                 fsm.m_substate_list);
- return HANDLED_TRUE;
+ return res;
         }
     };
     template<
@@ -728,14 +728,14 @@
         typedef typename ROW::Evt transition_event;
 
         // Take the transition action and return the next state.
- static HandledEnum execute(library_sm& fsm, int region_index, int state, transition_event const& evt)
+ static HandledEnum execute(library_sm& fsm, int, int, transition_event const& evt)
         {
             // then call the action method
- ROW::action_call(fsm,evt,
+ HandledEnum res = ROW::action_call(fsm,evt,
                 ::boost::fusion::at_key<StateType>(fsm.m_substate_list),
                 ::boost::fusion::at_key<StateType>(fsm.m_substate_list),
                 fsm.m_substate_list);
- return HANDLED_TRUE;
+ return res;
         }
     };
     template<
@@ -759,7 +759,7 @@
             return false;
         }
         // Take the transition action and return the next state.
- static HandledEnum execute(library_sm& fsm, int region_index, int state, transition_event const& evt)
+ static HandledEnum execute(library_sm& fsm, int, int, transition_event const& evt)
         {
             if (!check_guard(fsm,evt))
             {
@@ -1882,7 +1882,7 @@
          }
          template <class StateType>
          typename ::boost::disable_if<typename has_accept_sig<StateType>::type,void >::type
- visitor_helper(int id) const
+ visitor_helper(int) const
          {
              // nothing to do
          }

Modified: trunk/boost/msm/front/functor_row.hpp
==============================================================================
--- trunk/boost/msm/front/functor_row.hpp (original)
+++ trunk/boost/msm/front/functor_row.hpp 2010-11-10 16:59:19 EST (Wed, 10 Nov 2010)
@@ -15,17 +15,36 @@
 
 #include <boost/mpl/set.hpp>
 #include <boost/mpl/for_each.hpp>
+#include <boost/mpl/has_xxx.hpp>
 
 #include <boost/typeof/typeof.hpp>
 
+#include <boost/msm/back/common_types.hpp>
 #include <boost/msm/row_tags.hpp>
 #include <boost/msm/common.hpp>
 #include <boost/msm/front/completion_event.hpp>
 
 #include BOOST_TYPEOF_INCREMENT_REGISTRATION_GROUP()
 
+BOOST_MPL_HAS_XXX_TRAIT_DEF(deferring_action)
+
 namespace boost { namespace msm { namespace front
 {
+ template <class Func,class Enable=void>
+ struct get_functor_return_value
+ {
+ static const ::boost::msm::back::HandledEnum value = ::boost::msm::back::HANDLED_TRUE;
+ };
+ template <class Func>
+ struct get_functor_return_value<Func,
+ typename ::boost::enable_if<
+ typename has_deferring_action<Func>::type
+ >::type
+ >
+ {
+ static const ::boost::msm::back::HandledEnum value = ::boost::msm::back::HANDLED_DEFERRED;
+ };
+
     template <class SOURCE,class EVENT,class TARGET,class ACTION=none,class GUARD=none>
     struct Row
     {
@@ -37,10 +56,11 @@
         // action plus guard
         typedef row_tag row_type_tag;
         template <class EVT,class FSM,class SourceState,class TargetState,class AllStates>
- static void action_call(FSM& fsm,EVT const& evt,SourceState& src,TargetState& tgt, AllStates&)
+ static ::boost::msm::back::HandledEnum action_call(FSM& fsm,EVT const& evt,SourceState& src,TargetState& tgt, AllStates&)
         {
             // create functor, call it
             Action()(evt,fsm,src,tgt);
+ return get_functor_return_value<Action>::value;
         }
         template <class EVT,class FSM,class SourceState,class TargetState,class AllStates>
         static bool guard_call(FSM& fsm,EVT const& evt,SourceState& src,TargetState& tgt,AllStates&)
@@ -72,10 +92,11 @@
         // no guard
         typedef a_row_tag row_type_tag;
         template <class EVT,class FSM,class SourceState,class TargetState,class AllStates>
- static void action_call(FSM& fsm,EVT const& evt,SourceState& src,TargetState& tgt, AllStates&)
+ static ::boost::msm::back::HandledEnum action_call(FSM& fsm,EVT const& evt,SourceState& src,TargetState& tgt, AllStates&)
         {
             // create functor, call it
             Action()(evt,fsm,src,tgt);
+ return get_functor_return_value<Action>::value;
         }
     };
     template<class SOURCE,class EVENT,class TARGET,class GUARD>
@@ -107,10 +128,11 @@
         // no guard
         typedef a_irow_tag row_type_tag;
         template <class EVT,class FSM,class SourceState,class TargetState,class AllStates>
- static void action_call(FSM& fsm,EVT const& evt,SourceState& src,TargetState& tgt, AllStates&)
+ static ::boost::msm::back::HandledEnum action_call(FSM& fsm,EVT const& evt,SourceState& src,TargetState& tgt, AllStates&)
         {
             // create functor, call it
             Action()(evt,fsm,src,tgt);
+ return get_functor_return_value<Action>::value;
         }
     };
     template<class SOURCE,class EVENT,class GUARD>
@@ -141,10 +163,11 @@
         // action + guard
         typedef irow_tag row_type_tag;
         template <class EVT,class FSM,class SourceState,class TargetState,class AllStates>
- static void action_call(FSM& fsm,EVT const& evt,SourceState& src,TargetState& tgt, AllStates&)
+ static ::boost::msm::back::HandledEnum action_call(FSM& fsm,EVT const& evt,SourceState& src,TargetState& tgt, AllStates&)
         {
             // create functor, call it
             Action()(evt,fsm,src,tgt);
+ return get_functor_return_value<Action>::value;
         }
         template <class EVT,class FSM,class SourceState,class TargetState,class AllStates>
         static bool guard_call(FSM& fsm,EVT const& evt,SourceState& src,TargetState& tgt, AllStates&)
@@ -179,10 +202,11 @@
         // action plus guard
         typedef sm_i_row_tag row_type_tag;
         template <class EVT,class FSM,class SourceState,class TargetState,class AllStates>
- static void action_call(FSM& fsm,EVT const& evt,SourceState& src,TargetState& tgt, AllStates&)
+ static ::boost::msm::back::HandledEnum action_call(FSM& fsm,EVT const& evt,SourceState& src,TargetState& tgt, AllStates&)
         {
             // create functor, call it
             Action()(evt,fsm,src,tgt);
+ return get_functor_return_value<Action>::value;
         }
         template <class EVT,class FSM,class SourceState,class TargetState,class AllStates>
         static bool guard_call(FSM& fsm,EVT const& evt,SourceState& src,TargetState& tgt, AllStates&)
@@ -201,10 +225,11 @@
         // no guard
         typedef sm_a_i_row_tag row_type_tag;
         template <class EVT,class FSM,class SourceState,class TargetState,class AllStates>
- static void action_call(FSM& fsm,EVT const& evt,SourceState& src,TargetState& tgt, AllStates&)
+ static ::boost::msm::back::HandledEnum action_call(FSM& fsm,EVT const& evt,SourceState& src,TargetState& tgt, AllStates&)
         {
             // create functor, call it
             Action()(evt,fsm,src,tgt);
+ return get_functor_return_value<Action>::value;
         }
     };
     template<class EVENT,class GUARD>
@@ -304,6 +329,8 @@
     // functor pre-defined for basic functionality
     struct Defer
     {
+ // mark as deferring to avoid stack overflows in certain conditions
+ typedef int deferring_action;
         template <class EVT,class FSM,class SourceState,class TargetState>
         void operator()(EVT const& evt,FSM& fsm,SourceState& ,TargetState& ) const
         {

Modified: trunk/boost/msm/front/internal_row.hpp
==============================================================================
--- trunk/boost/msm/front/internal_row.hpp (original)
+++ trunk/boost/msm/front/internal_row.hpp 2010-11-10 16:59:19 EST (Wed, 10 Nov 2010)
@@ -14,6 +14,7 @@
 #include <boost/type_traits/is_base_of.hpp>
 #include <boost/mpl/bool.hpp>
 #include <boost/fusion/include/at_key.hpp>
+#include <boost/msm/back/common_types.hpp>
 #include <boost/msm/row_tags.hpp>
 #include <boost/msm/front/detail/row2_helper.hpp>
 
@@ -29,13 +30,14 @@
         typedef sm_a_i_row_tag row_type_tag;
         typedef Event Evt;
         template <class FSM,class SourceState,class TargetState,class AllStates>
- static void action_call(FSM& fsm,Event const& evt,SourceState& src,TargetState& tgt,
+ static ::boost::msm::back::HandledEnum action_call(FSM& fsm,Event const& evt,SourceState& src,TargetState& tgt,
                                 AllStates& all_states)
         {
             // in this front-end, we don't need to know source and target states
             ::boost::msm::front::detail::row2_action_helper<CalledForAction,Event,action>::call_helper
                 (fsm,evt,src,tgt,all_states,
                 ::boost::mpl::bool_< ::boost::is_base_of<CalledForAction,FSM>::type::value>());
+ return ::boost::msm::back::HANDLED_TRUE;
         }
     };
 
@@ -51,13 +53,14 @@
         typedef sm_i_row_tag row_type_tag;
         typedef Event Evt;
         template <class FSM,class SourceState,class TargetState,class AllStates>
- static void action_call(FSM& fsm,Event const& evt,SourceState& src,TargetState& tgt,
+ static ::boost::msm::back::HandledEnum action_call(FSM& fsm,Event const& evt,SourceState& src,TargetState& tgt,
                                 AllStates& all_states)
         {
             // in this front-end, we don't need to know source and target states
             ::boost::msm::front::detail::row2_action_helper<CalledForAction,Event,action>::call_helper
                 (fsm,evt,src,tgt,all_states,
                 ::boost::mpl::bool_< ::boost::is_base_of<CalledForAction,FSM>::type::value>());
+ return ::boost::msm::back::HANDLED_TRUE;
         }
         template <class FSM,class SourceState,class TargetState,class AllStates>
         static bool guard_call(FSM& fsm,Event const& evt,SourceState& src,TargetState& tgt,

Modified: trunk/boost/msm/front/row2.hpp
==============================================================================
--- trunk/boost/msm/front/row2.hpp (original)
+++ trunk/boost/msm/front/row2.hpp 2010-11-10 16:59:19 EST (Wed, 10 Nov 2010)
@@ -14,6 +14,7 @@
 #include <boost/type_traits/is_base_of.hpp>
 #include <boost/mpl/bool.hpp>
 #include <boost/fusion/include/at_key.hpp>
+#include <boost/msm/back/common_types.hpp>
 #include <boost/msm/row_tags.hpp>
 #include <boost/msm/front/detail/row2_helper.hpp>
 
@@ -46,13 +47,14 @@
         typedef T2 Target;
         typedef Event Evt;
         template <class FSM,class SourceState,class TargetState,class AllStates>
- static void action_call(FSM& fsm,Event const& evt,SourceState& src,TargetState& tgt,
+ static ::boost::msm::back::HandledEnum action_call(FSM& fsm,Event const& evt,SourceState& src,TargetState& tgt,
                                 AllStates& all_states)
         {
             // in this front-end, we don't need to know source and target states
             ::boost::msm::front::detail::row2_action_helper<CalledForAction,Event,action>::template call_helper
                 (fsm,evt,src,tgt,all_states,
                 ::boost::mpl::bool_< ::boost::is_base_of<CalledForAction,FSM>::type::value>());
+ return ::boost::msm::back::HANDLED_TRUE;
         }
     };
 
@@ -72,13 +74,14 @@
         typedef T2 Target;
         typedef Event Evt;
         template <class FSM,class SourceState,class TargetState, class AllStates>
- static void action_call(FSM& fsm,Event const& evt,SourceState& src,TargetState& tgt,
+ static ::boost::msm::back::HandledEnum action_call(FSM& fsm,Event const& evt,SourceState& src,TargetState& tgt,
                                 AllStates& all_states)
         {
             // in this front-end, we don't need to know source and target states
             ::boost::msm::front::detail::row2_action_helper<CalledForAction,Event,action>::call_helper
                 (fsm,evt,src,tgt,all_states,
                 ::boost::mpl::bool_< ::boost::is_base_of<CalledForAction,FSM>::type::value>());
+ return ::boost::msm::back::HANDLED_TRUE;
         }
         template <class FSM,class SourceState,class TargetState,class AllStates>
         static bool guard_call(FSM& fsm,Event const& evt,SourceState& src,TargetState& tgt,
@@ -127,13 +130,14 @@
         typedef T1 Target;
         typedef Event Evt;
         template <class FSM,class SourceState,class TargetState,class AllStates>
- static void action_call(FSM& fsm,Event const& evt,SourceState& src,TargetState& tgt,
+ static ::boost::msm::back::HandledEnum action_call(FSM& fsm,Event const& evt,SourceState& src,TargetState& tgt,
                                 AllStates& all_states)
         {
             // in this front-end, we don't need to know source and target states
             ::boost::msm::front::detail::row2_action_helper<CalledForAction,Event,action>::call_helper
                 (fsm,evt,src,tgt,all_states,
                 ::boost::mpl::bool_< ::boost::is_base_of<CalledForAction,FSM>::type::value>());
+ return ::boost::msm::back::HANDLED_TRUE;
         }
     };
 
@@ -152,13 +156,14 @@
         typedef T1 Target;
         typedef Event Evt;
         template <class FSM,class SourceState,class TargetState,class AllStates>
- static void action_call(FSM& fsm,Event const& evt,SourceState& src,TargetState& tgt,
+ static ::boost::msm::back::HandledEnum action_call(FSM& fsm,Event const& evt,SourceState& src,TargetState& tgt,
                                 AllStates& all_states)
         {
             // in this front-end, we don't need to know source and target states
             ::boost::msm::front::detail::row2_action_helper<CalledForAction,Event,action>::call_helper
                 (fsm,evt,src,tgt,all_states,
                 ::boost::mpl::bool_< ::boost::is_base_of<CalledForAction,FSM>::type::value>());
+ return ::boost::msm::back::HANDLED_TRUE;
         }
         template <class FSM,class SourceState,class TargetState,class AllStates>
         static bool guard_call(FSM& fsm,Event const& evt,SourceState& src,TargetState& tgt,

Modified: trunk/boost/msm/front/state_machine_def.hpp
==============================================================================
--- trunk/boost/msm/front/state_machine_def.hpp (original)
+++ trunk/boost/msm/front/state_machine_def.hpp 2010-11-10 16:59:19 EST (Wed, 10 Nov 2010)
@@ -19,6 +19,7 @@
 #include <boost/mpl/vector.hpp>
 
 #include <boost/msm/row_tags.hpp>
+#include <boost/msm/back/common_types.hpp>
 #include <boost/msm/front/states.hpp>
 #include <boost/msm/front/completion_event.hpp>
 #include <boost/msm/front/common_states.hpp>
@@ -51,10 +52,11 @@
         typedef T2 Target;
         typedef Event Evt;
         template <class FSM,class SourceState,class TargetState,class AllStates>
- static void action_call(FSM& fsm,Event const& evt,SourceState&,TargetState&, AllStates&)
+ static ::boost::msm::back::HandledEnum action_call(FSM& fsm,Event const& evt,SourceState&,TargetState&, AllStates&)
         {
             // in this front-end, we don't need to know source and target states
             (fsm.*action)(evt);
+ return ::boost::msm::back::HANDLED_TRUE;
         }
     };
 
@@ -85,10 +87,11 @@
         typedef T2 Target;
         typedef Event Evt;
         template <class FSM,class SourceState,class TargetState, class AllStates>
- static void action_call(FSM& fsm,Event const& evt,SourceState&,TargetState&,AllStates&)
+ static ::boost::msm::back::HandledEnum action_call(FSM& fsm,Event const& evt,SourceState&,TargetState&,AllStates&)
         {
             // in this front-end, we don't need to know source and target states
             (fsm.*action)(evt);
+ return ::boost::msm::back::HANDLED_TRUE;
         }
         template <class FSM,class SourceState,class TargetState,class AllStates>
         static bool guard_call(FSM& fsm,Event const& evt,SourceState&,TargetState&,AllStates&)
@@ -129,10 +132,11 @@
         typedef T1 Target;
         typedef Event Evt;
         template <class FSM,class SourceState,class TargetState,class AllStates>
- static void action_call(FSM& fsm,Event const& evt,SourceState&,TargetState&,AllStates&)
+ static ::boost::msm::back::HandledEnum action_call(FSM& fsm,Event const& evt,SourceState&,TargetState&,AllStates&)
         {
             // in this front-end, we don't need to know source and target states
             (fsm.*action)(evt);
+ return ::boost::msm::back::HANDLED_TRUE;
         }
     };
 
@@ -149,10 +153,11 @@
         typedef T1 Target;
         typedef Event Evt;
         template <class FSM,class SourceState,class TargetState,class AllStates>
- static void action_call(FSM& fsm,Event const& evt,SourceState&,TargetState&,AllStates&)
+ static ::boost::msm::back::HandledEnum action_call(FSM& fsm,Event const& evt,SourceState&,TargetState&,AllStates&)
         {
             // in this front-end, we don't need to know source and target states
             (fsm.*action)(evt);
+ return ::boost::msm::back::HANDLED_TRUE;
         }
         template <class FSM,class SourceState,class TargetState,class AllStates>
         static bool guard_call(FSM& fsm,Event const& evt,SourceState&,TargetState&,AllStates&)


Boost-Commit list run by bdawes at acm.org, david.abrahams at rcn.com, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk