Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mapsme/omim.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDenis Koronchik <denis@mapswithme.com>2014-10-06 16:10:37 +0400
committerAlex Zolotarev <alex@maps.me>2015-09-23 02:29:30 +0300
commitd3220b00b7134f114a7fc36e4de74cdaaa17d874 (patch)
tree267170dbee3921701d431c37b07fc331353873b5
parentb09c040bab1042e47a1a499c42161241fb8f7688 (diff)
[routing] Do osrm routing async.
-rw-r--r--map/framework.cpp32
-rw-r--r--map/routing_session.cpp14
-rw-r--r--routing/osrm_router.cpp88
-rw-r--r--routing/osrm_router.hpp11
-rw-r--r--std/atomic.hpp15
5 files changed, 112 insertions, 48 deletions
diff --git a/map/framework.cpp b/map/framework.cpp
index 607b170c2f..9b7f3cb56b 100644
--- a/map/framework.cpp
+++ b/map/framework.cpp
@@ -1865,22 +1865,24 @@ void Framework::BuildRoute(m2::PointD const & destination)
if (IsRoutingActive())
CloseRouting();
- m_routingSession.BuildRoute(state->Position(), destination, [&] (Route const & route, IRouter::ResultCode code)
- {
- if (code == IRouter::NoError)
- {
- InsertRoute(route);
- state->RouteBuilded();
- ShowRectExVisibleScale(route.GetPoly().GetLimitRect());
- }
- else
+ m_routingSession.BuildRoute(state->Position(), destination,
+ // Capture all dependent state by value! Functor is passed for async calculation and called in UI thread.
+ [this, state] (Route const & route, IRouter::ResultCode code)
{
- RemoveRoute();
- ///@TODO resolve message about this error
- string messageID = "route_build_failed_reason";
- ShowDialog(messageID, DialogOptions::Ok);
- }
- });
+ if (code == IRouter::NoError)
+ {
+ InsertRoute(route);
+ state->RouteBuilded();
+ ShowRectExVisibleScale(route.GetPoly().GetLimitRect());
+ }
+ else
+ {
+ RemoveRoute();
+ ///@TODO resolve message about this error
+ string messageID = "route_build_failed_reason";
+ ShowDialog(messageID, DialogOptions::Ok);
+ }
+ });
}
void Framework::FollowRoute()
diff --git a/map/routing_session.cpp b/map/routing_session.cpp
index 62e0b9ebff..72204f239c 100644
--- a/map/routing_session.cpp
+++ b/map/routing_session.cpp
@@ -35,13 +35,15 @@ void RoutingSession::RebuildRoute(m2::PointD const & startPoint, TReadyCallbackF
Reset();
m_state = RouteNotReady;
- m_router->CalculateRoute(startPoint, [&] (Route & route, IRouter::ResultCode e)
- {
- if (e == IRouter::NoError)
- AssignRoute(route);
+ m_router->CalculateRoute(startPoint,
+ // Capture all dependent state by value! Functor is passed for async calculation and called in UI thread.
+ [this, callback] (Route & route, IRouter::ResultCode e)
+ {
+ if (e == IRouter::NoError)
+ AssignRoute(route);
- callback(m_route, e);
- });
+ callback(m_route, e);
+ });
}
bool RoutingSession::IsActive() const
diff --git a/routing/osrm_router.cpp b/routing/osrm_router.cpp
index 168f7ff63f..63befcd5bb 100644
--- a/routing/osrm_router.cpp
+++ b/routing/osrm_router.cpp
@@ -169,7 +169,7 @@ public:
OsrmRouter::OsrmRouter(Index const * index, CountryFileFnT const & fn)
- : m_countryFn(fn), m_pIndex(index)
+ : m_countryFn(fn), m_pIndex(index), m_isFinalChanged(false), m_isReadyThread(false)
{
}
@@ -180,44 +180,80 @@ string OsrmRouter::GetName() const
void OsrmRouter::SetFinalPoint(m2::PointD const & finalPt)
{
+ threads::MutexGuard guard(m_paramsMutex);
+ UNUSED_VALUE(guard);
+
m_finalPt = finalPt;
- m_cachedFinalNodes.clear();
+ m_isFinalChanged = true;
+}
+
+void OsrmRouter::CalculateRoute(m2::PointD const & startPt, ReadyCallback const & callback)
+{
+ GetPlatform().RunAsync(bind(&OsrmRouter::CalculateRouteAsync, this, startPt, callback));
}
-void OsrmRouter::CalculateRoute(m2::PointD const & startingPt, ReadyCallback const & callback)
+void OsrmRouter::CalculateRouteAsync(m2::PointD const & startPt, ReadyCallback const & callback)
{
+ if (m_isReadyThread.test_and_set())
+ return;
+
Route route(GetName());
ResultCode code;
- try
{
- code = CalculateRouteImpl(startingPt, m_finalPt, route);
- switch (code)
+ threads::MutexGuard guard(m_routeMutex);
+ UNUSED_VALUE(guard);
+
+ m_isReadyThread.clear();
+
+ m2::PointD finalPt;
{
- case StartPointNotFound:
- LOG(LWARNING, ("Can't find start point node"));
- break;
- case EndPointNotFound:
- LOG(LWARNING, ("Can't find end point node"));
- break;
- case PointsInDifferentMWM:
- LOG(LWARNING, ("Points are in different MWMs"));
- break;
- case RouteNotFound:
- LOG(LWARNING, ("Route not found"));
- break;
+ threads::MutexGuard params(m_paramsMutex);
+ UNUSED_VALUE(params);
- default:
- break;
+ finalPt = m_finalPt;
+
+ if (m_isFinalChanged)
+ m_cachedFinalNodes.clear();
+ m_isFinalChanged = false;
+ }
+
+ try
+ {
+ code = CalculateRouteImpl(startPt, finalPt, route);
+ switch (code)
+ {
+ case StartPointNotFound:
+ LOG(LWARNING, ("Can't find start point node"));
+ break;
+ case EndPointNotFound:
+ LOG(LWARNING, ("Can't find end point node"));
+ break;
+ case PointsInDifferentMWM:
+ LOG(LWARNING, ("Points are in different MWMs"));
+ break;
+ case RouteNotFound:
+ LOG(LWARNING, ("Route not found"));
+ break;
+
+ default:
+ break;
+ }
+ }
+ catch (Reader::Exception const & e)
+ {
+ LOG(LERROR, ("Routing index absent or incorrect. Error while loading routing index:", e.Msg()));
+ code = InternalError;
+
+ // Clear data while m_container is valid.
+ m_dataFacade.Clear();
+ m_mapping.Clear();
+
+ m_container.Close();
}
- }
- catch (Reader::Exception const & e)
- {
- LOG(LERROR, ("Routing index absent or incorrect. Error while loading routing index:", e.Msg()));
- code = InternalError;
}
- callback(route, code);
+ GetPlatform().RunOnGuiThread(bind(callback, route, code));
}
namespace
diff --git a/routing/osrm_router.hpp b/routing/osrm_router.hpp
index d1946cf9c8..e2a41d74cf 100644
--- a/routing/osrm_router.hpp
+++ b/routing/osrm_router.hpp
@@ -4,7 +4,10 @@
#include "osrm2feature_map.hpp"
#include "osrm_data_facade.hpp"
+#include "../base/mutex.hpp"
+
#include "../std/function.hpp"
+#include "../std/atomic.hpp"
#include "../3party/osrm/osrm-backend/DataStructures/QueryEdge.h"
@@ -36,7 +39,7 @@ public:
virtual string GetName() const;
virtual void SetFinalPoint(m2::PointD const & finalPt);
- virtual void CalculateRoute(m2::PointD const & startingPt, ReadyCallback const & callback);
+ virtual void CalculateRoute(m2::PointD const & startPt, ReadyCallback const & callback);
protected:
IRouter::ResultCode FindPhantomNodes(string const & fName, m2::PointD const & startPt, m2::PointD const & finalPt,
@@ -44,6 +47,7 @@ protected:
bool NeedReload(string const & fPath) const;
+ void CalculateRouteAsync(m2::PointD const & startPt, ReadyCallback const & callback);
ResultCode CalculateRouteImpl(m2::PointD const & startPt, m2::PointD const & finalPt, Route & route);
private:
@@ -55,7 +59,12 @@ private:
FilesMappingContainer m_container;
+ bool m_isFinalChanged;
FeatureGraphNodeVecT m_cachedFinalNodes;
+
+ threads::Mutex m_paramsMutex;
+ threads::Mutex m_routeMutex;
+ atomic_flag m_isReadyThread;
};
}
diff --git a/std/atomic.hpp b/std/atomic.hpp
new file mode 100644
index 0000000000..0e479ffa0a
--- /dev/null
+++ b/std/atomic.hpp
@@ -0,0 +1,15 @@
+#pragma once
+#include "common_defines.hpp"
+
+#ifdef new
+#undef new
+#endif
+
+#include <atomic>
+
+using std::atomic;
+using std::atomic_flag;
+
+#ifdef DEBUG_NEW
+#define new DEBUG_NEW
+#endif