[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