From f4986a7716ce58749f6c61524fc01a20a51c8214 Mon Sep 17 00:00:00 2001 From: Denis Shienkov Date: Mon, 30 Jun 2014 13:35:50 +0400 Subject: Unify handling of errors of the overlapped I/O result MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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 Reviewed-by: Peter Kümmel Reviewed-by: Denis Shienkov --- src/serialport/qserialport_win.cpp | 81 +++++++++++++++++--------------------- 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); -- cgit v1.2.1