diff options
| -rw-r--r-- | libadhocutil/Jamfile.jam | 5 | ||||
| -rw-r--r-- | libadhocutil/semaphore.cpp | 40 | ||||
| -rw-r--r-- | libadhocutil/semaphore.h | 29 | ||||
| -rw-r--r-- | libadhocutil/unittests/Jamfile.jam | 11 | ||||
| -rw-r--r-- | libadhocutil/unittests/testSemaphore.cpp | 44 | 
5 files changed, 128 insertions, 1 deletions
diff --git a/libadhocutil/Jamfile.jam b/libadhocutil/Jamfile.jam index 861509a..c82dade 100644 --- a/libadhocutil/Jamfile.jam +++ b/libadhocutil/Jamfile.jam @@ -1,7 +1,8 @@  import package ;  import lex ; -lib boost_utf : : <name>boost_unit_test_framework ; +lib boost_system ; +lib boost_thread ;  lib Ice : ;  lib IceUtil ;  lib pthread ; @@ -15,6 +16,8 @@ lib adhocutil :  	:  	<include>.  	<library>iceall +	<library>boost_system +	<library>boost_thread  	<library>curl  	<library>dl  	<cflags>-fvisibility=hidden diff --git a/libadhocutil/semaphore.cpp b/libadhocutil/semaphore.cpp new file mode 100644 index 0000000..0500445 --- /dev/null +++ b/libadhocutil/semaphore.cpp @@ -0,0 +1,40 @@ +#include "semaphore.h" + +namespace AdHoc { +	Semaphore::Semaphore(unsigned int initial) : count(initial) +	{ +	} + +	void +	Semaphore::notify() +	{ +		boost::mutex::scoped_lock lock(mutex); +		++count; +		condition.notify_one(); +	} + +	void +	Semaphore::wait() +	{ +		boost::mutex::scoped_lock lock(mutex); +		while (!count) { +			condition.wait(lock); +		} +		--count; +	} + +	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); +		while (!count) { +			if (!condition.timed_wait(lock, expiry)) { +				return false; +			} +		} +		--count; +		return true; +	} +} + diff --git a/libadhocutil/semaphore.h b/libadhocutil/semaphore.h new file mode 100644 index 0000000..de10333 --- /dev/null +++ b/libadhocutil/semaphore.h @@ -0,0 +1,29 @@ +#ifndef ADHOCUTIL_SEMAPHORE_H +#define ADHOCUTIL_SEMAPHORE_H + +// 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 "visibility.h" + +namespace AdHoc { +	/// A portable semaphore with timeout support +	class DLL_PUBLIC Semaphore { +		public: +			Semaphore(unsigned int initial = 0); + +			void notify(); +			void wait(); +			bool wait(unsigned int); + +		private: +			boost::mutex mutex; +			boost::condition_variable condition; +			unsigned long count; +	}; +} + +#endif + diff --git a/libadhocutil/unittests/Jamfile.jam b/libadhocutil/unittests/Jamfile.jam index 0961f31..334b47e 100644 --- a/libadhocutil/unittests/Jamfile.jam +++ b/libadhocutil/unittests/Jamfile.jam @@ -165,6 +165,17 @@ run  	;  run +	testSemaphore.cpp +	: : : +	<define>BOOST_TEST_DYN_LINK +	<library>..//adhocutil +	<library>boost_utf +	<library>boost_system +	: +	testSemaphore +	; + +run  	testException.cpp  	: : :  	<define>BOOST_TEST_DYN_LINK diff --git a/libadhocutil/unittests/testSemaphore.cpp b/libadhocutil/unittests/testSemaphore.cpp new file mode 100644 index 0000000..b5e435e --- /dev/null +++ b/libadhocutil/unittests/testSemaphore.cpp @@ -0,0 +1,44 @@ +#define BOOST_TEST_MODULE Semaphore +#include <boost/test/unit_test.hpp> + +#include <thread> +#include <semaphore.h> + +BOOST_AUTO_TEST_CASE( addRemoveOne ) +{ +	AdHoc::Semaphore s; +	s.notify(); +	s.wait(); +} + +BOOST_AUTO_TEST_CASE( addRemoveSome ) +{ +	AdHoc::Semaphore s; +	s.notify(); +	s.notify(); +	s.notify(); +	s.wait(); +	s.wait(); +	s.wait(); +} + +BOOST_AUTO_TEST_CASE( addRemoveTimeOut ) +{ +	AdHoc::Semaphore s; +	s.notify(); +	s.wait(); +	BOOST_REQUIRE_EQUAL(false, s.wait(100)); +	BOOST_REQUIRE_EQUAL(false, s.wait(0)); +} + +BOOST_AUTO_TEST_CASE( addRemoveWait ) +{ +	AdHoc::Semaphore s; +	s.notify(); +	s.wait(); +	std::thread th([&s]() { usleep(100000); s.notify(); }); +	BOOST_REQUIRE_EQUAL(false, s.wait(1)); +	s.wait(); +	th.join(); +} +  | 
