[rkward-cvs] rkward/rkward/rbackend rinterface.cpp, 1.49, 1.50 rthread.cpp, 1.40, 1.41 rthread.h, 1.21, 1.22
Thomas Friedrichsmeier
tfry at users.sourceforge.net
Sun Sep 10 23:01:10 UTC 2006
Update of /cvsroot/rkward/rkward/rkward/rbackend
In directory sc8-pr-cvs9.sourceforge.net:/tmp/cvs-serv22080
Modified Files:
rinterface.cpp rthread.cpp rthread.h
Log Message:
Use saner output locking, and avoid deadlocks
Index: rinterface.cpp
===================================================================
RCS file: /cvsroot/rkward/rkward/rkward/rbackend/rinterface.cpp,v
retrieving revision 1.49
retrieving revision 1.50
diff -C2 -d -r1.49 -r1.50
*** rinterface.cpp 1 Sep 2006 15:38:17 -0000 1.49
--- rinterface.cpp 10 Sep 2006 23:01:07 -0000 1.50
***************
*** 120,127 ****
// TODO: not quite good, yet, leads to staggering output (but overall throughput is the same):
! // output events can easily stack up in the hundreds, not allowing GUI events to get through. Let's block further output events for a minute (using MUTEX_LOCK) and then catch up with the event queue
! MUTEX_LOCK;
! qApp->processEvents ();
! MUTEX_UNLOCK;
} else if (e->type () == RCOMMAND_IN_EVENT) {
watch->addInput (static_cast <RCommand *> (e->data ()));
--- 120,129 ----
// TODO: not quite good, yet, leads to staggering output (but overall throughput is the same):
! // output events can easily stack up in the hundreds, not allowing GUI events to get through. Let's block further output events for a minute and then catch up with the event queue
! if (qApp->hasPendingEvents ()) {
! r_thread->pauseOutput (true);
! qApp->processEvents ();
! r_thread->pauseOutput (false);
! }
} else if (e->type () == RCOMMAND_IN_EVENT) {
watch->addInput (static_cast <RCommand *> (e->data ()));
***************
*** 155,160 ****
--- 157,164 ----
RKGlobals::rkApp ()->setRStatus (true);
} else if ((e->type () == R_EVAL_REQUEST_EVENT)) {
+ r_thread->pauseOutput (false); // we may be recursing downwards into event loops here. Hence we need to make sure, we don't create a deadlock
processREvalRequest (static_cast<REvalRequest *> (e->data ()));
} else if ((e->type () == R_CALLBACK_REQUEST_EVENT)) {
+ r_thread->pauseOutput (false); // see above
processRCallbackRequest (static_cast<RCallbackArgs *> (e->data ()));
} else if ((e->type () == RSTARTED_EVENT)) {
***************
*** 293,298 ****
if (request->call_length >= 2) {
QString lib_name = request->call[1];
KMessageBox::information (0, i18n ("The R-backend has indicated that in order to carry out the current task it needs the package '%1', which is not currently installed. We'll open the package-management tool, and there you can try to locate and install the needed package.").arg (lib_name), i18n ("Require package '%1'").arg (lib_name));
! RKLoadLibsDialog::showInstallPackagesModal (0, request->in_chain);
issueCommand (".rk.rkreply <- \"\"", RCommand::App | RCommand::Sync, QString::null, 0, 0, request->in_chain);
} else {
--- 297,303 ----
if (request->call_length >= 2) {
QString lib_name = request->call[1];
+ issueCommand (".rk.rkreply <- NULL", RCommand::App | RCommand::Sync, QString::null, 0, 0, request->in_chain);
KMessageBox::information (0, i18n ("The R-backend has indicated that in order to carry out the current task it needs the package '%1', which is not currently installed. We'll open the package-management tool, and there you can try to locate and install the needed package.").arg (lib_name), i18n ("Require package '%1'").arg (lib_name));
! RKLoadLibsDialog::showInstallPackagesModal (0, request->in_chain, lib_name);
issueCommand (".rk.rkreply <- \"\"", RCommand::App | RCommand::Sync, QString::null, 0, 0, request->in_chain);
} else {
Index: rthread.cpp
===================================================================
RCS file: /cvsroot/rkward/rkward/rkward/rbackend/rthread.cpp,v
retrieving revision 1.40
retrieving revision 1.41
diff -C2 -d -r1.40 -r1.41
*** rthread.cpp 18 Aug 2006 14:37:30 -0000 1.40
--- rthread.cpp 10 Sep 2006 23:01:07 -0000 1.41
***************
*** 44,47 ****
--- 44,48 ----
current_output = 0;
out_buf_len = 0;
+ output_paused = false;
}
***************
*** 146,150 ****
runCommandInternal ("sink (\"" + RKSettingsModuleGeneral::filesPath () + "/rk_out.html\", append=TRUE, split=TRUE)\n", &error);
}
!
MUTEX_UNLOCK;
--- 147,151 ----
runCommandInternal ("sink (\"" + RKSettingsModuleGeneral::filesPath () + "/rk_out.html\", append=TRUE, split=TRUE)\n", &error);
}
!
MUTEX_UNLOCK;
***************
*** 158,164 ****
runCommandInternal (ccommand, &error, ctype & RCommand::User);
}
!
MUTEX_LOCK;
!
if (error != NoError) {
command->status |= RCommand::WasTried | RCommand::Failed;
--- 159,165 ----
runCommandInternal (ccommand, &error, ctype & RCommand::User);
}
!
MUTEX_LOCK;
!
if (error != NoError) {
command->status |= RCommand::WasTried | RCommand::Failed;
***************
*** 201,204 ****
--- 202,212 ----
}
+ void RThread::waitIfOutputPaused () {
+ // don't trace
+ while (output_paused) {
+ msleep (10);
+ }
+ }
+
void RThread::handleOutput (char *buf, int buf_length) {
RK_TRACE (RBACKEND);
***************
*** 207,210 ****
--- 215,219 ----
if (!buf_length) return;
+ waitIfOutputPaused ();
MUTEX_LOCK;
***************
*** 268,271 ****
--- 277,281 ----
if (!call_length) return;
+ waitIfOutputPaused ();
MUTEX_LOCK;
Index: rthread.h
===================================================================
RCS file: /cvsroot/rkward/rkward/rkward/rbackend/rthread.h,v
retrieving revision 1.21
retrieving revision 1.22
diff -C2 -d -r1.21 -r1.22
*** rthread.h 3 Nov 2005 19:34:29 -0000 1.21
--- rthread.h 10 Sep 2006 23:01:07 -0000 1.22
***************
*** 91,94 ****
--- 91,98 ----
/** "Kills" the thread. Actually this just tells the thread that is is about to be terminated. Allows the thread to terminate gracefully */
void kill () { killed = true; };
+ /** Pause output by placing it in a delay loop, until unpaused again */
+ void pauseOutput (bool paused) { output_paused = paused; };
+ /** the internal counterpart to pauseOutput () */
+ void waitIfOutputPaused ();
/** An enum describing whether initialization of the embedded R-process went well, or what errors occurred. */
***************
*** 165,168 ****
--- 169,173 ----
/** thread is killed. Should exit as soon as possible. @see kill */
bool killed;
+ bool output_paused;
};
More information about the rkward-tracker
mailing list