summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDenis Shienkov <denis.shienkov@gmail.com>2015-10-01 15:53:09 +0300
committerDenis Shienkov <denis.shienkov@gmail.com>2015-10-01 13:45:05 +0000
commitba204a95e6650a6992510530c1fa5a4dac2b5da8 (patch)
tree01082896bdaebabfdd42c0c67cb3d5ec6c9a1a94
parent2e7e58c7f225ee2237b27285c19a060a277e35fe (diff)
downloadqtserialport-ba204a95e6650a6992510530c1fa5a4dac2b5da8.tar.gz
Fix stalling of reading with the limited buffer size on *nix
When the read buffer with a limited size is used, the read notifier becomes disabled when the buffer completely is filled. The notifier should be enabled again when several bytes were read from the read buffer. (cherry-picked from 23c89518d1404a4db570fe41f3cc04451703e16f) Change-Id: I723253fb153a1144009579141fa0ce1aca93b648 Reviewed-by: Denis Shienkov <denis.shienkov@gmail.com>
-rw-r--r--src/serialport/qserialport_unix.cpp8
-rw-r--r--tests/auto/qserialport/tst_qserialport.cpp45
2 files changed, 52 insertions, 1 deletions
diff --git a/src/serialport/qserialport_unix.cpp b/src/serialport/qserialport_unix.cpp
index 7c18d08..df8e9cb 100644
--- a/src/serialport/qserialport_unix.cpp
+++ b/src/serialport/qserialport_unix.cpp
@@ -395,7 +395,12 @@ bool QSerialPortPrivate::setBreakEnabled(bool set)
qint64 QSerialPortPrivate::readData(char *data, qint64 maxSize)
{
- return readBuffer.read(data, maxSize);
+ const qint64 result = readBuffer.read(data, maxSize);
+ // 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.
+ if (d->readBufferMaxSize && result > 0 && !d->isReadNotificationEnabled())
+ d->setReadNotificationEnabled(true);
+ return result;
}
bool QSerialPortPrivate::waitForReadyRead(int msecs)
@@ -744,6 +749,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 74eec3d..134c7d7 100644
--- a/tests/auto/qserialport/tst_qserialport.cpp
+++ b/tests/auto/qserialport/tst_qserialport.cpp
@@ -129,6 +129,8 @@ private slots:
void asynchronousWriteByTimer_data();
void asynchronousWriteByTimer();
+ void asyncReadWithLimitedReadBufferSize();
+
void readBufferOverflow();
void readAfterInputClear();
void synchronousReadWriteAfterAsynchronousReadWrite();
@@ -807,6 +809,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, SIGNAL(readyRead()), this, SLOT(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);