diff options
author | Denis Shienkov <denis.shienkov@gmail.com> | 2013-12-25 17:52:51 +0400 |
---|---|---|
committer | The Qt Project <gerrit-noreply@qt-project.org> | 2014-01-15 10:07:28 +0100 |
commit | f404826e695c3affb684f3185d74cd3a5b31efbc (patch) | |
tree | 9c795ec28a93c2854b16733bc637d91b76f72c93 | |
parent | d5658bd0ced4a1eb0703d3cb1b566025d610fbdd (diff) |
Unify of the internal API of asynchronous handling
It makes sense to unify internal methods of asynchronous I/O where to each
method of start of operation corresponds the method of completion of
operation:
* startAsyncCommunication() - it is a new method which has a code relating
to the handling of the WaitCommEvent() function. It implementations is taken
directly by copy/paste with minimal modifications relating with adding of
returns a boolean values.
* _q_completeAsyncCommunication() - it is an existing method which is renamed
from the _q_canCompleteCommunication().
* startAsyncRead() - it is an existing method without modifications.
* _q_completeAsyncRead() - it is an existing method which is renamed from
the _q_canCompleteRead(). Earlier this method contained a subfunction of
the completeAsyncRead(DWORD) which is deleted now, and its code (related with
the policy processing) is moved into body of the _q_completeAsyncRead() with
the minimum modifications which do not change it behavior.
* startAsyncWrite() - it is an existing method without modifications.
* _q_completeAsyncWrite() - it is an existing method which is renamed from
the _q_canCompleteWrite(). Earlier this method contained a subfunction of
the completeAsyncWrite(DWORD) which is deleted now, and its code is moved
into body of the _q_completeAsyncWrite() without modifications.
Also in addition is added the new method emitReadyRead() and the code of
policy emulation is moved into new method emulateErrorPolicy().
Change-Id: I58345e3270d676879a16efc4b7f35f74869894d8
Reviewed-by: Sergey Belyashov <Sergey.Belyashov@gmail.com>
Reviewed-by: Denis Shienkov <denis.shienkov@gmail.com>
-rw-r--r-- | src/serialport/qserialport.h | 6 | ||||
-rw-r--r-- | src/serialport/qserialport_win.cpp | 171 | ||||
-rw-r--r-- | src/serialport/qserialport_win_p.h | 12 |
3 files changed, 94 insertions, 95 deletions
diff --git a/src/serialport/qserialport.h b/src/serialport/qserialport.h index c07af91b..1689222b 100644 --- a/src/serialport/qserialport.h +++ b/src/serialport/qserialport.h @@ -276,9 +276,9 @@ private: Q_DISABLE_COPY(QSerialPort) #if defined (Q_OS_WIN32) || defined(Q_OS_WIN64) - Q_PRIVATE_SLOT(d_func(), void _q_canCompleteCommunication()) - Q_PRIVATE_SLOT(d_func(), void _q_canCompleteRead()) - Q_PRIVATE_SLOT(d_func(), void _q_canCompleteWrite()) + Q_PRIVATE_SLOT(d_func(), void _q_completeAsyncCommunication()) + Q_PRIVATE_SLOT(d_func(), void _q_completeAsyncRead()) + Q_PRIVATE_SLOT(d_func(), void _q_completeAsyncWrite()) #endif }; diff --git a/src/serialport/qserialport_win.cpp b/src/serialport/qserialport_win.cpp index e460c785..ecbfa393 100644 --- a/src/serialport/qserialport_win.cpp +++ b/src/serialport/qserialport_win.cpp @@ -115,7 +115,7 @@ QSerialPortPrivate::QSerialPortPrivate(QSerialPort *q) q->setError(decodeSystemError()); else { communicationNotifier->setHandle(communicationOverlapped.hEvent); - q->connect(communicationNotifier, SIGNAL(activated(HANDLE)), q, SLOT(_q_canCompleteCommunication())); + q->connect(communicationNotifier, SIGNAL(activated(HANDLE)), q, SLOT(_q_completeAsyncCommunication())); } ::ZeroMemory(&readCompletionOverlapped, sizeof(readCompletionOverlapped)); @@ -124,7 +124,7 @@ QSerialPortPrivate::QSerialPortPrivate(QSerialPort *q) q->setError(decodeSystemError()); else { readCompletionNotifier->setHandle(readCompletionOverlapped.hEvent); - q->connect(readCompletionNotifier, SIGNAL(activated(HANDLE)), q, SLOT(_q_canCompleteRead())); + q->connect(readCompletionNotifier, SIGNAL(activated(HANDLE)), q, SLOT(_q_completeAsyncRead())); } ::ZeroMemory(&writeCompletionOverlapped, sizeof(writeCompletionOverlapped)); @@ -133,7 +133,7 @@ QSerialPortPrivate::QSerialPortPrivate(QSerialPort *q) q->setError(decodeSystemError()); else { writeCompletionNotifier->setHandle(writeCompletionOverlapped.hEvent); - q->connect(writeCompletionNotifier, SIGNAL(activated(HANDLE)), q, SLOT(_q_canCompleteWrite())); + q->connect(writeCompletionNotifier, SIGNAL(activated(HANDLE)), q, SLOT(_q_completeAsyncWrite())); } } @@ -197,14 +197,8 @@ bool QSerialPortPrivate::open(QIODevice::OpenMode mode) return false; } - initializeOverlappedStructure(communicationOverlapped); - if (!::WaitCommEvent(descriptor, &triggeredEventMask, &communicationOverlapped)) { - const QSerialPort::SerialPortError error = decodeSystemError(); - if (error != QSerialPort::NoError) { - q->setError(decodeSystemError()); - return false; - } - } + if (!startAsyncCommunication()) + return false; communicationNotifier->setEnabled(true); @@ -393,14 +387,14 @@ bool QSerialPortPrivate::waitForReadyRead(int msecs) } if (triggeredEvent == communicationOverlapped.hEvent) { - _q_canCompleteCommunication(); + _q_completeAsyncCommunication(); if (error != QSerialPort::NoError) return false; } else if (triggeredEvent == readCompletionOverlapped.hEvent) { - _q_canCompleteRead(); + _q_completeAsyncRead(); return error == QSerialPort::NoError; } else if (triggeredEvent == writeCompletionOverlapped.hEvent) { - _q_canCompleteWrite(); + _q_completeAsyncWrite(); } else { return false; } @@ -431,11 +425,11 @@ bool QSerialPortPrivate::waitForBytesWritten(int msecs) } if (triggeredEvent == communicationOverlapped.hEvent) { - _q_canCompleteRead(); + _q_completeAsyncRead(); } else if (triggeredEvent == readCompletionOverlapped.hEvent) { - _q_canCompleteRead(); + _q_completeAsyncRead(); } else if (triggeredEvent == writeCompletionOverlapped.hEvent) { - _q_canCompleteWrite(); + _q_completeAsyncWrite(); return error == QSerialPort::NoError; } else { return false; @@ -544,7 +538,7 @@ bool QSerialPortPrivate::setDataErrorPolicy(QSerialPort::DataErrorPolicy policy) #ifndef Q_OS_WINCE -void QSerialPortPrivate::_q_canCompleteCommunication() +void QSerialPortPrivate::_q_completeAsyncCommunication() { Q_Q(QSerialPort); @@ -576,7 +570,7 @@ void QSerialPortPrivate::_q_canCompleteCommunication() startAsyncRead(); } -void QSerialPortPrivate::_q_canCompleteRead() +void QSerialPortPrivate::_q_completeAsyncRead() { Q_Q(QSerialPort); @@ -584,23 +578,22 @@ void QSerialPortPrivate::_q_canCompleteRead() if (!::GetOverlappedResult(descriptor, &readCompletionOverlapped, &numberOfBytesTransferred, FALSE)) q->setError(decodeSystemError()); - completeAsyncRead(numberOfBytesTransferred); + if (numberOfBytesTransferred > 0) { + + readBuffer.append(readChunkBuffer.left(numberOfBytesTransferred)); + + if (!emulateErrorPolicy()) + emitReadyRead(); + } // start async read for possible remainder into driver queue - if ((numberOfBytesTransferred > 0) && (policy == QSerialPort::IgnorePolicy)) { + if ((numberOfBytesTransferred > 0) && (policy == QSerialPort::IgnorePolicy)) startAsyncRead(); - } else { // driver queue is emplty, so startup wait comm event - initializeOverlappedStructure(communicationOverlapped); - if (!::WaitCommEvent(descriptor, &triggeredEventMask, &communicationOverlapped)) { - const QSerialPort::SerialPortError error = decodeSystemError(); - if (error != QSerialPort::NoError) { - q->setError(decodeSystemError()); - } - } - } + else // driver queue is emplty, so startup wait comm event + startAsyncCommunication(); } -void QSerialPortPrivate::_q_canCompleteWrite() +void QSerialPortPrivate::_q_completeAsyncWrite() { Q_Q(QSerialPort); @@ -610,7 +603,30 @@ void QSerialPortPrivate::_q_canCompleteWrite() q->setError(decodeSystemError()); } - completeAsyncWrite(numberOfBytesTransferred); + writeBuffer.free(numberOfBytesTransferred); + + if (numberOfBytesTransferred > 0) + emit q->bytesWritten(numberOfBytesTransferred); + + if (writeBuffer.isEmpty()) + writeSequenceStarted = false; + else + startAsyncWrite(); +} + +bool QSerialPortPrivate::startAsyncCommunication() +{ + Q_Q(QSerialPort); + + initializeOverlappedStructure(communicationOverlapped); + if (!::WaitCommEvent(descriptor, &triggeredEventMask, &communicationOverlapped)) { + const QSerialPort::SerialPortError error = decodeSystemError(); + if (error != QSerialPort::NoError) { + q->setError(decodeSystemError()); + return false; + } + } + return true; } bool QSerialPortPrivate::startAsyncRead() @@ -675,6 +691,42 @@ bool QSerialPortPrivate::startAsyncWrite() return true; } +bool QSerialPortPrivate::emulateErrorPolicy() +{ + if (!parityErrorOccurred) + return false; + + parityErrorOccurred = false; + + switch (policy) { + case QSerialPort::SkipPolicy: + readBuffer.getChar(); + break; + case QSerialPort::PassZeroPolicy: + readBuffer.getChar(); + readBuffer.putChar('\0'); + emitReadyRead(); + break; + case QSerialPort::IgnorePolicy: + return false; + case QSerialPort::StopReceivingPolicy: + emitReadyRead(); + break; + default: + return false; + } + + return true; +} + +void QSerialPortPrivate::emitReadyRead() +{ + Q_Q(QSerialPort); + + readyReadEmitted = true; + emit q->readyRead(); +} + #endif // #ifndef Q_OS_WINCE void QSerialPortPrivate::processIoErrors(bool error) @@ -706,61 +758,6 @@ void QSerialPortPrivate::processIoErrors(bool error) #ifndef Q_OS_WINCE -void QSerialPortPrivate::completeAsyncRead(DWORD numberOfBytes) -{ - Q_Q(QSerialPort); - - if (numberOfBytes > 0) { - - readBuffer.append(readChunkBuffer.left(numberOfBytes)); - - // Process emulate policy. - if ((policy != QSerialPort::IgnorePolicy) && parityErrorOccurred) { - - parityErrorOccurred = false; - - // Ignore received character, remove it from buffer - if (policy == QSerialPort::SkipPolicy) { - readBuffer.getChar(); - // Force returning without emitting a readyRead() signal - return; - } - - // Abort receiving - if (policy == QSerialPort::StopReceivingPolicy) { - readyReadEmitted = true; - emit q->readyRead(); - return; - } - - // Replace received character by zero - if (policy == QSerialPort::PassZeroPolicy) { - readBuffer.getChar(); - readBuffer.putChar('\0'); - } - - } - - readyReadEmitted = true; - emit q->readyRead(); - } -} - -void QSerialPortPrivate::completeAsyncWrite(DWORD numberOfBytes) -{ - Q_Q(QSerialPort); - - writeBuffer.free(numberOfBytes); - - if (numberOfBytes > 0) - emit q->bytesWritten(numberOfBytes); - - if (writeBuffer.isEmpty()) - writeSequenceStarted = false; - else - startAsyncWrite(); -} - bool QSerialPortPrivate::updateDcb() { Q_Q(QSerialPort); diff --git a/src/serialport/qserialport_win_p.h b/src/serialport/qserialport_win_p.h index 61e6ce80..9876fe4b 100644 --- a/src/serialport/qserialport_win_p.h +++ b/src/serialport/qserialport_win_p.h @@ -96,14 +96,16 @@ public: void processIoErrors(bool error); QSerialPort::SerialPortError decodeSystemError() const; #ifndef Q_OS_WINCE - void _q_canCompleteCommunication(); - void _q_canCompleteRead(); - void _q_canCompleteWrite(); + void _q_completeAsyncCommunication(); + void _q_completeAsyncRead(); + void _q_completeAsyncWrite(); + bool startAsyncCommunication(); bool startAsyncRead(); bool startAsyncWrite(); - void completeAsyncRead(DWORD numberOfBytes); - void completeAsyncWrite(DWORD numberOfBytes); + + bool emulateErrorPolicy(); + void emitReadyRead(); #else bool notifyRead(); bool notifyWrite(); |