# # # patch "MonotoneThread.cpp" # from [4f8b7ce09075fb1f46e046f7fe4bea66d489a1eb] # to [0363d27105d7e6e21dfc57795daf3653530cd7b5] # # patch "MonotoneThread.h" # from [b8475556bd836dc28167ac42a37a10a6c87aef80] # to [7e2fa231c46b06ccea13cf85d92a035f7cc5de08] # # patch "test.cpp" # from [581c6d829be0253d7383a62eecf94effdb74b08a] # to [2e56517014b8cb86c7b786f1f75c13203c1cc46a] # # patch "test.h" # from [076086d24821d8abca53acb9e312a15e6b201727] # to [5701722dc2d6773d4e0f514d6e7823dcd605e6dc] # ============================================================ --- MonotoneThread.cpp 4f8b7ce09075fb1f46e046f7fe4bea66d489a1eb +++ MonotoneThread.cpp 0363d27105d7e6e21dfc57795daf3653530cd7b5 @@ -107,45 +107,43 @@ MonotoneThread::MonotoneThread(const QSt const int MonotoneThread::StdioBufferSize = 50 * 1024 * 1024; MonotoneThread::MonotoneThread(const QString & mtn, const QString & database, const QString & workspace) - : QThread(), doAbort(false) + : QThread(), doAbort(false), mtnBinary(mtn), databasePath(database), workspacePath(workspace) { qRegisterMetaType("MonotoneTask"); - - process = new QProcess(); - - QStringList args; - args << "automate"; - args << "stdio"; - args << QString("--automate-stdio-size=%1").arg(StdioBufferSize); - args << "--db" << database; - - if (!workspace.isEmpty()) - { - process->setWorkingDirectory(workspace); - } - - qDebug(QString("starting %1 %2").arg(mtn).arg(args.join(" ")).toLatin1()); - process->start(mtn, args); } -MonotoneThread::~MonotoneThread() -{ - cleanup(); - delete process; -} +MonotoneThread::~MonotoneThread() {} void MonotoneThread::enqueueTask(const MonotoneTask & task) { + if (doAbort) return; + QMutexLocker locker(&lock); queue.enqueue(task); } void MonotoneThread::run() { + QObject threadParent; + QProcess * process = new QProcess(&threadParent); + + QStringList args; + args << "automate"; + args << "stdio"; + args << QString("--automate-stdio-size=%1").arg(StdioBufferSize); + args << "--db" << databasePath; + + if (!workspacePath.isEmpty()) + { + process->setWorkingDirectory(workspacePath); + } + + qDebug(QString("starting %1 %2").arg(mtnBinary).arg(args.join(" ")).toLatin1()); + process->start(mtnBinary, args); + if (!process->waitForStarted()) { - qDebug("not started"); - emit error(processErrorToString()); - cleanup(); + emit aborted(processErrorToString(process)); + cleanup(process); return; } @@ -164,14 +162,14 @@ void MonotoneThread::run() QString err; if (process->exitStatus() == QProcess::CrashExit) { - err = processErrorToString(); + err = processErrorToString(process); } // read anything we get from stderr err.append(QString::fromUtf8(process->readAllStandardError())); - emit error(err); - cleanup(); + emit aborted(err); + cleanup(process); return; } @@ -193,10 +191,10 @@ void MonotoneThread::run() if (!process->waitForReadyRead(-1)) { qDebug("timeout waiting for ready read"); - QString err(processErrorToString()); + QString err(processErrorToString(process)); err.append(QString::fromUtf8(process->readAllStandardError())); - emit error(err); - cleanup(); + emit aborted(err); + cleanup(process); return; } @@ -232,13 +230,13 @@ void MonotoneThread::run() emit taskFinished(task); } - cleanup(); + cleanup(process); } -QString MonotoneThread::processErrorToString() +QString MonotoneThread::processErrorToString(QProcess * proc) { QString desc; - switch (process->error()) + switch (proc->error()) { case QProcess::FailedToStart: desc = tr("failed to start"); case QProcess::Crashed: desc = tr("crashed"); @@ -250,13 +248,12 @@ QString MonotoneThread::processErrorToSt return desc; } -void MonotoneThread::abort() +void MonotoneThread::cleanup(QProcess * proc) { + QMutexLocker locker(&lock); + doAbort = true; -} - -void MonotoneThread::cleanup() -{ + if (queue.size() > 0) { foreach (MonotoneTask task, queue) @@ -267,10 +264,16 @@ void MonotoneThread::cleanup() } // close the pipes - process->close(); + proc->close(); // send SIGTERM - process->terminate(); + proc->terminate(); // block until the process has really been finished - process->waitForFinished(); + proc->waitForFinished(); } +void MonotoneThread::abort() +{ + QMutexLocker locker(&lock); + doAbort = true; +} + ============================================================ --- MonotoneThread.h b8475556bd836dc28167ac42a37a10a6c87aef80 +++ MonotoneThread.h 7e2fa231c46b06ccea13cf85d92a035f7cc5de08 @@ -24,6 +24,7 @@ #include #include #include +#include class MonotoneTask { @@ -72,16 +73,19 @@ signals: signals: void taskFinished(const MonotoneTask &); void taskAborted(const MonotoneTask &); - void error(const QString &); + void aborted(const QString &); private: - QString processErrorToString(); - void cleanup(); + QString processErrorToString(QProcess *); + void cleanup(QProcess *); static const int StdioBufferSize; bool doAbort; - QProcess * process; + QString mtnBinary; + QString databasePath; + QString workspacePath; QQueue queue; + QMutex lock; }; #endif ============================================================ --- test.cpp 581c6d829be0253d7383a62eecf94effdb74b08a +++ test.cpp 2e56517014b8cb86c7b786f1f75c13203c1cc46a @@ -24,7 +24,7 @@ TestDlg::TestDlg() : QDialog(0) { setupUi(this); - mtn = new MonotoneThread("mtn", "~/Entwicklung/guitone.mtn", "~/Entwicklung/guitone"); + mtn = new MonotoneThread("mtn", "../guitone.mtn", "."); mtn->start(); connect( @@ -38,8 +38,8 @@ TestDlg::TestDlg() : QDialog(0) ); connect( - mtn, SIGNAL(error(const QString &)), - this, SLOT(mtnerror(const QString &)) + mtn, SIGNAL(aborted(const QString &)), + this, SLOT(threadAborted(const QString &)) ); } @@ -62,8 +62,15 @@ void TestDlg::finished(const MonotoneTas output->setText(task.getOutputUtf8()); } -void TestDlg::mtnerror(const QString & err) +void TestDlg::threadAborted(const QString & err) { error->setText(err); } +void TestDlg::accept() +{ + mtn->abort(); + mtn->wait(); + QApplication::quit(); +} + ============================================================ --- test.h 076086d24821d8abca53acb9e312a15e6b201727 +++ test.h 5701722dc2d6773d4e0f514d6e7823dcd605e6dc @@ -40,7 +40,8 @@ private slots: private slots: void execute(); void finished(const MonotoneTask &); - void mtnerror(const QString &); + void threadAborted(const QString &); + void accept(); }; #endif