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);
ret = pthread_cond_timedwait( &q->q_cond, &q->q_mtx, abs_timeout );
if (ret == ETIMEDOUT)
{
dbg("cond timed out\n");
return -ETIMEDOUT;
}
dbg
calls gettimeofday
before every line and prepends the line with the time. It results in the following output:
7.991151: condwait: timeout = 5, 705032704
7.991158: cond timed out
As you can see, only 7 microseconds passed in between the two debug lines, yet pthread_cond_timedwait
returned ETIMEDOUT
. How can this happen? I even tried setting the clock to something else when initializing the cond variable:
int ret;
ret = pthread_condattr_init(&attributes);
if (ret != 0) printf("CONDATTR INIT FAILED: %d\n", ret);
ret = pthread_condattr_setclock(&attributes, CLOCK_REALTIME);
if (ret != 0) printf("SETCLOCK FAILED: %d\n", ret);
ret = pthread_cond_init( &q->q_cond, &attributes );
if (ret != 0) printf("COND INIT FAILED: %d\n", ret);
(none of the error messages are printed out). I tried both CLOCK_REALTIME
and CLOCK_MONOTONIC
.
This code is part of a blocking queue. I need functionality such that if nothing gets put on this queue in 5 seconds, something else happens. The mutex and the cond are both initialized, as the blocking queue works fine if I don't use pthread_cond_timedwait
.
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.
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;
}
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