From 97178a91fe834cfb1422c0715c7187dece34c905 Mon Sep 17 00:00:00 2001 From: cerf Date: Tue, 16 Aug 2011 08:29:38 +0000 Subject: [PATCH] vcsbase: fix bug causing redundant output In VCSJobRunner::task() some execution paths left a signal/slot connection, causing redundant output emission. This would occur for example after a VCS job fails : if the next job succeeds then its output is emitted twice, because the previous connection for signal output() was not destroyed. The bug is now fixed by ensuring disconnect is done for all execution paths (thanks to helper DisconnectSignalHelper). Change-Id: I67a7ba2829208f7e71158cb17a99575d79c9f9f7 Merge-request: 364 Reviewed-by: Tobias Hunger Reviewed-on: http://codereview.qt.nokia.com/2997 --- src/plugins/vcsbase/vcsjobrunner.cpp | 32 +++++++++++++++++++++++++--- 1 file changed, 29 insertions(+), 3 deletions(-) diff --git a/src/plugins/vcsbase/vcsjobrunner.cpp b/src/plugins/vcsbase/vcsjobrunner.cpp index ca705171477..70e2ee0b2d3 100644 --- a/src/plugins/vcsbase/vcsjobrunner.cpp +++ b/src/plugins/vcsbase/vcsjobrunner.cpp @@ -49,6 +49,30 @@ #include #include +namespace { + +//Helper class to automatically disconnect a signal from all its receivers. +//The disconnect occurs on destruction of the helper object. +class DisconnectSignalHelper +{ +public: + DisconnectSignalHelper(QObject *sender, const char *signal) : + m_sender(sender), m_signal(signal) + { + } + + ~DisconnectSignalHelper() + { + QObject::disconnect(m_sender, m_signal, 0, 0); + } + +private: + QObject *m_sender; + const char *m_signal; +}; + +} // Anonymous namespace + /*! \class VCSBase::VCSJob @@ -290,6 +314,11 @@ void VCSJobRunner::task(const QSharedPointer &job) break; } + //the signal connection is to last only for the duration of a job/task. next time a new + //output signal connection must be made + DisconnectSignalHelper autoDisconnectOutputSig(this, SIGNAL(output(QByteArray))); + Q_UNUSED(autoDisconnectOutputSig); + 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 @@ -341,9 +370,6 @@ void VCSJobRunner::task(const QSharedPointer &job) } vcsProcess->close(); - //the signal connection is to last only for the duration of a job/task. next time a new - //output signal connection must be made - disconnect(this, SIGNAL(output(QByteArray)), 0, 0); } } // namespace VCSBase