From fb56ee788784bb285de4b56e981580756c61e477 Mon Sep 17 00:00:00 2001 From: Dan Goodliffe Date: Tue, 17 Nov 2015 22:05:16 +0000 Subject: Improve core with traits and decltype for working with functions that return references to mutexes. Add support for upgradable locks --- libadhocutil/lockHelpers.h | 29 ++++++++++++++++++----------- libadhocutil/unittests/testLocks.cpp | 17 +++++++++++++++++ 2 files changed, 35 insertions(+), 11 deletions(-) diff --git a/libadhocutil/lockHelpers.h b/libadhocutil/lockHelpers.h index 5ac4bf7..1482644 100644 --- a/libadhocutil/lockHelpers.h +++ b/libadhocutil/lockHelpers.h @@ -1,13 +1,15 @@ #ifndef ADHOCUTIL_LOCKHELPERS_H #define ADHOCUTIL_LOCKHELPERS_H +#include + /// @cond template -class _LockLoop { +class _LockLoop : public locktype { public: - template - _LockLoop(l & _l) : - lock(_l), + template + _LockLoop(MutexType & m) : + locktype(m), flag(true) { } @@ -16,7 +18,6 @@ class _LockLoop { void operator!() { flag = false; } private: - locktype lock; bool flag; }; /// @endcond @@ -24,15 +25,21 @@ class _LockLoop { #define LIBADHOC_LOCK_CONCAT2(a, b) a ## b #define LIBADHOC_LOCK_CONCAT(a, b) LIBADHOC_LOCK_CONCAT2(a, b) #define LIBADHOC_LOCK_WITHLINE(a) LIBADHOC_LOCK_CONCAT(a, __LINE__) +#define LIBADHOC_RRT(l) typename std::remove_reference::type -#define BaseScopeLock(l,lt,mt) for (_LockLoop> LIBADHOC_LOCK_WITHLINE(_lck)(l); LIBADHOC_LOCK_WITHLINE(_lck); !LIBADHOC_LOCK_WITHLINE(_lck)) -#define BaseLock(l,lt,mt) lt LIBADHOC_LOCK_WITHLINE(_lck)(l) +#define BaseScopeLock(l,lt) for (_LockLoop> LIBADHOC_LOCK_WITHLINE(_lck)(l); LIBADHOC_LOCK_WITHLINE(_lck); !LIBADHOC_LOCK_WITHLINE(_lck)) +#define TypeBaseLock(l,lt,mt) lt LIBADHOC_LOCK_WITHLINE(_lck)(l) +#define BaseLock(l,lt) TypeBaseLock(l, lt, LIBADHOC_RRT(l)) -#define Lock(l) BaseLock(l, boost::unique_lock, boost::shared_mutex) -#define SharedLock(l) BaseLock(l, boost::shared_lock, boost::shared_mutex) +#define Lock(l) BaseLock(l, boost::unique_lock) +#define SharedLock(l) BaseLock(l, boost::shared_lock) +#define UpgradableLock(l, ln) boost::upgrade_lock ln(l) +#define UpgradeLock(l) TypeBaseLock(l, boost::upgrade_to_unique_lock, LIBADHOC_RRT(l)::mutex_type) -#define ScopeLock(l) BaseScopeLock(l, boost::unique_lock, boost::shared_mutex) -#define SharedScopeLock(l) BaseScopeLock(l, boost::shared_lock, boost::shared_mutex) +#define ScopeLock(l) BaseScopeLock(l, boost::unique_lock) +#define SharedScopeLock(l) BaseScopeLock(l, boost::shared_lock) +#define UpgradableScopeLock(l, ln) for (_LockLoop> ln(l); ln; !ln) +#define UpgradeScopeLock(l) for (_LockLoop> LIBADHOC_LOCK_WITHLINE(_lck)(l); LIBADHOC_LOCK_WITHLINE(_lck); !LIBADHOC_LOCK_WITHLINE(_lck)) #endif diff --git a/libadhocutil/unittests/testLocks.cpp b/libadhocutil/unittests/testLocks.cpp index bdf0d18..4b0bad5 100644 --- a/libadhocutil/unittests/testLocks.cpp +++ b/libadhocutil/unittests/testLocks.cpp @@ -16,6 +16,14 @@ BOOST_AUTO_TEST_CASE ( sharedlock ) SharedLock(_lock); } +BOOST_AUTO_TEST_CASE ( upgradelock ) +{ + boost::upgrade_mutex _lock; + UpgradableLock(_lock, ln); + UpgradeScopeLock(ln) { } + UpgradeLock(ln); +} + BOOST_AUTO_TEST_CASE ( scopelock ) { boost::shared_mutex _lock; @@ -28,3 +36,12 @@ BOOST_AUTO_TEST_CASE ( sharedscopelock ) SharedScopeLock(_lock) { } } +BOOST_AUTO_TEST_CASE ( upgradescopelock ) +{ + boost::upgrade_mutex _lock; + UpgradableScopeLock(_lock, ln) { + UpgradeScopeLock(ln) { } + UpgradeLock(ln); + } +} + -- cgit v1.2.3