2016-08-28 4 views
1

Я написал таймер eventloop с epoll и linux API timerfd. Magpage из timerfd_gettime гласит следующее:Проверьте, является ли 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 на разоруженных таймерах.

Это программа работает под управлением ядра 3.18.23 по архитектуре MIPS (OpenWRT).

Прежде чем я укажу это как ошибку в реализации ядра, я хотел бы знать, правильно ли проверять, является ли time_t 0, делая time_t == 0. Может ли кто-нибудь подтвердить это?

С наилучшими пожеланиями, Даан

+1

Используйте '||' в возвращаемом выражении, а не '&&'. – Peter

+0

Вы задали третий аргумент как 'timerspec.it_value.tv_nsec == 0'? Это будет оцениваться до '0', когда таймер имеет значение. Я спрашиваю, потому что это не будет 64-битное значение, соответствующее спецификации формата. –

ответ

3

Это не ошибка в реализации ядра. Это ваш код, который является ошибочным.

Поле it_value возвращает количество времени, до которого таймер будет следующий истек. Если оба поля этой структуры равны нулю, то таймер в настоящее время снят с охраны.

Обратное этого является то, что (в предположении, вызов завершается успешно timerfd_gettime()) таймер вооружен, если один или оба из полей структуры не равны нулю.

Последнее возвращение утверждение вашей функции

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

Большое спасибо. Теперь он работает, я также вводил в заблуждение, потому что оператор printf, в котором я использовал 'time_t' для' uint64_t', работал некорректно. –

3

time_t типа псевдоним является арифметическим или в режиме реального типа. Как арифметические, так и реальные типы могут быть неявно сопоставлены с целым значением 0.

Кроме того, на POSIX системах (таких как Linux) time_t определяется как целое число (смотри, например, this <sys/types.h> reference).

В то время как в стандарте C явно не указывается тип time_t, практически все реализации используют целые числа для time_t по соображениям совместимости. Я не знаю никакой реализации, где это не целое число.

Таким образом, ответ на ваш вопрос заключается в том, что сравнение правильное.

Следует отметить, что это только элемент tv_sec, который имеет тип time_t. Член tv_nsec является long.

 Смежные вопросы

  • Нет связанных вопросов^_^