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 <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:
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
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.
Related
I have a server and client codes that IPC with each other via named pipes(FIFO). Client sends SIGNAL(SIGUSR1 for example) to Server and checking to see if any signal arrived with given time resolution(via command line argument). Server checks (if its 5ms) 5ms everytime, checks if any signal arrived after 5ms , if arrived it does some code , if not continues until it catches a signal.
So here is that what my problem lies. I dont know what to use for these kind of action. I looked up "Unix Systems Programming: Communication, Concurrency, and Threads Kay A. Robbins , Steven Robbins" found some functions that might be use for me. Sleep,Alarm,uSleep,NanoSleep,Pause. But i dont know which one to use in my situation. Sleep is out of question i think due it takes seconds and i think it overflows when you try to convert to milliseconds.
A little code snippet or psudocode would be nice to understand for me.
I simply asking how to check if signal arrived in given resolution frequency. I have to check if signal arrived in those milliseconds. Check any given "n" mseconds if signal catched.
I think that the function nanosleep (and also usleep) could work!
You have to install a signal handler for the desired signal that can be catched by the program, e.g.:
#include <signal.h>
/* Handler for the signals */
void my_handler(int signum)
{
if(signum == SIGUSR1) {
/* Perform an action on signal SIGUSR1*/
}
}
int main(int argc, char * argv[]){
/* .... */
/* Install the signal handler to catch the desired signals*/
signal(SIGUSR1, my_handler);
/* .... */
}
You have to loop and wait for a signal. And if you catch a signal you have to perform the actions either inside the handler or using the exception that raise when nanosleep is interrupted.
#include <time.h> /* Contains nanosleep + timespec definition */
#include <errno.h> /* Contains the errno variable and the ERROR_CODE macros */
#include <stdio.h> /* Contains definition of perror */
#include <stdlib.h> /* Contains the exit function */
int main(int argc, char * argv[]){
/* fetch milliseconds from argv and put in a variable named "ms" */
struct timespec interval;
interval.tv_sec = 0; /* Seconds*/
interval.tv_nsec = ms*1e6; /* 10^6 Nanoseconds = 1 millisecond */
struct timespec interrupted;
/* .. */
while(1) {
if(nanosleep(&interval, &interrupted) != 0){
/* The sleeping was interrupted! */
if(errno == EINTR){
//The interruption is due to a signal
}
else {
/*The interruption is due to another cause (read the man page) --> Print an error message */
perror("Nanosleep");
break; /* Exit from main loop */
}
}
return EXIT_FAILURE;
}
Alternatively you can also deal the signals inside the handlers.
Alternative Solution
If you are sure that a signal will ever come and don't need to control each 5 milliseconds you could also use the function pause. In fact the man page says:
pause causes the calling process (or thread) to sleep until a signal
is delivered that either terminates the process or causes the
invocation of a signal-catching function.
In this case you have only to install the signal handler and wait.
Let me know if it answered your question.
Sincerly yours,
Mirko
#include <signal.h>
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
static jmp_buf env_alrm;
static void sig_alarm(int signo)
{
longjmp(env_alrm, 1);
}
int sleep2(unsigned int seconds)
{
if(signal(SIGALRM, sig_alarm)==SIG_ERR)
return seconds;
if(setjmp(env_alrm)==0) //when it is first called, return value is 0
{
alarm(seconds);
pause();
}
return (alarm(0))
}
On this code, I think this is making infinite loop. My thinkings are following:
We call sleep2()functions in main like sleep2(3), then after calling pause(), SIGALRM will be delivered after 3 secs. So, signal handler sig_alarm() will be called.
And, after calling longjmp(), it will go to setjmp() function in sleep2. And finally, after testing setjmp()'s return value(which should be 1 after calling longjmp()) it will execute return alarm(0). So, it will immediately call sig_alarm() again(because SIGALRM is delivered again), and this loop will be continued.
What am I missing?
alarm(0) does not deliver any alarm event. It cancels a previously scheduled alarm and returns the number of seconds remaining until this canceled alarm (if any).
The last line of your code does not cause infinite loop, because it does not execute sig_alarm. It returns the number of seconds remaining to a normal expiration of your sleep2. In your small example this will be zero. Your code is probably a part of larger software where longjmp (and the last line of your sleep2) may be executed before the timer expires. In this case sleep2 returns the number of seconds remaining to a normal expiration.
I don't understand how the EVLOOP_NO_EXIT_ON_EMPTY flag is supposed to work in version 2.1.x of libevent.
If I don't add any events to my event_base the
event_base_loop(my_base, EVLOOP_NO_EXIT_ON_EMPTY);
call returns
immediately which is not at all what I think it's supposed to do.
If I add an event it loops with that pending event until it get's active but then the loop exits which I hoped would not happen.
Goal:
Have a named pipe open and libevent listening for a read.
Whenever I
echo "something" > pipe
the registered callback should be called. If the callback has finished the event get's back to pending and the loop waits for another echo.
Here's what I got so far: (error checking omitted)
#include <fcntl.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <event.h>
#include <unistd.h>
#define PIPE "/tmp/ev_pipe"
void cb_func(evutil_socket_t fd, short what, void *arg)
{
printf("foo\n");
}
int main(void)
{
/* create & open named pipe */
mkfifo(PIPE, 0666);
int socket = open(PIPE, O_RDONLY | O_NONBLOCK);
/* libevent specific stuff */
struct event_base *ev_base = event_base_new();
struct event *ev = event_new(ev_base, (evutil_socket_t) socket, EV_READ, cb_func, NULL);
event_add(ev, NULL);
/* loop forever */
event_base_loop(ev_base, EVLOOP_NO_EXIT_ON_EMPTY);
printf("a\n");
/* clean up */
unlink(PIPE);
event_base_free(ev_base);
close(socket);
return 0;
}
What am I missing? The event loop exits after the first write to the queue :/
Thanks for any help!
The implementation of the feature looks buggy! I had faced the same issue with the 2.1.x version. One way to get around the issue is as #Wizzard has pointed out. Another way of getting around the issue is OR the flag EV_PERSIST to the events argument to the function event_new:
struct event *ev = event_new(ev_base,
(evutil_socket_t) socket, EV_READ|EV_PERSIST, cb_func, NULL);
This will prevent the event from being removed. https://github.com/libevent/libevent/blob/master/include/event2/event.h +872
Please be aware that you might get multiple callbacks when there is data on pipe.
Just use event_base_dispatch (ev_base); instead of event_base_loop ()``, it will loop and handle all attached events either until you explicitly delete all attached events or callevent_base_loopbreak ()``` function.
I would like to have a function run periodically, given a time step. What is the most efficient way to do this?
I know I could use a while look and just keep checking till the dt period has elapsed. But I'd like to know if there is a better, more efficient/elegant function to use.
I was looking into virtual timers and sigaction. Using this method, I would have the sigaction handler set a flag when the time has elapsed, but I would still need to sit in a while loop checking for that flag to be set in my main function. Alternatively I wonder if I could actually have the handler run the function, but then I would have to pass a lot of arguments, and as far as I have read, handlers don't take arguments, so I would have to use lots of global variables.
What would be the best way to tackled this?
On an *IX'ish system you could
install a handler for SIGALRM, which does nothing
set an alarm using alarm()
call blocking pause()
If the alarm signal is sent pause() will return and
you can run the function in question,
again set the alarm
start over calling pause()
#define _POSIX_SOURCE 1
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <signal.h>
#include <errno.h>
void handler_SIGALRM(int signo)
{
signo = 0; /* Get rid of warning "unused parameter ‘signo’" (in a portable way). */
/* Do nothing. */
}
int main()
{
/* Override SIGALRM's default handler, as the default handler might end the program. */
{
struct sigaction sa;
memset(&sa, 0, sizeof(sa));
sa.sa_handler = handler_SIGALRM;
if (-1 == sigaction(SIGALRM, &sa, NULL ))
{
perror("sigaction() failed");
exit(EXIT_FAILURE);
}
}
while (1)
{
alarm(2); /* Set alarm to occur in two seconds. */
pause(); /* The call blocks until a signal is received; in theis case typically SIGARLM. */
/* Do what is to be done every 2 seconds. */
}
return EXIT_SUCCESS;
}
The easiest way is to use sleep or usleep as defined in unistd.h.
If neither of those are available then a common workaround is to use a select with a timeout on no file descriptors.
Include time.h and use sleep function like
#include <time.h>
#include <stdio.h>
#include<windows.h>
#include <conio.h>
int main() {
printf("I am going to wait for 4 sec");
Sleep(4000); //sleep for 4000 microsecond= 4 second
printf("Finaaly the wait is over");
getch();
return 0;
}
It will give you a precise delay on microsecond level.
Hope it helped.
I am new to sockets programming and I'm trying to thoroughly understand how it works, but for now I'm really stuck on select().
The problem is that in my code, after select detects activity and the fd stays set, it seems that on next iterations FD_ISSET will return true automatically, like it would ignore the select function. The problem seems to be identical to this one, but I did all that I found there and to no avail: http://compgroups.net/comp.unix.programmer/how-does-fd_isset-return-0-after-returne/55058
I made sure to reinitialize the timeval variable after select() since I'm on Linux and I understood this function behaves differently on different OSes, I also reinitialized the fd set with FD_ZERO and FD_SET before select.
What am I doing wrong? Here is the code:
#include <stdio.h>
#include <strings.h>
#include <sys/select.h>
#include <sys/time.h>
int main () {
struct timeval tv;
tv.tv_sec = 5; // 5 seconds timeout
tv.tv_usec = 0;
fd_set afds, rfds;
FD_ZERO(&afds);
FD_SET(0, &afds);
while (1) {
rfds = afds;
select(1, &rfds, NULL, NULL, &tv);
// linux, reinitialize tv?
tv.tv_sec = 5;
tv.tv_usec = 0;
// so at this point after select runs the first time and detects STDIN activity
// it will enter an infinite loop printing "fd 0 is set" (why?)
if (FD_ISSET(0, &rfds)) {
printf("fd 0 is set\n");
FD_CLR(0, &rfds);
} else {
printf("fd 0 is NOT set\n");
}
}
}
Question edit since I'm a new user and can't answer this:
The fact is I initialize rfds before select when it is assigned the value of afds, which in turn is always set with FD_ZERO(&afds); FD_SET(0, &afds); This still doesn't work for me.
Here's what I understand:
I add stdin file descriptor to afds
Enter while infinite loop, rfds = afds (rfds will always be = afds at the start of the loop)
Also, at this time, FD_ISSET(0, &rfds) will always be != 0
select has a timeout of 5 seconds, so at this time if I don't type anything before the 5 seconds pass, it exits, UNSETTING FD_ISSET(0, &rfds) - is that correct? so select will actually unset the fd 0 if nothing is typed. This seems to work OK
The problem arrives when I type something before the timeout. At this point, FD_ISSET(0, &rfds) returns != 0, it prints fd 0 is set, and then each loop fd will be set
Ok, is this accurate, did I get it right? So practically select doesn't wait for the time to pass because it actually detects that the fd is ready and exits, setting the fd != 0 ?
Which would beg for a further question: if I need the server to send automatically messages to several clients every once in a while (independently of what it reads from clients), would it be possible to do it with select and gettimeofday by adapting the code above?
Thanks for the help.
select() is level-triggered, not edge-triggered. When you pass it a set of file descriptors, it will come back telling you which ones are readable/writable/exceptional at the moment, not just the ones that have changed state recently.
In this case, fhe FD is being marked as readable every time you call select() because you're not doing anything to make it not readable (like draining the available input) when it shows up.
The values stored in your fd_set do remain after select() fires. In an application it is possible for select() to monitor many sockets. Automatically cleaning the fd_set would mean you could never detect that multiple sockets need servicing.
You need to do your FD_ZERO() and FD_SET() inside the infinite loop so that on each pass the fd_set is initialized cleanly before select() is called.