diff options
author | Dan Goodliffe <dan@randomdan.homeip.net> | 2018-04-06 11:30:10 +0100 |
---|---|---|
committer | Dan Goodliffe <dan@randomdan.homeip.net> | 2018-04-06 15:26:07 +0100 |
commit | db2c0bd9baf2a7e19f977b38fb0c19d9aba75dc1 (patch) | |
tree | 201c731ce37782f638dd731754253afb8187e2ff | |
parent | C++17 (diff) | |
download | libadhocutil-db2c0bd9baf2a7e19f977b38fb0c19d9aba75dc1.tar.bz2 libadhocutil-db2c0bd9baf2a7e19f977b38fb0c19d9aba75dc1.tar.xz libadhocutil-db2c0bd9baf2a7e19f977b38fb0c19d9aba75dc1.zip |
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.
-rw-r--r-- | libadhocutil/cache.impl.h | 1 | ||||
-rw-r--r-- | libadhocutil/lockHelpers.h | 39 | ||||
-rw-r--r-- | libadhocutil/semaphore.cpp | 10 | ||||
-rw-r--r-- | libadhocutil/semaphore.h | 8 | ||||
-rw-r--r-- | libadhocutil/unittests/Jamfile.jam | 2 | ||||
-rw-r--r-- | 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 <boost/lambda/lambda.hpp> #include "lockHelpers.h" +#include <shared_mutex> 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 <type_traits> - -/// @cond -template <typename locktype> -class _LockLoop : public locktype { - public: - template<typename MutexType> - _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<decltype(l)>::type -#define BaseScopeLock(l,lt) for (_LockLoop<lt<LIBADHOC_RRT(l)>> LIBADHOC_LOCK_WITHLINE(_lck)(l); LIBADHOC_LOCK_WITHLINE(_lck); !LIBADHOC_LOCK_WITHLINE(_lck)) -#define TypeBaseLock(l,lt,mt) lt<mt> 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<LIBADHOC_RRT(l)> 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<boost::upgrade_lock<LIBADHOC_RRT(l)>> ln(l); ln; !ln) -#define UpgradeScopeLock(l) for (_LockLoop<boost::upgrade_to_unique_lock<LIBADHOC_RRT(l)::mutex_type>> 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 <boost/thread/condition.hpp> -#include <boost/thread/mutex.hpp> +#include <condition_variable> +#include <mutex> #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 <library>..//adhocutil <library>boost_utf <library>boost_system - <library>boost_thread + <library>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 <boost/test/unit_test.hpp> #include "lockHelpers.h" -#include <boost/thread/shared_mutex.hpp> +#include <shared_mutex> 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(); } |