[Opalvoip-svn] SF.net SVN: opalvoip:[28549] opal/branches/v3_12
Brought to you by:
csoutheren,
rjongbloed
From: <rjo...@us...> - 2012-11-16 11:31:22
|
Revision: 28549 http://opalvoip.svn.sourceforge.net/opalvoip/?rev=28549&view=rev Author: rjongbloed Date: 2012-11-16 11:31:10 +0000 (Fri, 16 Nov 2012) Log Message: ----------- Major change to the way the network interface monitor call backs work. The old scheme cannot be made 100% thread safe as is, so the architecture (class with virtuals) had to be changed to use notifiers, which are known to be thread safe. Modified Paths: -------------- opal/branches/v3_12/include/h323/gkclient.h opal/branches/v3_12/include/opal/manager.h opal/branches/v3_12/include/sip/sipep.h opal/branches/v3_12/src/h323/gkclient.cxx opal/branches/v3_12/src/opal/manager.cxx opal/branches/v3_12/src/sip/sipep.cxx Modified: opal/branches/v3_12/include/h323/gkclient.h =================================================================== --- opal/branches/v3_12/include/h323/gkclient.h 2012-11-16 11:30:48 UTC (rev 28548) +++ opal/branches/v3_12/include/h323/gkclient.h 2012-11-16 11:31:10 UTC (rev 28549) @@ -341,7 +341,6 @@ // Handling interface changes void OnAddInterface(const PIPSocket::InterfaceEntry & entry, PINDEX priority); void OnRemoveInterface(const PIPSocket::InterfaceEntry & entry, PINDEX priority); - void UpdateConnectionStatus(); bool SetListenerAddresses(H225_ArrayOf_TransportAddress & pdu); // Gatekeeper registration state variables @@ -351,25 +350,8 @@ void SetRegistrationFailReason(unsigned reason, unsigned commandMask); void SetRegistrationFailReason(RegistrationFailReasons reason); - enum { - HighPriority = 80, - LowPriority = 40, - }; - class InterfaceMonitor : public PInterfaceMonitorClient - { - PCLASSINFO(InterfaceMonitor, PInterfaceMonitorClient); - - public: - InterfaceMonitor(H323Gatekeeper & gk, PINDEX priority); - - protected: - virtual void OnAddInterface(const PIPSocket::InterfaceEntry & entry); - virtual void OnRemoveInterface(const PIPSocket::InterfaceEntry & entry); - - H323Gatekeeper & gk; - }; - InterfaceMonitor highPriorityMonitor; - InterfaceMonitor lowPriorityMonitor; + PDECLARE_InterfaceNotifier(H323Gatekeeper, OnHighPriorityInterfaceChange); + PDECLARE_InterfaceNotifier(H323Gatekeeper, OnLowPriorityInterfaceChange); class AlternateInfo : public PObject { PCLASSINFO(AlternateInfo, PObject); Modified: opal/branches/v3_12/include/opal/manager.h =================================================================== --- opal/branches/v3_12/include/opal/manager.h 2012-11-16 11:30:48 UTC (rev 28548) +++ opal/branches/v3_12/include/opal/manager.h 2012-11-16 11:31:10 UTC (rev 28549) @@ -1953,23 +1953,6 @@ WORD current; } tcpPorts, udpPorts, rtpIpPorts; - class InterfaceMonitor : public PInterfaceMonitorClient - { - PCLASSINFO(InterfaceMonitor, PInterfaceMonitorClient); - - enum { - OpalManagerInterfaceMonitorClientPriority = 100, - }; - public: - InterfaceMonitor(OpalManager & manager); - - protected: - virtual void OnAddInterface(const PIPSocket::InterfaceEntry & entry); - virtual void OnRemoveInterface(const PIPSocket::InterfaceEntry & entry); - - OpalManager & m_manager; - }; - #if OPAL_PTLIB_SSL PString m_caFiles; PFilePath m_certificateFile; @@ -1983,8 +1966,8 @@ PString m_natServer; PNatStrategy * m_natMethods; PNatMethod * m_natMethod; + PDECLARE_InterfaceNotifier(OpalManager, OnInterfaceChange); #endif - InterfaceMonitor * interfaceMonitor; RouteTable m_routeTable; PMutex m_routeMutex; Modified: opal/branches/v3_12/include/sip/sipep.h =================================================================== --- opal/branches/v3_12/include/sip/sipep.h 2012-11-16 11:30:48 UTC (rev 28548) +++ opal/branches/v3_12/include/sip/sipep.h 2012-11-16 11:31:10 UTC (rev 28549) @@ -1014,28 +1014,9 @@ SIPThreadPool m_threadPool; // Network interface checking - enum { - HighPriority = 80, - LowPriority = 30, - }; - class InterfaceMonitor : public PInterfaceMonitorClient - { - PCLASSINFO(InterfaceMonitor, PInterfaceMonitorClient); - public: - InterfaceMonitor(SIPEndPoint & manager, PINDEX priority); - - virtual void OnAddInterface(const PIPSocket::InterfaceEntry & entry); - virtual void OnRemoveInterface(const PIPSocket::InterfaceEntry & entry); + PDECLARE_InterfaceNotifier(SIPEndPoint, OnHighPriorityInterfaceChange); + PDECLARE_InterfaceNotifier(SIPEndPoint, OnLowPriorityInterfaceChange); - protected: - SIPEndPoint & m_endpoint; - }; - InterfaceMonitor m_highPriorityMonitor; - InterfaceMonitor m_lowPriorityMonitor; - - friend void InterfaceMonitor::OnAddInterface(const PIPSocket::InterfaceEntry & entry); - friend void InterfaceMonitor::OnRemoveInterface(const PIPSocket::InterfaceEntry & entry); - bool m_disableTrying; P_REMOVE_VIRTUAL_VOID(OnReceivedIntervalTooBrief(SIPTransaction &, SIP_PDU &)); Modified: opal/branches/v3_12/src/h323/gkclient.cxx =================================================================== --- opal/branches/v3_12/src/h323/gkclient.cxx 2012-11-16 11:30:48 UTC (rev 28548) +++ opal/branches/v3_12/src/h323/gkclient.cxx 2012-11-16 11:31:10 UTC (rev 28549) @@ -92,8 +92,6 @@ : H225_RAS(ep, trans) , discoveryComplete(false) , m_registrationFailReason(UnregisteredLocally) - , P_DISABLE_MSVC_WARNINGS(4355, highPriorityMonitor(*this, HighPriority)) - , P_DISABLE_MSVC_WARNINGS(4355, lowPriorityMonitor(*this, LowPriority)) , alternatePermanent(false) , requestMutex(1, 1) , authenticators(ep.CreateAuthenticators()) @@ -117,11 +115,17 @@ features->AttachEndPoint(&ep); features->LoadFeatureSet(H460_Feature::FeatureRas); #endif + + PInterfaceMonitor::GetInstance().AddNotifier(PCREATE_InterfaceNotifier(OnHighPriorityInterfaceChange), 80); + PInterfaceMonitor::GetInstance().AddNotifier(PCREATE_InterfaceNotifier(OnLowPriorityInterfaceChange), 40); } H323Gatekeeper::~H323Gatekeeper() { + PInterfaceMonitor::GetInstance().RemoveNotifier(PCREATE_InterfaceNotifier(OnHighPriorityInterfaceChange)); + PInterfaceMonitor::GetInstance().RemoveNotifier(PCREATE_InterfaceNotifier(OnLowPriorityInterfaceChange)); + if (monitor != NULL) { monitorStop = true; monitorTickle.Signal(); @@ -1998,11 +2002,9 @@ } -void H323Gatekeeper::OnAddInterface(const PIPSocket::InterfaceEntry & /*entry*/, PINDEX priority) +void H323Gatekeeper::OnHighPriorityInterfaceChange(PInterfaceMonitor & monitor, PInterfaceMonitor::InterfaceChange entry) { - if (priority != HighPriority) - UpdateConnectionStatus(); - else { + if (entry.m_added) { // special case if interface filtering is used: A new interface may 'hide' the old interface. // If this is the case, remove the transport interface and do a full rediscovery. // @@ -2019,40 +2021,32 @@ if (!transport->GetRemoteAddress().GetIpAddress(addr)) return; - PStringArray ifaces = lowPriorityMonitor.GetInterfaces(false, addr); + PStringArray ifaces = monitor.GetInterfaces(false, addr); if (ifaces.GetStringsIndex(iface) == P_MAX_INDEX) { // original interface no longer available transport->SetInterface(PString::Empty()); } } } -} - - -void H323Gatekeeper::OnRemoveInterface(const PIPSocket::InterfaceEntry & entry, PINDEX priority) -{ - if (priority == LowPriority) { - UpdateConnectionStatus(); - return; - } + else { + if (transport == NULL) + return; - if (transport == NULL) - return; + PString iface = transport->GetInterface(); + if (iface.IsEmpty()) // not connected. + return; - PString iface = transport->GetInterface(); - if (iface.IsEmpty()) // not connected. - return; - - if (PInterfaceMonitor::IsMatchingInterface(iface, entry)) { - // currently used interface went down. make transport listen - // on all available interfaces. - transport->SetInterface(PString::Empty()); - PTRACE(3, "RAS\tInterface gatekeeper is bound to has gone down, restarting discovery"); + if (PInterfaceMonitor::IsMatchingInterface(iface, entry)) { + // currently used interface went down. make transport listen + // on all available interfaces. + transport->SetInterface(PString::Empty()); + PTRACE(3, "RAS\tInterface gatekeeper is bound to has gone down, restarting discovery"); + } } } -void H323Gatekeeper::UpdateConnectionStatus() +void H323Gatekeeper::OnLowPriorityInterfaceChange(PInterfaceMonitor & monitor, PInterfaceMonitor::InterfaceChange entry) { // sanity check if (transport == NULL) @@ -2068,7 +2062,7 @@ if (!transport->GetRemoteAddress().GetIpAddress(addr)) return; - if (lowPriorityMonitor.GetInterfaces(false, addr).GetSize() > 0) { + if (monitor.GetInterfaces(false, addr).GetSize() > 0) { // at least one interface available, locate gatekeper discoveryComplete = false; reregisterNow = true; @@ -2137,24 +2131,6 @@ strm << ";priority=" << priority; } -///////////////////////////////////////////////////////////////////////////// - -H323Gatekeeper::InterfaceMonitor::InterfaceMonitor(H323Gatekeeper & _gk, PINDEX priority) -: PInterfaceMonitorClient(priority), gk(_gk) -{ -} - -void H323Gatekeeper::InterfaceMonitor::OnAddInterface(const PIPSocket::InterfaceEntry & entry) -{ - gk.OnAddInterface(entry, priority); -} - -void H323Gatekeeper::InterfaceMonitor::OnRemoveInterface(const PIPSocket::InterfaceEntry & entry) -{ - gk.OnRemoveInterface(entry, priority); -} - - #if OPAL_H460 H460_FeatureSet & H323Gatekeeper::GetFeatures() Modified: opal/branches/v3_12/src/opal/manager.cxx =================================================================== --- opal/branches/v3_12/src/opal/manager.cxx 2012-11-16 11:30:48 UTC (rev 28548) +++ opal/branches/v3_12/src/opal/manager.cxx 2012-11-16 11:31:10 UTC (rev 28549) @@ -262,7 +262,6 @@ , m_natMethods(new PNatStrategy) , m_natMethod(NULL) #endif - , interfaceMonitor(NULL) , P_DISABLE_MSVC_WARNINGS(4355, activeCalls(*this)) , garbageCollectSkip(false) , m_decoupledEventPool(5, 0, "Event Pool") @@ -301,6 +300,10 @@ garbageCollector = PThread::Create(PCREATE_NOTIFIER(GarbageMain), "Opal Garbage"); +#if P_NAT + PInterfaceMonitor::GetInstance().AddNotifier(PCREATE_InterfaceNotifier(OnInterfaceChange)); +#endif + PTRACE(4, "OpalMan\tCreated manager."); } @@ -323,10 +326,10 @@ delete garbageCollector; #if P_NAT + PInterfaceMonitor::GetInstance().RemoveNotifier(PCREATE_InterfaceNotifier(OnInterfaceChange)); delete m_natMethod; delete m_natMethods; #endif - delete interfaceMonitor; PTRACE(4, "OpalMan\tDeleted manager."); } @@ -1884,9 +1887,7 @@ if (m_natMethod != NULL) { PInterfaceMonitor::GetInstance().OnRemoveNatMethod(m_natMethod); delete m_natMethod; - delete interfaceMonitor; m_natMethod = NULL; - interfaceMonitor = NULL; } m_natMethod = PNatMethod::Create(natType); @@ -1900,8 +1901,6 @@ return false; } - interfaceMonitor = new InterfaceMonitor(*this); - PNatMethod::NatTypes type = m_natMethod->GetNatType(); PIPSocket::Address stunExternalAddress; if (type != PNatMethod::BlockedNat) @@ -2329,43 +2328,22 @@ ///////////////////////////////////////////////////////////////////////////// -OpalManager::InterfaceMonitor::InterfaceMonitor(OpalManager & manager) - : PInterfaceMonitorClient(OpalManagerInterfaceMonitorClientPriority) - , m_manager(manager) -{ -} - - #if P_NAT -void OpalManager::InterfaceMonitor::OnAddInterface(const PIPSocket::InterfaceEntry & entry) +void OpalManager::OnInterfaceChange(PInterfaceMonitor &, PInterfaceMonitor::InterfaceChange entry) { - PNatMethod * nat = m_manager.GetNatMethod(); + PNatMethod * nat = GetNatMethod(); if (nat != NULL) { - PIPSocket::Address addr; - if (!nat->GetInterfaceAddress(addr) || entry.GetAddress() != addr) - nat->Open(entry.GetAddress()); + PIPSocket::Address addr; + if (entry.m_added) { + if (!nat->GetInterfaceAddress(addr) || entry.GetAddress() != addr) + nat->Open(entry.GetAddress()); + } + else { + if (nat->GetInterfaceAddress(addr) && entry.GetAddress() == addr) + nat->Close(); + } } } - - -void OpalManager::InterfaceMonitor::OnRemoveInterface(const PIPSocket::InterfaceEntry & entry) -{ - PNatMethod * nat = m_manager.GetNatMethod(); - if (nat != NULL) { - PIPSocket::Address addr; - if (nat->GetInterfaceAddress(addr) && entry.GetAddress() == addr) - nat->Close(); - } -} -#else // P_NAT -void OpalManager::InterfaceMonitor::OnAddInterface(const PIPSocket::InterfaceEntry &) -{ -} - - -void OpalManager::InterfaceMonitor::OnRemoveInterface(const PIPSocket::InterfaceEntry &) -{ -} #endif // P_NAT Modified: opal/branches/v3_12/src/sip/sipep.cxx =================================================================== --- opal/branches/v3_12/src/sip/sipep.cxx 2012-11-16 11:30:48 UTC (rev 28548) +++ opal/branches/v3_12/src/sip/sipep.cxx 2012-11-16 11:31:10 UTC (rev 28549) @@ -85,8 +85,6 @@ , m_shuttingDown(false) , m_defaultAppearanceCode(-1) , m_threadPool(maxThreads, "SIP Pool") - , P_DISABLE_MSVC_WARNINGS(4355, m_highPriorityMonitor(*this, HighPriority)) - , P_DISABLE_MSVC_WARNINGS(4355, m_lowPriorityMonitor(*this, LowPriority)) , m_disableTrying(true) { defaultSignalPort = SIPURL::DefaultPort; @@ -107,12 +105,17 @@ manager.AttachEndPoint(this, "sips"); #endif + PInterfaceMonitor::GetInstance().AddNotifier(PCREATE_InterfaceNotifier(OnHighPriorityInterfaceChange), 80); + PInterfaceMonitor::GetInstance().AddNotifier(PCREATE_InterfaceNotifier(OnLowPriorityInterfaceChange), 30); + PTRACE(4, "SIP\tCreated endpoint."); } SIPEndPoint::~SIPEndPoint() { + PInterfaceMonitor::GetInstance().RemoveNotifier(PCREATE_InterfaceNotifier(OnHighPriorityInterfaceChange)); + PInterfaceMonitor::GetInstance().RemoveNotifier(PCREATE_InterfaceNotifier(OnLowPriorityInterfaceChange)); } @@ -1972,21 +1975,9 @@ /////////////////////////////////////////////////////////////////////////////////////////////// -SIPEndPoint::InterfaceMonitor::InterfaceMonitor(SIPEndPoint & ep, PINDEX priority) - : PInterfaceMonitorClient(priority) - , m_endpoint(ep) +void SIPEndPoint::OnHighPriorityInterfaceChange(PInterfaceMonitor &, PInterfaceMonitor::InterfaceChange entry) { -} - - -void SIPEndPoint::InterfaceMonitor::OnAddInterface(const PIPSocket::InterfaceEntry & entry) -{ - if (priority == SIPEndPoint::LowPriority) { - for (PSafePtr<SIPHandler> handler = m_endpoint.activeSIPHandlers.GetFirstHandler(); handler != NULL; ++handler) { - if (handler->GetState() == SIPHandler::Unavailable) - handler->ActivateState(SIPHandler::Restoring); - } - } else { + if (entry.m_added) { // special case if interface filtering is used: A new interface may 'hide' the old interface. // If this is the case, remove the transport interface. // @@ -1995,7 +1986,7 @@ // the transport will still listen on the old interface only. Therefore, clear the // socket binding BEFORE the monitored sockets update their interfaces. if (PInterfaceMonitor::GetInstance().HasInterfaceFilter()) { - for (PSafePtr<SIPHandler> handler = m_endpoint.activeSIPHandlers.GetFirstHandler(PSafeReadOnly); handler != NULL; ++handler) { + for (PSafePtr<SIPHandler> handler = activeSIPHandlers.GetFirstHandler(PSafeReadOnly); handler != NULL; ++handler) { if (handler->GetInterface() == entry.GetName()) { handler->ResetInterface(); handler->SetState(SIPHandler::Unavailable); @@ -2006,10 +1997,14 @@ } -void SIPEndPoint::InterfaceMonitor::OnRemoveInterface(const PIPSocket::InterfaceEntry & entry) +void SIPEndPoint::OnLowPriorityInterfaceChange(PInterfaceMonitor &, PInterfaceMonitor::InterfaceChange entry) { - if (priority == SIPEndPoint::LowPriority) { - for (PSafePtr<SIPHandler> handler = m_endpoint.activeSIPHandlers.GetFirstHandler(PSafeReadOnly); handler != NULL; ++handler) { + for (PSafePtr<SIPHandler> handler = activeSIPHandlers.GetFirstHandler(); handler != NULL; ++handler) { + if (entry.m_added) { + if (handler->GetState() == SIPHandler::Unavailable) + handler->ActivateState(SIPHandler::Restoring); + } + else { if (handler->GetInterface() == entry.GetName()) { handler->ResetInterface(); if (handler->GetState() == SIPHandler::Subscribed) This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |