diff options
-rw-r--r-- | src/serialport/qserialport.cpp | 8 | ||||
-rw-r--r-- | src/serialport/qserialport_unix.cpp | 1 | ||||
-rw-r--r-- | tests/auto/qserialport/tst_qserialport.cpp | 45 |
3 files changed, 53 insertions, 1 deletions
diff --git a/src/serialport/qserialport.cpp b/src/serialport/qserialport.cpp index 690eb65..369be62 100644 --- a/src/serialport/qserialport.cpp +++ b/src/serialport/qserialport.cpp @@ -1409,7 +1409,7 @@ qint64 QSerialPort::readData(char *data, qint64 maxSize) Q_UNUSED(data); Q_UNUSED(maxSize); -#ifdef Q_OS_WIN32 +#if defined(Q_OS_WIN32) // We need try to start async reading to read a remainder from a driver's queue // in case we have a limited read buffer size. Because the read notification can // be stalled since Windows do not re-triggered an EV_RXCHAR event if a driver's @@ -1417,6 +1417,12 @@ qint64 QSerialPort::readData(char *data, qint64 maxSize) Q_D(QSerialPort); if (d->readBufferMaxSize || d->flowControl == QSerialPort::HardwareControl) d->startAsyncRead(); +#elif defined(Q_OS_UNIX) + // We need try to re-trigger the read notification to read a remainder from a + // driver's queue in case we have a limited read buffer size. + Q_D(QSerialPort); + if (d->readBufferMaxSize && !d->isReadNotificationEnabled()) + d->setReadNotificationEnabled(true); #endif // return 0 indicating there may be more data in the future diff --git a/src/serialport/qserialport_unix.cpp b/src/serialport/qserialport_unix.cpp index 4659a18..c243319 100644 --- a/src/serialport/qserialport_unix.cpp +++ b/src/serialport/qserialport_unix.cpp @@ -727,6 +727,7 @@ bool QSerialPortPrivate::readNotification() if (bytesToRead == 0) { // Buffer is full. User must read data from the buffer // before we can read more from the port. + setReadNotificationEnabled(false); return false; } } diff --git a/tests/auto/qserialport/tst_qserialport.cpp b/tests/auto/qserialport/tst_qserialport.cpp index d50afe9..3a62bfa 100644 --- a/tests/auto/qserialport/tst_qserialport.cpp +++ b/tests/auto/qserialport/tst_qserialport.cpp @@ -120,6 +120,8 @@ private slots: void asynchronousWriteByTimer_data(); void asynchronousWriteByTimer(); + void asyncReadWithLimitedReadBufferSize(); + void readBufferOverflow(); void readAfterInputClear(); void synchronousReadWriteAfterAsynchronousReadWrite(); @@ -808,6 +810,49 @@ void tst_QSerialPort::asynchronousWriteByTimer() QCOMPARE(receiverPort.readAll(), alphabetArray); } +class AsyncReader2 : public QObject +{ + Q_OBJECT +public: + explicit AsyncReader2(QSerialPort &port, const QByteArray &expectedData) + : serialPort(port), expectedData(expectedData) + { + connect(&serialPort, &QSerialPort::readyRead, this, &AsyncReader2::receive); + } + +private slots: + void receive() + { + receivedData.append(serialPort.readAll()); + if (receivedData == expectedData) + tst_QSerialPort::exitLoop(); + } + +private: + QSerialPort &serialPort; + const QByteArray expectedData; + QByteArray receivedData; +}; + +void tst_QSerialPort::asyncReadWithLimitedReadBufferSize() +{ + QSerialPort senderPort(m_senderPortName); + QVERIFY(senderPort.open(QSerialPort::WriteOnly)); + + QSerialPort receiverPort(m_receiverPortName); + QVERIFY(receiverPort.open(QSerialPort::ReadOnly)); + + receiverPort.setReadBufferSize(1); + QCOMPARE(receiverPort.readBufferSize(), qint64(1)); + + AsyncReader2 reader(receiverPort, alphabetArray); + + QCOMPARE(senderPort.write(alphabetArray), qint64(alphabetArray.size())); + + enterLoop(1); + QVERIFY2(!timeout(), "Timed out when waiting for the read or write."); +} + void tst_QSerialPort::readBufferOverflow() { QSerialPort senderPort(m_senderPortName); |