Files
qt-creator/src/plugins/autotoolsprojectmanager/makefileparserthread.cpp
Jarek Kobus f6b37328c7 AutotoolsBuildSystem: Avoid using sender()
According to the old explanation inside makefileParsingFinished()
the solution of using sender() can't work reliably in this
case. In scenarion where the old, deleted m_makefileParserThread
had the same address as newly allocated one we might not detect
correctly posted finished() signal of the deleted object.
According to QObject::sender() documentation:
"The pointer returned by this function becomes invalid if the
sender is destroyed", so we can't rely on its value.

Instead, add a new done() signal to the MakefileParserThread,
which is being emitted from MakefileParserThread thread (i.e. from
the thread where MakefileParserThread object lives in). In this way
the finished() signal is still posted to the caller's thread,
but this time if the MakefileParserThread object is already
deleted, the finished() signal will be gone together with the
MakefileParserThread object itself, so we also won't receive done()
signal anymore.

Simplify the internals by using std::unique_ptr.

Change-Id: I43be209ecb71539ddefd72e50e9d60bfb43c49cb
Reviewed-by: <github-actions-qt-creator@cristianadam.eu>
Reviewed-by: Eike Ziller <eike.ziller@qt.io>
2022-07-26 11:15:58 +00:00

119 lines
3.4 KiB
C++

/****************************************************************************
**
** Copyright (C) 2016 Openismus GmbH.
** Author: Peter Penz (ppenz@openismus.com)
** Author: Patricia Santana Cruz (patriciasantanacruz@gmail.com)
** Contact: https://www.qt.io/licensing/
**
** This file is part of Qt Creator.
**
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3 as published by the Free Software
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
**
****************************************************************************/
#include "makefileparserthread.h"
#include <QMutexLocker>
using namespace AutotoolsProjectManager::Internal;
MakefileParserThread::MakefileParserThread(ProjectExplorer::BuildSystem *bs)
: m_parser(bs->projectFilePath().toString()),
m_guard(bs->guardParsingRun())
{
connect(&m_parser, &MakefileParser::status, this, &MakefileParserThread::status);
connect(this, &QThread::finished, this, &MakefileParserThread::done, Qt::QueuedConnection);
}
QStringList MakefileParserThread::sources() const
{
QMutexLocker locker(&m_mutex);
return m_sources;
}
QStringList MakefileParserThread::makefiles() const
{
QMutexLocker locker(&m_mutex);
return m_makefiles;
}
QString MakefileParserThread::executable() const
{
QMutexLocker locker(&m_mutex);
return m_executable;
}
QStringList MakefileParserThread::includePaths() const
{
QMutexLocker locker(&m_mutex);
return m_includePaths;
}
ProjectExplorer::Macros MakefileParserThread::macros() const
{
QMutexLocker locker(&m_mutex);
return m_macros;
}
QStringList MakefileParserThread::cflags() const
{
QMutexLocker locker(&m_mutex);
return m_cflags;
}
QStringList MakefileParserThread::cxxflags() const
{
QMutexLocker locker(&m_mutex);
return m_cxxflags;
}
bool MakefileParserThread::hasError() const
{
QMutexLocker locker(&m_mutex);
return !m_guard.isSuccess();
}
bool MakefileParserThread::isCanceled() const
{
// MakefileParser::isCanceled() is thread-safe
return m_parser.isCanceled();
}
void MakefileParserThread::cancel()
{
m_parser.cancel();
}
void MakefileParserThread::run()
{
const bool success = m_parser.parse();
// Important: Start locking the mutex _after_ the parsing has been finished, as
// this prevents long locks if the caller reads a value before the signal
// finished() has been emitted.
QMutexLocker locker(&m_mutex);
if (success)
m_guard.markAsSuccess();
m_executable = m_parser.executable();
m_sources = m_parser.sources();
m_makefiles = m_parser.makefiles();
m_includePaths = m_parser.includePaths();
m_macros = m_parser.macros();
m_cflags = m_parser.cflags();
m_cxxflags = m_parser.cxxflags();
}