[asterisk-scf-commits] asterisk-scf/integration/ice-util-cpp.git branch "retry_deux" updated.

Commits to the Asterisk SCF project code repositories asterisk-scf-commits at lists.digium.com
Wed Apr 4 14:35:49 CDT 2012


branch "retry_deux" has been updated
       via  31ebb4a34f9f0a4f3e1e6a0c18d655f38ebe4bed (commit)
       via  a2b337efe361062b487eb5172fd7e03e861e207f (commit)
       via  5738e5a108f13ac7e547690b9c27f50bbaa6467e (commit)
      from  c1aee7ef1cdb3dbab3d4aacf89a5fbd11a89972e (commit)

Summary of changes:
 include/AsteriskSCF/Operations/ExceptionWrapper.h  |   16 +-
 .../AsteriskSCF/Operations/OperationContextCache.h |  236 +++-----------------
 include/AsteriskSCF/Operations/OperationMonitor.h  |   65 +++++-
 .../OperationContextCacheTest.cpp                  |   79 -------
 4 files changed, 97 insertions(+), 299 deletions(-)


- Log -----------------------------------------------------------------
commit 31ebb4a34f9f0a4f3e1e6a0c18d655f38ebe4bed
Author: David M. Lee <dlee at digium.com>
Date:   Wed Apr 4 13:42:04 2012 -0500

    Removed ValueOperationContextCookie, and associated helpers

diff --git a/include/AsteriskSCF/Operations/OperationContextCache.h b/include/AsteriskSCF/Operations/OperationContextCache.h
index 75c7314..071bf2f 100644
--- a/include/AsteriskSCF/Operations/OperationContextCache.h
+++ b/include/AsteriskSCF/Operations/OperationContextCache.h
@@ -41,126 +41,6 @@ public:
 };
 typedef ASTSCF_DLL_EXPORT boost::shared_ptr<OperationContextCookie> OperationContextCookiePtr;
 
-/**
- * An OperationContextCookie which can hold a single, copyable value.
- * Ice proxies are very typical, as are literal values. Be careful when using
- * smart pointers, so that you don't change the contents of the stored value
- * behind the scenes.
- *
- * The value may also be set to an Ice exception, which will be thrown on the
- * call to get().
- *
- * The only constraints on T are 1) it must have a default constructor and 2)
- * must the assignment operator defined.
- */
-template<typename T>
-class ValueOperationContextCookie : public OperationContextCookie
-{
-public:
-    ValueOperationContextCookie() : mPoorlyTypedException(false) {}
-
-    /** Set the value of this cookie. */
-    void set(const T& v)
-    {
-        boost::mutex::scoped_lock lock(mMutex);
-        mVal = v;
-    }
-
-    /** Set the exception value of this cookie. */
-    void setException(const std::exception& e)
-    {
-        boost::mutex::scoped_lock lock(mMutex);
-        const IceUtil::Exception *iceEx = dynamic_cast<const IceUtil::Exception *>(&e);
-        if (iceEx)
-        {
-            // Ice exceptions are clonable; copy it so we can rethrow the original
-            // exception
-            mEx.reset(iceEx->ice_clone());
-        }
-        else
-        {
-            // std::exception can't be copied. Fortunately, Ice doesn't really
-            // care what it is if it's not an Ice exception. Just keep the
-            // what() message for later.
-            mStdExceptionWhat = e.what();
-        }
-    }
-
-    /**
-     * Set the cookie to throw an exception, but we don't know what that
-     * exception is. Ideally, this code is never called at runtime, because
-     * we never throw any type that's not derived from std::exception. But
-     * we have to cover our bases.
-     */
-    void setException()
-    {
-        boost::mutex::scoped_lock lock(mMutex);
-        mPoorlyTypedException = true;
-    }
-
-    /**
-     * If setException has been called, throw that exception. Otherwise,
-     * return the value of this cookie.
-     */
-    T get() const
-    {
-        boost::mutex::scoped_lock lock(mMutex);
-        if (mEx)
-        {
-            mEx->ice_throw();
-        }
-        else if (!mStdExceptionWhat.empty())
-        {
-            // throw an exception with the same what() message as the original
-            // exception
-            throw StdException(mStdExceptionWhat);
-        }
-        else if (mPoorlyTypedException)
-        {
-            // someone throw a non-standard exception; we should, too.
-            throw "Okay; who's throwing non-exception types?";
-        }
-        return mVal;
-    }
-
-private:
-    // This class has a very high write-to-read ratio, and the chance of two
-    // reads happening concurrently are small. There would be no benefit from
-    // a shared_mutex, so just using a plain mutex instead.
-    mutable boost::mutex mMutex;
-    T mVal;
-
-    boost::shared_ptr<IceUtil::Exception> mEx;
-    std::string mStdExceptionWhat;
-    bool mPoorlyTypedException;
-
-    class StdException : public std::exception
-    {
-    public:
-        StdException(const std::string& wat): mWhat(wat) {}
-        ~StdException() throw() {}
-
-        const char* what() throw() { return mWhat.c_str(); }
-    private:
-        std::string mWhat;
-    };
-};
-
-/**
- * A variation of ValueOperationContextCookie which has a mutex in addition to the
- * the return value/exception. This is useful for services that otherwise do not
- * require locking, but need synchronization on getting/setting the cookie's value.
- */
-template<typename T, typename M = boost::mutex>
-class ValueOperationContextCookieWithLock : public ValueOperationContextCookie<T>
-{
-public:
-    M& getMutex() { return mMutex; }
-private:
-    M mMutex;
-};
-
-
 class OperationContextCache;
 typedef boost::shared_ptr<OperationContextCache> OperationContextCachePtr;
 
@@ -173,75 +53,75 @@ public:
     /**
      * Factory method for non-logging cache.
      * @param ttlSeconds  The time-to-live for the OperationContexts being cached.
-     * Entries will remain in the cache for at least the provided value, but can 
-     * remain in cache longer. 
+     * Entries will remain in the cache for at least the provided value, but can
+     * remain in cache longer.
      */
     static OperationContextCachePtr create(int ttlSeconds);
 
     /**
      * Factory method for logging cache.
      * @param ttlSeconds  The time-to-live for the OperationContexts being cached.
-     * Entries will remain in the cache for at least the provided value, but can 
-     * remain in cache longer. 
-     * @param logger The logger to log to. 
+     * Entries will remain in the cache for at least the provided value, but can
+     * remain in cache longer.
+     * @param logger The logger to log to.
      * @param label Label to apply when logging to identify this cache.
      */
-    static OperationContextCachePtr create(int ttlSeconds, 
+    static OperationContextCachePtr create(int ttlSeconds,
                               const AsteriskSCF::System::Logging::Logger& logger,
                               const std::string& label);
 
     ~OperationContextCache();
 
     /**
-     * Caches the specified context if it isn't already in the cache. 
+     * Caches the specified context if it isn't already in the cache.
      *
-     * @param operationContext The context to add to the cache. 
+     * @param operationContext The context to add to the cache.
      * @return true The context was added, which means it wasn't already in the cache.
      *
      * @note Make sure you don't confuse the return value of this operation with the return
-     * value of the 'contains' operation. 
+     * value of the 'contains' operation.
      */
     bool addOperationContext(const AsteriskSCF::System::V1::OperationContextPtr& operationContext);
 
     /**
-     * Caches the specified context if it isn't already in the cache, and associate a cookie with it. 
+     * Caches the specified context if it isn't already in the cache, and associate a cookie with it.
      *
-     * @param operationContext The context to add to the cache. 
-     * @param inCookie A cookie object to associate with this entry in the cache. 
+     * @param operationContext The context to add to the cache.
+     * @param inCookie A cookie object to associate with this entry in the cache.
      * @param existingCookie This value will be set by this method to the cookie of an existing
-     * operationContext if there was already an entry in the cache with the same identity. 
+     * operationContext if there was already an entry in the cache with the same identity.
      * @return true The context was added, which means it wasn't already in the cache.
      *
      * @note Make sure you don't confuse the return value of this operation with the return
-     * value of the 'contains' operation. 
+     * value of the 'contains' operation.
      */
     bool addOperationContext(
         const AsteriskSCF::System::V1::OperationContextPtr& operationContext,
-        const OperationContextCookiePtr& inCookie, 
+        const OperationContextCookiePtr& inCookie,
         OperationContextCookiePtr& existingCookie);
 
     /**
-     * Tests if the specified context is in the cache. 
+     * Tests if the specified context is in the cache.
      */
     bool contains(const AsteriskSCF::System::V1::OperationContextPtr& operationContext);
 
     /**
-     * This will remove an OperationContext from the cache if one exists with the given id. 
-     * Removal is typically done automatically within the cache based on an internal timer. 
-     * This operation exists to support clients that wish to force an immediate removal of a 
-     * context themselves. 
+     * This will remove an OperationContext from the cache if one exists with the given id.
+     * Removal is typically done automatically within the cache based on an internal timer.
+     * This operation exists to support clients that wish to force an immediate removal of a
+     * context themselves.
      */
     void removeOperationContext(const AsteriskSCF::System::V1::OperationContextPtr& operationContext);
 
     /**
-     * Drop entries that are older than the TTL. 
+     * Drop entries that are older than the TTL.
      * @note This method is called by an internal timer task, so clients
-     * of this class don't need to call it. (There's no harm if a client does call it.)  
+     * of this class don't need to call it. (There's no harm if a client does call it.)
      */
-    void prune(); 
+    void prune();
 
     /**
-     * Retrieve the number of entries currently in the cache. 
+     * Retrieve the number of entries currently in the cache.
      */
     std::size_t size();
 
@@ -252,7 +132,7 @@ private:
     //
     OperationContextCache(int ttlSeconds);
 
-    OperationContextCache(int ttlSeconds, 
+    OperationContextCache(int ttlSeconds,
                           const AsteriskSCF::System::Logging::Logger& logger,
                           const std::string& label);
 
@@ -269,67 +149,5 @@ private:
     std::map<std::string, OperationContextCacheEntryPtr> mCache;
 };
 
-/**
- * Common access pattern for testing the cache for an entry. If the cache contains an entry for the
- * given context, this returns true and that entry. Otherwise, a new cookie of type T is built, put
- * into the cache, and false is returned with the new cookie.
- */
-template<typename T>
-std::pair<bool, boost::shared_ptr<T> > testOrSet(
-    OperationContextCachePtr cache, const AsteriskSCF::System::V1::OperationContextPtr& context)
-{
-    typedef boost::shared_ptr<T> TPtr;
-    const TPtr cookie(new T);
-    OperationContextCookiePtr existingCookie;
-    cache->addOperationContext(cache, cookie, existingCookie);
-
-    if (existingCookie)
-    {
-        TPtr c = boost::dynamic_pointer_cast<T>(existingCookie);
-        assert(c);
-        return std::make_pair(true, c);
-    }
-    return std::make_pair(false, cookie);
-}
-
-/**
- * Just like testOrSet above, but thread safe w.r.t. the cookie's mutex (available via the getMutex() member
- * function). Unfortunately, this function must lock the mutex, and the caller must release it. The recommended
- * pattern is:
- *
- *   std::pair<bool, MyCookiePtr> cacheHit = testOrSetAndLock<MyCookie>(cache, context);
- *   boost::mutex::scoped_lock lock(cacheHit.second->getMutex(), boost::adopt_lock);
- */
-template<typename T>
-std::pair<bool, boost::shared_ptr<T> > testOrSetAndLock(
-    OperationContextCachePtr cache, const AsteriskSCF::System::V1::OperationContextPtr& context)
-{
-    typedef boost::shared_ptr<T> TPtr;
-    const TPtr cookie(new T);
-    OperationContextCookiePtr existingCookie;
-    // lock this cookie so that no one will get our results prematurely
-    boost::mutex::scoped_lock lock(cookie->getMutex());
-    cache->addOperationContext(context, cookie, existingCookie);
-
-    if (existingCookie)
-    {
-        TPtr c = boost::dynamic_pointer_cast<T>(existingCookie);
-        assert(c);
-        // Even though we're holding a lock on cookie, it's never left this function; no one can be waiting on it.
-        // There's no danger of deadlocking while waiting on the lock for existingCookie.
-
-        // The caller needs to unlock this mutex when it's ready to return. boost's RAII lock guards
-        // aren't the best fit; lock manually. However the lock guard on cookie's mutex will do the
-        // right thing and unlock that mutex.
-        c->getMutex().lock();
-        return std::make_pair(true, c);
-    }
-
-    // The caller needs to unlock this mutex when it's ready to return state. Release the lock so the caller
-    // can unlock when it's donw.
-    lock.release();
-    return std::make_pair(false, cookie);
-}
-
-} // Operations 
-} // AsteriskSCF 
+} // Operations
+} // AsteriskSCF
diff --git a/test/OperationContextCache/OperationContextCacheTest.cpp b/test/OperationContextCache/OperationContextCacheTest.cpp
index e3eaf0c..ad8a5c0 100644
--- a/test/OperationContextCache/OperationContextCacheTest.cpp
+++ b/test/OperationContextCache/OperationContextCacheTest.cpp
@@ -91,77 +91,6 @@ void runOperationContextCacheTest()
     testOperations.clear();
 }
 
-void ValueOperationContextCookie_valueTest()
-{
-    ValueOperationContextCookie<int> uut;
-
-    uut.set(5);
-
-    BOOST_REQUIRE_EQUAL(5, uut.get());
-}
-
-void ValueOperationContextCookie_iceExceptionTest()
-{
-    ValueOperationContextCookie<int> uut;
-    IceUtil::NullHandleException e("not-a-file.cpp", 314159);
-
-    uut.setException(e);
-
-    try
-    {
-        uut.get();
-    }
-    catch (const IceUtil::NullHandleException&)
-    {
-        // expected
-    }
-}
-
-void ValueOperationContextCookie_stdExceptionTest()
-{
-    ValueOperationContextCookie<int> uut;
-    PhonyException e;
-
-    uut.setException(e);
-
-    try
-    {
-        uut.get();
-    }
-    catch (const Ice::Exception&)
-    {
-        BOOST_FAIL("Unexpected Ice exception");
-    }
-    catch (const std::exception&)
-    {
-        // expected
-    }
-}
-
-void ValueOperationContextCookie_untypedExceptionTest()
-{
-    ValueOperationContextCookie<int> uut;
-
-    uut.setException();
-
-    try
-    {
-        uut.get();
-    }
-    catch (const Ice::Exception&)
-    {
-        BOOST_FAIL("Unexpected Ice exception");
-    }
-    catch (const std::exception&)
-    {
-        BOOST_FAIL("Unexpected std::exception");
-    }
-    catch (...)
-    {
-        // expected
-    }
-}
-
 } // anonymous namespace
 
 using namespace boost::unit_test;
@@ -170,12 +99,4 @@ AsteriskSCF::OperationContextCacheTests::OperationContextCacheTestSuite::Operati
 {
     framework::master_test_suite().
         add(BOOST_TEST_CASE(runOperationContextCacheTest));
-    framework::master_test_suite().
-        add(BOOST_TEST_CASE(ValueOperationContextCookie_valueTest));
-    framework::master_test_suite().
-        add(BOOST_TEST_CASE(ValueOperationContextCookie_iceExceptionTest));
-    framework::master_test_suite().
-        add(BOOST_TEST_CASE(ValueOperationContextCookie_stdExceptionTest));
-    framework::master_test_suite().
-        add(BOOST_TEST_CASE(ValueOperationContextCookie_untypedExceptionTest));
 }

commit a2b337efe361062b487eb5172fd7e03e861e207f
Author: David M. Lee <dlee at digium.com>
Date:   Wed Apr 4 13:41:19 2012 -0500

    OperationMonitor additions to make non-AMD usage easier.

diff --git a/include/AsteriskSCF/Operations/ExceptionWrapper.h b/include/AsteriskSCF/Operations/ExceptionWrapper.h
index c4d5659..76a3a10 100755
--- a/include/AsteriskSCF/Operations/ExceptionWrapper.h
+++ b/include/AsteriskSCF/Operations/ExceptionWrapper.h
@@ -63,9 +63,19 @@ public:
      * occurs.
      */
     explicit
-    ExceptionWrapper(const std::exception& ex) :
-        mException(new Ice::UnknownException(__FILE__, __LINE__, ex.what()))
+    ExceptionWrapper(const std::exception& ex)
     {
+        // properly handle the case where ex is actually an IceUtil::Exception
+        const IceUtil::Exception* iceEx = dynamic_cast<const IceUtil::Exception*>(&ex);
+
+        if (iceEx)
+        {
+            mException.reset(iceEx->ice_clone());
+        }
+        else
+        {
+            mException.reset(new Ice::UnknownException(__FILE__, __LINE__, ex.what()));
+        }
     }
 
     /**
diff --git a/include/AsteriskSCF/Operations/OperationMonitor.h b/include/AsteriskSCF/Operations/OperationMonitor.h
index c53c7f9..8e3cda0 100755
--- a/include/AsteriskSCF/Operations/OperationMonitor.h
+++ b/include/AsteriskSCF/Operations/OperationMonitor.h
@@ -109,6 +109,19 @@ public:
 
     void setException(const ExceptionWrapperPtr& exception);
 
+    void setException(const std::exception& exception)
+    {
+        setException(ExceptionWrapper::create(exception));
+    }
+
+    void setException()
+    {
+        // All exceptions _should_ derive from std::exception, so we really
+        // should never get here. but not everyone does what they should,
+        // do they.
+        setException(ExceptionWrapper::create("Unknown unexpected exception"));
+    }
+
     /**
      * A quick, single point accessor to determine the completion
      * statius of the related operation. The alternative would be to
@@ -502,12 +515,21 @@ private:
 ASTSCF_DLL_EXPORT ContextDataPtr checkAndThrow(const AsteriskSCF::Operations::OperationContextCachePtr& cache,
     const AsteriskSCF::System::V1::OperationContextPtr& context);
 
-
-template <class DT, class AT>
-ASTSCF_DLL_EXPORT DT getContext(const AsteriskSCF::Operations::OperationContextCachePtr& cache,
-    const AsteriskSCF::System::V1::OperationContextPtr& context,
-    const AT& amdCallback)
+/**
+ * Gets a OperationContextCookie subclass for a given context, creating it if necessary. This is useful for
+ * non-AMD invocations that return a value.
+ *
+ * @param  DT      a boost::shared_ptr to the OperationContextCookie subclass
+ * @param  cache   Cache to get cookie from
+ * @param  context Context to look up in cache
+ * @return A pair indicating true if it was a cache hit, and the cookie that's now in the cache for the given
+ *         context
+ */
+template <class DT>
+ASTSCF_DLL_EXPORT std::pair<bool, DT> getContextSync(const AsteriskSCF::Operations::OperationContextCachePtr& cache,
+    const AsteriskSCF::System::V1::OperationContextPtr& context)
 {
+    bool cacheHit = false;
     DT c(new typename DT::element_type);
     AsteriskSCF::Operations::OperationContextCookiePtr o;
 
@@ -515,11 +537,38 @@ ASTSCF_DLL_EXPORT DT getContext(const AsteriskSCF::Operations::OperationContextC
     {
         c = boost::dynamic_pointer_cast<typename DT::element_type>(o);
         assert(c);
-        c->addCB(amdCallback);
+        cacheHit = true;
+    }
+    return std::make_pair(cacheHit, c);
+}
+
+/**
+ * Gets a OperationContextCookie subclass for a given context, creating it if necessary.
+ *
+ * If the context is already in the cache, the amdCallback is added to the existing cookie and null is
+ * returned; nothing else need be done.
+ *
+ * If the context is not in the cache, a new cookie is created, the amdCallback is added to it, and the
+ * new cookie is returned. The caller then needs to complete normal execution, and either setException() or
+ * setResult() on the cookie when finished.
+ */
+template <class DT, class AT>
+ASTSCF_DLL_EXPORT DT getContext(const AsteriskSCF::Operations::OperationContextCachePtr& cache,
+    const AsteriskSCF::System::V1::OperationContextPtr& context,
+    const AT& amdCallback)
+{
+    std::pair<bool, DT> cacheHit = getContextSync<DT>(cache, context);
+
+    cacheHit.second->addCB(amdCallback);
+
+    if (cacheHit.first)
+    {
         return DT();
     }
-    c->addCB(amdCallback);
-    return c;
+    else
+    {
+        return cacheHit.second;
+    }
 }
 
 } /* End of namespace Operations */

commit 5738e5a108f13ac7e547690b9c27f50bbaa6467e
Author: David M. Lee <dlee at digium.com>
Date:   Wed Apr 4 09:50:05 2012 -0500

    Fixed a copyright statement

diff --git a/include/AsteriskSCF/Operations/ExceptionWrapper.h b/include/AsteriskSCF/Operations/ExceptionWrapper.h
index 52d4a43..c4d5659 100755
--- a/include/AsteriskSCF/Operations/ExceptionWrapper.h
+++ b/include/AsteriskSCF/Operations/ExceptionWrapper.h
@@ -1,7 +1,7 @@
 /*
  * Asterisk SCF -- An open-source communications framework.
  *
- * Copyright (C) 2010-2011, Digium, Inc.
+ * Copyright (C) 2012, Digium, Inc.
  *
  * See http://www.asterisk.org for more information about
  * the Asterisk SCF project. Please do not directly contact

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


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



More information about the asterisk-scf-commits mailing list