Script 'mail_helper' called by obssrc
Hello community,

here is the log from the commit of package libqt5-qtserialport for 
openSUSE:Factory checked in at 2023-10-08 12:16:58
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/libqt5-qtserialport (Old)
 and      /work/SRC/openSUSE:Factory/.libqt5-qtserialport.new.28202 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "libqt5-qtserialport"

Sun Oct  8 12:16:58 2023 rev:51 rq:1116125 version:5.15.11+kde0

Changes:
--------
--- /work/SRC/openSUSE:Factory/libqt5-qtserialport/libqt5-qtserialport.changes  
2023-06-16 16:53:08.457098737 +0200
+++ 
/work/SRC/openSUSE:Factory/.libqt5-qtserialport.new.28202/libqt5-qtserialport.changes
       2023-10-08 12:18:00.837500636 +0200
@@ -1,0 +2,12 @@
+Fri Oct  6 06:42:53 UTC 2023 - Fabian Vogt <fab...@ritter-vogt.de>
+
+- Update to version 5.15.11+kde0, rebased upstream:
+  * Update LGPL license header
+  * Windows: guard against closing the connection while processing incoming 
data
+  * Windows: fix soft memory leak in synchronous mode
+  * Revert "QSerialPort: Port to alertable I/O functions on Windows"
+  * Revert "Emit _q_notify only if there's no notification pending"
+  * Revert "Revert "Emit _q_notify only if there's no notification pending""
+  * Revert "Avoid possible symbol clashes on static builds on Windows"
+
+-------------------------------------------------------------------

Old:
----
  qtserialport-everywhere-src-5.15.10+kde0.obscpio

New:
----
  qtserialport-everywhere-src-5.15.11+kde0.obscpio

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ libqt5-qtserialport.spec ++++++
--- /var/tmp/diff_new_pack.q2deLP/_old  2023-10-08 12:18:02.373555864 +0200
+++ /var/tmp/diff_new_pack.q2deLP/_new  2023-10-08 12:18:02.377556007 +0200
@@ -19,11 +19,11 @@
 %define qt5_snapshot 1
 %define libname libQt5SerialPort5
 %define base_name libqt5
-%define real_version 5.15.10
-%define so_version 5.15.10
+%define real_version 5.15.11
+%define so_version 5.15.11
 %define tar_version qtserialport-everywhere-src-%{version}
 Name:           libqt5-qtserialport
-Version:        5.15.10+kde0
+Version:        5.15.11+kde0
 Release:        0
 Summary:        Qt 5 Serial Port Addon
 License:        LGPL-3.0-only OR (GPL-2.0-only OR GPL-3.0-or-later)

++++++ _service ++++++
--- /var/tmp/diff_new_pack.q2deLP/_old  2023-10-08 12:18:02.413557302 +0200
+++ /var/tmp/diff_new_pack.q2deLP/_new  2023-10-08 12:18:02.417557445 +0200
@@ -1,12 +1,12 @@
 <services>
   <service name="obs_scm" mode="disabled">
    <param name="changesgenerate">enable</param>
-   <param name="versionformat">5.15.10+kde@TAG_OFFSET@</param>
+   <param name="versionformat">5.15.11+kde@TAG_OFFSET@</param>
    <param name="url">https://invent.kde.org/qt/qt/qtserialport.git</param>
    <param name="scm">git</param>
    <param name="filename">qtserialport-everywhere-src</param>
    <param name="revision">kde/5.15</param>
-   <param name="parent-tag">v5.15.10-lts-lgpl</param>
+   <param name="parent-tag">v5.15.11-lts-lgpl</param>
    <param name="changesgenerate">enable</param>
   </service>
   <service name="set_version" mode="disabled"/>

++++++ _servicedata ++++++
--- /var/tmp/diff_new_pack.q2deLP/_old  2023-10-08 12:18:02.437558165 +0200
+++ /var/tmp/diff_new_pack.q2deLP/_new  2023-10-08 12:18:02.441558308 +0200
@@ -1,6 +1,6 @@
 <servicedata>
 <service name="tar_scm">
                 <param 
name="url">https://invent.kde.org/qt/qt/qtserialport.git</param>
-              <param 
name="changesrevision">af58a4c62415fbfd997c43422acf93e2e6ab5155</param></service></servicedata>
+              <param 
name="changesrevision">3380465d5d4977326616c5e57789a81681be650e</param></service></servicedata>
 (No newline at EOF)
 

++++++ qtserialport-everywhere-src-5.15.10+kde0.obscpio -> 
qtserialport-everywhere-src-5.15.11+kde0.obscpio ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/qtserialport-everywhere-src-5.15.10+kde0/.qmake.conf 
new/qtserialport-everywhere-src-5.15.11+kde0/.qmake.conf
--- old/qtserialport-everywhere-src-5.15.10+kde0/.qmake.conf    2023-04-24 
09:14:05.000000000 +0200
+++ new/qtserialport-everywhere-src-5.15.11+kde0/.qmake.conf    2023-08-25 
10:37:11.000000000 +0200
@@ -2,4 +2,4 @@
 
 DEFINES += QT_NO_FOREACH QT_NO_JAVA_STYLE_ITERATORS QT_NO_LINKED_LIST
 
-MODULE_VERSION = 5.15.10
+MODULE_VERSION = 5.15.11
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/qtserialport-everywhere-src-5.15.10+kde0/src/serialport/qserialport.h 
new/qtserialport-everywhere-src-5.15.11+kde0/src/serialport/qserialport.h
--- old/qtserialport-everywhere-src-5.15.10+kde0/src/serialport/qserialport.h   
2023-04-24 09:14:05.000000000 +0200
+++ new/qtserialport-everywhere-src-5.15.11+kde0/src/serialport/qserialport.h   
2023-08-25 10:37:11.000000000 +0200
@@ -306,6 +306,7 @@
 
 #if defined(Q_OS_WIN32)
     Q_PRIVATE_SLOT(d_func(), bool _q_startAsyncWrite())
+    Q_PRIVATE_SLOT(d_func(), void _q_notified(quint32, quint32, OVERLAPPED*))
 #endif
 };
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/qtserialport-everywhere-src-5.15.10+kde0/src/serialport/qserialport_p.h 
new/qtserialport-everywhere-src-5.15.11+kde0/src/serialport/qserialport_p.h
--- old/qtserialport-everywhere-src-5.15.10+kde0/src/serialport/qserialport_p.h 
2023-04-24 09:14:05.000000000 +0200
+++ new/qtserialport-everywhere-src-5.15.11+kde0/src/serialport/qserialport_p.h 
2023-08-25 10:37:11.000000000 +0200
@@ -104,6 +104,7 @@
 
 QT_BEGIN_NAMESPACE
 
+class QWinOverlappedIoNotifier;
 class QTimer;
 class QSocketNotifier;
 
@@ -181,6 +182,7 @@
 
     bool setDcb(DCB *dcb);
     bool getDcb(DCB *dcb);
+    OVERLAPPED *waitForNotified(QDeadlineTimer deadline);
 
     qint64 queuedBytesCount(QSerialPort::Direction direction) const;
 
@@ -190,15 +192,10 @@
 
     bool startAsyncCommunication();
     bool _q_startAsyncWrite();
-    void handleNotification(DWORD bytesTransferred, DWORD errorCode,
-                            OVERLAPPED *overlapped);
+    void _q_notified(DWORD numberOfBytes, DWORD errorCode, OVERLAPPED 
*overlapped);
 
     void emitReadyRead();
 
-    static void CALLBACK ioCompletionRoutine(
-            DWORD errorCode, DWORD bytesTransfered,
-            OVERLAPPED *overlappedBase);
-
     DCB restoredDcb;
     COMMTIMEOUTS currentCommTimeouts;
     COMMTIMEOUTS restoredCommTimeouts;
@@ -208,12 +205,11 @@
     bool communicationStarted = false;
     bool writeStarted = false;
     bool readStarted = false;
-    qint64 writeBytesTransferred = 0;
-    qint64 readBytesTransferred = 0;
+    QWinOverlappedIoNotifier *notifier = nullptr;
     QTimer *startAsyncWriteTimer = nullptr;
-    class Overlapped *communicationCompletionOverlapped = nullptr;
-    class Overlapped *readCompletionOverlapped = nullptr;
-    class Overlapped *writeCompletionOverlapped = nullptr;
+    OVERLAPPED communicationOverlapped;
+    OVERLAPPED readCompletionOverlapped;
+    OVERLAPPED writeCompletionOverlapped;
     DWORD triggeredEventMask = 0;
 
 #elif defined(Q_OS_UNIX)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/qtserialport-everywhere-src-5.15.10+kde0/src/serialport/qserialport_win.cpp 
new/qtserialport-everywhere-src-5.15.11+kde0/src/serialport/qserialport_win.cpp
--- 
old/qtserialport-everywhere-src-5.15.10+kde0/src/serialport/qserialport_win.cpp 
    2023-04-24 09:14:05.000000000 +0200
+++ 
new/qtserialport-everywhere-src-5.15.11+kde0/src/serialport/qserialport_win.cpp 
    2023-08-25 10:37:11.000000000 +0200
@@ -40,15 +40,45 @@
 ****************************************************************************/
 
 #include "qserialport_p.h"
-#include "qtntdll_p.h"
+#include "qwinoverlappedionotifier_p.h"
 
 #include <QtCore/qcoreevent.h>
 #include <QtCore/qelapsedtimer.h>
-#include <QtCore/qmutex.h>
-#include <QtCore/qtimer.h>
 #include <QtCore/qvector.h>
+#include <QtCore/qtimer.h>
 #include <algorithm>
 
+#ifndef CTL_CODE
+#  define CTL_CODE(DeviceType, Function, Method, Access) ( \
+    ((DeviceType) << 16) | ((Access) << 14) | ((Function) << 2) | (Method) \
+    )
+#endif
+
+#ifndef FILE_DEVICE_SERIAL_PORT
+#  define FILE_DEVICE_SERIAL_PORT  27
+#endif
+
+#ifndef METHOD_BUFFERED
+#  define METHOD_BUFFERED  0
+#endif
+
+#ifndef FILE_ANY_ACCESS
+#  define FILE_ANY_ACCESS  0x00000000
+#endif
+
+#ifndef IOCTL_SERIAL_GET_DTRRTS
+#  define IOCTL_SERIAL_GET_DTRRTS \
+    CTL_CODE(FILE_DEVICE_SERIAL_PORT, 30, METHOD_BUFFERED, FILE_ANY_ACCESS)
+#endif
+
+#ifndef SERIAL_DTR_STATE
+#  define SERIAL_DTR_STATE  0x00000001
+#endif
+
+#ifndef SERIAL_RTS_STATE
+#  define SERIAL_RTS_STATE  0x00000002
+#endif
+
 QT_BEGIN_NAMESPACE
 
 static inline void qt_set_common_props(DCB *dcb)
@@ -143,117 +173,8 @@
     }
 }
 
-// Translate NT-callbacks to Win32 callbacks.
-static VOID WINAPI qt_apc_routine(
-        PVOID context,
-        PIO_STATUS_BLOCK ioStatusBlock,
-        DWORD reserved)
-{
-    Q_UNUSED(reserved);
-
-    const DWORD errorCode = ::RtlNtStatusToDosError(ioStatusBlock->Status);
-    const DWORD bytesTransfered = NT_SUCCESS(ioStatusBlock->Status)
-            ? DWORD(ioStatusBlock->Information) : 0;
-    const LPOVERLAPPED overlapped = CONTAINING_RECORD(ioStatusBlock,
-                                                      OVERLAPPED, Internal);
-
-    (reinterpret_cast<LPOVERLAPPED_COMPLETION_ROUTINE>(context))
-            (errorCode, bytesTransfered, overlapped);
-}
-
-// Alertable analog of DeviceIoControl function.
-static BOOL qt_device_io_control_ex(
-        HANDLE deviceHandle,
-        DWORD ioControlCode,
-        LPVOID inputBuffer,
-        DWORD inputBufferSize,
-        LPVOID outputBuffer,
-        DWORD outputBufferSize,
-        LPOVERLAPPED overlapped,
-        LPOVERLAPPED_COMPLETION_ROUTINE completionRoutine)
-{
-    const auto ioStatusBlock = reinterpret_cast<PIO_STATUS_BLOCK>(
-                &overlapped->Internal);
-    ioStatusBlock->Status = STATUS_PENDING;
-
-    const NTSTATUS status = ::NtDeviceIoControlFile(
-                deviceHandle,
-                nullptr,
-                qt_apc_routine,
-                reinterpret_cast<PVOID>(completionRoutine),
-                ioStatusBlock,
-                ioControlCode,
-                inputBuffer,
-                inputBufferSize,
-                outputBuffer,
-                outputBufferSize);
-
-    if (!NT_SUCCESS(status)) {
-        ::SetLastError(::RtlNtStatusToDosError(status));
-        return false;
-    }
-
-    return true;
-}
-
-// Alertable analog of WaitCommEvent function.
-static BOOL qt_wait_comm_event_ex(
-        HANDLE deviceHandle,
-        LPDWORD eventsMask,
-        LPOVERLAPPED overlapped,
-        LPOVERLAPPED_COMPLETION_ROUTINE completionRoutine)
-{
-    return qt_device_io_control_ex(
-                deviceHandle,
-                IOCTL_SERIAL_WAIT_ON_MASK,
-                nullptr,
-                0,
-                eventsMask,
-                sizeof(DWORD),
-                overlapped,
-                completionRoutine);
-}
-
-struct RuntimeHelper
-{
-    QLibrary ntLibrary;
-    QBasicMutex mutex;
-};
-
-Q_GLOBAL_STATIC(RuntimeHelper, helper)
-
-class Overlapped final : public OVERLAPPED
-{
-    Q_DISABLE_COPY(Overlapped)
-public:
-    explicit Overlapped(QSerialPortPrivate *d);
-    void clear();
-
-    QSerialPortPrivate *dptr = nullptr;
-};
-
-Overlapped::Overlapped(QSerialPortPrivate *d)
-    : dptr(d)
-{
-}
-
-void Overlapped::clear()
-{
-    ::ZeroMemory(this, sizeof(OVERLAPPED));
-}
-
 bool QSerialPortPrivate::open(QIODevice::OpenMode mode)
 {
-    {
-        QMutexLocker locker(&helper()->mutex);
-        static bool symbolsResolved = 
resolveNtdllSymbols(&helper()->ntLibrary);
-        if (!symbolsResolved) {
-            setError(QSerialPortErrorInfo(QSerialPort::OpenError,
-                                          helper()->ntLibrary.errorString()));
-            return false;
-        }
-    }
-
     DWORD desiredAccess = 0;
 
     if (mode & QIODevice::ReadOnly)
@@ -278,44 +199,17 @@
 
 void QSerialPortPrivate::close()
 {
-    delete startAsyncWriteTimer;
-    startAsyncWriteTimer = nullptr;
-
-    if (communicationStarted) {
-        communicationCompletionOverlapped->dptr = nullptr;
-        ::CancelIoEx(handle, communicationCompletionOverlapped);
-        // The object will be deleted in the I/O callback.
-        communicationCompletionOverlapped = nullptr;
-        communicationStarted = false;
-    } else {
-        delete communicationCompletionOverlapped;
-        communicationCompletionOverlapped = nullptr;
-    }
+    ::CancelIo(handle);
 
-    if (readStarted) {
-        readCompletionOverlapped->dptr = nullptr;
-        ::CancelIoEx(handle, readCompletionOverlapped);
-        // The object will be deleted in the I/O callback.
-        readCompletionOverlapped = nullptr;
-        readStarted = false;
-    } else {
-        delete readCompletionOverlapped;
-        readCompletionOverlapped = nullptr;
-    };
+    delete notifier;
+    notifier = nullptr;
 
-    if (writeStarted) {
-        writeCompletionOverlapped->dptr = nullptr;
-        ::CancelIoEx(handle, writeCompletionOverlapped);
-        // The object will be deleted in the I/O callback.
-        writeCompletionOverlapped = nullptr;
-        writeStarted = false;
-    } else {
-        delete writeCompletionOverlapped;
-        writeCompletionOverlapped = nullptr;
-    }
+    delete startAsyncWriteTimer;
+    startAsyncWriteTimer = nullptr;
 
-    readBytesTransferred = 0;
-    writeBytesTransferred = 0;
+    communicationStarted = false;
+    readStarted = false;
+    writeStarted = false;
     writeBuffer.clear();
 
     if (settingsRestoredOnClose) {
@@ -447,25 +341,30 @@
     if (!writeStarted && !_q_startAsyncWrite())
         return false;
 
+    const qint64 initialReadBufferSize = buffer.size();
+    qint64 currentReadBufferSize = initialReadBufferSize;
+
     QDeadlineTimer deadline(msecs);
 
     do {
-        if (readBytesTransferred <= 0) {
-            const qint64 remaining = deadline.remainingTime();
-            const DWORD result = ::SleepEx(
-                        remaining == -1 ? INFINITE : DWORD(remaining),
-                        TRUE);
-            if (result != WAIT_IO_COMPLETION)
-                continue;
-        }
+        const OVERLAPPED *overlapped = waitForNotified(deadline);
+        if (!overlapped)
+            return false;
 
-        if (readBytesTransferred > 0) {
-            readBytesTransferred = 0;
-            return true;
+        if (overlapped == &readCompletionOverlapped) {
+            const qint64 readBytesForOneReadOperation = qint64(buffer.size()) 
- currentReadBufferSize;
+            if (readBytesForOneReadOperation == QSERIALPORT_BUFFERSIZE) {
+                currentReadBufferSize = buffer.size();
+            } else if (readBytesForOneReadOperation == 0) {
+                if (initialReadBufferSize != currentReadBufferSize)
+                    return true;
+            } else {
+                return true;
+            }
         }
+
     } while (!deadline.hasExpired());
 
-    setError(getSystemError(WAIT_TIMEOUT));
     return false;
 }
 
@@ -479,23 +378,15 @@
 
     QDeadlineTimer deadline(msecs);
 
-    do {
-        if (writeBytesTransferred <= 0) {
-            const qint64 remaining = deadline.remainingTime();
-            const DWORD result = ::SleepEx(
-                        remaining == -1 ? INFINITE : DWORD(remaining),
-                        TRUE);
-            if (result != WAIT_IO_COMPLETION)
-                continue;
-        }
+    for (;;) {
+        const OVERLAPPED *overlapped = waitForNotified(deadline);
+        if (!overlapped)
+            return false;
 
-        if (writeBytesTransferred > 0) {
-            writeBytesTransferred = 0;
+         if (overlapped == &writeCompletionOverlapped)
             return true;
-        }
-    } while (!deadline.hasExpired());
+    }
 
-    setError(getSystemError(WAIT_TIMEOUT));
     return false;
 }
 
@@ -576,10 +467,6 @@
 
 bool QSerialPortPrivate::completeAsyncRead(qint64 bytesTransferred)
 {
-    // Store the number of transferred bytes which are
-    // required only in waitForReadyRead() method.
-    readBytesTransferred = bytesTransferred;
-
     if (bytesTransferred == qint64(-1)) {
         readStarted = false;
         return false;
@@ -607,10 +494,6 @@
 {
     Q_Q(QSerialPort);
 
-    // Store the number of transferred bytes which are
-    // required only in waitForBytesWritten() method.
-    writeBytesTransferred = bytesTransferred;
-
     if (writeStarted) {
         if (bytesTransferred == qint64(-1)) {
             writeChunkBuffer.clear();
@@ -631,16 +514,8 @@
     if (communicationStarted)
         return true;
 
-    if (!communicationCompletionOverlapped)
-        communicationCompletionOverlapped = new Overlapped(this);
-
-    communicationCompletionOverlapped->clear();
-    communicationStarted = true;
-    if (!::qt_wait_comm_event_ex(handle,
-                                 &triggeredEventMask,
-                                 communicationCompletionOverlapped,
-                                 ioCompletionRoutine)) {
-        communicationStarted = false;
+    ::ZeroMemory(&communicationOverlapped, sizeof(communicationOverlapped));
+    if (!::WaitCommEvent(handle, &triggeredEventMask, 
&communicationOverlapped)) {
         QSerialPortErrorInfo error = getSystemError();
         if (error.errorCode != QSerialPort::NoError) {
             if (error.errorCode == QSerialPort::PermissionError)
@@ -649,6 +524,7 @@
             return false;
         }
     }
+    communicationStarted = true;
     return true;
 }
 
@@ -670,27 +546,23 @@
 
     Q_ASSERT(int(bytesToRead) <= readChunkBuffer.size());
 
-    if (!readCompletionOverlapped)
-        readCompletionOverlapped = new Overlapped(this);
+    ::ZeroMemory(&readCompletionOverlapped, sizeof(readCompletionOverlapped));
+    if (::ReadFile(handle, readChunkBuffer.data(), bytesToRead, nullptr, 
&readCompletionOverlapped)) {
+        readStarted = true;
+        return true;
+    }
 
-    readCompletionOverlapped->clear();
-    readStarted = true;
-    if (!::ReadFileEx(handle,
-                      readChunkBuffer.data(),
-                      bytesToRead,
-                      readCompletionOverlapped,
-                      ioCompletionRoutine)) {
-        readStarted = false;
-        QSerialPortErrorInfo error = getSystemError();
-        if (error.errorCode != QSerialPort::NoError) {
-            if (error.errorCode == QSerialPort::PermissionError)
-                error.errorCode = QSerialPort::ResourceError;
-            if (error.errorCode != QSerialPort::ResourceError)
-                error.errorCode = QSerialPort::ReadError;
-            setError(error);
-            return false;
-        }
+    QSerialPortErrorInfo error = getSystemError();
+    if (error.errorCode != QSerialPort::NoError) {
+        if (error.errorCode == QSerialPort::PermissionError)
+            error.errorCode = QSerialPort::ResourceError;
+        if (error.errorCode != QSerialPort::ResourceError)
+            error.errorCode = QSerialPort::ReadError;
+        setError(error);
+        return false;
     }
+
+    readStarted = true;
     return true;
 }
 
@@ -700,18 +572,10 @@
         return true;
 
     writeChunkBuffer = writeBuffer.read();
+    ::ZeroMemory(&writeCompletionOverlapped, 
sizeof(writeCompletionOverlapped));
+    if (!::WriteFile(handle, writeChunkBuffer.constData(),
+                     writeChunkBuffer.size(), nullptr, 
&writeCompletionOverlapped)) {
 
-    if (!writeCompletionOverlapped)
-        writeCompletionOverlapped = new Overlapped(this);
-
-    writeCompletionOverlapped->clear();
-    writeStarted = true;
-    if (!::WriteFileEx(handle,
-                       writeChunkBuffer.constData(),
-                       writeChunkBuffer.size(),
-                       writeCompletionOverlapped,
-                       ioCompletionRoutine)) {
-        writeStarted = false;
         QSerialPortErrorInfo error = getSystemError();
         if (error.errorCode != QSerialPort::NoError) {
             if (error.errorCode != QSerialPort::ResourceError)
@@ -720,29 +584,25 @@
             return false;
         }
     }
+
+    writeStarted = true;
     return true;
 }
 
-void QSerialPortPrivate::handleNotification(DWORD bytesTransferred, DWORD 
errorCode,
-                                            OVERLAPPED *overlapped)
+void QSerialPortPrivate::_q_notified(DWORD numberOfBytes, DWORD errorCode, 
OVERLAPPED *overlapped)
 {
-    // This occurred e.g. after calling the CloseHandle() function,
-    // just skip handling at all.
-    if (handle == INVALID_HANDLE_VALUE)
-        return;
-
     const QSerialPortErrorInfo error = getSystemError(errorCode);
     if (error.errorCode != QSerialPort::NoError) {
         setError(error);
         return;
     }
 
-    if (overlapped == communicationCompletionOverlapped)
-        completeAsyncCommunication(bytesTransferred);
-    else if (overlapped == readCompletionOverlapped)
-        completeAsyncRead(bytesTransferred);
-    else if (overlapped == writeCompletionOverlapped)
-        completeAsyncWrite(bytesTransferred);
+    if (overlapped == &communicationOverlapped)
+        completeAsyncCommunication(numberOfBytes);
+    else if (overlapped == &readCompletionOverlapped)
+        completeAsyncRead(numberOfBytes);
+    else if (overlapped == &writeCompletionOverlapped)
+        completeAsyncWrite(numberOfBytes);
     else
         Q_ASSERT(!"Unknown OVERLAPPED activated");
 }
@@ -772,6 +632,16 @@
     return maxSize;
 }
 
+OVERLAPPED *QSerialPortPrivate::waitForNotified(QDeadlineTimer deadline)
+{
+    OVERLAPPED *overlapped = notifier->waitForAnyNotified(deadline);
+    if (!overlapped) {
+        setError(getSystemError(WAIT_TIMEOUT));
+        return nullptr;
+    }
+    return overlapped;
+}
+
 qint64 QSerialPortPrivate::queuedBytesCount(QSerialPort::Direction direction) 
const
 {
     COMSTAT comstat;
@@ -784,6 +654,8 @@
 
 inline bool QSerialPortPrivate::initialize(QIODevice::OpenMode mode)
 {
+    Q_Q(QSerialPort);
+
     DCB dcb;
     if (!getDcb(&dcb))
         return false;
@@ -819,8 +691,17 @@
         return false;
     }
 
-    if ((eventMask & EV_RXCHAR) && !startAsyncCommunication())
+    notifier = new QWinOverlappedIoNotifier(q);
+    QObjectPrivate::connect(notifier, &QWinOverlappedIoNotifier::notified,
+               this, &QSerialPortPrivate::_q_notified);
+    notifier->setHandle(handle);
+    notifier->setEnabled(true);
+
+    if ((eventMask & EV_RXCHAR) && !startAsyncCommunication()) {
+        delete notifier;
+        notifier = nullptr;
         return false;
+    }
 
     return true;
 }
@@ -920,17 +801,4 @@
     return d->handle;
 }
 
-void QSerialPortPrivate::ioCompletionRoutine(
-        DWORD errorCode, DWORD bytesTransfered,
-        OVERLAPPED *overlappedBase)
-{
-    const auto overlapped = static_cast<Overlapped *>(overlappedBase);
-    if (overlapped->dptr) {
-        overlapped->dptr->handleNotification(bytesTransfered, errorCode,
-                                             overlappedBase);
-    } else {
-        delete overlapped;
-    }
-}
-
 QT_END_NAMESPACE
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/qtserialport-everywhere-src-5.15.10+kde0/src/serialport/qtntdll_p.h 
new/qtserialport-everywhere-src-5.15.11+kde0/src/serialport/qtntdll_p.h
--- old/qtserialport-everywhere-src-5.15.10+kde0/src/serialport/qtntdll_p.h     
2023-04-24 09:14:05.000000000 +0200
+++ new/qtserialport-everywhere-src-5.15.11+kde0/src/serialport/qtntdll_p.h     
1970-01-01 01:00:00.000000000 +0100
@@ -1,158 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2019 Denis Shienkov <denis.shien...@gmail.com>
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtSerialPort module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QTNTDLL_P_H
-#define QTNTDLL_P_H
-
-//
-//  W A R N I N G
-//  -------------
-//
-// This file is not part of the Qt API.  It exists purely as an
-// implementation detail.  This header file may change from version to
-// version without notice, or even be removed.
-//
-// We mean it.
-//
-
-#include <QtCore/qlibrary.h>
-#include <QtCore/qstring.h>
-#include <QtCore/qdebug.h>
-
-#include <qt_windows.h>
-
-// Internal control codes.
-
-#ifndef CTL_CODE
-#  define CTL_CODE(DeviceType, Function, Method, Access) ( \
-    ((DeviceType) << 16) | ((Access) << 14) | ((Function) << 2) | (Method) \
-    )
-#endif
-
-#ifndef FILE_DEVICE_SERIAL_PORT
-#  define FILE_DEVICE_SERIAL_PORT  27
-#endif
-
-#ifndef METHOD_BUFFERED
-#  define METHOD_BUFFERED  0
-#endif
-
-#ifndef FILE_ANY_ACCESS
-#  define FILE_ANY_ACCESS  0x00000000
-#endif
-
-#ifndef IOCTL_SERIAL_GET_DTRRTS
-#  define IOCTL_SERIAL_GET_DTRRTS \
-    CTL_CODE(FILE_DEVICE_SERIAL_PORT, 30, METHOD_BUFFERED, FILE_ANY_ACCESS)
-#endif
-
-#ifndef SERIAL_DTR_STATE
-#  define SERIAL_DTR_STATE  0x00000001
-#endif
-
-#ifndef SERIAL_RTS_STATE
-#  define SERIAL_RTS_STATE  0x00000002
-#endif
-
-#ifndef IOCTL_SERIAL_WAIT_ON_MASK
-#  define IOCTL_SERIAL_WAIT_ON_MASK \
-    CTL_CODE(FILE_DEVICE_SERIAL_PORT, 18, METHOD_BUFFERED, FILE_ANY_ACCESS)
-#endif
-
-// Internal NT-based data types.
-
-#ifndef NT_SUCCESS
-#define NT_SUCCESS(status) (((NTSTATUS)(status)) >= 0)
-#endif
-
-typedef struct _IO_STATUS_BLOCK {
-    union {
-        NTSTATUS Status;
-        PVOID Pointer;
-    } DUMMYUNIONNAME;
-
-    ULONG_PTR Information;
-} IO_STATUS_BLOCK, *PIO_STATUS_BLOCK;
-
-typedef VOID (WINAPI *PIO_APC_ROUTINE) (
-        PVOID ApcContext,
-        PIO_STATUS_BLOCK IoStatusBlock,
-        ULONG Reserved
-        );
-
-// Resolving macros.
-
-#define GENERATE_SYMBOL_VARIABLE(returnType, symbolName, ...) \
-    typedef returnType (WINAPI *fp_##symbolName)(__VA_ARGS__); \
-    static fp_##symbolName symbolName;
-
-#define RESOLVE_SYMBOL(symbolName) \
-    symbolName = 
reinterpret_cast<fp_##symbolName>(resolveNtdllSymbol(ntLibrary, #symbolName)); \
-    if (!symbolName) \
-        return false;
-
-GENERATE_SYMBOL_VARIABLE(ULONG, RtlNtStatusToDosError, NTSTATUS)
-GENERATE_SYMBOL_VARIABLE(NTSTATUS, NtDeviceIoControlFile, HANDLE, HANDLE, 
PIO_APC_ROUTINE, PVOID, PIO_STATUS_BLOCK, ULONG, PVOID, ULONG, PVOID, ULONG)
-
-inline QFunctionPointer resolveNtdllSymbol(QLibrary *ntLibrary, const char 
*symbolName)
-{
-    QFunctionPointer symbolFunctionPointer = ntLibrary->resolve(symbolName);
-    if (!symbolFunctionPointer)
-        qWarning("Failed to resolve the symbol: %s", symbolName);
-
-    return symbolFunctionPointer;
-}
-
-inline bool resolveNtdllSymbols(QLibrary *ntLibrary)
-{
-    if (!ntLibrary->isLoaded()) {
-        ntLibrary->setFileName(QStringLiteral("ntdll"));
-        if (!ntLibrary->load()) {
-            qWarning("Failed to load the library: %s", 
qPrintable(ntLibrary->fileName()));
-            return false;
-        }
-    }
-
-    RESOLVE_SYMBOL(RtlNtStatusToDosError)
-    RESOLVE_SYMBOL(NtDeviceIoControlFile)
-
-    return true;
-}
-
-#endif // QTNTDLL_P_H
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/qtserialport-everywhere-src-5.15.10+kde0/src/serialport/qwinoverlappedionotifier.cpp
 
new/qtserialport-everywhere-src-5.15.11+kde0/src/serialport/qwinoverlappedionotifier.cpp
--- 
old/qtserialport-everywhere-src-5.15.10+kde0/src/serialport/qwinoverlappedionotifier.cpp
    2023-04-24 09:14:05.000000000 +0200
+++ 
new/qtserialport-everywhere-src-5.15.11+kde0/src/serialport/qwinoverlappedionotifier.cpp
    2023-08-25 10:37:11.000000000 +0200
@@ -129,6 +129,7 @@
     HANDLE hSemaphore = nullptr;
     HANDLE hResultsMutex = nullptr;
     QAtomicInt waiting;
+    QAtomicInt signalSent;
     QQueue<IOResult> results;
 };
 
@@ -397,14 +398,34 @@
     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()
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/qtserialport-everywhere-src-5.15.10+kde0/src/serialport/qwinoverlappedionotifier_p.h
 
new/qtserialport-everywhere-src-5.15.11+kde0/src/serialport/qwinoverlappedionotifier_p.h
--- 
old/qtserialport-everywhere-src-5.15.10+kde0/src/serialport/qwinoverlappedionotifier_p.h
    1970-01-01 01:00:00.000000000 +0100
+++ 
new/qtserialport-everywhere-src-5.15.11+kde0/src/serialport/qwinoverlappedionotifier_p.h
    2023-08-25 10:37:11.000000000 +0200
@@ -0,0 +1,91 @@
+/****************************************************************************
+**
+** Copyright (C) 2023 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtCore module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QWINOVERLAPPEDIONOTIFIER_P_H
+#define QWINOVERLAPPEDIONOTIFIER_P_H
+
+//
+//  W A R N I N G
+//  -------------
+//
+// This file is not part of the Qt API.  It exists purely as an
+// implementation detail.  This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include <QtCore/private/qglobal_p.h>
+#include <qobject.h>
+#include <qdeadlinetimer.h>
+
+typedef struct _OVERLAPPED OVERLAPPED;
+
+QT_BEGIN_NAMESPACE
+
+class QWinOverlappedIoNotifierPrivate;
+
+class QWinOverlappedIoNotifier : public QObject
+{
+    Q_OBJECT
+    Q_DISABLE_COPY(QWinOverlappedIoNotifier)
+    Q_DECLARE_PRIVATE(QWinOverlappedIoNotifier)
+    Q_PRIVATE_SLOT(d_func(), void _q_notified())
+    friend class QWinIoCompletionPort;
+public:
+    QWinOverlappedIoNotifier(QObject *parent = 0);
+    ~QWinOverlappedIoNotifier();
+
+    void setHandle(Qt::HANDLE h);
+    Qt::HANDLE handle() const;
+
+    void setEnabled(bool enabled);
+    OVERLAPPED *waitForAnyNotified(QDeadlineTimer deadline);
+    bool waitForNotified(QDeadlineTimer deadline, OVERLAPPED *overlapped);
+
+Q_SIGNALS:
+    void notified(quint32 numberOfBytes, quint32 errorCode, OVERLAPPED 
*overlapped);
+#if !defined(Q_QDOC)
+    void _q_notify();
+#endif
+};
+
+QT_END_NAMESPACE
+
+#endif // QWINOVERLAPPEDIONOTIFIER_P_H
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/qtserialport-everywhere-src-5.15.10+kde0/src/serialport/serialport-lib.pri 
new/qtserialport-everywhere-src-5.15.11+kde0/src/serialport/serialport-lib.pri
--- 
old/qtserialport-everywhere-src-5.15.10+kde0/src/serialport/serialport-lib.pri  
    2023-04-24 09:14:05.000000000 +0200
+++ 
new/qtserialport-everywhere-src-5.15.11+kde0/src/serialport/serialport-lib.pri  
    2023-08-25 10:37:11.000000000 +0200
@@ -23,9 +23,10 @@
     SOURCES += \
         $$PWD/qserialport_win.cpp \
         $$PWD/qserialportinfo_win.cpp \
+        $$PWD/qwinoverlappedionotifier.cpp
 
     PRIVATE_HEADERS += \
-        $$PWD/qtntdll_p.h
+        $$PWD/qwinoverlappedionotifier_p.h
 
     LIBS_PRIVATE += -lsetupapi -ladvapi32
 }

++++++ qtserialport-everywhere-src.obsinfo ++++++
--- /var/tmp/diff_new_pack.q2deLP/_old  2023-10-08 12:18:02.693567369 +0200
+++ /var/tmp/diff_new_pack.q2deLP/_new  2023-10-08 12:18:02.697567513 +0200
@@ -1,5 +1,5 @@
 name: qtserialport-everywhere-src
-version: 5.15.10+kde0
-mtime: 1682320445
-commit: af58a4c62415fbfd997c43422acf93e2e6ab5155
+version: 5.15.11+kde0
+mtime: 1692952631
+commit: 3380465d5d4977326616c5e57789a81681be650e
 

Reply via email to