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
IIRC, ManualResetEvent
s 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 ofcondition_variable
orcondition_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 callswait
again to resume waiting.
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_;
};