Don't retain SharedDataFacade between queries (#3485)
* Don't retain SharedDataFacade between queries * More caching code
This commit is contained in:
parent
2ed6b181c8
commit
f7ad2e1e26
@ -22,11 +22,6 @@ 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.
|
||||
//
|
||||
// TODO: This also needs a shared memory reader lock with other clients and
|
||||
// possibly osrm-datastore since updating the CURRENT_REGIONS data is not atomic.
|
||||
// Currently we enfore this by waiting that all queries have finished before
|
||||
// osrm-datastore writes to this section.
|
||||
class DataWatchdog
|
||||
{
|
||||
public:
|
||||
@ -57,7 +52,9 @@ class DataWatchdog
|
||||
const auto shared_timestamp =
|
||||
static_cast<const storage::SharedDataTimestamp *>(shared_regions->Ptr());
|
||||
|
||||
const auto get_locked_facade = [this, shared_timestamp]() {
|
||||
|
||||
const auto get_locked_facade = [this, shared_timestamp](
|
||||
const std::shared_ptr<datafacade::SharedMemoryDataFacade> &facade) {
|
||||
if (current_timestamp.region == storage::REGION_1)
|
||||
{
|
||||
return std::make_pair(RegionsLock(shared_barriers->region_1_mutex), facade);
|
||||
@ -76,8 +73,11 @@ class DataWatchdog
|
||||
|
||||
if (shared_timestamp->timestamp == current_timestamp.timestamp)
|
||||
{
|
||||
BOOST_ASSERT(shared_timestamp->region == current_timestamp.region);
|
||||
return get_locked_facade();
|
||||
if (auto facade = cached_facade.lock())
|
||||
{
|
||||
BOOST_ASSERT(shared_timestamp->region == current_timestamp.region);
|
||||
return get_locked_facade(facade);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -89,20 +89,41 @@ class DataWatchdog
|
||||
// in that case we don't modify anything
|
||||
if (shared_timestamp->timestamp == current_timestamp.timestamp)
|
||||
{
|
||||
BOOST_ASSERT(shared_timestamp->region == current_timestamp.region);
|
||||
|
||||
return get_locked_facade();
|
||||
if (auto facade = cached_facade.lock())
|
||||
{
|
||||
BOOST_ASSERT(shared_timestamp->region == current_timestamp.region);
|
||||
return get_locked_facade(facade);
|
||||
}
|
||||
}
|
||||
|
||||
// this thread has won and can update the data
|
||||
boost::upgrade_to_unique_lock<boost::upgrade_mutex> unique_facade_lock(facade_lock);
|
||||
|
||||
current_timestamp = *shared_timestamp;
|
||||
facade = std::make_shared<datafacade::SharedMemoryDataFacade>(shared_barriers,
|
||||
current_timestamp.region,
|
||||
current_timestamp.timestamp);
|
||||
// if two threads try to enter this critical section one will loose
|
||||
// and will find an up-to-date instance of the shared data facade
|
||||
if (shared_timestamp->timestamp == current_timestamp.timestamp)
|
||||
{
|
||||
// if the thread that updated the facade finishes the query before
|
||||
// we can aquire our handle here, we need to regenerate
|
||||
if (auto facade = cached_facade.lock())
|
||||
{
|
||||
BOOST_ASSERT(shared_timestamp->region == current_timestamp.region);
|
||||
|
||||
return get_locked_facade();
|
||||
return get_locked_facade(facade);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
current_timestamp = *shared_timestamp;
|
||||
}
|
||||
|
||||
auto new_facade =
|
||||
std::make_shared<datafacade::SharedMemoryDataFacade>(shared_barriers,
|
||||
current_timestamp.region,
|
||||
current_timestamp.timestamp);
|
||||
cached_facade = new_facade;
|
||||
|
||||
return get_locked_facade(new_facade);
|
||||
}
|
||||
|
||||
private:
|
||||
@ -114,7 +135,7 @@ class DataWatchdog
|
||||
std::unique_ptr<storage::SharedMemory> shared_regions;
|
||||
|
||||
mutable boost::shared_mutex facade_mutex;
|
||||
std::shared_ptr<datafacade::SharedMemoryDataFacade> facade;
|
||||
std::weak_ptr<datafacade::SharedMemoryDataFacade> cached_facade;
|
||||
storage::SharedDataTimestamp current_timestamp;
|
||||
};
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user