From db2c0bd9baf2a7e19f977b38fb0c19d9aba75dc1 Mon Sep 17 00:00:00 2001 From: Dan Goodliffe Date: Fri, 6 Apr 2018 11:30:10 +0100 Subject: C++17 Replaces boost locks with std locks. Removes upgradable locks which aren't yet supported in native C++. Bolsters tests around behaviour of lock helpers and simplifies their implementation. --- libadhocutil/cache.impl.h | 1 + libadhocutil/lockHelpers.h | 39 ++++---------------- libadhocutil/semaphore.cpp | 10 +++--- libadhocutil/semaphore.h | 8 ++--- libadhocutil/unittests/Jamfile.jam | 2 +- libadhocutil/unittests/testLocks.cpp | 69 +++++++++++++++++++++++------------- 6 files changed, 61 insertions(+), 68 deletions(-) diff --git a/libadhocutil/cache.impl.h b/libadhocutil/cache.impl.h index 5f51c36..42e4e3a 100644 --- a/libadhocutil/cache.impl.h +++ b/libadhocutil/cache.impl.h @@ -4,6 +4,7 @@ #include "cache.h" #include #include "lockHelpers.h" +#include namespace AdHoc { diff --git a/libadhocutil/lockHelpers.h b/libadhocutil/lockHelpers.h index 1482644..3e2a208 100644 --- a/libadhocutil/lockHelpers.h +++ b/libadhocutil/lockHelpers.h @@ -1,45 +1,18 @@ #ifndef ADHOCUTIL_LOCKHELPERS_H #define ADHOCUTIL_LOCKHELPERS_H -#include - -/// @cond -template -class _LockLoop : public locktype { - public: - template - _LockLoop(MutexType & m) : - locktype(m), - flag(true) - { - } - - operator bool() const { return flag; } - void operator!() { flag = false; } - - private: - bool flag; -}; -/// @endcond - #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) 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 BaseLock(l,lt) lt LIBADHOC_LOCK_WITHLINE(_lck)(l) +#define BaseScopeLock(l,lt) if (auto LIBADHOC_LOCK_WITHLINE(_lck) = lt(l)) -#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 Lock(l) BaseLock(l, std::unique_lock) +#define SharedLock(l) BaseLock(l, std::shared_lock) -#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)) +#define ScopeLock(l) BaseScopeLock(l, std::unique_lock) +#define SharedScopeLock(l) BaseScopeLock(l, std::shared_lock) #endif diff --git a/libadhocutil/semaphore.cpp b/libadhocutil/semaphore.cpp index ac2900e..38ff0fe 100644 --- a/libadhocutil/semaphore.cpp +++ b/libadhocutil/semaphore.cpp @@ -8,7 +8,7 @@ namespace AdHoc { void Semaphore::notify() { - boost::mutex::scoped_lock lock(mutex); + std::scoped_lock lock(mutex); ++count; condition.notify_one(); } @@ -16,7 +16,7 @@ namespace AdHoc { void Semaphore::wait() { - boost::mutex::scoped_lock lock(mutex); + std::unique_lock lock(mutex); while (!count) { condition.wait(lock); } @@ -26,10 +26,10 @@ namespace AdHoc { bool Semaphore::wait(unsigned int timeout) { - const boost::system_time expiry = boost::get_system_time() + boost::posix_time::milliseconds(timeout); - boost::mutex::scoped_lock lock(mutex); + const auto expiry = std::chrono::milliseconds(timeout); + std::unique_lock lock(mutex); while (!count) { - if (!condition.timed_wait(lock, expiry)) { + if (condition.wait_for(lock, expiry) == std::cv_status::timeout) { return false; } } diff --git a/libadhocutil/semaphore.h b/libadhocutil/semaphore.h index 3411543..5c7bbea 100644 --- a/libadhocutil/semaphore.h +++ b/libadhocutil/semaphore.h @@ -4,8 +4,8 @@ // Borrowed from StackOverflow // http://stackoverflow.com/questions/4792449/c0x-has-no-semaphores-how-to-synchronize-threads -#include -#include +#include +#include #include "visibility.h" namespace AdHoc { @@ -26,8 +26,8 @@ namespace AdHoc { unsigned int freeCount() const; private: - boost::mutex mutex; - boost::condition_variable condition; + std::mutex mutex; + std::condition_variable condition; unsigned long count; }; } diff --git a/libadhocutil/unittests/Jamfile.jam b/libadhocutil/unittests/Jamfile.jam index 56f29c9..3cc32c1 100644 --- a/libadhocutil/unittests/Jamfile.jam +++ b/libadhocutil/unittests/Jamfile.jam @@ -108,7 +108,7 @@ run ..//adhocutil boost_utf boost_system - boost_thread + pthread : testLocks ; diff --git a/libadhocutil/unittests/testLocks.cpp b/libadhocutil/unittests/testLocks.cpp index 4b0bad5..0c93d99 100644 --- a/libadhocutil/unittests/testLocks.cpp +++ b/libadhocutil/unittests/testLocks.cpp @@ -2,46 +2,65 @@ #include #include "lockHelpers.h" -#include +#include BOOST_AUTO_TEST_CASE ( lock ) { - boost::shared_mutex _lock; - Lock(_lock); + std::shared_mutex _lock; + { + Lock(_lock); + BOOST_CHECK(_lck11.owns_lock()); + BOOST_CHECK(!_lock.try_lock()); + BOOST_CHECK(!_lock.try_lock_shared()); + } + BOOST_CHECK(_lock.try_lock()); + _lock.unlock(); + BOOST_CHECK(_lock.try_lock_shared()); + _lock.unlock_shared(); } BOOST_AUTO_TEST_CASE ( sharedlock ) { - boost::shared_mutex _lock; - SharedLock(_lock); -} - -BOOST_AUTO_TEST_CASE ( upgradelock ) -{ - boost::upgrade_mutex _lock; - UpgradableLock(_lock, ln); - UpgradeScopeLock(ln) { } - UpgradeLock(ln); + std::shared_mutex _lock; + { + SharedLock(_lock); + BOOST_CHECK(_lck26.owns_lock()); + BOOST_CHECK(!_lock.try_lock()); + BOOST_CHECK(_lock.try_lock_shared()); + _lock.unlock_shared(); + } + BOOST_CHECK(_lock.try_lock()); + _lock.unlock(); + BOOST_CHECK(_lock.try_lock_shared()); + _lock.unlock_shared(); } BOOST_AUTO_TEST_CASE ( scopelock ) { - boost::shared_mutex _lock; - ScopeLock(_lock) { } + std::shared_mutex _lock; + ScopeLock(_lock) { + BOOST_CHECK(_lck41.owns_lock()); + BOOST_CHECK(!_lock.try_lock()); + BOOST_CHECK(!_lock.try_lock_shared()); + } + BOOST_CHECK(_lock.try_lock()); + _lock.unlock(); + BOOST_CHECK(_lock.try_lock_shared()); + _lock.unlock_shared(); } BOOST_AUTO_TEST_CASE ( sharedscopelock ) { - boost::shared_mutex _lock; - SharedScopeLock(_lock) { } -} - -BOOST_AUTO_TEST_CASE ( upgradescopelock ) -{ - boost::upgrade_mutex _lock; - UpgradableScopeLock(_lock, ln) { - UpgradeScopeLock(ln) { } - UpgradeLock(ln); + std::shared_mutex _lock; + SharedScopeLock(_lock) { + BOOST_CHECK(_lck55.owns_lock()); + BOOST_CHECK(!_lock.try_lock()); + BOOST_CHECK(_lock.try_lock_shared()); + _lock.unlock_shared(); } + BOOST_CHECK(_lock.try_lock()); + _lock.unlock(); + BOOST_CHECK(_lock.try_lock_shared()); + _lock.unlock_shared(); } -- cgit v1.2.3