summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/serialport/qserialport_win.cpp14
-rw-r--r--tests/auto/qserialport/tst_qserialport.cpp104
2 files changed, 112 insertions, 6 deletions
diff --git a/src/serialport/qserialport_win.cpp b/src/serialport/qserialport_win.cpp
index b01d2d0e..57b70966 100644
--- a/src/serialport/qserialport_win.cpp
+++ b/src/serialport/qserialport_win.cpp
@@ -426,18 +426,20 @@ bool QSerialPortPrivate::completeAsyncRead(qint64 bytesTransferred)
if (bytesTransferred > 0) {
char *ptr = buffer.reserve(bytesTransferred);
::memcpy(ptr, readChunkBuffer.constData(), bytesTransferred);
- if (!emulateErrorPolicy())
- emitReadyRead();
}
readStarted = false;
+ bool result = true;
if ((bytesTransferred == ReadChunkSize) && (policy == QSerialPort::IgnorePolicy))
- return startAsyncRead();
+ result = startAsyncRead();
else if (readBufferMaxSize == 0 || readBufferMaxSize > buffer.size())
- return startAsyncCommunication();
- else
- return true;
+ result = startAsyncCommunication();
+
+ if ((bytesTransferred > 0) && !emulateErrorPolicy())
+ emitReadyRead();
+
+ return result;
}
bool QSerialPortPrivate::completeAsyncWrite(qint64 bytesTransferred)
diff --git a/tests/auto/qserialport/tst_qserialport.cpp b/tests/auto/qserialport/tst_qserialport.cpp
index 1a714b2f..54118afe 100644
--- a/tests/auto/qserialport/tst_qserialport.cpp
+++ b/tests/auto/qserialport/tst_qserialport.cpp
@@ -35,6 +35,8 @@
#include <QtSerialPort/QSerialPort>
#include <QtSerialPort/QSerialPortInfo>
+#include <QThread>
+
Q_DECLARE_METATYPE(QSerialPort::SerialPortError);
Q_DECLARE_METATYPE(QIODevice::OpenMode);
Q_DECLARE_METATYPE(QIODevice::OpenModeFlag);
@@ -105,6 +107,7 @@ private slots:
#ifdef Q_OS_WIN
void readBufferOverflow();
void readAfterInputClear();
+ void synchronousReadWriteAfterAsynchronousReadWrite();
#endif
void controlBreak();
@@ -739,6 +742,107 @@ void tst_QSerialPort::readAfterInputClear()
// No more bytes available
QVERIFY(receiverPort.bytesAvailable() == 0);
}
+
+class MasterTransactor : public QObject
+{
+ Q_OBJECT
+public:
+ explicit MasterTransactor(const QString &name)
+ : serialPort(name)
+ {
+ }
+
+public slots:
+ void open()
+ {
+ if (serialPort.open(QSerialPort::ReadWrite)) {
+ createAsynchronousConnection();
+ serialPort.write("A", 1);
+ }
+ }
+
+private slots:
+ void synchronousTransaction()
+ {
+ serialPort.write("B", 1);
+ if (serialPort.waitForBytesWritten(100)) {
+ if (serialPort.waitForReadyRead(100))
+ tst_QSerialPort::exitLoop();
+ }
+ }
+
+ void transaction()
+ {
+ deleteAsyncronousConnection();
+ synchronousTransaction();
+ }
+
+private:
+ void createAsynchronousConnection()
+ {
+ connect(&serialPort, &QSerialPort::readyRead, this, &MasterTransactor::transaction);
+ }
+
+ void deleteAsyncronousConnection()
+ {
+ serialPort.disconnect();
+ }
+
+ QSerialPort serialPort;
+};
+
+class SlaveTransactor : public QObject
+{
+ Q_OBJECT
+public:
+ explicit SlaveTransactor(const QString &name)
+ : serialPort(new QSerialPort(name, this))
+ {
+ connect(serialPort, &QSerialPort::readyRead, this, &SlaveTransactor::transaction);
+ }
+
+public slots:
+ void open()
+ {
+ if (serialPort->open(QSerialPort::ReadWrite))
+ emit ready();
+ }
+
+signals:
+ void ready();
+
+private slots:
+ void transaction()
+ {
+ serialPort->write("Z", 1);
+ }
+
+private:
+ QSerialPort *serialPort;
+};
+
+void tst_QSerialPort::synchronousReadWriteAfterAsynchronousReadWrite()
+{
+ MasterTransactor master(m_senderPortName);
+ SlaveTransactor *slave = new SlaveTransactor(m_receiverPortName);
+
+ QThread thread;
+ slave->moveToThread(&thread);
+ thread.start();
+
+ QObject::connect(&thread, &QThread::finished, slave, &SlaveTransactor::deleteLater);
+ QObject::connect(slave, &SlaveTransactor::ready, &master, &MasterTransactor::open);
+
+ QMetaObject::invokeMethod(slave, "open", Qt::QueuedConnection);
+
+ tst_QSerialPort::enterLoopMsecs(500);
+
+ thread.quit();
+ thread.wait();
+
+ QVERIFY2(!timeout(), "Timed out when testing of transactions.");
+}
+
#endif
class BreakReader : public QObject