diff options
-rw-r--r-- | .cmake.conf | 4 | ||||
-rw-r--r-- | dependencies.yaml | 2 | ||||
-rw-r--r-- | src/serialport/qwinoverlappedionotifier.cpp | 27 |
3 files changed, 27 insertions, 6 deletions
diff --git a/.cmake.conf b/.cmake.conf index 54b068ef..e5cf5fa4 100644 --- a/.cmake.conf +++ b/.cmake.conf @@ -1,2 +1,2 @@ -set(QT_REPO_MODULE_VERSION "6.3.1") -set(QT_REPO_MODULE_PRERELEASE_VERSION_SEGMENT "alpha1") +set(QT_REPO_MODULE_VERSION "6.3.3") +set(QT_REPO_MODULE_PRERELEASE_VERSION_SEGMENT "") diff --git a/dependencies.yaml b/dependencies.yaml index f975a8f3..4385e2da 100644 --- a/dependencies.yaml +++ b/dependencies.yaml @@ -1,4 +1,4 @@ dependencies: ../qtbase: - ref: 9a75c286b45afa061459ce8256a5a2ad6b278409 + ref: fe0dd828ab031eb1fb6bcf081b463833086c5383 required: true diff --git a/src/serialport/qwinoverlappedionotifier.cpp b/src/serialport/qwinoverlappedionotifier.cpp index 08561685..25eeff99 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 signalSent; QQueue<IOResult> results; }; @@ -397,14 +398,34 @@ void QWinOverlappedIoNotifierPrivate::notify(DWORD numberOfBytes, DWORD errorCod results.enqueue(IOResult(numberOfBytes, errorCode, overlapped)); ReleaseMutex(hResultsMutex); ReleaseSemaphore(hSemaphore, 1, NULL); - if (!waiting) + // 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. + if (!waiting && !signalSent.loadAcquire()) { + signalSent.storeRelease(1); emit q->_q_notify(); + } } void QWinOverlappedIoNotifierPrivate::_q_notified() { - if (WaitForSingleObject(hSemaphore, 0) == WAIT_OBJECT_0) - dispatchNextIoResult(); + Q_Q(QWinOverlappedIoNotifier); + signalSent.storeRelease(0); // signal processed - ready for a new one + if (WaitForSingleObject(hSemaphore, 0) == WAIT_OBJECT_0) { + // As we do not queue signals anymore, we need to process the whole + // queue at once. + WaitForSingleObject(hResultsMutex, INFINITE); + QQueue<IOResult> values; + results.swap(values); + 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. + QPointer<QWinOverlappedIoNotifier> qptr(q); + while (!values.empty() && qptr) { + IOResult ioresult = values.dequeue(); + emit qptr->notified(ioresult.numberOfBytes, ioresult.errorCode, ioresult.overlapped); + } + } } OVERLAPPED *QWinOverlappedIoNotifierPrivate::dispatchNextIoResult() |