summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/serialport/qserialport.cpp34
-rw-r--r--src/serialport/qserialport_p.h7
-rw-r--r--src/serialport/qserialport_win.cpp93
3 files changed, 88 insertions, 46 deletions
diff --git a/src/serialport/qserialport.cpp b/src/serialport/qserialport.cpp
index 84c086e..0312b44 100644
--- a/src/serialport/qserialport.cpp
+++ b/src/serialport/qserialport.cpp
@@ -72,9 +72,9 @@ QSerialPortPrivate::QSerialPortPrivate(QSerialPort *q)
, readyReadEmitted(0)
, writeStarted(false)
, readStarted(false)
- , communicationNotifier(new QWinEventNotifier(q))
- , readCompletionNotifier(new QWinEventNotifier(q))
- , writeCompletionNotifier(new QWinEventNotifier(q))
+ , communicationNotifier(0)
+ , readCompletionNotifier(0)
+ , writeCompletionNotifier(0)
, startAsyncWriteTimer(0)
, originalEventMask(0)
, triggeredEventMask(0)
@@ -92,34 +92,6 @@ QSerialPortPrivate::QSerialPortPrivate(QSerialPort *q)
, writeSequenceStarted(false)
#endif
{
-#ifdef Q_OS_WIN32
- ::ZeroMemory(&communicationOverlapped, sizeof(communicationOverlapped));
- communicationOverlapped.hEvent = ::CreateEvent(NULL, FALSE, FALSE, NULL);
- if (!communicationOverlapped.hEvent) {
- q->setError(decodeSystemError());
- } else {
- communicationNotifier->setHandle(communicationOverlapped.hEvent);
- q->connect(communicationNotifier, SIGNAL(activated(HANDLE)), q, SLOT(_q_completeAsyncCommunication()));
- }
-
- ::ZeroMemory(&readCompletionOverlapped, sizeof(readCompletionOverlapped));
- readCompletionOverlapped.hEvent = ::CreateEvent(NULL, FALSE, FALSE, NULL);
- if (!readCompletionOverlapped.hEvent) {
- q->setError(decodeSystemError());
- } else {
- readCompletionNotifier->setHandle(readCompletionOverlapped.hEvent);
- q->connect(readCompletionNotifier, SIGNAL(activated(HANDLE)), q, SLOT(_q_completeAsyncRead()));
- }
-
- ::ZeroMemory(&writeCompletionOverlapped, sizeof(writeCompletionOverlapped));
- writeCompletionOverlapped.hEvent = ::CreateEvent(NULL, FALSE, FALSE, NULL);
- if (!writeCompletionOverlapped.hEvent) {
- q->setError(decodeSystemError());
- } else {
- writeCompletionNotifier->setHandle(writeCompletionOverlapped.hEvent);
- q->connect(writeCompletionNotifier, SIGNAL(activated(HANDLE)), q, SLOT(_q_completeAsyncWrite()));
- }
-#endif
}
int QSerialPortPrivate::timeoutValue(int msecs, int elapsed)
diff --git a/src/serialport/qserialport_p.h b/src/serialport/qserialport_p.h
index e39ba2b..f0d6fff 100644
--- a/src/serialport/qserialport_p.h
+++ b/src/serialport/qserialport_p.h
@@ -55,7 +55,6 @@
# include <QtCore/qmutex.h>
# include <qt_windows.h>
#elif defined (Q_OS_WIN32)
-# include <QtCore/qwineventnotifier.h>
# include <qt_windows.h>
#elif defined (Q_OS_UNIX)
# include <QtCore/qlockfile.h>
@@ -204,7 +203,7 @@ public:
#elif defined (Q_OS_WIN32)
- bool initialize(QIODevice::OpenMode mode);
+ bool initialize();
bool updateDcb();
bool updateCommTimeouts();
qint64 handleOverlappedResult(int direction, OVERLAPPED &overlapped);
@@ -222,6 +221,10 @@ public:
bool emulateErrorPolicy();
void emitReadyRead();
+ bool setCommunicationNotificationEnabled(bool enable);
+ bool setReadNotificationEnabled(bool enable);
+ bool setWriteNotificationEnabled(bool enable);
+
DCB currentDcb;
DCB restoredDcb;
COMMTIMEOUTS currentCommTimeouts;
diff --git a/src/serialport/qserialport_win.cpp b/src/serialport/qserialport_win.cpp
index c965c3e..567d1a2 100644
--- a/src/serialport/qserialport_win.cpp
+++ b/src/serialport/qserialport_win.cpp
@@ -105,7 +105,7 @@ bool QSerialPortPrivate::open(QIODevice::OpenMode mode)
return false;
}
- if (initialize(mode))
+ if (initialize())
return true;
::CloseHandle(handle);
@@ -119,9 +119,9 @@ void QSerialPortPrivate::close()
if (!::CancelIo(handle))
q->setError(decodeSystemError());
- readCompletionNotifier->setEnabled(false);
- writeCompletionNotifier->setEnabled(false);
- communicationNotifier->setEnabled(false);
+ setReadNotificationEnabled(false);
+ setWriteNotificationEnabled(false);
+ setCommunicationNotificationEnabled(false);
readStarted = false;
readBuffer.clear();
@@ -527,6 +527,9 @@ bool QSerialPortPrivate::startAsyncCommunication()
{
Q_Q(QSerialPort);
+ if (!setCommunicationNotificationEnabled(true))
+ return false;
+
initializeOverlappedStructure(communicationOverlapped);
if (!::WaitCommEvent(handle, &triggeredEventMask, &communicationOverlapped)) {
QSerialPort::SerialPortError error = decodeSystemError();
@@ -558,6 +561,9 @@ bool QSerialPortPrivate::startAsyncRead()
}
}
+ if (!setReadNotificationEnabled(true))
+ return false;
+
initializeOverlappedStructure(readCompletionOverlapped);
if (::ReadFile(handle, readChunkBuffer.data(), bytesToRead, NULL, &readCompletionOverlapped)) {
readStarted = true;
@@ -585,6 +591,9 @@ bool QSerialPortPrivate::_q_startAsyncWrite()
if (writeBuffer.isEmpty() || writeStarted)
return true;
+ if (!setWriteNotificationEnabled(true))
+ return false;
+
initializeOverlappedStructure(writeCompletionOverlapped);
const int writeBytes = writeBuffer.nextDataBlockSize();
@@ -687,7 +696,7 @@ void QSerialPortPrivate::handleLineStatusErrors()
}
}
-inline bool QSerialPortPrivate::initialize(QIODevice::OpenMode mode)
+inline bool QSerialPortPrivate::initialize()
{
Q_Q(QSerialPort);
@@ -724,12 +733,6 @@ inline bool QSerialPortPrivate::initialize(QIODevice::OpenMode mode)
if (!updateCommTimeouts())
return false;
- if (mode & QIODevice::ReadOnly)
- readCompletionNotifier->setEnabled(true);
-
- if (mode & QIODevice::WriteOnly)
- writeCompletionNotifier->setEnabled(true);
-
if (!::SetCommMask(handle, originalEventMask)) {
q->setError(decodeSystemError());
return false;
@@ -738,8 +741,6 @@ inline bool QSerialPortPrivate::initialize(QIODevice::OpenMode mode)
if (!startAsyncCommunication())
return false;
- communicationNotifier->setEnabled(true);
-
return true;
}
@@ -856,6 +857,72 @@ bool QSerialPortPrivate::waitAnyEvent(int msecs, bool *timedOut, HANDLE *trigger
return true;
}
+bool QSerialPortPrivate::setCommunicationNotificationEnabled(bool enable)
+{
+ Q_Q(QSerialPort);
+
+ if (communicationNotifier) {
+ communicationNotifier->setEnabled(enable);
+ } else if (enable) {
+ communicationOverlapped.hEvent = ::CreateEvent(NULL, FALSE, FALSE, NULL);
+ if (!communicationOverlapped.hEvent) {
+ q->setError(decodeSystemError());
+ return false;
+ }
+ communicationNotifier = new QWinEventNotifier(q);
+ q->connect(communicationNotifier, SIGNAL(activated(HANDLE)),
+ q, SLOT(_q_completeAsyncCommunication()));
+ communicationNotifier->setHandle(communicationOverlapped.hEvent);
+ communicationNotifier->setEnabled(true);
+ }
+
+ return true;
+}
+
+bool QSerialPortPrivate::setReadNotificationEnabled(bool enable)
+{
+ Q_Q(QSerialPort);
+
+ if (readCompletionNotifier) {
+ readCompletionNotifier->setEnabled(enable);
+ } else if (enable) {
+ readCompletionOverlapped.hEvent = ::CreateEvent(NULL, FALSE, FALSE, NULL);
+ if (!readCompletionOverlapped.hEvent) {
+ q->setError(decodeSystemError());
+ return false;
+ }
+ readCompletionNotifier = new QWinEventNotifier(q);
+ q->connect(readCompletionNotifier, SIGNAL(activated(HANDLE)),
+ q, SLOT(_q_completeAsyncRead()));
+ readCompletionNotifier->setHandle(readCompletionOverlapped.hEvent);
+ readCompletionNotifier->setEnabled(true);
+ }
+
+ return true;
+}
+
+bool QSerialPortPrivate::setWriteNotificationEnabled(bool enable)
+{
+ Q_Q(QSerialPort);
+
+ if (writeCompletionNotifier) {
+ writeCompletionNotifier->setEnabled(enable);
+ } else if (enable) {
+ writeCompletionOverlapped.hEvent = ::CreateEvent(NULL, FALSE, FALSE, NULL);
+ if (!writeCompletionOverlapped.hEvent) {
+ q->setError(decodeSystemError());
+ return false;
+ }
+ writeCompletionNotifier = new QWinEventNotifier(q);
+ q->connect(writeCompletionNotifier, SIGNAL(activated(HANDLE)),
+ q, SLOT(_q_completeAsyncWrite()));
+ writeCompletionNotifier->setHandle(writeCompletionOverlapped.hEvent);
+ writeCompletionNotifier->setEnabled(true);
+ }
+
+ return true;
+}
+
static const QString defaultPathPrefix = QStringLiteral("\\\\.\\");
QString QSerialPortPrivate::portNameToSystemLocation(const QString &port)