Restore --max-wait and file_lock for osrm-datastore

This commit is contained in:
Patrick Niklaus
2017-01-05 22:38:48 +00:00
committed by Patrick Niklaus
parent a7bb26f2d6
commit 104e23abf3
12 changed files with 234 additions and 120 deletions
+25 -17
View File
@@ -26,10 +26,20 @@ namespace engine
class DataWatchdog
{
public:
DataWatchdog()
: active(true)
, timestamp(0)
DataWatchdog() : active(true), timestamp(0)
{
// create the initial facade before launching the watchdog thread
{
boost::interprocess::scoped_lock<boost::interprocess::named_mutex> current_region_lock(
barrier.region_mutex);
auto shared_memory = makeSharedMemory(storage::CURRENT_REGION);
auto current = static_cast<storage::SharedDataTimestamp *>(shared_memory->Ptr());
facade = std::make_shared<datafacade::SharedMemoryDataFacade>(current->region);
timestamp = current->timestamp;
}
watcher = std::thread(&DataWatchdog::Run, this);
}
@@ -46,36 +56,34 @@ class DataWatchdog
return storage::SharedMemory::RegionExists(storage::CURRENT_REGION);
}
auto GetDataFacade() const
{
return facade;
}
auto GetDataFacade() const { return facade; }
private:
void Run()
{
boost::interprocess::scoped_lock<boost::interprocess::named_mutex>
current_region_lock(barrier.region_mutex);
auto shared_memory = makeSharedMemory(storage::CURRENT_REGION);
auto current = static_cast<storage::SharedDataTimestamp *>(shared_memory->Ptr());
while (active)
{
boost::interprocess::scoped_lock<boost::interprocess::named_mutex> current_region_lock(
barrier.region_mutex);
while (active && timestamp == current->timestamp)
{
barrier.region_condition.wait(current_region_lock);
}
if (timestamp != current->timestamp)
{
facade = std::make_shared<datafacade::SharedMemoryDataFacade>(current->region);
timestamp = current->timestamp;
util::Log() << "updated facade to region " << storage::regionToString(current->region)
<< " with timestamp " << current->timestamp;
util::Log() << "updated facade to region "
<< storage::regionToString(current->region) << " with timestamp "
<< current->timestamp;
}
barrier.region_condition.wait(current_region_lock);
}
facade.reset();
util::Log() << "DataWatchdog thread stopped";
}
@@ -30,9 +30,7 @@ class SharedMemoryDataFacade : public ContiguousInternalMemoryDataFacadeBase
SharedMemoryDataFacade() {}
public:
SharedMemoryDataFacade(storage::SharedDataType data_region)
: data_region(data_region)
SharedMemoryDataFacade(storage::SharedDataType data_region) : data_region(data_region)
{
util::Log(logDEBUG) << "Loading new data for region " << regionToString(data_region);
+9 -2
View File
@@ -4,6 +4,8 @@
#include <boost/interprocess/sync/named_condition.hpp>
#include <boost/interprocess/sync/named_mutex.hpp>
#include "util/retry_lock.hpp"
namespace osrm
{
namespace storage
@@ -13,8 +15,8 @@ struct SharedBarriers
{
SharedBarriers()
: region_mutex(boost::interprocess::open_or_create, "osrm-region")
, region_condition(boost::interprocess::open_or_create, "osrm-region-cv")
: region_mutex(boost::interprocess::open_or_create, "osrm-region"),
region_condition(boost::interprocess::open_or_create, "osrm-region-cv")
{
}
@@ -24,6 +26,11 @@ struct SharedBarriers
boost::interprocess::named_condition::remove("osrm-region-cv");
}
static RetryLock getLockWithRetry(int timeout_seconds)
{
return RetryLock(timeout_seconds, "osrm-region");
}
boost::interprocess::named_mutex region_mutex;
boost::interprocess::named_condition region_condition;
};
+18 -8
View File
@@ -23,6 +23,7 @@
#include <algorithm>
#include <exception>
#include <thread>
namespace osrm
{
@@ -106,6 +107,20 @@ class SharedMemory
return Remove(key);
}
void WaitForDetach()
{
auto shmid = shm.get_shmid();
::shmid_ds xsi_ds;
do
{
int ret = ::shmctl(shmid, IPC_STAT, &xsi_ds);
(void)ret; // no unused warning
BOOST_ASSERT(ret >= 0);
std::this_thread::sleep_for(std::chrono::microseconds(100));
} while (xsi_ds.shm_nattch > 1);
}
private:
static bool RegionExists(const boost::interprocess::xsi_key &key)
{
@@ -147,17 +162,13 @@ class SharedMemory
public:
void *Ptr() const { return region.get_address(); }
SharedMemory(const boost::filesystem::path &lock_file,
const int id,
const uint64_t size = 0)
SharedMemory(const boost::filesystem::path &lock_file, const int id, const uint64_t size = 0)
{
sprintf(key, "%s.%d", "osrm.lock", id);
if (0 == size)
{ // read_only
shm = boost::interprocess::shared_memory_object(
boost::interprocess::open_only,
key,
boost::interprocess::read_only);
boost::interprocess::open_only, key, boost::interprocess::read_only);
region = boost::interprocess::mapped_region(shm, boost::interprocess::read_only);
}
else
@@ -225,8 +236,7 @@ class SharedMemory
#endif
template <typename IdentifierT, typename LockFileT = OSRMLockFile>
std::unique_ptr<SharedMemory>
makeSharedMemory(const IdentifierT &id, const uint64_t size = 0)
std::unique_ptr<SharedMemory> makeSharedMemory(const IdentifierT &id, const uint64_t size = 0)
{
try
{
+1 -3
View File
@@ -31,7 +31,6 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "storage/shared_datatype.hpp"
#include "storage/storage_config.hpp"
#include <boost/interprocess/sync/named_mutex.hpp>
#include <boost/filesystem/path.hpp>
#include <string>
@@ -45,14 +44,13 @@ class Storage
public:
Storage(StorageConfig config);
int Run();
int Run(int max_wait);
void PopulateLayout(DataLayout &layout);
void PopulateData(const DataLayout &layout, char *memory_ptr);
private:
StorageConfig config;
boost::interprocess::named_mutex datastore_mutex;
};
}
}
+49
View File
@@ -0,0 +1,49 @@
#ifndef OSRM_RETRY_TIMED_LOCK_HPP
#define OSRM_RETRY_TIMED_LOCK_HPP
#include <boost/date_time/posix_time/posix_time.hpp>
#include <boost/interprocess/exceptions.hpp>
#include <boost/interprocess/sync/named_mutex.hpp>
#include <boost/interprocess/sync/scoped_lock.hpp>
class RetryLock
{
public:
RetryLock(int timeout_seconds, const char *name)
: timeout_seconds(timeout_seconds), name(name),
mutex(std::make_unique<boost::interprocess::named_mutex>(
boost::interprocess::open_or_create, name)),
internal_lock(*mutex, boost::interprocess::defer_lock)
{
}
bool TryLock()
{
if (timeout_seconds >= 0)
{
return internal_lock.timed_lock(boost::posix_time::microsec_clock::universal_time() +
boost::posix_time::seconds(timeout_seconds));
}
else
{
internal_lock.lock();
return true;
}
}
void ForceLock()
{
mutex.reset();
boost::interprocess::named_mutex::remove(name);
mutex = std::make_unique<boost::interprocess::named_mutex>(
boost::interprocess::open_or_create, name);
}
private:
int timeout_seconds;
const char *name;
std::unique_ptr<boost::interprocess::named_mutex> mutex;
boost::interprocess::scoped_lock<boost::interprocess::named_mutex> internal_lock;
};
#endif