From f7d8cefd72ea2b213af5a4a6f8b2fc41d350c9a5 Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Sun, 25 Jan 2009 14:21:23 +0000 Subject: [PATCH] notify the timers outside of loop over m_timers to avoid crashes if a timer event hanlder modifies the timers list (#10094) git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@58396 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- src/unix/timerunx.cpp | 31 ++++++++++++++++++++++--------- 1 file changed, 22 insertions(+), 9 deletions(-) diff --git a/src/unix/timerunx.cpp b/src/unix/timerunx.cpp index d6ee503df5..bcdebf9167 100644 --- a/src/unix/timerunx.cpp +++ b/src/unix/timerunx.cpp @@ -31,6 +31,7 @@ #include "wx/apptrait.h" #include "wx/longlong.h" +#include "wx/vector.h" #include #include @@ -139,13 +140,12 @@ bool wxTimerScheduler::NotifyExpired() if ( m_timers.empty() ) return false; - bool notified = false; - const wxUsecClock_t now = wxGetLocalTimeUsec(); - wxTimerList::iterator cur, - next; - for ( cur = m_timers.begin(); cur != m_timers.end(); cur = next ) + typedef wxVector TimerImpls; + TimerImpls toNotify; + for ( wxTimerList::iterator next, + cur = m_timers.begin(); cur != m_timers.end(); cur = next ) { wxTimerSchedule * const s = *cur; if ( s->m_expiration > now ) @@ -182,12 +182,25 @@ bool wxTimerScheduler::NotifyExpired() DoAddTimer(s); } - // and finally notify the timer - timer->Notify(); - notified = true; + // we can't notify the timer from this loop as the timer event handler + // could modify m_timers (for example, but not only, by stopping this + // timer) which would render our iterators invalid, so do it after the + // loop end + toNotify.push_back(timer); + } + + if ( toNotify.empty() ) + return false; + + for ( TimerImpls::const_iterator i = toNotify.begin(), + end = toNotify.end(); + i != end; + ++i ) + { + (*i)->Notify(); } - return notified; + return true; } // ============================================================================ -- 2.45.2