osrm-backend/include/engine/data_watchdog.hpp

96 lines
3.2 KiB
C++
Raw Normal View History

2016-10-07 08:12:05 -04:00
#ifndef OSRM_ENGINE_DATA_WATCHDOG_HPP
#define OSRM_ENGINE_DATA_WATCHDOG_HPP
#include "engine/datafacade/contiguous_internalmem_datafacade.hpp"
#include "engine/datafacade/shared_memory_allocator.hpp"
#include "engine/datafacade_factory.hpp"
2016-10-06 19:51:34 -04:00
#include "storage/shared_datatype.hpp"
#include "storage/shared_memory.hpp"
#include "storage/shared_monitor.hpp"
2016-10-06 19:51:34 -04:00
#include <boost/interprocess/sync/named_upgradable_mutex.hpp>
2016-10-06 19:51:34 -04:00
#include <boost/thread/lock_types.hpp>
#include <boost/thread/locks.hpp>
2016-10-07 12:53:49 -04:00
#include <boost/thread/shared_mutex.hpp>
2016-10-06 19:51:34 -04:00
#include <memory>
#include <thread>
2016-10-06 19:51:34 -04:00
namespace osrm
{
namespace engine
{
// This class monitors the shared memory region that contains the pointers to
// the data and layout regions that should be used. This region is updated
// once a new dataset arrives.
template <template<typename A> class FacadeT, typename AlgorithmT> class DataWatchdog;
template <typename AlgorithmT> class DataWatchdog<datafacade::ContiguousInternalMemoryDataFacade,AlgorithmT> final
2016-10-06 19:51:34 -04:00
{
using mutex_type = typename storage::SharedMonitor<storage::SharedDataTimestamp>::mutex_type;
using Facade = datafacade::ContiguousInternalMemoryDataFacade<AlgorithmT>;
2016-10-06 19:51:34 -04:00
public:
DataWatchdog() : active(true), timestamp(0)
2016-10-06 19:51:34 -04:00
{
// create the initial facade before launching the watchdog thread
{
boost::interprocess::scoped_lock<mutex_type> current_region_lock(barrier.get_mutex());
facade_factory = DataFacadeFactory<datafacade::ContiguousInternalMemoryDataFacade, AlgorithmT>(
std::make_shared<datafacade::SharedMemoryAllocator>(barrier.data().region));
timestamp = barrier.data().timestamp;
}
watcher = std::thread(&DataWatchdog::Run, this);
}
~DataWatchdog()
{
active = false;
barrier.notify_all();
watcher.join();
2016-10-06 19:51:34 -04:00
}
std::shared_ptr<const Facade> Get(const api::BaseParameters &params) const { return facade_factory.Get(params); }
std::shared_ptr<const Facade> Get(const api::TileParameters &params) const { return facade_factory.Get(params); }
private:
void Run()
{
while (active)
2016-10-06 19:51:34 -04:00
{
boost::interprocess::scoped_lock<mutex_type> current_region_lock(barrier.get_mutex());
while (active && timestamp == barrier.data().timestamp)
{
barrier.wait(current_region_lock);
}
if (timestamp != barrier.data().timestamp)
{
auto region = barrier.data().region;
facade_factory = DataFacadeFactory<datafacade::ContiguousInternalMemoryDataFacade, AlgorithmT>(
std::make_shared<datafacade::SharedMemoryAllocator>(region));
timestamp = barrier.data().timestamp;
util::Log() << "updated facade to region " << region << " with timestamp "
<< timestamp;
}
}
util::Log() << "DataWatchdog thread stopped";
2016-10-06 19:51:34 -04:00
}
storage::SharedMonitor<storage::SharedDataTimestamp> barrier;
std::thread watcher;
bool active;
unsigned timestamp;
DataFacadeFactory<datafacade::ContiguousInternalMemoryDataFacade, AlgorithmT> facade_factory;
2016-10-06 19:51:34 -04:00
};
}
}
2016-10-07 08:12:05 -04:00
#endif