Boost logo

Boost :

Subject: Re: [boost] Request for interest in the new Synchro library
From: vicente.botet (vicente.botet_at_[hidden])
Date: 2009-02-27 12:39:46


----- Original Message -----
From: "Dmitry Goncharov" <dgoncharov_at_[hidden]>
To: <boost_at_[hidden]>
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




Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk