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