diff options
-rw-r--r-- | src/serialport/qserialport.cpp | 34 | ||||
-rw-r--r-- | src/serialport/qserialport_p.h | 7 | ||||
-rw-r--r-- | src/serialport/qserialport_win.cpp | 93 |
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) |