diff options
author | Denis Shienkov <denis.shienkov@gmail.com> | 2016-04-22 18:47:41 +0300 |
---|---|---|
committer | Denis Shienkov <denis.shienkov@gmail.com> | 2016-04-27 15:53:00 +0000 |
commit | 4679301c184b7964fd197cca5bf5b30fefaee386 (patch) | |
tree | 9aa9ea17547e5049f47e04506c10567efccdb354 /src | |
parent | 9a70ee2389d3302f6a4262325f8a76e4d867b478 (diff) | |
download | qtserialport-4679301c184b7964fd197cca5bf5b30fefaee386.tar.gz |
Fix reading of data remainder with CDC USB device on Windows
In some cases the WaitCommEvent function does not triggered,
even if the input driver's queue has an unread bytes. Most
likely this happens if a bytes has been arrived between calls
of ReadFile and WaitCommEvent. Thus, it can be avoided by means
of ClearCommError function which should be called in end of
ReadFile to require amount of bytes that has been arrived but
still are unread. If it returns more than zero, then we start
reading again, without calling of WaitCommEvent.
Task-number: QTBUG-48677
Change-Id: I054975971a7c1823f7de879669c3d97f31348ed8
Reviewed-by: Sergey Belyashov <Sergey.Belyashov@gmail.com>
Reviewed-by: Denis Shienkov <denis.shienkov@gmail.com>
Diffstat (limited to 'src')
-rw-r--r-- | src/serialport/qserialport_p.h | 2 | ||||
-rw-r--r-- | src/serialport/qserialport_win.cpp | 17 |
2 files changed, 17 insertions, 2 deletions
diff --git a/src/serialport/qserialport_p.h b/src/serialport/qserialport_p.h index 29c1d5a..81febed 100644 --- a/src/serialport/qserialport_p.h +++ b/src/serialport/qserialport_p.h @@ -206,6 +206,8 @@ public: bool getDcb(DCB *dcb); OVERLAPPED *waitForNotified(int msecs); + qint64 queuedBytesCount(QSerialPort::Direction direction) const; + bool completeAsyncCommunication(qint64 bytesTransferred); bool completeAsyncRead(qint64 bytesTransferred); bool completeAsyncWrite(qint64 bytesTransferred); diff --git a/src/serialport/qserialport_win.cpp b/src/serialport/qserialport_win.cpp index 6d5dac0..e356e4c 100644 --- a/src/serialport/qserialport_win.cpp +++ b/src/serialport/qserialport_win.cpp @@ -437,10 +437,13 @@ bool QSerialPortPrivate::completeAsyncRead(qint64 bytesTransferred) readStarted = false; bool result = true; - if (bytesTransferred == ReadChunkSize) + if (bytesTransferred == ReadChunkSize + || queuedBytesCount(QSerialPort::Input) > 0) { result = startAsyncRead(); - else if (readBufferMaxSize == 0 || readBufferMaxSize > buffer.size()) + } else if (readBufferMaxSize == 0 + || readBufferMaxSize > buffer.size()) { result = startAsyncCommunication(); + } if (bytesTransferred > 0) emitReadyRead(); @@ -598,6 +601,16 @@ OVERLAPPED *QSerialPortPrivate::waitForNotified(int msecs) return overlapped; } +qint64 QSerialPortPrivate::queuedBytesCount(QSerialPort::Direction direction) const +{ + COMSTAT comstat; + if (::ClearCommError(handle, Q_NULLPTR, &comstat) == 0) + return -1; + return (direction == QSerialPort::Input) + ? comstat.cbInQue + : ((direction == QSerialPort::Output) ? comstat.cbOutQue : -1); +} + inline bool QSerialPortPrivate::initialize() { Q_Q(QSerialPort); |