[asterisk-scf-commits] team/dlee/servicediscovery.git branch "ami" updated.

Commits to the Asterisk SCF project code repositories asterisk-scf-commits at lists.digium.com
Fri Nov 19 23:35:49 CST 2010


branch "ami" has been updated
       via  c3a005c4fba65370be3abe014d626aed30ba1d41 (commit)
       via  e5b9f4a036dc687b2720383ccdc2a4fe552fe3b0 (commit)
       via  4cadd2f7e17aa2b01da0fd13cec7fefb615228f5 (commit)
       via  94ab5e476840703f71784a2fd82dee124f9ab2f2 (commit)
      from  dd4d3d7d801b7babf5cf24b66c88cb14869a1fae (commit)

Summary of changes:
 config/test_component.config.in    |    7 +
 config/test_service_locator.config |   12 ++
 src/ServiceLocator.cpp             |   93 ++---------
 src/ServiceLocatorManagement.cpp   |  323 +++++++++++++++++++++++++++++-------
 src/ServiceLocatorManagement.h     |   48 +++++-
 src/ServiceManagement.cpp          |  131 +++++++++++----
 src/ServiceManagement.h            |    4 +-
 test/CMakeLists.txt                |    3 +-
 test/TestComparatorBlocking.cpp    |   56 +++++--
 9 files changed, 479 insertions(+), 198 deletions(-)


- Log -----------------------------------------------------------------
commit c3a005c4fba65370be3abe014d626aed30ba1d41
Author: David M. Lee <dlee at digium.com>
Date:   Fri Nov 19 23:29:50 2010 -0600

    Commenting, formating and general clean up

diff --git a/src/ServiceLocator.cpp b/src/ServiceLocator.cpp
index e2e1159..f16fda5 100644
--- a/src/ServiceLocator.cpp
+++ b/src/ServiceLocator.cpp
@@ -65,9 +65,18 @@ class ServiceLocatorImpl : public ServiceLocator
 public:
     ServiceLocatorImpl(ServiceLocatorManagementImpl* LocatorServiceManagement) :
         mLocatorServiceManagement(LocatorServiceManagement) { };
-
-    void locate_async(const ::AsteriskSCF::Core::Discovery::V1::AMD_ServiceLocator_locatePtr&, const ::AsteriskSCF::Core::Discovery::V1::ServiceLocatorParamsPtr&, const ::Ice::Current&);
-    void locateAll_async(const ::AsteriskSCF::Core::Discovery::V1::AMD_ServiceLocator_locateAllPtr&, const ::AsteriskSCF::Core::Discovery::V1::ServiceLocatorParamsPtr&, const ::Ice::Current&);
+    /**
+     * Asynchronously locate a service for the given parameters.
+     * @see ServiceLocator::locate_async
+     */
+    void locate_async(const AMD_ServiceLocator_locatePtr&,
+        const ServiceLocatorParamsPtr&, const Ice::Current&);
+    /**
+     * Asynchronously locate all service for the given parameters.
+     * @see ServiceLocator::locateAll_async
+     */
+    void locateAll_async(const AMD_ServiceLocator_locateAllPtr&,
+        const ServiceLocatorParamsPtr&, const ::Ice::Current&);
 private:
     /**
      * A pointer to the ServiceManagement implementation as that is where everything is
@@ -83,6 +92,7 @@ void ServiceLocatorImpl::locate_async(const AMD_ServiceLocator_locatePtr& cb,
     const ServiceLocatorParamsPtr& params,
     const ::Ice::Current&)
 {
+    // delegate to the management object, where the data is kept
     mLocatorServiceManagement->locate(cb, params);
 }
 
@@ -90,6 +100,7 @@ void ServiceLocatorImpl::locateAll_async(const AMD_ServiceLocator_locateAllPtr&
     const ServiceLocatorParamsPtr& params,
     const ::Ice::Current&)
 {
+    // delegate to the management object, where the data is kept
     mLocatorServiceManagement->locateAll(cb, params);
 }
 
diff --git a/src/ServiceLocatorManagement.cpp b/src/ServiceLocatorManagement.cpp
index 6ffdfd7..7fed90f 100644
--- a/src/ServiceLocatorManagement.cpp
+++ b/src/ServiceLocatorManagement.cpp
@@ -30,19 +30,17 @@ using namespace std;
 using namespace AsteriskSCF::System::Discovery;
 using namespace AsteriskSCF::System::Logging;
 using namespace AsteriskSCF::Core::Discovery::V1;
+using namespace AsteriskSCF::ServiceDiscovery;
 
 namespace
 {
-Logger const &lg = getLoggerFactory().getLogger("AsteriskSCF.System.Discovery");
-}
 
-namespace AsteriskSCF
-{
-namespace ServiceDiscovery
-{
+Logger const &lg = getLoggerFactory().getLogger("AsteriskSCF.System.Discovery");
 
 /**
- * Callback class for isSupported AMI calls.
+ * Callback class for isSupported AMI calls.  Acts as a bridge between
+ * Ice callbacks and IsSupportedCallback.
+ * @see IsSupportedCallback
  */
 class Comparator_IsSupported_Callback : public IceUtil::Shared
 {
@@ -59,6 +57,7 @@ public:
 
         try
         {
+            // forward result to callback
             callback->result(comparator->end_isSupported(r));
         }
         catch (std::exception const &e)
@@ -99,11 +98,18 @@ public:
      * Results are returned via callback object.
      *
      * @param params Service locator parameters that describe a locator request.
+     * @param callback Callback object which receives the results.
      */
-    void isSupported(const ServiceLocatorParamsPtr& params, IsSupportedCallbackPtr const &callback)
+    void isSupported(const ServiceLocatorParamsPtr& params,
+        IsSupportedCallbackPtr const &callback)
     {
-        Comparator_IsSupported_CallbackPtr iceCallback = new Comparator_IsSupported_Callback(callback);
-        Ice::CallbackPtr d = Ice::newCallback(iceCallback, &Comparator_IsSupported_Callback::finished);
+        // wrap our callback with an Ice callback
+        Comparator_IsSupported_CallbackPtr iceCallback =
+            new Comparator_IsSupported_Callback(callback);
+        // which is wrapped again...
+        Ice::CallbackPtr d = Ice::newCallback(iceCallback,
+            &Comparator_IsSupported_Callback::finished);
+        // async forward to the comparator
         mCompare->begin_isSupported(params, d);
     }
 private:
@@ -114,68 +120,34 @@ private:
 };
 
 /**
- * Small internal class which is used to store private details for
- * ServiceLocatorManagementImpl.
+ * Interface that the LocateCallback uses for collecting information on which
+ * services are supported and which are not.
  */
-class ServiceLocatorManagementImplPriv : public Ice::Object
+class LocateCollector : public IceUtil::Shared
 {
 public:
-    ServiceLocatorManagementImplPriv(const Ice::ObjectAdapterPtr& adapter, const EventsPrx& serviceDiscoveryTopic) :
-        mAdapter(adapter), mLocatorTopic(serviceDiscoveryTopic)
-    {
-    };
-
-    /**
-     * Shared mutex lock which protects the services and comparators.
-     */
-    boost::shared_mutex mLock;
-
-    /**
-     * Object adapter that our service management proxies originate from, it is houses the
-     * main management service.
-     */
-    Ice::ObjectAdapterPtr mAdapter;
-
-    /**
-     * A map of all the comparators that have been added by external components. The key
-     * is the unique identifier that they add themselves with.
-     */
-    std::map<std::string, ServiceLocatorComparator> mCompares;
-
-    /**
-     * A vector of all the services that have been added.
-     */
-    std::vector<ServiceManagementImplPtr> mServices;
-
+    virtual ~LocateCollector() {}
     /**
-     * A proxy that can be used to publish locator events.
+     * Invoked for every service in ServiceLocatorManagementImplPriv::mServices.
+     * @param management Pointer to the management object
+     * @param supported resultsf from ServiceManagementImplPtr::isSupported
      */
-    AsteriskSCF::System::Discovery::EventsPrx mLocatorTopic;
+    virtual void isSupported(ServiceManagementImplPtr management,
+        bool supported) = 0;
 };
-} /* end of ServiceDiscovery */
-} /* end of AsteriskSCF */
-
-using namespace AsteriskSCF::ServiceDiscovery;
 
 /**
- * Implementation of a constructor for the ServiceLocatorManagementImpl class.
+ * A LocateCollector which forwards the first supported service to the
+ * given Ice callback.
  */
-ServiceLocatorManagementImpl::ServiceLocatorManagementImpl(const Ice::ObjectAdapterPtr& adapter,
-    const EventsPrx& serviceDiscoveryTopic) :
-    mImpl(new ServiceLocatorManagementImplPriv(adapter, serviceDiscoveryTopic))
-{
-}
-
-class LocateCollector : public IceUtil::Shared
-{
-public:
-    virtual ~LocateCollector() {}
-    virtual void isSupported(ServiceManagementImplPtr management, bool supported) = 0;
-};
-
 class LocateOneCollector : public LocateCollector
 {
 public:
+    /**
+     * ctor.
+     * @param cb Ice callback.
+     * @param numVotes The number of times isSupported will be called.
+     */
     LocateOneCollector(const AMD_ServiceLocator_locatePtr& cb, int numVotes) :
         cb(cb), numVotes(numVotes)
     {
@@ -193,29 +165,45 @@ public:
 
         if (supported && cb)
         {
-            lg(Debug) << "  ...locate() = " << management->getService()->ice_toString() << '\n';
+            lg(Debug) << "  ...locate() = "
+                      << management->getService()->ice_toString() << '\n';
             cb->ice_response(management->getService());
+            // clear the cb pointer so we only answer once
             cb = 0;
         }
 
+        assert(numVotes > 0); // isSupported was called too many times
+
         if (--numVotes == 0 && cb)
         {
             lg(Debug) << "  ...locate() = ServiceNotFound\n";
             ServiceNotFound e;
             cb->ice_exception(e);
+            // clear the cb pointer so we only answer once
             cb = 0;
         }
     }
 
 private:
     boost::mutex mLock;
+    /** Ice callback */
     AMD_ServiceLocator_locatePtr cb;
+    /** The number of times isSupported will be called. */
     int numVotes;
 };
 
+/**
+ * A LocateCollector which makes a list of all supported services to
+ * forward to the given Ice callback.
+ */
 class LocateAllCollector : public LocateCollector
 {
 public:
+    /**
+     * ctor.
+     * @param cb Ice callback.
+     * @param numVotes The number of times isSupported will be called.
+     */
     LocateAllCollector(const AMD_ServiceLocator_locateAllPtr& cb, int numVotes) :
         cb(cb), numVotes(numVotes)
     {
@@ -238,6 +226,7 @@ public:
 
         if (--numVotes == 0 && cb)
         {
+            // the votes are in!
             if (!value.empty())
             {
                 cb->ice_response(value);
@@ -247,17 +236,29 @@ public:
                 ServiceNotFound e;
                 cb->ice_exception(e);
             }
+            // we're done with the callback
+            cb = 0;
         }
     }
 
 private:
     boost::mutex mLock;
+    /** Ice callback */
     AMD_ServiceLocator_locateAllPtr cb;
+    /** The number of times isSupported will be called. */
     int numVotes;
+    /** Collected results */
     Ice::ObjectProxySeq value;
 };
-
 typedef IceUtil::Handle<LocateCollector> LocateCollectorPtr;
+
+/**
+ * Callback with the results for ServiceManagementImpl::isSupported.  This
+ * implementation simply forwards the info on to a LocateCollector.
+ *
+ * @see ServiceManagementImpl::isSupported
+ * @see LocateCollector
+ */
 class LocateCallback : public IsSupportedCallback
 {
 public:
@@ -281,6 +282,64 @@ private:
 };
 typedef IceUtil::Handle<LocateCallback> LocateCallbackPtr;
 
+} // end of anonymous namespace
+
+IsSupportedCallback::~IsSupportedCallback()
+{
+    // no-op
+}
+
+/**
+ * Small internal class which is used to store private details for
+ * ServiceLocatorManagementImpl.
+ */
+class AsteriskSCF::ServiceDiscovery::ServiceLocatorManagementImplPriv :
+    public Ice::Object
+{
+public:
+    ServiceLocatorManagementImplPriv(const Ice::ObjectAdapterPtr& adapter,
+        const EventsPrx& serviceDiscoveryTopic) :
+        mAdapter(adapter), mLocatorTopic(serviceDiscoveryTopic)
+    {
+    };
+
+    /**
+     * Shared mutex lock which protects the services and comparators.
+     */
+    boost::shared_mutex mLock;
+
+    /**
+     * Object adapter that our service management proxies originate from, it is
+     * houses the main management service.
+     */
+    Ice::ObjectAdapterPtr mAdapter;
+
+    /**
+     * A map of all the comparators that have been added by external components.
+     * The key is the unique identifier that they add themselves with.
+     */
+    std::map<std::string, ServiceLocatorComparator> mCompares;
+
+    /**
+     * A vector of all the services that have been added.
+     */
+    std::vector<ServiceManagementImplPtr> mServices;
+
+    /**
+     * A proxy that can be used to publish locator events.
+     */
+    AsteriskSCF::System::Discovery::EventsPrx mLocatorTopic;
+};
+
+/**
+ * Implementation of a constructor for the ServiceLocatorManagementImpl class.
+ */
+ServiceLocatorManagementImpl::ServiceLocatorManagementImpl(
+    const Ice::ObjectAdapterPtr& adapter,
+    const EventsPrx& serviceDiscoveryTopic) :
+    mImpl(new ServiceLocatorManagementImplPriv(adapter, serviceDiscoveryTopic))
+{
+}
 
 void ServiceLocatorManagementImpl::locate(const AMD_ServiceLocator_locatePtr& cb,
     const ServiceLocatorParamsPtr& params)
@@ -288,23 +347,33 @@ void ServiceLocatorManagementImpl::locate(const AMD_ServiceLocator_locatePtr& cb
     lg(Debug) << "locate(" << params->category << ")\n";
     boost::shared_lock<boost::shared_mutex> lock(mImpl->mLock);
 
-    LocateCollectorPtr collector = new LocateOneCollector(cb, mImpl->mServices.size());
+    LocateCollectorPtr collector = new LocateOneCollector(cb,
+        mImpl->mServices.size());
 
-    for (vector<ServiceManagementImplPtr>::iterator service = mImpl->mServices.begin(); service != mImpl->mServices.end(); ++service)
+    for (vector<ServiceManagementImplPtr>::iterator service =
+             mImpl->mServices.begin();
+         service != mImpl->mServices.end();
+         ++service)
     {
         LocateCallbackPtr callback = new LocateCallback(collector,  *service);
         (*service)->isSupported(params, callback);
     }
 }
 
-void ServiceLocatorManagementImpl::locateAll(const AMD_ServiceLocator_locateAllPtr& cb,
+void ServiceLocatorManagementImpl::locateAll(
+    const AMD_ServiceLocator_locateAllPtr& cb,
     const ServiceLocatorParamsPtr& params)
 {
+    lg(Debug) << "locateAll(" << params->category << ")\n";
     boost::shared_lock<boost::shared_mutex> lock(mImpl->mLock);
 
-    LocateCollectorPtr collector = new LocateAllCollector(cb, mImpl->mServices.size());
+    LocateCollectorPtr collector = new LocateAllCollector(cb,
+        mImpl->mServices.size());
 
-    for (vector<ServiceManagementImplPtr>::iterator service = mImpl->mServices.begin(); service != mImpl->mServices.end(); ++service)
+    for (vector<ServiceManagementImplPtr>::iterator service =
+             mImpl->mServices.begin();
+         service != mImpl->mServices.end();
+         ++service)
     {
         LocateCallbackPtr callback = new LocateCallback(collector,  *service);
         (*service)->isSupported(params, callback);
diff --git a/src/ServiceLocatorManagement.h b/src/ServiceLocatorManagement.h
index a2f4f31..4dddc41 100644
--- a/src/ServiceLocatorManagement.h
+++ b/src/ServiceLocatorManagement.h
@@ -39,36 +39,55 @@ typedef IceUtil::Handle<ServiceManagementImpl> ServiceManagementImplPtr;
  */
 class ServiceLocatorManagementImplPriv;
 
+/**
+ * Callback interface for ServiceLocatorManagementImpl::isSupported.
+ * @see ServiceLocatorManagementImpl::isSupported
+ */
 class IsSupportedCallback : public IceUtil::Shared
 {
 public:
+    virtual ~IsSupportedCallback();
+    /**
+     * Callback for the results from ServiceLocatorManagementImpl::isSupported.
+     */
     virtual void result(bool result) = 0;
 };
 typedef IceUtil::Handle<IsSupportedCallback> IsSupportedCallbackPtr;
 
 /**
- * Implementation of the ServiceLocatorManagement interface as defined in service_locator.ice
+ * Implementation of the ServiceLocatorManagement interface as defined in
+ * service_locator.ice
  */
-class ServiceLocatorManagementImpl : public AsteriskSCF::Core::Discovery::V1::ServiceLocatorManagement
+class ServiceLocatorManagementImpl :
+        public AsteriskSCF::Core::Discovery::V1::ServiceLocatorManagement
 {
 public:
     ServiceLocatorManagementImpl(const Ice::ObjectAdapterPtr& adapter,
         const AsteriskSCF::System::Discovery::EventsPrx& serviceDiscoveryTopic);
-    void locate(const AsteriskSCF::Core::Discovery::V1::AMD_ServiceLocator_locatePtr& cb,
+    void locate(
+        const AsteriskSCF::Core::Discovery::V1::AMD_ServiceLocator_locatePtr&,
         const AsteriskSCF::Core::Discovery::V1::ServiceLocatorParamsPtr&);
-    void locateAll(const AsteriskSCF::Core::Discovery::V1::AMD_ServiceLocator_locateAllPtr&,
+    void locateAll(
+        const AsteriskSCF::Core::Discovery::V1::AMD_ServiceLocator_locateAllPtr&,
         const AsteriskSCF::Core::Discovery::V1::ServiceLocatorParamsPtr&);
 
     //
     // AsteriskSCF::Core::Discovery::V1::ServiceLocatorManagement interface.
     //
-    AsteriskSCF::Core::Discovery::V1::ServiceManagementPrx addService(const Ice::ObjectPrx&, const std::string&, const Ice::Current&);
-    AsteriskSCF::Core::Discovery::V1::ServiceInfoSeq getServices(const ::Ice::Current&) const;
-    AsteriskSCF::Core::Discovery::V1::ServiceInfo getService(const std::string &, const ::Ice::Current&) const;
-    void addCompare(const std::string&, const AsteriskSCF::Core::Discovery::V1::ServiceLocatorParamsComparePrx&, const Ice::Current&);
+    AsteriskSCF::Core::Discovery::V1::ServiceManagementPrx addService(
+        const Ice::ObjectPrx&, const std::string&, const Ice::Current&);
+    AsteriskSCF::Core::Discovery::V1::ServiceInfoSeq getServices(
+        const ::Ice::Current&) const;
+    AsteriskSCF::Core::Discovery::V1::ServiceInfo getService(
+        const std::string &, const ::Ice::Current&) const;
+    void addCompare(const std::string&,
+        const AsteriskSCF::Core::Discovery::V1::ServiceLocatorParamsComparePrx&,
+        const Ice::Current&);
     void removeCompare(const std::string&, const Ice::Current&);
 
-    void isSupported(const std::string&, const AsteriskSCF::Core::Discovery::V1::ServiceLocatorParamsPtr&, IsSupportedCallbackPtr const &);
+    void isSupported(const std::string&,
+        const AsteriskSCF::Core::Discovery::V1::ServiceLocatorParamsPtr&,
+        IsSupportedCallbackPtr const &);
     void removeService(const ServiceManagementImplPtr&);
 private:
     /**
diff --git a/src/ServiceManagement.cpp b/src/ServiceManagement.cpp
index eda51e1..4f96399 100644
--- a/src/ServiceManagement.cpp
+++ b/src/ServiceManagement.cpp
@@ -46,8 +46,10 @@ namespace ServiceDiscovery
 class ServiceLocatorParamsSpec
 {
 public:
-    ServiceLocatorParamsSpec(const AsteriskSCF::Core::Discovery::V1::ServiceLocatorParamsPtr& params, const std::string& compareGuid,
-        ServiceLocatorManagementImpl* management) :
+    ServiceLocatorParamsSpec(const ServiceLocatorParamsPtr& params,
+        const std::string& compareGuid,
+        ServiceLocatorManagementImpl* management)
+        :
         mParams(params),
         mCompareGuid(compareGuid),
         mManagement(management)
@@ -174,6 +176,11 @@ ServiceManagementPrx ServiceManagementImpl::getServiceManagementPrx()
     return mImpl->mManagementPrx;
 }
 
+/**
+ * An IsSupportedCallback that maps a certain number of callback
+ * invocations to a single callback.  If any callbacks are true, true is
+ * called back.  If none are true, false is called back.
+ */
 class CountedIsSupported : public IsSupportedCallback
 {
 public:
@@ -215,20 +222,24 @@ private:
 };
 
 /**
- * An internal function which is called by the service locator to perform a locator parameters comparison
- * at the service level.
+ * An internal function which is called by the service locator to perform a
+ * locator parameters comparison at the service level.
  *
- * @param params A concrete class containing parameters describing the service that is trying to be found.
+ * @param params A concrete class containing parameters describing the
+ *               service that is trying to be found.
+ * @param callback Callback to asynchronously rx the results.
  */
 void ServiceManagementImpl::isSupported(const ServiceLocatorParamsPtr& params, const IsSupportedCallbackPtr& callback)
 {
     boost::shared_lock<boost::shared_mutex> lock(mImpl->mLock);
-    lg(Debug) << __PRETTY_FUNCTION__ << "(" << params->category << ")\n";
+    lg(Debug) << "isSupported(" << params->category << ")\n";
 
-    /* If this service is suspended we can just skip the entire check and return false now, easy as pie */
+    /* If this service is suspended we can just skip the entire check and
+     * return false now, easy as pie
+     */
     if (mImpl->mSuspended)
     {
-        lg(Debug) << "  ..." << __PRETTY_FUNCTION__ << "(" << params->category << ") = false\n";
+        lg(Debug) << "  ...isSupported(" << params->category << ") = false\n";
         callback->result(false);
         return;
     }
@@ -236,7 +247,10 @@ void ServiceManagementImpl::isSupported(const ServiceLocatorParamsPtr& params, c
     IsSupportedCallbackPtr myCallback = new CountedIsSupported(
         callback, mImpl->mSupportedLocatorParams.size());
 
-    for (vector<ServiceLocatorParamsSpec>::iterator spec = mImpl->mSupportedLocatorParams.begin(); spec != mImpl->mSupportedLocatorParams.end(); ++spec)
+    for (vector<ServiceLocatorParamsSpec>::iterator
+             spec = mImpl->mSupportedLocatorParams.begin();
+         spec != mImpl->mSupportedLocatorParams.end();
+         ++spec)
     {
         spec->isSupported(params, myCallback);
     }
@@ -248,25 +262,28 @@ std::string const &ServiceManagementImpl::getGuid() const
 }
 
 /**
- * An internal function which is called by the service locator to perform a locator parameters comparison
- * at the parameter and perhaps comparator level.
- *
- * @param params A concrete class containing parameters describing the service that is trying to be found.
+ * An internal function which is called by the service locator to perform a
+ * locator parameters comparison at the parameter and perhaps comparator level.
  *
+ * @param params A concrete class containing parameters describing the service
+ *               that is trying to be found.
+ * @param callback Callback to asynchronously rx the results.
  */
 void ServiceLocatorParamsSpec::isSupported(const ServiceLocatorParamsPtr& params, const IsSupportedCallbackPtr& callback)
 {
-    lg(Debug) << __PRETTY_FUNCTION__ << "(" << params->category << ")\n";
-    // If no category is passed to us then the component doing the locate wants everything/anything, so give it to them
+    lg(Debug) << "isSupported(" << params->category << ")\n";
+    // If no category is passed to us then the component doing the locate wants
+    // everything/anything, so give it to them
     if (params->category.empty())
     {
-        lg(Debug) << "  ..." << __PRETTY_FUNCTION__ << "(" << params->category << ") = true\n";
+        lg(Debug) << "  ...isSupported(" << params->category << ") = true\n";
         callback->result(true);
     }
-    /* This is just a simple comparison that acts as a preliminary, and perhaps final, check */
+    /* This is just a simple comparison that acts as a preliminary, and
+     * perhaps final, check */
     else if (mParams->category != params->category)
     {
-        lg(Debug) << "  ..." << __PRETTY_FUNCTION__ << "(" << params->category << ") = false\n";
+        lg(Debug) << "  ...isSupported(" << params->category << ") = false\n";
         callback->result(false);
     }
     /* If a comparator was provided then yield to it for a final yay or nay */
@@ -274,6 +291,7 @@ void ServiceLocatorParamsSpec::isSupported(const ServiceLocatorParamsPtr& params
     {
         mManagement->isSupported(mCompareGuid, params, callback);
     }
+    /* category matches, no comparator to turn us down.  it's a match. */
     else
     {
         callback->result(true);
diff --git a/src/ServiceManagement.h b/src/ServiceManagement.h
index a70ccec..24236c1 100644
--- a/src/ServiceManagement.h
+++ b/src/ServiceManagement.h
@@ -47,7 +47,9 @@ public:
 
     Ice::ObjectPrx getService();
     AsteriskSCF::Core::Discovery::V1::ServiceManagementPrx getServiceManagementPrx();
-    void isSupported(const AsteriskSCF::Core::Discovery::V1::ServiceLocatorParamsPtr&, const IsSupportedCallbackPtr&);
+    void isSupported(
+        const AsteriskSCF::Core::Discovery::V1::ServiceLocatorParamsPtr&,
+        const IsSupportedCallbackPtr&);
     const std::string &getGuid() const;
     AsteriskSCF::Core::Discovery::V1::ServiceStatus getStatus() const;
 private:
diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt
index 4176ec2..d5dd7fc 100644
--- a/test/CMakeLists.txt
+++ b/test/CMakeLists.txt
@@ -13,7 +13,8 @@ asterisk_scf_component_add_slice(service_locator_test ServiceLocatorEventsIf)
 asterisk_scf_component_add_file(service_locator_test TestServiceLocator.cpp)
 asterisk_scf_component_add_file(service_locator_test TestComparatorBlocking.cpp)
 asterisk_scf_component_add_ice_libraries(service_locator_test IceStorm)
-asterisk_scf_component_add_boost_libraries(service_locator_test unit_test_framework thread)
+asterisk_scf_component_add_boost_libraries(service_locator_test
+    unit_test_framework thread)
 asterisk_scf_component_build_icebox(service_locator_test)
 #asterisk_scf_component_install(service_locator_test RUNTIME bin "Service Locator Test Driver." Core)
 
diff --git a/test/TestComparatorBlocking.cpp b/test/TestComparatorBlocking.cpp
index 2e0ccfd..d3701e2 100644
--- a/test/TestComparatorBlocking.cpp
+++ b/test/TestComparatorBlocking.cpp
@@ -14,6 +14,15 @@
  * at the top of the source tree.
  */
 
+/*
+ * The purpose of these tests are to verify the resilience of the service
+ * locator in the event of wacky comparators.  For example, the machine
+ * hosting a comparator may suddenly die, at which point Ice calls to the
+ * comparator could take as long as a minute to time out.  Per call.
+ * Without special efforts in implementation, the service locator would be
+ * unable to service calls while it was waiting on the comparator.
+ */
+
 #define BOOST_TEST_DYN_LINK
 
 #include <iostream>
@@ -40,7 +49,7 @@ class BlockingComparator : public ServiceLocatorParamsCompare
 public:
     BlockingComparator() : blocked(true), completed(false) {}
 
-    bool isSupported(const ::AsteriskSCF::Core::Discovery::V1::ServiceLocatorParamsPtr&,
+    bool isSupported(const ServiceLocatorParamsPtr&,
         const ::Ice::Current&)
     {
         boost::unique_lock<boost::mutex> lock(mut);
@@ -59,6 +68,7 @@ public:
     {
         boost::unique_lock<boost::mutex> lock(mut);
         blocked = false;
+        BOOST_TEST_MESSAGE("  ...Unblocking\n");
         cond.notify_one();
     }
 
@@ -69,11 +79,17 @@ private:
     boost::mutex mut;
     bool blocked, completed;
 };
+typedef IceUtil::Handle<BlockingComparator> BlockingComparatorPtr;
 
+/**
+ * An Ice callback object which can pause execution until the callback has
+ * been invoked.
+ */
 class BlockingCallback : public IceUtil::Shared
 {
 public:
     BlockingCallback() : beenCalled(false) {}
+
     void locateCB(const Ice::ObjectPrx&located)
     {
         boost::unique_lock<boost::mutex> lock(mut);
@@ -88,6 +104,13 @@ public:
         cond.notify_one();
     }
 
+    /**
+     * Blocks waiting for callback notification, or until the given timeout
+     * has expired.
+     *
+     * @param waitTimeMillis Max number of milliseconds to wait for callback.
+     * @return True if the callback was invoked.  False if timed out.
+     */
     bool waitForCallback(int waitTimeMillis)
     {
         boost::unique_lock<boost::mutex> lock(mut);
@@ -103,8 +126,6 @@ private:
     boost::mutex mut;
     bool beenCalled;
 };
-
-typedef IceUtil::Handle<BlockingComparator> BlockingComparatorPtr;
 typedef IceUtil::Handle<BlockingCallback> BlockingCallbackPtr;
 
 class Fixture
@@ -114,14 +135,20 @@ public:
         // create an register the blocker
         blockerCommunicator(Ice::initialize()),
         blocker(new BlockingComparator()),
-        blockerAdapter(blockerCommunicator->createObjectAdapterWithEndpoints("blocker", "default")),
-        blockerProxy(ServiceLocatorParamsComparePrx::checkedCast(blockerAdapter->addWithUUID(blocker))),
-        // get references to discovery on different communictor
+        blockerAdapter(
+            blockerCommunicator->createObjectAdapterWithEndpoints(
+                "blocker", "default")),
+        blockerProxy(
+            ServiceLocatorParamsComparePrx::checkedCast(
+                blockerAdapter->addWithUUID(blocker))),
+        // get references to discovery on different communicator
         discoveryCommunicator(Ice::initialize()),
         management(ServiceLocatorManagementPrx::checkedCast(
-                discoveryCommunicator->stringToProxy("LocatorServiceManagement:tcp -p 4422"))),
+                discoveryCommunicator->stringToProxy(
+                    "LocatorServiceManagement:tcp -p 4422"))),
         discovery(ServiceLocatorPrx::checkedCast(
-                discoveryCommunicator->stringToProxy("LocatorService:tcp -p 4411"))),
+                discoveryCommunicator->stringToProxy(
+                    "LocatorService:tcp -p 4411"))),
         proxy(management->addService(management, "self")),
         params(new ServiceLocatorParams())
     {
@@ -211,10 +238,11 @@ BOOST_AUTO_TEST_CASE(testBlocking)
 
     discovery->begin_locate(dne, undiscoveredCB);
 
+    // 10 seconds is ample time to discover something that doesn't exist
     bool secondDiscoveryCompleted = callback->waitForCallback(10000);
     BOOST_REQUIRE(secondDiscoveryCompleted);
-    BOOST_REQUIRE(!blocker->hasCompleted());
 
+    BOOST_REQUIRE(!blocker->hasCompleted());
     blocker->unblock();
     asyncDiscovered->waitForCompleted();
     BOOST_REQUIRE(blocker->hasCompleted());

commit e5b9f4a036dc687b2720383ccdc2a4fe552fe3b0
Author: David M. Lee <dlee at digium.com>
Date:   Fri Nov 19 15:45:47 2010 -0600

    Unit tests pass.

diff --git a/src/ServiceLocator.cpp b/src/ServiceLocator.cpp
index e16dc03..e2e1159 100644
--- a/src/ServiceLocator.cpp
+++ b/src/ServiceLocator.cpp
@@ -77,92 +77,20 @@ private:
     ServiceLocatorManagementImpl* mLocatorServiceManagement;
 };
 
-class LocateThread
-{
-public:
-    LocateThread(const AMD_ServiceLocator_locatePtr& cb,
-        const ServiceLocatorParamsPtr& params,
-        ServiceLocatorManagementImpl* locatorServiceManagement) :
-        mCallback(cb),
-        mParams(params),
-        mLocatorServiceManagement(locatorServiceManagement)
-    {
-    }
-
-    void operator()()
-    {
-        try
-        {
-            lg(Info) << "locate(" << mParams->category << ")\n";
-            mCallback->ice_response(mLocatorServiceManagement->locate(mParams));
-            lg(Info) << "locate(" << mParams->category << "): complete\n";
-        }
-        catch(std::exception const &e)
-        {
-            lg(Info) << "locate(" << mParams->category << "): std::exception(" << e.what() << ")\n";
-            mCallback->ice_exception(e);
-        }
-        catch(...)
-        {
-            lg(Info) << "locate(" << mParams->category << "): bad::exception\n";
-            mCallback->ice_exception();
-        }
-    }
-private:
-    AMD_ServiceLocator_locatePtr mCallback;
-    ServiceLocatorParamsPtr mParams;
-    ServiceLocatorManagementImpl* mLocatorServiceManagement;
-};
-
-class LocateAllThread
-{
-public:
-    LocateAllThread(const AMD_ServiceLocator_locateAllPtr& cb,
-        const ServiceLocatorParamsPtr& params,
-        ServiceLocatorManagementImpl* locatorServiceManagement) :
-        mCallback(cb),
-        mParams(params),
-        mLocatorServiceManagement(locatorServiceManagement)
-    {
-    }
-
-    void operator()()
-    {
-        try
-        {
-            mCallback->ice_response(mLocatorServiceManagement->locateAll(mParams));
-        }
-catch(std::exception const &e)
-        {
-            lg(Info) << "locate(" << mParams->category << "): std::exception(" << e.what() << ")\n";
-            mCallback->ice_exception(e);
-        }
-        catch(...)
-        {
-            lg(Info) << "locate(" << mParams->category << "): bad::exception\n";
-            mCallback->ice_exception();
-        }
-    }
-private:
-    AMD_ServiceLocator_locateAllPtr mCallback;
-    ServiceLocatorParamsPtr mParams;
-    ServiceLocatorManagementImpl* mLocatorServiceManagement;
-};
-
 }
 
 void ServiceLocatorImpl::locate_async(const AMD_ServiceLocator_locatePtr& cb,
     const ServiceLocatorParamsPtr& params,
     const ::Ice::Current&)
 {
-    boost::thread(LocateThread(cb, params, mLocatorServiceManagement));
+    mLocatorServiceManagement->locate(cb, params);
 }
 
 void ServiceLocatorImpl::locateAll_async(const AMD_ServiceLocator_locateAllPtr& cb,
     const ServiceLocatorParamsPtr& params,
     const ::Ice::Current&)
 {
-    boost::thread(LocateAllThread(cb, params, mLocatorServiceManagement));
+    mLocatorServiceManagement->locateAll(cb, params);
 }
 
 void ServiceLocatorApp::start(const string& name, const Ice::CommunicatorPtr& communicator,
diff --git a/src/ServiceLocatorManagement.cpp b/src/ServiceLocatorManagement.cpp
index fdef99d..6ffdfd7 100644
--- a/src/ServiceLocatorManagement.cpp
+++ b/src/ServiceLocatorManagement.cpp
@@ -42,6 +42,43 @@ namespace ServiceDiscovery
 {
 
 /**
+ * Callback class for isSupported AMI calls.
+ */
+class Comparator_IsSupported_Callback : public IceUtil::Shared
+{
+public:
+    Comparator_IsSupported_Callback(IsSupportedCallbackPtr const &callback) :
+        callback(callback)
+    {
+    }
+
+    void finished(const Ice::AsyncResultPtr& r)
+    {
+        ServiceLocatorParamsComparePrx comparator =
+            ServiceLocatorParamsComparePrx::uncheckedCast(r->getProxy());
+
+        try
+        {
+            callback->result(comparator->end_isSupported(r));
+        }
+        catch (std::exception const &e)
+        {
+            lg(Error) << "Error communicating with comparator: " << e.what();
+            callback->result(false);
+        }
+        catch(...)
+        {
+            lg(Error) << "Error communicating with comparator";
+            callback->result(false);
+        }
+    }
+
+private:
+    IsSupportedCallbackPtr callback;
+};
+typedef IceUtil::Handle<Comparator_IsSupported_Callback> Comparator_IsSupported_CallbackPtr;
+
+/**
  * Small internal class which is used to store information about a comparator.
  */
 class ServiceLocatorComparator
@@ -59,15 +96,15 @@ public:
 
     /**
      * API call which forwards an isSupported over ICE to a remote comparator.
+     * Results are returned via callback object.
      *
      * @param params Service locator parameters that describe a locator request.
-     *
-     * @return A boolean value with true indicating the parameters are supported while
-     *         false indicates otherwise.
      */
-    bool isSupported(const ServiceLocatorParamsPtr& params)
+    void isSupported(const ServiceLocatorParamsPtr& params, IsSupportedCallbackPtr const &callback)
     {
-        return mCompare->isSupported(params);
+        Comparator_IsSupported_CallbackPtr iceCallback = new Comparator_IsSupported_Callback(callback);
+        Ice::CallbackPtr d = Ice::newCallback(iceCallback, &Comparator_IsSupported_Callback::finished);
+        mCompare->begin_isSupported(params, d);
     }
 private:
     /**
@@ -129,49 +166,148 @@ ServiceLocatorManagementImpl::ServiceLocatorManagementImpl(const Ice::ObjectAdap
 {
 }
 
-/**
- * Implementation of the locate method as defined in service_locator.ice
- */
-Ice::ObjectPrx ServiceLocatorManagementImpl::locate(const ServiceLocatorParamsPtr& params)
+class LocateCollector : public IceUtil::Shared
 {
-    boost::shared_lock<boost::shared_mutex> lock(mImpl->mLock);
+public:
+    virtual ~LocateCollector() {}
+    virtual void isSupported(ServiceManagementImplPtr management, bool supported) = 0;
+};
 
-    for (vector<ServiceManagementImplPtr>::iterator service = mImpl->mServices.begin(); service != mImpl->mServices.end(); ++service)
+class LocateOneCollector : public LocateCollector
+{
+public:
+    LocateOneCollector(const AMD_ServiceLocator_locatePtr& cb, int numVotes) :
+        cb(cb), numVotes(numVotes)
     {
-        if ((*service)->isSupported(params) == true)
+        if (numVotes == 0)
         {
-            return (*service)->getService();
+            ServiceNotFound e;
+            cb->ice_exception(e);
+            this->cb = 0;
         }
     }
 
-    throw ServiceNotFound();
-}
+    void isSupported(ServiceManagementImplPtr management, bool supported)
+    {
+        boost::lock_guard<boost::mutex> guard(mLock);
 
-/**
- * Implementation of the locateAll method as defined in service_locator.ice
- */
-Ice::ObjectProxySeq ServiceLocatorManagementImpl::locateAll(
-    const ServiceLocatorParamsPtr& params)
+        if (supported && cb)
+        {
+            lg(Debug) << "  ...locate() = " << management->getService()->ice_toString() << '\n';
+            cb->ice_response(management->getService());
+            cb = 0;
+        }
+
+        if (--numVotes == 0 && cb)
+        {
+            lg(Debug) << "  ...locate() = ServiceNotFound\n";
+            ServiceNotFound e;
+            cb->ice_exception(e);
+            cb = 0;
+        }
+    }
+
+private:
+    boost::mutex mLock;
+    AMD_ServiceLocator_locatePtr cb;
+    int numVotes;
+};
+
+class LocateAllCollector : public LocateCollector
 {
-    boost::shared_lock<boost::shared_mutex> lock(mImpl->mLock);
-    Ice::ObjectProxySeq applicableServices;
+public:
+    LocateAllCollector(const AMD_ServiceLocator_locateAllPtr& cb, int numVotes) :
+        cb(cb), numVotes(numVotes)
+    {
+        if (numVotes == 0)
+        {
+            ServiceNotFound e;
+            cb->ice_exception(e);
+            this->cb = 0;
+        }
+    }
 
-    for (vector<ServiceManagementImplPtr>::iterator service = mImpl->mServices.begin();
-         service != mImpl->mServices.end(); ++service)
+    void isSupported(ServiceManagementImplPtr management, bool supported)
     {
-        if ((*service)->isSupported(params) == true)
+        boost::lock_guard<boost::mutex> guard(mLock);
+
+        if (supported)
+        {
+            value.push_back(management->getService());
+        }
+
+        if (--numVotes == 0 && cb)
         {
-            applicableServices.push_back((*service)->getService());
+            if (!value.empty())
+            {
+                cb->ice_response(value);
+            }
+            else
+            {
+                ServiceNotFound e;
+                cb->ice_exception(e);
+            }
         }
     }
 
-    if (!applicableServices.empty())
+private:
+    boost::mutex mLock;
+    AMD_ServiceLocator_locateAllPtr cb;
+    int numVotes;
+    Ice::ObjectProxySeq value;
+};
+
+typedef IceUtil::Handle<LocateCollector> LocateCollectorPtr;
+class LocateCallback : public IsSupportedCallback
+{
+public:
+    LocateCallback(const LocateCollectorPtr& collector,
+        const ServiceManagementImplPtr& management) :
+        collector(collector),
+        management(management)
+    {
+    }
+
+    void result(bool result)
+    {
+        // delegation to thread safe object
+        // no lock needed
+        collector->isSupported(management, result);
+        collector = 0;
+    }
+private:
+    LocateCollectorPtr collector;
+    ServiceManagementImplPtr management;
+};
+typedef IceUtil::Handle<LocateCallback> LocateCallbackPtr;
+
+
+void ServiceLocatorManagementImpl::locate(const AMD_ServiceLocator_locatePtr& cb,
+    const ServiceLocatorParamsPtr& params)
+{
+    lg(Debug) << "locate(" << params->category << ")\n";
+    boost::shared_lock<boost::shared_mutex> lock(mImpl->mLock);
+
+    LocateCollectorPtr collector = new LocateOneCollector(cb, mImpl->mServices.size());
+
+    for (vector<ServiceManagementImplPtr>::iterator service = mImpl->mServices.begin(); service != mImpl->mServices.end(); ++service)
     {
-        return applicableServices;
+        LocateCallbackPtr callback = new LocateCallback(collector,  *service);
+        (*service)->isSupported(params, callback);
     }
-    else
+}
+
+void ServiceLocatorManagementImpl::locateAll(const AMD_ServiceLocator_locateAllPtr& cb,
+    const ServiceLocatorParamsPtr& params)
+{
+    boost::shared_lock<boost::shared_mutex> lock(mImpl->mLock);
+
+    LocateCollectorPtr collector = new LocateAllCollector(cb, mImpl->mServices.size());
+
+    for (vector<ServiceManagementImplPtr>::iterator service = mImpl->mServices.begin(); service != mImpl->mServices.end(); ++service)
     {
-        throw ServiceNotFound();
+        LocateCallbackPtr callback = new LocateCallback(collector,  *service);
+        (*service)->isSupported(params, callback);
     }
 }
 
@@ -265,8 +401,9 @@ void ServiceLocatorManagementImpl::removeCompare(const string& guid, const Ice::
 /**
  * Implementation of the isSupported method as defined in service_locator.ice
  */
-bool ServiceLocatorManagementImpl::isSupported(const string& compareGuid,
-    const ServiceLocatorParamsPtr& params)
+void ServiceLocatorManagementImpl::isSupported(const string& compareGuid,
+    const ServiceLocatorParamsPtr& params,
+    IsSupportedCallbackPtr const &callback)
 {
     /* You'll note there is no lock here. This is because we already have a lock in the locate or locateAll
      * functions.
@@ -276,18 +413,11 @@ bool ServiceLocatorManagementImpl::isSupported(const string& compareGuid,
 
     if (comparator == mImpl->mCompares.end())
     {
-        return false;
+        callback->result(false);
+        return;
     }
 
-    try
-    {
-        return (comparator->second).isSupported(params);
-    }
-    catch (...)
-    {
-        lg(Error) << "An exception was raised when attempting to contact comparator " << compareGuid << ".";
-        return false;
-    }
+    (comparator->second).isSupported(params, callback);
 }
 
 /**
diff --git a/src/ServiceLocatorManagement.h b/src/ServiceLocatorManagement.h
index 2e6a361..a2f4f31 100644
--- a/src/ServiceLocatorManagement.h
+++ b/src/ServiceLocatorManagement.h
@@ -18,6 +18,8 @@
 
 #include <boost/shared_ptr.hpp>
 
+#include <IceUtil/Shared.h>
+
 namespace AsteriskSCF
 {
 namespace ServiceDiscovery
@@ -37,6 +39,13 @@ typedef IceUtil::Handle<ServiceManagementImpl> ServiceManagementImplPtr;
  */
 class ServiceLocatorManagementImplPriv;
 
+class IsSupportedCallback : public IceUtil::Shared
+{
+public:
+    virtual void result(bool result) = 0;
+};
+typedef IceUtil::Handle<IsSupportedCallback> IsSupportedCallbackPtr;
+
 /**
  * Implementation of the ServiceLocatorManagement interface as defined in service_locator.ice
  */
@@ -45,8 +54,10 @@ class ServiceLocatorManagementImpl : public AsteriskSCF::Core::Discovery::V1::Se
 public:
     ServiceLocatorManagementImpl(const Ice::ObjectAdapterPtr& adapter,
         const AsteriskSCF::System::Discovery::EventsPrx& serviceDiscoveryTopic);
-    Ice::ObjectPrx locate(const AsteriskSCF::Core::Discovery::V1::ServiceLocatorParamsPtr&);
-    Ice::ObjectProxySeq locateAll(const AsteriskSCF::Core::Discovery::V1::ServiceLocatorParamsPtr&);
+    void locate(const AsteriskSCF::Core::Discovery::V1::AMD_ServiceLocator_locatePtr& cb,
+        const AsteriskSCF::Core::Discovery::V1::ServiceLocatorParamsPtr&);
+    void locateAll(const AsteriskSCF::Core::Discovery::V1::AMD_ServiceLocator_locateAllPtr&,
+        const AsteriskSCF::Core::Discovery::V1::ServiceLocatorParamsPtr&);
 
     //
     // AsteriskSCF::Core::Discovery::V1::ServiceLocatorManagement interface.
@@ -57,7 +68,7 @@ public:
     void addCompare(const std::string&, const AsteriskSCF::Core::Discovery::V1::ServiceLocatorParamsComparePrx&, const Ice::Current&);
     void removeCompare(const std::string&, const Ice::Current&);
 
-    bool isSupported(const std::string&, const AsteriskSCF::Core::Discovery::V1::ServiceLocatorParamsPtr&);
+    void isSupported(const std::string&, const AsteriskSCF::Core::Discovery::V1::ServiceLocatorParamsPtr&, IsSupportedCallbackPtr const &);
     void removeService(const ServiceManagementImplPtr&);
 private:
     /**
diff --git a/src/ServiceManagement.cpp b/src/ServiceManagement.cpp
index f8ae230..eda51e1 100644
--- a/src/ServiceManagement.cpp
+++ b/src/ServiceManagement.cpp
@@ -54,7 +54,7 @@ public:
     {
     }
 
-    bool isSupported(const AsteriskSCF::Core::Discovery::V1::ServiceLocatorParamsPtr&);
+    void isSupported(const AsteriskSCF::Core::Discovery::V1::ServiceLocatorParamsPtr&, const IsSupportedCallbackPtr&);
 
 private:
     /**
@@ -174,34 +174,72 @@ ServiceManagementPrx ServiceManagementImpl::getServiceManagementPrx()
     return mImpl->mManagementPrx;
 }
 
+class CountedIsSupported : public IsSupportedCallback
+{
+public:
+    CountedIsSupported(const IsSupportedCallbackPtr& callback, int numVotes) :
+        callback(callback),
+        numVotes(numVotes)
+    {
+        if (numVotes == 0)
+        {
+            callback->result(false);
+            lg(Debug) << "  ...isSupported() = false\n";
+            this->callback = 0;
+        }
+    }
+
+    void result(bool result)
+    {
+        boost::lock_guard<boost::mutex> guard(mLock);
+        // any affirmitive vote means success
+        if (result && callback)
+        {
+            lg(Debug) << "  ...isSupported() = true\n";
+            callback->result(true);
+            callback = 0;
+        }
+        // all negative votes means failure
+        if (--numVotes == 0 && callback)
+        {
+            lg(Debug) << "  ...isSupported() = false\n";
+            callback->result(false);
+            callback = 0;
+        }
+    }
+
+private:
+    boost::mutex mLock;
+    IsSupportedCallbackPtr callback;
+    int numVotes;
+};
+
 /**
  * An internal function which is called by the service locator to perform a locator parameters comparison
  * at the service level.
  *
  * @param params A concrete class containing parameters describing the service that is trying to be found.
- *
- * @return A boolean value with true meaning the parameters are supported and false if not.
- *
  */
-bool ServiceManagementImpl::isSupported(const ServiceLocatorParamsPtr& params)
+void ServiceManagementImpl::isSupported(const ServiceLocatorParamsPtr& params, const IsSupportedCallbackPtr& callback)
 {
     boost::shared_lock<boost::shared_mutex> lock(mImpl->mLock);
+    lg(Debug) << __PRETTY_FUNCTION__ << "(" << params->category << ")\n";
 
     /* If this service is suspended we can just skip the entire check and return false now, easy as pie */
     if (mImpl->mSuspended)
     {
-        return false;
+        lg(Debug) << "  ..." << __PRETTY_FUNCTION__ << "(" << params->category << ") = false\n";
+        callback->result(false);
+        return;
     }
 
+    IsSupportedCallbackPtr myCallback = new CountedIsSupported(
+        callback, mImpl->mSupportedLocatorParams.size());
+
     for (vector<ServiceLocatorParamsSpec>::iterator spec = mImpl->mSupportedLocatorParams.begin(); spec != mImpl->mSupportedLocatorParams.end(); ++spec)
     {
-        if ((*spec).isSupported(params) == true)
-        {
-            return true;
-        }
+        spec->isSupported(params, myCallback);
     }
-
-    return false;
 }
 
 std::string const &ServiceManagementImpl::getGuid() const
@@ -215,30 +253,31 @@ std::string const &ServiceManagementImpl::getGuid() const
  *
  * @param params A concrete class containing parameters describing the service that is trying to be found.
  *
- * @return A boolean value with true meaning the parameters are supported and false if not.
- *
  */
-bool ServiceLocatorParamsSpec::isSupported(const ServiceLocatorParamsPtr& params)
+void ServiceLocatorParamsSpec::isSupported(const ServiceLocatorParamsPtr& params, const IsSupportedCallbackPtr& callback)
 {
+    lg(Debug) << __PRETTY_FUNCTION__ << "(" << params->category << ")\n";
     // If no category is passed to us then the component doing the locate wants everything/anything, so give it to them
     if (params->category.empty())
     {
-        return true;
+        lg(Debug) << "  ..." << __PRETTY_FUNCTION__ << "(" << params->category << ") = true\n";
+        callback->result(true);
     }
-
     /* This is just a simple comparison that acts as a preliminary, and perhaps final, check */
-    if (mParams->category != params->category)
+    else if (mParams->category != params->category)
     {
-        return false;
+        lg(Debug) << "  ..." << __PRETTY_FUNCTION__ << "(" << params->category << ") = false\n";
+        callback->result(false);
     }
-
     /* If a comparator was provided then yield to it for a final yay or nay */
-    if (!mCompareGuid.empty())
+    else if (!mCompareGuid.empty())
     {
-        return mManagement->isSupported(mCompareGuid, params);
+        mManagement->isSupported(mCompareGuid, params, callback);
+    }
+    else
+    {
+        callback->result(true);
     }
-
-    return true;
 }
 
 /**
diff --git a/src/ServiceManagement.h b/src/ServiceManagement.h
index 1f30b10..a70ccec 100644
--- a/src/ServiceManagement.h
+++ b/src/ServiceManagement.h
@@ -47,7 +47,7 @@ public:
 
     Ice::ObjectPrx getService();
     AsteriskSCF::Core::Discovery::V1::ServiceManagementPrx getServiceManagementPrx();
-    bool isSupported(const AsteriskSCF::Core::Discovery::V1::ServiceLocatorParamsPtr&);
+    void isSupported(const AsteriskSCF::Core::Discovery::V1::ServiceLocatorParamsPtr&, const IsSupportedCallbackPtr&);
     const std::string &getGuid() const;
     AsteriskSCF::Core::Discovery::V1::ServiceStatus getStatus() const;
 private:
diff --git a/test/TestComparatorBlocking.cpp b/test/TestComparatorBlocking.cpp
index f2621f4..2e0ccfd 100644
--- a/test/TestComparatorBlocking.cpp
+++ b/test/TestComparatorBlocking.cpp
@@ -78,12 +78,14 @@ public:
     {
         boost::unique_lock<boost::mutex> lock(mut);
         beenCalled = true;
+        cond.notify_one();
     }
 
     void locateFailureCB(const Ice::Exception& e)
     {
         boost::unique_lock<boost::mutex> lock(mut);
         beenCalled = true;
+        cond.notify_one();
     }
 
     bool waitForCallback(int waitTimeMillis)

commit 4cadd2f7e17aa2b01da0fd13cec7fefb615228f5
Author: David M. Lee <dlee at digium.com>
Date:   Fri Nov 19 12:16:17 2010 -0600

    Disable collocation optimization.

diff --git a/config/test_component.config.in b/config/test_component.config.in
index b06ab7f..b793c27 100644
--- a/config/test_component.config.in
+++ b/config/test_component.config.in
@@ -1,6 +1,13 @@
 # This is a configuration file used in conjunction with the service discovery test driver
 
 #
+# Ice configuration
+#
+
+# Collocation is incompatible with AMI/AMD which sharing a communicator
+Ice.Default.CollocationOptimized=0
+
+#
 # icebox configuration
 #
 IceBox.InheritProperties=1
diff --git a/config/test_service_locator.config b/config/test_service_locator.config
index 8eb93ff..d058ee6 100644
--- a/config/test_service_locator.config
+++ b/config/test_service_locator.config
@@ -1,5 +1,17 @@
 # This is a configuration file used in conjunction with the service discovery test driver
 
+
+#
+# Ice configuration
+#
+
+# Collocation is incompatible with AMI/AMD which sharing a communicator
+Ice.Default.CollocationOptimized=0
+
+#
+# IceBox configuration
+#
+
 IceBox.InheritProperties=1
 IceBox.Service.ServiceDiscovery=service_locator:create
 

commit 94ab5e476840703f71784a2fd82dee124f9ab2f2
Author: David M. Lee <dlee at digium.com>
Date:   Fri Nov 19 11:07:57 2010 -0600

    Formatting.

diff --git a/test/TestComparatorBlocking.cpp b/test/TestComparatorBlocking.cpp
index 615dd66..f2621f4 100644
--- a/test/TestComparatorBlocking.cpp
+++ b/test/TestComparatorBlocking.cpp
@@ -35,13 +35,17 @@ namespace
  * real-world(TM) scenario where this might happen is a dead server, where
  * TCP timeouts would cause comparator's to block for a minute or so.
  */
-class BlockingComparator : public ServiceLocatorParamsCompare {
+class BlockingComparator : public ServiceLocatorParamsCompare
+{
 public:
     BlockingComparator() : blocked(true), completed(false) {}
 
-    bool isSupported(const ::AsteriskSCF::Core::Discovery::V1::ServiceLocatorParamsPtr&, const ::Ice::Current&) {
+    bool isSupported(const ::AsteriskSCF::Core::Discovery::V1::ServiceLocatorParamsPtr&,
+        const ::Ice::Current&)
+    {
         boost::unique_lock<boost::mutex> lock(mut);
-        while (blocked) {
+        while (blocked)
+        {
             BOOST_TEST_MESSAGE("Blocking\n");
             cond.wait(lock);
             BOOST_TEST_MESSAGE("Unblocked\n");

-----------------------------------------------------------------------


-- 
team/dlee/servicediscovery.git



More information about the asterisk-scf-commits mailing list