From afa039f92043f4a5dd4ed4adba007b17d82c28cb Mon Sep 17 00:00:00 2001 From: Julian Smart Date: Fri, 26 Sep 2003 10:50:58 +0000 Subject: [PATCH] Clean up event hash tables in a timely fashion git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@23928 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- include/wx/event.h | 14 ++++++++- src/common/event.cpp | 67 ++++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 78 insertions(+), 3 deletions(-) diff --git a/include/wx/event.h b/include/wx/event.h index 9f328e6c51..884475de28 100644 --- a/include/wx/event.h +++ b/include/wx/event.h @@ -2118,6 +2118,12 @@ public: // and call self->ProcessEvent() if a match was found. bool HandleEvent(wxEvent &event, wxEvtHandler *self); + // Clear table + void Clear(); + + // Clear all tables + static void ClearAll(); + protected: // Init the hash table with the entries of the static event table. void InitHashTable(); @@ -2136,6 +2142,10 @@ protected: size_t m_size; EventTypeTablePointer *m_eventTypeTable; + static wxEventHashTable* sm_first; + wxEventHashTable* m_previous; + wxEventHashTable* m_next; + DECLARE_NO_COPY_CLASS(wxEventHashTable) }; @@ -2166,7 +2176,6 @@ public: // process all pending events void ProcessPendingEvents(); - // add a #if wxUSE_THREADS bool ProcessThreadEvent(wxEvent& event); #endif @@ -2223,6 +2232,9 @@ public: void ClearEventLocker(); #endif // wxUSE_THREADS + // Avoid problems at exit by cleaning up static hash table gracefully + void ClearEventHashTable() { GetEventHashTable().Clear(); } + private: static const wxEventTableEntry sm_eventTableEntries[]; diff --git a/src/common/event.cpp b/src/common/event.cpp index 187dbf5fcd..68c063950e 100644 --- a/src/common/event.cpp +++ b/src/common/event.cpp @@ -48,6 +48,7 @@ #endif #include "wx/event.h" +#include "wx/module.h" #if wxUSE_GUI #include "wx/validate.h" @@ -119,6 +120,24 @@ wxEventHashTable wxEvtHandler::sm_eventHashTable(wxEvtHandler::sm_eventTable); const wxEventTableEntry wxEvtHandler::sm_eventTableEntries[] = { DECLARE_EVENT_TABLE_ENTRY(wxEVT_NULL, 0, 0, (wxObjectEventFunction)NULL, NULL) }; + +#ifdef __WXDEBUG__ +// Clear up event hash table contents or we can get problems +// when C++ is cleaning up the static object +class wxEventTableEntryModule: public wxModule +{ +DECLARE_DYNAMIC_CLASS(wxEventTableEntryModule) +public: + wxEventTableEntryModule() {} + bool OnInit() { return true; } + void OnExit() + { + wxEventHashTable::ClearAll(); + } +}; +IMPLEMENT_DYNAMIC_CLASS(wxEventTableEntryModule, wxModule) +#endif + // ---------------------------------------------------------------------------- // global variables // ---------------------------------------------------------------------------- @@ -717,16 +736,35 @@ wxChildFocusEvent::wxChildFocusEvent(wxWindow *win) // wxEventHashTable // ---------------------------------------------------------------------------- -static const int EVENT_TYPE_TABLE_INIT_SIZE = 31; // Not to big not to small... +static const int EVENT_TYPE_TABLE_INIT_SIZE = 31; // Not too big not too small... + +wxEventHashTable* wxEventHashTable::sm_first = NULL; wxEventHashTable::wxEventHashTable(const wxEventTable &table) : m_table(table), m_rebuildHash(true) { AllocEventTypeTable(EVENT_TYPE_TABLE_INIT_SIZE); + + m_next = sm_first; + if (m_next) + m_next->m_previous = this; + sm_first = this; } wxEventHashTable::~wxEventHashTable() +{ + if (m_next) + m_next->m_previous = m_previous; + if (m_previous) + m_previous->m_next = m_next; + if (sm_first == this) + sm_first = m_next; + + Clear(); +} + +void wxEventHashTable::Clear() { size_t i; for(i = 0; i < m_size; i++) @@ -738,7 +776,24 @@ wxEventHashTable::~wxEventHashTable() } } - delete[] m_eventTypeTable; + // Necessary in order to not invoke the + // overloaded delete operator when statics are cleaned up + if (m_eventTypeTable) + delete[] m_eventTypeTable; + + m_eventTypeTable = NULL; + m_size = 0; +} + +// Clear all tables +void wxEventHashTable::ClearAll() +{ + wxEventHashTable* table = sm_first; + while (table) + { + table->Clear(); + table = table->m_next; + } } bool wxEventHashTable::HandleEvent(wxEvent &event, wxEvtHandler *self) @@ -748,6 +803,9 @@ bool wxEventHashTable::HandleEvent(wxEvent &event, wxEvtHandler *self) InitHashTable(); m_rebuildHash = false; } + + if (!m_eventTypeTable) + return FALSE; // Find all entries for the given event type. wxEventType eventType = event.GetEventType(); @@ -806,6 +864,10 @@ void wxEventHashTable::InitHashTable() void wxEventHashTable::AddEntry(const wxEventTableEntry &entry) { + // This might happen 'accidentally' as the app is exiting + if (!m_eventTypeTable) + return; + EventTypeTablePointer *peTTnode = &m_eventTypeTable[entry.m_eventType % m_size]; EventTypeTablePointer eTTnode = *peTTnode; @@ -874,6 +936,7 @@ void wxEventHashTable::GrowEventTypeTable() delete[] oldEventTypeTable; } + // ---------------------------------------------------------------------------- // wxEvtHandler // ---------------------------------------------------------------------------- -- 2.45.2