From 5de025800dd96904e10d062c9306f08f95832aba Mon Sep 17 00:00:00 2001 From: paulc Date: Mon, 4 Jun 2007 22:18:59 +0000 Subject: [PATCH] Added virtual method to control zero reference notification before the RefObject mutex is unlocked. Also expose said mutex through static method. git-svn-id: http://yate.null.ro/svn/yate/trunk@1348 acf43c95-373e-0410-b603-e72c3f656dc1 --- engine/TelEngine.cpp | 14 +++++++++++++- yateclass.h | 20 +++++++++++++++++++- 2 files changed, 32 insertions(+), 2 deletions(-) diff --git a/engine/TelEngine.cpp b/engine/TelEngine.cpp index a5987533..47a1f231 100644 --- a/engine/TelEngine.cpp +++ b/engine/TelEngine.cpp @@ -545,12 +545,15 @@ bool RefObject::ref() bool RefObject::deref() { + bool zeroCall = false; s_refmutex.lock(); int i = m_refcount; if (i > 0) --m_refcount; - s_refmutex.unlock(); if (i == 1) + zeroCall = zeroRefsTest(); + s_refmutex.unlock(); + if (zeroCall) zeroRefs(); else if (i <= 0) Debug(DebugFail,"RefObject::deref() called with count=%d [%p]",i,this); @@ -563,6 +566,11 @@ void RefObject::zeroRefs() delete this; } +bool RefObject::zeroRefsTest() +{ + return true; +} + bool RefObject::resurrect() { s_refmutex.lock(); @@ -577,6 +585,10 @@ void RefObject::destroyed() { } +Mutex& RefObject::refMutex() +{ + return s_refmutex; +} void RefPointerBase::assign(RefObject* oldptr, RefObject* newptr, void* pointer) { diff --git a/yateclass.h b/yateclass.h index 1079c844..ab34172d 100644 --- a/yateclass.h +++ b/yateclass.h @@ -566,6 +566,7 @@ struct TokenDict { }; class String; +class Mutex; #if 0 /* for documentation generator */ /** @@ -703,13 +704,30 @@ public: */ virtual void destruct(); + /** + * Retrieve the mutex that protects ref() and deref() for all objects + * @return Reference to the global mutex used for all counter operations + */ + static Mutex& refMutex(); + protected: /** - * This method is called when the reference count reaches zero. + * This method is called when the reference count reaches zero after + * unlocking the mutex if the call to zeroRefsTest() returned true. * The default behaviour is to delete the object. */ virtual void zeroRefs(); + /** + * This method is called when the reference count reaches zero just before + * calling zeroRefs() with the non-recursive mutex still locked. + * Extra care must be taken to prevent deadlocks, normally the code should + * only change some variables and return. + * The default implementation just returns true. + * @return True to call zeroRefs() after releasing the mutex + */ + virtual bool zeroRefsTest(); + /** * Bring the object back alive by setting the reference counter to one. * Note that it works only if the counter was zero previously