aboutsummaryrefslogtreecommitdiffstats
path: root/tools
diff options
context:
space:
mode:
authorSami Shalayel <sami.shalayel@qt.io>2022-06-10 12:05:33 +0200
committerSami Shalayel <sami.shalayel@qt.io>2022-08-12 17:10:01 +0200
commit1c7c277bf17c33fe00583db79626cb1015c5d15f (patch)
tree74877a7f1226fb4cfdeafc374f894154c7a66061 /tools
parenta9c3ca83800c9a0bb510407a169195ffa5dca6fb (diff)
qmlls: reduce latency by using "dry" QHttpMessageStreamParser
StdinReader::run() (qmllanguageservertool.cpp) just uses readSome, which might read just a single character (and on several platforms that is what it does), and then sends it via signal to another thread. This is rather expensive, we should read larger chunks to be more efficient, but we should never wait for more data if a full message was already read (to avoid deadlocks). This commit uses QHttpMessageStreamParser in dry mode to know when to send the data via the signal, that is, when a message has been entirely read. Change-Id: Iee795ded0a539413ec15c686a416f2ccf6673ec9 Task-number: QTBUG-104553 Fixes: QTBUG-104150 Pick-to: 6.4 Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
Diffstat (limited to 'tools')
-rw-r--r--tools/qmlls/qmllanguageservertool.cpp42
1 files changed, 35 insertions, 7 deletions
diff --git a/tools/qmlls/qmllanguageservertool.cpp b/tools/qmlls/qmllanguageservertool.cpp
index 82f0dedbf3..2dfcc3894d 100644
--- a/tools/qmlls/qmllanguageservertool.cpp
+++ b/tools/qmlls/qmllanguageservertool.cpp
@@ -18,6 +18,8 @@
#include <QtCore/qthreadpool.h>
#include <QtCore/qtimer.h>
+#include <QtJsonRpc/private/qhttpmessagestreamparser_p.h>
+
#include <QtQmlCompiler/private/qqmljsresourcefilemapper_p.h>
#include <QtQmlCompiler/private/qqmljscompiler_p.h>
#include <QtQmlCompiler/private/qqmljslogger_p.h>
@@ -31,8 +33,6 @@
# include <QtCore/qlibraryinfo.h>
#endif
-#include "qlanguageserver_p.h"
-
#include <iostream>
#ifdef Q_OS_WIN32
# include <fcntl.h>
@@ -51,12 +51,40 @@ public:
void run()
{
auto guard = qScopeGuard([this]() { emit eof(); });
- char data[256];
- auto buffer = static_cast<char *>(data);
- while (std::cin.get(buffer[0])) { // should poll/select and process events
- const int read = std::cin.readsome(buffer + 1, 255) + 1;
- emit receivedData(QByteArray(buffer, read));
+ const constexpr qsizetype bufSize = 1024;
+ qsizetype bytesInBuf = 0;
+ char bufferData[2 * bufSize];
+ char *buffer = static_cast<char *>(bufferData);
+
+ auto trySend = [this, &bytesInBuf, buffer]() {
+ if (bytesInBuf == 0)
+ return;
+ qsizetype toSend = bytesInBuf;
+ bytesInBuf = 0;
+ QByteArray dataToSend(buffer, toSend);
+ emit receivedData(dataToSend);
+ };
+ QHttpMessageStreamParser streamParser(
+ [](const QByteArray &, const QByteArray &) { /* just a header, do nothing */ },
+ [&trySend](const QByteArray &) {
+ // message body
+ trySend();
+ },
+ [&trySend](QtMsgType, QString) {
+ // there was an error
+ trySend();
+ },
+ QHttpMessageStreamParser::UNBUFFERED);
+
+ while (std::cin.get(buffer[bytesInBuf])) { // should poll/select and process events
+ qsizetype readNow = std::cin.readsome(buffer + bytesInBuf + 1, bufSize) + 1;
+ QByteArray toAdd(buffer + bytesInBuf, readNow);
+ bytesInBuf += readNow;
+ if (bytesInBuf >= bufSize)
+ trySend();
+ streamParser.receiveData(toAdd);
}
+ trySend();
}
signals:
void receivedData(const QByteArray &data);