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
#include <unistd.h>
#include <sys/poll.h>
#include "wx/gtk/win_gtk.h"
#include <gtk/gtk.h>
@@ -50,25 +51,17 @@
wxApp *wxTheApp = (wxApp *) NULL;
wxAppInitializerFunction wxAppBase::m_appInitFn = (wxAppInitializerFunction) NULL;
extern bool g_isIdle;
bool g_mainThreadLocked = FALSE;
gint g_pendingTag = 0;
static GtkWidget *gs_RootWindow = (GtkWidget*) NULL;
//-----------------------------------------------------------------------------
// local functions
// idle system
//-----------------------------------------------------------------------------
extern "C"
{
gint wxapp_idle_callback( gpointer WXUNUSED(data) );
gint wxapp_pending_callback( gpointer WXUNUSED(data) );
}
extern bool g_isIdle;
void wxapp_install_thread_wakeup();
void wxapp_uninstall_thread_wakeup();
void wxapp_install_idle_handler();
//-----------------------------------------------------------------------------
@@ -165,29 +158,11 @@ void wxWakeUpIdle()
// 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
extern "C"
{
gint wxapp_pending_callback( gpointer WXUNUSED(data) )
static gint wxapp_pending_callback( gpointer WXUNUSED(data) )
{
if (!wxTheApp) return TRUE;
@@ -214,7 +189,7 @@ gint wxapp_pending_callback( gpointer WXUNUSED(data) )
return FALSE;
}
gint wxapp_idle_callback( gpointer WXUNUSED(data) )
static gint wxapp_idle_callback( gpointer WXUNUSED(data) )
{
if (!wxTheApp)
return TRUE;
@@ -239,7 +214,7 @@ gint wxapp_idle_callback( gpointer WXUNUSED(data) )
g_isIdle = TRUE;
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.
while (wxTheApp->ProcessIdle() && (gtk_events_pending() == 0))
;
@@ -254,69 +229,45 @@ gint wxapp_idle_callback( gpointer WXUNUSED(data) )
#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
// we are no longer within GDK's grab on the GUI
// thread so we must lock it here ourselves
gint res;
gdk_threads_enter();
wxapp_uninstall_thread_wakeup();
// unblock other threads wishing to do some GUI things
wxMutexGuiLeave();
g_mainThreadLocked = TRUE;
// wake up other threads
wxUsleep( 1 );
res = poll( (struct pollfd*) ufds, nfds, timeout );
// block other thread again
wxMutexGuiEnter();
g_mainThreadLocked = FALSE;
wxapp_install_thread_wakeup();
// release lock again
gdk_threads_leave();
return TRUE;
return res;
}
#endif // wxUSE_THREADS
} // extern "C"
#if wxUSE_THREADS
static int g_threadUninstallLevel = 0;
void wxapp_install_thread_wakeup()
void wxapp_install_idle_handler()
{
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
//-----------------------------------------------------------------------------
@@ -352,8 +303,7 @@ wxApp::wxApp()
wxapp_install_idle_handler();
#if wxUSE_THREADS
m_wakeUpTimerTag = 0;
wxapp_install_thread_wakeup();
g_main_set_poll_func( wxapp_poll_func );
#endif
m_colorCube = (unsigned char*) NULL;
@@ -366,10 +316,6 @@ wxApp::~wxApp()
{
if (m_idleTag) gtk_idle_remove( m_idleTag );
#if wxUSE_THREADS
wxapp_uninstall_thread_wakeup();
#endif
if (m_colorCube) free(m_colorCube);
}

View File

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

View File

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

View File

@@ -38,6 +38,7 @@
#endif
#include <unistd.h>
#include <sys/poll.h>
#include "wx/gtk/win_gtk.h"
#include <gtk/gtk.h>
@@ -50,25 +51,17 @@
wxApp *wxTheApp = (wxApp *) NULL;
wxAppInitializerFunction wxAppBase::m_appInitFn = (wxAppInitializerFunction) NULL;
extern bool g_isIdle;
bool g_mainThreadLocked = FALSE;
gint g_pendingTag = 0;
static GtkWidget *gs_RootWindow = (GtkWidget*) NULL;
//-----------------------------------------------------------------------------
// local functions
// idle system
//-----------------------------------------------------------------------------
extern "C"
{
gint wxapp_idle_callback( gpointer WXUNUSED(data) );
gint wxapp_pending_callback( gpointer WXUNUSED(data) );
}
extern bool g_isIdle;
void wxapp_install_thread_wakeup();
void wxapp_uninstall_thread_wakeup();
void wxapp_install_idle_handler();
//-----------------------------------------------------------------------------
@@ -165,29 +158,11 @@ void wxWakeUpIdle()
// 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
extern "C"
{
gint wxapp_pending_callback( gpointer WXUNUSED(data) )
static gint wxapp_pending_callback( gpointer WXUNUSED(data) )
{
if (!wxTheApp) return TRUE;
@@ -214,7 +189,7 @@ gint wxapp_pending_callback( gpointer WXUNUSED(data) )
return FALSE;
}
gint wxapp_idle_callback( gpointer WXUNUSED(data) )
static gint wxapp_idle_callback( gpointer WXUNUSED(data) )
{
if (!wxTheApp)
return TRUE;
@@ -239,7 +214,7 @@ gint wxapp_idle_callback( gpointer WXUNUSED(data) )
g_isIdle = TRUE;
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.
while (wxTheApp->ProcessIdle() && (gtk_events_pending() == 0))
;
@@ -254,69 +229,45 @@ gint wxapp_idle_callback( gpointer WXUNUSED(data) )
#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
// we are no longer within GDK's grab on the GUI
// thread so we must lock it here ourselves
gint res;
gdk_threads_enter();
wxapp_uninstall_thread_wakeup();
// unblock other threads wishing to do some GUI things
wxMutexGuiLeave();
g_mainThreadLocked = TRUE;
// wake up other threads
wxUsleep( 1 );
res = poll( (struct pollfd*) ufds, nfds, timeout );
// block other thread again
wxMutexGuiEnter();
g_mainThreadLocked = FALSE;
wxapp_install_thread_wakeup();
// release lock again
gdk_threads_leave();
return TRUE;
return res;
}
#endif // wxUSE_THREADS
} // extern "C"
#if wxUSE_THREADS
static int g_threadUninstallLevel = 0;
void wxapp_install_thread_wakeup()
void wxapp_install_idle_handler()
{
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
//-----------------------------------------------------------------------------
@@ -352,8 +303,7 @@ wxApp::wxApp()
wxapp_install_idle_handler();
#if wxUSE_THREADS
m_wakeUpTimerTag = 0;
wxapp_install_thread_wakeup();
g_main_set_poll_func( wxapp_poll_func );
#endif
m_colorCube = (unsigned char*) NULL;
@@ -366,10 +316,6 @@ wxApp::~wxApp()
{
if (m_idleTag) gtk_idle_remove( m_idleTag );
#if wxUSE_THREADS
wxapp_uninstall_thread_wakeup();
#endif
if (m_colorCube) free(m_colorCube);
}

View File

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

View File

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