[rkward-cvs] SF.net SVN: rkward:[3509] trunk/rkward/rkward/rbackend
tfry at users.sourceforge.net
tfry at users.sourceforge.net
Thu Apr 7 08:32:33 UTC 2011
Revision: 3509
http://rkward.svn.sourceforge.net/rkward/?rev=3509&view=rev
Author: tfry
Date: 2011-04-07 08:32:33 +0000 (Thu, 07 Apr 2011)
Log Message:
-----------
Better thread safety, and one leak less, while cancelling commands.
Modified Paths:
--------------
trunk/rkward/rkward/rbackend/rkrbackend.cpp
trunk/rkward/rkward/rbackend/rkrbackend.h
Modified: trunk/rkward/rkward/rbackend/rkrbackend.cpp
===================================================================
--- trunk/rkward/rkward/rbackend/rkrbackend.cpp 2011-04-06 17:19:05 UTC (rev 3508)
+++ trunk/rkward/rkward/rbackend/rkrbackend.cpp 2011-04-07 08:32:33 UTC (rev 3509)
@@ -130,8 +130,10 @@
if (all_current_commands.isEmpty ()) return;
if ((command_id == -1) || (all_current_commands.last ()->id == command_id)) {
- RK_DO (qDebug ("scheduling interrupt for command id %d", command_id), RBACKEND, DL_DEBUG);
- scheduleInterrupt ();
+ if (!too_late_to_interrupt) {
+ RK_DO (qDebug ("scheduling interrupt for command id %d", command_id), RBACKEND, DL_DEBUG);
+ scheduleInterrupt ();
+ }
} else {
// if the command to cancel is *not* the topmost command, then do not interrupt, yet.
foreach (RCommandProxy *candidate, all_current_commands) {
@@ -145,6 +147,16 @@
}
}
+void clearPendingInterrupt_Worker (void *) {
+ R_CheckUserInterrupt ();
+}
+
+void RKRBackend::clearPendingInterrupt () {
+ RK_TRACE (RBACKEND);
+ bool passed = R_ToplevelExec (clearPendingInterrupt_Worker, 0);
+ if (!passed) RK_DO (qDebug ("pending interrupt cleared"), RBACKEND, DL_DEBUG);
+}
+
// some functions we need that are not declared
LibExtern void Rf_PrintWarnings (void);
LibExtern void run_Rmainloop (void);
@@ -900,6 +912,7 @@
RKSignalSupport::saveDefaultSignalHandlers ();
+ too_late_to_interrupt = false;
r_running = true;
int argc = 3;
char* argv[3] = { qstrdup ("--slave"), qstrdup ("--no-save"), qstrdup ("--no-restore") };
@@ -1184,6 +1197,12 @@
RK_TRACE (RBACKEND);
RK_DO (qDebug ("done running command"), RBACKEND, DL_DEBUG);
+ {
+ QMutexLocker lock (&all_current_commands_mutex);
+ too_late_to_interrupt = true;
+ }
+ clearPendingInterrupt (); // Mutex must be unlocked for this!
+
current_command->status -= (current_command->status & RCommand::Running);
current_command->status |= RCommand::WasTried;
@@ -1206,6 +1225,7 @@
QMutexLocker lock (&all_current_commands_mutex);
all_current_commands.pop_back();
if (!all_current_commands.isEmpty ()) current_command = all_current_commands.last ();
+ too_late_to_interrupt = false;
}
}
@@ -1249,6 +1269,7 @@
QMutexLocker lock (&all_current_commands_mutex);
if (current_commands_to_cancel.contains (current_command)) {
RK_DO (qDebug ("will now interrupt parent command"), RBACKEND, DL_DEBUG);
+ current_commands_to_cancel.removeAll (current_command);
scheduleInterrupt ();
}
}
Modified: trunk/rkward/rkward/rbackend/rkrbackend.h
===================================================================
--- trunk/rkward/rkward/rbackend/rkrbackend.h 2011-04-06 17:19:05 UTC (rev 3508)
+++ trunk/rkward/rkward/rbackend/rkrbackend.h 2011-04-07 08:32:33 UTC (rev 3509)
@@ -176,7 +176,10 @@
QMutex all_current_commands_mutex;
QList<RCommandProxy*> current_commands_to_cancel;
+ bool too_late_to_interrupt;
void interruptCommand (int command_id);
+private:
+ void clearPendingInterrupt ();
protected:
RCommandProxy* handleRequest (RBackendRequest *request, bool mayHandleSubstack);
private:
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
More information about the rkward-tracker
mailing list