? atdoc.patch ? cairomm_refptr.patch ? examples/pdf-surface/image.pdf ? examples/png_file/image.png Index: ChangeLog =================================================================== RCS file: /cvs/cairo/cairomm/ChangeLog,v retrieving revision 1.71 diff -u -p -r1.71 ChangeLog --- ChangeLog 6 Jul 2006 03:12:17 -0000 1.71 +++ ChangeLog 6 Jul 2006 17:06:04 -0000 @@ -1,3 +1,10 @@ +2006-07-06 Murray Cumming + + * cairomm/refptr.h: Use an int to reference-count the C++ object, and + only reference/unreference the object (and hence the underlying C object) + when receiving/deleting the C++ object. Without this, we never delete + the C++ object. Fixes bug #7442. + 2006-07-05 Jonathon Jongsma * Makefile.am: Ooops, I had accidentally removed dependency info for Index: cairomm/refptr.h =================================================================== RCS file: /cvs/cairo/cairomm/cairomm/refptr.h,v retrieving revision 1.3 diff -u -p -r1.3 refptr.h --- cairomm/refptr.h 6 Mar 2006 17:55:51 -0000 1.3 +++ cairomm/refptr.h 6 Jul 2006 17:06:04 -0000 @@ -56,7 +56,9 @@ public: /// Destructor - decrements reference count. inline ~RefPtr(); - /// For use only by the ::create() methods. + /** For use only by the ::create() methods. + * This assumes that @a pCppObject already has a starting reference. + */ explicit inline RefPtr(T_CppObject* pCppObject); /** Copy constructor @@ -147,7 +149,10 @@ public: static inline RefPtr cast_const(const RefPtr& src); private: + void unref(); + T_CppObject* pCppObject_; + int* pCppRefcount_; }; @@ -165,29 +170,61 @@ T_CppObject* RefPtr::operat template inline RefPtr::RefPtr() : - pCppObject_ (0) + pCppObject_(0), + pCppRefcount_(0) {} template inline RefPtr::~RefPtr() { - if(pCppObject_) - pCppObject_->unreference(); // This could cause pCppObject to be deleted. + unref(); +} + +template inline +void RefPtr::unref() +{ + if(pCppRefcount_) + { + --(*pCppRefcount_); + + if(*pCppRefcount_ == 0) + { + if(pCppObject_) + { + //Release the underlying C object: + pCppObject_->unreference(); + + delete pCppObject_; + pCppObject_ = 0; + } + } + + delete pCppRefcount_; + pCppRefcount_ = 0; + } } + template inline RefPtr::RefPtr(T_CppObject* pCppObject) : - pCppObject_ (pCppObject) -{} + pCppObject_(pCppObject) +{ + if(pCppObject) + { + pCppRefcount_ = new int; + *pCppRefcount_ = 1; //This will be decremented in the destructor. + } +} template inline RefPtr::RefPtr(const RefPtr& src) : - pCppObject_ (src.pCppObject_) + pCppObject_ (src.pCppObject_), + pCppRefcount_(src.pCppRefcount_) { - if(pCppObject_) - pCppObject_->reference(); + if(pCppObject_ && pCppRefcount_) + ++(*pCppRefcount_); } // The templated ctor allows copy construction from any object that's @@ -203,16 +240,21 @@ RefPtr::RefPtr(const RefPtr // use, so we use the less well-known operator->() accessor: pCppObject_ (src.operator->()) { - if(pCppObject_) - pCppObject_->reference(); + if(pCppObject_ && pCppRefcount_) + ++(*pCppRefcount_); } template inline void RefPtr::swap(RefPtr& other) { T_CppObject *const temp = pCppObject_; + int* temp_count = pCppRefcount_; + pCppObject_ = other.pCppObject_; + pCppRefcount_ = other.pCppRefcount_; + other.pCppObject_ = temp; + other.pCppRefcount_ = temp_count; } template inline @@ -289,10 +331,10 @@ RefPtr RefPtr: { T_CppObject *const pCppObject = dynamic_cast(src.operator->()); - if(pCppObject) - pCppObject->reference(); + if(pCppObject && src.pCppRefcount_) + ++(*(src.pCppRefcount_)); - return RefPtr(pCppObject); + return RefPtr(pCppObject); //TODO: Does an unnecessary extra reference() on the C object. } template @@ -302,10 +344,10 @@ RefPtr RefPtr: { T_CppObject *const pCppObject = static_cast(src.operator->()); - if(pCppObject) - pCppObject->reference(); + if(pCppObject && src.pCppRefcount_) + ++(*(src.pCppRefcount_)); - return RefPtr(pCppObject); + return RefPtr(pCppObject); //TODO: Does an unnecessary extra reference() on the C object. } template @@ -315,10 +357,10 @@ RefPtr RefPtr: { T_CppObject *const pCppObject = const_cast(src.operator->()); - if(pCppObject) - pCppObject->reference(); + if(pCppObject && src.pCppRefcount_) + ++(*(src.pCppRefcount_)); - return RefPtr(pCppObject); + return RefPtr(pCppObject); //TODO: Does an unnecessary extra reference() on the C object. } #endif /* DOXYGEN_SHOULD_SKIP_THIS */