[education/rkward] rkward/rbackend: Simplify stack of current commands

Thomas Friedrichsmeier null at kde.org
Sun Sep 14 19:26:16 BST 2025


Git commit fa286aae1dc8bbadaf3e83031c5502cf782e21af by Thomas Friedrichsmeier.
Committed on 12/09/2025 at 20:23.
Pushed by tfry into branch 'master'.

Simplify stack of current commands

M  +7    -17   rkward/rbackend/rkrbackend.cpp
M  +0    -1    rkward/rbackend/rkrbackend.h
M  +1    -1    rkward/rbackend/rkrbackendprotocol_shared.cpp
M  +2    -0    rkward/rbackend/rkrbackendprotocol_shared.h

https://invent.kde.org/education/rkward/-/commit/fa286aae1dc8bbadaf3e83031c5502cf782e21af

diff --git a/rkward/rbackend/rkrbackend.cpp b/rkward/rbackend/rkrbackend.cpp
index b9b227b4b..47124fcb1 100644
--- a/rkward/rbackend/rkrbackend.cpp
+++ b/rkward/rbackend/rkrbackend.cpp
@@ -107,8 +107,8 @@ void RKRBackend::interruptCommand(int command_id) {
 
 	/** A request to interrupt a command may happen at very different points in the code:
 	 *  0) before it was even sent from the frontend -> trivially handled in the frontend, backend not involved
-	 *  1) after it was sent from the frontend, but before we properly started handling it in the backend (deserializing the request, pushing it onto
-	 *     all_current_commands, feeding it into the REPL/eval) -> handled in beginAllowInterruptCommand()
+	 *  1) after it was sent from the frontend, but before we properly started handling it in the backend (deserializing the request, setting as
+	 *     current_command, feeding it into the REPL/eval) -> handled in beginAllowInterruptCommand()
 	 *  2) when it is properly running in the backend -> this is the typical case, we worry about, "immediate interrupt", below
 	 *  2b) when it is properly running in the backend, but there is also an active sub-command, which we should allow to complete
 	 *      -> see commands_to_cancel_deferred and handleDeferredInterrupts()
@@ -1321,21 +1321,15 @@ void doPendingPriorityCommands() {
 	RCommandProxy *command = RKRBackend::this_pointer->pending_priority_command;
 	RKRBackend::this_pointer->pending_priority_command = nullptr;
 	if (command) {
-		auto prev_command = RKRBackend::this_pointer->current_command;
 		RK_DEBUG(RBACKEND, DL_DEBUG, "running priority command %s", qPrintable(command->command));
 		{
 			QMutexLocker lock(&RKRBackend::this_pointer->command_flow_mutex);
-			RKRBackend::this_pointer->all_current_commands.append(command);
+			command->outer_command = RKRBackend::this_pointer->current_command;
 			RKRBackend::this_pointer->current_command = command;
 		}
 
 		RKRBackend::this_pointer->runCommand(command);
 		RKRBackend::this_pointer->commandFinished(RKRBackend::NoFetchNextCommand, RKRBackend::NoCheckObjectUpdatesNeeded);
-		RKRBackend::this_pointer->current_command = prev_command;
-		{
-			QMutexLocker lock(&RKRBackend::this_pointer->command_flow_mutex);
-			RKRBackend::this_pointer->current_command = prev_command;
-		}
 	}
 }
 
@@ -1416,7 +1410,8 @@ RCommandProxy *RKRBackend::commandFinished(FetchCommandMode fetch_next, ObjectUp
 		checkObjectUpdatesNeeded(current_command->type & (RCommand::User | RCommand::ObjectListUpdate));
 	}
 
-	auto previous_command = current_command;
+	RBackendRequest req(fetch_next && !isKilled(), RBackendRequest::CommandOut);
+	req.command = current_command;
 
 	{
 		QMutexLocker lock(&command_flow_mutex);
@@ -1424,13 +1419,9 @@ RCommandProxy *RKRBackend::commandFinished(FetchCommandMode fetch_next, ObjectUp
 			repl_status.interrupted = false;
 			current_command->status |= RCommand::Canceled;
 		}
-		all_current_commands.pop_back();
-		if (!all_current_commands.isEmpty()) current_command = all_current_commands.last();
-		else current_command = nullptr;
+		current_command = current_command->outer_command;
 	}
 
-	RBackendRequest req(fetch_next && !isKilled(), RBackendRequest::CommandOut);
-	req.command = previous_command;
 	return RKRBackend::this_pointer->handleRequest(&req, false);
 }
 
@@ -1451,7 +1442,6 @@ RCommandProxy *RKRBackend::handleRequest2(RBackendRequest *request, bool mayHand
 	RK_TRACE(RBACKEND);
 
 	if ((!request->synchronous) && (!isKilled())) {
-		RK_ASSERT(mayHandleSubstack); // i.e. not called from fetchNextCommand
 		RK_ASSERT(!request->subcommandrequest);
 		return nullptr;
 	}
@@ -1474,7 +1464,7 @@ RCommandProxy *RKRBackend::handleRequest2(RBackendRequest *request, bool mayHand
 	{
 		QMutexLocker lock(&command_flow_mutex);
 		RK_ASSERT(command != current_command);
-		all_current_commands.append(command);
+		command->outer_command = current_command;
 		current_command = command;
 	}
 
diff --git a/rkward/rbackend/rkrbackend.h b/rkward/rbackend/rkrbackend.h
index 9b9f77027..7f101ffb9 100644
--- a/rkward/rbackend/rkrbackend.h
+++ b/rkward/rbackend/rkrbackend.h
@@ -99,7 +99,6 @@ class RKRBackend : public RKROutputBuffer {
 
 	/** The command currently being executed. */
 	RCommandProxy *current_command;
-	QList<RCommandProxy *> all_current_commands;
 
 	void runCommand(RCommandProxy *command);
 
diff --git a/rkward/rbackend/rkrbackendprotocol_shared.cpp b/rkward/rbackend/rkrbackendprotocol_shared.cpp
index 237f1a4d2..654446552 100644
--- a/rkward/rbackend/rkrbackendprotocol_shared.cpp
+++ b/rkward/rbackend/rkrbackendprotocol_shared.cpp
@@ -9,7 +9,7 @@ SPDX-License-Identifier: GPL-2.0-or-later
 
 #include "../debug.h"
 
-RCommandProxy::RCommandProxy(const QString &command, int type) {
+RCommandProxy::RCommandProxy(const QString &command, int type) : outer_command(nullptr) {
 	RK_TRACE(RBACKEND);
 
 	RCommandProxy::command = command;
diff --git a/rkward/rbackend/rkrbackendprotocol_shared.h b/rkward/rbackend/rkrbackendprotocol_shared.h
index 7aea84cae..0336a251b 100644
--- a/rkward/rbackend/rkrbackendprotocol_shared.h
+++ b/rkward/rbackend/rkrbackendprotocol_shared.h
@@ -127,7 +127,9 @@ class RCommandProxy : public RData {
 	int id;
 	int status;
 	int has_been_run_up_to;
+	// the following are used in the backend, only
 	bool interruptible_stage;
+	RCommandProxy *outer_command;
 };
 
 class RKROutputBuffer {



More information about the rkward-tracker mailing list