
vicente.botet wrote:
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
Could not find basic_semaphore in boost. Is it one from your Synchro library? Locking a mutex inside post() is inefficient. If one thread has the mutex locked then there is no need to wait until the mutex is unlocked. Use try_lock() and return if cannot lock. In one of the previous posts i described why a binary_semaphore::timed_wait() was superior in my case than condition_variable::timed_wait(). Using a condition variable defeats the purpose of a binary_semaphore (at least in my usage scenario). BR, Dmitry