I\'m having a strange problem. I have the following code:
dbg(\"condwait: timeout = %d, %d\\n\",
abs_timeout->tv_sec, abs_timeout->tv_nsec);
Overflow in timespec
is usually the culprit for weird timeouts.
Check for EINVAL:
void timespec_add(struct timespec* a, struct timespec* b, struct timespec* out)
{
time_t sec = a->tv_sec + b->tv_sec;
long nsec = a->tv_nsec + b->tv_nsec;
sec += nsec / 1000000000L;
nsec = nsec % 1000000000L;
out->tv_sec = sec;
out->tv_nsec = nsec;
}
As already in other answers mentioned you have to use the absolute time. Since C11 you can use timespec_get()
.
struct timespec time;
timespec_get(&time, TIME_UTC);
time.tv_sec += 5;
pthread_cond_timedwait(&cond, &mutex, &time);
pthread_cond_timedwait takes an absolute time, not a relative time. You need to make your wait time absolute by adding to the current time to your timeout value.
The condition variable can spuriously unblock. You need to check it in a loop and check the condition each time through. You'll probably need to update the timeout value too.
I found some documentation for pthread_cond_timedwait
here.
When using condition variables there is always a Boolean predicate involving shared variables associated with each condition wait that is true if the thread should proceed. Spurious wakeups from the pthread_cond_timedwait() or pthread_cond_wait() functions may occur. Since the return from pthread_cond_timedwait() or pthread_cond_wait() does not imply anything about the value of this predicate, the predicate should be re-evaluated upon such return.