diff options
author | Denis Shienkov <denis.shienkov@gmail.com> | 2014-06-30 13:35:50 +0400 |
---|---|---|
committer | Denis Shienkov <denis.shienkov@gmail.com> | 2014-07-08 09:35:48 +0200 |
commit | f4986a7716ce58749f6c61524fc01a20a51c8214 (patch) | |
tree | f36414eda609ccd194108f5fb782b3dc685f525c | |
parent | d34fce4a5d12789ded107631e22cb6ef54d35eee (diff) | |
download | qtserialport-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.cpp | 81 | ||||
-rw-r--r-- | src/serialport/qserialport_win_p.h | 2 |
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); |