summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDenis Shienkov <denis.shienkov@gmail.com>2014-06-30 18:38:04 +0400
committerDenis Shienkov <denis.shienkov@gmail.com>2014-07-08 12:04:56 +0200
commita55dbce3d1a5f75647d5325f94af9d76a41cdede (patch)
tree4605fb226b87eafe0179a148a65bdbe0a90b419c
parentf4986a7716ce58749f6c61524fc01a20a51c8214 (diff)
downloadqtserialport-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.h6
-rw-r--r--src/serialport/qserialport_win.cpp44
-rw-r--r--src/serialport/qserialport_win_p.h6
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();