[rkward-cvs] SF.net SVN: rkward:[3143] branches/2010_10_18_backend_restructuring_branch/ rkward/rbackend
tfry at users.sourceforge.net
tfry at users.sourceforge.net
Mon Oct 25 09:22:27 UTC 2010
Revision: 3143
http://rkward.svn.sourceforge.net/rkward/?rev=3143&view=rev
Author: tfry
Date: 2010-10-25 09:22:26 +0000 (Mon, 25 Oct 2010)
Log Message:
-----------
Basics are working, now.
Modified Paths:
--------------
branches/2010_10_18_backend_restructuring_branch/rkward/rbackend/rembedinternal.cpp
branches/2010_10_18_backend_restructuring_branch/rkward/rbackend/rinterface.cpp
branches/2010_10_18_backend_restructuring_branch/rkward/rbackend/rthread.cpp
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 21:14:08 UTC (rev 3142)
+++ branches/2010_10_18_backend_restructuring_branch/rkward/rbackend/rembedinternal.cpp 2010-10-25 09:22:26 UTC (rev 3143)
@@ -195,66 +195,68 @@
RK_ASSERT (buf && buflen);
RK_ASSERT (RThread::repl_status.eval_depth >= 0);
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 (RCommandStack::regular_stack);
- if (!command) return 0; // jumps out of the event loop!
+ while (1) {
+ if (RThread::repl_status.user_command_status == RThread::RKReplStatus::NoUserCommand) {
+ 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.
+ MUTEX_LOCK;
+ 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 ());
- MUTEX_UNLOCK;
- RKTransmitNextUserCommandChunk (buf, buflen);
- RThread::repl_status.user_command_status = RThread::RKReplStatus::UserCommandTransmitted;
- }
- buf[0] = '\0';
- return 1;
- } else if (RThread::repl_status.user_command_status == RThread::RKReplStatus::UserCommandTransmitted) {
- if (RThread::repl_status.user_command_completely_transmitted) {
- // fully transmitted, but R is still asking for more? -> Incomplete statement
+ 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 ());
+ MUTEX_UNLOCK;
+ RKTransmitNextUserCommandChunk (buf, buflen);
+ RThread::repl_status.user_command_status = RThread::RKReplStatus::UserCommandTransmitted;
+ return 1;
+ }
+ } else if (RThread::repl_status.user_command_status == RThread::RKReplStatus::UserCommandTransmitted) {
+ 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::Failed | RCommand::ErrorIncomplete;
+ RThread::repl_status.user_command_status = RThread::RKReplStatus::NoUserCommand;
+ MUTEX_UNLOCK;
+ RThread::this_pointer->commandFinished ();
+ RK_doIntr (); // to discard the buffer
+ } else {
+ RKTransmitNextUserCommandChunk (buf, buflen);
+ return 1;
+ }
+ } else if (RThread::repl_status.user_command_status == RThread::RKReplStatus::UserCommandSyntaxError) {
MUTEX_LOCK;
- RThread::this_pointer->current_command->status |= RCommand::Failed | RCommand::ErrorIncomplete;
+ RThread::this_pointer->current_command->status |= RCommand::Failed | RCommand::ErrorSyntax;
RThread::repl_status.user_command_status = RThread::RKReplStatus::NoUserCommand;
MUTEX_UNLOCK;
+ RThread::this_pointer->commandFinished ();
+ } else if (RThread::repl_status.user_command_status == RThread::RKReplStatus::UserCommandRunning) {
+ // it appears, the user command triggered a call to readline. Will be handled, below.
+ // NOT returning
+ break;
} else {
- RKTransmitNextUserCommandChunk (buf, buflen);
+ RK_ASSERT (false);
+ RThread::repl_status.user_command_status = RThread::RKReplStatus::NoUserCommand;
+ RThread::this_pointer->commandFinished ();
}
- buf[0] = '\0';
- return 1;
- } else if (RThread::repl_status.user_command_status == RThread::RKReplStatus::UserCommandSyntaxError) {
- MUTEX_LOCK;
- RThread::this_pointer->current_command->status |= RCommand::Failed | RCommand::ErrorSyntax;
- RThread::repl_status.user_command_status = RThread::RKReplStatus::NoUserCommand;
- MUTEX_UNLOCK;
- buf[0] = '\0';
- return 1;
- } else if (RThread::repl_status.user_command_status == RThread::RKReplStatus::UserCommandRunning) {
- // it appears, the user command triggered a call to readline. Will be handled, below.
- // NOT returning
- } else {
- RK_ASSERT (false);
- RThread::repl_status.user_command_status = RThread::RKReplStatus::NoUserCommand;
- buf[0] = '\0';
- return 1;
}
}
-
+
// 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! May be identifiable due to hist==true
RCallbackArgs args;
@@ -276,6 +278,7 @@
qstrncpy ((char *) buf, localres.left (buflen - 2).append ('\n').data (), buflen);
// we should not ever get here, but still...
+ RK_ASSERT (false);
buf[0] = '\0';
return 1;
}
Modified: branches/2010_10_18_backend_restructuring_branch/rkward/rbackend/rinterface.cpp
===================================================================
--- branches/2010_10_18_backend_restructuring_branch/rkward/rbackend/rinterface.cpp 2010-10-24 21:14:08 UTC (rev 3142)
+++ branches/2010_10_18_backend_restructuring_branch/rkward/rbackend/rinterface.cpp 2010-10-25 09:22:26 UTC (rev 3143)
@@ -86,7 +86,7 @@
r_thread = new RThread ();
// create a fake init command
- issueCommand (new RCommand (i18n ("R Startup"), RCommand::App | RCommand::Sync, i18n ("R Startup")));
+ issueCommand (new RCommand (i18n ("R Startup"), RCommand::App | RCommand::Sync | RCommand::ObjectListUpdate, i18n ("R Startup")));
flush_timer = new QTimer (this);
connect (flush_timer, SIGNAL (timeout ()), this, SLOT (flushOutput ()));
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 21:14:08 UTC (rev 3142)
+++ branches/2010_10_18_backend_restructuring_branch/rkward/rbackend/rthread.cpp 2010-10-25 09:22:26 UTC (rev 3143)
@@ -78,12 +78,7 @@
msleep (10);
}
- MUTEX_LOCK;
- checkObjectUpdatesNeeded (true);
- RCommandStack::regular_stack->pop (); // remove the fake command
- all_current_commands.pop_back ();
- notifyCommandDone (current_command);
- MUTEX_UNLOCK;
+ commandFinished (); // the fake startup command
enterEventLoop ();
}
@@ -102,13 +97,14 @@
notifyCommandDone (current_command); // command may be deleted after this
all_current_commands.pop_back();
- current_command = all_current_commands.last ();
+ if (!all_current_commands.isEmpty ()) current_command = all_current_commands.last ();
MUTEX_UNLOCK;
}
RCommand* RThread::fetchNextCommand (RCommandStack* stack) {
RK_TRACE (RBACKEND);
+ bool main_stack = (stack == RCommandStack::regular_stack);
#warning We would need so much less mutex locking everywhere, if the command would simply be copied between threads!
while (1) {
if (killed) {
@@ -125,7 +121,7 @@
}
}
- if ((!locked) && stack->isActive ()) {
+ if ((!(main_stack && locked)) && stack->isActive ()) { // do not respect locks in substacks
RCommand *command = stack->currentCommand ();
if (command) {
@@ -133,6 +129,7 @@
RKRBackendEvent* event = new RKRBackendEvent (RKRBackendEvent::RCommandIn, command);
qApp->postEvent (RKGlobals::rInterface (), event);
all_current_commands.append (command);
+ current_command = 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
@@ -157,7 +154,7 @@
}
}
- if ((!stack->isActive ()) && stack->isEmpty () && stack != RCommandStack::regular_stack) {
+ if ((!stack->isActive ()) && stack->isEmpty () && !main_stack) {
MUTEX_UNLOCK;
return 0; // substack depleted
}
@@ -181,27 +178,6 @@
return 0;
}
-void RThread::doCommand (RCommand *command) {
- RK_TRACE (RBACKEND);
-
- // step 2: actual handling
- if (!((command->type () & RCommand::EmptyCommand) || (command->status & RCommand::Canceled))) {
-
- runCommand (command);
-
- } else {
- if (command->status & RCommand::Canceled) {
- command->status |= RCommand::Failed;
- } else if (command->type () & RCommand::QuitCommand) {
- killed = true;
- MUTEX_UNLOCK;
- shutdown (false);
- MUTEX_LOCK;
- }
- }
-}
-
-
void RThread::notifyCommandDone (RCommand *command) {
RK_TRACE (RBACKEND);
@@ -345,7 +321,10 @@
RCommand *c;
while ((c = fetchNextCommand (reply_stack))) {
+ MUTEX_LOCK;
runCommand (c);
+ MUTEX_UNLOCK;
+ commandFinished ();
}
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