[Opalvoip-svn] SF.net SVN: opalvoip:[22738] opal/branches/v3_6/src/sip/handlers.cxx
Brought to you by:
csoutheren,
rjongbloed
From: <rjo...@us...> - 2009-05-27 10:12:13
|
Revision: 22738 http://opalvoip.svn.sourceforge.net/opalvoip/?rev=22738&view=rev Author: rjongbloed Date: 2009-05-27 10:12:07 +0000 (Wed, 27 May 2009) Log Message: ----------- Changed SIP handler searching functions to be more lenient on locking, in an attempt to prevent a strange deadlock. Modified Paths: -------------- opal/branches/v3_6/src/sip/handlers.cxx Modified: opal/branches/v3_6/src/sip/handlers.cxx =================================================================== --- opal/branches/v3_6/src/sip/handlers.cxx 2009-05-27 06:50:56 UTC (rev 22737) +++ opal/branches/v3_6/src/sip/handlers.cxx 2009-05-27 10:12:07 UTC (rev 22738) @@ -1465,6 +1465,16 @@ ////////////////////////////////////////////////////////////////// +/* All of the bwlow search loops run through the list with only + PSafeReference rather than PSafeReadOnly, even though they are + reading fields from the handler instances. We can get away with + this becuase the information being tested, e.g. AOR, is constant + for the life of the handler instance, once constructed. + + We need to use PSafeReference as there are some cases where + deadlocks can occur when locked handlers look for information + from other handlers. + */ unsigned SIPHandlersList::GetCount(SIP_PDU::Methods meth, const PString & eventPackage) const { unsigned count = 0; @@ -1493,11 +1503,12 @@ /** * Find the SIPHandler object with the specified callID */ -PSafePtr<SIPHandler> SIPHandlersList::FindSIPHandlerByCallID(const PString & callID, PSafetyMode m) +PSafePtr<SIPHandler> SIPHandlersList::FindSIPHandlerByCallID(const PString & callID, PSafetyMode mode) { - for (PSafePtr<SIPHandler> handler(*this, m); handler != NULL; ++handler) - if (callID == handler->GetCallID()) + for (PSafePtr<SIPHandler> handler(*this, PSafeReference); handler != NULL; ++handler) { + if (callID == handler->GetCallID() && handler.SetSafetyMode(mode)) return handler; + } return NULL; } @@ -1505,38 +1516,44 @@ /** * Find the SIPHandler object with the specified authRealm */ -PSafePtr<SIPHandler> SIPHandlersList::FindSIPHandlerByAuthRealm (const PString & authRealm, const PString & userName, PSafetyMode m) +PSafePtr<SIPHandler> SIPHandlersList::FindSIPHandlerByAuthRealm (const PString & authRealm, const PString & userName, PSafetyMode mode) { - PIPSocket::Address realmAddress; + PIPSocket::Address handlerRealmAddress; + PIPSocket::Address authRealmAddress(authRealm); // if username is specified, look for exact matches if (!userName.IsEmpty()) { // look for a match to exact user name and realm - for (PSafePtr<SIPHandler> handler(*this, m); handler != NULL; ++handler) { - if ((userName == handler->GetUsername()) && (handler->GetRealm().IsEmpty() || (handler->GetRealm() == authRealm))) + for (PSafePtr<SIPHandler> handler(*this, PSafeReference); handler != NULL; ++handler) { + if ( handler->GetUsername() == userName && + (handler->GetRealm().IsEmpty() || handler->GetRealm() == authRealm) && + handler.SetSafetyMode(mode)) return handler; } // look for a match to exact username and realm as hostname - for (PSafePtr<SIPHandler> handler(*this, m); handler != NULL; ++handler) { - if (PIPSocket::GetHostAddress(handler->GetRealm(), realmAddress)) - if ((userName == handler->GetUsername()) && (realmAddress == PIPSocket::Address(authRealm))) - return handler; + for (PSafePtr<SIPHandler> handler(*this, PSafeReference); handler != NULL; ++handler) { + if (PIPSocket::GetHostAddress(handler->GetRealm(), handlerRealmAddress) && + handlerRealmAddress == authRealmAddress && + handler->GetUsername() == userName && + handler.SetSafetyMode(mode)) + return handler; } } // look for a match to exact realm - for (PSafePtr<SIPHandler> handler(*this, m); handler != NULL; ++handler) { - if (authRealm == handler->GetRealm()) + for (PSafePtr<SIPHandler> handler(*this, PSafeReference); handler != NULL; ++handler) { + if (handler->GetRealm() == authRealm && handler.SetSafetyMode(mode)) return handler; } // look for a match to exact realm as hostname - for (PSafePtr<SIPHandler> handler(*this, m); handler != NULL; ++handler) { - if (PIPSocket::GetHostAddress(handler->GetRealm(), realmAddress)) - if (realmAddress == PIPSocket::Address(authRealm)) - return handler; + for (PSafePtr<SIPHandler> handler(*this, PSafeReference); handler != NULL; ++handler) { + if (PIPSocket::GetHostAddress(handler->GetRealm(), handlerRealmAddress) && + handlerRealmAddress == authRealmAddress && + handler.SetSafetyMode(mode)) + return handler; } return NULL; } @@ -1549,24 +1566,27 @@ * or 60...@se... when registering 60...@se... to * sip.seconix.com */ -PSafePtr<SIPHandler> SIPHandlersList::FindSIPHandlerByUrl(const PString & remoteAddress, SIP_PDU::Methods meth, PSafetyMode m) +PSafePtr<SIPHandler> SIPHandlersList::FindSIPHandlerByUrl(const PString & remoteAddress, SIP_PDU::Methods meth, PSafetyMode mode) { SIPURL remoteURL = remoteAddress; - for (PSafePtr<SIPHandler> handler(*this, m); handler != NULL; ++handler) { - if (meth == handler->GetMethod() && remoteURL == handler->GetAddressOfRecord()) + for (PSafePtr<SIPHandler> handler(*this, PSafeReference); handler != NULL; ++handler) { + if (handler->GetMethod() == meth && + handler->GetAddressOfRecord() == remoteURL && + handler.SetSafetyMode(mode)) return handler; } return NULL; } -PSafePtr<SIPHandler> SIPHandlersList::FindSIPHandlerByUrl(const PString & aor, SIP_PDU::Methods meth, const PString & eventPackage, PSafetyMode m) +PSafePtr<SIPHandler> SIPHandlersList::FindSIPHandlerByUrl(const PString & aor, SIP_PDU::Methods meth, const PString & eventPackage, PSafetyMode mode) { SIPURL aorURL = aor; - for (PSafePtr<SIPHandler> handler(*this, m); handler != NULL; ++handler) { - if (meth == handler->GetMethod() && + for (PSafePtr<SIPHandler> handler(*this, PSafeReference); handler != NULL; ++handler) { + if (handler->GetMethod() == meth && handler->GetAddressOfRecord() == aorURL && - handler->GetEventPackage() == eventPackage) + handler->GetEventPackage() == eventPackage && + handler.SetSafetyMode(mode)) return handler; } return NULL; @@ -1578,14 +1598,14 @@ * For example, in the above case, the name parameter * could be "sip.seconix.com" or "seconix.com". */ -PSafePtr<SIPHandler> SIPHandlersList::FindSIPHandlerByDomain(const PString & name, SIP_PDU::Methods meth, PSafetyMode m) +PSafePtr<SIPHandler> SIPHandlersList::FindSIPHandlerByDomain(const PString & name, SIP_PDU::Methods meth, PSafetyMode mode) { - for (PSafePtr<SIPHandler> handler(*this, m); handler != NULL; ++handler) { - - if ((handler->GetMethod() == meth) && - (handler->GetState() != SIPHandler::Unsubscribed) && + for (PSafePtr<SIPHandler> handler(*this, PSafeReference); handler != NULL; ++handler) { + if ( handler->GetMethod() == meth && + handler->GetState() != SIPHandler::Unsubscribed && (handler->GetAddressOfRecord().GetHostName() == name || - handler->GetAddressOfRecord().GetHostAddress().IsEquivalent(name))) + handler->GetAddressOfRecord().GetHostAddress().IsEquivalent(name)) && + handler.SetSafetyMode(mode)) return handler; } return NULL; This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |