aboutsummaryrefslogtreecommitdiff
path: root/src/zenbase/include
diff options
context:
space:
mode:
authorStefan Boberg <[email protected]>2025-10-22 17:57:29 +0200
committerGitHub Enterprise <[email protected]>2025-10-22 17:57:29 +0200
commit5c139e2d8a260544bc5e730de0440edbab4b0f03 (patch)
treeb477208925fe3b373d4833460b90d61a8051cf05 /src/zenbase/include
parent5.7.7-pre3 (diff)
downloadzen-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.h51
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;