From 25a171d940de235fc0da1b37ace99c8d174cc48d Mon Sep 17 00:00:00 2001 From: Ivan Solovev Date: Fri, 2 Dec 2022 17:42:23 +0100 Subject: Fix QWinOverlappedIoNotifier MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Commit f3a306a30fc4f40d1c96fee0ed44517fe8b43d76 started processing the whole input queue in _q_notified() slot. The reads from the input queue are guarded by the hSemaphore variable, and this approach results in discrepancy between the hSemaphore value and the amount of messages in the queue. As a result, we sometimes could try to read from an empty queue, because the semaphore still had a non-zero value. This commit attempts to fix it by manually adjusting the hSemaphore count in such scenarios, and also reorderding the mutex and semaphore calls to make sure that the hSemaphore value is not modified from the QWinOverlapped thread while it is decremented to match the messages count. This commit amends f3a306a30fc4f40d1c96fee0ed44517fe8b43d76. Fixes: QTBUG-108450 Change-Id: I0c568c37119b83aafd5f98a22703b19f37b4fbc9 Reviewed-by: Jörg Bornemann (cherry picked from commit ee17a51a12428924adadd16f8c2fe8246d6bcc7f) Reviewed-by: Qt Cherry-pick Bot --- src/serialport/qwinoverlappedionotifier.cpp | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/src/serialport/qwinoverlappedionotifier.cpp b/src/serialport/qwinoverlappedionotifier.cpp index d8b80afb..a8e1c706 100644 --- a/src/serialport/qwinoverlappedionotifier.cpp +++ b/src/serialport/qwinoverlappedionotifier.cpp @@ -396,8 +396,8 @@ void QWinOverlappedIoNotifierPrivate::notify(DWORD numberOfBytes, DWORD errorCod Q_Q(QWinOverlappedIoNotifier); WaitForSingleObject(hResultsMutex, INFINITE); results.enqueue(IOResult(numberOfBytes, errorCode, overlapped)); - ReleaseMutex(hResultsMutex); ReleaseSemaphore(hSemaphore, 1, NULL); + ReleaseMutex(hResultsMutex); // Do not send a signal if we didn't process the previous one. // This is done to prevent soft memory leaks when working in a completely // synchronous way. @@ -417,6 +417,15 @@ void QWinOverlappedIoNotifierPrivate::_q_notified() WaitForSingleObject(hResultsMutex, INFINITE); QQueue values; results.swap(values); + // Decreasing the semaphore count to keep it in sync with the number + // of messages in queue. As ReleaseSemaphore does not accept negative + // values, this is sort of a recommended way to go: + // https://learn.microsoft.com/en-us/windows/win32/api/synchapi/nf-synchapi-releasesemaphore#remarks + int numToDecrease = values.size() - 1; + while (numToDecrease > 0) { + WaitForSingleObject(hSemaphore, 0); + --numToDecrease; + } ReleaseMutex(hResultsMutex); // 'q' can go out of scope if the user decides to close the serial port // while processing some answer. So we need to guard against that. -- cgit v1.2.3 From 3e7f8e829be805a2bdffda8732d34c8f9c9f1594 Mon Sep 17 00:00:00 2001 From: Tarja Sundqvist Date: Thu, 22 Dec 2022 11:11:39 +0200 Subject: Bump version to 5.15.13 Change-Id: I2d4f3ad3fd914251955892b73c590e6c56f22369 Reviewed-by: Tarja Sundqvist --- .qmake.conf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.qmake.conf b/.qmake.conf index 0b51738b..33171164 100644 --- a/.qmake.conf +++ b/.qmake.conf @@ -2,4 +2,4 @@ load(qt_build_config) DEFINES += QT_NO_FOREACH QT_NO_JAVA_STYLE_ITERATORS QT_NO_LINKED_LIST -MODULE_VERSION = 5.15.12 +MODULE_VERSION = 5.15.13 -- cgit v1.2.3