Fix crash when unbinding event handlers from other handlers

Calling Unbind() on another handler from the currently executing handler which
had been bound after (and hence executed before) the handler being unbound
resulted in a crash previously as the iterators used in the loop over all
dynamic event handlers became invalid.

Fix this by storing the dynamic event table entries in a vector instead of a
list (which is also more memory and speed efficient anyhow) and null the
deleted entries instead of removing them to avoid invalidating the iterators
and only really remove them once we finish iterating.

Closes #17229.
This commit is contained in:
Vadim Zeitlin
2015-11-17 15:46:38 +01:00
parent 929b077894
commit 99d9a81e28
4 changed files with 175 additions and 56 deletions

View File

@@ -3587,8 +3587,6 @@ public:
userData);
}
wxList* GetDynamicEventTable() const { return m_dynamicEvents ; }
// User data can be associated with each wxEvtHandler
void SetClientObject( wxClientData *data ) { DoSetClientObject(data); }
wxClientData *GetClientObject() const { return DoGetClientObject(); }
@@ -3610,6 +3608,14 @@ public:
wxEvtHandler *handler,
wxEvent& event);
// Allow iterating over all connected dynamic event handlers: you must pass
// the same "cookie" to GetFirst() and GetNext() and call them until null
// is returned.
//
// These functions are for internal use only.
wxDynamicEventTableEntry* GetFirstDynamicEntry(size_t& cookie) const;
wxDynamicEventTableEntry* GetNextDynamicEntry(size_t& cookie) const;
virtual bool SearchEventTable(wxEventTable& table, wxEvent& event);
bool SearchDynamicEventTable( wxEvent& event );
@@ -3680,7 +3686,10 @@ protected:
wxEvtHandler* m_nextHandler;
wxEvtHandler* m_previousHandler;
wxList* m_dynamicEvents;
typedef wxVector<wxDynamicEventTableEntry*> DynamicEvents;
DynamicEvents* m_dynamicEvents;
wxList* m_pendingEvents;
#if wxUSE_THREADS