Made the osg::Referenced Mutex be declared as a pointer to a Mutex, with the

Mutex allocated dynamically when required. Added the following methods to
help manage the usage of the mutex:

        void setThreadSafeRefUnref(bool threadSafe);

        bool getThreadSafeRefUnref() const;
This commit is contained in:
Robert Osfield 2005-02-22 20:25:58 +00:00
parent 10c3f934f1
commit e01990d419
2 changed files with 63 additions and 23 deletions

View File

@ -41,30 +41,29 @@ class SG_EXPORT Referenced
public:
Referenced()
{
_refCount=0;
}
Referenced(const Referenced&) {
_refCount=0;
}
Referenced();
Referenced(const Referenced&);
inline Referenced& operator = (const Referenced&) { return *this; }
/** Set whether to use a mutex to ensure ref() and unref() are thread safe.*/
void setThreadSafeRefUnref(bool threadSafe);
/** Get whether a mutex is used to ensure ref() and unref() are thread safe.*/
bool getThreadSafeRefUnref() const { return _refMutex!=0; }
/** increment the reference count by one, indicating that
/** Increment the reference count by one, indicating that
this object has another pointer which is referencing it.*/
void ref() const;
/** decrement the reference count by one, indicating that
/** Decrement the reference count by one, indicating that
a pointer to this object is referencing it. If the
reference count goes to zero, it is assumed that this object
is no longer referenced and is automatically deleted.*/
void unref() const;
/** decrement the reference count by one, indicating that
/** Decrement the reference count by one, indicating that
a pointer to this object is referencing it. However, do
not delete it, even if ref count goes to 0. Warning, unref_nodelete()
should only be called if the user knows exactly who will
@ -72,7 +71,7 @@ class SG_EXPORT Referenced
as the later can lead to memory leaks.*/
void unref_nodelete() const;
/** return the number pointers currently referencing this object. */
/** Return the number pointers currently referencing this object. */
inline int referenceCount() const { return _refCount; }
@ -97,9 +96,9 @@ class SG_EXPORT Referenced
protected:
virtual ~Referenced();
mutable OpenThreads::Mutex _refMutex;
mutable OpenThreads::Mutex* _refMutex;
mutable int _refCount;
mutable int _refCount;
};

View File

@ -25,6 +25,7 @@ namespace osg
{
static bool s_useThreadSafeReferenceCounting = getenv("OSG_THREAD_SAFE_REF_UNREF")!=0;
static std::auto_ptr<DeleteHandler> s_deleteHandler(0);
void Referenced::setThreadSafeReferenceCounting(bool enableThreadSafeReferenceCounting)
{
@ -37,9 +38,6 @@ bool Referenced::getThreadSafeReferenceCounting()
}
static std::auto_ptr<DeleteHandler> s_deleteHandler(0);
void Referenced::setDeleteHandler(DeleteHandler* handler)
{
s_deleteHandler.reset(handler);
@ -50,6 +48,19 @@ DeleteHandler* Referenced::getDeleteHandler()
return s_deleteHandler.get();
}
Referenced::Referenced()
{
if (s_useThreadSafeReferenceCounting) _refMutex = new OpenThreads::Mutex;
else _refMutex = 0;
_refCount=0;
}
Referenced::Referenced(const Referenced&)
{
if (s_useThreadSafeReferenceCounting) _refMutex = new OpenThreads::Mutex;
else _refMutex = 0;
_refCount=0;
}
Referenced::~Referenced()
{
@ -58,13 +69,43 @@ Referenced::~Referenced()
notify(WARN)<<"Warning: deleting still referenced object "<<this<<" of type '"<<typeid(this).name()<<"'"<<std::endl;
notify(WARN)<<" the final reference count was "<<_refCount<<", memory corruption possible."<<std::endl;
}
if (_refMutex)
{
OpenThreads::Mutex* tmpMutexPtr = _refMutex;
_refMutex = 0;
delete tmpMutexPtr;
}
}
void Referenced::setThreadSafeRefUnref(bool threadSafe)
{
if (threadSafe)
{
if (!_refMutex)
{
// we want thread safe ref()/unref() so assing a mutex
_refMutex = new OpenThreads::Mutex;
}
}
else
{
if (_refMutex)
{
// we don't want thread safe ref()/unref() so remove any assigned mutex
OpenThreads::Mutex* tmpMutexPtr = _refMutex;
_refMutex = 0;
delete tmpMutexPtr;
}
}
}
void Referenced::ref() const
{
if (s_useThreadSafeReferenceCounting)
if (_refMutex)
{
OpenThreads::ScopedLock<OpenThreads::Mutex> lock(_refMutex);
OpenThreads::ScopedLock<OpenThreads::Mutex> lock(*_refMutex);
++_refCount;
}
else
@ -77,9 +118,9 @@ void Referenced::ref() const
void Referenced::unref() const
{
bool needDelete = false;
if (s_useThreadSafeReferenceCounting)
if (_refMutex)
{
OpenThreads::ScopedLock<OpenThreads::Mutex> lock(_refMutex);
OpenThreads::ScopedLock<OpenThreads::Mutex> lock(*_refMutex);
--_refCount;
needDelete = _refCount<=0;
}
@ -98,9 +139,9 @@ void Referenced::unref() const
void Referenced::unref_nodelete() const
{
if (s_useThreadSafeReferenceCounting)
if (_refMutex)
{
OpenThreads::ScopedLock<OpenThreads::Mutex> lock(_refMutex);
OpenThreads::ScopedLock<OpenThreads::Mutex> lock(*_refMutex);
--_refCount;
}
else