|
Boost : |
Subject: Re: [boost] Request for interest in the new Synchro library
From: Dmitry Goncharov (dgoncharov_at_[hidden])
Date: 2009-02-26 04:40:14
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
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk