#pragma once #include namespace c10 { /** * A very simple Synchronization class for error-free use of data * in a multi-threaded context. See folly/docs/Synchronized.md for * the inspiration of this class. * * Full URL: * https://github.com/facebook/folly/blob/main/folly/docs/Synchronized.md * * This class implements a small subset of the generic functionality * implemented by folly:Synchronized. Specifically, only withLock * is implemented here since it's the smallest possible API that is * able to cover a large surface area of functionality offered by * folly::Synchronized. */ template class Synchronized final { mutable std::mutex mutex_; T data_; public: Synchronized() = default; Synchronized(T const& data) : data_(data) {} Synchronized(T&& data) : data_(std::move(data)) {} // Don't permit copy construction, move, assignment, or // move assignment, since the underlying std::mutex // isn't necessarily copyable/moveable. Synchronized(Synchronized const&) = delete; Synchronized(Synchronized&&) = delete; Synchronized operator=(Synchronized const&) = delete; Synchronized operator=(Synchronized&&) = delete; /** * To use, call withLock with a callback that accepts T either * by copy or by reference. Use the protected variable in the * provided callback safely. */ template auto withLock(CB&& cb) { std::lock_guard guard(this->mutex_); return std::forward(cb)(this->data_); } /** * To use, call withLock with a callback that accepts T either * by copy or by const reference. Use the protected variable in * the provided callback safely. */ template auto withLock(CB&& cb) const { std::lock_guard guard(this->mutex_); return std::forward(cb)(this->data_); } }; } // end namespace c10