Reputation: 12104
I have created a timer using POSIX timerfd function.
Intention is, the timer should be periodic, and the timer expiry is observed from a seperate function called myFunc( )
I am calling this function multiple times, so that the timer expiry can be observed periodically after a wait of 5 secs.
Problem is, as soon as first time it expires after 5 seconds, next time onwards...it doesn't expire again, that is no delay of 5 seconds is observed from the second iteration onwards.
Can someone tell me what i am missing?
#include <stdio.h>
#include <iostream>
#include <errno.h>
#include <dlfcn.h>
#include <assert.h>
#include <sys/mman.h>
#include <new>
#include <limits.h>
#include <sys/epoll.h>
#include <sys/timerfd.h>
using namespace std;
struct epoll_event event;
int timer_fd, efd, no_of_fd;
void myFunc( int i );
int main()
{
struct itimerspec its;
its.it_value.tv_sec = 5;
its.it_value.tv_nsec = 0;
its.it_interval.tv_sec = 3; // Every 3 seconds interval
its.it_interval.tv_nsec = 0;
efd = epoll_create(2);
timer_fd = timerfd_create(CLOCK_REALTIME, TFD_NONBLOCK);
if ( timer_fd == -1 )
{
fprintf(stderr, "timerfd_create error in start timer");
return 1;
}
event.data.fd = timer_fd;
event.events = EPOLLIN|EPOLLPRI;
if ( epoll_ctl(efd, EPOLL_CTL_ADD, timer_fd, &event) == -1 )
{
fprintf(stderr, "epoll_ctl error in start timer");
return 1;
}
if ( timerfd_settime(timer_fd, 0, &its, NULL) == -1 )
{
fprintf(stderr, "timerfd_settime error in start timer");
return 1;
}
myFunc( 10 );
myFunc( 20 );
myFunc( 30 );
}
void myFunc( int i )
{
printf("Inside myFunc %d\n", i);
no_of_fd = 0;
struct epoll_event revent;
errno = 0;
do {
no_of_fd = epoll_wait(efd, &revent, 1, -1);
} while ( no_of_fd < 0 && errno == EINTR );
if ( no_of_fd < 0 )
{
fprintf(stderr, "epoll_wait error in start timer");
}
if ( revent.data.fd == timer_fd ) {
printf("Timer expired \n");
}
}
Upvotes: 1
Views: 694
Reputation: 4555
When using epoll
with level-triggering, you should read 8 bytes on every EPOLLIN. This is an int64 that tells you the number of event expirations. Reading it effectively "clears" this number so that the next EPOLLIN is the result of a different event expiration.
The manual tells you about reading:
If the timer has already expired one or more times since its
settings were last modified using timerfd_settime(), or since
the last successful read(2), then the buffer given to read(2)
returns an unsigned 8-byte integer (uint64_t) containing the
number of expirations that have occurred. (The returned value
is in host byte order—that is, the native byte order for
integers on the host machine.)
Upvotes: 0