I am trying to understand how to use timed_wait
. I found only few examples (here and here) and I have a problem when calling it with an absolute time. The following code is a simplified example, in reality this all happens inside a class, so I thought it would be easier to check my predicate manually instead of having to use some binding and pass it to timed_wait
.
#include <boost/date_time/posix_time/posix_time.hpp>
#include <boost/thread.hpp>
#include <iostream>
bool done = false;
boost::mutex mutex;
boost::thread waitingThread;
boost::condition_variable cond;
void wait(boost::posix_time::time_duration dt){
boost::mutex::scoped_lock lock(mutex);
boost::system_time x = boost::posix_time::microsec_clock::local_time() + dt;
bool timedOut = false;
while((done == false) && (x > boost::posix_time::microsec_clock::local_time())) {
timedOut = ! cond.timed_wait(lock,x);
}
if (timedOut){ std::cout << "timeout\n"; }
else { std::cout << "success\n"; }
}
void wait2(boost::posix_time::time_duration dt){
boost::mutex::scoped_lock lock(mutex);
bool timedOut = ! cond.timed_wait(lock,dt);
if (timedOut){ std::cout << "timeout\n"; }
else { std::cout << "success\n"; }
}
void test(){
//boost::thread waiter = boost::thread(wait,boost::posix_time::milliseconds(50));
boost::thread waiter = boost::thread(wait2,boost::posix_time::milliseconds(50));
boost::this_thread::sleep(boost::posix_time::milliseconds(2000));
}
The first version blocks forever and I dont understand why. On the other hand, the second version afaik is subject to spurious wakeups. As I said before, in the real code, all this is place inside a class, so to use the overload that takes a predicate I would have to do something like
cond.timed_wait(lock,dt, ?bind?(&Foo::isDone,this));
but then I am not 100% sure if a spurious wakeup will make timed_wait
return true
(if this is the case my while (x > local_time())
would be superfluous.