forked from qt-creator/qt-creator
When we are going to delete Parser object, it may happen, that its timer is still being active. A call to parserThread.quit() won't stop the timer. When we quit the thread and wait for it to finish, the thread's timer may still be active. Then we delete the Parser in the main thread, what cause the following warning to appear: "QObject::killTimer: Timers cannot be stopped from another thread". In order to fix it, we post a request to the parser's thread for stopping the timer by a call to aboutToShutdown() with Qt::BlockingQueuedConnection, just before quitting the thread, as the thread's event loop should still be spinning and is able to receive and handle our request. It's the only safe way to stop the active timer that was started in another thread - it must be stopped it the same thread it was started in. Inside the call to aboutToShutdown() we mark that we don't want to start the timer anymore with m_shuttingDown flag and we stop the timer. After the blocking call returns to the main thread we are sure that the timer is not active anymore and it won't became active in the future, so we safely quit the thread and delete the timer. Task-number: QTCREATORBUG-25317 Change-Id: I3b95c062b5561588c45c223d8588b2b700ad4040 Reviewed-by: Christian Kandeler <christian.kandeler@qt.io>
91 lines
3.2 KiB
C++
91 lines
3.2 KiB
C++
/****************************************************************************
|
|
**
|
|
** Copyright (C) 2016 Denis Mingulov
|
|
** 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.
|
|
**
|
|
****************************************************************************/
|
|
|
|
#pragma once
|
|
|
|
#include <QObject>
|
|
|
|
#include "classviewparsertreeitem.h"
|
|
|
|
#include <cplusplus/CppDocument.h>
|
|
|
|
// might be changed to forward declaration - is not done to be less dependent
|
|
#include <projectexplorer/projectnodes.h>
|
|
#include <projectexplorer/project.h>
|
|
|
|
#include <QList>
|
|
#include <QSharedPointer>
|
|
#include <QStandardItem>
|
|
|
|
namespace ClassView {
|
|
namespace Internal {
|
|
|
|
class ParserPrivate;
|
|
|
|
class Parser : public QObject
|
|
{
|
|
Q_OBJECT
|
|
|
|
public:
|
|
explicit Parser(QObject *parent = nullptr);
|
|
~Parser() override;
|
|
|
|
// TODO: below three methods are called directly from different thread
|
|
bool canFetchMore(QStandardItem *item, bool skipRoot = false) const;
|
|
void fetchMore(QStandardItem *item, bool skipRoot = false) const;
|
|
bool hasChildren(QStandardItem *item) const;
|
|
|
|
void requestCurrentState();
|
|
void removeFiles(const QStringList &fileList);
|
|
void resetDataToCurrentState();
|
|
void parseDocument(const CPlusPlus::Document::Ptr &doc);
|
|
void setFlatMode(bool flat);
|
|
void aboutToShutdown();
|
|
|
|
signals:
|
|
void treeDataUpdate(QSharedPointer<QStandardItem> result);
|
|
|
|
private:
|
|
void setFileList(const QStringList &fileList);
|
|
void resetData(const CPlusPlus::Snapshot &snapshot);
|
|
|
|
ParserTreeItem::ConstPtr getParseDocumentTree(const CPlusPlus::Document::Ptr &doc);
|
|
ParserTreeItem::ConstPtr getCachedOrParseDocumentTree(const CPlusPlus::Document::Ptr &doc);
|
|
ParserTreeItem::Ptr getParseProjectTree(const QStringList &fileList, const QString &projectId);
|
|
ParserTreeItem::Ptr getCachedOrParseProjectTree(const QStringList &fileList,
|
|
const QString &projectId);
|
|
ParserTreeItem::ConstPtr parse();
|
|
ParserTreeItem::ConstPtr findItemByRoot(const QStandardItem *item, bool skipRoot = false) const;
|
|
|
|
QStringList getAllFiles(const ProjectExplorer::Project *project);
|
|
ParserTreeItem::Ptr addFlatTree(const ProjectExplorer::Project *project);
|
|
|
|
//! Private class data pointer
|
|
ParserPrivate *d;
|
|
};
|
|
|
|
} // namespace Internal
|
|
} // namespace ClassView
|