rpms/qt/F-12 qeventdispatcher_glib_fix.diff, NONE, 1.1 qt.spec, 1.340, 1.341

Rex Dieter rdieter at fedoraproject.org
Fri Oct 30 12:01:24 UTC 2009


Author: rdieter

Update of /cvs/pkgs/rpms/qt/F-12
In directory cvs1.fedora.phx.redhat.com:/tmp/cvs-serv1475

Modified Files:
	qt.spec 
Added Files:
	qeventdispatcher_glib_fix.diff 
Log Message:
* Fri Oct 30 2009 Rex Dieter <rdieter at fedoraproject.org> - 4.5.3-8
- use upstream qeventdispatcher_glib_fix.diff (kde#210171)


qeventdispatcher_glib_fix.diff:
 qeventdispatcher_glib.cpp |  133 ++++++++++++++++++++++++++++++++++++----------
 qeventdispatcher_glib_p.h |    2 
 qeventdispatcher_unix.cpp |    8 +-
 3 files changed, 112 insertions(+), 31 deletions(-)

--- NEW FILE qeventdispatcher_glib_fix.diff ---
commit 063bded33b417cdf92fd51366fc7fdb06dea00ba
Author: Bradley T. Hughes <bradley.hughes at nokia.com>
Date:   Wed Sep 23 13:51:17 2009 +0200

    Fix regressions in qeventloop, qtimer, and qsocketnotifier autotests
    
    Commit ed375675d4a4f6fd63edeb242e23c87b3de4be6f triggers a behavior in
    Glib's mainloop implementation where some event sources are not
    "serviced" every iteration of the mainloop context. This breaks an
    invariant that many tests relied on, so we need to solve the problem.
    
    The invariant is that a newly added timer that would normally fire on
    the next pass of the event loop (liker a zero timer) SHOULD actually
    fire. We do this by registering 2 timer event sources with Glib's
    mainloop: one normal priority source and one idle priority source. The
    idle priority source is the one that will send events most of the
    time, with the normal priority one taking over only when
    processEvents() is called manually.
    
    Task-number: QT-877
    Reviewed-by: jbache
    Reviewed-by: thiago
    Reviewed-by: denis
    (cherry picked from commit d0d0fdb8e46351b4ab8492de31e5363ef6662b57)
    (cherry picked from commit 0ed23e95fa756fd851f509a565f91ab43fc30449)

diff --git a/src/corelib/kernel/qeventdispatcher_glib.cpp b/src/corelib/kernel/qeventdispatcher_glib.cpp
index 87e9728..7f6dbb6 100644
--- a/src/corelib/kernel/qeventdispatcher_glib.cpp
+++ b/src/corelib/kernel/qeventdispatcher_glib.cpp
@@ -127,16 +127,11 @@ struct GTimerSource
     GSource source;
     QTimerInfoList timerList;
     QEventLoop::ProcessEventsFlags processEventsFlags;
+    bool runWithIdlePriority;
 };
 
-static gboolean timerSourcePrepare(GSource *source, gint *timeout)
+static gboolean timerSourcePrepareHelper(GTimerSource *src, gint *timeout)
 {
-    gint dummy;
-    if (!timeout)
-        timeout = &dummy;
-
-    GTimerSource *src = reinterpret_cast<GTimerSource *>(source);
-
     timeval tv = { 0l, 0l };
     if (!(src->processEventsFlags & QEventLoop::X11ExcludeTimers) && src->timerList.timerWait(tv))
         *timeout = (tv.tv_sec * 1000) + (tv.tv_usec / 1000);
@@ -146,10 +141,8 @@ static gboolean timerSourcePrepare(GSource *source, gint *timeout)
     return (*timeout == 0);
 }
 
-static gboolean timerSourceCheck(GSource *source)
+static gboolean timerSourceCheckHelper(GTimerSource *src)
 {
-    GTimerSource *src = reinterpret_cast<GTimerSource *>(source);
-
     if (src->timerList.isEmpty()
         || (src->processEventsFlags & QEventLoop::X11ExcludeTimers))
         return false;
@@ -160,9 +153,35 @@ static gboolean timerSourceCheck(GSource *source)
     return true;
 }
 
+static gboolean timerSourcePrepare(GSource *source, gint *timeout)
+{
+    gint dummy;
+    if (!timeout)
+        timeout = &dummy;
+
+    GTimerSource *src = reinterpret_cast<GTimerSource *>(source);
+    if (src->runWithIdlePriority) {
+        if (timeout)
+            *timeout = -1;
+        return false;
+    }
+
+    return timerSourcePrepareHelper(src, timeout);
+}
+
+static gboolean timerSourceCheck(GSource *source)
+{
+    GTimerSource *src = reinterpret_cast<GTimerSource *>(source);
+    if (src->runWithIdlePriority)
+        return false;
+    return timerSourceCheckHelper(src);
+}
+
 static gboolean timerSourceDispatch(GSource *source, GSourceFunc, gpointer)
 {
-    (void) reinterpret_cast<GTimerSource *>(source)->timerList.activateTimers();
+    GTimerSource *timerSource = reinterpret_cast<GTimerSource *>(source);
+    timerSource->runWithIdlePriority = true;
+    (void) timerSource->timerList.activateTimers();
     return true; // ??? don't remove, right again?
 }
 
@@ -175,6 +194,53 @@ static GSourceFuncs timerSourceFuncs = {
     NULL
 };
 
+struct GIdleTimerSource
+{
+    GSource source;
+    GTimerSource *timerSource;
+};
+
+static gboolean idleTimerSourcePrepare(GSource *source, gint *timeout)
+{
+    GIdleTimerSource *idleTimerSource = reinterpret_cast<GIdleTimerSource *>(source);
+    GTimerSource *timerSource = idleTimerSource->timerSource;
+    if (!timerSource->runWithIdlePriority) {
+        // Yield to the normal priority timer source
+        if (timeout)
+            *timeout = -1;
+        return false;
+    }
+
+    return timerSourcePrepareHelper(timerSource, timeout);
+}
+
+static gboolean idleTimerSourceCheck(GSource *source)
+{
+    GIdleTimerSource *idleTimerSource = reinterpret_cast<GIdleTimerSource *>(source);
+    GTimerSource *timerSource = idleTimerSource->timerSource;
+    if (!timerSource->runWithIdlePriority) {
+        // Yield to the normal priority timer source
+        return false;
+    }
+    return timerSourceCheckHelper(timerSource);
+}
+
+static gboolean idleTimerSourceDispatch(GSource *source, GSourceFunc, gpointer)
+{
+    GTimerSource *timerSource = reinterpret_cast<GIdleTimerSource *>(source)->timerSource;
+    (void) timerSourceDispatch(&timerSource->source, 0, 0);
+    return true;
+}
+
+static GSourceFuncs idleTimerSourceFuncs = {
+    idleTimerSourcePrepare,
+    idleTimerSourceCheck,
+    idleTimerSourceDispatch,
+    NULL,
+    NULL,
+    NULL
+};
+
 struct GPostEventSource
 {
     GSource source;
@@ -235,14 +301,15 @@ QEventDispatcherGlibPrivate::QEventDispatcherGlibPrivate(GMainContext *context)
         g_main_context_ref(mainContext);
     } else {
         QCoreApplication *app = QCoreApplication::instance();
-	if (app && QThread::currentThread() == app->thread()) {
-	    mainContext = g_main_context_default();
-	    g_main_context_ref(mainContext);
-	} else {
-	    mainContext = g_main_context_new();
-	}
+        if (app && QThread::currentThread() == app->thread()) {
+            mainContext = g_main_context_default();
+            g_main_context_ref(mainContext);
+        } else {
+            mainContext = g_main_context_new();
+        }
     }
 
+    // setup post event source
     postEventSource = reinterpret_cast<GPostEventSource *>(g_source_new(&postEventSourceFuncs,
                                                                         sizeof(GPostEventSource)));
     postEventSource->serialNumber = 1;
@@ -257,14 +324,21 @@ QEventDispatcherGlibPrivate::QEventDispatcherGlibPrivate(GMainContext *context)
     g_source_set_can_recurse(&socketNotifierSource->source, true);
     g_source_attach(&socketNotifierSource->source, mainContext);
 
-    // setup timerSource
+    // setup normal and idle timer sources
     timerSource = reinterpret_cast<GTimerSource *>(g_source_new(&timerSourceFuncs,
                                                                 sizeof(GTimerSource)));
     (void) new (&timerSource->timerList) QTimerInfoList();
     timerSource->processEventsFlags = QEventLoop::AllEvents;
+    timerSource->runWithIdlePriority = false;
     g_source_set_can_recurse(&timerSource->source, true);
-    g_source_set_priority(&timerSource->source, G_PRIORITY_DEFAULT_IDLE);
     g_source_attach(&timerSource->source, mainContext);
+
+    idleTimerSource = reinterpret_cast<GIdleTimerSource *>(g_source_new(&idleTimerSourceFuncs,
+                                                                        sizeof(GIdleTimerSource)));
+    idleTimerSource->timerSource = timerSource;
+    g_source_set_can_recurse(&idleTimerSource->source, true);
+    g_source_set_priority(&idleTimerSource->source, G_PRIORITY_DEFAULT_IDLE);
+    g_source_attach(&idleTimerSource->source, mainContext);
 }
 
 QEventDispatcherGlib::QEventDispatcherGlib(QObject *parent)
@@ -272,12 +346,9 @@ QEventDispatcherGlib::QEventDispatcherGlib(QObject *parent)
 {
 }
 
-QEventDispatcherGlib::QEventDispatcherGlib(GMainContext *mainContext,
-					   QObject *parent)
-    : QAbstractEventDispatcher(*(new QEventDispatcherGlibPrivate(mainContext)),
-			       parent)
-{
-}
+QEventDispatcherGlib::QEventDispatcherGlib(GMainContext *mainContext, QObject *parent)
+    : QAbstractEventDispatcher(*(new QEventDispatcherGlibPrivate(mainContext)), parent)
+{ }
 
 QEventDispatcherGlib::~QEventDispatcherGlib()
 {
@@ -289,6 +360,9 @@ QEventDispatcherGlib::~QEventDispatcherGlib()
     g_source_destroy(&d->timerSource->source);
     g_source_unref(&d->timerSource->source);
     d->timerSource = 0;
+    g_source_destroy(&d->idleTimerSource->source);
+    g_source_unref(&d->idleTimerSource->source);
+    d->idleTimerSource = 0;
 
     // destroy socket notifier source
     for (int i = 0; i < d->socketNotifierSource->pollfds.count(); ++i) {
@@ -324,11 +398,16 @@ bool QEventDispatcherGlib::processEvents(QEventLoop::ProcessEventsFlags flags)
     // tell postEventSourcePrepare() and timerSource about any new flags
     QEventLoop::ProcessEventsFlags savedFlags = d->timerSource->processEventsFlags;
     d->timerSource->processEventsFlags = flags;
-    
+
+    if (!(flags & QEventLoop::EventLoopExec)) {
+        // force timers to be sent at normal priority
+        d->timerSource->runWithIdlePriority = false;
+    }
+
     bool result = g_main_context_iteration(d->mainContext, canWait);
     while (!result && canWait)
         result = g_main_context_iteration(d->mainContext, canWait);
-    
+
     d->timerSource->processEventsFlags = savedFlags;
 
     if (canWait)
diff --git a/src/corelib/kernel/qeventdispatcher_glib_p.h b/src/corelib/kernel/qeventdispatcher_glib_p.h
index eb7fb75..4103aa3 100644
--- a/src/corelib/kernel/qeventdispatcher_glib_p.h
+++ b/src/corelib/kernel/qeventdispatcher_glib_p.h
@@ -98,6 +98,7 @@ protected:
 struct GPostEventSource;
 struct GSocketNotifierSource;
 struct GTimerSource;
+struct GIdleTimerSource;
 
 class Q_CORE_EXPORT QEventDispatcherGlibPrivate : public QAbstractEventDispatcherPrivate
 {
@@ -108,6 +109,7 @@ public:
     GPostEventSource *postEventSource;
     GSocketNotifierSource *socketNotifierSource;
     GTimerSource *timerSource;
+    GIdleTimerSource *idleTimerSource;
 };
 
 QT_END_NAMESPACE
diff --git a/src/corelib/kernel/qeventdispatcher_unix.cpp b/src/corelib/kernel/qeventdispatcher_unix.cpp
index 897bb49..903b0eb 100644
--- a/src/corelib/kernel/qeventdispatcher_unix.cpp
+++ b/src/corelib/kernel/qeventdispatcher_unix.cpp
@@ -423,10 +423,10 @@ bool QTimerInfoList::timerWait(timeval &tm)
     // Find first waiting timer not already active
     QTimerInfo *t = 0;
     for (QTimerInfoList::const_iterator it = constBegin(); it != constEnd(); ++it) {
-	if (!(*it)->inTimerEvent) {
-	    t = *it;
-	    break;
-	}
+        if (!(*it)->inTimerEvent) {
+            t = *it;
+            break;
+        }
     }
 
     if (!t)


Index: qt.spec
===================================================================
RCS file: /cvs/pkgs/rpms/qt/F-12/qt.spec,v
retrieving revision 1.340
retrieving revision 1.341
diff -u -p -r1.340 -r1.341
--- qt.spec	29 Oct 2009 15:40:22 -0000	1.340
+++ qt.spec	30 Oct 2009 12:01:23 -0000	1.341
@@ -4,13 +4,13 @@
 # -no-pch disables precompiled headers, make ccache-friendly
 %define no_pch -no-pch
 
-%define _default_patch_fuzz 2
+%define _default_patch_fuzz 2 
 
 Summary: Qt toolkit
 Name:    qt
 Epoch:   1
 Version: 4.5.3
-Release: 7%{?dist}
+Release: 8%{?dist}
 
 # See LGPL_EXCEPTIONS.txt, LICENSE.GPL3, respectively, for exception details
 License: LGPLv2 with exceptions or GPLv3 with exceptions
@@ -57,7 +57,10 @@ Patch53: qt-x11-opensource-src-4.5.0-fix
 # fix invalid assumptions about mysql_config --libs
 # http://bugzilla.redhat.com/440673
 Patch54: qt-x11-opensource-src-4.5.1-mysql_config.patch
+# glib-event-loop regression
 Patch55: qt-x11-opensource-src-4.5.3-glib-event-loop.patch
+# or fix from http://bugs.kde.org/210171
+Patch155: http://www.davidfaure.fr/2009/qeventdispatcher_glib_fix.diff
 
 # security patches
 
@@ -392,7 +395,8 @@ Qt libraries used for drawing widgets an
 %patch52 -p1 -b .sparc64
 %patch53 -p1 -b .qatomic-inline-asm
 %patch54 -p1 -b .mysql_config
-%patch55 -p1 -b .glib-event-loop
+#patch55 -p1 -b .glib-event-loop
+%patch155 -p1 -b .qeventdispatcher_glib_fix
 
 # security fixes
 
@@ -989,6 +993,9 @@ fi
 
 
 %changelog
+* Fri Oct 30 2009 Rex Dieter <rdieter at fedoraproject.org> - 4.5.3-8
+- use upstream qeventdispatcher_glib_fix.diff (kde#210171)
+
 * Thu Oct 29 2009 Than Ngo <than at redhat.com> - 4.5.3-7
 - fix glib-even-loop issue, regression which causes
   Password dialogs get stuck




More information about the fedora-extras-commits mailing list