12

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

DigitalZebra
  • 39,494
  • 39
  • 114
  • 146

2 Answers2

13

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_;
};
Nick
  • 25,026
  • 7
  • 51
  • 83
R Samuel Klatchko
  • 74,869
  • 16
  • 134
  • 187
  • 1
    I think you might need to use `boost::condition_variable_any` for this to work. See: http://stackoverflow.com/questions/8758353/whats-the-difference-between-stdcondition-variable-and-stdcondition-variable – Nick Feb 24 '12 at 10:21
  • Also, the condition_variable_any::wait method has to be given the mutex as a parameter, not the lock guard. – Oliver Feb 27 '13 at 13:37
  • Hmm, I get: error C2664 'void boost::condition_variable::wait(boost::unique_lock &)' : cannot convert parameter 1 from 'boost::lock_guard' to 'boost::unique_lock &' It I use condition_variable_any, I get another error inside condition_variable about unlock() method do not exist. – Alexander Jul 06 '16 at 10:33
1

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
  • 19,717
  • 4
  • 46
  • 69
  • 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 – DigitalZebra Oct 01 '09 at 00:03
  • I would say that your design makes sense. – Max Lybbert Oct 01 '09 at 06:28