2016-08-28 101 views
1

我已经用epoll和timerfd linux API编写了一个定时器eventloop。的timerfd_gettime的magpage规定如下:检查time_t是否为零

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. 

所以要检查是否定时器当前布防或撤防我写了下面的代码:

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; 
} 

这是行不通的,据报道都定时器作为解除武装。当我看到在输出我看到当前解除计时器以下:

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

经过进一步调查,似乎只有tv_sec字段设置为0的解除武装定时器。

这是在MIPS架构(OpenWRT)上的内核3.18.23上运行的程序。

在我将其标记为内核实现中的一个bug之前,我想知道通过执行time_t == 0来检查time_t是否为0是否正确。任何人都可以确认吗?

此致 大安

+1

在返回的表达式中使用'||',而不是'&&'。 – Peter

+0

你打算第三个参数是'timerspec.it_value.tv_nsec == 0'吗?当计时器有一个值时,这将评估为'0'。我问,因为这不符合格式规格的64位值。 –

回答

3

这不是内核实现中的错误。这是你的代码有缺陷。

it_value字段返回的时间量,直到定时器将 下一个到期。如果这个结构的两个字段都是零,那么 定时器目前被解除。

的这反过来是(假设该呼叫timerfd_gettime()成功)定时器设防如果一个或两个该结构的字段都是非零的。

你的函数的最后一个return语句是

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

仅返回true如果这两个字段不为零。相反,您需要使用

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

非常感谢。它现在起作用了,我也误导了,因为我在'uint64_t'中投入'time_t'的printf语句无法正常工作。 –

3

time_t类型别名是一个算术或真实类型。算术类型和实数类型都可以通过与整数值零进行隐式比较。此外,在POSIX系统(如Linux)上,time_t被定义为整数整数(例如参见this <sys/types.h> reference)。

尽管C标准没有明确指定time_t的类型,但出于兼容性原因,几乎所有的实现都使用time_t的整数。我不知道任何实现它不是一个整数。

所以你的问题的答案是,比较是正确的。

应该指出,它只是tv_sec成员的类型time_ttv_nsec成员是long