Boost logo

Boost-Commit :

Subject: [Boost-commit] svn:boost r66410 - in trunk: boost/statechart libs/statechart/doc
From: ahd6974-boostorg_at_[hidden]
Date: 2010-11-06 07:12:18


Author: andreas_huber69
Date: 2010-11-06 07:12:15 EDT (Sat, 06 Nov 2010)
New Revision: 66410
URL: http://svn.boost.org/trac/boost/changeset/66410

Log:
Fixes #4817.
Text files modified:
   trunk/boost/statechart/simple_state.hpp | 19 +++--------
   trunk/boost/statechart/state_machine.hpp | 62 ++++++++++++++++++++++-----------------
   trunk/libs/statechart/doc/acknowledgments.html | 11 +++---
   trunk/libs/statechart/doc/future_and_history.html | 6 +++
   trunk/libs/statechart/doc/reference.html | 14 +++++---
   5 files changed, 61 insertions(+), 51 deletions(-)

Modified: trunk/boost/statechart/simple_state.hpp
==============================================================================
--- trunk/boost/statechart/simple_state.hpp (original)
+++ trunk/boost/statechart/simple_state.hpp 2010-11-06 07:12:15 EDT (Sat, 06 Nov 2010)
@@ -365,7 +365,7 @@
       {
         if ( this->deferred_events() )
         {
- outermost_context_base().release_events( this );
+ outermost_context_base().release_events();
         }
 
         pContext_->remove_inner_state( orthogonal_position::value );
@@ -490,19 +490,12 @@
 
       // At this point we can only safely access pContext_ if the handler did
       // not return do_discard_event!
- switch ( reactionResult )
+ if ( reactionResult == detail::do_forward_event )
       {
- case detail::do_forward_event:
- // TODO: The following call to react_impl of our outer state should
- // be made with a context_type:: prefix to call directly instead of
- // virtually. For some reason the compiler complains...
- reactionResult = pContext_->react_impl( evt, eventType );
- break;
- case detail::do_defer_event:
- outermost_context_base().defer_event( evt, this );
- break;
- default:
- break;
+ // TODO: The following call to react_impl of our outer state should
+ // be made with a context_type:: prefix to call directly instead of
+ // virtually. For some reason the compiler complains...
+ reactionResult = pContext_->react_impl( evt, eventType );
       }
 
       return reactionResult;

Modified: trunk/boost/statechart/state_machine.hpp
==============================================================================
--- trunk/boost/statechart/state_machine.hpp (original)
+++ trunk/boost/statechart/state_machine.hpp 2010-11-06 07:12:15 EDT (Sat, 06 Nov 2010)
@@ -272,7 +272,14 @@
 
     void process_event( const event_base_type & evt )
     {
- send_event( evt );
+ if ( send_event( evt ) == detail::do_defer_event )
+ {
+ // Before deferring, a reaction could post other events, which still
+ // need to be processed. This is why we push the event at the front.
+ eventQueue_.push_front( evt.intrusive_from_this() );
+ eventQueueBegin_ = ++eventQueue_.begin();
+ }
+
       process_queued_events();
     }
 
@@ -408,6 +415,7 @@
   protected:
     //////////////////////////////////////////////////////////////////////////
     state_machine() :
+ eventQueueBegin_( eventQueue_.begin() ),
       currentStatesEnd_( currentStates_.end() ),
       pOutermostState_( 0 ),
       isInnermostCommonOuter_( false ),
@@ -638,26 +646,9 @@
     }
 
 
- void defer_event(
- const event_base_type & evt,
- const state_base_type * pForState )
- {
- deferredMap_[ pForState ].push_back( evt.intrusive_from_this() );
- }
-
- void release_events( const state_base_type * pForState )
+ void release_events()
     {
- const typename deferred_map_type::iterator pFound =
- deferredMap_.find( pForState );
-
- // We are not guaranteed to find an entry because a state is marked for
- // having deferred events _before_ the event is actually deferred. An
- // exception might be thrown during deferral.
- if ( pFound != deferredMap_.end() )
- {
- eventQueue_.splice( eventQueue_.end(), pFound->second );
- deferredMap_.erase( pFound );
- }
+ eventQueueBegin_ = eventQueue_.begin();
     }
 
 
@@ -880,7 +871,7 @@
     friend class terminator;
 
 
- void send_event( const event_base_type & evt )
+ detail::reaction_result send_event( const event_base_type & evt )
     {
       terminator guard( *this, &evt );
       BOOST_ASSERT( get_pointer( pOutermostUnstableState_ ) == 0 );
@@ -908,16 +899,33 @@
       {
         polymorphic_downcast< MostDerived * >( this )->unconsumed_event( evt );
       }
+
+ return reactionResult;
     }
 
 
     void process_queued_events()
     {
- while ( !eventQueue_.empty() )
+ while ( eventQueueBegin_ != eventQueue_.end() )
       {
- const event_base_ptr_type pCurrentEvent( eventQueue_.front() );
- eventQueue_.pop_front();
- send_event( *pCurrentEvent );
+ const event_base_ptr_type pCurrentEvent( *eventQueueBegin_ );
+
+ try
+ {
+ if ( send_event( *pCurrentEvent ) == detail::do_defer_event )
+ {
+ ++eventQueueBegin_;
+ }
+ else
+ {
+ eventQueueBegin_ = eventQueue_.erase( eventQueueBegin_ );
+ }
+ }
+ catch ( ... )
+ {
+ eventQueueBegin_ = eventQueue_.erase( eventQueueBegin_ );
+ throw;
+ }
       }
     }
 
@@ -928,11 +936,11 @@
 
       if ( !terminated() )
       {
- // this also empties deferredMap_
         terminate_impl( *pOutermostState_, performFullExit );
       }
 
       eventQueue_.clear();
+ eventQueueBegin_ = eventQueue_.begin();
       shallowHistoryMap_.clear();
       deepHistoryMap_.clear();
     }
@@ -1075,7 +1083,7 @@
 
 
     event_queue_type eventQueue_;
- deferred_map_type deferredMap_;
+ typename event_queue_type::iterator eventQueueBegin_;
     state_list_type currentStates_;
     typename state_list_type::iterator currentStatesEnd_;
     state_base_type * pOutermostState_;

Modified: trunk/libs/statechart/doc/acknowledgments.html
==============================================================================
--- trunk/libs/statechart/doc/acknowledgments.html (original)
+++ trunk/libs/statechart/doc/acknowledgments.html 2010-11-06 07:12:15 EDT (Sat, 06 Nov 2010)
@@ -80,6 +80,8 @@
 
     <li>Joaqu&iacute;n M L&oacute;pez Mu&ntilde;oz for his broken allocator
     workaround in boost/detail/allocator_utilities.hpp</li>
+
+ <li>Igor R for uncovering and reporting several bugs</li>
   </ul>
 
   <p>Thanks for feedback and/or encouragement go to:</p>
@@ -90,17 +92,16 @@
   Gregor, Gustavo Guerra, Aleksey Gurtovoy, Federico J. Fern&aacute;ndez,
   Iain K. Hanson, Steve Hawkes, David B. Held, J&uuml;rgen Hunold, Sean
   Kelly, Oliver Kowalke, Thomas Mathys, Simon Meiklejohn, Jiang Miao, Johan
- Nilsson, Matthieu Paindavoine, Chris Paulse, Igor R, Yuval Ronen, Chris
- Russell, Bryan Silverthorn, Rob Stewart, Kwee Heong Tan, Marcin Tustin,
- Vincent N. Virgilio, Gang Wang, Steven Watanabe, Richard Webb and Scott
- Woods.</p>
+ Nilsson, Matthieu Paindavoine, Chris Paulse, Yuval Ronen, Chris Russell,
+ Bryan Silverthorn, Rob Stewart, Kwee Heong Tan, Marcin Tustin, Vincent N.
+ Virgilio, Gang Wang, Steven Watanabe, Richard Webb and Scott Woods.</p>
   <hr>
 
   <p><a href="http://validator.w3.org/check?uri=referer"><img border="0" src=
   "../../../doc/images/valid-html401.png" alt="Valid HTML 4.01 Transitional"
   height="31" width="88"></a></p>
 
- <p>Revised 04 April, 2010</p>
+ <p>Revised 06 November, 2010</p>
 
   <p><i>Copyright &copy; 2003-2010 <a href="contact.html">Andreas Huber
   D&ouml;nni</a></i></p>

Modified: trunk/libs/statechart/doc/future_and_history.html
==============================================================================
--- trunk/libs/statechart/doc/future_and_history.html (original)
+++ trunk/libs/statechart/doc/future_and_history.html 2010-11-06 07:12:15 EDT (Sat, 06 Nov 2010)
@@ -127,6 +127,12 @@
 
   <p>(<font color="#FF0000">red</font> = points raised during formal
   review)</p>
+ <p>1.46.0</p>
+ <ul>
+ <li>Fixed Bug #4817 (The order of deferred events is not preserved under
+ certain circumstances), reported by Igor R</li>
+ </ul>
+
   <p>1.43.0</p>
   <ul>
     <li>Generalized the context() functions so that they can also return a

Modified: trunk/libs/statechart/doc/reference.html
==============================================================================
--- trunk/libs/statechart/doc/reference.html (original)
+++ trunk/libs/statechart/doc/reference.html 2010-11-06 07:12:15 EDT (Sat, 06 Nov 2010)
@@ -1069,8 +1069,8 @@
     <li>If the return value of <code>ExceptionTranslator::operator()()</code>
     is equal to the one of <code>simple_state&lt;&gt;::defer_event()</code>
     then the return value of <code>currentEvent.<a href=
- "#intrusive_from_this">intrusive_from_this</a>()</code> is stored in a
- state-specific queue. Continues with step 11</li>
+ "#intrusive_from_this">intrusive_from_this</a>()</code> is stored in the
+ deferred events queue. Continues with step 11</li>
 
     <li>If the return value of <code>ExceptionTranslator::operator()()</code>
     is equal to the one of <code>simple_state&lt;&gt;::discard_event()</code>
@@ -2160,8 +2160,10 @@
 <a name="simple_statedtor" id="simple_statedtor">~simple_state</a>();
 </pre>
 
- <p><b>Effects</b>: Pushes all events deferred by the state into the posted
- events queue</p>
+ <p><b>Effects</b>: If the state has deferral reactions of which at least
+ one has been triggered during the lifetime of the state then the contents
+ of the deferred events queue is moved to the front of the posted events
+ queue.</p>
 
   <h3>Class template <code>simple_state</code> modifier functions</h3>
   <pre>
@@ -3579,9 +3581,9 @@
   "../../../doc/images/valid-html401.png" alt="Valid HTML 4.01 Transitional"
   height="31" width="88"></a></p>
 
- <p>Revised 06 January, 2008</p>
+ <p>Revised 06 November, 2010</p>
 
- <p><i>Copyright &copy; 2003-2008 <a href="contact.html">Andreas Huber
+ <p><i>Copyright &copy; 2003-2010 <a href="contact.html">Andreas Huber
   D&ouml;nni</a></i></p>
 
   <p><i>Distributed under the Boost Software License, Version 1.0. (See


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