xref: /aosp_15_r20/external/pytorch/c10/util/Synchronized.h (revision da0073e96a02ea20f0ac840b70461e3646d07c45)
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