views:

195

answers:

2

Hello, I'm wondering if there is a boost equivalent of ManualResetEvent? Basically, I'd like a cross-platform implementation... Or, could someone help me mimic ManualResetEvent's functionality using Boost::thread? Thanks guys

+1  A: 

IIRC, ManualResetEvents exist to allow multiple threads to wait on an object, and one thread to get woken at a time when the object is signaled. The "manual reset" part comes from the fact that the system does not automatically reset the event after it wakes a thread; you do that instead.

This sounds very similar to condition variables:

The general usage pattern is that one thread locks a mutex and then calls wait on an instance of condition_variable or condition_variable_any. When the thread is woken from the wait, then it checks to see if the appropriate condition is now true, and continues if so. If the condition is not true, then the thread then calls wait again to resume waiting.

Max Lybbert
I basically just have a writer thread that must always write and never be blocked, while I have a reader thread that can only read when the writer isn't writing... if that makes sense. Thanks
Polaris878
I would say that your design makes sense.
Max Lybbert
+5  A: 

It's pretty easy to write a manual reset event when you have mutexes and condition variables.

What you will need is a field that represents whether your reset event is signalled or not. Access to the field will need to be guarded by a mutex - this includes both setting/resetting your event as well as checking to see if it is signaled.

When you are waiting on your event, if it is currently not signaled, you will want to wait on a condition variable until it is signaled. Finally, in your code that sets the event, you will want to notify the condition variable to wake up anyone waiting on your event.

class manual_reset_event
{
public:
    manual_reset_event(bool signaled = false)
        : signaled_(signaled)
    {
    }

    void set()
    {
        {
            boost::lock_guard<boost::mutex> lock(m_)
            signaled = true;
        }

        // Notify all because until the event is manually
        // reset, all waiters should be able to see event signalling
        cv_.notify_all();
    }

    void unset()
    {
        boost::lock_guard<boost::mutex> lock(m_)
        signaled_ = false;
    }


    void wait()
    {
        boost::lock_guard<boost::mutex> lock(m_)
        while (!signaled_)
        {
            cv_.wait(lock);
        }
    }

private:
    boost::mutex m_;
    boost::condition_variable cv_;
    bool signaled_;
};
R Samuel Klatchko