summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlex Trotsenko <[email protected]>2021-06-23 18:26:10 +0300
committerAlex Trotsenko <[email protected]>2021-07-06 17:52:58 +0300
commitb3fbfcd3738a0ff864439499390513b95ca671aa (patch)
treeac274d4652ea3415e9b0ef302c3c6bd146e15e4d
parent46d2ba1ea4d0e5f1a2ae1d1801e416e487ea45b4 (diff)
QLocalSocket: reimplement readLineData() function
The base implementation reads data using repeated calls to getChar(), which is quite slow. Change-Id: Ie46624df63791b2cdd3c8a28fe3327427d942505 Reviewed-by: Oswald Buddenhagen <[email protected]>
-rw-r--r--src/corelib/io/qwindowspipereader.cpp24
-rw-r--r--src/corelib/io/qwindowspipereader_p.h1
-rw-r--r--src/network/socket/qlocalsocket.cpp5
-rw-r--r--src/network/socket/qlocalsocket.h1
-rw-r--r--src/network/socket/qlocalsocket_tcp.cpp10
-rw-r--r--src/network/socket/qlocalsocket_unix.cpp10
-rw-r--r--src/network/socket/qlocalsocket_win.cpp34
7 files changed, 76 insertions, 9 deletions
diff --git a/src/corelib/io/qwindowspipereader.cpp b/src/corelib/io/qwindowspipereader.cpp
index 539902c2337..c3ac51df949 100644
--- a/src/corelib/io/qwindowspipereader.cpp
+++ b/src/corelib/io/qwindowspipereader.cpp
@@ -209,6 +209,30 @@ qint64 QWindowsPipeReader::read(char *data, qint64 maxlen)
}
/*!
+ Reads a line from the internal buffer, but no more than \c{maxlen}
+ characters. A terminating '\0' byte is always appended to \c{data},
+ so \c{maxlen} must be larger than 1.
+ */
+qint64 QWindowsPipeReader::readLine(char *data, qint64 maxlen)
+{
+ QMutexLocker locker(&mutex);
+ qint64 readSoFar = 0;
+
+ if (actualReadBufferSize > 0) {
+ readSoFar = readBuffer.readLine(data, qMin(actualReadBufferSize + 1, maxlen));
+ actualReadBufferSize -= readSoFar;
+ }
+
+ if (!pipeBroken) {
+ startAsyncReadHelper(&locker);
+ if (readSoFar == 0)
+ return -2; // signal EWOULDBLOCK
+ }
+
+ return readSoFar;
+}
+
+/*!
Returns \c true if a complete line of data can be read from the buffer.
*/
bool QWindowsPipeReader::canReadLine() const
diff --git a/src/corelib/io/qwindowspipereader_p.h b/src/corelib/io/qwindowspipereader_p.h
index 77c90645c6d..e2190d67d92 100644
--- a/src/corelib/io/qwindowspipereader_p.h
+++ b/src/corelib/io/qwindowspipereader_p.h
@@ -78,6 +78,7 @@ public:
bool isPipeClosed() const { return pipeBroken; }
qint64 bytesAvailable() const;
qint64 read(char *data, qint64 maxlen);
+ qint64 readLine(char *data, qint64 maxlen);
bool canReadLine() const;
DWORD checkPipeState();
bool checkForReadyRead() { return consumePendingAndEmit(false); }
diff --git a/src/network/socket/qlocalsocket.cpp b/src/network/socket/qlocalsocket.cpp
index 98c686de639..12b9f45a142 100644
--- a/src/network/socket/qlocalsocket.cpp
+++ b/src/network/socket/qlocalsocket.cpp
@@ -167,6 +167,11 @@ QT_BEGIN_NAMESPACE
*/
/*!
+ \fn qint64 QLocalSocket::readLineData(char *data, qint64 maxSize)
+ \reimp
+*/
+
+/*!
\fn qint64 QLocalSocket::skipData(qint64 maxSize)
\reimp
*/
diff --git a/src/network/socket/qlocalsocket.h b/src/network/socket/qlocalsocket.h
index 2a578dd10ba..c74c36e9a79 100644
--- a/src/network/socket/qlocalsocket.h
+++ b/src/network/socket/qlocalsocket.h
@@ -139,6 +139,7 @@ Q_SIGNALS:
protected:
virtual qint64 readData(char*, qint64) override;
+ qint64 readLineData(char *data, qint64 maxSize) override;
qint64 skipData(qint64 maxSize) override;
virtual qint64 writeData(const char*, qint64) override;
diff --git a/src/network/socket/qlocalsocket_tcp.cpp b/src/network/socket/qlocalsocket_tcp.cpp
index 2f0179f40a7..1b6aa16c9ba 100644
--- a/src/network/socket/qlocalsocket_tcp.cpp
+++ b/src/network/socket/qlocalsocket_tcp.cpp
@@ -301,6 +301,16 @@ qint64 QLocalSocket::readData(char *data, qint64 c)
return d->tcpSocket->read(data, c);
}
+qint64 QLocalSocket::readLineData(char *data, qint64 maxSize)
+{
+ if (!maxSize)
+ return 0;
+
+ // QIODevice::readLine() reserves space for the trailing '\0' byte,
+ // so we must read 'maxSize + 1' bytes.
+ return d_func()->tcpSocket->readLine(data, maxSize + 1);
+}
+
qint64 QLocalSocket::skipData(qint64 maxSize)
{
return d_func()->tcpSocket->skip(maxSize);
diff --git a/src/network/socket/qlocalsocket_unix.cpp b/src/network/socket/qlocalsocket_unix.cpp
index 5e050ad3230..4dc542f2e34 100644
--- a/src/network/socket/qlocalsocket_unix.cpp
+++ b/src/network/socket/qlocalsocket_unix.cpp
@@ -483,6 +483,16 @@ qint64 QLocalSocket::readData(char *data, qint64 c)
return d->unixSocket.read(data, c);
}
+qint64 QLocalSocket::readLineData(char *data, qint64 maxSize)
+{
+ if (!maxSize)
+ return 0;
+
+ // QIODevice::readLine() reserves space for the trailing '\0' byte,
+ // so we must read 'maxSize + 1' bytes.
+ return d_func()->unixSocket.readLine(data, maxSize + 1);
+}
+
qint64 QLocalSocket::skipData(qint64 maxSize)
{
return d_func()->unixSocket.skip(maxSize);
diff --git a/src/network/socket/qlocalsocket_win.cpp b/src/network/socket/qlocalsocket_win.cpp
index aa5c12b5b8a..efeb3cdf0ac 100644
--- a/src/network/socket/qlocalsocket_win.cpp
+++ b/src/network/socket/qlocalsocket_win.cpp
@@ -238,6 +238,20 @@ void QLocalSocket::connectToServer(OpenMode openMode)
emit connected();
}
+static qint64 tranformPipeReaderResult(qint64 res)
+{
+ // QWindowsPipeReader's reading functions return error codes
+ // that don't match what we need.
+ switch (res) {
+ case 0: // EOF -> transform to error
+ return -1;
+ case -2: // EWOULDBLOCK -> no error, just no bytes
+ return 0;
+ default:
+ return res;
+ }
+}
+
// This is reading from the buffer
qint64 QLocalSocket::readData(char *data, qint64 maxSize)
{
@@ -246,17 +260,19 @@ qint64 QLocalSocket::readData(char *data, qint64 maxSize)
if (!maxSize)
return 0;
- qint64 ret = d->pipeReader->read(data, maxSize);
+ return tranformPipeReaderResult(d->pipeReader->read(data, maxSize));
+}
+
+qint64 QLocalSocket::readLineData(char *data, qint64 maxSize)
+{
+ Q_D(QLocalSocket);
- // QWindowsPipeReader::read() returns error codes that don't match what we need
- switch (ret) {
- case 0: // EOF -> transform to error
- return -1;
- case -2: // EWOULDBLOCK -> no error, just no bytes
+ if (!maxSize)
return 0;
- default:
- return ret;
- }
+
+ // QIODevice::readLine() reserves space for the trailing '\0' byte,
+ // so we must read 'maxSize + 1' bytes.
+ return tranformPipeReaderResult(d->pipeReader->readLine(data, maxSize + 1));
}
qint64 QLocalSocket::skipData(qint64 maxSize)