diff --git a/headers/private/shared/Referenceable.h b/headers/private/shared/Referenceable.h index 8a3c17071e..b59bee7362 100644 --- a/headers/private/shared/Referenceable.h +++ b/headers/private/shared/Referenceable.h @@ -1,5 +1,5 @@ /* - * Copyright 2004-2007, Ingo Weinhold, bonefish@users.sf.net. All rights reserved. + * Copyright 2004-2009, Ingo Weinhold, ingo_weinhold@gmx.de. * Distributed under the terms of the MIT License. */ #ifndef _REFERENCEABLE_H @@ -15,21 +15,46 @@ class Referenceable { public: Referenceable( bool deleteWhenUnreferenced = true); + // TODO: The parameter is deprecated. + // Override LastReferenceReleased() + // instead! virtual ~Referenceable(); - void AddReference() - { atomic_add(&fReferenceCount, 1); } - - bool RemoveReference(); // returns true after last + void AcquireReference(); + bool ReleaseReference(); + // returns true after last int32 CountReferences() const { return fReferenceCount; } + // deprecate aliases + inline void AddReference(); + inline bool RemoveReference(); + +protected: + virtual void FirstReferenceAcquired(); + virtual void LastReferenceReleased(); + protected: vint32 fReferenceCount; bool fDeleteWhenUnreferenced; }; + +void +Referenceable::AddReference() +{ + AcquireReference(); +} + + +bool +Referenceable::RemoveReference() +{ + return ReleaseReference(); +} + + // Reference template class Reference { diff --git a/src/kits/support/Referenceable.cpp b/src/kits/support/Referenceable.cpp index 2bbd6ff7fd..51d6fb6874 100644 --- a/src/kits/support/Referenceable.cpp +++ b/src/kits/support/Referenceable.cpp @@ -1,30 +1,50 @@ /* - * Copyright 2005-2007, Ingo Weinhold, bonefish@users.sf.net. All rights reserved. + * Copyright 2005-2009, Ingo Weinhold, ingo_weinhold@gmx.de. * Distributed under the terms of the MIT License. */ - #include -// constructor Referenceable::Referenceable(bool deleteWhenUnreferenced) : fReferenceCount(1), fDeleteWhenUnreferenced(deleteWhenUnreferenced) { } -// destructor + Referenceable::~Referenceable() { } -// RemoveReference + +void +Referenceable::AcquireReference() +{ + if (atomic_add(&fReferenceCount, 1) == 0) + FirstReferenceAcquired(); +} + + bool -Referenceable::RemoveReference() +Referenceable::ReleaseReference() { bool unreferenced = (atomic_add(&fReferenceCount, -1) == 1); - if (fDeleteWhenUnreferenced && unreferenced) - delete this; + if (unreferenced) + LastReferenceReleased(); return unreferenced; } + + +void +Referenceable::FirstReferenceAcquired() +{ +} + + +void +Referenceable::LastReferenceReleased() +{ + if (fDeleteWhenUnreferenced) + delete this; +}