mardi 30 mai 2017

condition variable wait_for/wait_until bug

I'm facing a very strange behavior on a simple code snippet.

The following code is part of a larger project, runs on a separate thread and produce a 100% cpu usage, being stuck on the wait_until call of the conditional variable:

class myclass {
protected:
    std::mutex mtx;
    std::condition_variable cv_should_go;

    // ... more stuff, thread initialization...

    void my_thread_func() {
        std::chrono::milliseconds timeout(1000);
        std::unique_lock<std::mutex> l(mtx, std::defer_lock);
        while (true) {
            auto now = std::chrono::system_clock::now();
            l.lock();
            while (true) {
                std::cout << "Here 1" << std::endl;
                auto result = cv_should_go.wait_until(l, now + timeout);
                std::cout << "Here 2" << std::endl;
                if (some_condition || result == std::cv_status::timeout)
                    break;
            }
            // Other logic goes here, but suppose there's nothing...
            l.unlock();
        } 
    }
}

When some_condition condition is false, I expect a timeout after one second, a break due to the timeout itself, and again a wait of one second and so on... However, only one Here 1 line appears on the console, and the program simply stucks at the wait_until call.

Looking at CPU usage with top I can see the process using 100% of the CPU time. The very strange thing is that if I replace the cv_should_go condition variable with a CV within the scope of the function (killing the purpose of the class-scoped CV):

        ...
        std::unique_lock<std::mutex> l(mtx, std::defer_lock);
        std::condition_variable cv;
        while (true) {
            auto now = std::chrono::system_clock::now();
            l.lock();
            while (true) {
                std::cout << "Here 1" << std::endl;
                auto result = cv.wait_until(l, now + timeout);
        ...

the code runs flawlessly and produces the sequence of "Here 1" and "Here 2" every second.

The same thing happens if I replace wait_until with wait_for.

This was reproduced with g++ 4.9 and g++ 6.3 on a Debian 8 system.

Is this a bug of BOTH compilers or something hidden I can't really see?

Aucun commentaire:

Enregistrer un commentaire