From 3f87c4685e3d93522e8cad11a725dd193156d20d Mon Sep 17 00:00:00 2001 From: Eike Ziller Date: Tue, 6 Feb 2018 09:33:54 +0100 Subject: 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 Reviewed-by: Christian Stenger --- src/plugins/coreplugin/locator/javascriptfilter.cpp | 20 ++++++++++---------- src/plugins/coreplugin/locator/javascriptfilter.h | 4 ++++ 2 files changed, 14 insertions(+), 10 deletions(-) diff --git a/src/plugins/coreplugin/locator/javascriptfilter.cpp b/src/plugins/coreplugin/locator/javascriptfilter.cpp index a4c20e7a7e..6f88a9188a 100644 --- a/src/plugins/coreplugin/locator/javascriptfilter.cpp +++ b/src/plugins/coreplugin/locator/javascriptfilter.cpp @@ -28,7 +28,6 @@ #include #include #include -#include 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 JavaScriptFilter::matchesFor( @@ -68,16 +76,8 @@ QList 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 { diff --git a/src/plugins/coreplugin/locator/javascriptfilter.h b/src/plugins/coreplugin/locator/javascriptfilter.h index 025ce2fa6a..feaf326036 100644 --- a/src/plugins/coreplugin/locator/javascriptfilter.h +++ b/src/plugins/coreplugin/locator/javascriptfilter.h @@ -27,6 +27,8 @@ #include +#include + #include QT_BEGIN_NAMESPACE @@ -54,6 +56,8 @@ private: void setupEngine(); mutable std::unique_ptr m_engine; + QTimer m_abortTimer; + bool m_aborted = false; }; } // namespace Internal -- cgit v1.2.3