diff --git a/search/engine.cpp b/search/engine.cpp index b2308883b2..a6a7c9209f 100644 --- a/search/engine.cpp +++ b/search/engine.cpp @@ -19,8 +19,22 @@ void Engine::Search(string const & queryText, m2::RectD const & rect, function const & f) { + { + threads::MutexGuard mutexGuard(m_mutex); + UNUSED_VALUE(mutexGuard); + if (m_pLastQuery) + m_pLastQuery->SetTerminateFlag(); + } + impl::Query * pQuery = new impl::Query(queryText, rect, m_pIndex); m_pRunner->Run(bind(&impl::Query::SearchAndDestroy, pQuery, f)); } +void Engine::OnQueryDelete() +{ + threads::MutexGuard mutexGuard(m_mutex); + UNUSED_VALUE(mutexGuard); + m_pLastQuery = NULL; +} + } // namespace search diff --git a/search/engine.hpp b/search/engine.hpp index 5ff87a9a86..bd3983b951 100644 --- a/search/engine.hpp +++ b/search/engine.hpp @@ -2,6 +2,7 @@ #include "../indexer/index.hpp" #include "../geometry/rect2d.hpp" #include "../base/base.hpp" +#include "../base/mutex.hpp" #include "../base/runner.hpp" #include "../std/function.hpp" #include "../std/scoped_ptr.hpp" @@ -13,6 +14,7 @@ class FeatureType; namespace search { +namespace impl { class Query; } class Result; class Engine @@ -26,9 +28,13 @@ public: m2::RectD const & rect, function const & f); + void OnQueryDelete(); + private: IndexType const * m_pIndex; scoped_ptr m_pRunner; + threads::Mutex m_mutex; + impl::Query * volatile m_pLastQuery; }; } // namespace search diff --git a/search/query.cpp b/search/query.cpp index 54e3fe708a..1f47a7e8b1 100644 --- a/search/query.cpp +++ b/search/query.cpp @@ -120,6 +120,9 @@ void Query::Search(function const & f) } } + if (m_bTerminate) + return; + // Category matching. if (!m_prefix.empty()) { @@ -134,12 +137,21 @@ void Query::Search(function const & f) } } + if (m_bTerminate) + return; + // Feature matching. FeatureProcessor featureProcessor(*this); int const scale = scales::GetScaleLevel(m_viewport) + 1; if (scale > scales::GetUpperWorldScale()) + { m_pIndex->ForEachInRect(featureProcessor, m_viewport, scales::GetUpperWorldScale()); + if (m_bTerminate) + return; + } m_pIndex->ForEachInRect(featureProcessor, m_viewport, min(scales::GetUpperScale(), scale)); + if (m_bTerminate) + return; vector results; results.reserve(m_results.size());