From 47e01f50758010532825aded2b0926dc668a3ef7 Mon Sep 17 00:00:00 2001 From: Ingo Weinhold Date: Tue, 25 Jan 2005 15:00:12 +0000 Subject: [PATCH] Added helper class Referencable (a simple base class for reference counting). git-svn-id: file:///srv/svn/repos/haiku/trunk/current@11028 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- src/servers/registrar/Referencable.cpp | 41 ++++++++++ src/servers/registrar/Referencable.h | 109 +++++++++++++++++++++++++ 2 files changed, 150 insertions(+) create mode 100644 src/servers/registrar/Referencable.cpp create mode 100644 src/servers/registrar/Referencable.h diff --git a/src/servers/registrar/Referencable.cpp b/src/servers/registrar/Referencable.cpp new file mode 100644 index 0000000000..065ebb70b9 --- /dev/null +++ b/src/servers/registrar/Referencable.cpp @@ -0,0 +1,41 @@ +// Referencable.cpp + +#include "Debug.h" +#include "Referencable.h" + +// constructor +Referencable::Referencable(bool deleteWhenUnreferenced) + : fReferenceCount(1), + fDeleteWhenUnreferenced(deleteWhenUnreferenced) +{ +} + +// destructor +Referencable::~Referencable() +{ +} + +// AddReference +void +Referencable::AddReference() +{ + atomic_add(&fReferenceCount, 1); +} + +// RemoveReference +bool +Referencable::RemoveReference() +{ + bool unreferenced = (atomic_add(&fReferenceCount, -1) == 1); + if (fDeleteWhenUnreferenced && unreferenced) + delete this; + return unreferenced; +} + +// CountReferences +int32 +Referencable::CountReferences() const +{ + return fReferenceCount; +} + diff --git a/src/servers/registrar/Referencable.h b/src/servers/registrar/Referencable.h new file mode 100644 index 0000000000..400b79f6e0 --- /dev/null +++ b/src/servers/registrar/Referencable.h @@ -0,0 +1,109 @@ +// Referencable.h + +#ifndef REFERENCABLE_H +#define REFERENCABLE_H + +#include + +// Referencable +class Referencable { +public: + Referencable( + bool deleteWhenUnreferenced = false); + virtual ~Referencable(); + + void AddReference(); + bool RemoveReference(); // returns true after last + + int32 CountReferences() const; + +protected: + vint32 fReferenceCount; + bool fDeleteWhenUnreferenced; +}; + +// Reference +template +class Reference { +public: + Reference() + : fObject(NULL) + { + } + + Reference(Type* object, bool alreadyHasReference = false) + : fObject(NULL) + { + SetTo(object, alreadyHasReference); + } + + Reference(const Reference& other) + : fObject(NULL) + { + SetTo(other.fObject); + } + + ~Reference() + { + Unset(); + } + + void SetTo(Type* object, bool alreadyHasReference = false) + { + Unset(); + fObject = object; + if (fObject && !alreadyHasReference) + fObject->AddReference(); + } + + void Unset() + { + if (fObject) { + fObject->RemoveReference(); + fObject = NULL; + } + } + + Type* Get() const + { + return fObject; + } + + Type* Detach() + { + Type* object = fObject; + fObject = NULL; + return object; + } + + Type& operator*() const + { + return *fObject; + } + + Type* operator->() const + { + return fObject; + } + + Reference& operator=(const Reference& other) + { + SetTo(other.fObject); + return *this; + } + + bool operator==(const Reference& other) const + { + return (fObject == other.fObject); + } + + bool operator!=(const Reference& other) const + { + return (fObject != other.fObject); + } + +private: + Type* fObject; +}; + +#endif // REFERENCABLE_H