[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