diff options
author | Olivier Goffart <olivier.goffart@nokia.com> | 2011-06-24 17:26:20 +0200 |
---|---|---|
committer | Qt by Nokia <qt-info@nokia.com> | 2011-06-27 10:59:28 +0200 |
commit | 7eeabcf70db658bca847498f618a94a375c95f5f (patch) | |
tree | 353aa41b3cb792bfab4e016173da91ad9fa0a359 /src | |
parent | 89459bc7cf6326bd68f395f1c3e774c1a4b598b6 (diff) |
Fix event delevery order
Some functions (such as QObject::moveToThread) did not keep
the event ordered by priority.
And because qUpperBound is used to add events, that mean new
events would not be inserted in order.
Task-number: QTBUG19637
Change-Id: I38eb9addb1cdd45b8566e000361ac6e5f1f2c2b8
Reviewed-on: http://codereview.qt.nokia.com/733
Reviewed-by: Qt Sanity Bot <qt_sanity_bot@ovi.com>
Reviewed-by: Bradley T. Hughes <bradley.hughes@nokia.com>
Reviewed-by: Olivier Goffart <olivier.goffart@nokia.com>
Diffstat (limited to 'src')
-rw-r--r-- | src/corelib/kernel/qcoreapplication.cpp | 17 | ||||
-rw-r--r-- | src/corelib/kernel/qobject.cpp | 2 | ||||
-rw-r--r-- | src/corelib/thread/qthread_p.h | 21 | ||||
-rw-r--r-- | src/gui/kernel/qapplication.cpp | 4 |
4 files changed, 26 insertions, 18 deletions
diff --git a/src/corelib/kernel/qcoreapplication.cpp b/src/corelib/kernel/qcoreapplication.cpp index a8c40c5180..cc1b1812e5 100644 --- a/src/corelib/kernel/qcoreapplication.cpp +++ b/src/corelib/kernel/qcoreapplication.cpp @@ -1272,20 +1272,7 @@ void QCoreApplication::postEvent(QObject *receiver, QEvent *event, int priority) // delete the event on exceptions to protect against memory leaks till the event is // properly owned in the postEventList QScopedPointer<QEvent> eventDeleter(event); - if (data->postEventList.isEmpty() || data->postEventList.last().priority >= priority) { - // optimization: we can simply append if the last event in - // the queue has higher or equal priority - data->postEventList.append(QPostEvent(receiver, event, priority)); - } else { - // insert event in descending priority order, using upper - // bound for a given priority (to ensure proper ordering - // of events with the same priority) - QPostEventList::iterator begin = data->postEventList.begin() - + data->postEventList.insertionOffset, - end = data->postEventList.end(); - QPostEventList::iterator at = qUpperBound(begin, end, priority); - data->postEventList.insert(at, QPostEvent(receiver, event, priority)); - } + data->postEventList.addEvent(QPostEvent(receiver, event, priority)); eventDeleter.take(); event->posted = true; ++receiver->d_func()->postedEvents; @@ -1445,7 +1432,7 @@ void QCoreApplicationPrivate::sendPostedEvents(QObject *receiver, int event_type // cannot send deferred delete if (!event_type && !receiver) { // don't lose the event - data->postEventList.append(pe); + data->postEventList.addEvent(pe); const_cast<QPostEvent &>(pe).event = 0; } continue; diff --git a/src/corelib/kernel/qobject.cpp b/src/corelib/kernel/qobject.cpp index b88643df5c..88618c3c87 100644 --- a/src/corelib/kernel/qobject.cpp +++ b/src/corelib/kernel/qobject.cpp @@ -1482,7 +1482,7 @@ void QObjectPrivate::setThreadData_helper(QThreadData *currentData, QThreadData continue; if (pe.receiver == q) { // move this post event to the targetList - targetData->postEventList.append(pe); + targetData->postEventList.addEvent(pe); const_cast<QPostEvent &>(pe).event = 0; ++eventsMoved; } diff --git a/src/corelib/thread/qthread_p.h b/src/corelib/thread/qthread_p.h index 13df3e6fea..461d93dd50 100644 --- a/src/corelib/thread/qthread_p.h +++ b/src/corelib/thread/qthread_p.h @@ -93,6 +93,8 @@ inline bool operator<(const QPostEvent &pe, int priority) return priority < pe.priority; } +// This class holds the list of posted events. +// The list has to be kept sorted by priority class QPostEventList : public QList<QPostEvent> { public: @@ -109,6 +111,25 @@ public: inline QPostEventList() : QList<QPostEvent>(), recursion(0), startOffset(0), insertionOffset(0) { } + + void addEvent(const QPostEvent &ev) { + int priority = ev.priority; + if (isEmpty() || last().priority >= priority) { + // optimization: we can simply append if the last event in + // the queue has higher or equal priority + append(ev); + } else { + // insert event in descending priority order, using upper + // bound for a given priority (to ensure proper ordering + // of events with the same priority) + QPostEventList::iterator at = qUpperBound(begin() + insertionOffset, end(), priority); + insert(at, ev); + } + } +private: + //hides because they do not keep that list sorted. addEvent must be used + using QList<QPostEvent>::append; + using QList<QPostEvent>::insert; }; #ifndef QT_NO_THREAD diff --git a/src/gui/kernel/qapplication.cpp b/src/gui/kernel/qapplication.cpp index 38035997fe..361ec6ddec 100644 --- a/src/gui/kernel/qapplication.cpp +++ b/src/gui/kernel/qapplication.cpp @@ -1288,8 +1288,8 @@ bool QApplication::compressEvent(QEvent *event, QObject *receiver, QPostEventLis || event->type() == QEvent::LanguageChange || event->type() == QEvent::UpdateSoftKeys || event->type() == QEvent::InputMethod)) { - for (int i = 0; i < postedEvents->size(); ++i) { - const QPostEvent &cur = postedEvents->at(i); + for (QPostEventList::const_iterator it = postedEvents->constBegin(); it != postedEvents->constEnd(); ++it) { + const QPostEvent &cur = *it; if (cur.receiver != receiver || cur.event == 0 || cur.event->type() != event->type()) continue; if (cur.event->type() == QEvent::LayoutRequest |