开发者

Why waiting indefinitely - timerfd_create? Where have i gone wrong?

I have created a timer which can expire, in 5 seconds using timerfd_create, but i can see that it is waiting indefinitely.

Can someone help me?

Thanks in advance.

Here is my code:

enter code here
#include <sys/timerfd.h>
#include <sys/time.h>
#include &l开发者_开发知识库t;unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/epoll.h>
#include <time.h>

int main()
{
  struct itimerspec its;
  struct epoll_event event, revent;

  int timer_fd, efd;

  /* Setting timer interval */
  its.it_interval.tv_sec=1;
  its.it_interval.tv_nsec=0;

  /* Setting timer expiration */
  its.it_value.tv_sec=5;
  its.it_value.tv_nsec=0;

  efd=epoll_create(2);
  event.data.fd=timer_fd;

  event.events=EPOLLIN;
  epoll_ctl(efd, EPOLL_CTL_ADD, timer_fd, &event);

  timer_fd=timerfd_create(CLOCK_REALTIME, 0);

  if(timer_fd==-1)
  {
    perror("timerfd:");
  }

  if(timerfd_settime(timer_fd, TFD_TIMER_ABSTIME, &its, NULL)==-1)
  {
   perror("timerfd_settime error:");
  }

  printf("Starting the timer...");

  while(1) {
     epoll_wait(efd, &revent, 1, -1);
  }
}


Reverse the order of calls to epoll_ctl and timerfd_create. Right now you are adding some random integer value to the event set.

Edit 0:

Several points:

  • timerfd_create(2) produces a file descriptor, just like open(2) or socket(2). You have to assign the return value to the timer_fd variable before giving it to the epoll_ctl(2), otherwise it's just a random integer value from the stack.
  • Don't use TFD_TIMER_ABSTIME - you are asking the kernel to start a timer that expires one second after the Epoch (which is not that big of a deal - it'll just expire immediately).
  • When the timer expires epoll_wait(2) returns the number of ready file descriptors, 1 in your example, and you are expected to handle that. You, on the other hand, just ignore that return value and spin around in a tight loop, so you don't even know the timer is expiring.
  • You need to read from timer file descriptor to consume the expiration event. Otherwise all subsequent calls to epoll_wait(2) will just return immediately since the descriptor remains in the "signaled" state.
  • Always check the return values of the system calls and handle error conditions based on the value of errno(3) - manual page for each call gives you possible error values.

Edit 1:

You do want a loop around the epoll_wait(2) (or select(2). or poll(2)), but you need:

  1. handle the IO events being signaled (that's the whole point of these multiplexing APIs - being able to wait on multiple descriptors and dispatch the events), and
  2. be able to break out of that loop (on a signal, on input from a dedicated file descriptor ala self-pipe trick, or on some application event).

Hope this helps.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜