* Renamed {Add,Remove}Reference() to {Acquire,Release}Reference(). Methods with

the old names still exist as deprecated aliases for the time being.
* Introduced hooks FirstReferenceAcquired() and LastReferenceReleased(). Besides
  added flexibility this also makes the deleteWhenUnreferenced constructor
  parameter and the fDeleteWhenUnreferenced attribute superfluous, since the
  "don't delete" behavior can be obtained by overriding LastReferenceReleased().
  Parameter and attribute will be removed eventually.


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@31367 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Ingo Weinhold 2009-07-01 21:59:27 +00:00
parent 668ed70bd0
commit 7aa7cb4b54
2 changed files with 58 additions and 13 deletions

View File

@ -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<typename Type = BPrivate::Referenceable>
class Reference {

View File

@ -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 <Referenceable.h>
// 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;
}