[asterisk-scf-commits] asterisk-scf/integration/ice-util-cpp.git branch "interrupt-item" created.

Commits to the Asterisk SCF project code repositories asterisk-scf-commits at lists.digium.com
Mon Nov 21 09:02:57 CST 2011


branch "interrupt-item" has been created
        at  b604f30dd24d6b500b39445220766c7fada40838 (commit)

- Log -----------------------------------------------------------------
commit b604f30dd24d6b500b39445220766c7fada40838
Author: Joshua Colp <jcolp at digium.com>
Date:   Mon Nov 21 11:03:39 2011 -0400

    Add a helper class for classes which use AMD and then queue the operations. The class allows the logical destroyed state of an object to be set and retrieved, thus allowing tasks to send an exception. This also adds tests which confirms the functionality.

diff --git a/include/AsteriskSCF/WorkQueue/Dispatched.h b/include/AsteriskSCF/WorkQueue/Dispatched.h
new file mode 100644
index 0000000..ef1c912
--- /dev/null
+++ b/include/AsteriskSCF/WorkQueue/Dispatched.h
@@ -0,0 +1,49 @@
+/*
+ * Asterisk SCF -- An open-source communications framework.
+ *
+ * Copyright (C) 2011, 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/interprocess/detail/atomic.hpp>
+
+namespace AsteriskSCF
+{
+namespace WorkQueue
+{
+
+class ASTSCF_DLL_EXPORT Dispatched
+{
+public:
+    Dispatched() : mDestroyed(0) { }
+
+    void setDestroyed() { boost::interprocess::detail::atomic_inc32(&mDestroyed); }
+
+    bool isDestroyed()
+    {
+        if (boost::interprocess::detail::atomic_read32(&mDestroyed))
+        {
+            return true;
+        }
+        else
+        {
+            return false;
+        }
+    }
+
+private:
+    unsigned int mDestroyed;
+};
+
+}; //end namespace WorkQueue
+}; //end namespace AsteriskSCF
diff --git a/test/WorkQueue/TestWorkQueue.cpp b/test/WorkQueue/TestWorkQueue.cpp
index 099445f..b7d77ef 100644
--- a/test/WorkQueue/TestWorkQueue.cpp
+++ b/test/WorkQueue/TestWorkQueue.cpp
@@ -19,6 +19,7 @@
 
 #include <AsteriskSCF/WorkQueue/WorkQueue.h>
 #include <AsteriskSCF/WorkQueue/DefaultQueueListener.h>
+#include <AsteriskSCF/WorkQueue/Dispatched.h>
 
 using namespace AsteriskSCF::System::WorkQueue::V1;
 using namespace AsteriskSCF::WorkQueue;
@@ -75,6 +76,34 @@ public:
 
 typedef IceUtil::Handle<Task> TaskPtr;
 
+class RandomObject : public IceUtil::Shared, public Dispatched
+{
+};
+
+typedef IceUtil::Handle<RandomObject> RandomObjectPtr;
+
+class DispatchedTask : public Work
+{
+public:
+    DispatchedTask(const RandomObjectPtr& object) : mObject(object), taskExecuted(false), taskAborted(false) { }
+    void execute()
+    {
+        if (mObject->isDestroyed())
+        {
+            taskAborted = true;
+        }
+        else
+        {
+            taskExecuted = true;
+        }
+    }
+    RandomObjectPtr mObject;
+    bool taskExecuted;
+    bool taskAborted;
+};
+
+typedef IceUtil::Handle<DispatchedTask> DispatchedTaskPtr;
+
 class ThreadHook : public Ice::ThreadNotification
 {
 public:
@@ -353,6 +382,51 @@ BOOST_AUTO_TEST_CASE(executeNonExistent)
     BOOST_CHECK(listener->shutdownNotice == true);
 }
 
+BOOST_AUTO_TEST_CASE(dispatchedWorkExecution)
+{
+    TestListenerPtr listener(new TestListener);
+    QueuePtr queue(new WorkQueue(listener));
+    RandomObjectPtr randomObject(new RandomObject());
+    DispatchedTaskPtr work(new DispatchedTask(randomObject));
+
+    queue->enqueueWork(work);
+    bool moreWork = queue->executeWork();
+
+    BOOST_CHECK(moreWork == false);
+    BOOST_CHECK(work->taskExecuted == true);
+    BOOST_CHECK(work->taskAborted == false);
+    BOOST_CHECK(listener->emptyNotice == true);
+    BOOST_CHECK(queue->getSize() == 0);
+
+    queue->shutdown();
+
+    BOOST_CHECK(listener->shutdownNotice == true);
+}
+
+BOOST_AUTO_TEST_CASE(dispatchedWorkAbortion)
+{
+    TestListenerPtr listener(new TestListener);
+    QueuePtr queue(new WorkQueue(listener));
+    RandomObjectPtr randomObject(new RandomObject());
+    DispatchedTaskPtr work(new DispatchedTask(randomObject));
+
+    queue->enqueueWork(work);
+
+    randomObject->setDestroyed();
+
+    bool moreWork = queue->executeWork();
+
+    BOOST_CHECK(moreWork == false);
+    BOOST_CHECK(work->taskExecuted == false);
+    BOOST_CHECK(work->taskAborted == true);
+    BOOST_CHECK(listener->emptyNotice == true);
+    BOOST_CHECK(queue->getSize() == 0);
+
+    queue->shutdown();
+
+    BOOST_CHECK(listener->shutdownNotice == true);
+}
+
 BOOST_AUTO_TEST_CASE(executionOrder1)
 {
     TestListenerPtr listener(new TestListener);

commit a86f5428fee250c75f4d4da80d26aebb97f659eb
Author: Joshua Colp <jcolp at digium.com>
Date:   Mon Nov 7 11:21:23 2011 -0400

    It is unsafe to hold the workqueue lock when calling into the listener upon shutdown since the listener may join the workqueue thread while the workqueue thread is waiting to get the workqueue lock. (issue ASTSCF-318)

diff --git a/src/WorkQueue/WorkQueue.cpp b/src/WorkQueue/WorkQueue.cpp
index a4a9da0..34a022e 100644
--- a/src/WorkQueue/WorkQueue.cpp
+++ b/src/WorkQueue/WorkQueue.cpp
@@ -187,9 +187,11 @@ void WorkQueue::setListener(const QueueListenerPtr& listener)
 
 void WorkQueue::shutdown()
 {
-    boost::unique_lock<boost::shared_mutex> lock(mPriv->mLock);
-    mPriv->checkForShuttingDown();
-    mPriv->mShuttingDown = true;
+    {
+        boost::unique_lock<boost::shared_mutex> lock(mPriv->mLock);
+        mPriv->checkForShuttingDown();
+        mPriv->mShuttingDown = true;
+    }
     mPriv->mListener->shuttingDown(this);
 }
 

commit a5df24d0de353dd646b0a8a8d3ee9dc16e369f44
Merge: e9f2c0c c94539b
Author: Mark Michelson <mmichelson at digium.com>
Date:   Wed Oct 5 17:05:35 2011 -0500

    Merge branch 'master' of git.asterisk.org:asterisk-scf/release/ice-util-cpp


commit e9f2c0c897b6d12c9f342c4ff226053408cf0361
Author: Mark Michelson <mmichelson at digium.com>
Date:   Wed Oct 5 17:05:19 2011 -0500

    Add a method to get the replica proxy.

diff --git a/include/AsteriskSCF/Component/Component.h b/include/AsteriskSCF/Component/Component.h
index a83b0f5..176c967 100644
--- a/include/AsteriskSCF/Component/Component.h
+++ b/include/AsteriskSCF/Component/Component.h
@@ -262,6 +262,7 @@ protected:
     const AsteriskSCF::Core::Discovery::V1::ServiceLocatorPrx&  getServiceLocator() const {return mServiceLocator;}
     const Ice::ObjectAdapterPtr& getServiceAdapter() const {return mServiceAdapter;}
     const Ice::ObjectAdapterPtr& getBackplaneAdapter() const {return mBackplaneAdapter;}
+    const AsteriskSCF::System::Component::V1::ReplicaPrx getReplicaProxy() const {return mReplicaPrx;}
     std::string getServiceLocatorManagementProperty() const;
 
     // Allow setting an alternative communicator. 

commit c94539bd3bea014b7c2cc470526ed3a6610ee365
Author: Brent Eagles <beagles at digium.com>
Date:   Wed Oct 5 16:59:31 2011 -0230

    Fix verifyProperties() to check for properties relative to the
    backplane and service adapter.

diff --git a/src/Component/Component.cpp b/src/Component/Component.cpp
index c9a0c17..70866e1 100644
--- a/src/Component/Component.cpp
+++ b/src/Component/Component.cpp
@@ -819,21 +819,21 @@ void Component::verifyProperties()
     string strDefaultSize = boost::lexical_cast<std::string>(defaultSize);
 
     Ice::Int defaultPoolSize = mCommunicator->getProperties()->getPropertyAsIntWithDefault("Ice.ThreadPool.Server.Size", 0);
-    if (mCommunicator->getProperties()->getPropertyAsIntWithDefault(mName + ".ThreadPool.Size", 0) < defaultSize)
+    if (mCommunicator->getProperties()->getPropertyAsIntWithDefault(mServiceAdapterName + ".ThreadPool.Size", 0) < defaultSize)
     {
         if (defaultPoolSize < defaultSize)
         {
-            mLogger(Info) << "Configured thread pool size for " << mName + " is too small, defaulting to " << strDefaultSize;
-            mCommunicator->getProperties()->setProperty(mName + ".ThreadPool.Size", strDefaultSize);
+            mLogger(Info) << "Configured thread pool size for " << mServiceAdapterName + " is too small, defaulting to " << strDefaultSize;
+            mCommunicator->getProperties()->setProperty(mServiceAdapterName + ".ThreadPool.Size", strDefaultSize);
         }
     }
 
-    if (mCommunicator->getProperties()->getPropertyAsIntWithDefault(mName + ".ThreadPool.Size", 0) < defaultSize)
+    if (mCommunicator->getProperties()->getPropertyAsIntWithDefault(mBackplaneAdapterName + ".ThreadPool.Size", 0) < defaultSize)
     {
         if (defaultPoolSize < defaultSize)
         {
-            mLogger(Info) << "Configured Internal thread pool size for " << mName + " is too small, defaulting to " << strDefaultSize;
-            mCommunicator->getProperties()->setProperty(mName + ".ThreadPool.Size", strDefaultSize);
+            mLogger(Info) << "Configured Internal thread pool size for " << mBackplaneAdapterName + " is too small, defaulting to " << strDefaultSize;
+            mCommunicator->getProperties()->setProperty(mBackplaneAdapterName + ".ThreadPool.Size", strDefaultSize);
         }
     }
 

commit ed89284be4fdd448088f70299a5b1f518d734c73
Author: Joshua Colp <jcolp at digium.com>
Date:   Wed Oct 5 11:04:56 2011 -0300

    Build astscf-ice-util-cpp-pjlib statically so the thread hook performs on Windows as it does on Linux.

diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index 30d5c21..15ed730 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -18,7 +18,12 @@ astscf_component_install(astscf-ice-util-cpp)
 astscf_component_init(astscf-ice-util-cpp-pjlib)
 add_subdirectory(PJLib)
 astscf_component_add_boost_libraries(astscf-ice-util-cpp core)
-astscf_component_build_library(astscf-ice-util-cpp-pjlib)
+astscf_component_build_library(astscf-ice-util-cpp-pjlib STATIC)
+if(CMAKE_COMPILER_IS_GNUCXX)
+  if(CMAKE_SIZEOF_VOID_P MATCHES 8)
+    set_target_properties(astscf-ice-util-cpp-pjlib PROPERTIES COMPILE_FLAGS -fPIC)
+  endif()
+endif()
 target_link_libraries(astscf-ice-util-cpp logging-client)
 astscf_component_install(astscf-ice-util-cpp-pjlib)
 pjproject_link(astscf-ice-util-cpp-pjlib pjlib)

commit 0eb08367686faa45b4f1d6604dfb589686990c03
Author: Ken Hunt <ken.hunt at digium.com>
Date:   Tue Oct 4 12:03:21 2011 -0500

    Fixed nasty memory bug.

diff --git a/include/AsteriskSCF/PJLib/ThreadHook.h b/include/AsteriskSCF/PJLib/ThreadHook.h
index dbae437..300ab45 100644
--- a/include/AsteriskSCF/PJLib/ThreadHook.h
+++ b/include/AsteriskSCF/PJLib/ThreadHook.h
@@ -142,7 +142,7 @@ private:
     /**
      * A string indicating the group that threads being tracked by this hook belong to.
      */
-    const std::string& mThreadGroup;
+    const std::string mThreadGroup;
 };
 
 } // end namespace PJLib
diff --git a/src/PJLib/ThreadHook.cpp b/src/PJLib/ThreadHook.cpp
index 4467acb..5d3b887 100644
--- a/src/PJLib/ThreadHook.cpp
+++ b/src/PJLib/ThreadHook.cpp
@@ -59,18 +59,26 @@ ThreadHook::ThreadHook(const std::string& threadGroup) : mThreadGroup(threadGrou
  */
 void ThreadHook::start()
 {
-    ThreadDescWrapperPtr wrapper(new ThreadDescWrapper());
-    pj_thread_t *thread;
-    std::string threadDescription = mThreadGroup + " Thread";
-
-    pj_status_t status = pj_thread_register(threadDescription.c_str(), wrapper->mDesc, &thread);
-    if (status != PJ_SUCCESS)
+    try
     {
-        throw ThreadRegistrationFailed(status);
+        ThreadDescWrapperPtr wrapper(new ThreadDescWrapper());
+        pj_thread_t *thread;
+        std::string threadDescription = mThreadGroup + " Thread";
+
+        pj_status_t status = pj_thread_register(threadDescription.c_str(), wrapper->mDesc, &thread);
+        if (status != PJ_SUCCESS)
+        {
+            throw ThreadRegistrationFailed(status);
+        }
+
+        boost::lock_guard<boost::mutex> lock(mMapLock);
+        mpjThreads.insert(std::make_pair(thread, wrapper));
+    }
+    catch(std::exception& ex)
+    {
+        std::cout << "ThreadHook::start() - " << ex.what() << std::endl;
+        throw; // This catch only useful for debugging. Rethrow it, because we can't handle it.
     }
-
-    boost::lock_guard<boost::mutex> lock(mMapLock);
-    mpjThreads.insert(std::make_pair(thread, wrapper));
 }
 
 /**

commit 85f2a4943c854ec6f5f08c7ac8a609c912160fc3
Author: Ken Hunt <ken.hunt at digium.com>
Date:   Sun Oct 2 17:55:07 2011 -0500

    Removed unreferenced exception param.

diff --git a/src/Component/Component.cpp b/src/Component/Component.cpp
index 50b18ee..c9a0c17 100644
--- a/src/Component/Component.cpp
+++ b/src/Component/Component.cpp
@@ -799,7 +799,7 @@ void Component::initServiceLocatorProxies()
             // If we made it to this point, everything's good.
             return;
         }
-        catch(const Ice::Exception& e)
+        catch(const Ice::Exception&)
         {
             mLogger(Notice) << " Unable to obtain proxies to ServiceLocator. Retry in " << retryDelay << " seconds.";
         }

commit 470710268ba226751c6098c3f65a761000f7d44c
Author: Ken Hunt <ken.hunt at digium.com>
Date:   Fri Sep 30 17:40:37 2011 -0500

    Added a clear operation to the LoggedSet collection.

diff --git a/include/AsteriskSCF/Collections/LoggedSet.h b/include/AsteriskSCF/Collections/LoggedSet.h
index c43111d..4edc4ee 100644
--- a/include/AsteriskSCF/Collections/LoggedSet.h
+++ b/include/AsteriskSCF/Collections/LoggedSet.h
@@ -244,6 +244,12 @@ public:
         return mMap.empty();
     }
 
+    void clear()
+    {
+        boost::unique_lock<boost::shared_mutex> lock(mLock);
+        return mMap.clear();
+    }
+
     // A shared pointer to this set type. 
     typedef boost::shared_ptr< LoggedSet<T, K, NullItemException> > SetPtr;
 

commit 80921541054ae118a5d491f310c15599b9fb3d6d
Author: Kevin P. Fleming <kpfleming at digium.com>
Date:   Fri Sep 30 14:03:39 2011 -0500

    Reorganize code in functions to better conform to coding guidelines.
    
    (This was requested in CR-ASTSCF-168, but forgotten during the merge of
    the reviewed branch.)

diff --git a/src/PJLib/ThreadHook.cpp b/src/PJLib/ThreadHook.cpp
index 93a7bab..4467acb 100644
--- a/src/PJLib/ThreadHook.cpp
+++ b/src/PJLib/ThreadHook.cpp
@@ -34,22 +34,24 @@ ThreadHook::ThreadHook(const std::string& threadGroup) : mThreadGroup(threadGrou
 {
     boost::lock_guard<boost::mutex> lock(mInitLock);
 
-    if(!mpjInitialized)
+    if(mpjInitialized)
     {
-	pj_status_t status = pj_init();
-	if(status != PJ_SUCCESS)
-	{
-	    throw PJLibInitializationFailed(status);
-	}
-
-	status = pjlib_util_init();
-	if(status != PJ_SUCCESS)
-	{
-	    throw PJLibUtilInitializationFailed(status);
-	}
-
-	mpjInitialized = true;
+	return;
     }
+
+    pj_status_t status = pj_init();
+    if(status != PJ_SUCCESS)
+    {
+	throw PJLibInitializationFailed(status);
+    }
+
+    status = pjlib_util_init();
+    if(status != PJ_SUCCESS)
+    {
+	throw PJLibUtilInitializationFailed(status);
+    }
+
+    mpjInitialized = true;
 }
 
 /**
@@ -66,11 +68,9 @@ void ThreadHook::start()
     {
         throw ThreadRegistrationFailed(status);
     }
-    else
-    {
-        boost::lock_guard<boost::mutex> lock(mMapLock);
-        mpjThreads.insert(std::make_pair(thread, wrapper));
-    }
+
+    boost::lock_guard<boost::mutex> lock(mMapLock);
+    mpjThreads.insert(std::make_pair(thread, wrapper));
 }
 
 /**
@@ -78,11 +78,13 @@ void ThreadHook::start()
  */
 void ThreadHook::stop()
 {
-    if (pj_thread_is_registered())
+    if (!pj_thread_is_registered())
     {
-        boost::lock_guard<boost::mutex> lock(mMapLock);
-        mpjThreads.erase(pj_thread_this());
+	return;
     }
+
+    boost::lock_guard<boost::mutex> lock(mMapLock);
+    mpjThreads.erase(pj_thread_this());
 }
 
 } // end namespace PJLib

commit a69578535af992b0e3a082832c3f90a934c7bc58
Author: Kevin P. Fleming <kpfleming at digium.com>
Date:   Fri Sep 30 13:24:01 2011 -0500

    Add a common implementation of a thread hook used for tracking threads in a
    component that also uses PJLIB.
    
    * Adds a new library, astscf-ice-util-cpp-pjlib.
    
    Review: https://code.asterisk.org/code/cru/CR-ASTSCF-168

diff --git a/include/AsteriskSCF/PJLib/ThreadHook.h b/include/AsteriskSCF/PJLib/ThreadHook.h
new file mode 100644
index 0000000..dbae437
--- /dev/null
+++ b/include/AsteriskSCF/PJLib/ThreadHook.h
@@ -0,0 +1,150 @@
+/*
+ * Asterisk SCF -- An open-source communications framework.
+ *
+ * Copyright (C) 2011, 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 <exception>
+#include <map>
+#include <string>
+
+#include <Ice/Ice.h>
+
+#include <pjlib.h>
+
+#include <boost/shared_ptr.hpp>
+#include <boost/thread/mutex.hpp>
+#include <boost/thread/locks.hpp>
+
+namespace AsteriskSCF
+{
+
+namespace PJLib
+{
+
+class ASTSCF_DLL_EXPORT PJLibInitializationFailed : public std::exception
+{
+public:
+    PJLibInitializationFailed(pj_status_t res) : result(res)
+    {
+    }
+
+    virtual const char* what() throw()
+    {
+        return "pj_init() returned failure.";
+    }
+
+    const pj_status_t result;
+};
+
+class ASTSCF_DLL_EXPORT PJLibUtilInitializationFailed : public std::exception
+{
+public:
+    PJLibUtilInitializationFailed(pj_status_t res) : result(res)
+    {
+    }
+
+    virtual const char* what() throw()
+    {
+        return "pjlib_util_init() returned failure.";
+    }
+
+    const pj_status_t result;
+};
+
+class ASTSCF_DLL_EXPORT ThreadRegistrationFailed : public std::exception
+{
+public:
+    ThreadRegistrationFailed(pj_status_t res) : result(res)
+    {
+    }
+
+    virtual const char* what() throw()
+    {
+        return "pj_thread_register() returned failure.";
+    }
+
+    const pj_status_t result;
+};
+
+class ASTSCF_DLL_EXPORT ThreadHook : public virtual Ice::ThreadNotification
+{
+public:
+    ThreadHook(const std::string&);
+
+    /**
+     * Implementation of the start function which is called when a thread is being started.
+     */
+    void start();
+
+    /**
+     * Implementation of the stop function which is called when a thread is being stopped.
+     */
+    void stop();
+
+    /**
+     * Wrapper class around pj_thread_desc. This is necessary so that we can ensure that
+     * the pj_thread_desc object is initialized properly, and also so that we can wrap
+     * a boost::shared_ptr<> around it to manage its lifetime.
+     */
+    class ThreadDescWrapper
+    {
+    public:
+        ThreadDescWrapper()
+        {
+            memset(mDesc, 0, sizeof(mDesc));
+        }
+
+	/**
+	 * pjthread thread description information, must persist for the life of the thread
+	 */
+	pj_thread_desc mDesc;
+    };
+
+    /**
+     * Type definition used to create a smart pointer for the above.
+     */
+    typedef boost::shared_ptr<ThreadDescWrapper> ThreadDescWrapperPtr;
+
+private:
+    /**
+     * A map containing thread lifetime persistent data.
+     */
+    std::map<pj_thread_t*, ThreadDescWrapperPtr> mpjThreads;
+
+    /**
+     * Mutex to protect the map
+     */
+    boost::mutex mMapLock;
+
+    /**
+     * A flag to indicate whether the PJ libraries have already been initialized by an instance
+     * of this class.
+     */
+    static bool mpjInitialized;
+
+    /**
+     * Mutex to protect the flag
+     */
+    static boost::mutex mInitLock;
+
+    /**
+     * A string indicating the group that threads being tracked by this hook belong to.
+     */
+    const std::string& mThreadGroup;
+};
+
+} // end namespace PJLib
+} // end namespace AsteriskSCF
+
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index ae964db..30d5c21 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -14,3 +14,12 @@ astscf_component_add_slice_collection_libraries(astscf-ice-util-cpp ASTSCF)
 astscf_component_build_library(astscf-ice-util-cpp)
 target_link_libraries(astscf-ice-util-cpp logging-client)
 astscf_component_install(astscf-ice-util-cpp)
+
+astscf_component_init(astscf-ice-util-cpp-pjlib)
+add_subdirectory(PJLib)
+astscf_component_add_boost_libraries(astscf-ice-util-cpp core)
+astscf_component_build_library(astscf-ice-util-cpp-pjlib)
+target_link_libraries(astscf-ice-util-cpp logging-client)
+astscf_component_install(astscf-ice-util-cpp-pjlib)
+pjproject_link(astscf-ice-util-cpp-pjlib pjlib)
+pjproject_link(astscf-ice-util-cpp-pjlib pjlib-util)
diff --git a/src/PJLib/CMakeLists.txt b/src/PJLib/CMakeLists.txt
new file mode 100644
index 0000000..be5232e
--- /dev/null
+++ b/src/PJLib/CMakeLists.txt
@@ -0,0 +1 @@
+astscf_component_add_files(astscf-ice-util-cpp-pjlib ThreadHook.cpp)
diff --git a/src/PJLib/ThreadHook.cpp b/src/PJLib/ThreadHook.cpp
new file mode 100644
index 0000000..93a7bab
--- /dev/null
+++ b/src/PJLib/ThreadHook.cpp
@@ -0,0 +1,89 @@
+/*
+ * Asterisk SCF -- An open-source communications framework.
+ *
+ * Copyright (C) 2011, 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 <AsteriskSCF/PJLib/ThreadHook.h>
+
+#include <pjlib-util.h>
+
+namespace AsteriskSCF
+{
+
+namespace PJLib
+{
+
+bool ThreadHook::mpjInitialized;
+boost::mutex ThreadHook::mInitLock;
+
+/**
+ * Constructor which initializes the PJSIP libraries.
+ */
+ThreadHook::ThreadHook(const std::string& threadGroup) : mThreadGroup(threadGroup)
+{
+    boost::lock_guard<boost::mutex> lock(mInitLock);
+
+    if(!mpjInitialized)
+    {
+	pj_status_t status = pj_init();
+	if(status != PJ_SUCCESS)
+	{
+	    throw PJLibInitializationFailed(status);
+	}
+
+	status = pjlib_util_init();
+	if(status != PJ_SUCCESS)
+	{
+	    throw PJLibUtilInitializationFailed(status);
+	}
+
+	mpjInitialized = true;
+    }
+}
+
+/**
+ * Implementation of the start function which is called when a thread is started.
+ */
+void ThreadHook::start()
+{
+    ThreadDescWrapperPtr wrapper(new ThreadDescWrapper());
+    pj_thread_t *thread;
+    std::string threadDescription = mThreadGroup + " Thread";
+
+    pj_status_t status = pj_thread_register(threadDescription.c_str(), wrapper->mDesc, &thread);
+    if (status != PJ_SUCCESS)
+    {
+        throw ThreadRegistrationFailed(status);
+    }
+    else
+    {
+        boost::lock_guard<boost::mutex> lock(mMapLock);
+        mpjThreads.insert(std::make_pair(thread, wrapper));
+    }
+}
+
+/**
+ * Implementation of the stop function which is called when a thread is being stopped.
+ */
+void ThreadHook::stop()
+{
+    if (pj_thread_is_registered())
+    {
+        boost::lock_guard<boost::mutex> lock(mMapLock);
+        mpjThreads.erase(pj_thread_this());
+    }
+}
+
+} // end namespace PJLib
+} // end namespace AsteriskSCF

commit a92c362e79a13611485a666b656e8a3ea3b60500
Author: David M. Lee <dlee at digium.com>
Date:   Thu Sep 29 14:44:25 2011 -0500

    Use getBooleanPropertyValueWithDefault for consistency

diff --git a/test/Component/ComponentTest.cpp b/test/Component/ComponentTest.cpp
index 6ecc91f..680143c 100644
--- a/test/Component/ComponentTest.cpp
+++ b/test/Component/ComponentTest.cpp
@@ -25,6 +25,7 @@
 #include <IceBox/IceBox.h>
 #include <IceUtil/UUID.h>
 
+#include <AsteriskSCF/Helpers/PropertyHelper.h>
 #include <AsteriskSCF/Testing/IceBoxBoostTest.h>
 #include <AsteriskSCF/System/Component/ComponentServiceIf.h>
 #include <AsteriskSCF/System/Component/ReplicaIf.h>
@@ -33,6 +34,7 @@
 #include "ComponentTestIf.h"
 
 using namespace std;
+using namespace AsteriskSCF;
 using namespace AsteriskSCF::ComponentTest;
 using namespace AsteriskSCF::System::Component::V1;
 using namespace AsteriskSCF::Core::Discovery::V1;
@@ -236,9 +238,9 @@ BOOST_AUTO_TEST_CASE(AccessTestFacet)
 {
     try
     {
-        string testProp = IceBoxTestEnv.communicator->getProperties()->getPropertyWithDefault(
-                                  "MockComponent.ComponentTest", "no");
-        bool hasTestFacet = boost::iequals(testProp,"yes") || boost::iequals(testProp,"true");
+        bool hasTestFacet = getBooleanPropertyValueWithDefault(
+            IceBoxTestEnv.communicator->getProperties(),
+            "MockComponent.ComponentTest", false);
 
         if (!hasTestFacet)
         {
diff --git a/test/UtilityTests.cpp b/test/UtilityTests.cpp
index b3bf3ec..5243613 100644
--- a/test/UtilityTests.cpp
+++ b/test/UtilityTests.cpp
@@ -81,7 +81,7 @@ public:
             }
         }
 
-        if (mCommunicator->getProperties()->getPropertyWithDefault("AsteriskSCF.Test.Continue", "no") == "no")
+        if (!getBooleanPropertyValueWithDefault(mCommunicator->getProperties(), "AsteriskSCF.Test.Continue", false))
         {
             try
             {

commit efa46708b13689012282a678cb3501c4a7f6037d
Author: Benjamin Oldenburg <benjamin.oldenburg at bericom.eu>
Date:   Mon Sep 26 23:16:29 2011 +0200

    ASTSCF-289: Enhance Component base class to cope with non-available Service Locator

diff --git a/src/Component/Component.cpp b/src/Component/Component.cpp
index f654031..50b18ee 100644
--- a/src/Component/Component.cpp
+++ b/src/Component/Component.cpp
@@ -17,6 +17,7 @@
 #include <boost/lexical_cast.hpp>
 
 #include <Ice/Ice.h>
+#include <IceUtil/Thread.h>
 #include <IceBox/IceBox.h>
 
 #include <AsteriskSCF/Helpers/PropertyHelper.h>
@@ -41,7 +42,7 @@ namespace Component
 {
 static const string ServiceLocatorManagementPropertyName("LocatorServiceManagement.Proxy");
 static const string ServiceLocatorPropertyName("LocatorService.Proxy");
-
+	
 static const string ComponentServiceProxyId("ComponentService");
 static const string ReplicaProxyId("Replica");
 
@@ -748,25 +749,68 @@ void Component::createBackplaneServices()
  */
 void Component::initServiceLocatorProxies()
 {
+    int timeout = 0, retryDelay = 0;
+
     try
     {
-        // Get a proxy to the management interface for the Service Locator manager.
-        mServiceLocatorManagement = 
-            ServiceLocatorManagementPrx::checkedCast(mCommunicator->stringToProxy(
-                 mCommunicator->getProperties()->getPropertyWithDefault(
-                  ServiceLocatorManagementPropertyName, "LocatorServiceManagement:tcp -p 4412")));
-
-        // Get a proxy to the interface for the Service Locator.
-        mServiceLocator = 
-            ServiceLocatorPrx::checkedCast(mCommunicator->stringToProxy(
-                 mCommunicator->getProperties()->getPropertyWithDefault(
-                  ServiceLocatorPropertyName, "LocatorService:default -p 4411")));
+        timeout = mCommunicator->getProperties()->getPropertyAsIntWithDefault(mName + ".InitServiceLocatorTimeout", 30);
+        retryDelay = mCommunicator->getProperties()->getPropertyAsIntWithDefault(mName + ".InitServiceLocatorRetryDelay", 2);
     }
     catch(const Ice::Exception& e)
     {
-        mLogger(Error) << BOOST_CURRENT_FUNCTION << "Unable to obtain proxies to ServiceLocator. Check configuration. " << e.what();
+        mLogger(Error) << BOOST_CURRENT_FUNCTION << "Failure to get property." << e.what();
+        throw;
+    }
+
+    if(timeout < 1)
+    {
+        mLogger(Error) << BOOST_CURRENT_FUNCTION << "The value (=" << timeout << ") of the property '"
+            << mName + ".InitServiceLocatorTimeout"
+            << "' cannot be less than 1.";
         throw;
     }
+
+    if(retryDelay < 1)
+    {
+        mLogger(Error) << BOOST_CURRENT_FUNCTION << "The value (=" << retryDelay << ") of the property '"
+            << mName + ".InitServiceLocatorRetryDelay"
+            << "' cannot be less than 1.";
+        throw;
+    }
+
+    IceUtil::Time tTimeout = IceUtil::Time::now() + IceUtil::Time::seconds(timeout);
+
+    while( IceUtil::Time::now() < tTimeout)
+    {
+        try
+        {
+            // Get a proxy to the management interface for the Service Locator manager.
+            mServiceLocatorManagement = 
+                ServiceLocatorManagementPrx::checkedCast(mCommunicator->stringToProxy(
+                    mCommunicator->getProperties()->getPropertyWithDefault(
+                        ServiceLocatorManagementPropertyName, "LocatorServiceManagement:tcp -p 4412")));
+
+            // Get a proxy to the interface for the Service Locator.
+            mServiceLocator = 
+                ServiceLocatorPrx::checkedCast(mCommunicator->stringToProxy(
+                     mCommunicator->getProperties()->getPropertyWithDefault(
+                      ServiceLocatorPropertyName, "LocatorService:default -p 4411")));
+
+            // If we made it to this point, everything's good.
+            return;
+        }
+        catch(const Ice::Exception& e)
+        {
+            mLogger(Notice) << " Unable to obtain proxies to ServiceLocator. Retry in " << retryDelay << " seconds.";
+        }
+
+        // Wait a little before retrying.
+        IceUtil::ThreadControl::sleep (IceUtil::Time::seconds(retryDelay));
+    }
+
+    // Timeout
+    mLogger(Error) << BOOST_CURRENT_FUNCTION << " Unable to obtain proxies to ServiceLocator for " << timeout << " seconds. Timeout!.";
+    throw; 
 }
 
 void Component::verifyProperties()

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


-- 
asterisk-scf/integration/ice-util-cpp.git



More information about the asterisk-scf-commits mailing list