diff --git a/src/plugins/vcsbase/vcsbaseclient.cpp b/src/plugins/vcsbase/vcsbaseclient.cpp index 15dda5ff2a9218e7f6bf3e17a0a73f60adc51ab4..b059b56a31ae6acf9d7b63d2d9f94e615320f69d 100644 --- a/src/plugins/vcsbase/vcsbaseclient.cpp +++ b/src/plugins/vcsbase/vcsbaseclient.cpp @@ -68,19 +68,32 @@ inline Core::IEditor *locateEditor(const Core::ICore *core, const char *property namespace VCSBase { +class VCSBaseClientPrivate +{ +public: + explicit VCSBaseClientPrivate(const VCSBaseClientSettings &settings); + + VCSJobRunner *m_jobManager; + Core::ICore *m_core; + const VCSBaseClientSettings& m_clientSettings; +}; + +VCSBaseClientPrivate::VCSBaseClientPrivate(const VCSBaseClientSettings &settings) : + m_jobManager(0), m_core(Core::ICore::instance()), m_clientSettings(settings) +{ +} + VCSBaseClient::VCSBaseClient(const VCSBaseClientSettings &settings) : - m_jobManager(0), - m_core(Core::ICore::instance()), - m_clientSettings(settings) + d(new VCSBaseClientPrivate(settings)) { qRegisterMetaType<QVariant>(); } VCSBaseClient::~VCSBaseClient() { - if (m_jobManager) { - delete m_jobManager; - m_jobManager = 0; + if (d->m_jobManager) { + delete d->m_jobManager; + d->m_jobManager = 0; } } @@ -175,8 +188,8 @@ bool VCSBaseClient::vcsFullySynchronousExec(const QString &workingDir, vcsProcess.setWorkingDirectory(workingDir); VCSJobRunner::setProcessEnvironment(&vcsProcess); - const QString binary = m_clientSettings.binary(); - const QStringList arguments = m_clientSettings.standardArguments() + args; + const QString binary = d->m_clientSettings.binary(); + const QStringList arguments = d->m_clientSettings.standardArguments() + args; VCSBase::VCSBaseOutputWindow *outputWindow = VCSBase::VCSBaseOutputWindow::instance(); outputWindow->appendCommand(workingDir, binary, args); @@ -191,10 +204,10 @@ bool VCSBaseClient::vcsFullySynchronousExec(const QString &workingDir, vcsProcess.closeWriteChannel(); QByteArray stdErr; - if (!Utils::SynchronousProcess::readDataFromProcess(vcsProcess, m_clientSettings.timeoutMilliSeconds(), + if (!Utils::SynchronousProcess::readDataFromProcess(vcsProcess, d->m_clientSettings.timeoutMilliSeconds(), output, &stdErr, true)) { Utils::SynchronousProcess::stopProcess(vcsProcess); - outputWindow->appendError(VCSJobRunner::msgTimeout(binary, m_clientSettings.timeoutSeconds())); + outputWindow->appendError(VCSJobRunner::msgTimeout(binary, d->m_clientSettings.timeoutSeconds())); return false; } if (!stdErr.isEmpty()) @@ -209,10 +222,10 @@ Utils::SynchronousProcessResponse VCSBaseClient::vcsSynchronousExec( unsigned flags, QTextCodec *outputCodec) { - const QString binary = m_clientSettings.binary(); - const QStringList arguments = m_clientSettings.standardArguments() + args; + const QString binary = d->m_clientSettings.binary(); + const QStringList arguments = d->m_clientSettings.standardArguments() + args; return VCSBase::VCSBasePlugin::runVCS(workingDirectory, binary, arguments, - m_clientSettings.timeoutMilliSeconds(), + d->m_clientSettings.timeoutMilliSeconds(), flags, outputCodec); } @@ -416,17 +429,17 @@ void VCSBaseClient::commit(const QString &repositoryRoot, void VCSBaseClient::settingsChanged() { - if (m_jobManager) { - m_jobManager->setSettings(m_clientSettings.binary(), - m_clientSettings.standardArguments(), - m_clientSettings.timeoutMilliSeconds()); - m_jobManager->restart(); + if (d->m_jobManager) { + d->m_jobManager->setSettings(d->m_clientSettings.binary(), + d->m_clientSettings.standardArguments(), + d->m_clientSettings.timeoutMilliSeconds()); + d->m_jobManager->restart(); } } QString VCSBaseClient::vcsEditorTitle(const QString &vcsCmd, const QString &sourceId) const { - return m_clientSettings.binary() + QLatin1Char(' ') + vcsCmd + QLatin1Char(' ') + sourceId; + return d->m_clientSettings.binary() + QLatin1Char(' ') + vcsCmd + QLatin1Char(' ') + sourceId; } VCSBase::VCSBaseEditorWidget *VCSBaseClient::createVCSEditor(const QString &kind, QString title, @@ -435,7 +448,7 @@ VCSBase::VCSBaseEditorWidget *VCSBaseClient::createVCSEditor(const QString &kind const QString &dynamicPropertyValue) const { VCSBase::VCSBaseEditorWidget *baseEditor = 0; - Core::IEditor *outputEditor = locateEditor(m_core, registerDynamicProperty, dynamicPropertyValue); + Core::IEditor *outputEditor = locateEditor(d->m_core, registerDynamicProperty, dynamicPropertyValue); const QString progressMsg = tr("Working..."); if (outputEditor) { // Exists already @@ -443,7 +456,7 @@ VCSBase::VCSBaseEditorWidget *VCSBaseClient::createVCSEditor(const QString &kind baseEditor = VCSBase::VCSBaseEditorWidget::getVcsBaseEditor(outputEditor); QTC_ASSERT(baseEditor, return 0); } else { - outputEditor = m_core->editorManager()->openEditorWithContents(kind, &title, progressMsg); + outputEditor = d->m_core->editorManager()->openEditorWithContents(kind, &title, progressMsg); outputEditor->file()->setProperty(registerDynamicProperty, dynamicPropertyValue); baseEditor = VCSBase::VCSBaseEditorWidget::getVcsBaseEditor(outputEditor); connect(baseEditor, SIGNAL(annotateRevisionRequested(QString,QString,int)), @@ -454,21 +467,21 @@ VCSBase::VCSBaseEditorWidget *VCSBaseClient::createVCSEditor(const QString &kind baseEditor->setCodec(VCSBase::VCSBaseEditorWidget::getCodec(source)); } - m_core->editorManager()->activateEditor(outputEditor, Core::EditorManager::ModeSwitch); + d->m_core->editorManager()->activateEditor(outputEditor, Core::EditorManager::ModeSwitch); baseEditor->setForceReadOnly(true); return baseEditor; } void VCSBaseClient::enqueueJob(const QSharedPointer<VCSJob> &job) { - if (!m_jobManager) { - m_jobManager = new VCSJobRunner(); - m_jobManager->setSettings(m_clientSettings.binary(), - m_clientSettings.standardArguments(), - m_clientSettings.timeoutMilliSeconds()); - m_jobManager->start(); + if (!d->m_jobManager) { + d->m_jobManager = new VCSJobRunner(); + d->m_jobManager->setSettings(d->m_clientSettings.binary(), + d->m_clientSettings.standardArguments(), + d->m_clientSettings.timeoutMilliSeconds()); + d->m_jobManager->start(); } - m_jobManager->enqueueJob(job); + d->m_jobManager->enqueueJob(job); } } // namespace VCSBase diff --git a/src/plugins/vcsbase/vcsbaseclient.h b/src/plugins/vcsbase/vcsbaseclient.h index 207e53f44421b7fe3d635cb1e2f8d08b7faa0bf7..6b9f3e1382fe8fc459c5502e7fdf0e3d64f59120 100644 --- a/src/plugins/vcsbase/vcsbaseclient.h +++ b/src/plugins/vcsbase/vcsbaseclient.h @@ -40,6 +40,7 @@ #include <QtCore/QStringList> #include <QtCore/QPair> #include <QtCore/QSharedPointer> +#include <QtCore/QScopedPointer> #include <QtCore/QHash> #include <QtCore/QVariant> @@ -60,8 +61,8 @@ namespace VCSBase { class VCSBaseEditorWidget; class VCSBaseClientSettings; -class VCSJobRunner; class VCSJob; +class VCSBaseClientPrivate; class VCSBASE_EXPORT VCSBaseClient : public QObject { @@ -69,7 +70,7 @@ class VCSBASE_EXPORT VCSBaseClient : public QObject public: typedef QHash<int, QVariant> ExtraCommandOptions; - VCSBaseClient(const VCSBaseClientSettings &settings); + explicit VCSBaseClient(const VCSBaseClientSettings &settings); ~VCSBaseClient(); virtual bool synchronousCreateRepository(const QString &workingDir); virtual bool synchronousClone(const QString &workingDir, @@ -180,9 +181,7 @@ private slots: void slotAnnotateRevisionRequested(const QString &source, QString change, int lineNumber); private: - VCSJobRunner *m_jobManager; - Core::ICore *m_core; - const VCSBaseClientSettings& m_clientSettings; + QScopedPointer<VCSBaseClientPrivate> d; }; } //namespace VCSBase diff --git a/src/plugins/vcsbase/vcsjobrunner.cpp b/src/plugins/vcsbase/vcsjobrunner.cpp index a2fbdc3140ad0fcf9e727edb69b31eef224a5551..4d374ccf4babaa3e7a8d307a0ee99d2d7bf0004a 100644 --- a/src/plugins/vcsbase/vcsjobrunner.cpp +++ b/src/plugins/vcsbase/vcsjobrunner.cpp @@ -45,8 +45,12 @@ #include <QtCore/QString> #include <QtCore/QDebug> #include <QtCore/QDir> +#include <QtCore/QQueue> +#include <QtCore/QMutex> +#include <QtCore/QWaitCondition> +#include <QtCore/QSharedPointer> -using namespace VCSBase; +namespace VCSBase { VCSJob::VCSJob(const QString &workingDir, const QStringList &args, @@ -124,10 +128,26 @@ void VCSJob::setUnixTerminalDisabled(bool v) m_unixTerminalDisabled = v; } +class VCSJobRunnerPrivate +{ +public: + VCSJobRunnerPrivate(); + + QQueue<QSharedPointer<VCSJob> > m_jobs; + QMutex m_mutex; + QWaitCondition m_waiter; + bool m_keepRunning; + QString m_binary; + QStringList m_standardArguments; + int m_timeoutMS; +}; + +VCSJobRunnerPrivate::VCSJobRunnerPrivate() : + m_keepRunning(true), m_timeoutMS(30000) +{ +} - -VCSJobRunner::VCSJobRunner() : - m_keepRunning(true) +VCSJobRunner::VCSJobRunner() : d(new VCSJobRunnerPrivate) { VCSBase::VCSBaseOutputWindow *ow = VCSBase::VCSBaseOutputWindow::instance(); connect(this, SIGNAL(error(QString)), @@ -144,12 +164,12 @@ VCSJobRunner::~VCSJobRunner() void VCSJobRunner::stop() { { - QMutexLocker mutexLocker(&m_mutex); Q_UNUSED(mutexLocker); - m_keepRunning = false; + QMutexLocker mutexLocker(&d->m_mutex); Q_UNUSED(mutexLocker); + d->m_keepRunning = false; //Create a dummy task to break the cycle QSharedPointer<VCSJob> job(0); - m_jobs.enqueue(job); - m_waiter.wakeAll(); + d->m_jobs.enqueue(job); + d->m_waiter.wakeAll(); } wait(); @@ -158,34 +178,34 @@ void VCSJobRunner::stop() void VCSJobRunner::restart() { stop(); - m_mutex.lock(); - m_keepRunning = true; - m_mutex.unlock(); + d->m_mutex.lock(); + d->m_keepRunning = true; + d->m_mutex.unlock(); start(); } void VCSJobRunner::enqueueJob(const QSharedPointer<VCSJob> &job) { - QMutexLocker mutexLocker(&m_mutex); Q_UNUSED(mutexLocker); - m_jobs.enqueue(job); - m_waiter.wakeAll(); + QMutexLocker mutexLocker(&d->m_mutex); Q_UNUSED(mutexLocker); + d->m_jobs.enqueue(job); + d->m_waiter.wakeAll(); } void VCSJobRunner::run() { forever { - m_mutex.lock(); - while (m_jobs.count() == 0) - m_waiter.wait(&m_mutex); + d->m_mutex.lock(); + while (d->m_jobs.count() == 0) + d->m_waiter.wait(&d->m_mutex); - if (!m_keepRunning) { - m_jobs.clear(); - m_mutex.unlock(); + if (!d->m_keepRunning) { + d->m_jobs.clear(); + d->m_mutex.unlock(); return; } - QSharedPointer<VCSJob> job = m_jobs.dequeue(); - m_mutex.unlock(); + QSharedPointer<VCSJob> job = d->m_jobs.dequeue(); + d->m_mutex.unlock(); task(job); } @@ -218,9 +238,9 @@ void VCSJobRunner::setSettings(const QString &bin, const QStringList &stdArgs, int timeoutMsec) { - m_binary = bin; - m_standardArguments = stdArgs; - m_timeoutMS = timeoutMsec; + d->m_binary = bin; + d->m_standardArguments = stdArgs; + d->m_timeoutMS = timeoutMsec; } void VCSJobRunner::task(const QSharedPointer<VCSJob> &job) @@ -250,8 +270,8 @@ void VCSJobRunner::task(const QSharedPointer<VCSJob> &job) break; } - const QStringList args = m_standardArguments + taskData->arguments(); - emit commandStarted(VCSBase::VCSBaseOutputWindow::msgExecutionLogEntry(taskData->workingDirectory(), m_binary, args)); + const QStringList args = d->m_standardArguments + taskData->arguments(); + emit commandStarted(VCSBase::VCSBaseOutputWindow::msgExecutionLogEntry(taskData->workingDirectory(), d->m_binary, args)); //infom the user of what we are going to try and perform if (Constants::Internal::debug) @@ -267,10 +287,10 @@ void VCSJobRunner::task(const QSharedPointer<VCSJob> &job) vcsProcess->setWorkingDirectory(taskData->workingDirectory()); VCSJobRunner::setProcessEnvironment(vcsProcess.data()); - vcsProcess->start(m_binary, args); + vcsProcess->start(d->m_binary, args); if (!vcsProcess->waitForStarted()) { - emit error(msgStartFailed(m_binary, vcsProcess->errorString())); + emit error(msgStartFailed(d->m_binary, vcsProcess->errorString())); return; } @@ -279,9 +299,9 @@ void VCSJobRunner::task(const QSharedPointer<VCSJob> &job) QByteArray stdOutput; QByteArray stdErr; - if (!Utils::SynchronousProcess::readDataFromProcess(*vcsProcess, m_timeoutMS, &stdOutput, &stdErr, false)) { + if (!Utils::SynchronousProcess::readDataFromProcess(*vcsProcess, d->m_timeoutMS, &stdOutput, &stdErr, false)) { Utils::SynchronousProcess::stopProcess(*vcsProcess); - emit error(msgTimeout(m_binary, m_timeoutMS / 1000)); + emit error(msgTimeout(d->m_binary, d->m_timeoutMS / 1000)); return; } @@ -305,3 +325,5 @@ void VCSJobRunner::task(const QSharedPointer<VCSJob> &job) //output signal connection must be made disconnect(this, SIGNAL(output(QByteArray)), 0, 0); } + +} // namespace VCSBase diff --git a/src/plugins/vcsbase/vcsjobrunner.h b/src/plugins/vcsbase/vcsjobrunner.h index c5de2f203d050f55b954ab2ca59a63ff8856abba..60592e55ac17755a301b18c56c3e5021dc92e35d 100644 --- a/src/plugins/vcsbase/vcsjobrunner.h +++ b/src/plugins/vcsbase/vcsjobrunner.h @@ -37,14 +37,12 @@ #include "vcsbase_global.h" #include <QtCore/QThread> -#include <QtCore/QQueue> -#include <QtCore/QMutex> -#include <QtCore/QWaitCondition> #include <QtCore/QStringList> -#include <QtCore/QSharedPointer> -#include <QtCore/QVariant> #include <QtCore/QString> #include <QtCore/QPointer> +#include <QtCore/QSharedPointer> +#include <QtCore/QScopedPointer> +#include <QtCore/QVariant> QT_BEGIN_NAMESPACE class QProcess; @@ -52,6 +50,7 @@ QT_END_NAMESPACE namespace VCSBase { class VCSBaseEditorWidget; +class VCSJobRunnerPrivate; class VCSBASE_EXPORT VCSJob : public QObject { @@ -127,13 +126,7 @@ private: void task(const QSharedPointer<VCSJob> &job); void stop(); - QQueue<QSharedPointer<VCSJob> > m_jobs; - QMutex m_mutex; - QWaitCondition m_waiter; - bool m_keepRunning; - QString m_binary; - QStringList m_standardArguments; - int m_timeoutMS; + QScopedPointer<VCSJobRunnerPrivate> d; }; } //namespace VCSBase