0
votes

I have a class which allows to wait on a condition_variable taking care of the spurious wake ups. Following is the code:

Code:

// CondVarWrapper.hpp
#pragma once
#include <mutex>
#include <chrono>
#include <condition_variable>

class CondVarWrapper {
public:
    void Signal() {
        std::unique_lock<std::mutex> unique_lock(mutex);
        cond_var_signalled = true;
        unique_lock.unlock();
        cond_var.notify_one();
    }

    // TODO: WaitFor needs to return false if timed out waiting
    bool WaitFor(const std::chrono::seconds timeout) {
        std::unique_lock<std::mutex> unique_lock(mutex);
        bool timed_out = false;
        // How to determine if wait_for timed out ?
        cond_var.wait_for(unique_lock, timeout, [this] {
            return cond_var_signalled;
        });
        cond_var_signalled = false;
        return timed_out;
    }

    void Wait() {
        std::unique_lock<std::mutex> unique_lock(mutex);
        cond_var.wait(unique_lock, [this] {
            return cond_var_signalled;
        });
        cond_var_signalled = false;
    }

private:
    bool cond_var_signalled = false;
    std::mutex  mutex;
    std::condition_variable cond_var;
};

// main.cpp
#include "CondVarWrapper.hpp"
#include <iostream>
#include <string>
#include <thread>

int main() {
   CondVarWrapper cond_var_wrapper;

   std::thread my_thread = std::thread([&cond_var_wrapper]{
       std::cout << "Thread started" << std::endl;
        if (cond_var_wrapper.WaitFor(std::chrono::seconds(1))) {
            std::cout << "Wait ended before timeout" << std::endl;
        } else {
            std::cout << "Timed out waiting" << std::endl;
        }
    });

   std::this_thread::sleep_for(std::chrono::seconds(6));
   // Uncomment following line to see the timeout working
   cond_var_wrapper.Signal();
   my_thread.join();
}

Question:
In the method WaitFor, I need to determine if cond_var timed out waiting? How do I do that? WaitFor should return false when it timed out waiting else it should return true. Is that possible?
I see cv_status explained on cppreference but struggling to find a good expample of how to use it.

Hint: What would be the value of cond_var_signalled immediately after cond_var.wait_for(...) returns because Signal() was called? And, what would be the value of the same variable immediately after cond_var.wait_for(...) returned because of a timeout? - Solomon Slow
Yes. I know that trick. I was looking for more sure way from the method wait_for or wait_until. The reason is that if I have priority based approach for more than 2 threads waiting on the condition_variable then just a boolean way of indicating wont help. Right? - AdeleGoldberg
Maybe you should say more about what you really are trying to achieve. As it is, your question sounds a bit like the XY problem. For the case where Wait() returns before the Signal() is given, can you explain why it is important for your application to know the difference between it happening because of a timeout or, it happening for some other reason? Also, are you saying that you intend to have two threads waiting for the same condition at different priorities? What is the reason for that? - Solomon Slow