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

tfry at users.sourceforge.net tfry at users.sourceforge.net
Wed Nov 17 13:00:50 UTC 2010


Revision: 3190
          http://rkward.svn.sourceforge.net/rkward/?rev=3190&view=rev
Author:   tfry
Date:     2010-11-17 13:00:50 +0000 (Wed, 17 Nov 2010)

Log Message:
-----------
Finish first draft of split backend implementation. Not quite compilable, yet.

Modified Paths:
--------------
    branches/2010_10_18_backend_restructuring_branch/rkward/rbackend/CMakeLists.txt
    branches/2010_10_18_backend_restructuring_branch/rkward/rbackend/rkrbackend.cpp
    branches/2010_10_18_backend_restructuring_branch/rkward/rbackend/rkrbackendprotocol_backend.cpp
    branches/2010_10_18_backend_restructuring_branch/rkward/rbackend/rkrbackendprotocol_frontend.cpp
    branches/2010_10_18_backend_restructuring_branch/rkward/rbackend/rkrbackendprotocol_shared.cpp
    branches/2010_10_18_backend_restructuring_branch/rkward/rbackend/rkrbackendprotocol_shared.h

Modified: branches/2010_10_18_backend_restructuring_branch/rkward/rbackend/CMakeLists.txt
===================================================================
--- branches/2010_10_18_backend_restructuring_branch/rkward/rbackend/CMakeLists.txt	2010-11-16 00:53:38 UTC (rev 3189)
+++ branches/2010_10_18_backend_restructuring_branch/rkward/rbackend/CMakeLists.txt	2010-11-17 13:00:50 UTC (rev 3190)
@@ -8,29 +8,58 @@
 
 INCLUDE_DIRECTORIES( ${R_INCLUDEDIR} ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_BINARY_DIR} ${KDE4_INCLUDE_DIR} ${QT_INCLUDES}  )
 
-########### next target ###############
+SET (
+	rbackend_shared_SRCS
+	rkrbackendprotocol_shared.cpp
+	rdata.cpp
+)
 
-SET(
-	rbackend_STAT_SRCS
+SET (
+	rbackend_backend_SRCS
 	rkrbackend.cpp
-	rinterface.cpp
-	rcommand.cpp
-	rcommandreceiver.cpp
-	rcommandstack.cpp
-	rdata.cpp
 	rkpthreadsupport.cpp
 	rksignalsupport.cpp
 	rklocalesupport.cpp
 	rkrsupport.cpp
 	rkstructuregetter.cpp
 	rkrbackendprotocol_backend.cpp
+)
+
+SET (
+	rbackend_frontend_SRCS
+	rinterface.cpp
+	rcommand.cpp
+	rcommandreceiver.cpp
+	rcommandstack.cpp
 	rkrbackendprotocol_frontend.cpp
-	rkrbackendprotocol_shared.cpp
 )
 
+#SET(RBACKEND_SPLIT 1)
+IF(RBACKEND_SPLIT)
+	SET (
+		rbackend_STAT_SRCS
+		${rbackend_frontend_SRCS}
+		${rbackend_shared_SRCS}
+	)
+	QT4_AUTOMOC(${rbackend_STAT_SRCS})
+	ADD_LIBRARY(rbackend STATIC ${rbackend_STAT_SRCS})
+	TARGET_LINK_LIBRARIES(rbackend ${CMAKE_THREAD_LIBS_INIT})
 
-QT4_AUTOMOC(${rbackend_STAT_SRCS})
+	QT4_AUTOMOC(${rbackend_backend_SRCS})
+	ADD_DEFINITIONS (-DRKWARD_SPLIT_PROCESS)
+	KDE4_ADD_EXECUTABLE(rkward.rbackend ${rbackend_backend_SRCS} ${rbackend_shared_SRCS})
+	TARGET_LINK_LIBRARIES(rkward.rbackend ${R_USED_LIBS} ${CMAKE_THREAD_LIBS_INIT})
+	LINK_DIRECTORIES(${R_SHAREDLIBDIR})
+ELSE(RBACKEND_SPLIT)
+	SET (
+		rbackend_STAT_SRCS
+		${rbackend_frontend_SRCS}
+		${rbackend_shared_SRCS}
+		${rbackend_backend_SRCS}
+	)
 
-ADD_LIBRARY(rbackend STATIC ${rbackend_STAT_SRCS})
-TARGET_LINK_LIBRARIES(rbackend ${R_USED_LIBS} ${CMAKE_THREAD_LIBS_INIT})
-LINK_DIRECTORIES(${R_SHAREDLIBDIR})
+	QT4_AUTOMOC(${rbackend_STAT_SRCS})
+	ADD_LIBRARY(rbackend STATIC ${rbackend_STAT_SRCS})
+	TARGET_LINK_LIBRARIES(rbackend ${R_USED_LIBS} ${CMAKE_THREAD_LIBS_INIT})
+	LINK_DIRECTORIES(${R_SHAREDLIBDIR})
+ENDIF(RBACKEND_SPLIT)

Modified: branches/2010_10_18_backend_restructuring_branch/rkward/rbackend/rkrbackend.cpp
===================================================================
--- branches/2010_10_18_backend_restructuring_branch/rkward/rbackend/rkrbackend.cpp	2010-11-16 00:53:38 UTC (rev 3189)
+++ branches/2010_10_18_backend_restructuring_branch/rkward/rbackend/rkrbackend.cpp	2010-11-17 13:00:50 UTC (rev 3190)
@@ -88,7 +88,11 @@
 
 void RK_scheduleIntr () {
 	RKRBackend::repl_status.interrupted = true;
+#ifdef Q_WS_WIN
+	UserBreak = 1;
+#else
 	RKSignalSupport::callOldSigIntHandler ();
+#endif
 }
 
 void RK_doIntr () {

Modified: branches/2010_10_18_backend_restructuring_branch/rkward/rbackend/rkrbackendprotocol_backend.cpp
===================================================================
--- branches/2010_10_18_backend_restructuring_branch/rkward/rbackend/rkrbackendprotocol_backend.cpp	2010-11-16 00:53:38 UTC (rev 3189)
+++ branches/2010_10_18_backend_restructuring_branch/rkward/rbackend/rkrbackendprotocol_backend.cpp	2010-11-17 13:00:50 UTC (rev 3190)
@@ -133,7 +133,7 @@
 
 			// send request
 			QByteArray buffer = RKRBackendSerializer::serialize (*request);
-			connection.write (QString (buffer.length () + 1).local8Bit ().data () + "\n");
+			connection.write (QString::number (buffer.length ()).local8Bit ().data () + "\n");
 			connection.write (buffer);
 			while (connection.bytesToWrite ()) {
 				if (!connection.waitForBytesWritten ()) handleTransmitError ("Could not connect: %s");
@@ -210,7 +210,7 @@
 				}
 
 				receive_buffer.append (connection.readAll (expected_length - receive_buffer.length ()));
-				if (receive_buffer.length () >= expected_length () return receive_buffer;
+				if (receive_buffer.length () >= expected_length) return receive_buffer;
 			}
 		}
 

Modified: branches/2010_10_18_backend_restructuring_branch/rkward/rbackend/rkrbackendprotocol_frontend.cpp
===================================================================
--- branches/2010_10_18_backend_restructuring_branch/rkward/rbackend/rkrbackendprotocol_frontend.cpp	2010-11-16 00:53:38 UTC (rev 3189)
+++ branches/2010_10_18_backend_restructuring_branch/rkward/rbackend/rkrbackendprotocol_frontend.cpp	2010-11-17 13:00:50 UTC (rev 3190)
@@ -28,12 +28,13 @@
 #	include <QLocalServer>
 #	include <QLocalSocket>
 #	include <QProcess>
+#	include <QCoreApplication>
 #endif
 
 #include "../debug.h"
 
 #ifndef RKWARD_THREADED
-	class RKFrontendTransmitter : public QThread, public QObject, public RKROutputBuffer {
+	class RKFrontendTransmitter : public QThread, public RKROutputBuffer {
 		Q_OBJECT
 		public:
 			RKFrontendTransmitter () {
@@ -47,11 +48,14 @@
 				// start backend
 				QStringList args;
 				args.append ("--debug-level " + QString::number (RK_Debug_Level));
-				args.append ("--server-name " + server.fullName ());
+				args.append ("--server-name " + server.fullServerName ());
 				backend.setProcessChannelMode (QProcess::MergedChannels);	// at least for now. Seems difficult to get interleaving right, without this.
 				connect (&backend, SIGNAL (readyReadStandardOutput ()), this, SLOT (newProcessOutput ()));
 				connect (&backend, SIGNAL (finished (int, QProcess::ExitStatus)), this, SLOT (backendExit (int, QProcess::ExitStatus)));
 				backend.start ("rkward_backend", args, QIODevice::ReadOnly);
+
+				RK_ASSERT (_instance == 0);
+				_instance = this;
 			};
 
 			~RKFrontendTransmitter () {
@@ -61,6 +65,8 @@
 				delete connection;
 			};
 
+			static RKFrontendTransmitter* instance () { return _instance; };
+
 			void run () {
 				RK_ASSERT (connection);
 
@@ -70,7 +76,12 @@
 				backend.moveToThread (this);
 
 				exec ();
-			}
+			};
+
+			bool doMSleep (int delay) {
+				msleep (delay);
+				return true;
+			};
 		private slots:
 			void connectAndEnterLoop () {
 				RK_TRACE (RBACKEND);
@@ -83,31 +94,92 @@
 			};
 
 			void newProcessOutput () {
-				#error
+				RK_TRACE (RBACKEND);
+#warning TODO: fix interleaving
+				QString output = QString::fromLocal8Bit (backend.readAll ());
+				handleOutput (output, output.size (), ROutput::Warning);
 			};
+
 			void newConnectionData () {
-				#error
+				RK_TRACE (RBACKEND);
+
+				if (!connection->canReadLine ()) return;
+
+				QString line = QString::fromLocal8Bit (connection->readLine ());
+				bool ok;
+				int expected_length = line.toInt (&ok);
+				if (!ok) handleTransmitError ("Protocol header error. Last connection error was: " + connection->errorString ());
+
+				QByteArray receive_buffer;
+				while (receive_buffer.length () < expected_length) {
+					if (connection->bytesAvailable ()) {
+						receive_buffer.append (connection->read (expected_length - receive_buffer.length ()));
+					} else {
+						connection->waitForReadyRead (1000);
+						if (!connection->isOpen ()) {
+							handleTransmitError ("Connection closed unexepctedly. Last error: " + connection->errorString ());
+							return;
+						}
+					}
+				}
+
+				RBackendRequest *req = RKRBackendSerializer::unserialize (receive_buffer);
+				RKRBackendEvent* event = new RKRBackendEvent (req);
+				qApp->postEvent (RKRBackendProtocolFrontend::instance ()->parent (), event);
 			};
+
 			void backendExit (int exitcode, QProcess::ExitStatus exitstatus) {
-				#error
+				RK_TRACE (RBACKEND);
+
+				RBackendRequest* req = new RBackendRequest (false, RBackendRequest::BackendExit);
+				RKRBackendEvent* event = new RKRBackendEvent (req);
+				qApp->postEvent (RKRBackendProtocolFrontend::instance ()->parent (), event);
 			};
+
 			void connectionStateChanged (QLocalSocket::LocalSocketState state) {
 				if (state != QLocalSocket::UnconnectedState) return;		// only interested in connection failure
-				#error
+				RK_TRACE (RBACKEND);
 
+				RBackendRequest* req = new RBackendRequest (false, RBackendRequest::BackendExit);
+				RKRBackendEvent* event = new RKRBackendEvent (req);
+				qApp->postEvent (RKRBackendProtocolFrontend::instance ()->parent (), event);
 			};
+
+			void writeRequest (RBackendRequest *request) {
+				RK_TRACE (RBACKEND);
+
+				QByteArray buffer = RKRBackendSerializer::serialize (*request);
+				connection->write (QString::number (buffer.length ()).toLocal8Bit () + "\n");
+				connection->write (buffer);
+				delete request;
+			};
+
+			void customEvent (QEvent *e) {
+				if (((int) e->type ()) == ((int) RKRBackendEvent::RKWardEvent)) {
+					RKRBackendEvent *ev = static_cast<RKRBackendEvent*> (e);
+					writeRequest (ev->data ());
+				} else {
+					RK_ASSERT (false);
+					return;
+				}
+			};
 		private:
 			void handleTransmitError (const QString &message) {
 				RK_TRACE (RBACKEND);
 				#warning: Show those errors to the user!
 
 				qDebug ("%s", qPrintable (message));
-			}
+			};
 
+			int current_request_length;
 			QProcess backend;
 			QLocalServer server;
 			QLocalSocket* connection;
+			static RKFrontendTransmitter *_instance;
 	};
+	RKFrontendTransmitter* RKFrontendTransmitter::_instance = 0;
+
+	#include "rkrbackendprotocol_frontend.moc"
 #endif
 
 RKRBackendProtocolFrontend* RKRBackendProtocolFrontend::_instance = 0;
@@ -123,7 +195,11 @@
 	RK_TRACE (RBACKEND);
 
 	terminateBackend ();
+#ifdef RKWARD_THREADED
 	delete RKRBackendProtocolBackend::instance ();
+#else
+	delete RKFrontendTransmitter::instance ();
+#endif
 }
 
 void RKRBackendProtocolFrontend::setupBackend (QVariantMap backend_params) {
@@ -132,20 +208,22 @@
 #ifdef RKWARD_THREADED
 	new RKRBackendProtocolBackend ();
 #else
-#error
+	new RKFrontendTransmitter ();
 #endif
 }
 
 void RKRBackendProtocolFrontend::setRequestCompleted (RBackendRequest *request) {
 	RK_TRACE (RBACKEND);
 
-#ifdef RKWARD_THREADED
 	bool sync = request->synchronous;
 	request->completed ();
-	if (sync) QThread::yieldCurrentThread ();
-#else
-#error
+	if (!sync) return;
+
+#ifndef RKWARD_THREADED
+	RKRBackendEvent* ev = new RKRBackendEvent (request);
+	qApp->postEvent (RKFrontendTransmitter::instance (), ev);
 #endif
+	QThread::yieldCurrentThread ();
 }
 
 ROutputList RKRBackendProtocolFrontend::flushOutput (bool force) {
@@ -154,7 +232,7 @@
 #ifdef RKWARD_THREADED
 	return (RKRBackend::this_pointer->flushOutput (force));
 #else
-#error
+	return RKFrontendTransmitter::instance ()->flushOutput (force);
 #endif
 }
 
@@ -165,8 +243,8 @@
 	RK_ASSERT (!RKRBackendProtocolBackend::inRThread ());
 	RKRBackendProtocolBackend::interruptProcessing ();
 #else
-	kill (SIGUSR1, pid_of_it);
-#error
+//	kill (SIGUSR1, pid_of_it);
+#warning wont't work on windows!
 #endif
 }
 
@@ -176,8 +254,8 @@
 #ifdef RKWARD_THREADED
 	RKRBackend::this_pointer->kill ();
 #else
-	kill (SIGUSR2, pid_of_it);
-#error
+//	kill (SIGUSR2, pid_of_it);
+#warning wont't work on windows!
 #endif
 }
 
@@ -192,3 +270,4 @@
 	}
 }
 #endif
+

Modified: branches/2010_10_18_backend_restructuring_branch/rkward/rbackend/rkrbackendprotocol_shared.cpp
===================================================================
--- branches/2010_10_18_backend_restructuring_branch/rkward/rbackend/rkrbackendprotocol_shared.cpp	2010-11-16 00:53:38 UTC (rev 3189)
+++ branches/2010_10_18_backend_restructuring_branch/rkward/rbackend/rkrbackendprotocol_shared.cpp	2010-11-17 13:00:50 UTC (rev 3190)
@@ -97,7 +97,7 @@
 		}
 		if (request.output) {
 			RK_ASSERT (request.type == RBackendRequest::Output);
-			sream << true;
+			stream << true;
 			serializeOutput (*(request.output), stream);
 		} else {
 			stream << false;
@@ -111,16 +111,20 @@
 		RK_TRACE (RBACKEND);
 
 		QDataStream stream (buffer);
-		RBackendRequest *request = new RBackendRequest (false, RBackendRequest::OtherType);		// will be overwritten
+		RBackendRequest *request = new RBackendRequest (false, RBackendRequest::OtherRequest);		// will be overwritten
 
-		stream >> (qint8) (RBackendRequest::RCallbackType) (*request.type);
-		stream >> (*request.synchronous);
-		stream >> (*request.done);
-		bool has_command << stream;
-		if (has_command) (*request.command) = unserializeProxy (stream);
-		bool has_output << stream;
-		if (has_output) (*request.output) = unserializeProxy (stream);
-		(*request.params) << stream;
+		bool dummyb;
+		qint8 dummy8;
+		stream >> dummy8;
+		request->type = (RBackendRequest::RCallbackType) dummy8;
+		stream >> request->synchronous;
+		stream >> dummyb;
+		request->done = dummyb;
+		stream >> dummyb;
+		if (dummyb) request->command = unserializeProxy (stream);
+		stream >> dummyb;
+		if (dummyb) request->output = unserializeOutput (stream);
+		stream >> request->params;
 
 		return request;
 	}
@@ -130,24 +134,27 @@
 
 		stream << (qint32) list.size ();
 		for (qint32 i = 0; i < list.size (); ++i) {
-			stream << (qint8) list[i].type;
-			stream << list[i].output;
+			stream << (qint8) list[i]->type;
+			stream << list[i]->output;
 		}
 	}
 
-	*ROutputList RKRBackendSerializer::unserializeOutput (QDataStream &stream) {
+	ROutputList* RKRBackendSerializer::unserializeOutput (QDataStream &stream) {
 		RK_TRACE (RBACKEND);
 
 		ROutputList *ret = new ROutputList ();
-		qint32 len << stream;
+		qint32 len;
+		stream >> len;
 #if QT_VERSION >= 0x040700
 		ret->reserve (len);
 #endif
 
 		for (qint32 i = 0; i < len; ++i) {
-			ROutput out;
-			out.type << (ROutput::ROutputType) (qint8) stream;
-			out.output << stream;
+			ROutput* out = new ROutput;
+			qint8 dummy8;
+			stream >> dummy8;
+			out->type = (ROutput::ROutputType) dummy8;
+			stream >> out->output;
 			ret->append (out);
 		}
 
@@ -157,7 +164,7 @@
 	void RKRBackendSerializer::serializeData (const RData &data, QDataStream &stream) {
 		RK_TRACE (RBACKEND);
 
-		RDataType type = data.getDataType ();
+		RData::RDataType type = data.getDataType ();
 		stream << (qint8) type;
 		if (type == RData::IntVector) stream << data.getIntVector ();
 		else if (type == RData::StringVector) stream << data.getStringVector ();
@@ -167,7 +174,7 @@
 			qint32 len = list.size ();
 			stream << len;
 			for (qint32 i = 0; i < list.size (); ++i) {
-				serializeData (*(list[i]));
+				serializeData (*(list[i]), stream);
 			}
 		} else {
 			RK_ASSERT (type == RData::NoData);
@@ -178,30 +185,38 @@
 		RK_TRACE (RBACKEND);
 
 		RData* ret = new RData;
-		RDataType type;
-		stream >> (qint8) (RDataType) type;
+		RData::RDataType type;
+		qint8 dummy8;
+		stream >> dummy8;
+		type = (RData::RDataType) dummy8;
 		if (type == RData::IntVector) {
-			RData::IntStorage data << stream;
+			RData::IntStorage data;
+			stream >> data;
 			ret->setData (data);
 		} else if (type == RData::StringVector) {
-			RData::StringStorage data << steam;
+			RData::StringStorage data;
+			stream >> data;
 			ret->setData (data);
 		} else if (type == RData::RealVector) {
-			RData::RealStorage data << stream;
+			RData::RealStorage data;
+			stream >> data;;
 			ret->setData (data);
 		} else if (type == RData::StructureVector) {
 			RData::RDataStorage data;
-			qint32 len << stream;
+			qint32 len;
+			stream >> len;
 #if QT_VERSION >= 0x040700
 			data.reserve (len);
 #endif
-			for (qint32 i = 0; i < lne; ++i) {
+			for (qint32 i = 0; i < len; ++i) {
 				data.append (unserializeData (stream));
 			}
 			ret->setData (data);
 		} else {
 			RK_ASSERT (type == RData::NoData);
 		}
+
+		return ret;
 	}
 
 	void RKRBackendSerializer::serializeProxy (const RCommandProxy &proxy, QDataStream &stream) {
@@ -215,19 +230,25 @@
 		serializeData (proxy, stream);
 	}
 
-	*RCommandProxy RKRBackendSerializer::unserializeProxy (QDataStream &stream) {
+	RCommandProxy* RKRBackendSerializer::unserializeProxy (QDataStream &stream) {
 		RK_TRACE (RBACKEND);
 
-		QString command << stream;
-		qint32 type << stream;
+		QString command;
+		stream >> command;
+		qint32 type;
+		stream >> type;
 		RCommandProxy* ret = new RCommandProxy (command, type);
-		proxy->id << (qint32) stream;
-		proxy->status << (qint32) stream;
+		qint32 dummy32;
+		stream >> dummy32;
+		ret->id = dummy32;
+		stream >> dummy32;
+		ret->status = dummy32;
 
 		RData *data = unserializeData (stream);
-		proxy->swallowData (*data);
+		ret->swallowData (*data);
 		delete (data);
-		return proxy;
+
+		return ret;
 	}
 #endif
 

Modified: branches/2010_10_18_backend_restructuring_branch/rkward/rbackend/rkrbackendprotocol_shared.h
===================================================================
--- branches/2010_10_18_backend_restructuring_branch/rkward/rbackend/rkrbackendprotocol_shared.h	2010-11-16 00:53:38 UTC (rev 3189)
+++ branches/2010_10_18_backend_restructuring_branch/rkward/rbackend/rkrbackendprotocol_shared.h	2010-11-17 13:00:50 UTC (rev 3190)
@@ -92,28 +92,27 @@
 	RBackendRequest *duplicate ();
 };
 
-#ifdef RKWARD_THREADED
-#	include <QEvent>
-	/** Simple event class to relay information from the RKRBackend to the main thread. This is basically like QCustomEvent in Qt3*/
-	class RKRBackendEvent : public QEvent {
-	public:
-		enum EventType {
-			RKWardEvent = QEvent::User + 1
-		};
-		RKRBackendEvent (RBackendRequest* data=0) : QEvent ((QEvent::Type) RKWardEvent) { _data = data; };
-		RKRBackendEvent ();
-
-		RBackendRequest* data () { return _data; };
-	private:
-		RBackendRequest* _data;
+#include <QEvent>
+/** Simple event class to relay information from the RKRBackend to the main thread. This is basically like QCustomEvent in Qt3*/
+class RKRBackendEvent : public QEvent {
+public:
+	enum EventType {
+		RKWardEvent = QEvent::User + 1
 	};
-#endif
+	RKRBackendEvent (RBackendRequest* data=0) : QEvent ((QEvent::Type) RKWardEvent) { _data = data; };
+	RKRBackendEvent ();
 
+	RBackendRequest* data () { return _data; };
+private:
+	RBackendRequest* _data;
+};
+
 /** This is a reduced version of an RCommand, intended for use in the R backend. */
 class RCommandProxy : public RData {
 protected:
 friend class RCommand;
 friend class RKRBackend;
+friend class RKRBackendSerializer;
 friend class RBackendRequest;
 	RCommandProxy ();
 	~RCommandProxy ();


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