[rkward-cvs] SF.net SVN: rkward:[3132] branches/2010_10_18_backend_restructuring_branch/ rkward/rbackend

tfry at users.sourceforge.net tfry at users.sourceforge.net
Tue Oct 19 10:37:33 UTC 2010


Revision: 3132
          http://rkward.svn.sourceforge.net/rkward/?rev=3132&view=rev
Author:   tfry
Date:     2010-10-19 10:37:33 +0000 (Tue, 19 Oct 2010)

Log Message:
-----------
Slowly continue merging RThread and REmbedInternal

Modified Paths:
--------------
    branches/2010_10_18_backend_restructuring_branch/rkward/rbackend/rdata.cpp
    branches/2010_10_18_backend_restructuring_branch/rkward/rbackend/rdata.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
    branches/2010_10_18_backend_restructuring_branch/rkward/rbackend/rthread.h

Modified: branches/2010_10_18_backend_restructuring_branch/rkward/rbackend/rdata.cpp
===================================================================
--- branches/2010_10_18_backend_restructuring_branch/rkward/rbackend/rdata.cpp	2010-10-18 13:12:31 UTC (rev 3131)
+++ branches/2010_10_18_backend_restructuring_branch/rkward/rbackend/rdata.cpp	2010-10-19 10:37:33 UTC (rev 3132)
@@ -2,7 +2,7 @@
                           rdata  -  description
                              -------------------
     begin                : Sun Oct 01 2006
-    copyright            : (C) 2006 by Thomas Friedrichsmeier
+    copyright            : (C) 2006, 2010 by Thomas Friedrichsmeier
     email                : tfry at users.sourceforge.net
  ***************************************************************************/
 
@@ -81,13 +81,12 @@
 	detachData ();
 }
 
-void RData::setData (RData *from) {
-	data = from->data;
-	length = from->length;
-	datatype = from->datatype;
+void RData::setData (RData &from) {
+	data = from.data;
+	length = from.length;
+	datatype = from.datatype;
 
-	from->detachData ();
-	delete from;
+	from.detachData ();
 }
 
 void RData::printStructure (const QString &prefix) {

Modified: branches/2010_10_18_backend_restructuring_branch/rkward/rbackend/rdata.h
===================================================================
--- branches/2010_10_18_backend_restructuring_branch/rkward/rbackend/rdata.h	2010-10-18 13:12:31 UTC (rev 3131)
+++ branches/2010_10_18_backend_restructuring_branch/rkward/rbackend/rdata.h	2010-10-19 10:37:33 UTC (rev 3132)
@@ -50,8 +50,8 @@
 /** purely for debugging! */
 	void printStructure (const QString &prefix);
 
-/** public for technical reasons only. Do not use! Copy data from the given RData, and discard it */
-	void setData (RData *from);
+/** public for technical reasons only. Do not use! Move data from the given RData to this RData. The source RData is emptied! */
+	void setData (RData &from);
 /** public for technical reasons only. Do not use! */
 	RDataType datatype;
 /** public for technical reasons only. Do not use! */

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-18 13:12:31 UTC (rev 3131)
+++ branches/2010_10_18_backend_restructuring_branch/rkward/rbackend/rembedinternal.cpp	2010-10-19 10:37:33 UTC (rev 3132)
@@ -31,6 +31,7 @@
 #include "rklocalesupport.h"
 #include "rkpthreadsupport.h"
 #include "rksignalsupport.h"
+#include "rinterface.h"		// for acces to the mutex
 #include "../misc/rkcommonfunctions.h"
 
 #include <stdlib.h>
@@ -1064,8 +1065,15 @@
 
 	RKWardRError error = NoError;
 
+	// NOTE the command must not be accessed while the mutex is unlocked!
+	// Therefore we copy the data we need, and create a container for the returned data
+	int ctype = command->type ();
+	QByteArray ccommand = current_locale_codec->fromUnicode (command->command ());
+	RData retdata;
+
+	MUTEX_UNLOCK;
 	// running user commands is quite different from all other commands
-	if (command->type () & RCommand::User) {
+	if (ctype & RCommand::User) {
 		// 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).
 
@@ -1091,8 +1099,7 @@
 		R_ReplDLLinit ();		// resets the parse buffer (things might be left over from a previous incomplete parse)
 		bool prev_iteration_was_incomplete = false;
 
-		QByteArray localc = current_locale_codec->fromUnicode (command->command ());		// needed so the string below does not go out of scope
-		current_buffer = localc.data ();
+		current_buffer = ccommand.data ();
 
 		repldll_buffer_transfer_finished = false;
 		Rboolean ok = (Rboolean) 1;	// set to false, if there is a jump during the R_ToplevelExec (i.e.. some sort of error)
@@ -1125,24 +1132,28 @@
 			SEXP exp;
 			PROTECT (exp = runCommandInternalBase (parsed, &error));
 			if (error == NoError) {
-				if (command->type () & RCommand::GetStringVector) {
-					command->datatype = RData::StringVector;
-					command->data = SEXPToStringList (exp, &(command->length));
-				} else if (command->type () & RCommand::GetRealVector) {
-					command->datatype = RData::RealVector;
-					command->data = SEXPToRealArray (exp, &(command->length));
-				} else if (command->type () & RCommand::GetIntVector) {
-					command->datatype = RData::IntVector;
-					command->data = SEXPToIntArray (exp, &(command->length));
-				} else if (command->type () & RCommand::GetStructuredData) {
-					RData *data = SEXPToRData (exp);
-					if (data) command->setData (data);
+				if (ctype & RCommand::GetStringVector) {
+					retdata.datatype = RData::StringVector;
+					retdata.data = SEXPToStringList (exp, &(command->length));
+				} else if (ctype & RCommand::GetRealVector) {
+					retdata.datatype = RData::RealVector;
+					retdata.data = SEXPToRealArray (exp, &(command->length));
+				} else if (ctype & RCommand::GetIntVector) {
+					retdata.datatype = RData::IntVector;
+					retdata.data = SEXPToIntArray (exp, &(command->length));
+				} else if (ctype & RCommand::GetStructuredData) {
+					RData *dummy = SEXPToRData (exp);
+					retdata.setData (*dummy);
+					delete dummy;
 				}
 			}
 			UNPROTECT (1); // exp
 		}
 	}
+	if (!locked || killed) processX11Events ();
+	MUTEX_LOCK;
 
+	command->setData (retdata);
 	// common error/status handling
 	#ifdef RKWARD_DEBUG
 		int dl = DL_WARNING;		// failed application commands are an issue worth reporting, failed user commands are not
@@ -1171,4 +1182,18 @@
 	} else {
 		command->status |= RCommand::WasTried;
 	}
+
+	flushOutput ();
+	if (command->type () & RCommand::DirectToOutput) {
+		QString outp = command->fullOutput();
+
+		if (!outp.isEmpty ()) {
+			// all regular output was sink()ed, i.e. all remaining output is a message/warning/error
+			runDirectCommand (".rk.cat.output (\"<h2>Messages, warnings, or errors:</h2>\\n\")");
+
+			outp.replace ('\\', "\\\\");
+			outp.replace ('"', "\\\"");
+			runDirectCommand ("rk.print.literal (\"" + outp + "\")");
+		}
+	}
 }

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-18 13:12:31 UTC (rev 3131)
+++ branches/2010_10_18_backend_restructuring_branch/rkward/rbackend/rembedinternal.h	2010-10-19 10:37:33 UTC (rev 3132)
@@ -53,10 +53,6 @@
 
 class QStringList;
 class QTextCodec;
-/** This function converts a list of strings to a QStringList (locale aware), and returns the pointer. Needed to keep R and Qt includes separate. The strings can be deleted afterwards. Implementation is in rthread.cpp */
-QString *stringsToStringList (char **strings, int count);
-/** Function to delete an array of Qstring. Does delete [] strings, nothing more. But can not inline this in this class due to conflicting R and Qt includes. Implementation is in rthread.cpp */
-void deleteQStringArray (QString *strings);
 
  /** The main purpose of separating this class from RThread is that R- and Qt-includes don't go together well. Hence this class is Qt-agnostic while
 	RThread is essentially R-agnostic.
@@ -146,11 +142,32 @@
 		return (r_version >= (1000 * major + 10 * minor + revision));
 	}
 
-/** Flags used to classify output. */
-//	static bool output_is_warning;
-/** Flags used to classify output. */
-//	static bool next_output_is_error;
+/** @see lock (), @see unlock ()*/
+	enum LockType {
+		User=1,		/**< locked on user request */
+		Cancel=2,	/**< locked to safely cancel a running command */
+		Startup=4	/**< locked on startup */
+	};
+
+/** Locks the thread. This is called by RInterface, when the currently running command is to be cancelled. It is used to make sure that the
+backend thread does not proceed with further commands, before the main thread takes notice. Also it is called, if the RThread is paused on User request. Further, the thread is initially locked so the main thread can check for some conditions before the backend thread may produce
+more errors/crashes. @see unlock @see RInterface::cancelCommand @see RInterface::pauseProcessing
+ at param reason As there are several reasons to lock the thread, and more than one reason may be in place at a given time, a reason needs to be specified for both lock () and unlock (). Only if all "reasons are unlocked ()", processing continues. */
+	void lock (LockType reason) { locked |= reason; };
+/** Unlocks the thread.  Also the thread may get locked when canceling the currently running command. @see lock */
+	void unlock (LockType reason) { locked -= (locked & reason); };
+/** "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; };
+	bool isKilled () { return killed; };
+
 	QTextCodec *current_locale_codec;
+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;
+/** The internal storage for pauseOutput () */
+	bool output_paused;
 private:
 	int r_version;
 // can't declare this as part of the class, as it would confuse REmbed

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-18 13:12:31 UTC (rev 3131)
+++ branches/2010_10_18_backend_restructuring_branch/rkward/rbackend/rthread.cpp	2010-10-19 10:37:33 UTC (rev 3132)
@@ -170,24 +170,7 @@
 		command->status |= RCommand::Running;	// it is important that this happens before the Mutex is unlocked!
 		RCommandStackModel::getModel ()->itemChange (command);
 
-		MUTEX_UNLOCK;
 		runCommand (command);
-		if (!locked || killed) processX11Events ();
-		MUTEX_LOCK;
-
-		flushOutput ();
-		if (command->type () & RCommand::DirectToOutput) {
-			QString outp = command->fullOutput();
-
-			if (!outp.isEmpty ()) {
-				// all regular output was sink()ed, i.e. all remaining output is a message/warning/error
-				runDirectCommand (".rk.cat.output (\"<h2>Messages, warnings, or errors:</h2>\\n\")");
-
-				outp.replace ('\\', "\\\\");
-				outp.replace ('"', "\\\"");
-				runDirectCommand ("rk.print.literal (\"" + outp + "\")");
-			}
-		}
 	
 		RK_DO (qDebug ("done running command"), RBACKEND, DL_DEBUG);
 		all_current_commands.pop_back();
@@ -232,7 +215,6 @@
 	if (!buf_length) return;
 	waitIfOutputPaused ();
 
-	MUTEX_LOCK;
 	ROutput::ROutputType output_type;
 	if (regular) {
 		output_type = ROutput::Output;
@@ -256,13 +238,13 @@
 		RK_DO (qDebug ("Output buffer has %d characters. Forcing flush", out_buf_len), RBACKEND, DL_DEBUG);
 		flushOutput ();
 	}
-	MUTEX_UNLOCK;
 }
 
 void RThread::flushOutput () {
 	if (!current_output) return;		// avoid creating loads of traces
 	RK_TRACE (RBACKEND);
 
+	MUTEX_LOCK;
 	if (current_command) {
 		for (QList<RCommand*>::const_iterator it = all_current_commands.constBegin (); it != all_current_commands.constEnd(); ++it) {
 			ROutput *output = current_output;
@@ -295,6 +277,7 @@
 		RK_DO (qDebug ("output without receiver'%s'", current_output->output.toLatin1 ().data ()), RBACKEND, DL_WARNING);
 		delete current_output;
 	}
+	MUTEX_UNLOCK;
 
 // forget output
 	current_output = 0;
@@ -390,9 +373,7 @@
 void RThread::handleStandardCallback (RCallbackArgs *args) {
 	RK_TRACE (RBACKEND);
 
-	MUTEX_LOCK;
 	flushOutput ();
-	MUTEX_UNLOCK;
 	args->done = false;
 
 	RKRBackendEvent* event = new RKRBackendEvent (RKRBackendEvent::RCallbackRequest, args);
@@ -456,9 +437,7 @@
 	if (!runDirectCommand ("options (error=quote (.rk.do.error ()))\n")) status |= SinkFail;
 	if (!runDirectCommand ("rk.set.output.html.file (\"" + RKSettingsModuleGeneral::filesPath () + "/rk_out.html\")\n")) status |= SinkFail;
 
-	MUTEX_LOCK;
 	flushOutput ();
-	MUTEX_UNLOCK;
 
 	return status;
 }

Modified: branches/2010_10_18_backend_restructuring_branch/rkward/rbackend/rthread.h
===================================================================
--- branches/2010_10_18_backend_restructuring_branch/rkward/rbackend/rthread.h	2010-10-18 13:12:31 UTC (rev 3131)
+++ branches/2010_10_18_backend_restructuring_branch/rkward/rbackend/rthread.h	2010-10-19 10:37:33 UTC (rev 3132)
@@ -102,22 +102,6 @@
 /** destructor */
 	~RThread ();
 
-/** @see lock (), @see unlock ()*/
-	enum LockType {
-		User=1,		/**< locked on user request */
-		Cancel=2,	/**< locked to safely cancel a running command */
-		Startup=4	/**< locked on startup */
-	};
-/** Locks the thread. This is called by RInterface, when the currently running command is to be cancelled. It is used to make sure that the
-backend thread does not proceed with further commands, before the main thread takes notice. Also it is called, if the RThread is paused on User request. Further, the thread is initially locked so the main thread can check for some conditions before the backend thread may produce
-more errors/crashes. @see unlock @see RInterface::cancelCommand @see RInterface::pauseProcessing
- at param reason As there are several reasons to lock the thread, and more than one reason may be in place at a given time, a reason needs to be specified for both lock () and unlock (). Only if all "reasons are unlocked ()", processing continues. */
-	void lock (LockType reason) { locked |= reason; };
-/** Unlocks the thread.  Also the thread may get locked when canceling the currently running command. @see lock */
-	void unlock (LockType reason) { locked -= (locked & reason); };
-/** "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; };
-	bool isKilled () { return killed; };
 /** Pause output by placing it in a delay loop, until unpaused again */
 	void pauseOutput (bool paused) { output_paused = paused; };
 /** the internal counterpart to pauseOutput () */
@@ -190,10 +174,6 @@
 /** This is the function in which an RCommand actually gets processed. Basically it passes the command to REmbedInteranl::runCommandInternal () and sends RInterface some events about what is currently happening. */
 	void doCommand (RCommand *command);
 	void notifyCommandDone (RCommand *command);
-/** 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;
 /** The internal storage for pauseOutput () */
 	bool output_paused;
 


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