[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