X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/c72066194932cc6760f59be3de66be77798efcd6..1c7da10ebff58f95aa6eaad1a0bf8cd39a516b54:/src/gtk/app.cpp diff --git a/src/gtk/app.cpp b/src/gtk/app.cpp index 17b4f900b7..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; } @@ -164,20 +168,31 @@ bool wxApp::Yield(bool onlyIfNeeded) // wxWakeUpIdle //----------------------------------------------------------------------------- +// RR/KH: The wxMutexGui calls are not needed on GTK2 according to +// the GTK faq, http://www.gtk.org/faq/#AEN500 +// The calls to gdk_threads_enter() and leave() are specifically noted +// as not being necessary. The MutexGui calls are still left in for GTK1. +// Eliminating the MutexGui calls fixes the long-standing "random" lockup +// when using wxPostEvent (which calls WakeUpIdle) from a thread. + void wxApp::WakeUpIdle() { +#ifndef __WXGTK20__ #if wxUSE_THREADS if (!wxThread::IsMain()) wxMutexGuiEnter(); -#endif +#endif // wxUSE_THREADS_ +#endif // __WXGTK2__ if (g_isIdle) wxapp_install_idle_handler(); +#ifndef __WXGTK20__ #if wxUSE_THREADS if (!wxThread::IsMain()) wxMutexGuiLeave(); -#endif +#endif // wxUSE_THREADS_ +#endif // __WXGTK2__ } //----------------------------------------------------------------------------- @@ -200,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 @@ -248,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. @@ -357,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? @@ -668,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; +}