From 5fa150e233fa449ee270ac26ecf074f5c40acb1e Mon Sep 17 00:00:00 2001 From: Robert Roebling Date: Tue, 10 Oct 2006 10:28:00 +0000 Subject: [PATCH] Added part of patch [ 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 | 9 ++++++++- src/common/appbase.cpp | 17 +++++++++++++++++ src/common/event.cpp | 16 ++++++++++++++-- 3 files changed, 39 insertions(+), 3 deletions(-) diff --git a/include/wx/event.h b/include/wx/event.h index 43ed9f4e21..e04df54707 100644 --- a/include/wx/event.h +++ b/include/wx/event.h @@ -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; diff --git a/src/common/appbase.cpp b/src/common/appbase.cpp index 40706d3aee..d727ffeafd 100644 --- a/src/common/appbase.cpp +++ b/src/common/appbase.cpp @@ -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 ); diff --git a/src/common/event.cpp b/src/common/event.cpp index 043eafa869..abca39a4b7 100644 --- a/src/common/event.cpp +++ b/src/common/event.cpp @@ -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() ); -- 2.45.2