Fix crash in timeout of JavaScript locator filter

The timeout code may not access thread local state, because if it fires
on the main thread after the thread already finished, that state is
gone.

Change-Id: I3b9b432515ff6f0c46c46b1904bdd622a19960d2
Reviewed-by: Orgad Shaneh <orgads@gmail.com>
Reviewed-by: Christian Stenger <christian.stenger@qt.io>
This commit is contained in:
Eike Ziller
2018-02-06 09:33:54 +01:00
parent 6ca1d2bfa4
commit 3f87c4685e
2 changed files with 14 additions and 10 deletions

View File

@@ -28,7 +28,6 @@
#include <QClipboard>
#include <QGuiApplication>
#include <QScriptEngine>
#include <QTimer>
namespace Core {
namespace Internal {
@@ -45,6 +44,13 @@ JavaScriptFilter::JavaScriptFilter()
setDisplayName(tr("Evaluate JavaScript"));
setIncludedByDefault(false);
setShortcutString("=");
m_abortTimer.setSingleShot(true);
m_abortTimer.setInterval(1000);
connect(&m_abortTimer, &QTimer::timeout, this, [this] {
m_aborted = true;
if (m_engine && m_engine->isEvaluating())
m_engine->abortEvaluation();
});
}
JavaScriptFilter::~JavaScriptFilter()
@@ -57,6 +63,8 @@ void JavaScriptFilter::prepareSearch(const QString &entry)
if (!m_engine)
setupEngine();
m_aborted = false;
m_abortTimer.start();
}
QList<LocatorFilterEntry> JavaScriptFilter::matchesFor(
@@ -68,16 +76,8 @@ QList<LocatorFilterEntry> JavaScriptFilter::matchesFor(
if (entry.trimmed().isEmpty()) {
entries.append({this, tr("Reset Engine"), QVariant(ResetEngine, nullptr)});
} else {
bool aborted = false;
QTimer::singleShot(1000, this, [this, &aborted]() {
m_engine->abortEvaluation();
aborted = true;
});
const QString result = m_engine->evaluate(entry).toString();
if (aborted) {
if (m_aborted) {
const QString message = entry + " = " + tr("Engine aborted after timeout.");
entries.append({this, message, QVariant(AbortEngine, nullptr)});
} else {

View File

@@ -27,6 +27,8 @@
#include <coreplugin/locator/ilocatorfilter.h>
#include <QTimer>
#include <memory>
QT_BEGIN_NAMESPACE
@@ -54,6 +56,8 @@ private:
void setupEngine();
mutable std::unique_ptr<QScriptEngine> m_engine;
QTimer m_abortTimer;
bool m_aborted = false;
};
} // namespace Internal