Added new methods into osg::Referenced for controlling the use of thread safe
ref/unref: /** Set whether reference counting should be use a mutex to create thread reference counting.*/ static void setThreadSafeReferenceCounting(bool enableThreadSafeReferenceCounting); /** Get whether reference counting is active.*/ static bool getThreadSafeReferenceCounting();
This commit is contained in:
parent
7e5c87de6a
commit
de0e616433
@ -17,12 +17,7 @@
|
||||
|
||||
#include <osg/Export>
|
||||
|
||||
// #define THREAD_SAFE_REF_UNREF 1
|
||||
|
||||
#ifdef THREAD_SAFE_REF_UNREF
|
||||
#include <OpenThreads/ScopedLock>
|
||||
#include <OpenThreads/Mutex>
|
||||
#endif
|
||||
#include <OpenThreads/Mutex>
|
||||
|
||||
namespace osg {
|
||||
|
||||
@ -36,6 +31,8 @@ class SG_EXPORT Referenced
|
||||
{
|
||||
|
||||
public:
|
||||
|
||||
|
||||
Referenced()
|
||||
{
|
||||
|
||||
@ -47,6 +44,38 @@ class SG_EXPORT Referenced
|
||||
|
||||
inline Referenced& operator = (const Referenced&) { return *this; }
|
||||
|
||||
|
||||
|
||||
/** 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
|
||||
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
|
||||
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
|
||||
be resonsible for, one should prefer unref() over unref_nodelete()
|
||||
as the later can lead to memory leaks.*/
|
||||
void unref_nodelete() const;
|
||||
|
||||
/** return the number pointers currently referencing this object. */
|
||||
inline int referenceCount() const { return _refCount; }
|
||||
|
||||
|
||||
public:
|
||||
|
||||
/** Set whether reference counting should be use a mutex to create thread reference counting.*/
|
||||
static void setThreadSafeReferenceCounting(bool enableThreadSafeReferenceCounting);
|
||||
|
||||
/** Get whether reference counting is active.*/
|
||||
static bool getThreadSafeReferenceCounting();
|
||||
|
||||
friend class DeleteHandler;
|
||||
|
||||
/** Set a DeleteHandler to which deletion of all referenced counted objects
|
||||
@ -56,41 +85,12 @@ class SG_EXPORT Referenced
|
||||
/** Get a DeleteHandler.*/
|
||||
static DeleteHandler* getDeleteHandler();
|
||||
|
||||
|
||||
/** increment the reference count by one, indicating that
|
||||
this object has another pointer which is referencing it.*/
|
||||
inline void ref() const
|
||||
{
|
||||
#ifdef THREAD_SAFE_REF_UNREF
|
||||
OpenThreads::ScopedLock<OpenThreads::Mutex> lock(_refMutex);
|
||||
#endif
|
||||
++_refCount;
|
||||
}
|
||||
|
||||
/** 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.*/
|
||||
inline void unref() const;
|
||||
|
||||
/** 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
|
||||
be resonsible for, one should prefer unref() over unref_nodelete()
|
||||
as the later can lead to memory leaks.*/
|
||||
inline void unref_nodelete() const { --_refCount; }
|
||||
|
||||
/** return the number pointers currently referencing this object. */
|
||||
inline int referenceCount() const { return _refCount; }
|
||||
|
||||
|
||||
protected:
|
||||
virtual ~Referenced();
|
||||
|
||||
#ifdef THREAD_SAFE_REF_UNREF
|
||||
mutable OpenThreads::Mutex _refMutex;
|
||||
#endif
|
||||
|
||||
mutable int _refCount;
|
||||
|
||||
};
|
||||
@ -121,22 +121,6 @@ class DeleteHandler
|
||||
virtual void requestDelete(const Referenced* object) { doDelete(object); }
|
||||
};
|
||||
|
||||
inline void Referenced::unref() const
|
||||
{
|
||||
bool needDelete = false;
|
||||
{
|
||||
#ifdef THREAD_SAFE_REF_UNREF
|
||||
OpenThreads::ScopedLock<OpenThreads::Mutex> lock(_refMutex);
|
||||
#endif
|
||||
--_refCount;
|
||||
needDelete = _refCount<=0;
|
||||
}
|
||||
if (needDelete)
|
||||
{
|
||||
if (getDeleteHandler()) getDeleteHandler()->requestDelete(this);
|
||||
else delete this;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
@ -16,9 +16,27 @@
|
||||
#include <typeinfo>
|
||||
#include <memory>
|
||||
|
||||
#include <OpenThreads/ScopedLock>
|
||||
#include <OpenThreads/Mutex>
|
||||
|
||||
|
||||
namespace osg
|
||||
{
|
||||
|
||||
static bool s_useThreadSafeReferenceCounting = getenv("OSG_THREAD_SAFE_REF_UNREF")!=0;
|
||||
|
||||
void Referenced::setThreadSafeReferenceCounting(bool enableThreadSafeReferenceCounting)
|
||||
{
|
||||
s_useThreadSafeReferenceCounting = enableThreadSafeReferenceCounting;
|
||||
}
|
||||
|
||||
bool Referenced::getThreadSafeReferenceCounting()
|
||||
{
|
||||
return s_useThreadSafeReferenceCounting;
|
||||
}
|
||||
|
||||
|
||||
|
||||
static std::auto_ptr<DeleteHandler> s_deleteHandler(0);
|
||||
|
||||
void Referenced::setDeleteHandler(DeleteHandler* handler)
|
||||
@ -31,6 +49,7 @@ DeleteHandler* Referenced::getDeleteHandler()
|
||||
return s_deleteHandler.get();
|
||||
}
|
||||
|
||||
|
||||
Referenced::~Referenced()
|
||||
{
|
||||
if (_refCount>0)
|
||||
@ -40,4 +59,54 @@ Referenced::~Referenced()
|
||||
}
|
||||
}
|
||||
|
||||
void Referenced::ref() const
|
||||
{
|
||||
if (s_useThreadSafeReferenceCounting)
|
||||
{
|
||||
OpenThreads::ScopedLock<OpenThreads::Mutex> lock(_refMutex);
|
||||
++_refCount;
|
||||
}
|
||||
else
|
||||
{
|
||||
++_refCount;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void Referenced::unref() const
|
||||
{
|
||||
bool needDelete = false;
|
||||
if (s_useThreadSafeReferenceCounting)
|
||||
{
|
||||
OpenThreads::ScopedLock<OpenThreads::Mutex> lock(_refMutex);
|
||||
--_refCount;
|
||||
needDelete = _refCount<=0;
|
||||
}
|
||||
else
|
||||
{
|
||||
--_refCount;
|
||||
needDelete = _refCount<=0;
|
||||
}
|
||||
|
||||
if (needDelete)
|
||||
{
|
||||
if (getDeleteHandler()) getDeleteHandler()->requestDelete(this);
|
||||
else delete this;
|
||||
}
|
||||
}
|
||||
|
||||
void Referenced::unref_nodelete() const
|
||||
{
|
||||
if (s_useThreadSafeReferenceCounting)
|
||||
{
|
||||
OpenThreads::ScopedLock<OpenThreads::Mutex> lock(_refMutex);
|
||||
--_refCount;
|
||||
}
|
||||
else
|
||||
{
|
||||
--_refCount;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}; // end of namespace osg
|
||||
|
Loading…
Reference in New Issue
Block a user