[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);
};