The following behavior was seen under g++ 11.2.1 . The std::condition_variable wait_for method returns immediately if the timeout variable is too large. In particular in the program below, if num_years==1, then the program hangs waiting as expected (presumably for 1 year), but if the variable num_years==1000 then the program returns immediatly.
Why does this happen? Is this a bug in g++? And a related question, how do you make the cv.wait_for() wait indefinitely, instead of guessing a large timeout value?
// This is 'cv_wait.cc' compile with:
//
// g++ -o cv_wait -std=c++2a cv_wait.cc
//
// An example showing that wait_for() returns immediately with a timeout
// return value if the duration variable is "too large".
//
#include <iostream>
#include <condition_variable>
#include <chrono>
int main(int argc, char **argv)
{
std::condition_variable cv;
std::mutex cv_m;
// If num_years is "too large", e.g. 1000, then cv.wait_for()
// returns immediately with a timeout condition!
int num_years = 1; // If 1000 then cv.wait_for() returns immediately!
std::chrono::seconds timeout((uint64_t)3600 * 24 * 365 * num_years);
std::unique_lock<std::mutex> lock(cv_m);
if (cv.wait_for(lock, timeout, [] { return false; }))
std::cerr << "No timeout!\n";
else
std::cerr << "Timeout!\n";
}
This is an overflow bug under the hood of condition_variable::wait_for. Internally it is waiting using steady_clock which counts nanoseconds. This clock overflows at +/-292 years. So when 1000 years gets converted to nanoseconds, it is overflowing.
This looks like a standards bug as opposed to an implementation bug: http://eel.is/c++draft/thread.condition#condvar-24
The implementation should check for overflows of this type and in case found, just wait for the maximum time it is capable of waiting for.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With