# # # patch "src/monotone/MonotoneThread.cpp" # from [aa371bf1e9c55b57371417d36127fb1723526c7b] # to [c14d137aa0b5fe493aff2945ed43e40080e92a0d] # # patch "src/monotone/MonotoneThread.h" # from [137aa57d261f140e9e824d758fe89a24ad1c88d0] # to [f8d8df1ec8f103893babbaf00a411e89fb7d374c] # ============================================================ --- src/monotone/MonotoneThread.cpp aa371bf1e9c55b57371417d36127fb1723526c7b +++ src/monotone/MonotoneThread.cpp c14d137aa0b5fe493aff2945ed43e40080e92a0d @@ -67,7 +67,7 @@ void MonotoneTask::init(const ByteArrayL options = opts; returnCode = -1; finished = false; - + static bool initialized = false; if (!initialized) { @@ -90,12 +90,12 @@ QByteArray MonotoneTask::getEncodedInput { QByteArray commandLine; QTextStream streamCmdLine(&commandLine); - + if (options.size() > 0) { // currently mtn can only understand key => value option pairs I(options.size() % 2 == 0); - + streamCmdLine << "o"; for (int i=0, c=options.size(); i 0); - + streamCmdLine << "l"; for (int i=0, c=arguments.size(); isetWorkingDirectory(workspacePath); } - + L(QString("starting %1 %2").arg(mtnBinary).arg(args.join(" "))); process->start(mtnBinary, args); - + if (!process->waitForStarted()) { emit aborted(threadNumber, process->error(), @@ -175,16 +175,16 @@ void MonotoneThread::run() cleanup(process); return; } - + emit started(threadNumber); - + QTextStream streamProcess(process); - + QByteArray buffer; QByteArray output; - + bool processingTask = false; - + while (!doAbort) { if (process->state() != QProcess::Running) @@ -195,9 +195,9 @@ void MonotoneThread::run() cleanup(process); return; } - + if (queue.size() == 0) continue; - + if (!processingTask) { MonotoneTask task = queue.head(); @@ -205,7 +205,7 @@ void MonotoneThread::run() streamProcess.flush(); processingTask = true; } - + if (!process->waitForReadyRead(-1)) { emit aborted(threadNumber, process->error(), @@ -214,21 +214,21 @@ void MonotoneThread::run() cleanup(process); return; } - + // FIXME: what about stderr output here? buffer.append(process->readAllStandardOutput()); StdioParser parser(buffer); - + // if the chunk is not yet complete, try again later if (!parser.parse()) { continue; } - + buffer = parser.getLeftBytes(); output.append(parser.getPayload()); int returnCode = parser.getErrorCode(); - + // TODO: support for other chunk types here? if (parser.getChunkType() == 'm') { @@ -241,7 +241,7 @@ void MonotoneThread::run() task.setFinished(); processingTask = false; output.clear(); - + emit taskFinished(task); } cleanup(process); @@ -250,9 +250,9 @@ void MonotoneThread::cleanup(QProcess * void MonotoneThread::cleanup(QProcess * proc) { QMutexLocker locker(&lock); - + doAbort = true; - + if (queue.size() > 0) { foreach (MonotoneTask task, queue) @@ -261,7 +261,7 @@ void MonotoneThread::cleanup(QProcess * } queue.clear(); } - + // close the pipes proc->close(); // send SIGTERM @@ -278,13 +278,6 @@ void MonotoneThread::abort() // FIXME: I think we need to care somehow if we pass // threads around - i.e. use shared ptrs or something -MonotoneThread * MonotoneThreadManager::getThread(const QString & workspace) -{ - QString normalizedWorkspace = normalizeWorkspacePath(workspace); - QString databaseFilePath = getDatabaseFilePath(normalizedWorkspace); - return getThread(databaseFilePath, normalizedWorkspace); -} - MonotoneThread * MonotoneThreadManager::getThread( const QString & database, const QString & workspace = QString()) { @@ -292,11 +285,11 @@ MonotoneThread * MonotoneThreadManager:: { // TODO: connect to started(int) and aborted(int, ...) here // and wait for started() - MonotoneThread * thread = + MonotoneThread * thread = new MonotoneThread(threadNumber++, mtnPath, database, workspace); threadMap.insert(database, thread); } - + // TODO: we may want to add support for multiple threads for one // and the same database here in the future... MonotoneThread * thread = threadMap.value(database); @@ -332,12 +325,12 @@ QString MonotoneThreadManager::normalize } } while (!tempDir.isRoot() && tempDir.cdUp()); - + if (!found) { throw GuitoneException(tr("could not find _MTN directory")); } - + return normalizedWorkspace; } @@ -349,21 +342,21 @@ QString MonotoneThreadManager::getDataba { return workspaceMap.value(workspace); } - + QFile optionsFile(workspace + "/_MTN/options"); if (!optionsFile.open(QIODevice::ReadOnly | QIODevice::Text)) { throw GuitoneException(tr("could not open _MTN/options for reading")); } - + QByteArray contents = optionsFile.readAll(); optionsFile.close(); - + if (contents.size() == 0) { throw GuitoneException(tr("file _MTN/options is empty")); } - + BasicIOParser parser(QString::fromUtf8(contents)); if (!parser.parse()) { @@ -372,7 +365,7 @@ QString MonotoneThreadManager::getDataba StanzaList stanzas = parser.getStanzas(); I(stanzas.size() == 1); Stanza st = stanzas.at(0); - + QString databaseFilePath; foreach (StanzaEntry entry, st) { @@ -383,12 +376,12 @@ QString MonotoneThreadManager::getDataba break; } } - + if (databaseFilePath.isEmpty()) { throw GuitoneException(tr("could not find database for workspace")); } - + // remember what we've just found for later requests workspaceMap.insert(workspace, databaseFilePath); return databaseFilePath; ============================================================ --- src/monotone/MonotoneThread.h 137aa57d261f140e9e824d758fe89a24ad1c88d0 +++ src/monotone/MonotoneThread.h f8d8df1ec8f103893babbaf00a411e89fb7d374c @@ -38,13 +38,13 @@ public: MonotoneTask(const QStringList &, const QStringList &); MonotoneTask(const ByteArrayList &); MonotoneTask(const ByteArrayList &, const ByteArrayList &); - + void setCommandNumber(int num) { commandNumber = num; } void setThreadNumber(int num) { threadNumber = num; } void setOutput(const QByteArray & out) { output = out; } void setReturnCode(int code) { returnCode = code; } void setFinished() { finished = true; } - + QByteArray getEncodedInput() const; ByteArrayList getArguments() const { return arguments; } ByteArrayList getOptions() const { return options; } @@ -54,7 +54,7 @@ public: int getCommandNumber() const { return commandNumber; } int getThreadNumber() const { return threadNumber; } bool isFinished() const { return finished; } - + private: void init(const ByteArrayList &, const ByteArrayList &); ByteArrayList stringToByteArrayList(const QStringList &); @@ -63,7 +63,7 @@ private: int commandNumber; int threadNumber; bool finished; - + ByteArrayList arguments; ByteArrayList options; QByteArray output; @@ -80,7 +80,7 @@ public: inline QString getWorkspacePath() const { return workspacePath; } inline int getQueueCount() const { return queue.size(); } inline int getThreadNumber() const { return threadNumber; } - + protected: void run(); @@ -96,9 +96,9 @@ private: private: void cleanup(QProcess *); - + static const int StdioBufferSize; - + bool doAbort; int commandNumber; int threadNumber; @@ -116,19 +116,18 @@ public: public: MonotoneThreadManager(const QString & p) : mtnPath(p), threadNumber(0) {}; ~MonotoneThreadManager() {}; - + inline void setMtnBinaryPath(const QString & path) { mtnPath = path; } - MonotoneThread * getThread(const QString &); + + QString getDatabaseFilePath(const QString &); + QString normalizeWorkspacePath(const QString &); MonotoneThread * getThread(const QString &, const QString &); - + private: QMap threadMap; QMap workspaceMap; QString mtnPath; int threadNumber; - - QString getDatabaseFilePath(const QString &); - QString normalizeWorkspacePath(const QString &); private slots: void aborted(int, QProcess::ProcessError, const QString &);