summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFathi Boudra <fabo@debian.org>2009-10-06 11:03:50 +0200
committerFathi Boudra <fabo@debian.org>2009-10-06 11:03:50 +0200
commit3c63650cac8671977161e400f9689f1c8d6065bb (patch)
treef7573d45d1355f7f4604b9862817c9fe04735f94
parent22d134346ac55ae1e9c7a583c9db6ed660fa39fe (diff)
downloadqt4-x11-3c63650cac8671977161e400f9689f1c8d6065bb.tar.gz
Add upstream patches:
- 0078-Fix-regressions-in-qeventloop-qtimer-and-qsocketnoti.patch Fix regressions in qeventloop, qtimer, and qsocketnotifier autotests.
-rw-r--r--debian/changelog3
-rw-r--r--debian/patches/0078-Fix-regressions-in-qeventloop-qtimer-and-qsocketnoti.patch278
-rw-r--r--debian/patches/series3
3 files changed, 284 insertions, 0 deletions
diff --git a/debian/changelog b/debian/changelog
index 2ad979c..3593659 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -19,6 +19,9 @@ qt4-x11 (4:4.5.3-0r1) UNRELEASED; urgency=low
+++ Changes by Fathi Boudra:
+ * Add upstream patches:
+ - 0078-Fix-regressions-in-qeventloop-qtimer-and-qsocketnoti.patch
+ Fix regressions in qeventloop, qtimer, and qsocketnotifier autotests.
* Add Debian patches:
- 99_build_translations
Fix translations build when sources comes from git.
diff --git a/debian/patches/0078-Fix-regressions-in-qeventloop-qtimer-and-qsocketnoti.patch b/debian/patches/0078-Fix-regressions-in-qeventloop-qtimer-and-qsocketnoti.patch
new file mode 100644
index 0000000..628f1cf
--- /dev/null
+++ b/debian/patches/0078-Fix-regressions-in-qeventloop-qtimer-and-qsocketnoti.patch
@@ -0,0 +1,278 @@
+From 089708893cfb018af28b7c0d98a23ae6745d9a1b Mon Sep 17 00:00:00 2001
+From: Bradley T. Hughes <bradley.hughes@nokia.com>
+Date: Wed, 23 Sep 2009 13:51:17 +0200
+Subject: [PATCH 78/78] 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
+---
+ src/corelib/kernel/qeventdispatcher_glib.cpp | 133 ++++++++++++++++++++-----
+ src/corelib/kernel/qeventdispatcher_glib_p.h | 2 +
+ src/corelib/kernel/qeventdispatcher_unix.cpp | 8 +-
+ 3 files changed, 112 insertions(+), 31 deletions(-)
+
+--- 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(GSour
+ 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
+ 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::QEventDispa
+ 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::QEventDispa
+ 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::QEventDispatcherGl
+ {
+ }
+
+-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::~QEventDispatcherG
+ 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
+ // 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)
+--- 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
+--- a/src/corelib/kernel/qeventdispatcher_unix.cpp
++++ b/src/corelib/kernel/qeventdispatcher_unix.cpp
+@@ -423,10 +423,10 @@ bool QTimerInfoList::timerWait(timeval &
+ // 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)
diff --git a/debian/patches/series b/debian/patches/series
index 9dcca04..f2292e1 100644
--- a/debian/patches/series
+++ b/debian/patches/series
@@ -1,3 +1,6 @@
+# upstream patches
+0078-Fix-regressions-in-qeventloop-qtimer-and-qsocketnoti.patch
+
# qt-copy patches
0180-window-role.diff
0195-compositing-properties.diff