|
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