[SVN r66410]
This commit is contained in:
Andreas Huber 2010-11-06 11:12:15 +00:00
parent 9a8435a90d
commit 7d7c895db1
5 changed files with 61 additions and 51 deletions

View File

@ -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>

View File

@ -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

View File

@ -1069,8 +1069,8 @@ void <a name="process_event" id=
<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 @@ namespace statechart
<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 @@ namespace statechart
"../../../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

View File

@ -365,7 +365,7 @@ class simple_state : public detail::simple_state_base_type< MostDerived,
{
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 @@ class simple_state : public detail::simple_state_base_type< MostDerived,
// 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;

View File

@ -272,7 +272,14 @@ class state_machine : noncopyable
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 @@ class state_machine : noncopyable
protected:
//////////////////////////////////////////////////////////////////////////
state_machine() :
eventQueueBegin_( eventQueue_.begin() ),
currentStatesEnd_( currentStates_.end() ),
pOutermostState_( 0 ),
isInnermostCommonOuter_( false ),
@ -638,26 +646,9 @@ class state_machine : noncopyable
}
void defer_event(
const event_base_type & evt,
const state_base_type * pForState )
void release_events()
{
deferredMap_[ pForState ].push_back( evt.intrusive_from_this() );
}
void release_events( const state_base_type * pForState )
{
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 @@ class state_machine : noncopyable
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 @@ class state_machine : noncopyable
{
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 @@ class state_machine : noncopyable
if ( !terminated() )
{
// this also empties deferredMap_
terminate_impl( *pOutermostState_, performFullExit );
}
eventQueue_.clear();
eventQueueBegin_ = eventQueue_.begin();
shallowHistoryMap_.clear();
deepHistoryMap_.clear();
}
@ -1075,7 +1083,7 @@ class state_machine : noncopyable
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_;