diff options
author | Denis Shienkov <denis.shienkov@gmail.com> | 2014-06-30 18:38:04 +0400 |
---|---|---|
committer | Denis Shienkov <denis.shienkov@gmail.com> | 2014-07-08 12:04:56 +0200 |
commit | a55dbce3d1a5f75647d5325f94af9d76a41cdede (patch) | |
tree | 4605fb226b87eafe0179a148a65bdbe0a90b419c | |
parent | f4986a7716ce58749f6c61524fc01a20a51c8214 (diff) | |
download | qtserialport-a55dbce3d1a5f75647d5325f94af9d76a41cdede.tar.gz |
Improve error handling for the waitForXX() methods on Windows
The slots _q_completeXX() returns empty values, therefore the
waitForXX() methods continue to work even if occurs an error
from the I/O completion.
Is reasonable allow to return of boolean values for the I/O
completion slots.
Besides, it allows avoiding indirect detection of an error,
comparing of the sizes of I/O buffers before and after the
operation completion. Though, for the waitForReadyRead(),
for this purpose it is necessary to add additional
modifications in a following patches.
Tested on Windows 7/8 with the virtual com0com ports using
Qt4 and then Qt5. Testing was made using of autotests
and examples.
Change-Id: I95a76461af4595f6658f0cad766a4fff14eb7afc
Reviewed-by: Peter Kümmel <syntheticpp@gmx.net>
Reviewed-by: Denis Shienkov <denis.shienkov@gmail.com>
-rw-r--r-- | src/serialport/qserialport.h | 6 | ||||
-rw-r--r-- | src/serialport/qserialport_win.cpp | 44 | ||||
-rw-r--r-- | src/serialport/qserialport_win_p.h | 6 |
3 files changed, 29 insertions, 27 deletions
diff --git a/src/serialport/qserialport.h b/src/serialport/qserialport.h index ae5eaf3..45b9bbf 100644 --- a/src/serialport/qserialport.h +++ b/src/serialport/qserialport.h @@ -282,9 +282,9 @@ private: Q_DISABLE_COPY(QSerialPort) #if defined (Q_OS_WIN32) || defined(Q_OS_WIN64) - Q_PRIVATE_SLOT(d_func(), void _q_completeAsyncCommunication()) - Q_PRIVATE_SLOT(d_func(), void _q_completeAsyncRead()) - Q_PRIVATE_SLOT(d_func(), void _q_completeAsyncWrite()) + Q_PRIVATE_SLOT(d_func(), bool _q_completeAsyncCommunication()) + Q_PRIVATE_SLOT(d_func(), bool _q_completeAsyncRead()) + Q_PRIVATE_SLOT(d_func(), bool _q_completeAsyncWrite()) #endif }; diff --git a/src/serialport/qserialport_win.cpp b/src/serialport/qserialport_win.cpp index c76edb9..3432fc9 100644 --- a/src/serialport/qserialport_win.cpp +++ b/src/serialport/qserialport_win.cpp @@ -400,9 +400,11 @@ bool QSerialPortPrivate::waitForReadyRead(int msecs) } if (triggeredEvent == communicationOverlapped.hEvent) { - _q_completeAsyncCommunication(); + if (!_q_completeAsyncCommunication()) + return false; } else if (triggeredEvent == readCompletionOverlapped.hEvent) { - _q_completeAsyncRead(); + if (!_q_completeAsyncRead()) + return false; const qint64 readBytesForOneReadOperation = qint64(readBuffer.size()) - currentReadBufferSize; if (readBytesForOneReadOperation == ReadChunkSize) { currentReadBufferSize = readBuffer.size(); @@ -413,7 +415,8 @@ bool QSerialPortPrivate::waitForReadyRead(int msecs) return true; } } else if (triggeredEvent == writeCompletionOverlapped.hEvent) { - _q_completeAsyncWrite(); + if (!_q_completeAsyncWrite()) + return false; } else { return false; } @@ -433,8 +436,8 @@ bool QSerialPortPrivate::waitForBytesWritten(int msecs) QElapsedTimer stopWatch; stopWatch.start(); - if (!writeStarted) - startAsyncWrite(); + if (!writeStarted && !startAsyncWrite()) + return false; forever { bool timedOut = false; @@ -446,13 +449,12 @@ bool QSerialPortPrivate::waitForBytesWritten(int msecs) return false; } - if (triggeredEvent == communicationOverlapped.hEvent) { - _q_completeAsyncRead(); - } else if (triggeredEvent == readCompletionOverlapped.hEvent) { - _q_completeAsyncRead(); + if (triggeredEvent == communicationOverlapped.hEvent + || triggeredEvent == readCompletionOverlapped.hEvent) { + if (!_q_completeAsyncRead()) + return false; } else if (triggeredEvent == writeCompletionOverlapped.hEvent) { - _q_completeAsyncWrite(); - return writeBuffer.isEmpty(); + return _q_completeAsyncWrite(); } else { return false; } @@ -561,21 +563,21 @@ bool QSerialPortPrivate::setDataErrorPolicy(QSerialPort::DataErrorPolicy policy) return true; } -void QSerialPortPrivate::_q_completeAsyncCommunication() +bool QSerialPortPrivate::_q_completeAsyncCommunication() { if (handleOverlappedResult(0, communicationOverlapped) == qint64(-1)) - return; + return false; if (EV_ERR & triggeredEventMask) handleLineStatusErrors(); - startAsyncRead(); + return startAsyncRead(); } -void QSerialPortPrivate::_q_completeAsyncRead() +bool QSerialPortPrivate::_q_completeAsyncRead() { const qint64 bytesTransferred = handleOverlappedResult(QSerialPort::Input, readCompletionOverlapped); if (bytesTransferred == qint64(-1)) - return; + return false; if (bytesTransferred > 0) { readBuffer.append(readChunkBuffer.left(bytesTransferred)); if (!emulateErrorPolicy()) @@ -584,12 +586,12 @@ void QSerialPortPrivate::_q_completeAsyncRead() // start async read for possible remainder into driver queue if ((bytesTransferred == ReadChunkSize) && (policy == QSerialPort::IgnorePolicy)) - startAsyncRead(); + return startAsyncRead(); else // driver queue is emplty, so startup wait comm event - startAsyncCommunication(); + return startAsyncCommunication(); } -void QSerialPortPrivate::_q_completeAsyncWrite() +bool QSerialPortPrivate::_q_completeAsyncWrite() { Q_Q(QSerialPort); @@ -597,14 +599,14 @@ void QSerialPortPrivate::_q_completeAsyncWrite() writeStarted = false; const qint64 bytesTransferred = handleOverlappedResult(QSerialPort::Output, writeCompletionOverlapped); if (bytesTransferred == qint64(-1)) - return; + return false; if (bytesTransferred > 0) { writeBuffer.free(bytesTransferred); emit q->bytesWritten(bytesTransferred); } } - startAsyncWrite(); + return startAsyncWrite(); } bool QSerialPortPrivate::startAsyncCommunication() diff --git a/src/serialport/qserialport_win_p.h b/src/serialport/qserialport_win_p.h index 9981973..daf5788 100644 --- a/src/serialport/qserialport_win_p.h +++ b/src/serialport/qserialport_win_p.h @@ -91,9 +91,9 @@ public: void handleLineStatusErrors(); QSerialPort::SerialPortError decodeSystemError() const; - void _q_completeAsyncCommunication(); - void _q_completeAsyncRead(); - void _q_completeAsyncWrite(); + bool _q_completeAsyncCommunication(); + bool _q_completeAsyncRead(); + bool _q_completeAsyncWrite(); bool startAsyncCommunication(); bool startAsyncRead(); |