Skip to content

Commit

Permalink
Add a Reading/Writer lock to the ScenarioConnectionCaches
Browse files Browse the repository at this point in the history
We add this shared mutex to make insure an ordely operation in a multithreaded environment.
Const read operation should be ok the map version, but others are not atomic.
  • Loading branch information
greenscientist committed Nov 24, 2023
1 parent 250d80e commit dae309b
Show file tree
Hide file tree
Showing 2 changed files with 7 additions and 1 deletion.
3 changes: 3 additions & 0 deletions include/connection_cache.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
#include <boost/uuid/uuid.hpp>
#include <memory>
#include <map>
#include <shared_mutex>

namespace TrRouting {

Expand Down Expand Up @@ -46,6 +47,7 @@ class ScenarioConnectionCacheOne : public ScenarioConnectionCache {
virtual void set(boost::uuids::uuid uuid, std::shared_ptr<ConnectionSet> cache);

private:
mutable std::shared_mutex mutex; //Reader/Writer locking
std::optional<boost::uuids::uuid> lastUuid;
std::shared_ptr<ConnectionSet> lastConnection;
};
Expand All @@ -68,6 +70,7 @@ class ScenarioConnectionCacheAll : public ScenarioConnectionCache {
virtual void set(boost::uuids::uuid uuid, std::shared_ptr<ConnectionSet> cache);

private:
mutable std::shared_mutex mutex; //Reader/Writer locking
std::map<boost::uuids::uuid, std::shared_ptr<ConnectionSet> > connectionSets;
};

Expand Down
5 changes: 4 additions & 1 deletion src/connection_cache.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
namespace TrRouting {
// ScenarioConnectionCacheOne
std::optional<std::shared_ptr<ConnectionSet>> ScenarioConnectionCacheOne::get(boost::uuids::uuid uuid) const {
std::shared_lock lock(mutex); //Sharing lock when reading
if (uuid == lastUuid) {
return std::optional(lastConnection);
} else {
Expand All @@ -16,12 +17,14 @@ namespace TrRouting {
}

void ScenarioConnectionCacheOne::set(boost::uuids::uuid uuid, std::shared_ptr<ConnectionSet> cache) {
std::unique_lock lock(mutex); //Exclusive lock when writing
lastUuid = uuid;
lastConnection = cache;
}

// ScenarioConnectionCacheAll
std::optional<std::shared_ptr<ConnectionSet>> ScenarioConnectionCacheAll::get(boost::uuids::uuid uuid) const {
std::shared_lock lock(mutex); //Sharing lock when reading
// Lookup the scenario uuid in the map. If found, returns it, if not, return a null_opt
auto connectionSetItr = connectionSets.find(uuid);
if (connectionSetItr != connectionSets.end()) {
Expand All @@ -33,7 +36,7 @@ namespace TrRouting {

void ScenarioConnectionCacheAll::set(boost::uuids::uuid uuid, std::shared_ptr<ConnectionSet> cache) {
spdlog::debug("Caching connection set for scenario {}", boost::uuids::to_string(uuid));

std::unique_lock lock(mutex); //Exclusive lock when writing
connectionSets[uuid] = cache;
}
}

0 comments on commit dae309b

Please sign in to comment.