[rkward-cvs] SF.net SVN: rkward:[3141] branches/2010_10_18_backend_restructuring_branch/ rkward/rbackend
tfry at users.sourceforge.net
tfry at users.sourceforge.net
Sun Oct 24 19:05:09 UTC 2010
Revision: 3141
http://rkward.svn.sourceforge.net/rkward/?rev=3141&view=rev
Author: tfry
Date: 2010-10-24 19:05:08 +0000 (Sun, 24 Oct 2010)
Log Message:
-----------
Completed turning the event loop upside down. Compiles, but does not run, yet.
Modified Paths:
--------------
branches/2010_10_18_backend_restructuring_branch/rkward/rbackend/rcommand.cpp
branches/2010_10_18_backend_restructuring_branch/rkward/rbackend/rcommand.h
branches/2010_10_18_backend_restructuring_branch/rkward/rbackend/rembedinternal.cpp
branches/2010_10_18_backend_restructuring_branch/rkward/rbackend/rembedinternal.h
branches/2010_10_18_backend_restructuring_branch/rkward/rbackend/rthread.cpp
Modified: branches/2010_10_18_backend_restructuring_branch/rkward/rbackend/rcommand.cpp
===================================================================
--- branches/2010_10_18_backend_restructuring_branch/rkward/rbackend/rcommand.cpp 2010-10-24 12:40:33 UTC (rev 3140)
+++ branches/2010_10_18_backend_restructuring_branch/rkward/rbackend/rcommand.cpp 2010-10-24 19:05:08 UTC (rev 3141)
@@ -23,8 +23,6 @@
#include "../debug.h"
#include "../rkglobals.h"
-#define MAX_RECEIVERS 3
-
RCommandBase::RCommandBase (bool is_chain) {
is_command_chain = is_chain;
RCommandBase::parent = 0;
@@ -57,8 +55,7 @@
if (_command.isEmpty ()) _type |= EmptyCommand;
status = 0;
_rk_equiv = rk_equiv;
- RCommand::receivers = new RCommandReceiver* [MAX_RECEIVERS];
- num_receivers = 0;
+ for (int i = 0; i < MAX_RECEIVERS_PER_RCOMMAND; ++i) receivers[i] = 0;
if (!(type & Internal)) {
addReceiver (receiver);
addReceiver (RKCommandLog::getLog ());
@@ -71,7 +68,6 @@
for (QList<ROutput*>::const_iterator it = output_list.constBegin (); it != output_list.constEnd (); ++it) {
delete (*it);
}
- delete [] receivers;
// The output_list itself is cleared automatically
}
@@ -80,13 +76,15 @@
if (!receiver) return;
- if (num_receivers >= MAX_RECEIVERS) {
- RK_DO (qDebug ("Too many receivers for command"), RBACKEND, DL_ERROR);
- return;
+ for (int i = 0; i < MAX_RECEIVERS_PER_RCOMMAND; ++i) {
+ if (receivers[i] == 0) {
+ receivers[i] = receiver;
+ receiver->addCommand (this);
+ return;
+ }
}
- receivers[num_receivers++] = receiver;
- receiver->addCommand (this);
+ RK_DO (qDebug ("Too many receivers for command"), RBACKEND, DL_ERROR);
}
void RCommand::removeReceiver (RCommandReceiver *receiver) {
@@ -94,27 +92,21 @@
if (!receiver) return;
- RCommandReceiver **newlist = new RCommandReceiver* [MAX_RECEIVERS];
- int num_new_receivers = 0;
- for (int i=0; i < num_receivers; ++i) {
- if (receivers[i] != receiver) {
- newlist[num_new_receivers++] = receivers[i];
+ for (int i = 0; i < MAX_RECEIVERS_PER_RCOMMAND; ++i) {
+ if (receivers[i] == receiver) {
+ receivers[i] = 0;
+ return;
}
}
- if (num_new_receivers == num_receivers) {
- RK_DO (qDebug ("Was not a receiver in RCommand::removeReceiver"), RBACKEND, DL_WARNING);
- }
-
- delete [] receivers;
- receivers = newlist;
- num_receivers = num_new_receivers;
+ RK_DO (qDebug ("Was not a receiver in RCommand::removeReceiver: %p", receiver), RBACKEND, DL_WARNING);
}
void RCommand::finished () {
RK_TRACE (RBACKEND);
- for (int i=0; i < num_receivers; ++i) {
+ for (int i=0; i < MAX_RECEIVERS_PER_RCOMMAND; ++i) {
+ if (receivers[i] == 0) continue;
receivers[i]->delCommand (this);
receivers[i]->rCommandDone (this);
}
@@ -123,7 +115,8 @@
void RCommand::newOutput (ROutput *output) {
RK_TRACE (RBACKEND);
- for (int i=0; i < num_receivers; ++i) {
+ for (int i=0; i < MAX_RECEIVERS_PER_RCOMMAND; ++i) {
+ if (receivers[i] == 0) continue;
receivers[i]->newOutput (this, output);
}
}
Modified: branches/2010_10_18_backend_restructuring_branch/rkward/rbackend/rcommand.h
===================================================================
--- branches/2010_10_18_backend_restructuring_branch/rkward/rbackend/rcommand.h 2010-10-24 12:40:33 UTC (rev 3140)
+++ branches/2010_10_18_backend_restructuring_branch/rkward/rbackend/rcommand.h 2010-10-24 19:05:08 UTC (rev 3141)
@@ -2,7 +2,7 @@
rcommand.h - description
-------------------
begin : Mon Nov 11 2002
- copyright : (C) 2002, 2006, 2007, 2009 by Thomas Friedrichsmeier
+ copyright : (C) 2002, 2006, 2007, 2009, 2010 by Thomas Friedrichsmeier
email : tfry at users.sourceforge.net
***************************************************************************/
@@ -25,6 +25,8 @@
#include "rdata.h"
+#define MAX_RECEIVERS_PER_RCOMMAND 3
+
class RCommandReceiver;
class RCommand;
class RCommandChain;
@@ -73,24 +75,6 @@
typedef QList<ROutput*> ROutputList;
-/*
-struct RGetValueRequest {
-private:
-friend class RInterface;
-friend class RThread;
- char **call;
- int call_length;
-};
-
-struct RGetValueReply {
-private:
-friend class RInterface;
-friend class RThread;
- char **reply;
- int reply_length;
-};
-*/
-
/** For introductory information on using RCommand, see \ref UsingTheInterfaceToR
This class is used to encapsulate an R-command, so it can be easily identified
@@ -221,8 +205,7 @@
QString _rk_equiv;
int _id;
static int next_id;
- int num_receivers;
- RCommandReceiver **receivers;
+ RCommandReceiver *receivers[MAX_RECEIVERS_PER_RCOMMAND];
};
#endif
Modified: branches/2010_10_18_backend_restructuring_branch/rkward/rbackend/rembedinternal.cpp
===================================================================
--- branches/2010_10_18_backend_restructuring_branch/rkward/rbackend/rembedinternal.cpp 2010-10-24 12:40:33 UTC (rev 3140)
+++ branches/2010_10_18_backend_restructuring_branch/rkward/rbackend/rembedinternal.cpp 2010-10-24 19:05:08 UTC (rev 3141)
@@ -19,7 +19,7 @@
// static
RThread *RThread::this_pointer = 0;
-RThread::RKReplStatus RThread::repl_status = { QByteArray (), 0, true, 0, RThread::RKReplStatus::NoUserCommand, 0 };
+RThread::RKReplStatus RThread::repl_status = { QByteArray (), 0, true, 0, 0, RThread::RKReplStatus::NoUserCommand, 0 };
#include <qstring.h>
#include <QStringList>
@@ -134,13 +134,19 @@
if (RThread::repl_status.eval_depth == 0) {
RK_ASSERT (RThread::repl_status.user_command_status = RThread::RKReplStatus::UserCommandRunning);
if (succeeded) {
- RThread::repl_status.user_command_successful_up_to = RThread::repl_status.user_command_transmitted_up_to;
+ RThread::repl_status.user_command_successful_up_to = RThread::repl_status.user_command_parsed_up_to;
if (RThread::repl_status.user_command_completely_transmitted) RThread::repl_status.user_command_status = RThread::RKReplStatus::NoUserCommand;
else RThread::repl_status.user_command_status = RThread::RKReplStatus::UserCommandTransmitted;
} else {
// skip remainder of command
RThread::repl_status.user_command_status = RThread::RKReplStatus::NoUserCommand;
}
+ if (RThread::repl_status.user_command_status == RThread::RKReplStatus::NoUserCommand) {
+ MUTEX_LOCK;
+ if (!succeeded) RThread::this_pointer->current_command->status |= RCommand::Failed | RCommand::ErrorOther;
+ MUTEX_UNLOCK;
+ RThread::this_pointer->commandFinished ();
+ }
}
return (Rboolean) true;
@@ -191,17 +197,28 @@
if (RThread::repl_status.eval_depth == 0) {
if (RThread::repl_status.user_command_status == RThread::RKReplStatus::NoUserCommand) {
MUTEX_LOCK;
- RCommand *command = RThread::this_pointer->fetchNextCommand ();
+ RCommand *command = RThread::this_pointer->fetchNextCommand (RCommandStack::regular_stack);
+ if (!command) return 0; // jumps out of the event loop!
+
+ RThread::this_pointer->current_command = command;
if (!(command->type () & RCommand::User)) {
RThread::this_pointer->runCommand (command);
+ RThread::this_pointer->commandFinished ();
MUTEX_UNLOCK;
} else {
// so, we are about to transmit a new user command, which is quite a complex endeavour...
+ /* Some words about running user commands:
+ - User commands can only be run at the top level of execution, not in any sub-stacks. But then, they should never get there, in the first place.
+ - Handling user commands is totally different from all other commands, and relies on R's "REPL" (read-evaluate-print-loop). This is a whole bunch of dedicated code, but there is no other way to achieve handling of commands as if they had been entered on a plain R console (incluing auto-printing, and toplevel handlers). Most importantly, since important symbols are not exported, such as R_Visible. Vice versa, it is not possible to treat all commands like user commands, esp. in substacks.
+
+ Problems to deal with:
+ - R_ReadConsole serves a lot of different functions, including reading in code, but also handling user input for readline() or browser(). This makes it necessary to carefully track the current status using "repl_status". You will find repl_status to be modified at a couple of different functions.
+ */
RThread::repl_status.user_command_transmitted_up_to = 0;
RThread::repl_status.user_command_completely_transmitted = false;
+ RThread::repl_status.user_command_parsed_up_to = 0;
RThread::repl_status.user_command_successful_up_to = 0;
RThread::repl_status.user_command_buffer = RThread::this_pointer->current_locale_codec->fromUnicode (command->command ());
- RThread::this_pointer->current_command = command;
MUTEX_UNLOCK;
RKTransmitNextUserCommandChunk (buf, buflen);
RThread::repl_status.user_command_status = RThread::RKReplStatus::UserCommandTransmitted;
@@ -212,7 +229,7 @@
if (RThread::repl_status.user_command_completely_transmitted) {
// fully transmitted, but R is still asking for more? -> Incomplete statement
MUTEX_LOCK;
- RThread::this_pointer->current_command->status |= RCommand::ErrorIncomplete;
+ RThread::this_pointer->current_command->status |= RCommand::Failed | RCommand::ErrorIncomplete;
RThread::repl_status.user_command_status = RThread::RKReplStatus::NoUserCommand;
MUTEX_UNLOCK;
} else {
@@ -222,7 +239,7 @@
return 1;
} else if (RThread::repl_status.user_command_status == RThread::RKReplStatus::UserCommandSyntaxError) {
MUTEX_LOCK;
- RThread::this_pointer->current_command->status |= RCommand::ErrorIncomplete;
+ RThread::this_pointer->current_command->status |= RCommand::Failed | RCommand::ErrorSyntax;
RThread::repl_status.user_command_status = RThread::RKReplStatus::NoUserCommand;
MUTEX_UNLOCK;
buf[0] = '\0';
@@ -239,7 +256,7 @@
}
// here, we handle readline() calls and such, i.e. not the regular prompt for code
- // browser() also takes us here. TODO: give browser() special handling!
+ // browser() also takes us here. TODO: give browser() special handling! May be identifiable due to hist==true
RCallbackArgs args;
args.type = RCallbackArgs::RReadLine;
args.params["prompt"] = QVariant (prompt);
@@ -487,6 +504,7 @@
// R_ReplIteration calls R_Busy (1) after reading in code (if needed), successfully parsing it, and right before evaluating it.
if (busy) {
if (RThread::repl_status.user_command_status == RThread::RKReplStatus::UserCommandTransmitted) {
+ RThread::repl_status.user_command_parsed_up_to = RThread::repl_status.user_command_transmitted_up_to;
RThread::repl_status.user_command_status = RThread::RKReplStatus::UserCommandRunning;
}
}
@@ -509,6 +527,7 @@
current_output = 0;
out_buf_len = 0;
output_paused = false;
+ previously_idle = false;
#ifdef Q_WS_WIN
// we hope that on other platforms the default is reasonable
@@ -947,7 +966,6 @@
#endif
RKGlobals::na_double = NA_REAL;
- R_ReplDLLinit ();
RKWard_RData_Tag = Rf_install ("RKWard_RData_Tag");
R_LastvalueSymbol = Rf_install (".Last.value");
@@ -1137,59 +1155,38 @@
QByteArray ccommand = current_locale_codec->fromUnicode (command->command ());
RData retdata;
+ // running user commands is quite different from all other commands and should have been handled by RReadConsole
+ RK_ASSERT (!(ctype & RCommand::User));
+
if (!(ctype & RCommand::Internal)) {
MUTEX_UNLOCK;
}
- // running user commands is quite different from all other commands
- if (ctype & RCommand::User) {
-#error restructure, move this, keep comment
- // run a user command
-/* Using R_ReplDLLdo1 () is a pain, but it seems to be the only entry point for evaluating a command as if it had been entered on a plain R console (with auto-printing if not invisible, etc.). Esp. since R_Visible is no longer exported in R 2.5.0, as it seems as of today (2007-01-17).
-Problems to deal with:
-- R_ReplDLLdo1 () may do a jump on an error. Hence we need R_ToplevelExec (public sind R 2.4.0)
- - this is why runUserCommandInternal needs to be a separate function
-- R_ReplDLLdo1 () expects to receive the code input via R_ReadConsole. The same R_ReadConsole that commands like readline () or browser () will use to get their input.
- - hence we need some state variables to figure out, when a call to R_ReadConsole originates directly from R_ReplDLLdo1 (), or some R statement. R_Busy () is our friend, here.
-- R_ReplDLLdo1 () will only ever evaluate one statement, even if several statements have already been transfered to the buffer. In fact, it will even return once after each ';' or '\n', even if the statement is not complete, but more is already in the buffer
- - Hence we need two loops around R_ReplDLLdo1 (): one to make sure it continues reading until a statement is actually complete, another to continue if there is a second (complete or incomplete) statement in the command
- - Also, in case the command was too long to fit inside the buffer at once (repldll_buffer_transfer_finished)
-- Some more state variables are used for figuring out, which type of error occurred, if any, since we don't get any decent return value
-
-This is the logic spread out over the following section, runUserCommandInternal (), and RReadConsole ().
-
-NOTE from Deepayan Sarkar: Another possible simplification (which may not be worth doing
-ultimately): you distinguish between two types of calls to
-R_ReadConsole based on R_busy calls, but you may be able to use the
-second 'hist' argument. I didn't look too carefully, but it seems like
-hist == 1 iff R wants a parse-able input.
-*/
- } else { // not a user command
- repl_status.eval_depth++;
- SEXP parsed = parseCommand (command->command (), &error);
+ repl_status.eval_depth++;
+ SEXP parsed = parseCommand (command->command (), &error);
+ if (error == NoError) {
+ SEXP exp;
+ PROTECT (exp = runCommandInternalBase (parsed, &error));
if (error == NoError) {
- SEXP exp;
- PROTECT (exp = runCommandInternalBase (parsed, &error));
- if (error == NoError) {
- if (ctype & RCommand::GetStringVector) {
- retdata.datatype = RData::StringVector;
- retdata.data = SEXPToStringList (exp, &(retdata.length));
- } else if (ctype & RCommand::GetRealVector) {
- retdata.datatype = RData::RealVector;
- retdata.data = SEXPToRealArray (exp, &(retdata.length));
- } else if (ctype & RCommand::GetIntVector) {
- retdata.datatype = RData::IntVector;
- retdata.data = SEXPToIntArray (exp, &(retdata.length));
- } else if (ctype & RCommand::GetStructuredData) {
- RData *dummy = SEXPToRData (exp);
- retdata.setData (*dummy);
- delete dummy;
- }
+ if (ctype & RCommand::GetStringVector) {
+ retdata.datatype = RData::StringVector;
+ retdata.data = SEXPToStringList (exp, &(retdata.length));
+ } else if (ctype & RCommand::GetRealVector) {
+ retdata.datatype = RData::RealVector;
+ retdata.data = SEXPToRealArray (exp, &(retdata.length));
+ } else if (ctype & RCommand::GetIntVector) {
+ retdata.datatype = RData::IntVector;
+ retdata.data = SEXPToIntArray (exp, &(retdata.length));
+ } else if (ctype & RCommand::GetStructuredData) {
+ RData *dummy = SEXPToRData (exp);
+ retdata.setData (*dummy);
+ delete dummy;
}
- UNPROTECT (1); // exp
}
- repl_status.eval_depth--;
+ UNPROTECT (1); // exp
}
+ repl_status.eval_depth--;
+
if (!(ctype & RCommand::Internal)) {
if (!locked || killed) processX11Events ();
MUTEX_LOCK;
Modified: branches/2010_10_18_backend_restructuring_branch/rkward/rbackend/rembedinternal.h
===================================================================
--- branches/2010_10_18_backend_restructuring_branch/rkward/rbackend/rembedinternal.h 2010-10-24 12:40:33 UTC (rev 3140)
+++ branches/2010_10_18_backend_restructuring_branch/rkward/rbackend/rembedinternal.h 2010-10-24 19:05:08 UTC (rev 3141)
@@ -255,6 +255,7 @@
QByteArray user_command_buffer;
int user_command_transmitted_up_to;
bool user_command_completely_transmitted;
+ int user_command_parsed_up_to;
int user_command_successful_up_to;
enum {
NoUserCommand,
@@ -265,11 +266,16 @@
int eval_depth; // Number (depth) of non-user commands currently running. User commands can only run at depth 0
};
static RKReplStatus repl_status;
+
+ // fetch next command (and do event processing while waiting)
+ RCommand *fetchNextCommand (RCommandStack *stack);
+ void commandFinished ();
protected:
/** thread is locked. No new commands will be executed. @see LockType @see lock @see unlock */
int locked;
/** thread is killed. Should exit as soon as possible. @see kill */
bool killed;
+ bool previously_idle;
/** On pthread systems this is the pthread_id of the backend thread. It is needed to send SIGINT to the R backend */
Qt::HANDLE thread_id;
private:
Modified: branches/2010_10_18_backend_restructuring_branch/rkward/rbackend/rthread.cpp
===================================================================
--- branches/2010_10_18_backend_restructuring_branch/rkward/rbackend/rthread.cpp 2010-10-24 12:40:33 UTC (rev 3140)
+++ branches/2010_10_18_backend_restructuring_branch/rkward/rbackend/rthread.cpp 2010-10-24 19:05:08 UTC (rev 3141)
@@ -57,7 +57,6 @@
locked = Startup;
killed = false;
int err;
- bool previously_idle = false;
// in RInterface::RInterface() we create a fake RCommand to capture all the output/errors during startup
MUTEX_LOCK;
@@ -86,7 +85,36 @@
notifyCommandDone (current_command);
MUTEX_UNLOCK;
+ enterEventLoop ();
+}
+
+void RThread::commandFinished () {
+ RK_TRACE (RBACKEND);
+
+ RK_DO (qDebug ("done running command"), RBACKEND, DL_DEBUG);
+ MUTEX_LOCK;
+ current_command->status -= (current_command->status & RCommand::Running);
+ current_command->status |= RCommand::WasTried;
+ RCommandStackModel::getModel ()->itemChange (current_command);
+
+ checkObjectUpdatesNeeded (current_command->type () & (RCommand::User | RCommand::ObjectListUpdate));
+ RCommandStack::currentStack ()->pop ();
+ notifyCommandDone (current_command); // command may be deleted after this
+
+ all_current_commands.pop_back();
+ current_command = all_current_commands.last ();
+ MUTEX_UNLOCK;
+}
+
+RCommand* RThread::fetchNextCommand (RCommandStack* stack) {
+ RK_TRACE (RBACKEND);
+
+#warning We would need so much less mutex locking everywhere, if the command would simply be copied between threads!
while (1) {
+ if (killed) {
+ return 0;
+ }
+
processX11Events ();
MUTEX_LOCK;
@@ -96,26 +124,44 @@
previously_idle = false;
}
}
-
- // while commands are in queue, don't wait
- while ((!locked) && RCommandStack::regular_stack->isActive ()) {
- current_command = RCommandStack::regular_stack->currentCommand ();
-
- if (current_command) {
- // mutex will be unlocked inside
- doCommand (current_command);
- checkObjectUpdatesNeeded (current_command->type () & (RCommand::User | RCommand::ObjectListUpdate));
- RCommandStack::regular_stack->pop ();
- notifyCommandDone (current_command); // command may be deleted after this
+
+ if ((!locked) && stack->isActive ()) {
+ RCommand *command = stack->currentCommand ();
+
+ if (command) {
+ // notify GUI-thread that a new command is being tried and initialize
+ RKRBackendEvent* event = new RKRBackendEvent (RKRBackendEvent::RCommandIn, command);
+ qApp->postEvent (RKGlobals::rInterface (), event);
+ all_current_commands.append (command);
+
+ if ((command->type () & RCommand::EmptyCommand) || (command->status & RCommand::Canceled) || (command->type () & RCommand::QuitCommand)) {
+ // some commands are not actually run by R, but handled inline, here
+ if (command->status & RCommand::Canceled) {
+ command->status |= RCommand::Failed;
+ } else if (command->type () & RCommand::QuitCommand) {
+ killed = true;
+ MUTEX_UNLOCK;
+ shutdown (false);
+ MUTEX_LOCK; // I guess we don't get here, though?
+ }
+ commandFinished ();
+ } else {
+ RK_DO (qDebug ("running command: %s", command->command ().toLatin1().data ()), RBACKEND, DL_DEBUG);
+
+ command->status |= RCommand::Running; // it is important that this happens before the Mutex is unlocked!
+ RCommandStackModel::getModel ()->itemChange (command);
+
+ MUTEX_UNLOCK;
+ return command;
+ }
}
-
- if (killed) {
- shutdown (false);
- MUTEX_UNLOCK;
- return;
- }
}
+ if ((!stack->isActive ()) && stack->isEmpty () && stack != RCommandStack::regular_stack) {
+ MUTEX_UNLOCK;
+ return 0; // substack depleted
+ }
+
if (!previously_idle) {
if (RCommandStack::regular_stack->isEmpty ()) {
qApp->postEvent (RKGlobals::rInterface (), new RKRBackendEvent (RKRBackendEvent::RIdle));
@@ -127,32 +173,22 @@
MUTEX_UNLOCK;
if (killed) {
shutdown (false);
- return;
+ return 0;
}
- current_command = 0;
msleep (10);
}
+
+ return 0;
}
void RThread::doCommand (RCommand *command) {
RK_TRACE (RBACKEND);
- // step 1: notify GUI-thread that a new command is being tried and initialize
- RKRBackendEvent* event = new RKRBackendEvent (RKRBackendEvent::RCommandIn, command);
- qApp->postEvent (RKGlobals::rInterface (), event);
// step 2: actual handling
if (!((command->type () & RCommand::EmptyCommand) || (command->status & RCommand::Canceled))) {
- all_current_commands.append (command);
- RK_DO (qDebug ("running command: %s", command->command ().toLatin1().data ()), RBACKEND, DL_DEBUG);
-
- command->status |= RCommand::Running; // it is important that this happens before the Mutex is unlocked!
- RCommandStackModel::getModel ()->itemChange (command);
-
runCommand (command);
- RK_DO (qDebug ("done running command"), RBACKEND, DL_DEBUG);
- all_current_commands.pop_back();
} else {
if (command->status & RCommand::Canceled) {
command->status |= RCommand::Failed;
@@ -163,9 +199,6 @@
MUTEX_LOCK;
}
}
-
- command->status -= (command->status & RCommand::Running);
- RCommandStackModel::getModel ()->itemChange (command);
}
@@ -299,50 +332,20 @@
}
}
- RCommand *prev_command = current_command;
REvalRequest request;
request.call = call;
MUTEX_LOCK;
flushOutput ();
- RCommandStack *reply_stack = new RCommandStack (prev_command);
+ RCommandStack *reply_stack = new RCommandStack (current_command);
request.in_chain = reply_stack->startChain (reply_stack);
MUTEX_UNLOCK;
RKRBackendEvent* event = new RKRBackendEvent (RKRBackendEvent::REvalRequest, &request);
qApp->postEvent (RKGlobals::rInterface (), event);
-
- bool done = false;
- while (!done) {
- processX11Events ();
- MUTEX_LOCK;
- // while commands are in queue, don't wait
- while (reply_stack->isActive ()) { // substack calls are to be considered "sync", and don't respect locks
- if (killed) {
- done = true;
- break;
- }
- current_command = reply_stack->currentCommand ();
- if (current_command) {
- // mutex will be unlocked inside
- bool object_update_forced = (current_command->type () & RCommand::ObjectListUpdate);
- doCommand (current_command);
- if (object_update_forced) checkObjectUpdatesNeeded (true);
- reply_stack->pop ();
- notifyCommandDone (current_command); // command may be deleted after this
- } else {
- msleep (10);
- }
- }
-
- if (reply_stack->isEmpty ()) {
- done = true;
- }
- MUTEX_UNLOCK;
-
- // if no commands are in queue, sleep for a while
- current_command = prev_command;
- msleep (10);
+ RCommand *c;
+ while ((c = fetchNextCommand (reply_stack))) {
+ runCommand (c);
}
MUTEX_LOCK;
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