
----- Original Message ----- From: "Dmitry Goncharov" <dgoncharov@unison.com> To: <boost@lists.boost.org> Sent: Thursday, February 26, 2009 10:40 AM Subject: Re: [boost] Request for interest in the new Synchro library
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: 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.
OOPS! Where I have my head!
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.
Thanks for the proposal. I have another alternative using inheritance that avoid adding a new mutex. template <typename ScopeTag=multi_threaded_tag> class basic_binary_semaphore: public basic_semaphore<ScopeTag> { public: BOOST_COPY_CONSTRUCTOR_DELETE(basic_binary_semaphore) /*< disable copy construction >*/ BOOST_COPY_ASSIGNEMENT_DELETE(basic_binary_semaphore) /*< disable copy asignement >*/ inline explict basic_binary_semaphore(int initialCount):basic_semaphore<ScopeTag>(initialCount>0?1:0) {}; inline void post() { scoped_lock lock(this->m_mut); if(this->m_count == 0){ this->m_cond.notify_one(); ++(this->m_count); } } }; typedef basic_binary_semaphore<> binary_semaphore; Attached the complete file. What do you think? Thanks, Vicente