From 5aa389f311cae593530b0d0f500d67b10f7dd494 Mon Sep 17 00:00:00 2001 From: Timothy Pearson Date: Tue, 12 Feb 2013 18:15:11 -0600 Subject: Fix GTK threading deadlock --- src/kernel/qeventloop_glib_p.h | 3 +++ src/kernel/qeventloop_x11_glib.cpp | 32 ++++++++++++++++++++++---------- 2 files changed, 25 insertions(+), 10 deletions(-) (limited to 'src/kernel') diff --git a/src/kernel/qeventloop_glib_p.h b/src/kernel/qeventloop_glib_p.h index 663f20e..3fa3593 100644 --- a/src/kernel/qeventloop_glib_p.h +++ b/src/kernel/qeventloop_glib_p.h @@ -100,6 +100,8 @@ public: exitloop = FALSE; shortcut = FALSE; singletoolkit = TRUE; + ctx = 0; + ctx_is_default = false; } int looplevel; @@ -129,6 +131,7 @@ public: // main context GMainContext *ctx; + bool ctx_is_default; }; #endif // QEVENTLOOP_GLIB_P_H diff --git a/src/kernel/qeventloop_x11_glib.cpp b/src/kernel/qeventloop_x11_glib.cpp index 877ff44..d37fbee 100644 --- a/src/kernel/qeventloop_x11_glib.cpp +++ b/src/kernel/qeventloop_x11_glib.cpp @@ -79,8 +79,7 @@ static GSourceFuncs qt_gsource_funcs = { // forward main loop callbacks to QEventLoop methods! -static gboolean qt_gsource_prepare ( GSource *source, - gint *timeout ) +static gboolean qt_gsource_prepare ( GSource *source, gint *timeout ) { QtGSource * qtGSource = (QtGSource*) source; QEventLoop* candidateEventLoop = qtGSource->qeventLoop; @@ -95,7 +94,7 @@ static gboolean qt_gsource_prepare ( GSource *source, } } -static gboolean qt_gsource_check ( GSource *source ) +static gboolean qt_gsource_check ( GSource *source ) { QtGSource * qtGSource = (QtGSource*) source; QEventLoop* candidateEventLoop = qtGSource->qeventLoop; @@ -110,8 +109,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); @@ -215,6 +213,7 @@ void QEventLoop::init() // new main context for thread d->ctx = g_main_context_new(); g_main_context_push_thread_default(d->ctx); + d->ctx_is_default = true; // new GSource QtGSource * qtGSource = (QtGSource*) g_source_new(&qt_gsource_funcs, sizeof(QtGSource)); @@ -241,9 +240,9 @@ void QEventLoop::init() 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); + g_source_add_poll(d->gSource, &d->threadPipe_gPollFD); -#ifdef DEBUG_QT_GLIBMAINLOOP +#ifdef DEBUG_QT_GLIBMAINLOOP printf("inside init(2)\n"); #endif @@ -375,7 +374,7 @@ bool QEventLoop::processX11Events() } -bool QEventLoop::gsourcePrepare(GSource *gs, int * timeout) +bool QEventLoop::gsourcePrepare(GSource *gs, int * timeout) { Q_UNUSED(gs); @@ -428,7 +427,7 @@ bool QEventLoop::gsourcePrepare(GSource *gs, int * timeout) #ifdef DEBUG_QT_GLIBMAINLOOP printf("inside gsourcePrepare(2) canwait=%d\n", canWait); -#endif +#endif if ( canWait ) { emit aboutToBlock(); @@ -440,7 +439,7 @@ bool QEventLoop::gsourcePrepare(GSource *gs, int * timeout) (**it)(); } -#ifdef DEBUG_QT_GLIBMAINLOOP +#ifdef DEBUG_QT_GLIBMAINLOOP printf("inside gsourcePrepare(2.1) canwait=%d\n", canWait); #endif @@ -649,4 +648,17 @@ void QEventLoop::appClosingDown() void QEventLoop::setSingleToolkitEventHandling(bool enabled) { d->singletoolkit = enabled; + + if (!d->singletoolkit) { + if (d->ctx_is_default) { + d->ctx_is_default = false; + g_main_context_pop_thread_default(d->ctx); + } + } + else { + if (!d->ctx_is_default) { + g_main_context_push_thread_default(d->ctx); + d->ctx_is_default = true; + } + } } \ No newline at end of file -- cgit v1.2.3 From c47f5e14e4231c872828374d05815d59a045cb2c Mon Sep 17 00:00:00 2001 From: Timothy Pearson Date: Wed, 13 Feb 2013 20:35:23 -0600 Subject: Fix CLI application failure when glib event loop is used --- src/kernel/qeventloop_glib_p.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'src/kernel') diff --git a/src/kernel/qeventloop_glib_p.h b/src/kernel/qeventloop_glib_p.h index 3fa3593..4dfc02c 100644 --- a/src/kernel/qeventloop_glib_p.h +++ b/src/kernel/qeventloop_glib_p.h @@ -90,6 +90,9 @@ public: xfd = -1; x_gPollFD.fd = -1; #endif // Q_WS_X11 + singletoolkit = TRUE; + ctx = 0; + ctx_is_default = false; reset(); } @@ -99,11 +102,8 @@ public: quitnow = FALSE; exitloop = FALSE; shortcut = FALSE; - singletoolkit = TRUE; - ctx = 0; - ctx_is_default = false; } - + int looplevel; int quitcode; unsigned int quitnow : 1; -- cgit v1.2.3 From 89af6f8007568a86132c9b4cc0a21356572a8bda Mon Sep 17 00:00:00 2001 From: Timothy Pearson Date: Sun, 24 Feb 2013 02:27:31 -0600 Subject: Restore expected qApp->exit() behaviour when called from a non-GUI thread --- src/kernel/qapplication.cpp | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) (limited to 'src/kernel') diff --git a/src/kernel/qapplication.cpp b/src/kernel/qapplication.cpp index 5b43301..591fc8d 100644 --- a/src/kernel/qapplication.cpp +++ b/src/kernel/qapplication.cpp @@ -2931,7 +2931,14 @@ int QApplication::exec() */ void QApplication::exit( int retcode ) { - qApp->eventLoop()->exit( retcode ); + QThread* thread = qApp->guiThread(); + if (thread) { + if (thread->d) { + if (thread->d->eventLoop) { + thread->d->eventLoop->exit( retcode ); + } + } + } } /*! -- cgit v1.2.3