[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
Fri Mar 30 16:11:21 CDT 2012


branch "retry_deux" has been updated
       via  1c2633ef7cfdb6fc38e987ca6672615f1a88cb58 (commit)
       via  512bdacb53786a6815ff93256c456eb8f1cdf414 (commit)
      from  495d0049efbbfd4ae25dcc87c385d569a8b83c05 (commit)

Summary of changes:
 .../AsteriskSCF/Operations/OperationContextCache.h |   87 +++++++++++++++++++-
 1 files changed, 83 insertions(+), 4 deletions(-)


- Log -----------------------------------------------------------------
commit 1c2633ef7cfdb6fc38e987ca6672615f1a88cb58
Author: David M. Lee <dlee at digium.com>
Date:   Thu Mar 29 18:01:49 2012 -0500

    Added testOrSet and testOrSetAndLock helpers

diff --git a/include/AsteriskSCF/Operations/OperationContextCache.h b/include/AsteriskSCF/Operations/OperationContextCache.h
index 160870c..75c7314 100644
--- a/include/AsteriskSCF/Operations/OperationContextCache.h
+++ b/include/AsteriskSCF/Operations/OperationContextCache.h
@@ -62,14 +62,14 @@ public:
     /** Set the value of this cookie. */
     void set(const T& v)
     {
-        boost::lock_guard<boost::mutex> lock(mMutex);
+        boost::mutex::scoped_lock lock(mMutex);
         mVal = v;
     }
 
     /** Set the exception value of this cookie. */
     void setException(const std::exception& e)
     {
-        boost::lock_guard<boost::mutex> lock(mMutex);
+        boost::mutex::scoped_lock lock(mMutex);
         const IceUtil::Exception *iceEx = dynamic_cast<const IceUtil::Exception *>(&e);
         if (iceEx)
         {
@@ -94,7 +94,7 @@ public:
      */
     void setException()
     {
-        boost::lock_guard<boost::mutex> lock(mMutex);
+        boost::mutex::scoped_lock lock(mMutex);
         mPoorlyTypedException = true;
     }
 
@@ -104,7 +104,7 @@ public:
      */
     T get() const
     {
-        boost::lock_guard<boost::mutex> lock(mMutex);
+        boost::mutex::scoped_lock lock(mMutex);
         if (mEx)
         {
             mEx->ice_throw();
@@ -146,6 +146,21 @@ private:
     };
 };
 
+/**
+ * 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;
 
@@ -254,5 +269,67 @@ 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 

commit 512bdacb53786a6815ff93256c456eb8f1cdf414
Author: David M. Lee <dlee at digium.com>
Date:   Fri Mar 30 09:47:37 2012 -0500

    Stupid uninitialized variable

diff --git a/include/AsteriskSCF/Operations/OperationContextCache.h b/include/AsteriskSCF/Operations/OperationContextCache.h
index d4678a3..160870c 100644
--- a/include/AsteriskSCF/Operations/OperationContextCache.h
+++ b/include/AsteriskSCF/Operations/OperationContextCache.h
@@ -57,6 +57,8 @@ template<typename T>
 class ValueOperationContextCookie : public OperationContextCookie
 {
 public:
+    ValueOperationContextCookie() : mPoorlyTypedException(false) {}
+
     /** Set the value of this cookie. */
     void set(const T& v)
     {

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


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



More information about the asterisk-scf-commits mailing list