diff options
author | lukyan <lukyan@yandex-team.ru> | 2022-02-10 16:48:13 +0300 |
---|---|---|
committer | Daniil Cherednik <dcherednik@yandex-team.ru> | 2022-02-10 16:48:13 +0300 |
commit | 96647fad5355ff5ef45a00a6d85c097028584ab0 (patch) | |
tree | b222e5ac2e2e98872661c51ccceee5da0d291e13 /library/cpp/yt/memory/ref_counted.h | |
parent | 3e359c7e6344b01b8d0b0fc619297ffdc2644c49 (diff) | |
download | ydb-96647fad5355ff5ef45a00a6d85c097028584ab0.tar.gz |
Restoring authorship annotation for <lukyan@yandex-team.ru>. Commit 2 of 2.
Diffstat (limited to 'library/cpp/yt/memory/ref_counted.h')
-rw-r--r-- | library/cpp/yt/memory/ref_counted.h | 264 |
1 files changed, 132 insertions, 132 deletions
diff --git a/library/cpp/yt/memory/ref_counted.h b/library/cpp/yt/memory/ref_counted.h index cf03aedc1f..b683615b83 100644 --- a/library/cpp/yt/memory/ref_counted.h +++ b/library/cpp/yt/memory/ref_counted.h @@ -5,23 +5,23 @@ #include <library/cpp/yt/assert/assert.h> #include <library/cpp/ytalloc/api/ytalloc.h> - + #include <atomic> namespace NYT { //////////////////////////////////////////////////////////////////////////////// -//! A technical base class for ref-counted objects and promise states. +//! A technical base class for ref-counted objects and promise states. class TRefCountedBase { public: TRefCountedBase() = default; - - // Make destructor protected + + // Make destructor protected virtual ~TRefCountedBase() noexcept = default; - virtual void DestroyRefCounted() = 0; + virtual void DestroyRefCounted() = 0; private: TRefCountedBase(const TRefCountedBase&) = delete; @@ -33,156 +33,156 @@ private: //////////////////////////////////////////////////////////////////////////////// -template <class T, class = void> -struct TFreeMemory +template <class T, class = void> +struct TFreeMemory { - static void Do(void* ptr) - { - NYTAlloc::FreeNonNull(ptr); - } -}; + static void Do(void* ptr) + { + NYTAlloc::FreeNonNull(ptr); + } +}; -template <class T> +template <class T> struct TFreeMemory<T, std::void_t<typename T::TAllocator>> -{ - static void Do(void* ptr) - { - using TAllocator = typename T::TAllocator; - TAllocator::Free(ptr); - } -}; +{ + static void Do(void* ptr) + { + using TAllocator = typename T::TAllocator; + TAllocator::Free(ptr); + } +}; -//////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// class TRefCounter -{ +{ public: - //! Returns current number of strong references to the object. + //! Returns current number of strong references to the object. /*! * Note that you should never ever use this method in production code. * This method is mainly for debugging purposes. */ int GetRefCount() const noexcept; - //! Increments the strong reference counter. - void Ref() const noexcept; - - //! Increments the strong reference counter if it is not null. - bool TryRef() const noexcept; - - //! Decrements the strong reference counter. - bool Unref() const; - - //! Returns current number of weak references to the object. - int GetWeakRefCount() const noexcept; - - //! Increments the weak reference counter. - void WeakRef() const noexcept; - - //! Decrements the weak reference counter. - bool WeakUnref() const; - -private: - mutable std::atomic<int> StrongCount_ = 1; - mutable std::atomic<int> WeakCount_ = 1; -}; - -//////////////////////////////////////////////////////////////////////////////// - -template <class T> + //! Increments the strong reference counter. + void Ref() const noexcept; + + //! Increments the strong reference counter if it is not null. + bool TryRef() const noexcept; + + //! Decrements the strong reference counter. + bool Unref() const; + + //! Returns current number of weak references to the object. + int GetWeakRefCount() const noexcept; + + //! Increments the weak reference counter. + void WeakRef() const noexcept; + + //! Decrements the weak reference counter. + bool WeakUnref() const; + +private: + mutable std::atomic<int> StrongCount_ = 1; + mutable std::atomic<int> WeakCount_ = 1; +}; + +//////////////////////////////////////////////////////////////////////////////// + +template <class T> const TRefCounter* GetRefCounter(const T* obj); - -template <class T> + +template <class T> void DestroyRefCounted(const T* obj); - -template <class T> + +template <class T> void DeallocateRefCounted(const T* obj); - -//////////////////////////////////////////////////////////////////////////////// - -// API - -template <class T> -void Ref(T* obj); - -template <class T> -void Unref(T* obj); - -//////////////////////////////////////////////////////////////////////////////// - -struct TRefCounted - : public TRefCountedBase - , public TRefCounter -{ - void Unref() const; - - void WeakUnref() const; - - template <class T> - static void DestroyRefCountedImpl(T* ptr); -}; - -//////////////////////////////////////////////////////////////////////////////// - -// Forward declaration. -template <class T> -class TIntrusivePtr; - -using TRefCountedPtr = TIntrusivePtr<TRefCounted>; - -// A bunch of helpful macros that enable working with intrusive pointers to incomplete types. -/* - * Typically when you have a forward-declared type |T| and an instance - * of |TIntrusivePtr<T>| you need the complete definition of |T| to work with - * the pointer even if you're not actually using the members of |T|. - * E.g. the dtor of |TIntrusivePtr<T>|, should you ever need it, must be able - * to unref an instance of |T| and eventually destroy it. - * This may force #inclusion of way more headers than really seems necessary. - * - * |DECLARE_REFCOUNTED_STRUCT|, |DECLARE_REFCOUNTED_CLASS|, and |DEFINE_REFCOUNTED_TYPE| - * alleviate this issue by forcing TIntrusivePtr to work with the free-standing overloads - * of |Ref| and |Unref| instead of their template version. - * These overloads are declared together with the forward declaration of |T| and - * are subsequently defined afterwards. - */ - -#define DECLARE_REFCOUNTED_TYPE(type) \ + +//////////////////////////////////////////////////////////////////////////////// + +// API + +template <class T> +void Ref(T* obj); + +template <class T> +void Unref(T* obj); + +//////////////////////////////////////////////////////////////////////////////// + +struct TRefCounted + : public TRefCountedBase + , public TRefCounter +{ + void Unref() const; + + void WeakUnref() const; + + template <class T> + static void DestroyRefCountedImpl(T* ptr); +}; + +//////////////////////////////////////////////////////////////////////////////// + +// Forward declaration. +template <class T> +class TIntrusivePtr; + +using TRefCountedPtr = TIntrusivePtr<TRefCounted>; + +// A bunch of helpful macros that enable working with intrusive pointers to incomplete types. +/* + * Typically when you have a forward-declared type |T| and an instance + * of |TIntrusivePtr<T>| you need the complete definition of |T| to work with + * the pointer even if you're not actually using the members of |T|. + * E.g. the dtor of |TIntrusivePtr<T>|, should you ever need it, must be able + * to unref an instance of |T| and eventually destroy it. + * This may force #inclusion of way more headers than really seems necessary. + * + * |DECLARE_REFCOUNTED_STRUCT|, |DECLARE_REFCOUNTED_CLASS|, and |DEFINE_REFCOUNTED_TYPE| + * alleviate this issue by forcing TIntrusivePtr to work with the free-standing overloads + * of |Ref| and |Unref| instead of their template version. + * These overloads are declared together with the forward declaration of |T| and + * are subsequently defined afterwards. + */ + +#define DECLARE_REFCOUNTED_TYPE(type) \ using type ## Ptr = ::NYT::TIntrusivePtr<type>; \ - \ + \ [[maybe_unused]] ATTRIBUTE_USED const ::NYT::TRefCounter* GetRefCounter(const type* obj); \ [[maybe_unused]] ATTRIBUTE_USED void DestroyRefCounted(const type* obj); \ [[maybe_unused]] ATTRIBUTE_USED void DeallocateRefCounted(const type* obj); - -//! Forward-declares a class type, defines an intrusive pointer for it, and finally -//! declares Ref/Unref overloads. Use this macro in |public.h|-like files. -#define DECLARE_REFCOUNTED_CLASS(type) \ - class type; \ - DECLARE_REFCOUNTED_TYPE(type) - -//! Forward-declares a struct type, defines an intrusive pointer for it, and finally -//! declares Ref/Unref overloads. Use this macro in |public.h|-like files. -#define DECLARE_REFCOUNTED_STRUCT(type) \ - struct type; \ - DECLARE_REFCOUNTED_TYPE(type) - -//! Provides implementations for Ref/Unref overloads. Use this macro right -//! after the type's full definition. -#define DEFINE_REFCOUNTED_TYPE(type) \ + +//! Forward-declares a class type, defines an intrusive pointer for it, and finally +//! declares Ref/Unref overloads. Use this macro in |public.h|-like files. +#define DECLARE_REFCOUNTED_CLASS(type) \ + class type; \ + DECLARE_REFCOUNTED_TYPE(type) + +//! Forward-declares a struct type, defines an intrusive pointer for it, and finally +//! declares Ref/Unref overloads. Use this macro in |public.h|-like files. +#define DECLARE_REFCOUNTED_STRUCT(type) \ + struct type; \ + DECLARE_REFCOUNTED_TYPE(type) + +//! Provides implementations for Ref/Unref overloads. Use this macro right +//! after the type's full definition. +#define DEFINE_REFCOUNTED_TYPE(type) \ [[maybe_unused]] ATTRIBUTE_USED Y_FORCE_INLINE const ::NYT::TRefCounter* GetRefCounter(const type* obj) \ - { \ - return ::NYT::TRefCountedHelper<type>::GetRefCounter(obj); \ - } \ + { \ + return ::NYT::TRefCountedHelper<type>::GetRefCounter(obj); \ + } \ [[maybe_unused]] ATTRIBUTE_USED Y_FORCE_INLINE void DestroyRefCounted(const type* obj) \ - { \ - ::NYT::TRefCountedHelper<type>::Destroy(obj); \ - } \ + { \ + ::NYT::TRefCountedHelper<type>::Destroy(obj); \ + } \ [[maybe_unused]] ATTRIBUTE_USED Y_FORCE_INLINE void DeallocateRefCounted(const type* obj) \ - { \ - ::NYT::TRefCountedHelper<type>::Deallocate(obj); \ - } - -//////////////////////////////////////////////////////////////////////////////// - + { \ + ::NYT::TRefCountedHelper<type>::Deallocate(obj); \ + } + +//////////////////////////////////////////////////////////////////////////////// + } // namespace NYT #define REF_COUNTED_INL_H_ |