2005-04-15 05:41:28 +08:00
|
|
|
/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2005 Robert Osfield
|
2003-01-22 00:45:36 +08:00
|
|
|
*
|
|
|
|
* This library is open source and may be redistributed and/or modified under
|
|
|
|
* the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
|
|
|
|
* (at your option) any later version. The full license is in LICENSE file
|
|
|
|
* included with this distribution, and on the openscenegraph.org website.
|
|
|
|
*
|
|
|
|
* This library is distributed in the hope that it will be useful,
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
* OpenSceneGraph Public License for more details.
|
|
|
|
*/
|
2002-12-16 18:25:31 +08:00
|
|
|
#include <osg/Referenced>
|
|
|
|
#include <osg/Notify>
|
2004-03-08 05:03:01 +08:00
|
|
|
|
2002-12-16 18:25:31 +08:00
|
|
|
#include <typeinfo>
|
2004-03-08 05:03:01 +08:00
|
|
|
#include <memory>
|
2002-12-16 18:25:31 +08:00
|
|
|
|
2004-09-27 22:15:13 +08:00
|
|
|
#include <OpenThreads/ScopedLock>
|
|
|
|
#include <OpenThreads/Mutex>
|
|
|
|
|
2004-11-02 00:14:53 +08:00
|
|
|
#ifndef OSG_JAVA_BUILD
|
2004-09-27 22:15:13 +08:00
|
|
|
|
2002-12-16 18:25:31 +08:00
|
|
|
namespace osg
|
|
|
|
{
|
|
|
|
|
2004-09-27 22:15:13 +08:00
|
|
|
static bool s_useThreadSafeReferenceCounting = getenv("OSG_THREAD_SAFE_REF_UNREF")!=0;
|
2005-02-23 04:25:58 +08:00
|
|
|
static std::auto_ptr<DeleteHandler> s_deleteHandler(0);
|
2004-09-27 22:15:13 +08:00
|
|
|
|
|
|
|
void Referenced::setThreadSafeReferenceCounting(bool enableThreadSafeReferenceCounting)
|
|
|
|
{
|
|
|
|
s_useThreadSafeReferenceCounting = enableThreadSafeReferenceCounting;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool Referenced::getThreadSafeReferenceCounting()
|
|
|
|
{
|
|
|
|
return s_useThreadSafeReferenceCounting;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2002-12-16 18:25:31 +08:00
|
|
|
void Referenced::setDeleteHandler(DeleteHandler* handler)
|
|
|
|
{
|
2004-08-02 21:57:47 +08:00
|
|
|
s_deleteHandler.reset(handler);
|
2002-12-16 18:25:31 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
DeleteHandler* Referenced::getDeleteHandler()
|
|
|
|
{
|
|
|
|
return s_deleteHandler.get();
|
|
|
|
}
|
|
|
|
|
2005-02-23 04:25:58 +08:00
|
|
|
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;
|
|
|
|
}
|
2004-09-27 22:15:13 +08:00
|
|
|
|
2002-12-16 18:25:31 +08:00
|
|
|
Referenced::~Referenced()
|
|
|
|
{
|
|
|
|
if (_refCount>0)
|
|
|
|
{
|
|
|
|
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;
|
|
|
|
}
|
2005-02-23 04:25:58 +08:00
|
|
|
|
|
|
|
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;
|
|
|
|
}
|
|
|
|
}
|
2002-12-16 18:25:31 +08:00
|
|
|
}
|
|
|
|
|
2005-02-23 20:50:10 +08:00
|
|
|
/*
|
2004-09-27 22:15:13 +08:00
|
|
|
void Referenced::ref() const
|
|
|
|
{
|
2005-02-23 04:25:58 +08:00
|
|
|
if (_refMutex)
|
2004-09-27 22:15:13 +08:00
|
|
|
{
|
2005-02-23 04:25:58 +08:00
|
|
|
OpenThreads::ScopedLock<OpenThreads::Mutex> lock(*_refMutex);
|
2004-09-27 22:15:13 +08:00
|
|
|
++_refCount;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
++_refCount;
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
void Referenced::unref() const
|
|
|
|
{
|
|
|
|
bool needDelete = false;
|
2005-02-23 04:25:58 +08:00
|
|
|
if (_refMutex)
|
2004-09-27 22:15:13 +08:00
|
|
|
{
|
2005-02-23 04:25:58 +08:00
|
|
|
OpenThreads::ScopedLock<OpenThreads::Mutex> lock(*_refMutex);
|
2004-09-27 22:15:13 +08:00
|
|
|
--_refCount;
|
|
|
|
needDelete = _refCount<=0;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
--_refCount;
|
|
|
|
needDelete = _refCount<=0;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (needDelete)
|
|
|
|
{
|
|
|
|
if (getDeleteHandler()) getDeleteHandler()->requestDelete(this);
|
|
|
|
else delete this;
|
|
|
|
}
|
|
|
|
}
|
2005-02-23 20:50:10 +08:00
|
|
|
*/
|
2004-09-27 22:15:13 +08:00
|
|
|
void Referenced::unref_nodelete() const
|
|
|
|
{
|
2005-02-23 04:25:58 +08:00
|
|
|
if (_refMutex)
|
2004-09-27 22:15:13 +08:00
|
|
|
{
|
2005-02-23 04:25:58 +08:00
|
|
|
OpenThreads::ScopedLock<OpenThreads::Mutex> lock(*_refMutex);
|
2004-09-27 22:15:13 +08:00
|
|
|
--_refCount;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
--_refCount;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2002-12-16 18:25:31 +08:00
|
|
|
}; // end of namespace osg
|
2004-11-02 00:14:53 +08:00
|
|
|
|
|
|
|
#endif //OSG_JAVA_BUILD
|