Adds a shared/exclusive lock around queries and CheckAndReloadFacade.
Without this, it's possible for CheckAndReloadFacade to start working while a query is still in progress, leading to undefined behaviour.
This commit is contained in:
parent
25c8711aad
commit
23b2154d98
@ -109,7 +109,16 @@ int OSRM::OSRM_impl::RunQuery(const RouteParameters &route_parameters, osrm::jso
|
||||
}
|
||||
|
||||
increase_concurrent_query_count();
|
||||
auto return_code = plugin_iterator->second->HandleRequest(route_parameters, json_result);
|
||||
BasePlugin::Status return_code;
|
||||
if (barrier) {
|
||||
// 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{
|
||||
(static_cast<SharedDataFacade<QueryEdge::EdgeData> *>(query_data_facade))->data_mutex};
|
||||
return_code = plugin_iterator->second->HandleRequest(route_parameters, json_result);
|
||||
} else {
|
||||
return_code = plugin_iterator->second->HandleRequest(route_parameters, json_result);
|
||||
}
|
||||
decrease_concurrent_query_count();
|
||||
return static_cast<int>(return_code);
|
||||
}
|
||||
|
@ -239,6 +239,8 @@ template <class EdgeDataT> class SharedDataFacade final : public BaseDataFacade<
|
||||
public:
|
||||
virtual ~SharedDataFacade() {}
|
||||
|
||||
boost::shared_mutex data_mutex;
|
||||
|
||||
SharedDataFacade()
|
||||
{
|
||||
if (!SharedMemory::RegionExists(CURRENT_REGIONS))
|
||||
@ -258,6 +260,14 @@ template <class EdgeDataT> class SharedDataFacade final : public BaseDataFacade<
|
||||
|
||||
void CheckAndReloadFacade()
|
||||
{
|
||||
if (CURRENT_LAYOUT != data_timestamp_ptr->layout ||
|
||||
CURRENT_DATA != data_timestamp_ptr->data ||
|
||||
CURRENT_TIMESTAMP != data_timestamp_ptr->timestamp)
|
||||
{
|
||||
// Get exclusive lock
|
||||
SimpleLogger().Write(logDEBUG) << "Updates available, getting exclusive lock";
|
||||
boost::unique_lock<boost::shared_mutex> lock(data_mutex);
|
||||
|
||||
if (CURRENT_LAYOUT != data_timestamp_ptr->layout ||
|
||||
CURRENT_DATA != data_timestamp_ptr->data)
|
||||
{
|
||||
@ -268,11 +278,19 @@ template <class EdgeDataT> class SharedDataFacade final : public BaseDataFacade<
|
||||
CURRENT_LAYOUT = data_timestamp_ptr->layout;
|
||||
CURRENT_DATA = data_timestamp_ptr->data;
|
||||
CURRENT_TIMESTAMP = 0; // Force trigger a reload
|
||||
|
||||
SimpleLogger().Write(logDEBUG) << "Current layout was different to new layout, swapping";
|
||||
}
|
||||
else
|
||||
{
|
||||
SimpleLogger().Write(logDEBUG) << "Current layout was same to new layout, not swapping";
|
||||
}
|
||||
|
||||
if (CURRENT_TIMESTAMP != data_timestamp_ptr->timestamp)
|
||||
{
|
||||
CURRENT_TIMESTAMP = data_timestamp_ptr->timestamp;
|
||||
|
||||
SimpleLogger().Write(logDEBUG) << "Performing data reload";
|
||||
m_layout_memory.reset(SharedMemoryFactory::Get(CURRENT_LAYOUT));
|
||||
|
||||
data_layout = (SharedDataLayout *) (m_layout_memory->Ptr());
|
||||
@ -283,9 +301,9 @@ template <class EdgeDataT> class SharedDataFacade final : public BaseDataFacade<
|
||||
const char *file_index_ptr =
|
||||
data_layout->GetBlockPtr<char>(shared_memory, SharedDataLayout::FILE_INDEX_PATH);
|
||||
file_index_path = boost::filesystem::path(file_index_ptr);
|
||||
if (!boost::filesystem::exists(file_index_path))
|
||||
{
|
||||
SimpleLogger().Write(logDEBUG) << "Leaf file name " << file_index_path.string();
|
||||
if (!boost::filesystem::exists(file_index_path)) {
|
||||
SimpleLogger().Write(logDEBUG) << "Leaf file name "
|
||||
<< file_index_path.string();
|
||||
throw osrm::exception("Could not load leaf index file. "
|
||||
"Is any data loaded into shared memory?");
|
||||
}
|
||||
@ -310,6 +328,8 @@ template <class EdgeDataT> class SharedDataFacade final : public BaseDataFacade<
|
||||
}
|
||||
}
|
||||
}
|
||||
SimpleLogger().Write(logDEBUG) << "Releasing exclusive lock";
|
||||
}
|
||||
}
|
||||
|
||||
// search graph access
|
||||
|
Loading…
Reference in New Issue
Block a user