summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--.qmake.conf2
-rw-r--r--src/serialport/qserialport.cpp38
-rw-r--r--src/serialport/qserialport.h39
-rw-r--r--src/serialport/qserialport_p.h56
-rw-r--r--src/serialport/qserialport_unix.cpp38
-rw-r--r--src/serialport/qserialport_win.cpp402
-rw-r--r--src/serialport/qserialportglobal.h40
-rw-r--r--src/serialport/qserialportinfo.cpp38
-rw-r--r--src/serialport/qserialportinfo.h40
-rw-r--r--src/serialport/qserialportinfo_freebsd.cpp38
-rw-r--r--src/serialport/qserialportinfo_osx.cpp38
-rw-r--r--src/serialport/qserialportinfo_p.h40
-rw-r--r--src/serialport/qserialportinfo_unix.cpp38
-rw-r--r--src/serialport/qserialportinfo_win.cpp38
-rw-r--r--src/serialport/qtntdll_p.h158
-rw-r--r--src/serialport/qtudev_p.h40
-rw-r--r--src/serialport/qwinoverlappedionotifier.cpp78
-rw-r--r--src/serialport/qwinoverlappedionotifier_p.h91
-rw-r--r--src/serialport/serialport-lib.pri3
19 files changed, 542 insertions, 713 deletions
diff --git a/.qmake.conf b/.qmake.conf
index 6d03a03f..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.7
+MODULE_VERSION = 5.15.13
diff --git a/src/serialport/qserialport.cpp b/src/serialport/qserialport.cpp
index ba90ec9b..69f42b2b 100644
--- a/src/serialport/qserialport.cpp
+++ b/src/serialport/qserialport.cpp
@@ -8,8 +8,7 @@
**
** This file is part of the QtSerialPort module of the Qt Toolkit.
**
-** $QT_BEGIN_LICENSE:COMM$
-**
+** $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
@@ -18,25 +17,26 @@
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
-** $QT_END_LICENSE$
-**
-**
-**
-**
-**
-**
-**
-**
-**
-**
-**
-**
-**
-**
-**
-**
+** 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$
**
****************************************************************************/
diff --git a/src/serialport/qserialport.h b/src/serialport/qserialport.h
index 909ed4f5..9a5c1d03 100644
--- a/src/serialport/qserialport.h
+++ b/src/serialport/qserialport.h
@@ -6,8 +6,7 @@
**
** This file is part of the QtSerialPort module of the Qt Toolkit.
**
-** $QT_BEGIN_LICENSE:COMM$
-**
+** $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
@@ -16,25 +15,26 @@
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
-** $QT_END_LICENSE$
-**
-**
-**
-**
-**
-**
-**
-**
-**
-**
-**
-**
-**
-**
-**
-**
+** 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$
**
****************************************************************************/
@@ -306,6 +306,7 @@ private:
#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 --git a/src/serialport/qserialport_p.h b/src/serialport/qserialport_p.h
index d0524dab..b0955aef 100644
--- a/src/serialport/qserialport_p.h
+++ b/src/serialport/qserialport_p.h
@@ -7,8 +7,7 @@
**
** This file is part of the QtSerialPort module of the Qt Toolkit.
**
-** $QT_BEGIN_LICENSE:COMM$
-**
+** $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
@@ -17,25 +16,26 @@
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
-** $QT_END_LICENSE$
-**
-**
-**
-**
-**
-**
-**
-**
-**
-**
-**
-**
-**
-**
-**
-**
+** 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$
**
****************************************************************************/
@@ -104,6 +104,7 @@ struct serial_struct {
QT_BEGIN_NAMESPACE
+class QWinOverlappedIoNotifier;
class QTimer;
class QSocketNotifier;
@@ -181,6 +182,7 @@ public:
bool setDcb(DCB *dcb);
bool getDcb(DCB *dcb);
+ OVERLAPPED *waitForNotified(QDeadlineTimer deadline);
qint64 queuedBytesCount(QSerialPort::Direction direction) const;
@@ -190,15 +192,10 @@ public:
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 @@ public:
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 --git a/src/serialport/qserialport_unix.cpp b/src/serialport/qserialport_unix.cpp
index e9d9be94..294782b5 100644
--- a/src/serialport/qserialport_unix.cpp
+++ b/src/serialport/qserialport_unix.cpp
@@ -7,8 +7,7 @@
**
** This file is part of the QtSerialPort module of the Qt Toolkit.
**
-** $QT_BEGIN_LICENSE:COMM$
-**
+** $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
@@ -17,25 +16,26 @@
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
-** $QT_END_LICENSE$
-**
-**
-**
-**
-**
-**
-**
-**
-**
-**
-**
-**
-**
-**
-**
-**
+** 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$
**
****************************************************************************/
diff --git a/src/serialport/qserialport_win.cpp b/src/serialport/qserialport_win.cpp
index 7f916094..85dd8ee2 100644
--- a/src/serialport/qserialport_win.cpp
+++ b/src/serialport/qserialport_win.cpp
@@ -7,8 +7,7 @@
**
** This file is part of the QtSerialPort module of the Qt Toolkit.
**
-** $QT_BEGIN_LICENSE:COMM$
-**
+** $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
@@ -17,38 +16,69 @@
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
-** $QT_END_LICENSE$
-**
-**
-**
-**
-**
-**
-**
-**
-**
-**
-**
-**
-**
-**
-**
-**
+** 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$
**
****************************************************************************/
#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 @@ static inline void qt_set_flowcontrol(DCB *dcb, QSerialPort::FlowControl flowcon
}
}
-// 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 @@ bool QSerialPortPrivate::open(QIODevice::OpenMode mode)
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 @@ bool QSerialPortPrivate::waitForReadyRead(int msecs)
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 @@ bool QSerialPortPrivate::waitForBytesWritten(int msecs)
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::completeAsyncCommunication(qint64 bytesTransferred)
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 @@ bool QSerialPortPrivate::completeAsyncWrite(qint64 bytesTransferred)
{
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 @@ bool QSerialPortPrivate::startAsyncCommunication()
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 @@ bool QSerialPortPrivate::startAsyncCommunication()
return false;
}
}
+ communicationStarted = true;
return true;
}
@@ -670,27 +546,23 @@ bool QSerialPortPrivate::startAsyncRead()
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 @@ bool QSerialPortPrivate::_q_startAsyncWrite()
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 @@ bool QSerialPortPrivate::_q_startAsyncWrite()
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 @@ qint64 QSerialPortPrivate::writeData(const char *data, qint64 maxSize)
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 @@ qint64 QSerialPortPrivate::queuedBytesCount(QSerialPort::Direction direction) co
inline bool QSerialPortPrivate::initialize(QIODevice::OpenMode mode)
{
+ Q_Q(QSerialPort);
+
DCB dcb;
if (!getDcb(&dcb))
return false;
@@ -819,8 +691,17 @@ inline bool QSerialPortPrivate::initialize(QIODevice::OpenMode mode)
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 @@ QSerialPort::Handle QSerialPort::handle() const
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 --git a/src/serialport/qserialportglobal.h b/src/serialport/qserialportglobal.h
index fae83918..f6c58038 100644
--- a/src/serialport/qserialportglobal.h
+++ b/src/serialport/qserialportglobal.h
@@ -6,8 +6,7 @@
**
** This file is part of the QtSerialPort module of the Qt Toolkit.
**
-** $QT_BEGIN_LICENSE:COMM$
-**
+** $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
@@ -16,25 +15,26 @@
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
-** $QT_END_LICENSE$
-**
-**
-**
-**
-**
-**
-**
-**
-**
-**
-**
-**
-**
-**
-**
-**
-**
+** 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$
**
****************************************************************************/
diff --git a/src/serialport/qserialportinfo.cpp b/src/serialport/qserialportinfo.cpp
index 4e65d1a3..3bfa56c4 100644
--- a/src/serialport/qserialportinfo.cpp
+++ b/src/serialport/qserialportinfo.cpp
@@ -7,8 +7,7 @@
**
** This file is part of the QtSerialPort module of the Qt Toolkit.
**
-** $QT_BEGIN_LICENSE:COMM$
-**
+** $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
@@ -17,25 +16,26 @@
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
-** $QT_END_LICENSE$
-**
-**
-**
-**
-**
-**
-**
-**
-**
-**
-**
-**
-**
-**
-**
-**
+** 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$
**
****************************************************************************/
diff --git a/src/serialport/qserialportinfo.h b/src/serialport/qserialportinfo.h
index 6e704aee..e4c92885 100644
--- a/src/serialport/qserialportinfo.h
+++ b/src/serialport/qserialportinfo.h
@@ -6,8 +6,7 @@
**
** This file is part of the QtSerialPort module of the Qt Toolkit.
**
-** $QT_BEGIN_LICENSE:COMM$
-**
+** $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
@@ -16,25 +15,26 @@
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
-** $QT_END_LICENSE$
-**
-**
-**
-**
-**
-**
-**
-**
-**
-**
-**
-**
-**
-**
-**
-**
-**
+** 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$
**
****************************************************************************/
diff --git a/src/serialport/qserialportinfo_freebsd.cpp b/src/serialport/qserialportinfo_freebsd.cpp
index 0ef4d160..f6d6ea67 100644
--- a/src/serialport/qserialportinfo_freebsd.cpp
+++ b/src/serialport/qserialportinfo_freebsd.cpp
@@ -5,8 +5,7 @@
**
** This file is part of the QtSerialPort module of the Qt Toolkit.
**
-** $QT_BEGIN_LICENSE:COMM$
-**
+** $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
@@ -15,25 +14,26 @@
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
-** $QT_END_LICENSE$
-**
-**
-**
-**
-**
-**
-**
-**
-**
-**
-**
-**
-**
-**
-**
-**
+** 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$
**
****************************************************************************/
diff --git a/src/serialport/qserialportinfo_osx.cpp b/src/serialport/qserialportinfo_osx.cpp
index 0bd27c51..2e46397c 100644
--- a/src/serialport/qserialportinfo_osx.cpp
+++ b/src/serialport/qserialportinfo_osx.cpp
@@ -7,8 +7,7 @@
**
** This file is part of the QtSerialPort module of the Qt Toolkit.
**
-** $QT_BEGIN_LICENSE:COMM$
-**
+** $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
@@ -17,25 +16,26 @@
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
-** $QT_END_LICENSE$
-**
-**
-**
-**
-**
-**
-**
-**
-**
-**
-**
-**
-**
-**
-**
-**
+** 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$
**
****************************************************************************/
diff --git a/src/serialport/qserialportinfo_p.h b/src/serialport/qserialportinfo_p.h
index 01cbfdeb..405cc419 100644
--- a/src/serialport/qserialportinfo_p.h
+++ b/src/serialport/qserialportinfo_p.h
@@ -7,8 +7,7 @@
**
** This file is part of the QtSerialPort module of the Qt Toolkit.
**
-** $QT_BEGIN_LICENSE:COMM$
-**
+** $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
@@ -17,25 +16,26 @@
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
-** $QT_END_LICENSE$
-**
-**
-**
-**
-**
-**
-**
-**
-**
-**
-**
-**
-**
-**
-**
-**
-**
+** 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$
**
****************************************************************************/
diff --git a/src/serialport/qserialportinfo_unix.cpp b/src/serialport/qserialportinfo_unix.cpp
index fa1427ad..105d10af 100644
--- a/src/serialport/qserialportinfo_unix.cpp
+++ b/src/serialport/qserialportinfo_unix.cpp
@@ -7,8 +7,7 @@
**
** This file is part of the QtSerialPort module of the Qt Toolkit.
**
-** $QT_BEGIN_LICENSE:COMM$
-**
+** $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
@@ -17,25 +16,26 @@
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
-** $QT_END_LICENSE$
-**
-**
-**
-**
-**
-**
-**
-**
-**
-**
-**
-**
-**
-**
-**
-**
+** 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$
**
****************************************************************************/
diff --git a/src/serialport/qserialportinfo_win.cpp b/src/serialport/qserialportinfo_win.cpp
index dcf0ddb1..1bab3e9c 100644
--- a/src/serialport/qserialportinfo_win.cpp
+++ b/src/serialport/qserialportinfo_win.cpp
@@ -7,8 +7,7 @@
**
** This file is part of the QtSerialPort module of the Qt Toolkit.
**
-** $QT_BEGIN_LICENSE:COMM$
-**
+** $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
@@ -17,25 +16,26 @@
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
-** $QT_END_LICENSE$
-**
-**
-**
-**
-**
-**
-**
-**
-**
-**
-**
-**
-**
-**
-**
-**
+** 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$
**
****************************************************************************/
diff --git a/src/serialport/qtntdll_p.h b/src/serialport/qtntdll_p.h
deleted file mode 100644
index 2aff6c24..00000000
--- a/src/serialport/qtntdll_p.h
+++ /dev/null
@@ -1,158 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2019 Denis Shienkov <denis.shienkov@gmail.com>
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtSerialPort module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:COMM$
-**
-** 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.
-**
-** $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 --git a/src/serialport/qtudev_p.h b/src/serialport/qtudev_p.h
index e948e526..af2dab2e 100644
--- a/src/serialport/qtudev_p.h
+++ b/src/serialport/qtudev_p.h
@@ -5,8 +5,7 @@
**
** This file is part of the QtSerialPort module of the Qt Toolkit.
**
-** $QT_BEGIN_LICENSE:COMM$
-**
+** $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
@@ -15,25 +14,26 @@
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
-** $QT_END_LICENSE$
-**
-**
-**
-**
-**
-**
-**
-**
-**
-**
-**
-**
-**
-**
-**
-**
-**
+** 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$
**
****************************************************************************/
diff --git a/src/serialport/qwinoverlappedionotifier.cpp b/src/serialport/qwinoverlappedionotifier.cpp
index 09ac7a94..8ec5c1a8 100644
--- a/src/serialport/qwinoverlappedionotifier.cpp
+++ b/src/serialport/qwinoverlappedionotifier.cpp
@@ -1,12 +1,11 @@
/****************************************************************************
**
-** Copyright (C) 2021 The Qt Company Ltd.
+** Copyright (C) 2016 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:COMM$
-**
+** $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
@@ -15,25 +14,26 @@
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
-** $QT_END_LICENSE$
-**
-**
-**
-**
-**
-**
-**
-**
-**
-**
-**
-**
-**
-**
-**
-**
+** 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$
**
****************************************************************************/
@@ -129,6 +129,7 @@ public:
HANDLE hSemaphore = nullptr;
HANDLE hResultsMutex = nullptr;
QAtomicInt waiting;
+ QAtomicInt signalSent;
QQueue<IOResult> results;
};
@@ -395,16 +396,45 @@ 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);
- if (!waiting)
+ 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.
+ 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);
+ // 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.
+ 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 --git a/src/serialport/qwinoverlappedionotifier_p.h b/src/serialport/qwinoverlappedionotifier_p.h
new file mode 100644
index 00000000..dd406ed5
--- /dev/null
+++ b/src/serialport/qwinoverlappedionotifier_p.h
@@ -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 --git a/src/serialport/serialport-lib.pri b/src/serialport/serialport-lib.pri
index b9b3c83b..ddd31f2b 100644
--- a/src/serialport/serialport-lib.pri
+++ b/src/serialport/serialport-lib.pri
@@ -23,9 +23,10 @@ win32 {
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
}