[education/rkward] rkward/rbackend: Some further experiments to stabilizing startup handshake on Windows
Thomas Friedrichsmeier
null at kde.org
Fri May 6 21:44:57 BST 2022
Git commit 9b511a67d2e83e944ad79d9ad818b2e90fcc2c97 by Thomas Friedrichsmeier.
Committed on 06/05/2022 at 20:44.
Pushed by tfry into branch 'master'.
Some further experiments to stabilizing startup handshake on Windows
M +11 -8 rkward/rbackend/rkfrontendtransmitter.cpp
M +1 -1 rkward/rbackend/rkfrontendtransmitter.h
M +1 -0 rkward/rbackend/rkrbackendprotocol_backend.cpp
M +1 -2 rkward/rbackend/rkwarddevice/rkgraphicsdevice_frontendtransmitter.cpp
https://invent.kde.org/education/rkward/commit/9b511a67d2e83e944ad79d9ad818b2e90fcc2c97
diff --git a/rkward/rbackend/rkfrontendtransmitter.cpp b/rkward/rbackend/rkfrontendtransmitter.cpp
index 1815e7e0..96ccfc98 100644
--- a/rkward/rbackend/rkfrontendtransmitter.cpp
+++ b/rkward/rbackend/rkfrontendtransmitter.cpp
@@ -132,8 +132,7 @@ void RKFrontendTransmitter::run () {
if (!backend->waitForStarted()) {
handleTransmissionError(i18n("The backend executable could not be started. Error message was: %1", backend->errorString()));
} else {
- waitForCanReadLine(backend, 15000);
- token = QString::fromLocal8Bit(backend->readLine()).trimmed();
+ token = waitReadLine(backend, 5000).trimmed();
backend->closeReadChannel(QProcess::StandardError);
backend->closeReadChannel(QProcess::StandardOutput);
}
@@ -149,14 +148,20 @@ void RKFrontendTransmitter::run () {
}
}
-void RKFrontendTransmitter::waitForCanReadLine (QIODevice* con, int msecs) {
+QString RKFrontendTransmitter::waitReadLine (QIODevice* con, int msecs) {
RK_TRACE (RBACKEND);
// NOTE: On Qt5+Windows, readyReady may actually come in char by char, so calling waitForReadyRead() does not guarantee we will
// see the full line, at all. But also, of course, we want to put some cap on trying. Using a time threshold for this.
QElapsedTimer time;
time.start();
- while ((!con->canReadLine()) && (time.elapsed() < msecs)) con->waitForReadyRead(500);
+ QByteArray ret;
+ do {
+ ret.append(con->readLine());
+ if (ret.contains('\n')) break;
+ con->waitForReadyRead(500);
+ } while(time.elapsed() < msecs);
+ return QString::fromLocal8Bit(ret);
}
void RKFrontendTransmitter::connectAndEnterLoop () {
@@ -167,11 +172,9 @@ void RKFrontendTransmitter::connectAndEnterLoop () {
server->close ();
// handshake
- waitForCanReadLine (con, 1000);
- QString token_c = QString::fromLocal8Bit (con->readLine ()). trimmed ();
+ QString token_c = waitReadLine(con, 1000).trimmed();
if (token_c != token) handleTransmissionError (i18n ("Error during handshake with backend process. Expected token '%1', received token '%2'", token, token_c));
- waitForCanReadLine (con, 1000);
- QString version_c = QString::fromLocal8Bit (con->readLine ().trimmed ());
+ QString version_c = waitReadLine(con, 1000).trimmed();
if (version_c != RKWARD_VERSION) handleTransmissionError (i18n ("Version mismatch during handshake with backend process. Frontend is version '%1' while backend is '%2'.\nPlease fix your installation.", QString (RKWARD_VERSION), version_c));
setConnection (con);
diff --git a/rkward/rbackend/rkfrontendtransmitter.h b/rkward/rbackend/rkfrontendtransmitter.h
index 0b659d55..32281d83 100644
--- a/rkward/rbackend/rkfrontendtransmitter.h
+++ b/rkward/rbackend/rkfrontendtransmitter.h
@@ -31,7 +31,7 @@ public:
void requestReceived (RBackendRequest *request) override;
/** Simple convenience function similar to QIODevice::waitForReadyRead(), but waiting for a full line to be available.
In particular on Windows, we often receive _less_ than a full line per chunk. */
- static void waitForCanReadLine (QIODevice *con, int msecs);
+ static QString waitReadLine (QIODevice *con, int msecs);
private slots:
void connectAndEnterLoop ();
void backendExit (int exitcode);
diff --git a/rkward/rbackend/rkrbackendprotocol_backend.cpp b/rkward/rbackend/rkrbackendprotocol_backend.cpp
index 27d7751a..c1dec369 100644
--- a/rkward/rbackend/rkrbackendprotocol_backend.cpp
+++ b/rkward/rbackend/rkrbackendprotocol_backend.cpp
@@ -107,6 +107,7 @@ SPDX-License-Identifier: GPL-2.0-or-later
// this token is sent both via stdout and the local socket connection. The frontend simply compares both values.
QString token = QUuid::createUuid ().toString ();
std::cout << token.toLocal8Bit ().data () << "\n";
+ std::cout << token.toLocal8Bit ().data () << "\n";
std::cout.flush ();
RKRBackendTransmitter transmitter (servername, token);
diff --git a/rkward/rbackend/rkwarddevice/rkgraphicsdevice_frontendtransmitter.cpp b/rkward/rbackend/rkwarddevice/rkgraphicsdevice_frontendtransmitter.cpp
index 32093cc8..6c551cf1 100644
--- a/rkward/rbackend/rkwarddevice/rkgraphicsdevice_frontendtransmitter.cpp
+++ b/rkward/rbackend/rkwarddevice/rkgraphicsdevice_frontendtransmitter.cpp
@@ -61,8 +61,7 @@ void RKGraphicsDeviceFrontendTransmitter::newConnection () {
// handshake
QString token = RKFrontendTransmitter::instance ()->connectionToken ();
- RKFrontendTransmitter::waitForCanReadLine (con, 2000);
- QString token_c = QString::fromLocal8Bit (con->readLine ()).trimmed ();
+ QString token_c = RKFrontendTransmitter::waitReadLine(con, 2000).trimmed ();
if (token_c != token) {
KMessageBox::detailedError (0, QString ("<p>%1</p>").arg (i18n ("There has been an error while trying to connect the on-screen graphics backend. This means, on-screen graphics using the RKWard device will not work in this session.")), i18n ("Expected connection token %1, but read connection token %2", token, token_c), i18n ("Error while connection graphics backend"));
con->close ();
More information about the rkward-tracker
mailing list