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
This commit is contained in:
Julian Smart
2003-09-26 10:50:58 +00:00
parent fcb35beb94
commit afa039f920
2 changed files with 78 additions and 3 deletions

View File

@@ -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[];

View File

@@ -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
// ----------------------------------------------------------------------------