diff options
author | Fathi Boudra <fabo@debian.org> | 2009-10-06 11:03:50 +0200 |
---|---|---|
committer | Fathi Boudra <fabo@debian.org> | 2009-10-06 11:03:50 +0200 |
commit | 3c63650cac8671977161e400f9689f1c8d6065bb (patch) | |
tree | f7573d45d1355f7f4604b9862817c9fe04735f94 | |
parent | 22d134346ac55ae1e9c7a583c9db6ed660fa39fe (diff) | |
download | qt4-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/changelog | 3 | ||||
-rw-r--r-- | debian/patches/0078-Fix-regressions-in-qeventloop-qtimer-and-qsocketnoti.patch | 278 | ||||
-rw-r--r-- | debian/patches/series | 3 |
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 |