#include "engine/engine.hpp" #include "engine/engine_config.hpp" #include "engine/api/route_parameters.hpp" #include "engine/status.hpp" #include "engine/plugins/distance_table.hpp" //#include "engine/plugins/hello_world.hpp" //#include "engine/plugins/nearest.hpp" //#include "engine/plugins/timestamp.hpp" //#include "engine/plugins/trip.hpp" #include "engine/plugins/viaroute.hpp" //#include "engine/plugins/match.hpp" //#include "engine/plugins/tile.hpp" #include "engine/datafacade/datafacade_base.hpp" #include "engine/datafacade/internal_datafacade.hpp" #include "engine/datafacade/shared_datafacade.hpp" #include "storage/shared_barriers.hpp" #include "util/make_unique.hpp" #include "util/routed_options.hpp" #include "util/simple_logger.hpp" #include #include #include #include #include #include #include #include namespace osrm { namespace engine { struct Engine::EngineLock { // will only be initialized if shared memory is used storage::SharedBarriers barrier; // decrease number of concurrent queries void DecreaseQueryCount(); // increase number of concurrent queries void IncreaseQueryCount(); }; // decrease number of concurrent queries void Engine::EngineLock::DecreaseQueryCount() { // lock query boost::interprocess::scoped_lock query_lock( barrier.query_mutex); // decrement query count --(barrier.number_of_queries); BOOST_ASSERT_MSG(0 <= barrier.number_of_queries, "invalid number of queries"); // notify all processes that were waiting for this condition if (0 == barrier.number_of_queries) { barrier.no_running_queries_condition.notify_all(); } } // increase number of concurrent queries void Engine::EngineLock::IncreaseQueryCount() { // lock update pending boost::interprocess::scoped_lock pending_lock( barrier.pending_update_mutex); // lock query boost::interprocess::scoped_lock query_lock( barrier.query_mutex); // unlock update pending pending_lock.unlock(); // increment query count ++(barrier.number_of_queries); } } // ns engine } // ns osrm namespace { // Abstracted away the query locking into a template function // Works the same for every plugin. template osrm::engine::Status RunQuery(const std::unique_ptr &lock, osrm::engine::datafacade::BaseDataFacade &facade, const ParameterT ¶meters, PluginT &plugin, osrm::util::json::Object &json_result) { if (!lock) { return plugin.HandleRequest(parameters, json_result); } BOOST_ASSERT(lock); lock->IncreaseQueryCount(); auto &shared_facade = static_cast(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 data_lock{shared_facade.data_mutex}; osrm::engine::Status status = plugin.HandleRequest(parameters, json_result); lock->DecreaseQueryCount(); return status; } } // anon. ns namespace osrm { namespace engine { Engine::Engine(EngineConfig &config) { if (config.use_shared_memory) { lock = util::make_unique(); query_data_facade = util::make_unique(); } else { util::populate_base_path(config.server_paths); query_data_facade = util::make_unique(config.server_paths); } route_plugin = util::make_unique(*query_data_facade, config.max_locations_viaroute); } Status Engine::Route(const api::RouteParameters &route_parameters, util::json::Object &result) { return RunQuery(lock, *query_data_facade, route_parameters, *route_plugin, result); } } // engine ns } // osrm ns