summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBradley T. Hughes <bradley.hughes@nokia.com>2009-12-10 08:15:34 (GMT)
committerBradley T. Hughes <bradley.hughes@nokia.com>2009-12-10 08:18:51 (GMT)
commit9215506e6a057d8aef7415c2921214e1ba1c760d (patch)
treef21dc39dd99eb253fe345874b360424e4d179dc8
parentbc8e87016cfeb4a63151425bcd0f69f21a5fc1c1 (diff)
downloadQt-9215506e6a057d8aef7415c2921214e1ba1c760d.zip
Qt-9215506e6a057d8aef7415c2921214e1ba1c760d.tar.gz
Qt-9215506e6a057d8aef7415c2921214e1ba1c760d.tar.bz2
Prevent posted event starvation by native Windows messages
Avoid live-lock if native messages are generated quickly enough by allowing posted events to be sent if more than 10ms has passed since we last sent them. This means that we can allow multiple calls to sendPostedEvents() during a single call to processEvents(), but only when the QEventLoop::EventLoopExec flag is passed to processEvents(). Task-number: QTBUG-1697
-rw-r--r--src/corelib/kernel/qeventdispatcher_win.cpp16
1 files changed, 11 insertions, 5 deletions
diff --git a/src/corelib/kernel/qeventdispatcher_win.cpp b/src/corelib/kernel/qeventdispatcher_win.cpp
index c6eef5e..105cf28 100644
--- a/src/corelib/kernel/qeventdispatcher_win.cpp
+++ b/src/corelib/kernel/qeventdispatcher_win.cpp
@@ -341,6 +341,7 @@ public:
// for controlling when to send posted events
QAtomicInt serialNumber;
int lastSerialNumber;
+ int lastMessageTime;
QAtomicInt wakeUps;
// timers
@@ -364,7 +365,8 @@ public:
};
QEventDispatcherWin32Private::QEventDispatcherWin32Private()
- : threadId(GetCurrentThreadId()), interrupt(false), internalHwnd(0), getMessageHook(0), serialNumber(0), lastSerialNumber(0), wakeUps(0)
+ : threadId(GetCurrentThreadId()), interrupt(false), internalHwnd(0), getMessageHook(0),
+ serialNumber(0), lastSerialNumber(0), lastMessageTime(0), wakeUps(0)
{
resolveTimerAPI();
}
@@ -479,6 +481,7 @@ LRESULT CALLBACK qt_internal_proc(HWND hwnd, UINT message, WPARAM wp, LPARAM lp)
int localSerialNumber = d->serialNumber;
if (localSerialNumber != d->lastSerialNumber) {
d->lastSerialNumber = localSerialNumber;
+ d->lastMessageTime = GetMessageTime();
QCoreApplicationPrivate::sendPostedEvents(0, 0, d->threadData);
}
return 0;
@@ -495,9 +498,10 @@ LRESULT CALLBACK qt_GetMessageHook(int code, WPARAM wp, LPARAM lp)
if (q) {
QEventDispatcherWin32Private *d = q->d_func();
int localSerialNumber = d->serialNumber;
- if (HIWORD(GetQueueStatus(QS_INPUT | QS_RAWINPUT | QS_TIMER)) == 0) {
- // no more input or timer events in the message queue, we can allow posted events to be
- // sent now
+ if (HIWORD(GetQueueStatus(QS_INPUT | QS_RAWINPUT | QS_TIMER)) == 0
+ || GetMessageTime() - d->lastMessageTime >= 10) {
+ // no more input or timer events in the message queue or more than 10ms has elapsed since
+ // we send posted events, we can allow posted events to be sent now
(void) d->wakeUps.fetchAndStoreRelease(0);
MSG *msg = (MSG *) lp;
if (localSerialNumber != d->lastSerialNumber
@@ -732,7 +736,9 @@ bool QEventDispatcherWin32::processEvents(QEventLoop::ProcessEventsFlags flags)
}
if (haveMessage) {
if (d->internalHwnd == msg.hwnd && msg.message == WM_QT_SENDPOSTEDEVENTS) {
- if (seenWM_QT_SENDPOSTEDEVENTS) {
+ if (seenWM_QT_SENDPOSTEDEVENTS && !(flags & QEventLoop::EventLoopExec)) {
+ // when calling processEvents() "manually", we only want to send posted
+ // events once
needWM_QT_SENDPOSTEDEVENTS = true;
continue;
}