|
@@ -332,6 +332,41 @@ weak_unref(WeakPointerToVoid *ptv) {
|
|
|
_weak_list->clear_reference(ptv);
|
|
_weak_list->clear_reference(ptv);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+////////////////////////////////////////////////////////////////////
|
|
|
|
|
+// Function: DeleteWrapper::do_delete
|
|
|
|
|
+// Access: Public, Static
|
|
|
|
|
+// Description: This helper function encapsulates calling the
|
|
|
|
|
+// destructor and delete operator for the given pointer.
|
|
|
|
|
+// A pointer to this function is passed to the global
|
|
|
|
|
+// ObjectDeletor, when there is one.
|
|
|
|
|
+////////////////////////////////////////////////////////////////////
|
|
|
|
|
+template<class ObjectType>
|
|
|
|
|
+void DeleteWrapper<ObjectType>::
|
|
|
|
|
+do_delete(void *ptr) {
|
|
|
|
|
+ TAU_PROFILE("void DeleteWrapper::do_delete(void *)", " ", TAU_USER);
|
|
|
|
|
+ delete ((ObjectType *)ptr);
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+////////////////////////////////////////////////////////////////////
|
|
|
|
|
+// Function: RefCountDeleteWrapper::do_delete
|
|
|
|
|
+// Access: Public, Static
|
|
|
|
|
+// Description: This is similar to DeleteWrapper::do_delete(), above,
|
|
|
|
|
+// except it is specialized for an object that inherits
|
|
|
|
|
+// from ReferenceCount, and it will check that some
|
|
|
|
|
+// other pointer hasn't incremented the reference count
|
|
|
|
|
+// in the interim before the pointer is actually
|
|
|
|
|
+// deleted.
|
|
|
|
|
+////////////////////////////////////////////////////////////////////
|
|
|
|
|
+template<class RefCountType>
|
|
|
|
|
+void RefCountDeleteWrapper<RefCountType>::
|
|
|
|
|
+do_delete(void *ptr) {
|
|
|
|
|
+ TAU_PROFILE("void RefCountDeleteWrapper::do_delete(void *)", " ", TAU_USER);
|
|
|
|
|
+ if (!((RefCountType *)ptr)->unref()) {
|
|
|
|
|
+ // The reference count has reached 0; time to delete the pointer.
|
|
|
|
|
+ delete ((RefCountType *)ptr);
|
|
|
|
|
+ }
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
////////////////////////////////////////////////////////////////////
|
|
////////////////////////////////////////////////////////////////////
|
|
|
// Function: unref_delete
|
|
// Function: unref_delete
|
|
|
// Description: This global helper function will unref the given
|
|
// Description: This global helper function will unref the given
|
|
@@ -345,32 +380,66 @@ weak_unref(WeakPointerToVoid *ptv) {
|
|
|
template<class RefCountType>
|
|
template<class RefCountType>
|
|
|
INLINE void
|
|
INLINE void
|
|
|
unref_delete(RefCountType *ptr) {
|
|
unref_delete(RefCountType *ptr) {
|
|
|
- TAU_PROFILE("unref_delete()", " ", TAU_USER);
|
|
|
|
|
|
|
+ TAU_PROFILE("void unref_delete(RefCountType *)", " ", TAU_USER);
|
|
|
// Although it may be tempting to try to upcast ptr to a
|
|
// Although it may be tempting to try to upcast ptr to a
|
|
|
// ReferenceCount object (particularly to get around inheritance
|
|
// ReferenceCount object (particularly to get around inheritance
|
|
|
// issues), resist that temptation, since some classes (in
|
|
// issues), resist that temptation, since some classes (in
|
|
|
// particular, TransformState and RenderState) rely on a non-virtual
|
|
// particular, TransformState and RenderState) rely on a non-virtual
|
|
|
// overloading of the unref() method.
|
|
// overloading of the unref() method.
|
|
|
|
|
+
|
|
|
if (!ptr->unref()) {
|
|
if (!ptr->unref()) {
|
|
|
-#ifndef NDEBUG
|
|
|
|
|
- if (get_leak_memory()) {
|
|
|
|
|
- // In leak-memory mode, we don't actually delete the pointer,
|
|
|
|
|
- // although we do call the destructor explicitly. This has
|
|
|
|
|
- // exactly the same effect as deleting it, without actually
|
|
|
|
|
- // freeing up the memory it uses.
|
|
|
|
|
-
|
|
|
|
|
- // Furthermore, if we have never-destruct set, we don't even
|
|
|
|
|
- // call the destructor.
|
|
|
|
|
- if (!get_never_destruct()) {
|
|
|
|
|
- ptr->~RefCountType();
|
|
|
|
|
- }
|
|
|
|
|
|
|
+ // The reference count has reached 0; time to delete the pointer.
|
|
|
|
|
+
|
|
|
|
|
+ // Is there a deletor in effect? If so, pass it to that object.
|
|
|
|
|
+ ObjectDeletor *deletor = ObjectDeletor::get_global_ptr();
|
|
|
|
|
+ if (deletor != (ObjectDeletor *)NULL) {
|
|
|
|
|
+ // Re-ref the pointer before adding it to the deletor. The
|
|
|
|
|
+ // deletor will de-ref it again before deleting it.
|
|
|
|
|
+ ptr->ref();
|
|
|
|
|
+ deletor->delete_object(RefCountDeleteWrapper<RefCountType>::do_delete, (void *)ptr);
|
|
|
return;
|
|
return;
|
|
|
}
|
|
}
|
|
|
-#endif
|
|
|
|
|
|
|
+
|
|
|
|
|
+ // If there's no deletor, just delete the pointer now.
|
|
|
delete ptr;
|
|
delete ptr;
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+////////////////////////////////////////////////////////////////////
|
|
|
|
|
+// Function: defer_delete
|
|
|
|
|
+// Description: This global helper function is designed to be called
|
|
|
|
|
+// in lieu of the delete operator on any type of object
|
|
|
|
|
+// (except for an object that inherits from
|
|
|
|
|
+// ReferenceCount, of course, since you should never
|
|
|
|
|
+// call delete explicitly on a reference-counted
|
|
|
|
|
+// object).
|
|
|
|
|
+//
|
|
|
|
|
+// This function will ultimately have the same effect as
|
|
|
|
|
+// calling delete on the object. If a ObjectDeletor
|
|
|
|
|
+// is currently in effect, the delete will happen at
|
|
|
|
|
+// some later time; but if a ObjectDeletor is not in
|
|
|
|
|
+// effect, the delete will happen immediately.
|
|
|
|
|
+//
|
|
|
|
|
+// You should not attempt to replace an array-delete
|
|
|
|
|
+// call, e.g. delete[] array, with a call to
|
|
|
|
|
+// defer_delete(). This only replaces single-object
|
|
|
|
|
+// deletes, e.g. delete object.
|
|
|
|
|
+////////////////////////////////////////////////////////////////////
|
|
|
|
|
+template<class ObjectType>
|
|
|
|
|
+INLINE void
|
|
|
|
|
+defer_delete(ObjectType *ptr) {
|
|
|
|
|
+ TAU_PROFILE("void defer_delete(ObjectType *)", " ", TAU_USER);
|
|
|
|
|
+
|
|
|
|
|
+ ObjectDeletor *deletor = ObjectDeletor::get_global_ptr();
|
|
|
|
|
+ if (deletor != (ObjectDeletor *)NULL) {
|
|
|
|
|
+ deletor->delete_object(DeleteWrapper<ObjectType>::do_delete, (void *)ptr);
|
|
|
|
|
+ return;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // If there's no deletor, just delete the pointer now.
|
|
|
|
|
+ delete ptr;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
////////////////////////////////////////////////////////////////////
|
|
|
// Function: RefCountProxy::Constructor
|
|
// Function: RefCountProxy::Constructor
|