[ekiga] Fixed various deadlocks in the OPAL subscription code.



commit cc8525edc871ef8084651f31de4f04da14571b65
Author: Damien Sandras <dsandras seconix com>
Date:   Sat Sep 5 17:36:59 2009 +0200

    Fixed various deadlocks in the OPAL subscription code.
    
    Dropped many mutexes and private lists to register accounts and
    subscribe for presence. We can do so by relying on OPAL for many
    operations.

 lib/engine/components/opal/sip-endpoint.cpp |  202 +++-----------------------
 lib/engine/components/opal/sip-endpoint.h   |   12 --
 2 files changed, 24 insertions(+), 190 deletions(-)
---
diff --git a/lib/engine/components/opal/sip-endpoint.cpp b/lib/engine/components/opal/sip-endpoint.cpp
index 4f8f917..6af84e9 100644
--- a/lib/engine/components/opal/sip-endpoint.cpp
+++ b/lib/engine/components/opal/sip-endpoint.cpp
@@ -269,43 +269,18 @@ Opal::Sip::EndPoint::menu_builder_add_actions (const std::string& fullname,
 
 
 void
-Opal::Sip::EndPoint::fetch (const std::string _uri)
+Opal::Sip::EndPoint::fetch (const std::string uri)
 {
-  PWaitAndSignal mut(listsMutex);
-  std::string::size_type loc = _uri.find ("@", 0);
-  std::string domain;
-
-  if (loc != string::npos)
-    domain = _uri.substr (loc+1);
-
-  // It is not in the list of uris for which a subscribe is active
-  if (std::find (subscribed_uris.begin (), subscribed_uris.end (), _uri) == subscribed_uris.end ()) {
-
-    // The account is active
-    if (std::find (active_domains.begin (), active_domains.end (), domain) != active_domains.end ()) {
-
-      Subscribe (SIPSubscribe::Presence, 300, PString (_uri.c_str ()));
-      Subscribe (SIPSubscribe::Dialog, 300, PString (_uri.c_str ()));
-      subscribed_uris.push_back (_uri);
-    }
-    else {
-
-      to_subscribe_uris.push_back (_uri);
-    }
-  }
+  Subscribe (SIPSubscribe::Presence, 300, uri);
+  Subscribe (SIPSubscribe::Dialog, 300, uri);
 }
 
 
 void
 Opal::Sip::EndPoint::unfetch (const std::string uri)
 {
-  PWaitAndSignal mut(listsMutex);
-  if (std::find (subscribed_uris.begin (), subscribed_uris.end (), uri) != subscribed_uris.end ()) {
-
-    Subscribe (SIPSubscribe::Presence, 0, PString (uri.c_str ()));
-    Subscribe (SIPSubscribe::Dialog, 0, PString (uri.c_str ()));
-    subscribed_uris.remove (uri);
-  }
+  Subscribe (SIPSubscribe::Presence, 0, uri);
+  Subscribe (SIPSubscribe::Dialog, 0, uri);
 }
 
 
@@ -317,21 +292,19 @@ Opal::Sip::EndPoint::publish (const Ekiga::PersonalDetails & details)
   std::string presence = ((Ekiga::PersonalDetails &) (details)).get_presence ();
   std::string status = ((Ekiga::PersonalDetails &) (details)).get_status ();
 
-  {
-    PWaitAndSignal mut(listsMutex);
-    for (std::list<std::string>::iterator it = aors.begin ();
-	 it != aors.end ();
-	 it++) {
+  for (PSafePtr<SIPHandler> handler = activeSIPHandlers.GetFirstHandler(); handler != NULL; ++handler) {
+
+    if (handler->GetMethod() == SIP_PDU::Method_REGISTER) {
 
-      std::string to = it->substr (4);
       PString data;
+      std::string to = handler->GetAddressOfRecord ().AsString ().Mid (4);
       data += "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\r\n";
 
       data += "<presence xmlns=\"urn:ietf:params:xml:ns:pidf\" entity=\"pres:";
       data += to;
       data += "\">\r\n";
 
-      data += "<tuple id=\"";
+      data += "<tuple id=\"sip:";
       data += to;
       data += "_on_";
       data += hostname;
@@ -340,8 +313,8 @@ Opal::Sip::EndPoint::publish (const Ekiga::PersonalDetails & details)
       data += "<note>";
       data += presence.c_str ();
       if (!status.empty ()) {
-	data += " - ";
-	data += status.c_str ();
+        data += " - ";
+        data += status.c_str ();
       }
       data += "</note>\r\n";
 
@@ -351,8 +324,8 @@ Opal::Sip::EndPoint::publish (const Ekiga::PersonalDetails & details)
       data += "</basic>\r\n";
       data += "</status>\r\n";
 
-      data += "<contact priority=\"1\">sip:";
-      data += to;
+      data += "<contact priority=\"1\">";
+      data += to; 
       data += "</contact>\r\n";
 
       data += "</tuple>\r\n";
@@ -364,10 +337,8 @@ Opal::Sip::EndPoint::publish (const Ekiga::PersonalDetails & details)
 
   for (std::map<std::string, PString>::const_iterator iter = publishing.begin ();
        iter != publishing.end ();
-       ++iter) {
-
+       ++iter)
     Publish (iter->first, iter->second, 500); // TODO: allow to change the 500
-  }
 }
 
 
@@ -589,7 +560,6 @@ Opal::Sip::EndPoint::Register (const std::string username,
 			       bool is_limited,
 			       unsigned timeout)
 {
-  PWaitAndSignal mut(listsMutex);
   PString _aor;
   std::stringstream aor;
   std::string host(host_);
@@ -613,14 +583,6 @@ Opal::Sip::EndPoint::Register (const std::string username,
   params.m_minRetryTime = 0;
   params.m_maxRetryTime = 0;
 
-  // Update the list of active domains
-  std::string domain = Opal::Sip::EndPoint::get_aor_domain (aor.str ());
-  bool found = (std::find (active_domains.begin (), active_domains.end (), domain) != active_domains.end ());
-  if (is_enabled && !found)
-    active_domains.push_back (domain);
-  else if (!is_enabled && found)
-    active_domains.remove (domain);
-
   // Register the given aor to the give registrar
   if (!SIPEndPoint::Register (params, _aor))
     OnRegistrationFailed (aor.str (), SIP_PDU::MaxStatusCode, is_enabled);
@@ -631,11 +593,7 @@ void
 Opal::Sip::EndPoint::OnRegistered (const PString & _aor,
 				   bool was_registering)
 {
-  PWaitAndSignal mut(listsMutex);
   std::string aor = (const char *) _aor;
-  std::string::size_type found;
-  std::string::size_type loc = aor.find ("@", 0);
-  std::string server;
   std::stringstream strm;
 
   if (aor.find (uri_prefix) == std::string::npos)
@@ -643,59 +601,6 @@ Opal::Sip::EndPoint::OnRegistered (const PString & _aor,
   else
     strm << aor;
 
-  std::list<std::string>::iterator it = find (aors.begin (), aors.end (), aor);
-
-  if (was_registering) {
-
-    if (it == aors.end ())
-      aors.push_back (strm.str ());
-  }
-  else {
-
-    if (it != aors.end ())
-      aors.remove (strm.str ());
-  }
-
-  if (loc != string::npos) {
-
-    server = get_aor_domain (aor);
-    if (server.empty ())
-      return;
-
-    if (was_registering) {
-      for (std::list<std::string>::iterator iter = to_subscribe_uris.begin ();
-           iter != to_subscribe_uris.end () ; ) {
-
-        found = (*iter).find (server, 0);
-        if (found != string::npos) {
-
-          Subscribe (SIPSubscribe::Presence, 300, PString ((*iter).c_str ()));
-          Subscribe (SIPSubscribe::Dialog, 300, PString ((*iter).c_str ()));
-          subscribed_uris.push_back (*iter);
-          iter = to_subscribe_uris.erase (iter);
-        }
-        else
-          ++iter;
-      }
-    }
-    else {
-      for (std::list<std::string>::iterator iter = subscribed_uris.begin ();
-           iter != subscribed_uris.end () ; ) {
-
-        found = (*iter).find (server, 0);
-        if (found != string::npos) {
-
-          Unsubscribe (SIPSubscribe::Presence, PString ((*iter).c_str ()));
-          Unsubscribe (SIPSubscribe::Dialog, PString ((*iter).c_str ()));
-          to_subscribe_uris.push_back (*iter);
-          iter = subscribed_uris.erase (iter);
-        }
-        else
-          iter++;
-      }
-    }
-  }
-
   /* Subscribe for MWI */
   if (!IsSubscribed (SIPSubscribe::MessageSummary, aor))
     Subscribe (SIPSubscribe::MessageSummary, 3600, aor);
@@ -1075,39 +980,19 @@ Opal::Sip::EndPoint::OnMessageFailed (const SIPURL & messageUrl,
 
 
 SIPURL
-Opal::Sip::EndPoint::GetRegisteredPartyName (const SIPURL & host,
+Opal::Sip::EndPoint::GetRegisteredPartyName (const SIPURL & aor,
 					     const OpalTransport & transport)
 {
-  PString local_address;
-  PIPSocket::Address address;
-  WORD port;
-  PString url;
-  SIPURL registration_address;
-  PWaitAndSignal mut(defaultAORMutex);
-
-  /* If we are registered to an account corresponding to host, use it.
+  /*
+   * Do we have an account?
    */
-  PSafePtr<SIPHandler> info = activeSIPHandlers.FindSIPHandlerByDomain(host.GetHostName (), SIP_PDU::Method_REGISTER, PSafeReadOnly);
-  if (info != NULL) {
+  for (Opal::Bank::iterator it = bank->begin ();
+       it != bank->end ();
+       it++) 
+    if ((*it)->get_host () == (const char*) aor.GetHostName ())
+      return (*it)->get_aor ().c_str ();
 
-    return SIPURL ("\"" + GetDefaultDisplayName () + "\" <" + info->GetAddressOfRecord ().AsString () + ">");
-  }
-  else {
-
-    /* If we are not registered to host,
-     * then use the default account as outgoing identity.
-     * If we are exchanging messages with a peer on our network,
-     * then do not use the default account as outgoing identity.
-     */
-    if (host.GetHostAddress ().GetIpAndPort (address, port) && !manager.IsLocalAddress (address)) {
-
-      if ( !default_aor.empty ())
-        return SIPURL ("\"" + GetDefaultDisplayName () + "\" <" + PString(default_aor) + ">");
-    }
-  }
-
-  /* As a last resort, ie not registered to host, no default account or
-   * dialog with a local peer, then use the local address
+  /* As a last resort, use the local address
    */
   return GetDefaultRegisteredPartyName (transport);
 }
@@ -1291,42 +1176,3 @@ Opal::Sip::EndPoint::mwi_received_in_main (const std::string aor,
     account->handle_message_waiting_information (info);
   }
 }
-
-void
-Opal::Sip::EndPoint::on_bank_updated (Ekiga::AccountPtr /*account*/)
-{
-  { // first we flush the existing value
-    PWaitAndSignal mut(defaultAORMutex);
-    default_aor = "";
-  }
-
-  { // and now we compute it again
-    boost::shared_ptr<Opal::Bank> bank = core.get<Opal::Bank> ("opal-account-store");
-    bank->visit_accounts (boost::bind (&Opal::Sip::EndPoint::search_for_default_account, this, _1));
-  }
-}
-
-bool
-Opal::Sip::EndPoint::search_for_default_account (Ekiga::AccountPtr account_)
-{
-  Opal::AccountPtr account = boost::dynamic_pointer_cast<Opal::Account> (account_);
-  PWaitAndSignal mut(defaultAORMutex);
-  bool result = true;
-
-  /* here is how result is computed here : first, remember it means to go on
-   * the search ; then we want the ekiga.net accounts to have some priority over
-   * others, so by default we want to go on. But if we find an account which is both
-   * suitable (active) and ekiga.net, then we want to stop.
-   */
-
-  if (account->is_active ()) {
-
-    default_aor = account->get_aor ();
-    if (account->get_type () == Opal::Account::Ekiga) {
-
-      result = false;
-    }
-  }
-
-  return result;
-}
diff --git a/lib/engine/components/opal/sip-endpoint.h b/lib/engine/components/opal/sip-endpoint.h
index 0b4d4b4..5d61249 100644
--- a/lib/engine/components/opal/sip-endpoint.h
+++ b/lib/engine/components/opal/sip-endpoint.h
@@ -227,17 +227,6 @@ namespace Opal {
       msgDict msgData;
 
       CallManager & manager;
-
-      PMutex listsMutex;
-      std::list<std::string> to_subscribe_uris;  // List of uris to subscribe
-      std::list<std::string> subscribed_uris;    // List of subscribed uris
-      std::list<std::string> aors;               // List of registered aor
-
-      PMutex defaultAORMutex;
-      std::string default_aor;
-      void on_bank_updated (Ekiga::AccountPtr account);
-      bool search_for_default_account(Ekiga::AccountPtr account);
-
       Ekiga::ServiceCore & core;
 
       Ekiga::CallProtocolManager::Interface listen_iface;
@@ -252,7 +241,6 @@ namespace Opal {
 
       boost::shared_ptr<SIP::Dialect> dialect;
 
-      domain_list active_domains;   // List of active domains
       uri_info_map presence_infos;  // List of uri presences
       uri_info_map dialog_infos;    // List of uri dialog informations
     };



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]