[asterisk-scf-commits] asterisk-scf/integration/ice-util-cpp.git branch "ami-collector" created.
Commits to the Asterisk SCF project code repositories
asterisk-scf-commits at lists.digium.com
Wed Jan 5 22:06:37 UTC 2011
branch "ami-collector" has been created
at d56505c33fa1901dd5de58d07cb115549e51cb90 (commit)
- Log -----------------------------------------------------------------
commit d56505c33fa1901dd5de58d07cb115549e51cb90
Author: David M. Lee <dlee at digium.com>
Date: Wed Jan 5 16:02:10 2011 -0600
cleanup
diff --git a/AmiCollector/src/AmiCollector.h b/AmiCollector/src/AmiCollector.h
index 5e7e605..a5ddbb9 100644
--- a/AmiCollector/src/AmiCollector.h
+++ b/AmiCollector/src/AmiCollector.h
@@ -33,8 +33,19 @@ namespace IceUtil
* counting logic is properly locked and thread safe, it is incumbent upon the
* implementor of the <code>process*</code> functions to write those functions
* to be thread safe. Derived classes may use mMutex for their own locking.
+ *
+ * An example of the template parameters would be:
+ * <code>
+ * <bool, Ice::ObjectPrx, &Ice::ObjectPrx::element_type::end_ice_isA>
+ * </code>
+ *
+ * @param T The asynchronous result type (return value from end function)
+ * @param P The type of the proxy class
+ * @param EndFunction The pointer to member function for the end_ function
*/
-template<typename T, typename P, T (P::element_type::*EndFunction)(const Ice::AsyncResultPtr&)>
+template<typename T,
+ typename P,
+ T (P::element_type::*EndFunction)(const Ice::AsyncResultPtr&)>
class AmiCollector : public ::IceUtil::Shared
{
public:
diff --git a/AmiCollector/test/TestAmiCollector.h b/AmiCollector/test/TestAmiCollector.h
index b3cb484..6291702 100644
--- a/AmiCollector/test/TestAmiCollector.h
+++ b/AmiCollector/test/TestAmiCollector.h
@@ -27,7 +27,10 @@ namespace IceUtil
/**
* Simple AMI collector for testing
*/
-class TestAmiCollector : public AsteriskSCF::IceUtil::AmiCollector<bool, Ice::ObjectPrx, &Ice::ObjectPrx::element_type::end_ice_isA>
+class TestAmiCollector : public AsteriskSCF::IceUtil::AmiCollector<
+ bool,
+ Ice::ObjectPrx,
+ &Ice::ObjectPrx::element_type::end_ice_isA>
{
public:
explicit TestAmiCollector(size_t n) :
commit 676800cd66e893d4c171603dbe83e703754b23fa
Author: David M. Lee <dlee at digium.com>
Date: Wed Jan 5 15:56:14 2011 -0600
PTMF is now template param.
diff --git a/AmiCollector/src/AmiCollector.h b/AmiCollector/src/AmiCollector.h
index dcae2b9..5e7e605 100644
--- a/AmiCollector/src/AmiCollector.h
+++ b/AmiCollector/src/AmiCollector.h
@@ -34,29 +34,26 @@ namespace IceUtil
* implementor of the <code>process*</code> functions to write those functions
* to be thread safe. Derived classes may use mMutex for their own locking.
*/
-template<typename T, typename P>
+template<typename T, typename P, T (P::element_type::*EndFunction)(const Ice::AsyncResultPtr&)>
class AmiCollector : public ::IceUtil::Shared
{
public:
/** Proxy handle type (i.e. ObjectPrx) */
typedef P IceProxy;
/** Proxy element type (i.e. Proxy::Ice::Object) */
- typedef typename IceProxy::element_type ElementType;
+ typedef typename P::element_type ElementType;
/** Return type for the end function */
typedef T AsyncResultType;
/** The type for AmiCollector itself */
- typedef AmiCollector<T, P> Self;
- /** Pointer to member function for the end function */
- typedef AsyncResultType (ElementType::*EndFunction)(const Ice::AsyncResultPtr&);
+ typedef AmiCollector<T, P, EndFunction> Self;
/**
* Constructor.
* @param numResponses The number of responses expected.
* @param end Pointer to the end function to call for responses.
*/
- AmiCollector(size_t numResponses, EndFunction end) :
- mNumResponses(numResponses),
- mEnd(end)
+ AmiCollector(size_t numResponses) :
+ mNumResponses(numResponses)
{
}
@@ -107,9 +104,9 @@ protected:
if (r)
{
IceProxy p = IceProxy::uncheckedCast(r->getProxy());
- // invoke the mEnd function on our proxy, passing in r
+ // invoke the nd function on our proxy, passing in r
// the results are passed to processResult
- processResult(((*p).*mEnd)(r));
+ processResult(((*p).*EndFunction)(r));
}
else
{
@@ -139,7 +136,6 @@ protected:
private:
size_t mNumResponses;
- EndFunction mEnd;
/**
* Called from each AMI callback. When this function sees that the expected
diff --git a/AmiCollector/test/TestAmiCollector.h b/AmiCollector/test/TestAmiCollector.h
index 6471897..b3cb484 100644
--- a/AmiCollector/test/TestAmiCollector.h
+++ b/AmiCollector/test/TestAmiCollector.h
@@ -27,11 +27,11 @@ namespace IceUtil
/**
* Simple AMI collector for testing
*/
-class TestAmiCollector : public AsteriskSCF::IceUtil::AmiCollector<bool, Ice::ObjectPrx>
+class TestAmiCollector : public AsteriskSCF::IceUtil::AmiCollector<bool, Ice::ObjectPrx, &Ice::ObjectPrx::element_type::end_ice_isA>
{
public:
explicit TestAmiCollector(size_t n) :
- Self(n, &IceProxy::element_type::end_ice_isA),
+ Self(n),
results(0),
exceptions(0),
complete(false)
commit 58459137b2dbc653f98dacc6f8c7da891f0c7ae7
Author: David M. Lee <dlee at digium.com>
Date: Wed Jan 5 15:27:33 2011 -0600
Now I feel good about the AmiCollector :-)
diff --git a/AmiCollector/src/AmiCollector.h b/AmiCollector/src/AmiCollector.h
index 98d0998..dcae2b9 100644
--- a/AmiCollector/src/AmiCollector.h
+++ b/AmiCollector/src/AmiCollector.h
@@ -29,90 +29,117 @@ namespace IceUtil
{
/**
- * Collects the results for multiple asynchronous responses. While the vote
+ * Collects the results for multiple asynchronous responses. While the response
* counting logic is properly locked and thread safe, it is incumbent upon the
* implementor of the <code>process*</code> functions to write those functions
- * to be thread safe. Feel free to use mMutex (it's protected) if needed.
+ * to be thread safe. Derived classes may use mMutex for their own locking.
*/
-template<typename T>
+template<typename T, typename P>
class AmiCollector : public ::IceUtil::Shared
{
public:
+ /** Proxy handle type (i.e. ObjectPrx) */
+ typedef P IceProxy;
+ /** Proxy element type (i.e. Proxy::Ice::Object) */
+ typedef typename IceProxy::element_type ElementType;
+ /** Return type for the end function */
typedef T AsyncResultType;
- typedef AmiCollector<T> Self;
+ /** The type for AmiCollector itself */
+ typedef AmiCollector<T, P> Self;
+ /** Pointer to member function for the end function */
+ typedef AsyncResultType (ElementType::*EndFunction)(const Ice::AsyncResultPtr&);
- AmiCollector(size_t numVotes) : mNumVotes(numVotes)
+ /**
+ * Constructor.
+ * @param numResponses The number of responses expected.
+ * @param end Pointer to the end function to call for responses.
+ */
+ AmiCollector(size_t numResponses, EndFunction end) :
+ mNumResponses(numResponses),
+ mEnd(end)
{
}
/**
* Creates an Ice CallbackPtr wrapper around this object, for use with AMI.
*/
- Ice::CallbackPtr toIceCallback()
+ Ice::CallbackPtr newIceCallback()
{
// this happens prior to any callbacks, to no need to lock
// handle the case where we don't expect any responses
// can't handle this in the ctor, since you can't call virtual
// functions in the constructor
- if (mNumVotes == 0)
+ if (mNumResponses == 0)
{
processCompletion();
}
return Ice::newCallback(this, &Self::finished);
}
- size_t getRemainingVotes() const { return mNumVotes; }
+ /** The number of outstanding responses remaining. */
+ size_t getRemainingResponses() const { return mNumResponses; }
protected:
/** Protected dtor prevents creating instances on the stack */
~AmiCollector() {}
- /**
- * Wrapper to correctly end the remote function call.
- * Should almost always look like:
- * <code>
- * DerivedPrx d = DerivedPrx::uncheckedCast(r->getProxy());
- * return d->end_remoteFunction(r);
- * </code>
- */
- virtual AsyncResultType end(const Ice::AsyncResultPtr& proxy) = 0;
- /**
- * Called for each response received.
- */
+ /** Called for each response received. */
virtual void processResult(AsyncResultType result) = 0;
- /**
- * Called for each exception received.
- */
+ /** Called for each exception received. */
virtual void processException(const Ice::Exception& e) = 0;
- /**
- * Called after all the responses or exceptions have been accounted for.
- */
+ /** Called after all the responses or exceptions have been accounted for. */
virtual void processCompletion() {}
+ /**
+ * Thread safety for response counting. Derived classes may use this for
+ * their own thread safety needs as well.
+ */
boost::mutex mMutex;
+ /** Callback from Ice */
void finished(const Ice::AsyncResultPtr& r)
{
try
{
try
{
- processResult(end(r));
+ // unit test may not have an AsyncResultPtr
+ if (r)
+ {
+ IceProxy p = IceProxy::uncheckedCast(r->getProxy());
+ // invoke the mEnd function on our proxy, passing in r
+ // the results are passed to processResult
+ processResult(((*p).*mEnd)(r));
+ }
+ else
+ {
+ // we didn't have an AsyncResultPtr, so make something up
+ processResult(AsyncResultType());
+ }
}
catch(const Ice::Exception& e)
{
processException(e);
}
}
+ catch(const std::exception& e)
+ {
+ // any exceptions thrown during processing are programming errors
+ std::clog << "Unexpected exception: " << e.what() << '\n';
+ assert(false);
+ }
catch(...)
{
- // ignore any processing exceptions
+ // and _please_ don't just throw char pointers :-(
+ std::clog << "Unexpected exception\n";
+ assert(false);
}
countResponse();
}
private:
- size_t mNumVotes;
+ size_t mNumResponses;
+ EndFunction mEnd;
/**
* Called from each AMI callback. When this function sees that the expected
@@ -124,8 +151,8 @@ private:
bool done = false;
{
boost::lock_guard<boost::mutex> lock(mMutex);
- assert(mNumVotes > 0); // we got more responses than expected
- if (--mNumVotes == 0)
+ assert(mNumResponses > 0); // we got more responses than expected
+ if (--mNumResponses == 0)
{
done = true;
}
diff --git a/AmiCollector/test/AmiCollector-test.cpp b/AmiCollector/test/AmiCollector-test.cpp
index 6f659e1..05f2973 100644
--- a/AmiCollector/test/AmiCollector-test.cpp
+++ b/AmiCollector/test/AmiCollector-test.cpp
@@ -14,74 +14,20 @@
* at the top of the source tree.
*/
-#include <Ice/Proxy.h>
#include <boost/test/unit_test.hpp>
#include "AmiCollector.h"
+#include "TestAmiCollector.h"
using namespace AsteriskSCF::IceUtil;
-namespace
-{
-class TestAmiCollector : public AsteriskSCF::IceUtil::AmiCollector<bool>
-{
-public:
- explicit TestAmiCollector(size_t n) :
- AmiCollector<bool>(n),
- results(0),
- exceptions(0),
- complete(false)
- {}
- int results;
- int exceptions;
- bool complete;
-
- void finished(const Ice::AsyncResultPtr& r)
- {
- Self::finished(r);
- }
-
-protected:
- ~TestAmiCollector() {}
- virtual AsyncResultType end(const Ice::AsyncResultPtr& proxy)
- {
- // fake - do nothing
- return false;
- }
- void processResult(AsyncResultType result)
- {
- ++results;
- }
- void processException(const Ice::Exception& e)
- {
- ++exceptions;
- }
- void processCompletion()
- {
- BOOST_CHECK_EQUAL(false, complete);
- complete = true;
- }
-};
-
-typedef IceUtil::Handle<TestAmiCollector> TestAmiCollectorPtr;
-
-template<typename T>
-Ice::CallbackPtr noCallbackPtr(const IceUtil::Handle<T>& ptr,
- void (T::*cb)(const int&),
- void (T::*excb)(const Ice::Exception&),
- void (T::*sentcb)(bool) = 0)
-{
- return Ice::CallbackPtr();
-}
-}
-
BOOST_AUTO_TEST_SUITE(AmiCollectorTest)
BOOST_AUTO_TEST_CASE(test_zero)
{
TestAmiCollectorPtr uut = new TestAmiCollector(0);
- uut->toIceCallback();
+ uut->newIceCallback();
BOOST_CHECK_EQUAL(0, uut->results);
BOOST_CHECK_EQUAL(0, uut->exceptions);
@@ -92,7 +38,7 @@ BOOST_AUTO_TEST_CASE(test_one)
{
TestAmiCollectorPtr uut = new TestAmiCollector(1);
- uut->toIceCallback();
+ uut->newIceCallback();
BOOST_CHECK_EQUAL(0, uut->results);
BOOST_CHECK_EQUAL(0, uut->exceptions);
diff --git a/AmiCollector/test/CMakeLists.txt b/AmiCollector/test/CMakeLists.txt
index eb59de6..952caf0 100644
--- a/AmiCollector/test/CMakeLists.txt
+++ b/AmiCollector/test/CMakeLists.txt
@@ -2,9 +2,11 @@ asterisk_scf_component_init(ami-collector-test CXX)
include_directories("../src")
asterisk_scf_component_add_file(ami-collector-test AmiCollector-test.cpp)
+asterisk_scf_component_add_file(ami-collector-test IceIntegration-test.cpp)
+asterisk_scf_component_add_file(ami-collector-test TestAmiCollector.h)
asterisk_scf_component_add_file(ami-collector-test test.cpp)
-asterisk_scf_component_add_boost_libraries(ami-collector-test unit_test_framework)
+asterisk_scf_component_add_boost_libraries(ami-collector-test unit_test_framework thread)
asterisk_scf_component_build_standalone(ami-collector-test)
diff --git a/AmiCollector/test/IceIntegration-test.cpp b/AmiCollector/test/IceIntegration-test.cpp
new file mode 100644
index 0000000..343ef1e
--- /dev/null
+++ b/AmiCollector/test/IceIntegration-test.cpp
@@ -0,0 +1,120 @@
+/*
+ * Asterisk SCF -- An open-source communications framework.
+ *
+ * Copyright (C) 2010, Digium, Inc.
+ *
+ * See http://www.asterisk.org for more information about
+ * the Asterisk SCF project. Please do not directly contact
+ * any of the maintainers of this project for assistance;
+ * the project provides a web site, mailing lists and IRC
+ * channels for your use.
+ *
+ * This program is free software, distributed under the terms of
+ * the GNU General Public License Version 2. See the LICENSE.txt file
+ * at the top of the source tree.
+ */
+
+#include <unistd.h>
+
+#include <Ice/Ice.h>
+#include <Ice/Proxy.h>
+#include <boost/test/unit_test.hpp>
+
+#include "AmiCollector.h"
+#include "TestAmiCollector.h"
+
+using namespace AsteriskSCF::IceUtil;
+
+namespace
+{
+class MyObject : public Ice::Object{};
+
+struct Fixture
+{
+ Fixture() :
+ communicator(Ice::initialize()),
+ adapter(communicator->createObjectAdapterWithEndpoints("test", "default")),
+ object(new MyObject),
+ proxy(adapter->addWithUUID(object)->ice_collocationOptimized(false))
+ {
+ adapter->activate();
+ }
+
+ ~Fixture()
+ {
+ communicator->shutdown();
+ communicator->waitForShutdown();
+ }
+
+ Ice::CommunicatorPtr communicator;
+ Ice::ObjectAdapterPtr adapter;
+ Ice::ObjectPtr object;
+ Ice::ObjectPrx proxy;
+};
+} // anonymous namespace
+
+BOOST_FIXTURE_TEST_SUITE(AmiCollectorIceIntegration, Fixture)
+
+BOOST_AUTO_TEST_CASE(test_zero)
+{
+ TestAmiCollectorPtr uut = new TestAmiCollector(0);
+ uut->newIceCallback();
+
+ uut->waitForCompletion();
+
+ BOOST_CHECK_EQUAL(0, uut->results);
+ BOOST_CHECK_EQUAL(0, uut->exceptions);
+ BOOST_CHECK_EQUAL(true, uut->complete);
+}
+
+BOOST_AUTO_TEST_CASE(test_one)
+{
+ TestAmiCollectorPtr uut = new TestAmiCollector(1);
+
+ BOOST_CHECK_EQUAL(0, uut->results);
+ BOOST_CHECK_EQUAL(0, uut->exceptions);
+ BOOST_CHECK_EQUAL(false, uut->complete);
+
+ proxy->begin_ice_isA("::Ice::Object", uut->newIceCallback());
+
+ uut->waitForCompletion();
+
+ BOOST_CHECK_EQUAL(1, uut->results);
+ BOOST_CHECK_EQUAL(0, uut->exceptions);
+ BOOST_CHECK_EQUAL(true, uut->complete);
+}
+
+BOOST_AUTO_TEST_CASE(test_exception)
+{
+ TestAmiCollectorPtr uut = new TestAmiCollector(1);
+
+ // by destroying the adapter, we should get an exception back
+ adapter->destroy();
+
+ proxy->begin_ice_isA("object was shutdown", uut->newIceCallback());
+
+ uut->waitForCompletion();
+
+ BOOST_CHECK_EQUAL(0, uut->results);
+ BOOST_CHECK_EQUAL(1, uut->exceptions);
+ BOOST_CHECK_EQUAL(true, uut->complete);
+}
+
+BOOST_AUTO_TEST_CASE(test_some)
+{
+ TestAmiCollectorPtr uut = new TestAmiCollector(5);
+
+ proxy->begin_ice_isA("::Ice::Object", uut->newIceCallback());
+ proxy->begin_ice_isA("::Ice::Object", uut->newIceCallback());
+ proxy->begin_ice_isA("::Ice::Object", uut->newIceCallback());
+ proxy->begin_ice_isA("::Ice::Object", uut->newIceCallback());
+ proxy->begin_ice_isA("::Ice::Object", uut->newIceCallback());
+
+ uut->waitForCompletion();
+
+ BOOST_CHECK_EQUAL(5, uut->results);
+ BOOST_CHECK_EQUAL(0, uut->exceptions);
+ BOOST_CHECK_EQUAL(true, uut->complete);
+}
+
+BOOST_AUTO_TEST_SUITE_END()
diff --git a/AmiCollector/test/TestAmiCollector.h b/AmiCollector/test/TestAmiCollector.h
new file mode 100644
index 0000000..6471897
--- /dev/null
+++ b/AmiCollector/test/TestAmiCollector.h
@@ -0,0 +1,87 @@
+/*
+ * Asterisk SCF -- An open-source communications framework.
+ *
+ * Copyright (C) 2010, Digium, Inc.
+ *
+ * See http://www.asterisk.org for more information about
+ * the Asterisk SCF project. Please do not directly contact
+ * any of the maintainers of this project for assistance;
+ * the project provides a web site, mailing lists and IRC
+ * channels for your use.
+ *
+ * This program is free software, distributed under the terms of
+ * the GNU General Public License Version 2. See the LICENSE.txt file
+ * at the top of the source tree.
+ */
+
+#include <boost/thread/condition_variable.hpp>
+#include <IceUtil/Handle.h>
+
+#include "AmiCollector.h"
+
+namespace AsteriskSCF
+{
+namespace IceUtil
+{
+
+/**
+ * Simple AMI collector for testing
+ */
+class TestAmiCollector : public AsteriskSCF::IceUtil::AmiCollector<bool, Ice::ObjectPrx>
+{
+public:
+ explicit TestAmiCollector(size_t n) :
+ Self(n, &IceProxy::element_type::end_ice_isA),
+ results(0),
+ exceptions(0),
+ complete(false)
+ {}
+ /** Num results received */
+ int results;
+ /** Num exceptions received */
+ int exceptions;
+ /** Is complete? */
+ bool complete;
+
+ /** Exposes the 'finished' callback function for unit testing. */
+ void finished(const Ice::AsyncResultPtr& r)
+ {
+ Self::finished(r);
+ }
+
+ /** Blocks until processCompletion is called. */
+ void waitForCompletion()
+ {
+ boost::unique_lock<boost::mutex> lock(mMutex);
+ while (!complete)
+ {
+ cond.wait(lock);
+ }
+ }
+
+protected:
+ ~TestAmiCollector() {}
+ void processResult(AsyncResultType result)
+ {
+ ++results;
+ }
+ void processException(const Ice::Exception& e)
+ {
+ ++exceptions;
+ }
+ void processCompletion()
+ {
+ boost::unique_lock<boost::mutex> lock(mMutex);
+ BOOST_CHECK_EQUAL(false, complete);
+ complete = true;
+ cond.notify_all();
+ }
+
+private:
+ boost::condition_variable cond;
+};
+
+typedef ::IceUtil::Handle<TestAmiCollector> TestAmiCollectorPtr;
+
+} // IceUtil
+} // AsteriskSCF
commit 595d005e52185c8c7f1c1f8ed1486073cea2478b
Author: David M. Lee <dlee at digium.com>
Date: Wed Jan 5 13:27:22 2011 -0600
Improved AmiCollector.
By using the generic callback, ironically I've reduced the number of
type problems I had with the code.
diff --git a/AmiCollector/src/AmiCollector.h b/AmiCollector/src/AmiCollector.h
index b01e74b..98d0998 100644
--- a/AmiCollector/src/AmiCollector.h
+++ b/AmiCollector/src/AmiCollector.h
@@ -48,12 +48,7 @@ public:
/**
* Creates an Ice CallbackPtr wrapper around this object, for use with AMI.
*/
- template<typename CB, typename HN>
- IceInternal::CallbackBasePtr toIceCallback(CB (*newCallbackFunction)
- (HN,
- void (Self::*cb)(T),
- void (Self::*excb)(const ::Ice::Exception&),
- void (Self::*sentcb)(bool)))
+ Ice::CallbackPtr toIceCallback()
{
// this happens prior to any callbacks, to no need to lock
@@ -64,10 +59,7 @@ public:
{
processCompletion();
}
- return newCallbackFunction(this,
- &AmiCollector<AsyncResultType>::resultCallback,
- &AmiCollector<AsyncResultType>::errorCallback,
- 0 /* sentCallback */);
+ return Ice::newCallback(this, &Self::finished);
}
size_t getRemainingVotes() const { return mNumVotes; }
@@ -76,6 +68,15 @@ protected:
/** Protected dtor prevents creating instances on the stack */
~AmiCollector() {}
/**
+ * Wrapper to correctly end the remote function call.
+ * Should almost always look like:
+ * <code>
+ * DerivedPrx d = DerivedPrx::uncheckedCast(r->getProxy());
+ * return d->end_remoteFunction(r);
+ * </code>
+ */
+ virtual AsyncResultType end(const Ice::AsyncResultPtr& proxy) = 0;
+ /**
* Called for each response received.
*/
virtual void processResult(AsyncResultType result) = 0;
@@ -88,41 +89,28 @@ protected:
*/
virtual void processCompletion() {}
- /**
- * AMI result callback.
- */
- void resultCallback(AsyncResultType result)
- {
- try
- {
- processResult(result);
- }
- catch(...)
- {
- countResponse();
- throw;
- }
- countResponse();
- }
+ boost::mutex mMutex;
- /**
- * AMI exception callback.
- */
- void errorCallback(const Ice::Exception& e)
+ void finished(const Ice::AsyncResultPtr& r)
{
try
{
- processException(e);
+ try
+ {
+ processResult(end(r));
+ }
+ catch(const Ice::Exception& e)
+ {
+ processException(e);
+ }
}
catch(...)
{
- countResponse();
- throw;
+ // ignore any processing exceptions
}
countResponse();
}
- boost::mutex mMutex;
private:
size_t mNumVotes;
diff --git a/AmiCollector/test/AmiCollector-test.cpp b/AmiCollector/test/AmiCollector-test.cpp
index 92f1b1c..6f659e1 100644
--- a/AmiCollector/test/AmiCollector-test.cpp
+++ b/AmiCollector/test/AmiCollector-test.cpp
@@ -36,17 +36,18 @@ public:
int exceptions;
bool complete;
- void resultCallback(AsyncResultType result)
+ void finished(const Ice::AsyncResultPtr& r)
{
- AmiCollector<bool>::resultCallback(result);
- }
- void errorCallback(const Ice::Exception& e)
- {
- AmiCollector<bool>::errorCallback(e);
+ Self::finished(r);
}
protected:
~TestAmiCollector() {}
+ virtual AsyncResultType end(const Ice::AsyncResultPtr& proxy)
+ {
+ // fake - do nothing
+ return false;
+ }
void processResult(AsyncResultType result)
{
++results;
@@ -80,13 +81,7 @@ BOOST_AUTO_TEST_CASE(test_zero)
{
TestAmiCollectorPtr uut = new TestAmiCollector(0);
- Ice::Callback_Object_ice_isAPtr (*factory)
- (const IceUtil::Handle<AmiCollector<bool> >& instance,
- void (AmiCollector<bool>::*cb)(bool),
- void (AmiCollector<bool>::*excb)(const ::Ice::Exception&),
- void (AmiCollector<bool>::*sentcb)(bool)) = Ice::newCallback_Object_ice_isA;
-
- uut->toIceCallback(factory);
+ uut->toIceCallback();
BOOST_CHECK_EQUAL(0, uut->results);
BOOST_CHECK_EQUAL(0, uut->exceptions);
@@ -97,19 +92,13 @@ BOOST_AUTO_TEST_CASE(test_one)
{
TestAmiCollectorPtr uut = new TestAmiCollector(1);
- Ice::Callback_Object_ice_isAPtr (*factory)
- (const IceUtil::Handle<AmiCollector<bool> >& instance,
- void (AmiCollector<bool>::*cb)(bool),
- void (AmiCollector<bool>::*excb)(const ::Ice::Exception&),
- void (AmiCollector<bool>::*sentcb)(bool)) = Ice::newCallback_Object_ice_isA;
-
- uut->toIceCallback(factory);
+ uut->toIceCallback();
BOOST_CHECK_EQUAL(0, uut->results);
BOOST_CHECK_EQUAL(0, uut->exceptions);
BOOST_CHECK_EQUAL(false, uut->complete);
- uut->resultCallback(true);
+ uut->finished(0);
BOOST_CHECK_EQUAL(1, uut->results);
BOOST_CHECK_EQUAL(0, uut->exceptions);
commit dbbf73986f0b6e47f0b78acfd86a8e288a063b92
Author: David M. Lee <dlee at digium.com>
Date: Wed Jan 5 12:51:38 2011 -0600
First attempt at AmiCollector.
Typing of the callback factory class makes this unpleasant.
diff --git a/AmiCollector/CMakeLists.txt b/AmiCollector/CMakeLists.txt
new file mode 100644
index 0000000..47f2510
--- /dev/null
+++ b/AmiCollector/CMakeLists.txt
@@ -0,0 +1,2 @@
+add_subdirectory(src)
+add_subdirectory(test)
diff --git a/AmiCollector/src/AmiCollector.cpp b/AmiCollector/src/AmiCollector.cpp
new file mode 100644
index 0000000..a5e4797
--- /dev/null
+++ b/AmiCollector/src/AmiCollector.cpp
@@ -0,0 +1,17 @@
+/*
+ * Asterisk SCF -- An open-source communications framework.
+ *
+ * Copyright (C) 2010, Digium, Inc.
+ *
+ * See http://www.asterisk.org for more information about
+ * the Asterisk SCF project. Please do not directly contact
+ * any of the maintainers of this project for assistance;
+ * the project provides a web site, mailing lists and IRC
+ * channels for your use.
+ *
+ * This program is free software, distributed under the terms of
+ * the GNU General Public License Version 2. See the LICENSE.txt file
+ * at the top of the source tree.
+ */
+
+#include "AmiCollector.h"
diff --git a/AmiCollector/src/AmiCollector.h b/AmiCollector/src/AmiCollector.h
new file mode 100644
index 0000000..b01e74b
--- /dev/null
+++ b/AmiCollector/src/AmiCollector.h
@@ -0,0 +1,154 @@
+/*
+ * Asterisk SCF -- An open-source communications framework.
+ *
+ * Copyright (C) 2010, Digium, Inc.
+ *
+ * See http://www.asterisk.org for more information about
+ * the Asterisk SCF project. Please do not directly contact
+ * any of the maintainers of this project for assistance;
+ * the project provides a web site, mailing lists and IRC
+ * channels for your use.
+ *
+ * This program is free software, distributed under the terms of
+ * the GNU General Public License Version 2. See the LICENSE.txt file
+ * at the top of the source tree.
+ */
+
+#pragma once
+
+#include <boost/thread/mutex.hpp>
+#include <Ice/Object.h>
+#include <Ice/Proxy.h>
+#include <Ice/OutgoingAsync.h>
+#include <IceUtil/Handle.h>
+#include <IceUtil/Shared.h>
+
+namespace AsteriskSCF
+{
+namespace IceUtil
+{
+
+/**
+ * Collects the results for multiple asynchronous responses. While the vote
+ * counting logic is properly locked and thread safe, it is incumbent upon the
+ * implementor of the <code>process*</code> functions to write those functions
+ * to be thread safe. Feel free to use mMutex (it's protected) if needed.
+ */
+template<typename T>
+class AmiCollector : public ::IceUtil::Shared
+{
+public:
+ typedef T AsyncResultType;
+ typedef AmiCollector<T> Self;
+
+ AmiCollector(size_t numVotes) : mNumVotes(numVotes)
+ {
+ }
+
+ /**
+ * Creates an Ice CallbackPtr wrapper around this object, for use with AMI.
+ */
+ template<typename CB, typename HN>
+ IceInternal::CallbackBasePtr toIceCallback(CB (*newCallbackFunction)
+ (HN,
+ void (Self::*cb)(T),
+ void (Self::*excb)(const ::Ice::Exception&),
+ void (Self::*sentcb)(bool)))
+ {
+ // this happens prior to any callbacks, to no need to lock
+
+ // handle the case where we don't expect any responses
+ // can't handle this in the ctor, since you can't call virtual
+ // functions in the constructor
+ if (mNumVotes == 0)
+ {
+ processCompletion();
+ }
+ return newCallbackFunction(this,
+ &AmiCollector<AsyncResultType>::resultCallback,
+ &AmiCollector<AsyncResultType>::errorCallback,
+ 0 /* sentCallback */);
+ }
+
+ size_t getRemainingVotes() const { return mNumVotes; }
+
+protected:
+ /** Protected dtor prevents creating instances on the stack */
+ ~AmiCollector() {}
+ /**
+ * Called for each response received.
+ */
+ virtual void processResult(AsyncResultType result) = 0;
+ /**
+ * Called for each exception received.
+ */
+ virtual void processException(const Ice::Exception& e) = 0;
+ /**
+ * Called after all the responses or exceptions have been accounted for.
+ */
+ virtual void processCompletion() {}
+
+ /**
+ * AMI result callback.
+ */
+ void resultCallback(AsyncResultType result)
+ {
+ try
+ {
+ processResult(result);
+ }
+ catch(...)
+ {
+ countResponse();
+ throw;
+ }
+ countResponse();
+ }
+
+ /**
+ * AMI exception callback.
+ */
+ void errorCallback(const Ice::Exception& e)
+ {
+ try
+ {
+ processException(e);
+ }
+ catch(...)
+ {
+ countResponse();
+ throw;
+ }
+ countResponse();
+ }
+
+ boost::mutex mMutex;
+private:
+ size_t mNumVotes;
+
+ /**
+ * Called from each AMI callback. When this function sees that the expected
+ * number of responses have been received, it invokes
+ * <code>processCompletion</code>
+ */
+ void countResponse()
+ {
+ bool done = false;
+ {
+ boost::lock_guard<boost::mutex> lock(mMutex);
+ assert(mNumVotes > 0); // we got more responses than expected
+ if (--mNumVotes == 0)
+ {
+ done = true;
+ }
+ }
+
+ if (done)
+ {
+ processCompletion();
+ }
+ }
+};
+
+} // IceUtil
+} // AsteriskSCF
diff --git a/AmiCollector/src/CMakeLists.txt b/AmiCollector/src/CMakeLists.txt
new file mode 100644
index 0000000..319aea0
--- /dev/null
+++ b/AmiCollector/src/CMakeLists.txt
@@ -0,0 +1,6 @@
+asterisk_scf_component_init(ami-collector CXX)
+
+asterisk_scf_component_add_file(ami-collector AmiCollector.h)
+asterisk_scf_component_add_file(ami-collector AmiCollector.cpp)
+
+asterisk_scf_component_build_library(ami-collector)
diff --git a/AmiCollector/test/AmiCollector-test.cpp b/AmiCollector/test/AmiCollector-test.cpp
new file mode 100644
index 0000000..92f1b1c
--- /dev/null
+++ b/AmiCollector/test/AmiCollector-test.cpp
@@ -0,0 +1,119 @@
+/*
+ * Asterisk SCF -- An open-source communications framework.
+ *
+ * Copyright (C) 2010, Digium, Inc.
+ *
+ * See http://www.asterisk.org for more information about
+ * the Asterisk SCF project. Please do not directly contact
+ * any of the maintainers of this project for assistance;
+ * the project provides a web site, mailing lists and IRC
+ * channels for your use.
+ *
+ * This program is free software, distributed under the terms of
+ * the GNU General Public License Version 2. See the LICENSE.txt file
+ * at the top of the source tree.
+ */
+
+#include <Ice/Proxy.h>
+#include <boost/test/unit_test.hpp>
+
+#include "AmiCollector.h"
+
+using namespace AsteriskSCF::IceUtil;
+
+namespace
+{
+class TestAmiCollector : public AsteriskSCF::IceUtil::AmiCollector<bool>
+{
+public:
+ explicit TestAmiCollector(size_t n) :
+ AmiCollector<bool>(n),
+ results(0),
+ exceptions(0),
+ complete(false)
+ {}
+ int results;
+ int exceptions;
+ bool complete;
+
+ void resultCallback(AsyncResultType result)
+ {
+ AmiCollector<bool>::resultCallback(result);
+ }
+ void errorCallback(const Ice::Exception& e)
+ {
+ AmiCollector<bool>::errorCallback(e);
+ }
+
+protected:
+ ~TestAmiCollector() {}
+ void processResult(AsyncResultType result)
+ {
+ ++results;
+ }
+ void processException(const Ice::Exception& e)
+ {
+ ++exceptions;
+ }
+ void processCompletion()
+ {
+ BOOST_CHECK_EQUAL(false, complete);
+ complete = true;
+ }
+};
+
+typedef IceUtil::Handle<TestAmiCollector> TestAmiCollectorPtr;
+
+template<typename T>
+Ice::CallbackPtr noCallbackPtr(const IceUtil::Handle<T>& ptr,
+ void (T::*cb)(const int&),
+ void (T::*excb)(const Ice::Exception&),
+ void (T::*sentcb)(bool) = 0)
+{
+ return Ice::CallbackPtr();
+}
+}
+
+BOOST_AUTO_TEST_SUITE(AmiCollectorTest)
+
+BOOST_AUTO_TEST_CASE(test_zero)
+{
+ TestAmiCollectorPtr uut = new TestAmiCollector(0);
+
+ Ice::Callback_Object_ice_isAPtr (*factory)
+ (const IceUtil::Handle<AmiCollector<bool> >& instance,
+ void (AmiCollector<bool>::*cb)(bool),
+ void (AmiCollector<bool>::*excb)(const ::Ice::Exception&),
+ void (AmiCollector<bool>::*sentcb)(bool)) = Ice::newCallback_Object_ice_isA;
+
+ uut->toIceCallback(factory);
+
+ BOOST_CHECK_EQUAL(0, uut->results);
+ BOOST_CHECK_EQUAL(0, uut->exceptions);
+ BOOST_CHECK_EQUAL(true, uut->complete);
+}
+
+BOOST_AUTO_TEST_CASE(test_one)
+{
+ TestAmiCollectorPtr uut = new TestAmiCollector(1);
+
+ Ice::Callback_Object_ice_isAPtr (*factory)
+ (const IceUtil::Handle<AmiCollector<bool> >& instance,
+ void (AmiCollector<bool>::*cb)(bool),
+ void (AmiCollector<bool>::*excb)(const ::Ice::Exception&),
+ void (AmiCollector<bool>::*sentcb)(bool)) = Ice::newCallback_Object_ice_isA;
+
+ uut->toIceCallback(factory);
+
+ BOOST_CHECK_EQUAL(0, uut->results);
+ BOOST_CHECK_EQUAL(0, uut->exceptions);
+ BOOST_CHECK_EQUAL(false, uut->complete);
+
+ uut->resultCallback(true);
+
+ BOOST_CHECK_EQUAL(1, uut->results);
+ BOOST_CHECK_EQUAL(0, uut->exceptions);
+ BOOST_CHECK_EQUAL(true, uut->complete);
+}
+
+BOOST_AUTO_TEST_SUITE_END()
diff --git a/AmiCollector/test/CMakeLists.txt b/AmiCollector/test/CMakeLists.txt
new file mode 100644
index 0000000..eb59de6
--- /dev/null
+++ b/AmiCollector/test/CMakeLists.txt
@@ -0,0 +1,11 @@
+asterisk_scf_component_init(ami-collector-test CXX)
+include_directories("../src")
+
+asterisk_scf_component_add_file(ami-collector-test AmiCollector-test.cpp)
+asterisk_scf_component_add_file(ami-collector-test test.cpp)
+
+asterisk_scf_component_add_boost_libraries(ami-collector-test unit_test_framework)
+
+asterisk_scf_component_build_standalone(ami-collector-test)
+
+boost_add_test(ami-collector-test)
diff --git a/AmiCollector/test/test.cpp b/AmiCollector/test/test.cpp
new file mode 100644
index 0000000..5503c6c
--- /dev/null
+++ b/AmiCollector/test/test.cpp
@@ -0,0 +1,18 @@
+/*
+ * Asterisk SCF -- An open-source communications framework.
+ *
+ * Copyright (C) 2010, Digium, Inc.
+ *
+ * See http://www.asterisk.org for more information about
+ * the Asterisk SCF project. Please do not directly contact
+ * any of the maintainers of this project for assistance;
+ * the project provides a web site, mailing lists and IRC
+ * channels for your use.
+ *
+ * This program is free software, distributed under the terms of
+ * the GNU General Public License Version 2. See the LICENSE.txt file
+ * at the top of the source tree.
+ */
+
+#define BOOST_TEST_MODULE Logger-client
+#include <boost/test/unit_test.hpp>
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 8212b2a..67c5652 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -5,3 +5,4 @@ endif()
add_subdirectory(SmartProxy)
add_subdirectory(StateReplicator)
+add_subdirectory(AmiCollector)
commit df4537a88e8a9f42b3bb8e1c3030de31ef7a717a
Author: David M. Lee <dlee at digium.com>
Date: Wed Dec 8 14:59:44 2010 -0600
Tightened up state replicator's dependencies.
diff --git a/StateReplicator/src/CMakeLists.txt b/StateReplicator/src/CMakeLists.txt
index 1dc097d..3eb7d57 100644
--- a/StateReplicator/src/CMakeLists.txt
+++ b/StateReplicator/src/CMakeLists.txt
@@ -8,12 +8,5 @@ asterisk_scf_component_add_boost_libraries(StateReplicator thread)
asterisk_scf_component_build_library(StateReplicator)
-# MACH-O requires libraries for linking libraries
-if(APPLE)
- target_link_libraries(StateReplicator ${ICE_CXX_LIB_IceUtil})
- target_link_libraries(StateReplicator ${ICE_CXX_LIB_ZeroCIce})
-endif()
-
-
asterisk_scf_component_install(StateReplicator LIBRARY lib "State Replicator" statereplicator ARCHIVE DESTINATION lib)
diff --git a/StateReplicator/src/StateReplicator.cpp b/StateReplicator/src/StateReplicator.cpp
index 5674a57..a2b6af7 100644
--- a/StateReplicator/src/StateReplicator.cpp
+++ b/StateReplicator/src/StateReplicator.cpp
@@ -14,8 +14,6 @@
* at the top of the source tree.
*/
-#include <IceUtil/UUID.h>
-
#include "StateReplicator.h"
namespace AsteriskSCF
diff --git a/StateReplicator/src/StateReplicator.h b/StateReplicator/src/StateReplicator.h
index b778aeb..425d2fb 100644
--- a/StateReplicator/src/StateReplicator.h
+++ b/StateReplicator/src/StateReplicator.h
@@ -15,7 +15,8 @@
*/
#pragma once
-#include <Ice/Ice.h>
+#include <Ice/Exception.h>
+#include <Ice/Current.h>
#include <boost/thread/thread.hpp>
#include <boost/thread/shared_mutex.hpp>
commit 252d2c549a9b0e6c0b92e0e65896f93c108a44d7
Author: David M. Lee <dlee at digium.com>
Date: Wed Dec 8 14:31:27 2010 -0600
Ice libraries link more sanely now.
diff --git a/SmartProxy/src/CMakeLists.txt b/SmartProxy/src/CMakeLists.txt
index 2d38072..af426fb 100644
--- a/SmartProxy/src/CMakeLists.txt
+++ b/SmartProxy/src/CMakeLists.txt
@@ -15,12 +15,6 @@ include_directories(${logger_dir}/client/src)
asterisk_scf_component_build_library(SmartProxy)
-# MACH-O requires libraries for linking libraries
-if(APPLE)
- target_link_libraries(SmartProxy ${ICE_CXX_LIB_IceUtil})
- target_link_libraries(SmartProxy ${ICE_CXX_LIB_ZeroCIce})
-endif()
-
target_link_libraries(SmartProxy logging-client)
asterisk_scf_component_install(SmartProxy LIBRARY lib "Smart Proxy" SmartProxy ARCHIVE DESTINATION lib)
commit f892a8393bee4e04986191f1a214ba6803d4c643
Author: Ken Hunt <ken.hunt at digium.com>
Date: Tue Dec 7 16:49:18 2010 -0600
Added required logger target lib for windows build.
diff --git a/SmartProxy/src/CMakeLists.txt b/SmartProxy/src/CMakeLists.txt
index cb7ea20..2d38072 100644
--- a/SmartProxy/src/CMakeLists.txt
+++ b/SmartProxy/src/CMakeLists.txt
@@ -21,5 +21,7 @@ if(APPLE)
target_link_libraries(SmartProxy ${ICE_CXX_LIB_ZeroCIce})
endif()
+target_link_libraries(SmartProxy logging-client)
+
asterisk_scf_component_install(SmartProxy LIBRARY lib "Smart Proxy" SmartProxy ARCHIVE DESTINATION lib)
commit 92ca85d2d8db6e9bf2817eada1c4a6914fe5523d
Author: Ken Hunt <ken.hunt at digium.com>
Date: Fri Dec 3 13:07:22 2010 -0600
Manage boost link options in CMake.
diff --git a/StateReplicator/test/CMakeLists.txt b/StateReplicator/test/CMakeLists.txt
index 00d0337..673a9cd 100644
--- a/StateReplicator/test/CMakeLists.txt
+++ b/StateReplicator/test/CMakeLists.txt
@@ -7,7 +7,7 @@ asterisk_scf_component_add_file(StateReplicatorTest TestStateReplicator.cpp)
asterisk_scf_component_add_file(StateReplicatorTest SharedTestData.h)
asterisk_scf_component_add_file(StateReplicatorTest MockStateReplicatorListener.h)
-asterisk_scf_component_add_boost_libraries(StateReplicatorTest unit_test_framework thread)
+asterisk_scf_component_add_boost_libraries(StateReplicatorTest unit_test_framework thread date_time)
asterisk_scf_component_build_standalone(StateReplicatorTest)
asterisk_scf_component_install(StateReplicatorTest RUNTIME bin "StateReplicatorTest Component Test Driver." Test)
diff --git a/StateReplicator/test/TestStateReplicator.cpp b/StateReplicator/test/TestStateReplicator.cpp
index 5cc81a8..4b46e1e 100644
--- a/StateReplicator/test/TestStateReplicator.cpp
+++ b/StateReplicator/test/TestStateReplicator.cpp
@@ -13,7 +13,6 @@
* the GNU General Public License Version 2. See the LICENSE.txt file
* at the top of the source tree.
*/
-#define BOOST_TEST_DYN_LINK
#define BOOST_TEST_MODULE StateReplicatorComponentTestSuite
#define BOOST_TEST_NO_MAIN
commit 91df85017b172327c9464474c5a2224f0927c526
Author: David M. Lee <dlee at digium.com>
Date: Fri Dec 3 14:05:40 2010 -0600
Make initializeOnce public.
There are cases where the user of the SmartProxy may want to try to
safely initialize the proxy, without the ugliness of wrapping the
operator-> call with a try {} catch block.
diff --git a/SmartProxy/src/SmartProxy.h b/SmartProxy/src/SmartProxy.h
index e0443c9..e7b6bc9 100644
--- a/SmartProxy/src/SmartProxy.h
+++ b/SmartProxy/src/SmartProxy.h
@@ -105,6 +105,25 @@ public:
return mProxy != 0;
}
+ /**
+ * Initializes this SmartProxy, but only if it hasn't already been
+ * initialized.
+ *
+ * @return True if initialization successful; false if unsuccessful.
+ */
+ bool initializeOnce()
+ {
+ // isInitialized() and initialize() are thread safe. no need to lock
+ if (isInitialized())
+ {
+ return true;
+ }
+
+ // Try again to initialize.
+ initialize();
+ return isInitialized();
+ }
+
private:
/**
* Initialization. Primarily involves acquring access to specific IceStorm
@@ -157,25 +176,6 @@ private:
}
}
- /**
- * Initializes this SmartProxy, but only if it hasn't already been
- * initialized.
- *
- * @return True if initialization successful; false if unsuccessful.
- */
- bool initializeOnce()
- {
- // isInitialized() and initialize() are thread safe. no need to lock
- if (isInitialized())
- {
- return true;
- }
-
- // Try again to initialize.
- initialize();
- return isInitialized();
- }
-
void copy(const SmartProxy &rhs)
{
// thread safe
commit 6c28b354ea95d1722f3643320a3d4054913844fb
Author: David M. Lee <dlee at digium.com>
Date: Thu Dec 2 16:26:28 2010 -0600
Making SmartProxy thread safe.
See CR-ASTSCF-1.
diff --git a/SmartProxy/src/SmartProxy.h b/SmartProxy/src/SmartProxy.h
index 6af5aba..e0443c9 100644
--- a/SmartProxy/src/SmartProxy.h
+++ b/SmartProxy/src/SmartProxy.h
@@ -18,6 +18,7 @@
#include <iostream>
#include <Ice/Ice.h>
+#include <IceUtil/Mutex.h>
#include "Core/Discovery/ServiceLocatorIf.h"
#include "logger.h"
@@ -68,6 +69,7 @@ public:
P& operator->()
{
+ // everything this calls is thread safe. no need to lock.
assert(mServiceLocator && mLocatorParams);
if (!initializeOnce())
@@ -80,6 +82,8 @@ public:
SmartProxy &operator=(const SmartProxy &rhs)
{
+ // copy is thread safe. no need to lock.
+
// Boo to self-assignment
if (this == &rhs)
{
@@ -91,11 +95,13 @@ public:
operator void*() const
{
+ // mProxy itself is thread safe. no need to lock
return mProxy ? (void *)1 : 0;
}
bool isInitialized() const
{
+ // mProxy itself is thread safe. no need to lock
return mProxy != 0;
}
@@ -106,6 +112,9 @@ private:
*/
void initialize()
{
+ // thread safe
+ IceUtil::Mutex::Lock myLock(mMutex);
+
using namespace AsteriskSCF::System::Logging;
if (!mServiceLocator)
{
@@ -156,6 +165,7 @@ private:
*/
bool initializeOnce()
{
+ // isInitialized() and initialize() are thread safe. no need to lock
if (isInitialized())
{
return true;
@@ -168,12 +178,18 @@ private:
void copy(const SmartProxy &rhs)
{
+ // thread safe
+ IceUtil::Mutex::Lock myLock(mMutex);
+ IceUtil::Mutex::Lock rhsLock(rhs.mMutex);
+
mProxy = rhs.mProxy;
mServiceLocator = rhs.mServiceLocator;
mLocatorParams = rhs.mLocatorParams;
mLogger = rhs.mLogger;
}
+ // we want to lock even const instances, so mMutex must be mutable
+ mutable IceUtil::Mutex mMutex;
P mProxy;
AsteriskSCF::Core::Discovery::V1::ServiceLocatorPrx mServiceLocator;
AsteriskSCF::Core::Discovery::V1::ServiceLocatorParamsPtr mLocatorParams;
commit cf5c0c056f8b62c126dea4087f4c3003e77d08e7
Author: David M. Lee <dlee at digium.com>
Date: Thu Dec 2 16:20:47 2010 -0600
A little const correctness.
diff --git a/SmartProxy/src/SmartProxy.h b/SmartProxy/src/SmartProxy.h
index e295bbb..6af5aba 100644
--- a/SmartProxy/src/SmartProxy.h
+++ b/SmartProxy/src/SmartProxy.h
@@ -94,7 +94,7 @@ public:
return mProxy ? (void *)1 : 0;
}
- bool isInitialized()
+ bool isInitialized() const
{
return mProxy != 0;
}
commit 3f5e6b9888e8a75d3846f191c7cc0cc03a1c59b3
Author: David M. Lee <dlee at digium.com>
Date: Thu Dec 2 15:28:33 2010 -0600
Added some additional null checks.
See CR-ASTSCF-1.
diff --git a/SmartProxy/src/SmartProxy.h b/SmartProxy/src/SmartProxy.h
index 36597f7..e295bbb 100644
--- a/SmartProxy/src/SmartProxy.h
+++ b/SmartProxy/src/SmartProxy.h
@@ -57,6 +57,12 @@ public:
AsteriskSCF::System::Logging::Logger const &lg)
: mServiceLocator(locator), mLocatorParams(params), mLogger(&lg)
{
+ using namespace AsteriskSCF::System::Logging;
+ if (!mLocatorParams)
+ {
+ lg(Error) << "Cannot find service with null parameters";
+ throw AsteriskSCF::Core::Discovery::V1::ServiceNotFound();
+ }
initialize();
}
@@ -108,6 +114,16 @@ private:
return;
}
+ // all paths to set mServiceLocator also set mLogger.
+ // but just in case things change in the future...
+ assert(mLogger);
+
+ if (!mLocatorParams)
+ {
+ (*mLogger)(Error) << "Cannot find service with null parameters";
+ return;
+ }
+
try
{
// Use the locator to find the Proxy
commit c64f60676cb2cab9f7c94e159a4a3af577e24d1e
Author: David M. Lee <dlee at digium.com>
Date: Thu Dec 2 15:27:32 2010 -0600
Removed exception specification. Old Java habits die hard.
See CR-ASTSCF-1.
diff --git a/SmartProxy/src/SmartProxy.h b/SmartProxy/src/SmartProxy.h
index 550425b..36597f7 100644
--- a/SmartProxy/src/SmartProxy.h
+++ b/SmartProxy/src/SmartProxy.h
@@ -60,7 +60,7 @@ public:
initialize();
}
- P& operator->() throw (AsteriskSCF::Core::Discovery::V1::ServiceNotFound)
+ P& operator->()
{
assert(mServiceLocator && mLocatorParams);
commit 016cc138f828cff40f81a2f45247a3de9351886e
Author: David M. Lee <dlee at digium.com>
Date: Thu Dec 2 14:50:34 2010 -0600
Pass Ptr by reference instead of by value.
diff --git a/SmartProxy/src/SmartProxy.h b/SmartProxy/src/SmartProxy.h
index 71c5856..550425b 100644
--- a/SmartProxy/src/SmartProxy.h
+++ b/SmartProxy/src/SmartProxy.h
@@ -53,7 +53,7 @@ public:
SmartProxy(
const AsteriskSCF::Core::Discovery::V1::ServiceLocatorPrx& locator,
- AsteriskSCF::Core::Discovery::V1::ServiceLocatorParamsPtr params,
+ const AsteriskSCF::Core::Discovery::V1::ServiceLocatorParamsPtr& params,
AsteriskSCF::System::Logging::Logger const &lg)
: mServiceLocator(locator), mLocatorParams(params), mLogger(&lg)
{
commit 9719909659c73691c43007c173a12d193b5927f9
Author: David M. Lee <dlee at digium.com>
Date: Thu Dec 2 12:53:34 2010 -0600
mLg -> mLogger
The mLg name was carried over from the use of lg as the Logger name when
it's a file scoped variable. But given the scope of this member
variable, mLogger is more appropriate.
See CR-ASTSCF-1.
diff --git a/SmartProxy/src/SmartProxy.h b/SmartProxy/src/SmartProxy.h
index d141d95..71c5856 100644
--- a/SmartProxy/src/SmartProxy.h
+++ b/SmartProxy/src/SmartProxy.h
@@ -44,17 +44,18 @@ template <class P>
class SmartProxy
{
public:
- SmartProxy() : mServiceLocator(0), mLocatorParams(0), mLg(0) {}
+ SmartProxy() : mServiceLocator(0), mLocatorParams(0), mLogger(0) {}
SmartProxy(const SmartProxy &rhs)
{
copy(rhs);
}
- SmartProxy(const AsteriskSCF::Core::Discovery::V1::ServiceLocatorPrx& locator,
+ SmartProxy(
+ const AsteriskSCF::Core::Discovery::V1::ServiceLocatorPrx& locator,
AsteriskSCF::Core::Discovery::V1::ServiceLocatorParamsPtr params,
AsteriskSCF::System::Logging::Logger const &lg)
- : mServiceLocator(locator), mLocatorParams(params), mLg(&lg)
+ : mServiceLocator(locator), mLocatorParams(params), mLogger(&lg)
{
initialize();
}
@@ -94,7 +95,8 @@ public:
private:
/**
- * Initialization. Primarily involves acquring access to specific IceStorm topic.
+ * Initialization. Primarily involves acquring access to specific IceStorm
+ * topic.
*/
void initialize()
{
@@ -113,18 +115,20 @@ private:
mProxy = P::checkedCast(obj);
if (obj && !mProxy)
{
- (*mLg)(Error) << "Object (" << obj->ice_toString() << ") isn't of expected type";
+ (*mLogger)(Error) << "Object (" << obj->ice_toString()
+ << ") isn't of expected type";
}
}
catch (const Ice::Exception &e)
{
- (*mLg)(Error) << "Exception locating " << mLocatorParams->category << ": " << e.what();
+ (*mLogger)(Error) << "Exception locating "
+ << mLocatorParams->category << ": " << e.what();
return;
}
if (mProxy == 0)
{
- (*mLg)(Error) << "Unable to locate " << mLocatorParams->category;
+ (*mLogger)(Error) << "Unable to locate " << mLocatorParams->category;
}
}
@@ -151,13 +155,13 @@ private:
mProxy = rhs.mProxy;
mServiceLocator = rhs.mServiceLocator;
mLocatorParams = rhs.mLocatorParams;
- mLg = rhs.mLg;
+ mLogger = rhs.mLogger;
}
P mProxy;
AsteriskSCF::Core::Discovery::V1::ServiceLocatorPrx mServiceLocator;
AsteriskSCF::Core::Discovery::V1::ServiceLocatorParamsPtr mLocatorParams;
- AsteriskSCF::System::Logging::Logger const *mLg;
+ AsteriskSCF::System::Logging::Logger const *mLogger;
};
}; // end SmartProxy
commit f2da511f5e9c516626fb788254ee3c83d4df1a58
Author: David M. Lee <dlee at digium.com>
Date: Thu Dec 2 12:48:39 2010 -0600
verifyInitialize -> initializeOnce
Since the function does more than just verify, it needs a more accurate
name.
diff --git a/SmartProxy/src/SmartProxy.h b/SmartProxy/src/SmartProxy.h
index dd0d8bb..d141d95 100644
--- a/SmartProxy/src/SmartProxy.h
+++ b/SmartProxy/src/SmartProxy.h
@@ -63,7 +63,7 @@ public:
{
assert(mServiceLocator && mLocatorParams);
- if (!verifyInitialized())
+ if (!initializeOnce())
{
throw AsteriskSCF::Core::Discovery::V1::ServiceNotFound();
}
@@ -129,9 +129,12 @@ private:
}
/**
- * Utiltity to check for initialization state.
+ * Initializes this SmartProxy, but only if it hasn't already been
+ * initialized.
+ *
+ * @return True if initialization successful; false if unsuccessful.
*/
- bool verifyInitialized()
+ bool initializeOnce()
{
if (isInitialized())
{
commit f5e31dfba81ff92cec22ba81e36ff333afd38fa4
Author: David M. Lee <dlee at digium.com>
Date: Mon Nov 29 08:54:27 2010 -0600
Got rid of extra bool to track state.
diff --git a/SmartProxy/src/SmartProxy.h b/SmartProxy/src/SmartProxy.h
index 8e5da1f..dd0d8bb 100644
--- a/SmartProxy/src/SmartProxy.h
+++ b/SmartProxy/src/SmartProxy.h
@@ -44,7 +44,7 @@ template <class P>
class SmartProxy
{
public:
- SmartProxy() : mServiceLocator(0), mLocatorParams(0), mInitialized(false), mLg(0) {}
+ SmartProxy() : mServiceLocator(0), mLocatorParams(0), mLg(0) {}
SmartProxy(const SmartProxy &rhs)
{
@@ -54,7 +54,7 @@ public:
SmartProxy(const AsteriskSCF::Core::Discovery::V1::ServiceLocatorPrx& locator,
AsteriskSCF::Core::Discovery::V1::ServiceLocatorParamsPtr params,
AsteriskSCF::System::Logging::Logger const &lg)
- : mServiceLocator(locator), mLocatorParams(params), mInitialized(false), mLg(&lg)
+ : mServiceLocator(locator), mLocatorParams(params), mLg(&lg)
{
initialize();
}
@@ -89,7 +89,7 @@ public:
bool isInitialized()
{
- return mInitialized;
+ return mProxy != 0;
}
private:
@@ -126,10 +126,6 @@ private:
{
(*mLg)(Error) << "Unable to locate " << mLocatorParams->category;
}
- else
- {
- mInitialized = true;
- }
}
/**
@@ -137,14 +133,14 @@ private:
*/
bool verifyInitialized()
{
- if (mInitialized)
+ if (isInitialized())
{
return true;
}
// Try again to initialize.
initialize();
- return mInitialized;
+ return isInitialized();
}
void copy(const SmartProxy &rhs)
@@ -153,14 +149,12 @@ private:
mServiceLocator = rhs.mServiceLocator;
mLocatorParams = rhs.mLocatorParams;
mLg = rhs.mLg;
- mInitialized = rhs.mInitialized;
}
P mProxy;
AsteriskSCF::Core::Discovery::V1::ServiceLocatorPrx mServiceLocator;
AsteriskSCF::Core::Discovery::V1::ServiceLocatorParamsPtr mLocatorParams;
AsteriskSCF::System::Logging::Logger const *mLg;
- bool mInitialized;
};
}; // end SmartProxy
commit 909b2ff2d9b7796c1533718af692fe3cd2d69e01
Author: David M. Lee <dlee at digium.com>
Date: Mon Nov 22 20:55:14 2010 -0600
First round of SmartProxy cleanups.
* ProxyWrapper -> SmartProxy
* Log to Logger instead of cout
* Throw real exception instead of string
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 79e7361..8212b2a 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -3,5 +3,5 @@ if (integrated_build STREQUAL "true")
set(utils_bindir ${CMAKE_CURRENT_BINARY_DIR} PARENT_SCOPE)
endif()
-add_subdirectory(ProxyWrapper)
+add_subdirectory(SmartProxy)
add_subdirectory(StateReplicator)
diff --git a/ProxyWrapper/src/CMakeLists.txt b/ProxyWrapper/src/CMakeLists.txt
deleted file mode 100644
index da2461d..0000000
--- a/ProxyWrapper/src/CMakeLists.txt
+++ /dev/null
@@ -1,19 +0,0 @@
-# Define the SIP Channel Service component
-
-asterisk_scf_component_init(ProxyWrapper CXX)
-
-asterisk_scf_component_add_slice(ProxyWrapper ServiceLocatorIf)
-asterisk_scf_component_add_file(ProxyWrapper ProxyWrapper.h)
-asterisk_scf_component_add_file(ProxyWrapper ProxyWrapper.cpp)
-asterisk_scf_component_add_boost_libraries(ProxyWrapper core)
-
-asterisk_scf_component_build_library(ProxyWrapper)
-
-# MACH-O requires libraries for linking libraries
-if(APPLE)
- target_link_libraries(ProxyWrapper ${ICE_CXX_LIB_IceUtil})
- target_link_libraries(ProxyWrapper ${ICE_CXX_LIB_ZeroCIce})
-endif()
-
-asterisk_scf_component_install(ProxyWrapper LIBRARY lib "Proxy Wrapper" ProxyWrapper ARCHIVE DESTINATION lib)
-
diff --git a/ProxyWrapper/CMakeLists.txt b/SmartProxy/CMakeLists.txt
similarity index 100%
rename from ProxyWrapper/CMakeLists.txt
rename to SmartProxy/CMakeLists.txt
diff --git a/SmartProxy/src/CMakeLists.txt b/SmartProxy/src/CMakeLists.txt
new file mode 100644
index 0000000..cb7ea20
--- /dev/null
+++ b/SmartProxy/src/CMakeLists.txt
@@ -0,0 +1,25 @@
+# Define the SIP Channel Service component
+
+asterisk_scf_component_init(SmartProxy CXX)
+
+asterisk_scf_component_add_slice(SmartProxy ServiceLocatorIf)
+asterisk_scf_component_add_file(SmartProxy SmartProxy.h)
+asterisk_scf_component_add_file(SmartProxy SmartProxy.cpp)
+asterisk_scf_component_add_boost_libraries(SmartProxy core)
+
+if(NOT logger_dir)
+ message(FATAL_ERROR "The logger directory could not be found ${logger_dir}")
+endif()
+include_directories(${logger_dir}/common)
+include_directories(${logger_dir}/client/src)
+
+asterisk_scf_component_build_library(SmartProxy)
+
+# MACH-O requires libraries for linking libraries
+if(APPLE)
+ target_link_libraries(SmartProxy ${ICE_CXX_LIB_IceUtil})
+ target_link_libraries(SmartProxy ${ICE_CXX_LIB_ZeroCIce})
+endif()
+
+asterisk_scf_component_install(SmartProxy LIBRARY lib "Smart Proxy" SmartProxy ARCHIVE DESTINATION lib)
+
diff --git a/ProxyWrapper/src/ProxyWrapper.cpp b/SmartProxy/src/SmartProxy.cpp
similarity index 96%
rename from ProxyWrapper/src/ProxyWrapper.cpp
rename to SmartProxy/src/SmartProxy.cpp
index 875d360..d4e7c45 100644
--- a/ProxyWrapper/src/ProxyWrapper.cpp
+++ b/SmartProxy/src/SmartProxy.cpp
@@ -14,7 +14,7 @@
* at the top of the source tree.
*/
-#include "ProxyWrapper.h"
+#include "SmartProxy.h"
namespace AsteriskSCF
{
diff --git a/ProxyWrapper/src/ProxyWrapper.h b/SmartProxy/src/SmartProxy.h
similarity index 58%
rename from ProxyWrapper/src/ProxyWrapper.h
rename to SmartProxy/src/SmartProxy.h
index 3439f3f..8e5da1f 100644
--- a/ProxyWrapper/src/ProxyWrapper.h
+++ b/SmartProxy/src/SmartProxy.h
@@ -15,21 +15,23 @@
*/
#pragma once
+#include <iostream>
+
#include <Ice/Ice.h>
-#include <boost/shared_ptr.hpp>
#include "Core/Discovery/ServiceLocatorIf.h"
+#include "logger.h"
namespace AsteriskSCF
{
-namespace ProxyWrapper
+namespace SmartProxy
{
/**
* A wrapper for an Ice Proxy.
* The Template parameter P is the proxy we're wrapping
*
- * The main feature of using a proxy wrapper at this stage is that
+ * The main feature of using a smart proxy at this stage is that
* it provides the ability to detect if we could find a given proxy
* at initialization. If we did not, then the first time we try to
* invoke a proxy operation, then we will attempt to acquire a proxy
@@ -39,43 +41,44 @@ namespace ProxyWrapper
* more general purpose.
*/
template <class P>
-class ProxyWrapper
+class SmartProxy
{
public:
- ProxyWrapper() : mServiceLocator(0), mLocatorParams(0), mInitialized(false) {}
+ SmartProxy() : mServiceLocator(0), mLocatorParams(0), mInitialized(false), mLg(0) {}
- ProxyWrapper(const ProxyWrapper &pw)
+ SmartProxy(const SmartProxy &rhs)
{
- copy(pw);
+ copy(rhs);
}
- ProxyWrapper(const AsteriskSCF::Core::Discovery::V1::ServiceLocatorPrx& locator,
- AsteriskSCF::Core::Discovery::V1::ServiceLocatorParamsPtr params)
- : mServiceLocator(locator), mLocatorParams(params), mInitialized(false)
+ SmartProxy(const AsteriskSCF::Core::Discovery::V1::ServiceLocatorPrx& locator,
+ AsteriskSCF::Core::Discovery::V1::ServiceLocatorParamsPtr params,
+ AsteriskSCF::System::Logging::Logger const &lg)
+ : mServiceLocator(locator), mLocatorParams(params), mInitialized(false), mLg(&lg)
{
initialize();
}
- P& operator->()
+ P& operator->() throw (AsteriskSCF::Core::Discovery::V1::ServiceNotFound)
{
assert(mServiceLocator && mLocatorParams);
if (!verifyInitialized())
{
- throw "No access to Proxy";
+ throw AsteriskSCF::Core::Discovery::V1::ServiceNotFound();
}
return mProxy;
}
- ProxyWrapper operator=(const ProxyWrapper &pw)
+ SmartProxy &operator=(const SmartProxy &rhs)
{
// Boo to self-assignment
- if (this == &pw)
+ if (this == &rhs)
{
return *this;
}
- copy(pw);
+ copy(rhs);
return *this;
}
@@ -95,24 +98,38 @@ private:
*/
void initialize()
{
+ using namespace AsteriskSCF::System::Logging;
+ if (!mServiceLocator)
+ {
+ // uninitialized; probably no logger setup yet, either
+ std::clog << "Missing ServiceLocator proxy. Cannot initialize.\n";
+ return;
+ }
+
try
{
// Use the locator to find the Proxy
- Ice::ObjectPrx bridgeManagerObject = mServiceLocator->locate(mLocatorParams);
- mProxy = P::checkedCast(bridgeManagerObject);
+ Ice::ObjectPrx obj = mServiceLocator->locate(mLocatorParams);
+ mProxy = P::checkedCast(obj);
+ if (obj && !mProxy)
+ {
+ (*mLg)(Error) << "Object (" << obj->ice_toString() << ") isn't of expected type";
+ }
}
catch (const Ice::Exception &e)
{
... 4750 lines suppressed ...
--
asterisk-scf/integration/ice-util-cpp.git
More information about the asterisk-scf-commits
mailing list