summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/serialport/qserialport.cpp2
-rw-r--r--src/serialport/qserialport_unix.cpp5
-rw-r--r--src/serialport/qserialport_unix_p.h1
-rw-r--r--src/serialport/qserialport_win.cpp35
-rw-r--r--src/serialport/qserialport_win_p.h2
-rw-r--r--src/serialport/qserialport_wince.cpp5
-rw-r--r--src/serialport/qserialport_wince_p.h1
7 files changed, 47 insertions, 4 deletions
diff --git a/src/serialport/qserialport.cpp b/src/serialport/qserialport.cpp
index ffc763e3..c815dd02 100644
--- a/src/serialport/qserialport.cpp
+++ b/src/serialport/qserialport.cpp
@@ -1343,7 +1343,7 @@ bool QSerialPort::setBreakEnabled(bool set)
qint64 QSerialPort::readData(char *data, qint64 maxSize)
{
Q_D(QSerialPort);
- return d->readBuffer.read(data, maxSize);
+ return d->readData(data, maxSize);
}
/*!
diff --git a/src/serialport/qserialport_unix.cpp b/src/serialport/qserialport_unix.cpp
index e80c0e89..b082275b 100644
--- a/src/serialport/qserialport_unix.cpp
+++ b/src/serialport/qserialport_unix.cpp
@@ -383,6 +383,11 @@ void QSerialPortPrivate::startWriting()
setWriteNotificationEnabled(true);
}
+qint64 QSerialPortPrivate::readData(char *data, qint64 maxSize)
+{
+ return readBuffer.read(data, maxSize);
+}
+
bool QSerialPortPrivate::waitForReadyRead(int msecs)
{
Q_Q(QSerialPort);
diff --git a/src/serialport/qserialport_unix_p.h b/src/serialport/qserialport_unix_p.h
index 1213c30a..408fdc50 100644
--- a/src/serialport/qserialport_unix_p.h
+++ b/src/serialport/qserialport_unix_p.h
@@ -120,6 +120,7 @@ public:
bool setBreakEnabled(bool set);
void startWriting();
+ qint64 readData(char *data, qint64 maxSize);
bool waitForReadyRead(int msecs);
bool waitForBytesWritten(int msecs);
diff --git a/src/serialport/qserialport_win.cpp b/src/serialport/qserialport_win.cpp
index 18cef1ea..3174db56 100644
--- a/src/serialport/qserialport_win.cpp
+++ b/src/serialport/qserialport_win.cpp
@@ -98,6 +98,7 @@ QSerialPortPrivate::QSerialPortPrivate(QSerialPort *q)
, readChunkBuffer(ReadChunkSize, 0)
, readyReadEmitted(0)
, writeStarted(false)
+ , readStarted(false)
, communicationNotifier(new QWinEventNotifier(q))
, readCompletionNotifier(new QWinEventNotifier(q))
, writeCompletionNotifier(new QWinEventNotifier(q))
@@ -173,6 +174,7 @@ void QSerialPortPrivate::close()
writeCompletionNotifier->setEnabled(false);
communicationNotifier->setEnabled(false);
+ readStarted = false;
readBuffer.clear();
writeStarted = false;
@@ -267,8 +269,10 @@ bool QSerialPortPrivate::clear(QSerialPort::Directions directions)
Q_Q(QSerialPort);
DWORD flags = 0;
- if (directions & QSerialPort::Input)
+ if (directions & QSerialPort::Input) {
flags |= PURGE_RXABORT | PURGE_RXCLEAR;
+ readStarted = false;
+ }
if (directions & QSerialPort::Output) {
flags |= PURGE_TXABORT | PURGE_TXCLEAR;
writeStarted = false;
@@ -320,6 +324,21 @@ void QSerialPortPrivate::startWriting()
}
}
+qint64 QSerialPortPrivate::readData(char *data, qint64 maxSize)
+{
+ const qint64 result = readBuffer.read(data, maxSize);
+ // 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
+ // buffer has a remainder of data ready to read until a new data will be received.
+ if (readBufferMaxSize
+ && result > 0
+ && (result == readBufferMaxSize || flowControl == QSerialPort::HardwareControl)) {
+ startAsyncRead();
+ }
+ return result;
+}
+
bool QSerialPortPrivate::waitForReadyRead(int msecs)
{
Q_Q(QSerialPort);
@@ -523,14 +542,18 @@ bool QSerialPortPrivate::_q_completeAsyncCommunication()
bool QSerialPortPrivate::_q_completeAsyncRead()
{
const qint64 bytesTransferred = handleOverlappedResult(QSerialPort::Input, readCompletionOverlapped);
- if (bytesTransferred == qint64(-1))
+ if (bytesTransferred == qint64(-1)) {
+ readStarted = false;
return false;
+ }
if (bytesTransferred > 0) {
readBuffer.append(readChunkBuffer.left(bytesTransferred));
if (!emulateErrorPolicy())
emitReadyRead();
}
+ readStarted = false;
+
// start async read for possible remainder into driver queue
if ((bytesTransferred == ReadChunkSize) && (policy == QSerialPort::IgnorePolicy))
return startAsyncRead();
@@ -578,6 +601,9 @@ bool QSerialPortPrivate::startAsyncRead()
{
Q_Q(QSerialPort);
+ if (readStarted)
+ return true;
+
DWORD bytesToRead = policy == QSerialPort::IgnorePolicy ? ReadChunkSize : 1;
if (readBufferMaxSize && bytesToRead > (readBufferMaxSize - readBuffer.size())) {
@@ -590,8 +616,10 @@ bool QSerialPortPrivate::startAsyncRead()
}
initializeOverlappedStructure(readCompletionOverlapped);
- if (::ReadFile(handle, readChunkBuffer.data(), bytesToRead, NULL, &readCompletionOverlapped))
+ if (::ReadFile(handle, readChunkBuffer.data(), bytesToRead, NULL, &readCompletionOverlapped)) {
+ readStarted = true;
return true;
+ }
QSerialPort::SerialPortError error = decodeSystemError();
if (error != QSerialPort::NoError) {
@@ -603,6 +631,7 @@ bool QSerialPortPrivate::startAsyncRead()
return false;
}
+ readStarted = true;
return true;
}
diff --git a/src/serialport/qserialport_win_p.h b/src/serialport/qserialport_win_p.h
index cf30c189..8db3a74d 100644
--- a/src/serialport/qserialport_win_p.h
+++ b/src/serialport/qserialport_win_p.h
@@ -87,6 +87,7 @@ public:
bool setBreakEnabled(bool set);
void startWriting();
+ qint64 readData(char *data, qint64 maxSize);
bool waitForReadyRead(int msec);
bool waitForBytesWritten(int msec);
@@ -130,6 +131,7 @@ public:
QByteArray readChunkBuffer;
bool readyReadEmitted;
bool writeStarted;
+ bool readStarted;
QWinEventNotifier *communicationNotifier;
QWinEventNotifier *readCompletionNotifier;
QWinEventNotifier *writeCompletionNotifier;
diff --git a/src/serialport/qserialport_wince.cpp b/src/serialport/qserialport_wince.cpp
index c06e748c..d6c58aab 100644
--- a/src/serialport/qserialport_wince.cpp
+++ b/src/serialport/qserialport_wince.cpp
@@ -351,6 +351,11 @@ void QSerialPortPrivate::startWriting()
notifyWrite();
}
+qint64 QSerialPortPrivate::readData(char *data, qint64 maxSize)
+{
+ return readBuffer.read(data, maxSize);
+}
+
bool QSerialPortPrivate::waitForReadyRead(int msec)
{
if (!readBuffer.isEmpty())
diff --git a/src/serialport/qserialport_wince_p.h b/src/serialport/qserialport_wince_p.h
index 91bba3c7..be08bc15 100644
--- a/src/serialport/qserialport_wince_p.h
+++ b/src/serialport/qserialport_wince_p.h
@@ -86,6 +86,7 @@ public:
bool setBreakEnabled(bool set);
void startWriting();
+ qint64 readData(char *data, qint64 maxSize);
bool waitForReadyRead(int msec);
bool waitForBytesWritten(int msec);