diff options
author | Sami Shalayel <sami.shalayel@qt.io> | 2022-06-10 12:05:33 +0200 |
---|---|---|
committer | Sami Shalayel <sami.shalayel@qt.io> | 2022-08-12 17:10:01 +0200 |
commit | 1c7c277bf17c33fe00583db79626cb1015c5d15f (patch) | |
tree | 74877a7f1226fb4cfdeafc374f894154c7a66061 /tools | |
parent | a9c3ca83800c9a0bb510407a169195ffa5dca6fb (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.cpp | 42 |
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); |