r3334 - trunk/libmutil/source

erik at minisip.org erik at minisip.org
Tue Jun 26 14:46:59 CEST 2007


Author: erik
Date: 2007-06-26 14:46:59 +0200 (Tue, 26 Jun 2007)
New Revision: 3334

Modified:
   trunk/libmutil/source/MPlugin.cxx
   trunk/libmutil/source/MemObject.cxx
Log:

 * Fix massert that fails when exiting an application that has used
   MPluginManager::getInstance and has compiled libmutil with
   "--enable-memdebug".

   The massert fails when freeing the global "instance" reference to
   the MPluginManager object.

   I believe this is because a global mutex that is used by the 
   the MPluginManager super class (MObject) is freed before
   the MPluginManager is freed. This is kind of a race condition,
   and if they had been freed in the other order it would work.

   Now I instead keep a pointer to the global mutex. This way
   we know it is not destroyed before any global references.

   Note that this only affected debug builds.

 * Fix for a potential problem with a struct in MPlugin.cxx.

   We did memset on a struct containing MRefs. I'm not sure that
   is ok. If the MRef has attributes that are not "reset" by setting
   all attributes to zeros, then we crash. I tried with adding a
   string attribute to the MRef template, and I got a crash.



Modified: trunk/libmutil/source/MPlugin.cxx
===================================================================
--- trunk/libmutil/source/MPlugin.cxx	2007-06-18 17:57:57 UTC (rev 3333)
+++ trunk/libmutil/source/MPlugin.cxx	2007-06-26 12:46:59 UTC (rev 3334)
@@ -140,6 +140,9 @@
 }
 
 struct ltdl_info {
+		ltdl_info() : manager(NULL),nTotalPlugins(0){}
+		~ltdl_info(){manager=NULL;}
+
 		MRef<MPluginManager *> manager;
 		int32_t nTotalPlugins;
 };
@@ -160,8 +163,6 @@
 
 int32_t MPluginManager::loadFromDirectory( const string &path ){
 	ltdl_info info;
-
-	memset(&info, 0, sizeof(info));
 	info.manager = this;
 
 	int res = lt_dlforeachfile(path.c_str(), ltdl_callback, &info);

Modified: trunk/libmutil/source/MemObject.cxx
===================================================================
--- trunk/libmutil/source/MemObject.cxx	2007-06-18 17:57:57 UTC (rev 3333)
+++ trunk/libmutil/source/MemObject.cxx	2007-06-26 12:46:59 UTC (rev 3334)
@@ -35,19 +35,27 @@
 
 #ifdef MDEBUG
 #include<libmutil/stringutils.h>
-Mutex global;
+Mutex *globalLock=NULL;
 minilist<MObject *> objs;
 int ocount=0;
 bool outputOnDestructor=false;
+
+Mutex &global(){
+	if (!globalLock)
+		globalLock = new Mutex;
+	return *globalLock;
+}
 #endif
 
 MObject::MObject() : refCount(0){
-	refLock = new Mutex();
 #ifdef MDEBUG
-	global.lock();
+	global().lock();
 	ocount++;
 	objs.push_front(this);
-	global.unlock();
+	refLock=NULL;
+	global().unlock();
+#else
+	refLock = new Mutex();
 #endif
 }
 
@@ -56,18 +64,20 @@
 // any references to the argument object
 // are not referencing us.
 MObject::MObject(const MObject &):refCount(0){
-	refLock = new Mutex();	//We don't want to share the mutex
 #ifdef MDEBUG
-	global.lock();
+	global().lock();
 	ocount++;
 	objs.push_front(this);
-	global.unlock();
+	refLock=NULL;
+	global().unlock();
+#else
+	refLock = new Mutex();	//We don't want to share the mutex
 #endif
 }
 
 MObject::~MObject(){
 #ifdef MDEBUG
-	global.lock();
+	global().lock();
 	for (int i=0; i<objs.size(); i++){
 		if (this == objs[i]){
 			objs.remove(i);
@@ -75,10 +85,12 @@
 			break;
 		}
 	}
-	global.unlock();
-#endif
+	global().unlock();
+#else
+	massert(refLock);
 	delete refLock;
 	refLock=NULL;
+#endif
 }
 
 void MObject::operator=(const MObject &){
@@ -94,7 +106,7 @@
 int MObject::decRefCount() const{
 	int refRet;
 #ifdef MDEBUG
-	global.lock();
+	global().lock();
 #else
 	refLock->lock();
 #endif
@@ -103,7 +115,7 @@
 	refRet = refCount;
 	
 #ifdef MDEBUG
-	global.unlock();
+	global().unlock();
 	if (refRet==0 && outputOnDestructor){
 		string output = "MO (--):"+getMemObjectType()+ "; count=" + itoa(refRet) + "; ptr=" + itoa((int)this);
 		mdbg("memobject") << output << endl;
@@ -116,7 +128,7 @@
 
 void MObject::incRefCount() const{
 #ifdef MDEBUG
-	global.lock();
+	global().lock();
 #else
 	refLock->lock();
 #endif
@@ -124,7 +136,7 @@
 	refCount++;
 	
 #ifdef MDEBUG
-	global.unlock();
+	global().unlock();
 	if (refCount == 1 && outputOnDestructor ){
 		string output = "MO (++):"+getMemObjectType()+ "; count=" + itoa(refCount);
 		mdbg("memobject") << output << endl;
@@ -149,13 +161,13 @@
 minilist<string> getMemObjectNames(){
 #ifdef MDEBUG
 	minilist<string> ret;
-	global.lock();
+	global().lock();
 	for (int i=0; i< objs.size(); i++){
 		int count = objs[i]->getRefCount();
 		string countstr = count?itoa(count):"on stack"; 
 		ret.push_front(objs[i]->getMemObjectType()+"("+countstr+")" + "; ptr=" + itoa((int)objs[i]) );
 	}
-	global.unlock();
+	global().unlock();
 	return ret;
 #else
 	minilist<string> ret;
@@ -196,7 +208,7 @@
 	std::list<string>::iterator si;
 	std::list<string>::iterator js;
 	std::list<int>::iterator jc;
-	global.lock();
+	global().lock();
 	// get list of unique names, and count
 	int i;
 	for (i=0; i< objs.size(); i++){
@@ -250,7 +262,7 @@
 		ret.push_back( *js + " " + itoa( *jc ) );
 	}
 
-	global.unlock();
+	global().unlock();
 	return ret;
 #else
 	minilist<string> ret;



More information about the Minisip-devel mailing list