Applied thread wakeup patch.

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@13993 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
Robert Roebling
2002-02-04 12:38:11 +00:00
parent 1e3996b1bd
commit 3133cb9f53
6 changed files with 44 additions and 180 deletions

View File

@@ -38,6 +38,7 @@
#endif #endif
#include <unistd.h> #include <unistd.h>
#include <sys/poll.h>
#include "wx/gtk/win_gtk.h" #include "wx/gtk/win_gtk.h"
#include <gtk/gtk.h> #include <gtk/gtk.h>
@@ -50,25 +51,17 @@
wxApp *wxTheApp = (wxApp *) NULL; wxApp *wxTheApp = (wxApp *) NULL;
wxAppInitializerFunction wxAppBase::m_appInitFn = (wxAppInitializerFunction) NULL; wxAppInitializerFunction wxAppBase::m_appInitFn = (wxAppInitializerFunction) NULL;
extern bool g_isIdle;
bool g_mainThreadLocked = FALSE; bool g_mainThreadLocked = FALSE;
gint g_pendingTag = 0; gint g_pendingTag = 0;
static GtkWidget *gs_RootWindow = (GtkWidget*) NULL; static GtkWidget *gs_RootWindow = (GtkWidget*) NULL;
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// local functions // idle system
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
extern "C" extern bool g_isIdle;
{
gint wxapp_idle_callback( gpointer WXUNUSED(data) );
gint wxapp_pending_callback( gpointer WXUNUSED(data) );
}
void wxapp_install_thread_wakeup();
void wxapp_uninstall_thread_wakeup();
void wxapp_install_idle_handler(); void wxapp_install_idle_handler();
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
@@ -165,29 +158,11 @@ void wxWakeUpIdle()
// local functions // local functions
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
void wxapp_install_idle_handler()
{
wxASSERT_MSG( wxTheApp->m_idleTag == 0, wxT("attempt to install idle handler twice") );
g_isIdle = FALSE;
if (g_pendingTag == 0)
g_pendingTag = gtk_idle_add_priority( 900, wxapp_pending_callback, (gpointer) NULL );
/* This routine gets called by all event handlers
indicating that the idle is over. It may also
get called from other thread for sending events
to the main thread (and processing these in
idle time). Very low priority. */
wxTheApp->m_idleTag = gtk_idle_add_priority( 1000, wxapp_idle_callback, (gpointer) NULL );
}
// the callback functions must be extern "C" to comply with GTK+ declarations // the callback functions must be extern "C" to comply with GTK+ declarations
extern "C" extern "C"
{ {
gint wxapp_pending_callback( gpointer WXUNUSED(data) ) static gint wxapp_pending_callback( gpointer WXUNUSED(data) )
{ {
if (!wxTheApp) return TRUE; if (!wxTheApp) return TRUE;
@@ -214,7 +189,7 @@ gint wxapp_pending_callback( gpointer WXUNUSED(data) )
return FALSE; return FALSE;
} }
gint wxapp_idle_callback( gpointer WXUNUSED(data) ) static gint wxapp_idle_callback( gpointer WXUNUSED(data) )
{ {
if (!wxTheApp) if (!wxTheApp)
return TRUE; return TRUE;
@@ -239,7 +214,7 @@ gint wxapp_idle_callback( gpointer WXUNUSED(data) )
g_isIdle = TRUE; g_isIdle = TRUE;
wxTheApp->m_idleTag = 0; wxTheApp->m_idleTag = 0;
// Sent idle event to all who request them as long as // Send idle event to all who request them as long as
// no events have popped up in the event queue. // no events have popped up in the event queue.
while (wxTheApp->ProcessIdle() && (gtk_events_pending() == 0)) while (wxTheApp->ProcessIdle() && (gtk_events_pending() == 0))
; ;
@@ -254,69 +229,45 @@ gint wxapp_idle_callback( gpointer WXUNUSED(data) )
#if wxUSE_THREADS #if wxUSE_THREADS
gint wxapp_wakeup_timerout_callback( gpointer WXUNUSED(data) ) static gint wxapp_poll_func( GPollFD *ufds, guint nfds, gint timeout )
{ {
// when getting called from GDK's time-out handler gint res;
// we are no longer within GDK's grab on the GUI
// thread so we must lock it here ourselves
gdk_threads_enter(); gdk_threads_enter();
wxapp_uninstall_thread_wakeup();
// unblock other threads wishing to do some GUI things
wxMutexGuiLeave(); wxMutexGuiLeave();
g_mainThreadLocked = TRUE; g_mainThreadLocked = TRUE;
// wake up other threads res = poll( (struct pollfd*) ufds, nfds, timeout );
wxUsleep( 1 );
// block other thread again
wxMutexGuiEnter(); wxMutexGuiEnter();
g_mainThreadLocked = FALSE; g_mainThreadLocked = FALSE;
wxapp_install_thread_wakeup();
// release lock again
gdk_threads_leave(); gdk_threads_leave();
return TRUE; return res;
} }
#endif // wxUSE_THREADS #endif // wxUSE_THREADS
} // extern "C" } // extern "C"
#if wxUSE_THREADS void wxapp_install_idle_handler()
static int g_threadUninstallLevel = 0;
void wxapp_install_thread_wakeup()
{ {
g_threadUninstallLevel++; wxASSERT_MSG( wxTheApp->m_idleTag == 0, wxT("attempt to install idle handler twice") );
if (g_threadUninstallLevel != 1) return; g_isIdle = FALSE;
if (wxTheApp->m_wakeUpTimerTag) return; if (g_pendingTag == 0)
g_pendingTag = gtk_idle_add_priority( 900, wxapp_pending_callback, (gpointer) NULL );
wxTheApp->m_wakeUpTimerTag = gtk_timeout_add( 50, wxapp_wakeup_timerout_callback, (gpointer) NULL ); // This routine gets called by all event handlers
// indicating that the idle is over. It may also
// get called from other thread for sending events
// to the main thread (and processing these in
// idle time). Very low priority.
wxTheApp->m_idleTag = gtk_idle_add_priority( 1000, wxapp_idle_callback, (gpointer) NULL );
} }
void wxapp_uninstall_thread_wakeup()
{
g_threadUninstallLevel--;
if (g_threadUninstallLevel != 0) return;
if (!wxTheApp->m_wakeUpTimerTag) return;
gtk_timeout_remove( wxTheApp->m_wakeUpTimerTag );
wxTheApp->m_wakeUpTimerTag = 0;
}
#endif // wxUSE_THREADS
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// Access to the root window global // Access to the root window global
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
@@ -352,8 +303,7 @@ wxApp::wxApp()
wxapp_install_idle_handler(); wxapp_install_idle_handler();
#if wxUSE_THREADS #if wxUSE_THREADS
m_wakeUpTimerTag = 0; g_main_set_poll_func( wxapp_poll_func );
wxapp_install_thread_wakeup();
#endif #endif
m_colorCube = (unsigned char*) NULL; m_colorCube = (unsigned char*) NULL;
@@ -366,10 +316,6 @@ wxApp::~wxApp()
{ {
if (m_idleTag) gtk_idle_remove( m_idleTag ); if (m_idleTag) gtk_idle_remove( m_idleTag );
#if wxUSE_THREADS
wxapp_uninstall_thread_wakeup();
#endif
if (m_colorCube) free(m_colorCube); if (m_colorCube) free(m_colorCube);
} }

View File

@@ -28,8 +28,6 @@
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
#if wxUSE_THREADS #if wxUSE_THREADS
extern void wxapp_install_thread_wakeup();
extern void wxapp_uninstall_thread_wakeup();
#endif #endif
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
@@ -341,7 +339,6 @@ void wxClipboard::Clear()
{ {
#if wxUSE_THREADS #if wxUSE_THREADS
/* disable GUI threads */ /* disable GUI threads */
wxapp_uninstall_thread_wakeup();
#endif #endif
/* As we have data we also own the clipboard. Once we no longer own /* As we have data we also own the clipboard. Once we no longer own
@@ -374,7 +371,6 @@ void wxClipboard::Clear()
#if wxUSE_THREADS #if wxUSE_THREADS
/* re-enable GUI threads */ /* re-enable GUI threads */
wxapp_install_thread_wakeup();
#endif #endif
} }
@@ -443,7 +439,6 @@ bool wxClipboard::AddData( wxDataObject *data )
#if wxUSE_THREADS #if wxUSE_THREADS
/* disable GUI threads */ /* disable GUI threads */
wxapp_uninstall_thread_wakeup();
#endif #endif
/* Tell the world we offer clipboard data */ /* Tell the world we offer clipboard data */
@@ -458,7 +453,6 @@ bool wxClipboard::AddData( wxDataObject *data )
#if wxUSE_THREADS #if wxUSE_THREADS
/* re-enable GUI threads */ /* re-enable GUI threads */
wxapp_install_thread_wakeup();
#endif #endif
return res; return res;

View File

@@ -40,8 +40,6 @@ extern bool g_isIdle;
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
#if wxUSE_THREADS #if wxUSE_THREADS
extern void wxapp_install_thread_wakeup();
extern void wxapp_uninstall_thread_wakeup();
#endif #endif
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
@@ -258,7 +256,6 @@ static gboolean target_drag_drop( GtkWidget *widget,
#if wxUSE_THREADS #if wxUSE_THREADS
/* disable GUI threads */ /* disable GUI threads */
wxapp_uninstall_thread_wakeup();
#endif #endif
GdkAtom format = drop_target->GetMatchingPair(); GdkAtom format = drop_target->GetMatchingPair();
@@ -277,7 +274,6 @@ static gboolean target_drag_drop( GtkWidget *widget,
#if wxUSE_THREADS #if wxUSE_THREADS
/* re-enable GUI threads */ /* re-enable GUI threads */
wxapp_install_thread_wakeup();
#endif #endif
} }
@@ -555,7 +551,6 @@ source_drag_data_get (GtkWidget *WXUNUSED(widget),
#if wxUSE_THREADS #if wxUSE_THREADS
/* disable GUI threads */ /* disable GUI threads */
wxapp_uninstall_thread_wakeup();
#endif #endif
gtk_selection_data_set( selection_data, gtk_selection_data_set( selection_data,
@@ -566,7 +561,6 @@ source_drag_data_get (GtkWidget *WXUNUSED(widget),
#if wxUSE_THREADS #if wxUSE_THREADS
/* enable GUI threads */ /* enable GUI threads */
wxapp_install_thread_wakeup();
#endif #endif
delete[] d; delete[] d;
@@ -801,7 +795,6 @@ wxDragResult wxDropSource::DoDragDrop( bool allowMove )
#if wxUSE_THREADS #if wxUSE_THREADS
/* disable GUI threads */ /* disable GUI threads */
wxapp_uninstall_thread_wakeup();
#endif #endif
/* don't start dragging if no button is down */ /* don't start dragging if no button is down */
@@ -832,7 +825,6 @@ wxDragResult wxDropSource::DoDragDrop( bool allowMove )
#if wxUSE_THREADS #if wxUSE_THREADS
/* re-enable GUI threads */ /* re-enable GUI threads */
wxapp_install_thread_wakeup();
#endif #endif
g_blockEventsOnDrag = FALSE; g_blockEventsOnDrag = FALSE;

View File

@@ -38,6 +38,7 @@
#endif #endif
#include <unistd.h> #include <unistd.h>
#include <sys/poll.h>
#include "wx/gtk/win_gtk.h" #include "wx/gtk/win_gtk.h"
#include <gtk/gtk.h> #include <gtk/gtk.h>
@@ -50,25 +51,17 @@
wxApp *wxTheApp = (wxApp *) NULL; wxApp *wxTheApp = (wxApp *) NULL;
wxAppInitializerFunction wxAppBase::m_appInitFn = (wxAppInitializerFunction) NULL; wxAppInitializerFunction wxAppBase::m_appInitFn = (wxAppInitializerFunction) NULL;
extern bool g_isIdle;
bool g_mainThreadLocked = FALSE; bool g_mainThreadLocked = FALSE;
gint g_pendingTag = 0; gint g_pendingTag = 0;
static GtkWidget *gs_RootWindow = (GtkWidget*) NULL; static GtkWidget *gs_RootWindow = (GtkWidget*) NULL;
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// local functions // idle system
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
extern "C" extern bool g_isIdle;
{
gint wxapp_idle_callback( gpointer WXUNUSED(data) );
gint wxapp_pending_callback( gpointer WXUNUSED(data) );
}
void wxapp_install_thread_wakeup();
void wxapp_uninstall_thread_wakeup();
void wxapp_install_idle_handler(); void wxapp_install_idle_handler();
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
@@ -165,29 +158,11 @@ void wxWakeUpIdle()
// local functions // local functions
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
void wxapp_install_idle_handler()
{
wxASSERT_MSG( wxTheApp->m_idleTag == 0, wxT("attempt to install idle handler twice") );
g_isIdle = FALSE;
if (g_pendingTag == 0)
g_pendingTag = gtk_idle_add_priority( 900, wxapp_pending_callback, (gpointer) NULL );
/* This routine gets called by all event handlers
indicating that the idle is over. It may also
get called from other thread for sending events
to the main thread (and processing these in
idle time). Very low priority. */
wxTheApp->m_idleTag = gtk_idle_add_priority( 1000, wxapp_idle_callback, (gpointer) NULL );
}
// the callback functions must be extern "C" to comply with GTK+ declarations // the callback functions must be extern "C" to comply with GTK+ declarations
extern "C" extern "C"
{ {
gint wxapp_pending_callback( gpointer WXUNUSED(data) ) static gint wxapp_pending_callback( gpointer WXUNUSED(data) )
{ {
if (!wxTheApp) return TRUE; if (!wxTheApp) return TRUE;
@@ -214,7 +189,7 @@ gint wxapp_pending_callback( gpointer WXUNUSED(data) )
return FALSE; return FALSE;
} }
gint wxapp_idle_callback( gpointer WXUNUSED(data) ) static gint wxapp_idle_callback( gpointer WXUNUSED(data) )
{ {
if (!wxTheApp) if (!wxTheApp)
return TRUE; return TRUE;
@@ -239,7 +214,7 @@ gint wxapp_idle_callback( gpointer WXUNUSED(data) )
g_isIdle = TRUE; g_isIdle = TRUE;
wxTheApp->m_idleTag = 0; wxTheApp->m_idleTag = 0;
// Sent idle event to all who request them as long as // Send idle event to all who request them as long as
// no events have popped up in the event queue. // no events have popped up in the event queue.
while (wxTheApp->ProcessIdle() && (gtk_events_pending() == 0)) while (wxTheApp->ProcessIdle() && (gtk_events_pending() == 0))
; ;
@@ -254,69 +229,45 @@ gint wxapp_idle_callback( gpointer WXUNUSED(data) )
#if wxUSE_THREADS #if wxUSE_THREADS
gint wxapp_wakeup_timerout_callback( gpointer WXUNUSED(data) ) static gint wxapp_poll_func( GPollFD *ufds, guint nfds, gint timeout )
{ {
// when getting called from GDK's time-out handler gint res;
// we are no longer within GDK's grab on the GUI
// thread so we must lock it here ourselves
gdk_threads_enter(); gdk_threads_enter();
wxapp_uninstall_thread_wakeup();
// unblock other threads wishing to do some GUI things
wxMutexGuiLeave(); wxMutexGuiLeave();
g_mainThreadLocked = TRUE; g_mainThreadLocked = TRUE;
// wake up other threads res = poll( (struct pollfd*) ufds, nfds, timeout );
wxUsleep( 1 );
// block other thread again
wxMutexGuiEnter(); wxMutexGuiEnter();
g_mainThreadLocked = FALSE; g_mainThreadLocked = FALSE;
wxapp_install_thread_wakeup();
// release lock again
gdk_threads_leave(); gdk_threads_leave();
return TRUE; return res;
} }
#endif // wxUSE_THREADS #endif // wxUSE_THREADS
} // extern "C" } // extern "C"
#if wxUSE_THREADS void wxapp_install_idle_handler()
static int g_threadUninstallLevel = 0;
void wxapp_install_thread_wakeup()
{ {
g_threadUninstallLevel++; wxASSERT_MSG( wxTheApp->m_idleTag == 0, wxT("attempt to install idle handler twice") );
if (g_threadUninstallLevel != 1) return; g_isIdle = FALSE;
if (wxTheApp->m_wakeUpTimerTag) return; if (g_pendingTag == 0)
g_pendingTag = gtk_idle_add_priority( 900, wxapp_pending_callback, (gpointer) NULL );
wxTheApp->m_wakeUpTimerTag = gtk_timeout_add( 50, wxapp_wakeup_timerout_callback, (gpointer) NULL ); // This routine gets called by all event handlers
// indicating that the idle is over. It may also
// get called from other thread for sending events
// to the main thread (and processing these in
// idle time). Very low priority.
wxTheApp->m_idleTag = gtk_idle_add_priority( 1000, wxapp_idle_callback, (gpointer) NULL );
} }
void wxapp_uninstall_thread_wakeup()
{
g_threadUninstallLevel--;
if (g_threadUninstallLevel != 0) return;
if (!wxTheApp->m_wakeUpTimerTag) return;
gtk_timeout_remove( wxTheApp->m_wakeUpTimerTag );
wxTheApp->m_wakeUpTimerTag = 0;
}
#endif // wxUSE_THREADS
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// Access to the root window global // Access to the root window global
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
@@ -352,8 +303,7 @@ wxApp::wxApp()
wxapp_install_idle_handler(); wxapp_install_idle_handler();
#if wxUSE_THREADS #if wxUSE_THREADS
m_wakeUpTimerTag = 0; g_main_set_poll_func( wxapp_poll_func );
wxapp_install_thread_wakeup();
#endif #endif
m_colorCube = (unsigned char*) NULL; m_colorCube = (unsigned char*) NULL;
@@ -366,10 +316,6 @@ wxApp::~wxApp()
{ {
if (m_idleTag) gtk_idle_remove( m_idleTag ); if (m_idleTag) gtk_idle_remove( m_idleTag );
#if wxUSE_THREADS
wxapp_uninstall_thread_wakeup();
#endif
if (m_colorCube) free(m_colorCube); if (m_colorCube) free(m_colorCube);
} }

View File

@@ -28,8 +28,6 @@
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
#if wxUSE_THREADS #if wxUSE_THREADS
extern void wxapp_install_thread_wakeup();
extern void wxapp_uninstall_thread_wakeup();
#endif #endif
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
@@ -341,7 +339,6 @@ void wxClipboard::Clear()
{ {
#if wxUSE_THREADS #if wxUSE_THREADS
/* disable GUI threads */ /* disable GUI threads */
wxapp_uninstall_thread_wakeup();
#endif #endif
/* As we have data we also own the clipboard. Once we no longer own /* As we have data we also own the clipboard. Once we no longer own
@@ -374,7 +371,6 @@ void wxClipboard::Clear()
#if wxUSE_THREADS #if wxUSE_THREADS
/* re-enable GUI threads */ /* re-enable GUI threads */
wxapp_install_thread_wakeup();
#endif #endif
} }
@@ -443,7 +439,6 @@ bool wxClipboard::AddData( wxDataObject *data )
#if wxUSE_THREADS #if wxUSE_THREADS
/* disable GUI threads */ /* disable GUI threads */
wxapp_uninstall_thread_wakeup();
#endif #endif
/* Tell the world we offer clipboard data */ /* Tell the world we offer clipboard data */
@@ -458,7 +453,6 @@ bool wxClipboard::AddData( wxDataObject *data )
#if wxUSE_THREADS #if wxUSE_THREADS
/* re-enable GUI threads */ /* re-enable GUI threads */
wxapp_install_thread_wakeup();
#endif #endif
return res; return res;

View File

@@ -40,8 +40,6 @@ extern bool g_isIdle;
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
#if wxUSE_THREADS #if wxUSE_THREADS
extern void wxapp_install_thread_wakeup();
extern void wxapp_uninstall_thread_wakeup();
#endif #endif
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
@@ -258,7 +256,6 @@ static gboolean target_drag_drop( GtkWidget *widget,
#if wxUSE_THREADS #if wxUSE_THREADS
/* disable GUI threads */ /* disable GUI threads */
wxapp_uninstall_thread_wakeup();
#endif #endif
GdkAtom format = drop_target->GetMatchingPair(); GdkAtom format = drop_target->GetMatchingPair();
@@ -277,7 +274,6 @@ static gboolean target_drag_drop( GtkWidget *widget,
#if wxUSE_THREADS #if wxUSE_THREADS
/* re-enable GUI threads */ /* re-enable GUI threads */
wxapp_install_thread_wakeup();
#endif #endif
} }
@@ -555,7 +551,6 @@ source_drag_data_get (GtkWidget *WXUNUSED(widget),
#if wxUSE_THREADS #if wxUSE_THREADS
/* disable GUI threads */ /* disable GUI threads */
wxapp_uninstall_thread_wakeup();
#endif #endif
gtk_selection_data_set( selection_data, gtk_selection_data_set( selection_data,
@@ -566,7 +561,6 @@ source_drag_data_get (GtkWidget *WXUNUSED(widget),
#if wxUSE_THREADS #if wxUSE_THREADS
/* enable GUI threads */ /* enable GUI threads */
wxapp_install_thread_wakeup();
#endif #endif
delete[] d; delete[] d;
@@ -801,7 +795,6 @@ wxDragResult wxDropSource::DoDragDrop( bool allowMove )
#if wxUSE_THREADS #if wxUSE_THREADS
/* disable GUI threads */ /* disable GUI threads */
wxapp_uninstall_thread_wakeup();
#endif #endif
/* don't start dragging if no button is down */ /* don't start dragging if no button is down */
@@ -832,7 +825,6 @@ wxDragResult wxDropSource::DoDragDrop( bool allowMove )
#if wxUSE_THREADS #if wxUSE_THREADS
/* re-enable GUI threads */ /* re-enable GUI threads */
wxapp_install_thread_wakeup();
#endif #endif
g_blockEventsOnDrag = FALSE; g_blockEventsOnDrag = FALSE;