Use glib thread initialization functions when glib main loop is in use

This resolves Bug 1484
pull/2/head
Timothy Pearson 11 years ago
parent 83d39cad27
commit c69c3400cb

9
configure vendored

@ -734,9 +734,6 @@ while [ "$#" -gt 0 ]; do
glibmainloop) glibmainloop)
if [ "$VAL" = "yes" ] || [ "$VAL" = "no" ]; then if [ "$VAL" = "yes" ] || [ "$VAL" = "no" ]; then
CFG_GLIBMAINLOOP="$VAL" CFG_GLIBMAINLOOP="$VAL"
if [ "$VAL" = "yes" ]; then
echo "WARNING: glib main loop support is ***incomplete*** and will cause problems with threaded applications and/or those using non-standard event loops!"
fi
else else
UNKNOWN_OPT=yes UNKNOWN_OPT=yes
fi fi
@ -2644,13 +2641,11 @@ if [ "$CFG_GLIBMAINLOOP" = "no" ]; then
elif [ "$CFG_GLIBMAINLOOP" = "yes" ]; then elif [ "$CFG_GLIBMAINLOOP" = "yes" ]; then
QMAKE_CONFIG="$QMAKE_CONFIG glibmainloop" QMAKE_CONFIG="$QMAKE_CONFIG glibmainloop"
GLIB_CFLAGS="`pkg-config --cflags glib-2.0`" GLIB_CFLAGS="`pkg-config --cflags glib-2.0` `pkg-config --cflags gthread-2.0`"
QMAKE_VARS="$QMAKE_VARS \"QMAKE_CFLAGS_GLIB=$GLIB_CFLAGS\"" QMAKE_VARS="$QMAKE_VARS \"QMAKE_CFLAGS_GLIB=$GLIB_CFLAGS\""
GLIB_LINKFLAG="`pkg-config --libs glib-2.0`" GLIB_LINKFLAG="`pkg-config --libs glib-2.0` `pkg-config --libs gthread-2.0`"
QMAKE_VARS="$QMAKE_VARS \"QMAKE_LIBS_GLIB=$GLIB_LINKFLAG\"" QMAKE_VARS="$QMAKE_VARS \"QMAKE_LIBS_GLIB=$GLIB_LINKFLAG\""
fi fi
if [ "$CFG_GIF" = "no" ]; then if [ "$CFG_GIF" = "no" ]; then
QMAKE_CONFIG="$QMAKE_CONFIG no-gif" QMAKE_CONFIG="$QMAKE_CONFIG no-gif"

@ -223,8 +223,9 @@ int QEventLoop::enterLoop()
d->shortcut = FALSE; d->shortcut = FALSE;
d->looplevel++; d->looplevel++;
while ( ! d->exitloop ) while ( ! d->exitloop ) {
processEvents( AllEvents | WaitForMore ); processEvents( AllEvents | WaitForMore );
}
d->looplevel--; d->looplevel--;
// restore the exitloop state, but if quitnow is TRUE, we need to keep // restore the exitloop state, but if quitnow is TRUE, we need to keep

@ -54,6 +54,7 @@
#include <errno.h> #include <errno.h>
#include <glib.h> #include <glib.h>
#include <sys/syscall.h>
// #define DEBUG_QT_GLIBMAINLOOP 1 // #define DEBUG_QT_GLIBMAINLOOP 1
@ -245,7 +246,6 @@ void QEventLoop::init()
#ifdef DEBUG_QT_GLIBMAINLOOP #ifdef DEBUG_QT_GLIBMAINLOOP
printf("inside init(2)\n"); printf("inside init(2)\n");
#endif #endif
} }
void QEventLoop::cleanup() void QEventLoop::cleanup()
@ -266,9 +266,8 @@ void QEventLoop::cleanup()
bool QEventLoop::processEvents( ProcessEventsFlags flags ) bool QEventLoop::processEvents( ProcessEventsFlags flags )
{ {
#ifdef DEBUG_QT_GLIBMAINLOOP #ifdef DEBUG_QT_GLIBMAINLOOP
printf("inside processEvents(1) looplevel=%d\n", d->looplevel ); printf("inside processEvents(1) looplevel=%d eventloop=%p d->ctx=%p this=%p\n", d->looplevel, QApplication::eventLoop(), d->ctx, this ); fflush(stdout);
#endif #endif
ProcessEventsFlags save_flags; ProcessEventsFlags save_flags;
@ -282,7 +281,7 @@ bool QEventLoop::processEvents( ProcessEventsFlags flags )
d->pev_flags = save_flags; d->pev_flags = save_flags;
#ifdef DEBUG_QT_GLIBMAINLOOP #ifdef DEBUG_QT_GLIBMAINLOOP
printf("inside processEvents(2) looplevel=%d rval=%d\n", d->looplevel, rval ); printf("inside processEvents(2) looplevel=%d eventloop=%p d->ctx=%p this=%p rval=%d\n", d->looplevel, QApplication::eventLoop(), d->ctx, this, rval ); fflush(stdout);
#endif #endif
return rval; // were events processed? return rval; // were events processed?

@ -51,10 +51,12 @@ typedef pthread_mutex_t Q_MUTEX_T;
#include <errno.h> #include <errno.h>
#include <sched.h> #include <sched.h>
#if defined(QT_USE_GLIBMAINLOOP)
#include <glib.h>
#endif // QT_USE_GLIBMAINLOOP
static QMutexPool *qt_thread_mutexpool = 0; static QMutexPool *qt_thread_mutexpool = 0;
#if defined(Q_C_CALLBACKS) #if defined(Q_C_CALLBACKS)
extern "C" { extern "C" {
#endif #endif
@ -121,6 +123,11 @@ void *QThreadInstance::start( void *_arg )
{ {
void **arg = (void **) _arg; void **arg = (void **) _arg;
#if defined(QT_USE_GLIBMAINLOOP)
// This is the first time we have access to the native pthread ID of this newly created thread
((QThreadInstance*)arg[1])->thread_id = pthread_self();
#endif // QT_USE_GLIBMAINLOOP
setCurrentThread( (QThread *) arg[0] ); setCurrentThread( (QThread *) arg[0] );
pthread_cleanup_push( QThreadInstance::finish, arg[1] ); pthread_cleanup_push( QThreadInstance::finish, arg[1] );
@ -390,6 +397,20 @@ void QThread::start(Priority priority)
d->args[0] = this; d->args[0] = this;
d->args[1] = d; d->args[1] = d;
#if defined(QT_USE_GLIBMAINLOOP)
// Legacy glib versions require this threading system initialization call
g_thread_init(NULL);
GThread* glib_thread_handle = g_thread_create((GThreadFunc)QThreadInstance::start, d->args, false, NULL);
if (glib_thread_handle) {
ret = 0;
}
else {
ret = -1;
}
// The correct thread_id is set in QThreadInstance::start using the value of d->args[1]
d->thread_id = NULL;
#else // QT_USE_GLIBMAINLOOP
ret = pthread_create( &d->thread_id, &attr, (QtThreadCallback)QThreadInstance::start, d->args ); ret = pthread_create( &d->thread_id, &attr, (QtThreadCallback)QThreadInstance::start, d->args );
#if defined (Q_OS_HPUX) #if defined (Q_OS_HPUX)
if (ret == EPERM) { if (ret == EPERM) {
@ -398,6 +419,7 @@ void QThread::start(Priority priority)
} }
#endif #endif
pthread_attr_destroy( &attr ); pthread_attr_destroy( &attr );
#endif // QT_USE_GLIBMAINLOOP
if ( ret ) { if ( ret ) {
#ifdef QT_CHECK_STATE #ifdef QT_CHECK_STATE
@ -444,8 +466,9 @@ bool QThread::wait( unsigned long time )
return FALSE; return FALSE;
} }
if ( d->finished || ! d->running ) if ( d->finished || ! d->running ) {
return TRUE; return TRUE;
}
int ret; int ret;
if (time != ULONG_MAX) { if (time != ULONG_MAX) {
@ -458,12 +481,15 @@ bool QThread::wait( unsigned long time )
ti.tv_nsec %= 1000000000; ti.tv_nsec %= 1000000000;
ret = pthread_cond_timedwait(&d->thread_done, &locker.mutex()->d->handle, &ti); ret = pthread_cond_timedwait(&d->thread_done, &locker.mutex()->d->handle, &ti);
} else }
else {
ret = pthread_cond_wait(&d->thread_done, &locker.mutex()->d->handle); ret = pthread_cond_wait(&d->thread_done, &locker.mutex()->d->handle);
}
#ifdef QT_CHECK_RANGE #ifdef QT_CHECK_RANGE
if (ret && ret != ETIMEDOUT) if (ret && ret != ETIMEDOUT) {
qWarning("Wait condition wait failure: %s",strerror(ret)); qWarning("Wait condition wait failure: %s",strerror(ret));
}
#endif #endif
return (ret == 0); return (ret == 0);

Loading…
Cancel
Save