1*da0073e9SAndroid Build Coastguard Worker #pragma once 2*da0073e9SAndroid Build Coastguard Worker 3*da0073e9SAndroid Build Coastguard Worker #include <mutex> 4*da0073e9SAndroid Build Coastguard Worker 5*da0073e9SAndroid Build Coastguard Worker namespace c10 { 6*da0073e9SAndroid Build Coastguard Worker 7*da0073e9SAndroid Build Coastguard Worker /** 8*da0073e9SAndroid Build Coastguard Worker * A very simple Synchronization class for error-free use of data 9*da0073e9SAndroid Build Coastguard Worker * in a multi-threaded context. See folly/docs/Synchronized.md for 10*da0073e9SAndroid Build Coastguard Worker * the inspiration of this class. 11*da0073e9SAndroid Build Coastguard Worker * 12*da0073e9SAndroid Build Coastguard Worker * Full URL: 13*da0073e9SAndroid Build Coastguard Worker * https://github.com/facebook/folly/blob/main/folly/docs/Synchronized.md 14*da0073e9SAndroid Build Coastguard Worker * 15*da0073e9SAndroid Build Coastguard Worker * This class implements a small subset of the generic functionality 16*da0073e9SAndroid Build Coastguard Worker * implemented by folly:Synchronized<T>. Specifically, only withLock<T> 17*da0073e9SAndroid Build Coastguard Worker * is implemented here since it's the smallest possible API that is 18*da0073e9SAndroid Build Coastguard Worker * able to cover a large surface area of functionality offered by 19*da0073e9SAndroid Build Coastguard Worker * folly::Synchronized<T>. 20*da0073e9SAndroid Build Coastguard Worker */ 21*da0073e9SAndroid Build Coastguard Worker template <typename T> 22*da0073e9SAndroid Build Coastguard Worker class Synchronized final { 23*da0073e9SAndroid Build Coastguard Worker mutable std::mutex mutex_; 24*da0073e9SAndroid Build Coastguard Worker T data_; 25*da0073e9SAndroid Build Coastguard Worker 26*da0073e9SAndroid Build Coastguard Worker public: 27*da0073e9SAndroid Build Coastguard Worker Synchronized() = default; Synchronized(T const & data)28*da0073e9SAndroid Build Coastguard Worker Synchronized(T const& data) : data_(data) {} Synchronized(T && data)29*da0073e9SAndroid Build Coastguard Worker Synchronized(T&& data) : data_(std::move(data)) {} 30*da0073e9SAndroid Build Coastguard Worker 31*da0073e9SAndroid Build Coastguard Worker // Don't permit copy construction, move, assignment, or 32*da0073e9SAndroid Build Coastguard Worker // move assignment, since the underlying std::mutex 33*da0073e9SAndroid Build Coastguard Worker // isn't necessarily copyable/moveable. 34*da0073e9SAndroid Build Coastguard Worker Synchronized(Synchronized const&) = delete; 35*da0073e9SAndroid Build Coastguard Worker Synchronized(Synchronized&&) = delete; 36*da0073e9SAndroid Build Coastguard Worker Synchronized operator=(Synchronized const&) = delete; 37*da0073e9SAndroid Build Coastguard Worker Synchronized operator=(Synchronized&&) = delete; 38*da0073e9SAndroid Build Coastguard Worker 39*da0073e9SAndroid Build Coastguard Worker /** 40*da0073e9SAndroid Build Coastguard Worker * To use, call withLock<T> with a callback that accepts T either 41*da0073e9SAndroid Build Coastguard Worker * by copy or by reference. Use the protected variable in the 42*da0073e9SAndroid Build Coastguard Worker * provided callback safely. 43*da0073e9SAndroid Build Coastguard Worker */ 44*da0073e9SAndroid Build Coastguard Worker template <typename CB> withLock(CB && cb)45*da0073e9SAndroid Build Coastguard Worker auto withLock(CB&& cb) { 46*da0073e9SAndroid Build Coastguard Worker std::lock_guard<std::mutex> guard(this->mutex_); 47*da0073e9SAndroid Build Coastguard Worker return std::forward<CB>(cb)(this->data_); 48*da0073e9SAndroid Build Coastguard Worker } 49*da0073e9SAndroid Build Coastguard Worker 50*da0073e9SAndroid Build Coastguard Worker /** 51*da0073e9SAndroid Build Coastguard Worker * To use, call withLock<T> with a callback that accepts T either 52*da0073e9SAndroid Build Coastguard Worker * by copy or by const reference. Use the protected variable in 53*da0073e9SAndroid Build Coastguard Worker * the provided callback safely. 54*da0073e9SAndroid Build Coastguard Worker */ 55*da0073e9SAndroid Build Coastguard Worker template <typename CB> withLock(CB && cb)56*da0073e9SAndroid Build Coastguard Worker auto withLock(CB&& cb) const { 57*da0073e9SAndroid Build Coastguard Worker std::lock_guard<std::mutex> guard(this->mutex_); 58*da0073e9SAndroid Build Coastguard Worker return std::forward<CB>(cb)(this->data_); 59*da0073e9SAndroid Build Coastguard Worker } 60*da0073e9SAndroid Build Coastguard Worker }; 61*da0073e9SAndroid Build Coastguard Worker } // end namespace c10 62