From ac0422e8c9e74f2275129e3c7c69ef64299f07a9 Mon Sep 17 00:00:00 2001 From: Denis Shienkov Date: Mon, 29 Sep 2014 18:44:36 +0400 Subject: Fix reading on Windows at limited read buffer size In case the read buffer has a limited size then are impossible to read remainder which is still can be in driver's queue, since no readyRead signal emmitted and reading are stalled. Problem is that Windows does not fire the EV_RXCHAR event in case a driver's queue has ready to read remainder; this event will be triggered only when a new data are received. The solution is to start of asynchronous read operation for reading of possible remainder from the queue after doing QSP::read() from the user. Besides is necessary to meet conditions: - do not start reading in case a reading already is started - do not start reading in case is not in limited buffer size - do not start reading in case is a previous reading returns a less data than read buffer size or are not in the hardware flow control mode Tested on Windows 8 with virtual com0com serial ports using Qt5 and then Qt4. Task-number: QTBUG-41295 Change-Id: I01797e6f8d6006751244144fead3616b1de1b811 Reviewed-by: Robert Kurjata Reviewed-by: Sergey Belyashov --- tests/auto/qserialport/tst_qserialport.cpp | 35 ++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) (limited to 'tests') diff --git a/tests/auto/qserialport/tst_qserialport.cpp b/tests/auto/qserialport/tst_qserialport.cpp index 2b8de92..0fdde48 100644 --- a/tests/auto/qserialport/tst_qserialport.cpp +++ b/tests/auto/qserialport/tst_qserialport.cpp @@ -115,6 +115,10 @@ private slots: void asynchronousWriteByTimer_data(); void asynchronousWriteByTimer(); +#ifdef Q_OS_WIN + void readBufferOverflow(); +#endif + protected slots: void handleBytesWrittenAndExitLoopSlot(qint64 bytesWritten); void handleBytesWrittenAndExitLoopSlot2(qint64 bytesWritten); @@ -667,5 +671,36 @@ void tst_QSerialPort::asynchronousWriteByTimer() QCOMPARE(receiverPort.readAll(), alphabetArray); } +#ifdef Q_OS_WIN +void tst_QSerialPort::readBufferOverflow() +{ + clearReceiver(); + + QSerialPort senderPort(m_senderPortName); + QVERIFY(senderPort.open(QSerialPort::WriteOnly)); + + QSerialPort receiverPort(m_receiverPortName); + QVERIFY(receiverPort.open(QSerialPort::ReadOnly)); + + const int readBufferSize = alphabetArray.size() / 2; + receiverPort.setReadBufferSize(readBufferSize); + QCOMPARE(receiverPort.readBufferSize(), qint64(readBufferSize)); + + QCOMPARE(senderPort.write(alphabetArray), qint64(alphabetArray.size())); + QVERIFY2(senderPort.waitForBytesWritten(100), "Waiting for bytes written failed"); + + QByteArray readData; + while (receiverPort.waitForReadyRead(100)) { + QVERIFY(receiverPort.bytesAvailable() > 0); + readData += receiverPort.readAll(); + } + + QCOMPARE(readData, alphabetArray); + + // No more bytes available + QVERIFY(receiverPort.bytesAvailable() == 0); +} +#endif + QTEST_MAIN(tst_QSerialPort) #include "tst_qserialport.moc" -- cgit v1.2.1