
vicente.botet wrote:
Hi,
the binary_semaphore you describe must poll with test_and_set. I have no such implementation, but as far as a portable test_and_set is available this can be implemented in the library.
Waiting for that what do you think of using a mutex as a binary_semaphore:
template <typename ScopeTag=multi_threaded_tag> class basic_binary_semaphore { typedef synchronization_family<ScopeTag> Sync; typedef typename Sync::mutex_type lockable_type; lockable_type mtx_; public: BOOST_COPY_CONSTRUCTOR_DELETE(basic_binary_semaphore) /*< disable copy construction >*/ BOOST_COPY_ASSIGNEMENT_DELETE(basic_binary_semaphore) /*< disable copy asignement >*/
inline basic_binary_semaphore() { mtx_.unlock(); };
inline void post() { mtx_.unlock(); }
inline void wait() { mtx.lock(); }
inline bool try_wait() { return mtx.try_lock(); }
inline bool try_wait_until(const system_time &abs_time) { return mtx.try_lock_until(); }
template<typename TimeDuration> inline bool try_wait_for(const TimeDuration &rel_time) { return try_wait_until(get_system_time()+rel_time); }
inline void wait_until(const system_time &abs_time) { if (!try_wait_until(abs_time)) throw timeout_exception(); }
template<typename TimeDuration> inline void wait_for(const TimeDuration &rel_time) { if (!try_wait_until(rel_time)) throw timeout_exception(); } };
Vicente
Hi, Unfortunately, the class above is not a semaphore since only the thread which locked the mutex can unlock it. A semaphore can be posted by any thread. What about the following adapter? #ifndef BOOST_BINSEM_HPP #define BOOST_BINSEM_HPP #include <boost/thread.hpp> namespace boost { template <typename Semaphore> class binary_semaphore { public: explicit binary_semaphore(int v) : m_sem(v) {} void wait() { m_sem.wait(); } void post() { // If cannot lock then some other thread is posting. // In this case just return. if (m_mutex.try_lock()) { try { // The result of try_wait() is not important. m_sem.try_wait(); m_sem.post(); } catch (...) { m_mutex.unlock(); throw; } m_mutex.unlock(); } } bool timed_wait(boost::posix_time::ptime const& t) { return m_sem.timed_wait(t); } bool try_wait() { return m_sem.try_wait(); } private: boost::mutex m_mutex; Semaphore m_sem; }; } #endif This adapter makes a binary semaphore out of a regular one. The post() method is not as efficient as it should be. On the other hand the adapter is very simple. There is also a test attached. BR, Dmitry