3

I am writing an application wherein I want call a function every 1 second. This is what I've written so far

Timerspec.it_interval.tv_sec=1;
Timerspec.it_interval.tv_nsec=0;
Timerspec.it_value.tv_sec=1;
Timerspec.it_value.tv_nsec=0;

timer_t timerId;

struct sigaction sa
sa.sa_handler=&TimerFn;
sigaction(SIGALRM,&sa,NULL);

timer_create(CLOCK_REALTIME,NULL,&timerId);
timer_settime(timerId,0,(const itimerspec*)Timerspec,NULL);

If my timer function(TimerFn) takes more than 1 second to complete, how to ignore the SIGALRM signals while the handler is running. Please note I want the signal to be ignored only when the handler is running. If handler is not running TimerFn should get called.

Thanks

Harry
  • 2,177
  • 1
  • 19
  • 33
  • 2
    `man sigaction(): [...]In addition, the signal which triggered the handler will be blocked, unless the SA_NODEFER flag is used.[...]`. – EOF Aug 10 '15 at 12:14
  • Is that all of your code, with you declaring your `struct sigaction sa` on the stack as a local variable? If so, it will not be properly initialized and will be filled with undefined contents. You need to do something like `memset( &sa, 0, sizeof( sa ) );`. – Andrew Henle Aug 10 '15 at 12:18
  • @EOF Thanks for the answer – Harry Aug 10 '15 at 12:26

1 Answers1

1

As mentioned in the comments, the signal is atomically blocked before entering the handler (unless SA_NODEFER is used), and unblocked after returning from the handler, so there's nothing you need to do.

The way you declare and use sa is buggy: you need to at least initialize the sa_flags field to 0, and you need to initialize the sa_mask field to the empty signal set:

struct sigaction sa;
sa.sa_handler = &TimerFn;
sa.sa_flags = 0;
sigemptyset(&sa.sa_mask);
sigaction(SIGALRM,&sa,NULL);

Note that the signal being caught is always blocked upon entering the handler and unblocked when leaving, even if you specified an empty signal mask in the sa_mask field of struct sigaction.

Filipe Gonçalves
  • 20,783
  • 6
  • 53
  • 70