]> git.saurik.com Git - wxWidgets.git/commitdiff
Added part of patch
authorRobert Roebling <robert@roebling.de>
Tue, 10 Oct 2006 10:28:00 +0000 (10:28 +0000)
committerRobert Roebling <robert@roebling.de>
Tue, 10 Oct 2006 10:28:00 +0000 (10:28 +0000)
  [ 1573619 ] Fix for Reentrance problems in events
  in slightly modified form.

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@41874 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775

include/wx/event.h
src/common/appbase.cpp
src/common/event.cpp

index 43ed9f4e2118038f03e00d4f0ecffe03d6893afd..e04df5470756e078c5a9b6a80ec3262420bee02c 100644 (file)
@@ -2398,7 +2398,6 @@ public:
     // add an event to be processed later
     void AddPendingEvent(wxEvent& event);
 
-    // process all pending events
     void ProcessPendingEvents();
 
 #if wxUSE_THREADS
@@ -2458,6 +2457,11 @@ public:
     void SetClientData( void *data ) { DoSetClientData(data); }
     void *GetClientData() const { return DoGetClientData(); }
 
+    // reentrance guard
+    void AllowReentrance( bool allow = true ) { m_reentranceAllowed = allow; }
+    bool IsReentranceAllowed()                { return m_reentranceAllowed; }
+    bool IsEventHandlingInProgress()          { return m_eventHandlingInProgress; } 
+    
     // check if the given event table entry matches this event and call the
     // handler if it does
     //
@@ -2527,6 +2531,9 @@ protected:
 #  endif
 #endif
 
+    bool                m_reentranceAllowed;          // Reentrance is allowed for this handler?
+    bool                m_eventHandlingInProgress;    // Eventhandling is in progress?
+    
     // Is event handler enabled?
     bool                m_enabled;
 
index 40706d3aee03a262fed7419bc8da299e89eb8351..d727ffeafd9ae47d05640d0585143bd0ab87a15b 100644 (file)
@@ -298,6 +298,15 @@ void wxAppConsole::ProcessPendingEvents()
 
     // iterate until the list becomes empty
     wxList::compatibility_iterator node = wxPendingEvents->GetFirst();
+    
+    while (node && 
+           ((wxEvtHandler *)node->GetData())->IsEventHandlingInProgress() &&
+           ((wxEvtHandler *)node->GetData())->IsReentranceAllowed() == false)
+    {   
+        // skip over event
+        node = node->GetNext();
+    }
+    
     while (node)
     {
         wxEvtHandler *handler = (wxEvtHandler *)node->GetData();
@@ -312,6 +321,14 @@ void wxAppConsole::ProcessPendingEvents()
         wxENTER_CRIT_SECT( *wxPendingEventsLocker );
 
         node = wxPendingEvents->GetFirst();
+        
+        while (node && 
+               ((wxEvtHandler *)node->GetData())->IsEventHandlingInProgress() &&
+               ((wxEvtHandler *)node->GetData())->IsReentranceAllowed() == false)
+        {   
+            // skip over event
+            node = node->GetNext();
+        }
     }
 
     wxLEAVE_CRIT_SECT( *wxPendingEventsLocker );
index 043eafa8699211c28d83049141f569e1659c2b2b..abca39a4b70081125000d6317c2c32d693c4b8ea 100644 (file)
@@ -1011,6 +1011,10 @@ wxEvtHandler::wxEvtHandler()
     m_eventsLocker = new wxCriticalSection;
 #  endif
 #endif
+    // reentrace not allowed by default
+    m_reentranceAllowed = false;
+    m_eventHandlingInProgress = false;
+    
     // no client data (yet)
     m_clientData = NULL;
     m_clientDataType = wxClientData_None;
@@ -1131,10 +1135,13 @@ void wxEvtHandler::AddPendingEvent(wxEvent& event)
 
 void wxEvtHandler::ProcessPendingEvents()
 {
-    // this method is only called by wxApp if this handler does have pending
-    // events
+    // this method is only called by wxApp if this handler does have
+    // pending events
     wxCHECK_RET( m_pendingEvents,
                  wxT("Please call wxApp::ProcessPendingEvents() instead") );
+    
+    // eventhandling is now in progess
+    m_eventHandlingInProgress = true;
 
     wxENTER_CRIT_SECT( Lock() );
 
@@ -1152,11 +1159,16 @@ void wxEvtHandler::ProcessPendingEvents()
         // It's importan we remove event from list before processing it.
         // Else a nested event loop, for example from a modal dialog, might
         // process the same event again.
+
         m_pendingEvents->Erase(node);
 
         wxLEAVE_CRIT_SECT( Lock() );
 
         ProcessEvent(*event);
+
+        // eventhandling no longer in progess
+        m_eventHandlingInProgress = false;
+        
         delete event;
 
         wxENTER_CRIT_SECT( Lock() );