summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDenis Shienkov <denis.shienkov@gmail.com>2014-06-30 13:35:50 +0400
committerDenis Shienkov <denis.shienkov@gmail.com>2014-07-08 09:35:48 +0200
commitf4986a7716ce58749f6c61524fc01a20a51c8214 (patch)
treef36414eda609ccd194108f5fb782b3dc685f525c
parentd34fce4a5d12789ded107631e22cb6ef54d35eee (diff)
downloadqtserialport-f4986a7716ce58749f6c61524fc01a20a51c8214.tar.gz
Unify handling of errors of the overlapped I/O result
Each q_completeXXX() slot does call of GetOverlappedResult() and differently interprets an error depending on the type of I/O operation (read, write or communication). It is more reasonable to make it in the separate method handleOverlappedResult() which returns the number of the transferred bytes or -1 in case of error. Besides, this method accepts the additional integer parameter which expresses type of overlapped operation using the existing QSerialPort::Direction enumeration. The type of the communication operation has not separate value, so is used zero value for it. Tested build on Windows 7/8 using Qt4 and then Qt5. Change-Id: I8482392d06279bc430656e50b1e4392c513885c6 Reviewed-by: Sergey Belyashov <Sergey.Belyashov@gmail.com> Reviewed-by: Peter Kümmel <syntheticpp@gmx.net> Reviewed-by: Denis Shienkov <denis.shienkov@gmail.com>
-rw-r--r--src/serialport/qserialport_win.cpp81
-rw-r--r--src/serialport/qserialport_win_p.h2
2 files changed, 37 insertions, 46 deletions
diff --git a/src/serialport/qserialport_win.cpp b/src/serialport/qserialport_win.cpp
index e9792be..c76edb9 100644
--- a/src/serialport/qserialport_win.cpp
+++ b/src/serialport/qserialport_win.cpp
@@ -563,18 +563,8 @@ bool QSerialPortPrivate::setDataErrorPolicy(QSerialPort::DataErrorPolicy policy)
void QSerialPortPrivate::_q_completeAsyncCommunication()
{
- Q_Q(QSerialPort);
-
- DWORD numberOfBytesTransferred = 0;
-
- if (!::GetOverlappedResult(handle, &communicationOverlapped, &numberOfBytesTransferred, FALSE)) {
- const QSerialPort::SerialPortError error = decodeSystemError();
- if (error != QSerialPort::NoError) {
- q->setError(error);
- return;
- }
- }
-
+ if (handleOverlappedResult(0, communicationOverlapped) == qint64(-1))
+ return;
if (EV_ERR & triggeredEventMask)
handleLineStatusErrors();
@@ -583,29 +573,17 @@ void QSerialPortPrivate::_q_completeAsyncCommunication()
void QSerialPortPrivate::_q_completeAsyncRead()
{
- Q_Q(QSerialPort);
-
- DWORD numberOfBytesTransferred = 0;
- if (!::GetOverlappedResult(handle, &readCompletionOverlapped, &numberOfBytesTransferred, FALSE)) {
- QSerialPort::SerialPortError error = decodeSystemError();
- if (error != QSerialPort::NoError) {
- if (error != QSerialPort::ResourceError)
- error = QSerialPort::ReadError;
- q->setError(error);
- return;
- }
- }
-
- if (numberOfBytesTransferred > 0) {
-
- readBuffer.append(readChunkBuffer.left(numberOfBytesTransferred));
-
+ const qint64 bytesTransferred = handleOverlappedResult(QSerialPort::Input, readCompletionOverlapped);
+ if (bytesTransferred == qint64(-1))
+ return;
+ if (bytesTransferred > 0) {
+ readBuffer.append(readChunkBuffer.left(bytesTransferred));
if (!emulateErrorPolicy())
emitReadyRead();
}
// start async read for possible remainder into driver queue
- if ((numberOfBytesTransferred == ReadChunkSize) && (policy == QSerialPort::IgnorePolicy))
+ if ((bytesTransferred == ReadChunkSize) && (policy == QSerialPort::IgnorePolicy))
startAsyncRead();
else // driver queue is emplty, so startup wait comm event
startAsyncCommunication();
@@ -617,21 +595,12 @@ void QSerialPortPrivate::_q_completeAsyncWrite()
if (writeStarted) {
writeStarted = false;
- DWORD numberOfBytesTransferred = 0;
- if (!::GetOverlappedResult(handle, &writeCompletionOverlapped, &numberOfBytesTransferred, FALSE)) {
- numberOfBytesTransferred = 0;
- QSerialPort::SerialPortError error = decodeSystemError();
- if (error != QSerialPort::NoError) {
- if (error != QSerialPort::ResourceError)
- error = QSerialPort::WriteError;
- q->setError(error);
- return;
- }
- }
-
- if (numberOfBytesTransferred > 0) {
- writeBuffer.free(numberOfBytesTransferred);
- emit q->bytesWritten(numberOfBytesTransferred);
+ const qint64 bytesTransferred = handleOverlappedResult(QSerialPort::Output, writeCompletionOverlapped);
+ if (bytesTransferred == qint64(-1))
+ return;
+ if (bytesTransferred > 0) {
+ writeBuffer.free(bytesTransferred);
+ emit q->bytesWritten(bytesTransferred);
}
}
@@ -792,6 +761,28 @@ bool QSerialPortPrivate::updateCommTimeouts()
return true;
}
+qint64 QSerialPortPrivate::handleOverlappedResult(int direction, OVERLAPPED &overlapped)
+{
+ Q_Q(QSerialPort);
+
+ DWORD bytesTransferred = 0;
+ if (!::GetOverlappedResult(handle, &overlapped, &bytesTransferred, FALSE)) {
+ const QSerialPort::SerialPortError error = decodeSystemError();
+ if (error == QSerialPort::NoError)
+ return qint64(0);
+ if (error != QSerialPort::ResourceError) {
+ if (direction == QSerialPort::Input)
+ q->setError(QSerialPort::ReadError);
+ else if (direction == QSerialPort::Output)
+ q->setError(QSerialPort::WriteError);
+ else
+ q->setError(error);
+ return qint64(-1);
+ }
+ }
+ return bytesTransferred;
+}
+
QSerialPort::SerialPortError QSerialPortPrivate::decodeSystemError() const
{
QSerialPort::SerialPortError error;
diff --git a/src/serialport/qserialport_win_p.h b/src/serialport/qserialport_win_p.h
index 4e66685..9981973 100644
--- a/src/serialport/qserialport_win_p.h
+++ b/src/serialport/qserialport_win_p.h
@@ -132,7 +132,7 @@ public:
private:
bool updateDcb();
bool updateCommTimeouts();
-
+ qint64 handleOverlappedResult(int direction, OVERLAPPED &overlapped);
bool waitAnyEvent(int msecs, bool *timedOut, HANDLE *triggeredEvent);