2016-10-07 08:12:05 -04:00
|
|
|
#ifndef OSRM_ENGINE_DATA_WATCHDOG_HPP
|
|
|
|
#define OSRM_ENGINE_DATA_WATCHDOG_HPP
|
|
|
|
|
2017-01-18 07:44:17 -05:00
|
|
|
#include "engine/datafacade/contiguous_internalmem_datafacade.hpp"
|
|
|
|
#include "engine/datafacade/shared_memory_allocator.hpp"
|
2017-07-21 17:55:19 -04:00
|
|
|
#include "engine/datafacade_factory.hpp"
|
2016-10-06 19:51:34 -04:00
|
|
|
|
|
|
|
#include "storage/shared_datatype.hpp"
|
|
|
|
#include "storage/shared_memory.hpp"
|
2017-02-03 07:39:44 -05:00
|
|
|
#include "storage/shared_monitor.hpp"
|
2016-10-06 19:51:34 -04:00
|
|
|
|
2016-10-07 19:52:47 -04:00
|
|
|
#include <boost/interprocess/sync/named_upgradable_mutex.hpp>
|
2016-10-06 19:51:34 -04:00
|
|
|
#include <boost/thread/lock_types.hpp>
|
2016-10-11 19:09:20 -04:00
|
|
|
#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>
|
2016-12-25 19:00:37 -05:00
|
|
|
#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.
|
2017-01-09 15:40:33 -05:00
|
|
|
template <typename AlgorithmT> class DataWatchdog final
|
2016-10-06 19:51:34 -04:00
|
|
|
{
|
2017-02-03 07:39:44 -05:00
|
|
|
using mutex_type = typename storage::SharedMonitor<storage::SharedDataTimestamp>::mutex_type;
|
2017-01-09 15:40:33 -05:00
|
|
|
using FacadeT = datafacade::ContiguousInternalMemoryDataFacade<AlgorithmT>;
|
2017-02-03 07:39:44 -05:00
|
|
|
|
2016-10-06 19:51:34 -04:00
|
|
|
public:
|
2017-02-03 07:39:44 -05:00
|
|
|
DataWatchdog() : active(true), timestamp(0)
|
2016-10-06 19:51:34 -04:00
|
|
|
{
|
2017-01-05 17:38:48 -05:00
|
|
|
// create the initial facade before launching the watchdog thread
|
|
|
|
{
|
2017-02-03 07:39:44 -05:00
|
|
|
boost::interprocess::scoped_lock<mutex_type> current_region_lock(barrier.get_mutex());
|
2017-01-05 17:38:48 -05:00
|
|
|
|
2017-07-21 17:55:19 -04:00
|
|
|
facade_factory = DataFacadeFactory<const FacadeT>(
|
|
|
|
std::make_shared<datafacade::SharedMemoryAllocator>(barrier.data().region));
|
2017-02-03 07:39:44 -05:00
|
|
|
timestamp = barrier.data().timestamp;
|
2017-01-05 17:38:48 -05:00
|
|
|
}
|
|
|
|
|
2016-12-25 19:00:37 -05:00
|
|
|
watcher = std::thread(&DataWatchdog::Run, this);
|
|
|
|
}
|
|
|
|
|
2017-03-01 15:17:34 -05:00
|
|
|
~DataWatchdog()
|
2016-12-25 19:00:37 -05:00
|
|
|
{
|
|
|
|
active = false;
|
2017-02-03 07:39:44 -05:00
|
|
|
barrier.notify_all();
|
2016-12-25 19:00:37 -05:00
|
|
|
watcher.join();
|
2016-10-06 19:51:34 -04:00
|
|
|
}
|
|
|
|
|
2017-07-21 17:55:19 -04:00
|
|
|
std::shared_ptr<const FacadeT> Get(const api::BaseParameters ¶ms) const { return facade_factory.Get(params); }
|
|
|
|
std::shared_ptr<const FacadeT> Get(const api::TileParameters ¶ms) const { return facade_factory.Get(params); }
|
2016-10-11 19:09:20 -04:00
|
|
|
|
2016-12-25 19:00:37 -05:00
|
|
|
private:
|
|
|
|
void Run()
|
|
|
|
{
|
|
|
|
while (active)
|
2016-10-06 19:51:34 -04:00
|
|
|
{
|
2017-02-03 07:39:44 -05:00
|
|
|
boost::interprocess::scoped_lock<mutex_type> current_region_lock(barrier.get_mutex());
|
2017-01-05 17:38:48 -05:00
|
|
|
|
2017-02-03 07:39:44 -05:00
|
|
|
while (active && timestamp == barrier.data().timestamp)
|
2017-01-05 17:38:48 -05:00
|
|
|
{
|
2017-02-03 07:39:44 -05:00
|
|
|
barrier.wait(current_region_lock);
|
2017-01-05 17:38:48 -05:00
|
|
|
}
|
|
|
|
|
2017-02-03 07:39:44 -05:00
|
|
|
if (timestamp != barrier.data().timestamp)
|
2017-01-03 06:06:55 -05:00
|
|
|
{
|
2017-02-03 07:39:44 -05:00
|
|
|
auto region = barrier.data().region;
|
2017-07-21 17:55:19 -04:00
|
|
|
facade_factory = DataFacadeFactory<const FacadeT>(
|
|
|
|
std::make_shared<datafacade::SharedMemoryAllocator>(region));
|
2017-02-03 07:39:44 -05:00
|
|
|
timestamp = barrier.data().timestamp;
|
|
|
|
util::Log() << "updated facade to region " << region << " with timestamp "
|
2017-01-27 04:05:34 -05:00
|
|
|
<< timestamp;
|
2017-01-03 06:06:55 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-12-25 19:00:37 -05:00
|
|
|
util::Log() << "DataWatchdog thread stopped";
|
2016-10-06 19:51:34 -04:00
|
|
|
}
|
|
|
|
|
2017-02-03 07:39:44 -05:00
|
|
|
storage::SharedMonitor<storage::SharedDataTimestamp> barrier;
|
2016-12-25 19:00:37 -05:00
|
|
|
std::thread watcher;
|
|
|
|
bool active;
|
|
|
|
unsigned timestamp;
|
2017-07-21 17:55:19 -04:00
|
|
|
DataFacadeFactory<const FacadeT> facade_factory;
|
2016-10-06 19:51:34 -04:00
|
|
|
};
|
|
|
|
}
|
|
|
|
}
|
2016-10-07 08:12:05 -04:00
|
|
|
|
|
|
|
#endif
|