From 884b2730e83bda9a715d4a75ea9ba09e14ea17fd Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Mon, 16 Dec 2002 10:25:31 +0000 Subject: [PATCH] Added a DeleteHandler into osg::Referenced so that it can delete objects via a seperate delete handler. Useful for making unref()/ref() thread safe if the users needs to address this issue. --- VisualStudio/osg/osg.dsp | 4 ++++ include/osg/Object | 2 +- include/osg/Referenced | 50 +++++++++++++++++++++++++++++++++++++++- src/osg/Object.cpp | 24 ++++--------------- src/osg/Referenced.cpp | 38 ++++++++++++++++++++++++++++++ 5 files changed, 96 insertions(+), 22 deletions(-) create mode 100644 src/osg/Referenced.cpp diff --git a/VisualStudio/osg/osg.dsp b/VisualStudio/osg/osg.dsp index 1ccf2c34e..e3b21f185 100755 --- a/VisualStudio/osg/osg.dsp +++ b/VisualStudio/osg/osg.dsp @@ -333,6 +333,10 @@ SOURCE=..\..\src\osg\Projection.cpp # End Source File # Begin Source File +SOURCE=..\..\src\osg\Referenced.cpp +# End Source File +# Begin Source File + SOURCE=..\..\src\osg\ShapeDrawable.cpp # End Source File # Begin Source File diff --git a/include/osg/Object b/include/osg/Object index 494c07f78..bf84ca6f6 100644 --- a/include/osg/Object +++ b/include/osg/Object @@ -16,7 +16,7 @@ namespace osg { * the standard pure virtual clone, isSameKindAs and className methods * which are required for all Object subclasses.*/ #define META_Object(library,name) \ - virtual osg::Object* cloneType() const { return osgNew name (); } \ + virtual osg::Object* cloneType() const { return new name (); } \ virtual osg::Object* clone(const osg::CopyOp& copyop) const { return osgNew name (*this,copyop); } \ virtual bool isSameKindAs(const osg::Object* obj) const { return dynamic_cast(obj)!=NULL; } \ virtual const char* libraryName() const { return #library; }\ diff --git a/include/osg/Referenced b/include/osg/Referenced index eb7b2fb8e..5cf827788 100644 --- a/include/osg/Referenced +++ b/include/osg/Referenced @@ -9,6 +9,11 @@ namespace osg { + +// forward declar, declared after Refenced below. +class DeleteHandler; + + /** Base class from providing referencing counted objects.*/ class SG_EXPORT Referenced { @@ -31,6 +36,13 @@ class SG_EXPORT Referenced inline Referenced& operator = (Referenced&) { return *this; } + friend DeleteHandler; + + static void setDeleteHandler(DeleteHandler* handler); + + static DeleteHandler* getDeleteHandler(); + + /** increment the reference count by one, indicating that this object has another pointer which is referencing it.*/ inline void ref() const { ++_refCount; } @@ -39,7 +51,7 @@ class SG_EXPORT Referenced 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 { --_refCount; if (_refCount<=0) delete this; } + inline void unref() const; /** decrement the reference count by one, indicating that a pointer to this object is referencing it. However, do @@ -60,9 +72,13 @@ class SG_EXPORT Referenced inline static int deletedCount() { return _deletedCount; } #endif + + protected: virtual ~Referenced(); mutable int _refCount; + + #ifdef OSG_COMPILE_UNIT_TESTS static int _createdCount; // incremented in the constructor static int _deletedCount; // incremented in the destructor @@ -70,6 +86,38 @@ class SG_EXPORT Referenced }; + +/** Class for override the default delete behavior so that users can implment their own object + * deletion schemes. This might be done to help implement protection of multiple threads from deleting + * objects unintentionally.*/ +class DeleteHandler +{ + public: + + virtual ~DeleteHandler() {} + + /** flush any cache of objects that need to be deleted by doing an actual delete.*/ + virtual void flush() {} + + inline void doDelete(const Referenced* object) { delete object; } + + /** Request the deletion of an object. + * Depending on users implementation of DeleteHandler, the delete of the object may occur + * straight away or be delayed until doDelete is called. + * The default implementation does a delete straight away.*/ + virtual void requestDelete(const Referenced* object) { doDelete(object); } +}; + +inline void Referenced::unref() const +{ + --_refCount; + if (_refCount<=0) + { + if (getDeleteHandler()) getDeleteHandler()->requestDelete(this); + else delete this; + } +} + } #endif diff --git a/src/osg/Object.cpp b/src/osg/Object.cpp index 4ef343d23..802ff5f9d 100644 --- a/src/osg/Object.cpp +++ b/src/osg/Object.cpp @@ -1,28 +1,12 @@ #include -#include -#include -using namespace osg; - -#ifdef OSG_COMPILE_UNIT_TESTS -int Referenced::_createdCount = 0; -int Referenced::_deletedCount = 0; -#endif - -Referenced::~Referenced() +namespace osg { - if (_refCount>0) - { - notify(WARN)<<"Warning: deleting still referenced object "< +#include +#include + +namespace osg +{ + +static std::auto_ptr s_deleteHandler(0); + +void Referenced::setDeleteHandler(DeleteHandler* handler) +{ + s_deleteHandler.reset(handler); +} + +DeleteHandler* Referenced::getDeleteHandler() +{ + return s_deleteHandler.get(); +} + + +#ifdef OSG_COMPILE_UNIT_TESTS +int Referenced::_createdCount = 0; +int Referenced::_deletedCount = 0; +#endif + +Referenced::~Referenced() +{ + if (_refCount>0) + { + notify(WARN)<<"Warning: deleting still referenced object "<