< Previous by Date Date Index Next by Date >
  Thread Index Next in Thread >

[reSIProcate] [DialogUsagManager] InMemoryRegistrationDatabase usage.


Dear resip devels,
resiprocate 1.9.2

I have got a crash during InMemoryRegistrationDatabase usage. Sometimes I need to modify ContactInstanceRecord from separate thread. As I can notice from InMemoryRegistrationDatabase::updateContact sources ContactList is fetched and mutex is unlocked. I suppose at the same time my thread tries to modify the same ContactList, because it is not any more protected from simultaneous access. As result crash. Could you please consider provided patch? If it is not fine - please advice how can I safely update ContactList?

Sincerely Taras.
diff --git resip/dum/InMemoryRegistrationDatabase.cxx resip/dum/InMemoryRegistrationDatabase.cxx
index 8df0596..ee82f6c 100644
--- resip/dum/InMemoryRegistrationDatabase.cxx
+++ resip/dum/InMemoryRegistrationDatabase.cxx
@@ -33,11 +33,10 @@ InMemoryRegistrationDatabase::addAor(const Uri& aor,
 }
 
 void 
-InMemoryRegistrationDatabase::removeAor(const Uri& aor)
+InMemoryRegistrationDatabase::removeAorInternal(const Uri& aor)
 {
   database_map_t::iterator i;
 
-  Lock g(mDatabaseMutex);
   i = mDatabase.find(aor);
   //DebugLog (<< "Removing registration bindings " << aor);
   if (i != mDatabase.end())
@@ -52,6 +51,12 @@ InMemoryRegistrationDatabase::removeAor(const Uri& aor)
   }
 }
 
+void InMemoryRegistrationDatabase::removeAor(const Uri& aor)
+{
+    Lock g(mDatabaseMutex);
+    removeAorInternal(aor);
+}
+
 void
 InMemoryRegistrationDatabase::getAors(InMemoryRegistrationDatabase::UriList& container)
 {
@@ -123,22 +128,19 @@ InMemoryRegistrationDatabase::updateContact(const resip::Uri& aor,
                                              const ContactInstanceRecord& rec) 
 {
   ContactList *contactList = 0;
+  Lock g(mDatabaseMutex);
 
-  {
-    Lock g(mDatabaseMutex);
-
-    database_map_t::iterator i;
-    i = mDatabase.find(aor);
-    if (i == mDatabase.end() || i->second == 0)
-    {
-      contactList = new ContactList();
-      mDatabase[aor] = contactList;
-    }
-    else
-    {
-      contactList = i->second;
-    }
+  database_map_t::iterator i;
+  i = mDatabase.find(aor);
 
+  if (i == mDatabase.end() || i->second == 0)
+  {
+     contactList = new ContactList();
+     mDatabase[aor] = contactList;
+  }
+  else
+  {
+    contactList = i->second;
   }
 
   assert(contactList);
@@ -165,18 +167,16 @@ InMemoryRegistrationDatabase::removeContact(const Uri& aor,
                                              const ContactInstanceRecord& rec)
 {
   ContactList *contactList = 0;
+  Lock g(mDatabaseMutex);
 
+  database_map_t::iterator i;
+  i = mDatabase.find(aor);
+  if (i == mDatabase.end() || i->second == 0)
   {
-    Lock g(mDatabaseMutex);
-
-    database_map_t::iterator i;
-    i = mDatabase.find(aor);
-    if (i == mDatabase.end() || i->second == 0)
-    {
-      return;
-    }
-    contactList = i->second;
+    return;
   }
+  contactList = i->second;
+
 
   ContactList::iterator j;
 
@@ -188,7 +188,7 @@ InMemoryRegistrationDatabase::removeContact(const Uri& aor,
       contactList->erase(j);
       if (contactList->empty())
       {
-        removeAor(aor);
+        removeAorInternal(aor);
       }
       return;
     }
diff --git resip/dum/InMemoryRegistrationDatabase.hxx resip/dum/InMemoryRegistrationDatabase.hxx
index e06e4d0..89284c4 100644
--- resip/dum/InMemoryRegistrationDatabase.hxx
+++ resip/dum/InMemoryRegistrationDatabase.hxx
@@ -65,6 +65,7 @@ class InMemoryRegistrationDatabase : public RegistrationPersistenceManager
        * delete all expired contacts
        */
       database_map_t::iterator findNotExpired(const Uri& aor);
+      void removeAorInternal(const Uri& aor);
 
 };