#pragma once #include #include namespace NYT::NThreading { //////////////////////////////////////////////////////////////////////////////// //! A synchronization object to load and store nontrivial object. //! It looks like atomics but for objects. template class TAtomicObject { public: TAtomicObject() = default; template TAtomicObject(U&& u); template void Store(U&& u); //! Atomically replaces the old value with the new one and returns the old value. template T Exchange(U&& u); //! Atomically checks if the current value equals to #expected. //! If so, replaces it with #desired and returns |true|. //! Otherwise, copies it into #expected and returns |false|. bool CompareExchange(T& expected, const T& desired); //! Atomically transforms the value with function #func. template F> std::invoke_result_t Transform(const F& func); //! Atomicaly reads the value with function #func. template F> std::invoke_result_t Read(const F& func) const; T Load() const; private: T Object_; YT_DECLARE_SPIN_LOCK(NThreading::TReaderWriterSpinLock, Spinlock_); }; //////////////////////////////////////////////////////////////////////////////// template void ToProto(TSerialized* serialized, const TAtomicObject& original); template void FromProto(TAtomicObject* original, const TSerialized& serialized); //////////////////////////////////////////////////////////////////////////////// } // namespace NYT::NThreading #define ATOMIC_OBJECT_INL_H_ #include "atomic_object-inl.h" #undef ATOMIC_OBJECT_INL_H_