JefferyRPrice
JefferyRPrice

Reputation: 895

How does bool version of boost::condition_variable::wait_until using a predicate behave?

Trying to use the:

bool
wait_until(
    unique_lock<mutex>& lock,
    const chrono::time_point<Clock, Duration>& t,
    Predicate pred);

form of boost::condition_variable::wait_until (long story why not std). The documentation states that the effects of this are "As-if:"

while(!pred())
{
    if(!wait_until(lock,abs_time))
    {
        return pred();
    }
}
return true;

But the wait_until(lock,abs_time) form of wait_until actually returns a cv_status type defined as:

enum class cv_status;
{
  no_timeout,
  timeout
};

Since the cv_status type can't be implicitly cast to a bool (right?), what does the if(!wait_until(lock,abs_time)) conditional from the "As-if" imply exactly? I imagine it's saying "if the wait times out, return the value of the predicate" but I don't get that from the form of the if statement and the cv_status return type of that wait_until.

Now, the std documentation "Equivalent to" seems to be exactly what I'd expect:

while (!pred()) {
    if (wait_until(lock, abs_time) == std::cv_status::timeout) {
        return pred();
    }
}
return true;

So is it safe to assume the boost documentation is just a little off and the implementation is as-stated in the std documentation?

Upvotes: 1

Views: 1017

Answers (1)

sehe
sehe

Reputation: 393653

You might be mixing up documentation¹.

In this sample code: Live On Coliru (output: "Nay")

#include <boost/thread.hpp>
#include <iostream>

int main()
{
    boost::mutex m;
    boost::condition_variable cv;

    boost::unique_lock<boost::mutex> lk(m);
    if (cv.wait_until(lk,
            boost::chrono::high_resolution_clock::now() + boost::chrono::seconds(1), 
            [] { return false; }))
    {
        std::cout << "Yay\n";
    } else {
        std::cout << "Nay\n";
    }
}

The return type of wait_until is actually bool. The implementation of that call is actually:

    template <class Clock, class Duration, class Predicate>
    bool
    wait_until(
            unique_lock<mutex>& lock,
            const chrono::time_point<Clock, Duration>& t,
            Predicate pred)
    {
        while (!pred())
        {
            if (wait_until(lock, t) == cv_status::timeout)
                return pred();
        }
        return true;
    }

As you can see, it deals with the cv_status type explicitly.

Other than that it does look as if [sic] the "As-if" code is pseudo-code that assumes a bool-kind of return value. I agree this is technically "incorrect".


¹ See enter image description here

Upvotes: 1

Related Questions