* Added threads event propagation. Should compile on GTK (tested).

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@1986 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
Guilhem Lavaux
1999-03-27 18:50:54 +00:00
parent eedcfe5eb9
commit 7214297d16
14 changed files with 223 additions and 5 deletions

View File

@@ -78,6 +78,12 @@
#endif // !USE_SHARED_LIBRARY
#if wxUSE_THREADS
/* To put pending event handlers */
extern wxList wxPendingEvents;
extern wxCriticalSection wxPendingEventsLocker;
#endif
/*
* General wxWindows events, covering
* all interesting things that might happen (button clicking, resizing,
@@ -283,6 +289,10 @@ wxEvtHandler::wxEvtHandler()
m_enabled = TRUE;
m_dynamicEvents = (wxList *) NULL;
m_isWindow = FALSE;
#if wxUSE_THREADS
m_eventsLocker = new wxCriticalSection();
#endif
m_pendingEvents = (wxList *) NULL;
}
wxEvtHandler::~wxEvtHandler()
@@ -306,8 +316,54 @@ wxEvtHandler::~wxEvtHandler()
}
delete m_dynamicEvents;
};
if (m_pendingEvents)
delete m_pendingEvents;
#if wxUSE_THREADS
delete m_eventsLocker;
#endif
}
#if wxUSE_THREADS
bool wxEvtHandler::ProcessThreadEvent(wxEvent& event)
{
wxEvent *event_main;
wxCriticalSectionLocker locker(*m_eventsLocker);
// check that we are really in a child thread
wxASSERT( !wxThread::IsMain() );
if (m_pendingEvents == NULL)
m_pendingEvents = new wxList();
event_main = (wxEvent *)event.GetClassInfo()->CreateObject();
*event_main = event;
m_pendingEvents->Append(event_main);
wxPendingEventsLocker.Enter();
wxPendingEvents.Append(this);
wxPendingEventsLocker.Leave();
return TRUE;
}
void wxEvtHandler::ProcessPendingEvents()
{
wxCriticalSectionLocker locker(*m_eventsLocker);
wxNode *node = m_pendingEvents->First();
wxEvent *event;
while (node != NULL) {
event = (wxEvent *)node->Data();
ProcessEvent(*event);
delete node;
node = m_pendingEvents->First();
}
}
#endif
/*
* Event table stuff
*/
@@ -320,6 +376,11 @@ bool wxEvtHandler::ProcessEvent(wxEvent& event)
// An event handler can be enabled or disabled
if ( GetEvtHandlerEnabled() )
{
#if wxUSE_THREADS
// Check whether we are in a child thread.
if (!wxThread::IsMain())
return ProcessThreadEvent(event);
#endif
// Handle per-instance dynamic event tables first
if ( m_dynamicEvents && SearchDynamicEventTable(event) )

View File

@@ -46,6 +46,10 @@ wxApp *wxTheApp = (wxApp *) NULL;
wxAppInitializerFunction wxApp::m_appInitFn = (wxAppInitializerFunction) NULL;
extern wxList wxPendingDelete;
#if wxUSE_THREADS
extern wxList wxPendingEvents;
extern wxCriticalSection wxPendingEventsLocker;
#endif
extern wxResourceCache *wxTheResourceCache;
unsigned char g_palette[64*3] =
@@ -283,6 +287,10 @@ void wxApp::OnIdle( wxIdleEvent &event )
inOnIdle = TRUE;
/* Resend in the main thread events which have been prepared in other
threads */
ProcessPendingEvents();
/* 'Garbage' collection of windows deleted with Close(). */
DeletePendingObjects();
@@ -366,6 +374,25 @@ void wxApp::Dispatch()
{
}
#if wxUSE_THREADS
void wxApp::ProcessPendingEvents()
{
wxNode *node = wxPendingEvents.First();
wxCriticalSectionLocker locker(wxPendingEventsLocker);
while (node)
{
wxEvtHandler *handler = (wxEvtHandler *)node->Data();
handler->ProcessPendingEvents();
delete node;
node = wxPendingEvents.First();
}
}
#endif
void wxApp::DeletePendingObjects()
{
wxNode *node = wxPendingDelete.First();

View File

@@ -38,6 +38,12 @@ wxList wxTopLevelWindows;
/* List of windows pending deletion */
wxList wxPendingDelete;
#if wxUSE_THREADS
/* List of events pending processing */
wxList wxPendingEvents;
wxCriticalSection wxPendingEventsLocker;
#endif
/* Current cursor, in order to hang on to
* cursor handle when setting the cursor globally */
wxCursor *g_globalCursor = (wxCursor *) NULL;

View File

@@ -46,6 +46,10 @@ wxApp *wxTheApp = (wxApp *) NULL;
wxAppInitializerFunction wxApp::m_appInitFn = (wxAppInitializerFunction) NULL;
extern wxList wxPendingDelete;
#if wxUSE_THREADS
extern wxList wxPendingEvents;
extern wxCriticalSection wxPendingEventsLocker;
#endif
extern wxResourceCache *wxTheResourceCache;
unsigned char g_palette[64*3] =
@@ -283,6 +287,10 @@ void wxApp::OnIdle( wxIdleEvent &event )
inOnIdle = TRUE;
/* Resend in the main thread events which have been prepared in other
threads */
ProcessPendingEvents();
/* 'Garbage' collection of windows deleted with Close(). */
DeletePendingObjects();
@@ -366,6 +374,25 @@ void wxApp::Dispatch()
{
}
#if wxUSE_THREADS
void wxApp::ProcessPendingEvents()
{
wxNode *node = wxPendingEvents.First();
wxCriticalSectionLocker locker(wxPendingEventsLocker);
while (node)
{
wxEvtHandler *handler = (wxEvtHandler *)node->Data();
handler->ProcessPendingEvents();
delete node;
node = wxPendingEvents.First();
}
}
#endif
void wxApp::DeletePendingObjects()
{
wxNode *node = wxPendingDelete.First();

View File

@@ -38,6 +38,12 @@ wxList wxTopLevelWindows;
/* List of windows pending deletion */
wxList wxPendingDelete;
#if wxUSE_THREADS
/* List of events pending processing */
wxList wxPendingEvents;
wxCriticalSection wxPendingEventsLocker;
#endif
/* Current cursor, in order to hang on to
* cursor handle when setting the cursor globally */
wxCursor *g_globalCursor = (wxCursor *) NULL;

View File

@@ -49,6 +49,10 @@
extern char *wxBuffer;
extern wxList wxPendingDelete;
#if wxUSE_THREADS
extern wxList wxPendingEvents;
extern wxList wxPendingEventsLocker;
#endif
wxApp *wxTheApp = NULL;
@@ -411,6 +415,11 @@ void wxApp::OnIdle(wxIdleEvent& event)
// 'Garbage' collection of windows deleted with Close().
DeletePendingObjects();
#if wxUSE_THREADS
// Flush pending events.
ProcessPendingEvents();
#endif
// flush the logged messages if any
wxLog *pLog = wxLog::GetActiveTarget();
if ( pLog != NULL && pLog->HasPendingMessages() )
@@ -483,6 +492,24 @@ void wxApp::DeletePendingObjects()
}
}
#if wxUSE_THREADS
void wxApp::ProcessPendingEvents()
wxNode *node = wxPendingEvents.First();
wxCriticalSectionLocker locker(wxPendingEventsLocker);
while (node)
{
wxEvtHandler *handler = (wxEvtHandler *)node->Data();
handler->ProcessPendingEvents();
delete node;
node = wxPendingEvents.First();
}
#endif
wxLog* wxApp::CreateLogTarget()
{
return new wxLogGui;

View File

@@ -27,6 +27,12 @@ wxList wxTopLevelWindows;
// List of windows pending deletion
wxList wxPendingDelete;
#if wxUSE_THREADS
// List of events pending propagation
wxList wxPendingEvents;
wxCriticalSection wxPendingEventsLocker;
#endif
int wxPageNumber;
// GDI Object Lists

View File

@@ -92,6 +92,10 @@ extern char *wxBuffer;
extern char *wxOsVersion;
extern wxList *wxWinHandleList;
extern wxList WXDLLEXPORT wxPendingDelete;
#if wxUSE_THREADS
extern wxList wxPendingEvents;
extern wxCriticalSection wxPendingEventsLocker;
#endif
extern void wxSetKeyboardHook(bool doIt);
extern wxCursor *g_globalCursor;
@@ -893,7 +897,13 @@ int wxApp::MainLoop()
{
}
DoMessage();
// If they are pending events, we must process them.
#if wxUSE_THREADS
ProcessPendingEvents();
#endif
}
return s_currentMsg.wParam;
@@ -909,6 +919,25 @@ bool wxApp::ProcessIdle()
return event.MoreRequested();
}
#if wxUSE_THREADS
void wxApp::ProcessPendingEvents()
wxNode *node = wxPendingEvents.First();
wxCriticalSectionLocker locker(wxPendingEventsLocker);
while (node)
{
wxEvtHandler *handler = (wxEvtHandler *)node->Data();
handler->ProcessPendingEvents();
delete node;
node = wxPendingEvents.First();
}
}
#endif
void wxApp::ExitMainLoop()
{
m_keepGoing = FALSE;

View File

@@ -37,6 +37,12 @@ wxList wxTopLevelWindows;
// List of windows pending deletion
wxList WXDLLEXPORT wxPendingDelete;
// List of events pending processing
#if wxUSE_THREADS
wxList wxPendingEvents;
wxCriticalSection wxPendingEventsLocker;
#endif
// Current cursor, in order to hang on to
// cursor handle when setting the cursor globally
wxCursor *g_globalCursor = NULL;