Daan Pape Daan Pape - 3 months ago 13
C Question

Check if time_t is zero

I have written a timer eventloop with epoll and the timerfd linux API. The magpage of

timerfd_gettime
states the following:

The it_value field returns the amount of time until the timer will
next expire. If both fields of this structure are zero, then the
timer is currently disarmed.


So to check if a timer is currently armed or disarmed I had written the following code:

bool timer_is_running(struct timer *timer)
{
struct itimerspec timerspec;

if(timerfd_gettime(timer->_timer_fd, &timerspec) == -1) {
printf("[TIMER] Could not get timer '%s' running status\n", timer->name);
return false;
}

printf("[TIMER] Checking running state of timer '%s' it_value.tv_sec = %"PRIu64", it_value.tv_nsec = %"PRIu64"\n", timer->name, (uint64_t) timerspec.it_value.tv_sec, (uint64_t) timerspec.it_value.tv_nsec == 0);
return timerspec.it_value.tv_sec != 0 && timerspec.it_value.tv_nsec != 0;
}


This wasn't working and all timers were reported as disarmed. when I looked at the output I saw the following on a currently disarmed timer:

[TIMER] Checking running state of timer 'test' it_value.tv_sec = 0, it_value.tv_nsec = 4302591840


After further investigation it seems only the
tv_sec
field is set to 0 on disarmed timers.

This is program runs on kernel 3.18.23 on MIPS architecture (OpenWRT).

Before I flag this as a bug in the kernel implementation I would like to know if it's correct to check if a
time_t
is 0 by doing
time_t == 0
. Can anyone confirm this?

Kind regards,
Daan

Answer

This is not a bug in the kernel implementation. It is your code that is flawed.

The it_value field returns the amount of time until the timer will next expire. If both fields of this structure are zero, then the timer is currently disarmed.

The converse of this is that (assuming the call timerfd_gettime() succeeds) the timer is armed if ONE or BOTH of the fields of the structure are non-zero.

The last return statement of your function is

return timerspec.it_value.tv_sec != 0  && timerspec.it_value.tv_nsec != 0;

which returns true only if BOTH the fields are non-zero. Instead, you need to use

return timerspec.it_value.tv_sec != 0  || timerspec.it_value.tv_nsec != 0;
Comments