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
This commit is contained in:
Robert Roebling 2006-10-10 10:28:00 +00:00
parent 6f1db55b94
commit 5fa150e233
3 changed files with 39 additions and 3 deletions

View File

@ -2398,7 +2398,6 @@ public:
// add an event to be processed later // add an event to be processed later
void AddPendingEvent(wxEvent& event); void AddPendingEvent(wxEvent& event);
// process all pending events
void ProcessPendingEvents(); void ProcessPendingEvents();
#if wxUSE_THREADS #if wxUSE_THREADS
@ -2458,6 +2457,11 @@ public:
void SetClientData( void *data ) { DoSetClientData(data); } void SetClientData( void *data ) { DoSetClientData(data); }
void *GetClientData() const { return DoGetClientData(); } 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 // check if the given event table entry matches this event and call the
// handler if it does // handler if it does
// //
@ -2527,6 +2531,9 @@ protected:
# endif # endif
#endif #endif
bool m_reentranceAllowed; // Reentrance is allowed for this handler?
bool m_eventHandlingInProgress; // Eventhandling is in progress?
// Is event handler enabled? // Is event handler enabled?
bool m_enabled; bool m_enabled;

View File

@ -298,6 +298,15 @@ void wxAppConsole::ProcessPendingEvents()
// iterate until the list becomes empty // iterate until the list becomes empty
wxList::compatibility_iterator node = wxPendingEvents->GetFirst(); 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) while (node)
{ {
wxEvtHandler *handler = (wxEvtHandler *)node->GetData(); wxEvtHandler *handler = (wxEvtHandler *)node->GetData();
@ -312,6 +321,14 @@ void wxAppConsole::ProcessPendingEvents()
wxENTER_CRIT_SECT( *wxPendingEventsLocker ); wxENTER_CRIT_SECT( *wxPendingEventsLocker );
node = wxPendingEvents->GetFirst(); node = wxPendingEvents->GetFirst();
while (node &&
((wxEvtHandler *)node->GetData())->IsEventHandlingInProgress() &&
((wxEvtHandler *)node->GetData())->IsReentranceAllowed() == false)
{
// skip over event
node = node->GetNext();
}
} }
wxLEAVE_CRIT_SECT( *wxPendingEventsLocker ); wxLEAVE_CRIT_SECT( *wxPendingEventsLocker );

View File

@ -1011,6 +1011,10 @@ wxEvtHandler::wxEvtHandler()
m_eventsLocker = new wxCriticalSection; m_eventsLocker = new wxCriticalSection;
# endif # endif
#endif #endif
// reentrace not allowed by default
m_reentranceAllowed = false;
m_eventHandlingInProgress = false;
// no client data (yet) // no client data (yet)
m_clientData = NULL; m_clientData = NULL;
m_clientDataType = wxClientData_None; m_clientDataType = wxClientData_None;
@ -1131,10 +1135,13 @@ void wxEvtHandler::AddPendingEvent(wxEvent& event)
void wxEvtHandler::ProcessPendingEvents() void wxEvtHandler::ProcessPendingEvents()
{ {
// this method is only called by wxApp if this handler does have pending // this method is only called by wxApp if this handler does have
// events // pending events
wxCHECK_RET( m_pendingEvents, wxCHECK_RET( m_pendingEvents,
wxT("Please call wxApp::ProcessPendingEvents() instead") ); wxT("Please call wxApp::ProcessPendingEvents() instead") );
// eventhandling is now in progess
m_eventHandlingInProgress = true;
wxENTER_CRIT_SECT( Lock() ); wxENTER_CRIT_SECT( Lock() );
@ -1152,11 +1159,16 @@ void wxEvtHandler::ProcessPendingEvents()
// It's importan we remove event from list before processing it. // It's importan we remove event from list before processing it.
// Else a nested event loop, for example from a modal dialog, might // Else a nested event loop, for example from a modal dialog, might
// process the same event again. // process the same event again.
m_pendingEvents->Erase(node); m_pendingEvents->Erase(node);
wxLEAVE_CRIT_SECT( Lock() ); wxLEAVE_CRIT_SECT( Lock() );
ProcessEvent(*event); ProcessEvent(*event);
// eventhandling no longer in progess
m_eventHandlingInProgress = false;
delete event; delete event;
wxENTER_CRIT_SECT( Lock() ); wxENTER_CRIT_SECT( Lock() );