# # # patch "guitone/src/monotone/Monotone.cpp" # from [e81b5636581b65fa974485a3fefe72ff42a0f921] # to [88bc4ff50da75cffd8f07c736684f0623f7b9823] # # patch "guitone/src/monotone/Monotone.h" # from [239d5ba68bde0ac80b44da173ac9d0ea005bb2a3] # to [f459bf030a300af821f5dd4bcce361eb50cd3d25] # ============================================================ --- guitone/src/monotone/Monotone.cpp e81b5636581b65fa974485a3fefe72ff42a0f921 +++ guitone/src/monotone/Monotone.cpp 88bc4ff50da75cffd8f07c736684f0623f7b9823 @@ -17,7 +17,65 @@ * Free Software Foundation, Inc., * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ - + +// +// There are two ways to query data from the running monotone process: +// asynchronous and synchronous. Asynchronous queries are mainly useful for +// commands which can take a variable time to finish (e.g. inventory), while +// synchronous queries are good for constant time queries (get_base_revision_id +// and friends), whose data are actually prerequisites for more complex commands. +// +// In any of both cases a monotone process needs to be started beforehand by +// running setup() which takes a workspace directory as argument. +// +// The basic code flow is then the following: +// +// Asynchronous Synchronous +// ------------ ----------- +// +// triggerCommand() executeCommand() +// | | +// V V +// newCommandSetup() newCommandSetup() +// | | +// V V +// writeStdin() writeStdin() +// | | +// ... V +// (wait for signalling) readAndParseStdout() +// ... | +// | V +// V caller can immediately +// readAndProcessCommand() retrieve the queried output +// | +// V +// readAndParseStdout() +// | +// V +// signal caller that +// command finished +// +// In the synchronous case there also happens a waiting for output, however this +// is done with the SignalWaiter class which triggers the main event loop until +// data become available. +// +// Since there is only one instance of the monotone process running at a time, +// pending commands need to be queued somehow in order to avoid confusion +// (data are sent to the wrong caller, etc.) - this is done in newCommandSetup(). +// A QMutex hinders a second parallel request on entering the wait loop of a +// previous command. +// +// If a command is about to be executed, its data are written to STDIN of the +// running process, whilst encoded into stdio format. +// As soon as data arrive, they're read and parsed in readAndParseStdout(). +// It might be possible that not all data are written at once to STDOUT of the +// process, so we're careful and just wait for more output if we can't parse +// it at the right time. +// +// After parsing the output is made available to the calling process by +// getOutput(). +// + #include "Monotone.h" #include "../model/AutomateCommand.h" #include "../util/Settings.h" @@ -29,9 +87,9 @@ Monotone* Monotone::instance = 0; Monotone* Monotone::instance = 0; -const QString Monotone::RequiredVersion = "0.29"; -// 50KB buffer size +const QString Monotone::RequiredVersion = "0.32"; const int Monotone::StdioBufferSize = 50 * 1024 * 1024; +const int Monotone::TimeoutWaitForOtherCommand = 5000; // milliseconds Monotone::Monotone(QObject * parent) : QObject(parent), process(0) { @@ -133,8 +191,7 @@ bool Monotone::newCommandSetup() mutex.lock(); timeout = false; - // FIXME: make the timeout span configurable - QTimer::singleShot(5000, this, SLOT(timedOut())); + QTimer::singleShot(TimeoutWaitForOtherCommand, this, SLOT(timedOut())); while(isProcessingData && !timeout) QCoreApplication::processEvents(); if (timeout) @@ -220,14 +277,8 @@ bool Monotone::triggerCommand(AutomateCo return true; } -// TODO: we might want to implement a Queue for that some time so commands -// are executed sequentially in the order they've come in and don't need to -// wait for each other void Monotone::writeStdin(const QStringList & command, const QStringList & options) { - // wait until the process has been started up if it is not already - // running. Notice that if waitForStartup times out after 15 seconds - // the error handler is called and the program is terminated! commandLine = ""; if (options.size() > 0) @@ -261,8 +312,6 @@ void Monotone::writeStdin(const QStringL qDebug("Writing command %s", qPrintable(commandLine)); - // QProcess in QT4 doesn't have a writeToStdin(). - // So we need the following QTextStream QTextStream streamStdIn(process); streamStdIn << commandLine; } ============================================================ --- guitone/src/monotone/Monotone.h 239d5ba68bde0ac80b44da173ac9d0ea005bb2a3 +++ guitone/src/monotone/Monotone.h f459bf030a300af821f5dd4bcce361eb50cd3d25 @@ -35,6 +35,7 @@ class Monotone : public QObject static bool checkBinaryVersion(const QString &); static const QString RequiredVersion; static const int StdioBufferSize; + static const int TimeoutWaitForOtherCommand; void setup(QDir*); virtual ~Monotone();