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();  } | 
