From e01990d419dbf43dfa7ef42b7873815bc2caba35 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Tue, 22 Feb 2005 20:25:58 +0000 Subject: [PATCH] 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; --- include/osg/Referenced | 27 ++++++++++--------- src/osg/Referenced.cpp | 59 +++++++++++++++++++++++++++++++++++------- 2 files changed, 63 insertions(+), 23 deletions(-) diff --git a/include/osg/Referenced b/include/osg/Referenced index b90905117..a83fa28aa 100644 --- a/include/osg/Referenced +++ b/include/osg/Referenced @@ -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; }; diff --git a/src/osg/Referenced.cpp b/src/osg/Referenced.cpp index 8aafd7913..be48160ce 100644 --- a/src/osg/Referenced.cpp +++ b/src/osg/Referenced.cpp @@ -25,6 +25,7 @@ namespace osg { static bool s_useThreadSafeReferenceCounting = getenv("OSG_THREAD_SAFE_REF_UNREF")!=0; +static std::auto_ptr s_deleteHandler(0); void Referenced::setThreadSafeReferenceCounting(bool enableThreadSafeReferenceCounting) { @@ -37,9 +38,6 @@ bool Referenced::getThreadSafeReferenceCounting() } - -static std::auto_ptr 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 "< lock(_refMutex); + OpenThreads::ScopedLock 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 lock(_refMutex); + OpenThreads::ScopedLock 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 lock(_refMutex); + OpenThreads::ScopedLock lock(*_refMutex); --_refCount; } else