forked from qt-creator/qt-creator
ClassView: Stop the running timer in Parser thread on close
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>
This commit is contained in:
@@ -123,6 +123,7 @@ Manager::Manager(QObject *parent)
|
|||||||
|
|
||||||
Manager::~Manager()
|
Manager::~Manager()
|
||||||
{
|
{
|
||||||
|
QMetaObject::invokeMethod(&d->parser, &Parser::aboutToShutdown, Qt::BlockingQueuedConnection);
|
||||||
d->parserThread.quit();
|
d->parserThread.quit();
|
||||||
d->parserThread.wait();
|
d->parserThread.wait();
|
||||||
delete d;
|
delete d;
|
||||||
|
|||||||
@@ -89,6 +89,7 @@ public:
|
|||||||
CPlusPlus::Document::Ptr document(const QString &fileName) const;
|
CPlusPlus::Document::Ptr document(const QString &fileName) const;
|
||||||
|
|
||||||
QTimer timer;
|
QTimer timer;
|
||||||
|
bool m_shuttingDown = false;
|
||||||
|
|
||||||
struct DocumentCache {
|
struct DocumentCache {
|
||||||
unsigned treeRevision = 0;
|
unsigned treeRevision = 0;
|
||||||
@@ -199,6 +200,12 @@ void Parser::setFlatMode(bool flatMode)
|
|||||||
requestCurrentState();
|
requestCurrentState();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Parser::aboutToShutdown()
|
||||||
|
{
|
||||||
|
d->m_shuttingDown = true;
|
||||||
|
d->timer.stop();
|
||||||
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
Returns the internal tree item for \a item. \a skipRoot skips the root
|
Returns the internal tree item for \a item. \a skipRoot skips the root
|
||||||
item.
|
item.
|
||||||
@@ -405,9 +412,8 @@ void Parser::parseDocument(const CPlusPlus::Document::Ptr &doc)
|
|||||||
|
|
||||||
getParseDocumentTree(doc);
|
getParseDocumentTree(doc);
|
||||||
|
|
||||||
if (!d->timer.isActive())
|
if (!d->timer.isActive() && !d->m_shuttingDown)
|
||||||
d->timer.start(400); //! Delay in msecs before an update
|
d->timer.start(400); //! Delay in msecs before an update
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
|
|||||||
@@ -62,6 +62,7 @@ public:
|
|||||||
void resetDataToCurrentState();
|
void resetDataToCurrentState();
|
||||||
void parseDocument(const CPlusPlus::Document::Ptr &doc);
|
void parseDocument(const CPlusPlus::Document::Ptr &doc);
|
||||||
void setFlatMode(bool flat);
|
void setFlatMode(bool flat);
|
||||||
|
void aboutToShutdown();
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void treeDataUpdate(QSharedPointer<QStandardItem> result);
|
void treeDataUpdate(QSharedPointer<QStandardItem> result);
|
||||||
|
|||||||
Reference in New Issue
Block a user