From: Václav Slavík Date: Thu, 4 Nov 2004 20:04:59 +0000 (+0000) Subject: (hopefully) fixed race condition in installing idle handler (calling wxPostEvent... X-Git-Url: https://git.saurik.com/wxWidgets.git/commitdiff_plain/fe593cc504195a3c91281eae4edf5e852a51a59c?ds=sidebyside (hopefully) fixed race condition in installing idle handler (calling wxPostEvent from non-main thread) git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@30266 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- diff --git a/include/wx/gtk/app.h b/include/wx/gtk/app.h index 33b62e1c15..fd4fa6226b 100644 --- a/include/wx/gtk/app.h +++ b/include/wx/gtk/app.h @@ -56,6 +56,8 @@ public: #endif // __WXDEBUG__ gint m_idleTag; + void RemoveIdleTag(); + unsigned char *m_colorCube; // Used by the the wxGLApp and wxGLCanvas class for GL-based X visual diff --git a/include/wx/gtk1/app.h b/include/wx/gtk1/app.h index 33b62e1c15..fd4fa6226b 100644 --- a/include/wx/gtk1/app.h +++ b/include/wx/gtk1/app.h @@ -56,6 +56,8 @@ public: #endif // __WXDEBUG__ gint m_idleTag; + void RemoveIdleTag(); + unsigned char *m_colorCube; // Used by the the wxGLApp and wxGLCanvas class for GL-based X visual diff --git a/src/gtk/app.cpp b/src/gtk/app.cpp index 86822b5abd..5aa26126a7 100644 --- a/src/gtk/app.cpp +++ b/src/gtk/app.cpp @@ -34,6 +34,7 @@ #include "wx/filename.h" #include "wx/module.h" #include "wx/image.h" +#include "wx/thread.h" #ifdef __WXGPE__ #include @@ -97,6 +98,10 @@ extern bool g_isIdle; void wxapp_install_idle_handler(); +#if wxUSE_THREADS +static wxMutex gs_idleTagsMutex; +#endif + //----------------------------------------------------------------------------- // wxYield //----------------------------------------------------------------------------- @@ -132,8 +137,7 @@ bool wxApp::Yield(bool onlyIfNeeded) { // We need to remove idle callbacks or the loop will // never finish. - gtk_idle_remove( m_idleTag ); - m_idleTag = 0; + wxTheApp->RemoveIdleTag(); g_isIdle = TRUE; } @@ -211,7 +215,12 @@ static gint wxapp_pending_callback( gpointer WXUNUSED(data) ) // Sent idle event to all who request them. wxTheApp->ProcessPendingEvents(); - g_pendingTag = 0; + { +#if wxUSE_THREADS + wxMutexLocker lock(gs_idleTagsMutex); +#endif + g_pendingTag = 0; + } // Flush the logged messages if any. #if wxUSE_LOG @@ -259,8 +268,13 @@ static gint wxapp_idle_callback( gpointer WXUNUSED(data) ) // Indicate that we are now in idle mode and event handlers // will have to reinstall the idle handler again. - g_isIdle = TRUE; - wxTheApp->m_idleTag = 0; + { +#if wxUSE_THREADS + wxMutexLocker lock(gs_idleTagsMutex); +#endif + g_isIdle = TRUE; + wxTheApp->m_idleTag = 0; + } // Send idle event to all who request them as long as // no events have popped up in the event queue. @@ -368,6 +382,10 @@ static gint wxapp_poll_func( GPollFD *ufds, guint nfds, gint timeout ) void wxapp_install_idle_handler() { +#if wxUSE_THREADS + wxMutexLocker lock(gs_idleTagsMutex); +#endif + // GD: this assert is raised when using the thread sample (which works) // so the test is probably not so easy. Can widget callbacks be // triggered from child threads and, if so, for which widgets? @@ -679,3 +697,11 @@ void wxApp::OnAssert(const wxChar *file, int line, const wxChar* cond, const wxC #endif // __WXDEBUG__ +void wxApp::RemoveIdleTag() +{ +#if wxUSE_THREADS + wxMutexLocker lock(gs_idleTagsMutex); +#endif + gtk_idle_remove( wxTheApp->m_idleTag ); + wxTheApp->m_idleTag = 0; +} diff --git a/src/gtk/evtloop.cpp b/src/gtk/evtloop.cpp index d89a31d44f..429de81069 100644 --- a/src/gtk/evtloop.cpp +++ b/src/gtk/evtloop.cpp @@ -109,8 +109,7 @@ bool wxEventLoop::Pending() const { // We need to remove idle callbacks or gtk_events_pending will // never return false. - gtk_idle_remove( wxTheApp->m_idleTag ); - wxTheApp->m_idleTag = 0; + wxTheApp->RemoveIdleTag(); g_isIdle = TRUE; } diff --git a/src/gtk1/app.cpp b/src/gtk1/app.cpp index 86822b5abd..5aa26126a7 100644 --- a/src/gtk1/app.cpp +++ b/src/gtk1/app.cpp @@ -34,6 +34,7 @@ #include "wx/filename.h" #include "wx/module.h" #include "wx/image.h" +#include "wx/thread.h" #ifdef __WXGPE__ #include @@ -97,6 +98,10 @@ extern bool g_isIdle; void wxapp_install_idle_handler(); +#if wxUSE_THREADS +static wxMutex gs_idleTagsMutex; +#endif + //----------------------------------------------------------------------------- // wxYield //----------------------------------------------------------------------------- @@ -132,8 +137,7 @@ bool wxApp::Yield(bool onlyIfNeeded) { // We need to remove idle callbacks or the loop will // never finish. - gtk_idle_remove( m_idleTag ); - m_idleTag = 0; + wxTheApp->RemoveIdleTag(); g_isIdle = TRUE; } @@ -211,7 +215,12 @@ static gint wxapp_pending_callback( gpointer WXUNUSED(data) ) // Sent idle event to all who request them. wxTheApp->ProcessPendingEvents(); - g_pendingTag = 0; + { +#if wxUSE_THREADS + wxMutexLocker lock(gs_idleTagsMutex); +#endif + g_pendingTag = 0; + } // Flush the logged messages if any. #if wxUSE_LOG @@ -259,8 +268,13 @@ static gint wxapp_idle_callback( gpointer WXUNUSED(data) ) // Indicate that we are now in idle mode and event handlers // will have to reinstall the idle handler again. - g_isIdle = TRUE; - wxTheApp->m_idleTag = 0; + { +#if wxUSE_THREADS + wxMutexLocker lock(gs_idleTagsMutex); +#endif + g_isIdle = TRUE; + wxTheApp->m_idleTag = 0; + } // Send idle event to all who request them as long as // no events have popped up in the event queue. @@ -368,6 +382,10 @@ static gint wxapp_poll_func( GPollFD *ufds, guint nfds, gint timeout ) void wxapp_install_idle_handler() { +#if wxUSE_THREADS + wxMutexLocker lock(gs_idleTagsMutex); +#endif + // GD: this assert is raised when using the thread sample (which works) // so the test is probably not so easy. Can widget callbacks be // triggered from child threads and, if so, for which widgets? @@ -679,3 +697,11 @@ void wxApp::OnAssert(const wxChar *file, int line, const wxChar* cond, const wxC #endif // __WXDEBUG__ +void wxApp::RemoveIdleTag() +{ +#if wxUSE_THREADS + wxMutexLocker lock(gs_idleTagsMutex); +#endif + gtk_idle_remove( wxTheApp->m_idleTag ); + wxTheApp->m_idleTag = 0; +} diff --git a/src/gtk1/evtloop.cpp b/src/gtk1/evtloop.cpp index d89a31d44f..429de81069 100644 --- a/src/gtk1/evtloop.cpp +++ b/src/gtk1/evtloop.cpp @@ -109,8 +109,7 @@ bool wxEventLoop::Pending() const { // We need to remove idle callbacks or gtk_events_pending will // never return false. - gtk_idle_remove( wxTheApp->m_idleTag ); - wxTheApp->m_idleTag = 0; + wxTheApp->RemoveIdleTag(); g_isIdle = TRUE; }