From 85ee2c658a45d2958a54045951d236769640337f Mon Sep 17 00:00:00 2001 From: Joerg Bornemann Date: Mon, 17 Jun 2019 15:14:08 +0200 Subject: Emit _q_notify only if there's no notification pending When using the waitXXX functions in a loop, many _q_notify signals are emitted. They are connection via Qt::QueuedConnection, but the event loop never gets the chance to process them. Introduce a counter to count the attempts to send a notification, but only send it once. Fixes: QTBUG-74961 Change-Id: I0ee4522db63844bdd37169d3a31bde2d6f92f383 Reviewed-by: Denis Shienkov --- src/serialport/qwinoverlappedionotifier.cpp | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/serialport/qwinoverlappedionotifier.cpp b/src/serialport/qwinoverlappedionotifier.cpp index 615dacc..233ee69 100644 --- a/src/serialport/qwinoverlappedionotifier.cpp +++ b/src/serialport/qwinoverlappedionotifier.cpp @@ -129,6 +129,7 @@ public: HANDLE hSemaphore = nullptr; HANDLE hResultsMutex = nullptr; QAtomicInt waiting; + QAtomicInt pendingNotifications; QQueue results; }; @@ -395,14 +396,17 @@ void QWinOverlappedIoNotifierPrivate::notify(DWORD numberOfBytes, DWORD errorCod results.enqueue(IOResult(numberOfBytes, errorCode, overlapped)); ReleaseMutex(hResultsMutex); ReleaseSemaphore(hSemaphore, 1, NULL); - if (!waiting) + if (!waiting && pendingNotifications-- == 0) emit q->_q_notify(); } void QWinOverlappedIoNotifierPrivate::_q_notified() { - if (WaitForSingleObject(hSemaphore, 0) == WAIT_OBJECT_0) - dispatchNextIoResult(); + int n = pendingNotifications.fetchAndStoreAcquire(0); + while (--n >= 0) { + if (WaitForSingleObject(hSemaphore, 0) == WAIT_OBJECT_0) + dispatchNextIoResult(); + } } OVERLAPPED *QWinOverlappedIoNotifierPrivate::dispatchNextIoResult() -- cgit v1.2.1