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:
@@ -2118,6 +2118,12 @@ public:
|
|||||||
// and call self->ProcessEvent() if a match was found.
|
// and call self->ProcessEvent() if a match was found.
|
||||||
bool HandleEvent(wxEvent &event, wxEvtHandler *self);
|
bool HandleEvent(wxEvent &event, wxEvtHandler *self);
|
||||||
|
|
||||||
|
// Clear table
|
||||||
|
void Clear();
|
||||||
|
|
||||||
|
// Clear all tables
|
||||||
|
static void ClearAll();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
// Init the hash table with the entries of the static event table.
|
// Init the hash table with the entries of the static event table.
|
||||||
void InitHashTable();
|
void InitHashTable();
|
||||||
@@ -2136,6 +2142,10 @@ protected:
|
|||||||
size_t m_size;
|
size_t m_size;
|
||||||
EventTypeTablePointer *m_eventTypeTable;
|
EventTypeTablePointer *m_eventTypeTable;
|
||||||
|
|
||||||
|
static wxEventHashTable* sm_first;
|
||||||
|
wxEventHashTable* m_previous;
|
||||||
|
wxEventHashTable* m_next;
|
||||||
|
|
||||||
DECLARE_NO_COPY_CLASS(wxEventHashTable)
|
DECLARE_NO_COPY_CLASS(wxEventHashTable)
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -2166,7 +2176,6 @@ public:
|
|||||||
// process all pending events
|
// process all pending events
|
||||||
void ProcessPendingEvents();
|
void ProcessPendingEvents();
|
||||||
|
|
||||||
// add a
|
|
||||||
#if wxUSE_THREADS
|
#if wxUSE_THREADS
|
||||||
bool ProcessThreadEvent(wxEvent& event);
|
bool ProcessThreadEvent(wxEvent& event);
|
||||||
#endif
|
#endif
|
||||||
@@ -2223,6 +2232,9 @@ public:
|
|||||||
void ClearEventLocker();
|
void ClearEventLocker();
|
||||||
#endif // wxUSE_THREADS
|
#endif // wxUSE_THREADS
|
||||||
|
|
||||||
|
// Avoid problems at exit by cleaning up static hash table gracefully
|
||||||
|
void ClearEventHashTable() { GetEventHashTable().Clear(); }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static const wxEventTableEntry sm_eventTableEntries[];
|
static const wxEventTableEntry sm_eventTableEntries[];
|
||||||
|
|
||||||
|
@@ -48,6 +48,7 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "wx/event.h"
|
#include "wx/event.h"
|
||||||
|
#include "wx/module.h"
|
||||||
|
|
||||||
#if wxUSE_GUI
|
#if wxUSE_GUI
|
||||||
#include "wx/validate.h"
|
#include "wx/validate.h"
|
||||||
@@ -119,6 +120,24 @@ wxEventHashTable wxEvtHandler::sm_eventHashTable(wxEvtHandler::sm_eventTable);
|
|||||||
const wxEventTableEntry wxEvtHandler::sm_eventTableEntries[] =
|
const wxEventTableEntry wxEvtHandler::sm_eventTableEntries[] =
|
||||||
{ DECLARE_EVENT_TABLE_ENTRY(wxEVT_NULL, 0, 0, (wxObjectEventFunction)NULL, NULL) };
|
{ 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
|
// global variables
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
@@ -717,16 +736,35 @@ wxChildFocusEvent::wxChildFocusEvent(wxWindow *win)
|
|||||||
// wxEventHashTable
|
// 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)
|
wxEventHashTable::wxEventHashTable(const wxEventTable &table)
|
||||||
: m_table(table),
|
: m_table(table),
|
||||||
m_rebuildHash(true)
|
m_rebuildHash(true)
|
||||||
{
|
{
|
||||||
AllocEventTypeTable(EVENT_TYPE_TABLE_INIT_SIZE);
|
AllocEventTypeTable(EVENT_TYPE_TABLE_INIT_SIZE);
|
||||||
|
|
||||||
|
m_next = sm_first;
|
||||||
|
if (m_next)
|
||||||
|
m_next->m_previous = this;
|
||||||
|
sm_first = this;
|
||||||
}
|
}
|
||||||
|
|
||||||
wxEventHashTable::~wxEventHashTable()
|
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;
|
size_t i;
|
||||||
for(i = 0; i < m_size; 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)
|
bool wxEventHashTable::HandleEvent(wxEvent &event, wxEvtHandler *self)
|
||||||
@@ -748,6 +803,9 @@ bool wxEventHashTable::HandleEvent(wxEvent &event, wxEvtHandler *self)
|
|||||||
InitHashTable();
|
InitHashTable();
|
||||||
m_rebuildHash = false;
|
m_rebuildHash = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!m_eventTypeTable)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
// Find all entries for the given event type.
|
// Find all entries for the given event type.
|
||||||
wxEventType eventType = event.GetEventType();
|
wxEventType eventType = event.GetEventType();
|
||||||
@@ -806,6 +864,10 @@ void wxEventHashTable::InitHashTable()
|
|||||||
|
|
||||||
void wxEventHashTable::AddEntry(const wxEventTableEntry &entry)
|
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 *peTTnode = &m_eventTypeTable[entry.m_eventType % m_size];
|
||||||
EventTypeTablePointer eTTnode = *peTTnode;
|
EventTypeTablePointer eTTnode = *peTTnode;
|
||||||
|
|
||||||
@@ -874,6 +936,7 @@ void wxEventHashTable::GrowEventTypeTable()
|
|||||||
delete[] oldEventTypeTable;
|
delete[] oldEventTypeTable;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
// wxEvtHandler
|
// wxEvtHandler
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
|
Reference in New Issue
Block a user