diff options
| author | Stefan Boberg <[email protected]> | 2025-10-22 17:57:29 +0200 |
|---|---|---|
| committer | GitHub Enterprise <[email protected]> | 2025-10-22 17:57:29 +0200 |
| commit | 5c139e2d8a260544bc5e730de0440edbab4b0f03 (patch) | |
| tree | b477208925fe3b373d4833460b90d61a8051cf05 /src/zenbase/include | |
| parent | 5.7.7-pre3 (diff) | |
| download | zen-5c139e2d8a260544bc5e730de0440edbab4b0f03.tar.xz zen-5c139e2d8a260544bc5e730de0440edbab4b0f03.zip | |
add support for OTLP logging/tracing (#599)
- adds `zentelemetry` project which houses new functionality for serializing logs and traces in OpenTelemetry Protocol format (OTLP)
- moved existing stats functionality from `zencore` to `zentelemetry`
- adds `TRefCounted<T>` for vtable-less refcounting
- adds `MemoryArena` class which allows for linear allocation of memory from chunks
- adds `protozero` which is used to encode OTLP protobuf messages
Diffstat (limited to 'src/zenbase/include')
| -rw-r--r-- | src/zenbase/include/zenbase/refcount.h | 51 |
1 files changed, 48 insertions, 3 deletions
diff --git a/src/zenbase/include/zenbase/refcount.h b/src/zenbase/include/zenbase/refcount.h index 6ad49cba2..40ad7bca5 100644 --- a/src/zenbase/include/zenbase/refcount.h +++ b/src/zenbase/include/zenbase/refcount.h @@ -10,6 +10,9 @@ namespace zen { /** * Helper base class for reference counted objects using intrusive reference counting + * + * When the reference count reaches zero, the object deletes itself. This class relies + * on having a virtual destructor to ensure proper cleanup of derived classes. */ class RefCounted { @@ -17,7 +20,7 @@ public: RefCounted() = default; virtual ~RefCounted() = default; - inline uint32_t AddRef() const { return AtomicIncrement(const_cast<RefCounted*>(this)->m_RefCount); } + inline uint32_t AddRef() const noexcept { return AtomicIncrement(const_cast<RefCounted*>(this)->m_RefCount); } inline uint32_t Release() const { const uint32_t RefCount = AtomicDecrement(const_cast<RefCounted*>(this)->m_RefCount); @@ -43,6 +46,48 @@ private: }; /** + * Template helper base class for reference counted objects using intrusive reference counting. + * + * NOTE: Unlike RefCounted, this class deletes the derived type when the reference count reaches zero. + * It has no virtual destructor, so it's important that you either don't derive from it further, + * or ensure that the derived class has a virtual destructor. + */ + +template<typename T> +class TRefCounted +{ +public: + TRefCounted() = default; + ~TRefCounted() = default; + + inline uint32_t AddRef() const noexcept { return AtomicIncrement(const_cast<TRefCounted<T>*>(this)->m_RefCount); } + inline uint32_t Release() const + { + const uint32_t RefCount = AtomicDecrement(const_cast<TRefCounted<T>*>(this)->m_RefCount); + if (RefCount == 0) + { + const_cast<T*>(static_cast<const T*>(this))->DeleteThis(); + } + return RefCount; + } + + // Copying reference counted objects doesn't make a lot of sense generally, so let's prevent it + + TRefCounted(const TRefCounted&) = delete; + TRefCounted(TRefCounted&&) = delete; + TRefCounted& operator=(const TRefCounted&) = delete; + TRefCounted& operator=(TRefCounted&&) = delete; + +protected: + inline uint32_t RefCount() const { return m_RefCount; } + + void DeleteThis() const noexcept { delete static_cast<const T*>(this); } + +private: + uint32_t m_RefCount = 0; +}; + +/** * Smart pointer for classes derived from RefCounted */ @@ -127,7 +172,8 @@ class Ref { public: inline Ref() = default; - inline Ref(const Ref& Rhs) : m_Ref(Rhs.m_Ref) { m_Ref && m_Ref->AddRef(); } + inline Ref(Ref&& Rhs) noexcept : m_Ref(Rhs.m_Ref) { Rhs.m_Ref = nullptr; } + inline Ref(const Ref& Rhs) noexcept : m_Ref(Rhs.m_Ref) { m_Ref && m_Ref->AddRef(); } inline explicit Ref(T* Ptr) : m_Ref(Ptr) { m_Ref && m_Ref->AddRef(); } inline ~Ref() { m_Ref && m_Ref->Release(); } @@ -170,7 +216,6 @@ public: } return *this; } - inline Ref(Ref&& Rhs) noexcept : m_Ref(Rhs.m_Ref) { Rhs.m_Ref = nullptr; } private: T* m_Ref = nullptr; |