diff --git a/src/data/cassandra/impl/AsyncExecutor.hpp b/src/data/cassandra/impl/AsyncExecutor.hpp index 25a306cb..6ffb3503 100644 --- a/src/data/cassandra/impl/AsyncExecutor.hpp +++ b/src/data/cassandra/impl/AsyncExecutor.hpp @@ -23,6 +23,7 @@ #include "data/cassandra/Handle.hpp" #include "data/cassandra/Types.hpp" #include "data/cassandra/impl/RetryPolicy.hpp" +#include "util/Mutex.hpp" #include "util/log/Logger.hpp" #include @@ -64,8 +65,8 @@ class AsyncExecutor : public std::enable_shared_from_this future_; - std::mutex mtx_; + using OptionalFuture = std::optional; + util::Mutex future_; public: /** @@ -127,8 +128,8 @@ private: self = nullptr; // explicitly decrement refcount }; - std::scoped_lock const lck{mtx_}; - future_.emplace(handle.asyncExecute(data_, std::move(handler))); + auto future = future_.template lock(); + future->emplace(handle.asyncExecute(data_, std::move(handler))); } }; diff --git a/src/feed/impl/TrackableSignal.hpp b/src/feed/impl/TrackableSignal.hpp index 0384d7de..f190be3c 100644 --- a/src/feed/impl/TrackableSignal.hpp +++ b/src/feed/impl/TrackableSignal.hpp @@ -19,6 +19,8 @@ #pragma once +#include "util/Mutex.hpp" + #include #include #include @@ -45,8 +47,8 @@ class TrackableSignal { // map of connection and signal connection, key is the pointer of the connection object // allow disconnect to be called in the destructor of the connection - std::unordered_map connections_; - mutable std::mutex mutex_; + using ConnectionsMap = std::unordered_map; + util::Mutex connections_; using SignalType = boost::signals2::signal; SignalType signal_; @@ -64,8 +66,8 @@ public: bool connectTrackableSlot(ConnectionSharedPtr const& trackable, std::function slot) { - std::scoped_lock const lk(mutex_); - if (connections_.contains(trackable.get())) { + auto connections = connections_.template lock(); + if (connections->contains(trackable.get())) { return false; } @@ -73,7 +75,7 @@ public: // the trackable's destructor. However, the trackable can not be destroied when the slot is being called // either. track_foreign will hold a weak_ptr to the connection, which makes sure the connection is valid when // the slot is called. - connections_.emplace( + connections->emplace( trackable.get(), signal_.connect(typename SignalType::slot_type(slot).track_foreign(trackable)) ); return true; @@ -89,10 +91,9 @@ public: bool disconnect(ConnectionPtr trackablePtr) { - std::scoped_lock const lk(mutex_); - if (connections_.contains(trackablePtr)) { - connections_[trackablePtr].disconnect(); - connections_.erase(trackablePtr); + if (auto connections = connections_.template lock(); connections->contains(trackablePtr)) { + connections->operator[](trackablePtr).disconnect(); + connections->erase(trackablePtr); return true; } return false; @@ -115,8 +116,7 @@ public: std::size_t count() const { - std::scoped_lock const lk(mutex_); - return connections_.size(); + return connections_.template lock()->size(); } }; } // namespace feed::impl diff --git a/src/feed/impl/TrackableSignalMap.hpp b/src/feed/impl/TrackableSignalMap.hpp index 38dd91be..f9e3a06d 100644 --- a/src/feed/impl/TrackableSignalMap.hpp +++ b/src/feed/impl/TrackableSignalMap.hpp @@ -20,6 +20,7 @@ #pragma once #include "feed/impl/TrackableSignal.hpp" +#include "util/Mutex.hpp" #include @@ -49,8 +50,8 @@ class TrackableSignalMap { using ConnectionPtr = Session*; using ConnectionSharedPtr = std::shared_ptr; - mutable std::mutex mutex_; - std::unordered_map> signalsMap_; + using SignalsMap = std::unordered_map>; + util::Mutex signalsMap_; public: /** @@ -66,8 +67,8 @@ public: bool connectTrackableSlot(ConnectionSharedPtr const& trackable, Key const& key, std::function slot) { - std::scoped_lock const lk(mutex_); - return signalsMap_[key].connectTrackableSlot(trackable, slot); + auto map = signalsMap_.template lock(); + return map->operator[](key).connectTrackableSlot(trackable, slot); } /** @@ -80,14 +81,14 @@ public: bool disconnect(ConnectionPtr trackablePtr, Key const& key) { - std::scoped_lock const lk(mutex_); - if (!signalsMap_.contains(key)) + auto map = signalsMap_.template lock(); + if (!map->contains(key)) return false; - auto const disconnected = signalsMap_[key].disconnect(trackablePtr); + auto const disconnected = map->operator[](key).disconnect(trackablePtr); // clean the map if there is no connection left. - if (disconnected && signalsMap_[key].count() == 0) - signalsMap_.erase(key); + if (disconnected && map->operator[](key).count() == 0) + map->erase(key); return disconnected; } @@ -101,9 +102,9 @@ public: void emit(Key const& key, Args const&... args) { - std::scoped_lock const lk(mutex_); - if (signalsMap_.contains(key)) - signalsMap_[key].emit(args...); + auto map = signalsMap_.template lock(); + if (map->contains(key)) + map->operator[](key).emit(args...); } }; } // namespace feed::impl diff --git a/src/util/Mutex.hpp b/src/util/Mutex.hpp index e507f01f..bb952f97 100644 --- a/src/util/Mutex.hpp +++ b/src/util/Mutex.hpp @@ -34,7 +34,7 @@ class Mutex; * @tparam LockType type of lock * @tparam MutexType type of mutex */ -template typename LockType, typename MutexType> +template typename LockType, typename MutexType> class Lock { LockType lock_; ProtectedDataType& data_; @@ -129,7 +129,7 @@ public: * @tparam LockType The type of lock to use * @return A lock on the mutex and a reference to the protected data */ - template