summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDenis Shienkov <denis.shienkov@gmail.com>2016-04-22 18:47:41 +0300
committerDenis Shienkov <denis.shienkov@gmail.com>2016-04-27 15:53:00 +0000
commit4679301c184b7964fd197cca5bf5b30fefaee386 (patch)
tree9aa9ea17547e5049f47e04506c10567efccdb354
parent9a70ee2389d3302f6a4262325f8a76e4d867b478 (diff)
downloadqtserialport-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>
-rw-r--r--src/serialport/qserialport_p.h2
-rw-r--r--src/serialport/qserialport_win.cpp17
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);