It's recommended to use the wait
functions with predicate, because they are less error-prone compared to hand-written loops. A hand-written loop might look as follows:
for (;;) {
if (myPredicate()) {
// ... [successful case]
break;
} else if (myCondition.wait_until(lock, wakeUpTime) == boost::cv_status::timeout) {
// ... [timeout case]
break;
} // else: continue loop [spurious wakeup]
}
If you pass a predicate to the wait
function, it might be a function-like thing that can be invoked with no arguments and returns a type, that can be used as a bool
. For example you can use a static
member function for that purpose:
struct Foobar {
static bool isFoobar();
};
myCondition.wait_until(lock, wakeUpTime, Foobar::isFoobar);
You can't directly pass a non-static member function, because it can only be invoked with an object. However, you can use a function-object instead:
struct MyPredicateWrapper {
MyClass* _ptr;
explicit MyPredicateWrapper(MyClass* ptr) : _ptr(ptr) { }
bool operator()() const { return _ptr->myPredicate(); }
};
myCondition.wait_until(lock, wakeUpTime, MyPredicateWrapper(this));
You can do basically the same thing with boost::bind
:
myCondition.wait_until(lock, wakeUpTime, boost::bind(&MyClass::myPredicate, this));
And if you are using C++11, you can also use a lambda function:
myCondition.wait_until(lock, wakeUpTime, [this] { return myPredicate(); });