diff options
Diffstat (limited to 'src/kernel')
| -rw-r--r-- | src/kernel/qeventloop.cpp | 3 | ||||
| -rw-r--r-- | src/kernel/qeventloop_x11_glib.cpp | 85 | ||||
| -rw-r--r-- | src/kernel/qthread_unix.cpp | 34 | 
3 files changed, 74 insertions, 48 deletions
diff --git a/src/kernel/qeventloop.cpp b/src/kernel/qeventloop.cpp index 5eadb9e..1285098 100644 --- a/src/kernel/qeventloop.cpp +++ b/src/kernel/qeventloop.cpp @@ -223,8 +223,9 @@ int QEventLoop::enterLoop()      d->shortcut = FALSE;      d->looplevel++; -    while ( ! d->exitloop ) +    while ( ! d->exitloop ) {  	processEvents( AllEvents | WaitForMore ); +    }      d->looplevel--;      // restore the exitloop state, but if quitnow is TRUE, we need to keep diff --git a/src/kernel/qeventloop_x11_glib.cpp b/src/kernel/qeventloop_x11_glib.cpp index 5226aa9..23162c7 100644 --- a/src/kernel/qeventloop_x11_glib.cpp +++ b/src/kernel/qeventloop_x11_glib.cpp @@ -54,6 +54,7 @@  #include <errno.h>  #include <glib.h> +#include <sys/syscall.h>  // #define DEBUG_QT_GLIBMAINLOOP 1 @@ -109,7 +110,7 @@ static gboolean qt_gsource_check ( GSource *source )  	}  } -static gboolean qt_gsource_dispatch ( GSource *source, GSourceFunc  callback, gpointer user_data ) +static gboolean qt_gsource_dispatch ( GSource *source, GSourceFunc callback, gpointer user_data )  {  	Q_UNUSED(callback);  	Q_UNUSED(user_data); @@ -195,7 +196,7 @@ void qt_remove_postselect_handler( VFPTR handler )  void QEventLoop::init()  {  	// initialize ProcessEventFlags (all events & wait for more) -	d->pev_flags = AllEvents | WaitForMore;	 +	d->pev_flags = AllEvents | WaitForMore;  	// initialize the common parts of the event loop  	if (pipe( d->thread_pipe ) < 0) { @@ -239,13 +240,12 @@ void QEventLoop::init()  	// poll thread-pipe  	d->threadPipe_gPollFD.fd = d->thread_pipe[0];  	d->threadPipe_gPollFD.events = G_IO_IN | G_IO_HUP | G_IO_ERR; -	 +  	g_source_add_poll(d->gSource, &d->threadPipe_gPollFD); -	 +  #ifdef DEBUG_QT_GLIBMAINLOOP  	printf("inside init(2)\n");  #endif -	  }  void QEventLoop::cleanup() @@ -266,25 +266,24 @@ void QEventLoop::cleanup()  bool QEventLoop::processEvents( ProcessEventsFlags flags )  { -  #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 -	 +  	ProcessEventsFlags save_flags;  	int rval;  	save_flags = d->pev_flags; -	 +  	d->pev_flags = flags; -	 +  	rval = g_main_context_iteration(d->ctx, flags & WaitForMore ? TRUE : FALSE); -	 +  	d->pev_flags = save_flags; -	 +  #ifdef DEBUG_QT_GLIBMAINLOOP -	printf("inside processEvents(2) looplevel=%d rval=%d\n", d->looplevel, rval ); -#endif	 -	 +	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 +  	return rval; // were events processed?  } @@ -312,9 +311,9 @@ bool QEventLoop::processX11Events()  					if ( d->shortcut ) {  						return FALSE;  					} -			 +  					XNextEvent( QPaintDevice::x11AppDisplay(), &event ); -			 +  					if ( flags & ExcludeUserInput ) {  						switch ( event.type ) {  							case ButtonPress: @@ -325,31 +324,31 @@ bool QEventLoop::processX11Events()  							case EnterNotify:  							case LeaveNotify:  								continue; -					 +  							case ClientMessage:  								{  								// from qapplication_x11.cpp  								extern Atom qt_wm_protocols;  								extern Atom qt_wm_take_focus;  								extern Atom qt_qt_scrolldone; -					 +  								// only keep the wm_take_focus and  								// qt_qt_scrolldone protocols, discard all  								// other client messages  								if ( event.xclient.format != 32 )  									continue; -					 +  								if ( event.xclient.message_type == qt_wm_protocols ||  									(Atom) event.xclient.data.l[0] == qt_wm_take_focus )  									break;  								if ( event.xclient.message_type == qt_qt_scrolldone )  									break;  								} -					 +  							default: break;  						}  					} -			 +  					nevents++;  					if ( qApp->x11ProcessEvent( &event ) == 1 ) {  						return TRUE; @@ -358,13 +357,13 @@ bool QEventLoop::processX11Events()  			}  		}  	} -	 +  	if ( d->shortcut ) {  		return FALSE;  	}  	QApplication::sendPostedEvents(); -	 +  	const uint exclude_all = ExcludeSocketNotifiers | 0x08;  	// 0x08 == ExcludeTimers for X11 only  	if ( nevents > 0 && ( flags & exclude_all ) == exclude_all && ( flags & WaitForMore ) ) { @@ -372,27 +371,27 @@ bool QEventLoop::processX11Events()  	}  	return FALSE;  } -	 -	 + +  bool QEventLoop::gsourcePrepare(GSource *gs, int * timeout)  {  	Q_UNUSED(gs);  #ifdef DEBUG_QT_GLIBMAINLOOP  	printf("inside gsourcePrepare(1)\n"); -#endif	 +#endif  	ProcessEventsFlags flags = d->pev_flags; -		 +  #if defined(QT_THREAD_SUPPORT)  	QMutexLocker locker( QApplication::qt_mutex );  #endif -	 +  	// don't block if exitLoop() or exit()/quit() has been called.  	bool canWait = d->exitloop || d->quitnow ? FALSE : (flags & WaitForMore); -	 +  	// Process timers and socket notifiers - the common UNIX stuff -	 +  	// return the maximum time we can wait for an event.  	static timeval zerotm;  	timeval *tm = 0; @@ -406,13 +405,13 @@ bool QEventLoop::gsourcePrepare(GSource *gs, int * timeout)  			tm->tv_usec = 0;  		}  	} -	 +  	// include or exclude SocketNotifiers (by setting or cleaning poll events)  	if ( ! ( flags & ExcludeSocketNotifiers ) ) {  		QPtrListIterator<QSockNotGPollFD> it( d->sn_list );  		QSockNotGPollFD *sn;  		while ( (sn=it.current()) ) { -			++it;		 +			++it;  			sn->gPollFD.events = sn->events;  // restore poll events  		}  	} @@ -420,7 +419,7 @@ bool QEventLoop::gsourcePrepare(GSource *gs, int * timeout)  		QPtrListIterator<QSockNotGPollFD> it( d->sn_list );  		QSockNotGPollFD *sn;  		while ( (sn=it.current()) ) { -			++it;		 +			++it;  			sn->gPollFD.events = 0;  // delete poll events  		}  	} @@ -428,7 +427,7 @@ bool QEventLoop::gsourcePrepare(GSource *gs, int * timeout)  #ifdef DEBUG_QT_GLIBMAINLOOP  	printf("inside gsourcePrepare(2) canwait=%d\n", canWait);  #endif -	 +  	if ( canWait ) {  		emit aboutToBlock();  	} @@ -442,7 +441,7 @@ bool QEventLoop::gsourcePrepare(GSource *gs, int * timeout)  #ifdef DEBUG_QT_GLIBMAINLOOP  	printf("inside gsourcePrepare(2.1) canwait=%d\n", canWait);  #endif -	 +  	// do we have to dispatch events?  	if (hasPendingEvents()) {  		*timeout = 0; // no time to stay in poll @@ -451,7 +450,7 @@ bool QEventLoop::gsourcePrepare(GSource *gs, int * timeout)  #endif  		return FALSE;  	} -	 +  	// stay in poll until something happens?  	if (!tm) { // fixme  		*timeout = -1; // wait forever @@ -460,10 +459,10 @@ bool QEventLoop::gsourcePrepare(GSource *gs, int * timeout)  #endif  		return FALSE;  	} -		 +  	// else timeout >=0  	*timeout = tm->tv_sec * 1000 + tm->tv_usec/1000; -	 +  #ifdef DEBUG_QT_GLIBMAINLOOP  	printf("inside gsourcePrepare(3c) timeout=%d \n", *timeout);  #endif @@ -519,7 +518,7 @@ bool QEventLoop::gsourceCheck(GSource *gs) {  #ifdef DEBUG_QT_GLIBMAINLOOP  		printf("inside gsourceCheck(2) qtwaittimer!\n");  #endif -	 +  		return TRUE;  	} @@ -553,10 +552,10 @@ bool QEventLoop::gsourceDispatch(GSource *gs) {  	// we are awake, broadcast it  	emit awake();  	emit qApp->guiThreadAwake(); -	 +  	// some other thread woke us up... consume the data on the thread pipe so that  	// select doesn't immediately return next time -	 +  	if ( d->threadPipe_gPollFD.revents) {  		char c;  		if (::read( d->thread_pipe[0], &c, 1 ) < 0) { @@ -666,4 +665,4 @@ void QEventLoop::setSingleToolkitEventHandling(bool enabled) {  			d->ctx_is_default = true;  		}  	} -}
\ No newline at end of file +} diff --git a/src/kernel/qthread_unix.cpp b/src/kernel/qthread_unix.cpp index 52b070e..6005c42 100644 --- a/src/kernel/qthread_unix.cpp +++ b/src/kernel/qthread_unix.cpp @@ -51,10 +51,12 @@ typedef pthread_mutex_t Q_MUTEX_T;  #include <errno.h>  #include <sched.h> +#if defined(QT_USE_GLIBMAINLOOP) +#include <glib.h> +#endif // QT_USE_GLIBMAINLOOP  static QMutexPool *qt_thread_mutexpool = 0; -  #if defined(Q_C_CALLBACKS)  extern "C" {  #endif @@ -121,6 +123,11 @@ void *QThreadInstance::start( 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] );      pthread_cleanup_push( QThreadInstance::finish, arg[1] ); @@ -390,6 +397,20 @@ void QThread::start(Priority priority)      d->args[0] = this;      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 );  #if defined (Q_OS_HPUX)      if (ret == EPERM) { @@ -398,6 +419,7 @@ void QThread::start(Priority priority)      }  #endif      pthread_attr_destroy( &attr ); +#endif // QT_USE_GLIBMAINLOOP      if ( ret ) {  #ifdef QT_CHECK_STATE @@ -444,8 +466,9 @@ bool QThread::wait( unsigned long time )  	return FALSE;      } -    if ( d->finished || ! d->running ) +    if ( d->finished || ! d->running ) {  	return TRUE; +    }      int ret;      if (time != ULONG_MAX) { @@ -458,12 +481,15 @@ bool QThread::wait( unsigned long time )  	ti.tv_nsec %= 1000000000;  	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); +    }  #ifdef QT_CHECK_RANGE -    if (ret && ret != ETIMEDOUT) +    if (ret && ret != ETIMEDOUT) {  	qWarning("Wait condition wait failure: %s",strerror(ret)); +    }  #endif      return (ret == 0);  | 
