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