Make SharedDataFacade immutable
This commit is contained in:
committed by
Patrick Niklaus
parent
9af00b1925
commit
ceaf362326
+50
-13
@@ -2,6 +2,7 @@
|
||||
#include "engine/api/route_parameters.hpp"
|
||||
#include "engine/engine_config.hpp"
|
||||
#include "engine/status.hpp"
|
||||
#include "engine/data_watchdog.hpp"
|
||||
|
||||
#include "engine/plugins/match.hpp"
|
||||
#include "engine/plugins/nearest.hpp"
|
||||
@@ -36,7 +37,9 @@ namespace
|
||||
template <typename ParameterT, typename PluginT, typename ResultT>
|
||||
osrm::engine::Status
|
||||
RunQuery(const std::unique_ptr<osrm::storage::SharedBarriers> &lock,
|
||||
const std::shared_ptr<osrm::engine::datafacade::BaseDataFacade> &facade,
|
||||
std::mutex &facade_update_mutex,
|
||||
osrm::engine::DataWatchdog& watchdog,
|
||||
std::shared_ptr<osrm::engine::datafacade::BaseDataFacade> &facade,
|
||||
const ParameterT ¶meters,
|
||||
PluginT &plugin,
|
||||
ResultT &result)
|
||||
@@ -53,11 +56,32 @@ RunQuery(const std::unique_ptr<osrm::storage::SharedBarriers> &lock,
|
||||
boost::interprocess::sharable_lock<boost::interprocess::named_sharable_mutex> query_lock(
|
||||
lock->query_mutex);
|
||||
|
||||
auto &shared_facade = static_cast<osrm::engine::datafacade::SharedDataFacade &>(*facade);
|
||||
shared_facade.CheckAndReloadFacade();
|
||||
// Get a shared data lock so that other threads won't update
|
||||
// things while the query is running
|
||||
boost::shared_lock<boost::shared_mutex> data_lock{shared_facade.data_mutex};
|
||||
{
|
||||
// this lock ensures that we are never overtaken while creating a new
|
||||
// facade and setting it.
|
||||
// This is important since we need to ensure there is always exactly
|
||||
// one facade per shared memory region.
|
||||
// TODO: Remove this once the SharedDataFacade doesn't own the shared memory
|
||||
// segment anymore.
|
||||
std::lock_guard<std::mutex> update_lock(facade_update_mutex);
|
||||
|
||||
if (watchdog.HasNewRegion())
|
||||
{
|
||||
|
||||
auto new_facade = watchdog.MaybeLoadNewRegion();
|
||||
// for now the external locking will ensure that loading the new region
|
||||
// will ways work. In the future we might allow being overtaken
|
||||
// by other threads and they will also try to update.
|
||||
if (new_facade)
|
||||
{
|
||||
// TODO remove once we allow for more then one SharedMemoryFacade at the same time
|
||||
// at this point no other query is allowed to reference this facade!
|
||||
// the old facade will die exactly here
|
||||
BOOST_ASSERT(facade.use_count() == 1);
|
||||
facade = std::move(new_facade);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
osrm::engine::Status status = plugin.HandleRequest(facade, parameters, result);
|
||||
|
||||
@@ -77,7 +101,20 @@ Engine::Engine(const EngineConfig &config)
|
||||
{
|
||||
if (config.use_shared_memory)
|
||||
{
|
||||
query_data_facade = std::make_shared<datafacade::SharedDataFacade>();
|
||||
if (!DataWatchdog::TryConnect())
|
||||
{
|
||||
throw util::exception(
|
||||
"No shared memory blocks found, have you forgotten to run osrm-datastore?");
|
||||
}
|
||||
|
||||
facade_update_mutex = std::make_unique<std::mutex>();
|
||||
watchdog = std::make_unique<DataWatchdog>();
|
||||
// this will always either return a value or throw an exception
|
||||
// in the initial run
|
||||
query_data_facade = watchdog->MaybeLoadNewRegion();
|
||||
BOOST_ASSERT(query_data_facade);
|
||||
BOOST_ASSERT(watchdog);
|
||||
BOOST_ASSERT(lock);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -106,32 +143,32 @@ Engine &Engine::operator=(Engine &&) noexcept = default;
|
||||
|
||||
Status Engine::Route(const api::RouteParameters ¶ms, util::json::Object &result) const
|
||||
{
|
||||
return RunQuery(lock, query_data_facade, params, *route_plugin, result);
|
||||
return RunQuery(lock, *facade_update_mutex, *watchdog, query_data_facade, params, *route_plugin, result);
|
||||
}
|
||||
|
||||
Status Engine::Table(const api::TableParameters ¶ms, util::json::Object &result) const
|
||||
{
|
||||
return RunQuery(lock, query_data_facade, params, *table_plugin, result);
|
||||
return RunQuery(lock, *facade_update_mutex, *watchdog, query_data_facade, params, *table_plugin, result);
|
||||
}
|
||||
|
||||
Status Engine::Nearest(const api::NearestParameters ¶ms, util::json::Object &result) const
|
||||
{
|
||||
return RunQuery(lock, query_data_facade, params, *nearest_plugin, result);
|
||||
return RunQuery(lock, *facade_update_mutex, *watchdog, query_data_facade, params, *nearest_plugin, result);
|
||||
}
|
||||
|
||||
Status Engine::Trip(const api::TripParameters ¶ms, util::json::Object &result) const
|
||||
{
|
||||
return RunQuery(lock, query_data_facade, params, *trip_plugin, result);
|
||||
return RunQuery(lock, *facade_update_mutex, *watchdog, query_data_facade, params, *trip_plugin, result);
|
||||
}
|
||||
|
||||
Status Engine::Match(const api::MatchParameters ¶ms, util::json::Object &result) const
|
||||
{
|
||||
return RunQuery(lock, query_data_facade, params, *match_plugin, result);
|
||||
return RunQuery(lock, *facade_update_mutex, *watchdog, query_data_facade, params, *match_plugin, result);
|
||||
}
|
||||
|
||||
Status Engine::Tile(const api::TileParameters ¶ms, std::string &result) const
|
||||
{
|
||||
return RunQuery(lock, query_data_facade, params, *tile_plugin, result);
|
||||
return RunQuery(lock, *facade_update_mutex, *watchdog, query_data_facade, params, *tile_plugin, result);
|
||||
}
|
||||
|
||||
} // engine ns
|
||||
|
||||
Reference in New Issue
Block a user