C – Signal problem, timer (SIGEV_SIGNAL)

Signal problem, timer (SIGEV_SIGNAL)… here is a solution to the problem.

Signal problem, timer (SIGEV_SIGNAL)

I

have a small piece of code where I use the POSIX timer: timer_create(). Timers are created using the signaling method (SIGEV_SIGNAL) – because our platform does not support SIGEV_THREAD. When the timer expires, it generates a signal SIGUSR1 to notify it of its expiration, and there is a corresponding handler to capture this signal, inside this handler (in the actual program, not shown in the code) I have a flag for setting, once the signal given by the timer is captured.

So far, everything is fine: the problem is to assume that if the test program also generates the same signal as the timer (in this case, SIGUSR1), the same flag is set instead of being set by the timer. Therefore, it is not possible to distinguish whether the signal received by the signal handler is a timer signal or a signal from any other test program.

Can you help me with this?

Thanks in advance.

enter code here
#include <stdlib.h>
#include <time.h>
#include <stdio.h>
#include <signal.h>
#include <errno.h>
#include <string.h>

void sig_handlerTimer1(int);

time_t timerid;
int main()
{
     int i;
     static struct sigaction sa;

static struct sigevent sevp;   argument to timer_create
     static struct itimerspec its;  argument to timer_gettime

memset (&sevp, 0, sizeof (struct sigevent));
     sevp.sigev_value.sival_ptr = &timerid;
     sevp.sigev_notify = SIGEV_SIGNAL;
     sevp.sigev_notify_attributes = NULL;
     sevp.sigev_signo = SIGUSR1;
     sevp.sigev_notify_function=sig_handlerTimer1;

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

/* Setting timer expiration */
     its.it_value.tv_sec = 2;   First expiry after 1 sec
     its.it_value.tv_nsec = 0;

/* Setting the signal handlers before invoking timer*/
     sa.sa_handler = sig_handlerTimer1;
     sa.sa_flags = 0;
     sigaction(SIGUSR1, &sa, NULL);

if (timer_create(CLOCK_REALTIME, &sevp, &timerid) == -1)
     {
             fprintf(stderr, "LeakTracer (timer_trackStartTime): timer_create failed   to create timer. " \
                    "Leak measurement will be for entire duration of the execution   period:%s \n", strerror(errno));
            return;

}

if (timer_settime(timerid, 0, &its, NULL) == -1)
     {
             fprintf(stderr, "LeakTracer (timer_trackStartTime): timer_settime failed  to set the timer. " \
                    "Leak measurement will be for entire duration of execution period:%s \n", strerror(errno));
             return;

}

for(i=0; i<10; i++)
      {
             printf("%d\n",i);
             if(i==3) {
                 kill(getpid(), SIGUSR1);  SIGUSR1 also generated by test program  which reaches same handler and sets flag (THIS IS UN-DESIRABLE)
              }
             sleep(1);
       }

}

void sig_handlerTimer1(int signum)
  {

int flag = 1;
     printf("Caught signal: %d\n",signum);  How to understand this signal caught, is that of test program of timer expiry?
     if (timer_delete(timerid) < 0)
     {
             fprintf(stderr, "timer deletion failed. " \
                     "This may result in some memory leaks (sig_handlerTimer1):%s \n", strerror(errno));
      }
   }

Added: Once the signal is captured, is there any way to know inside the handler if the timer is really expired?

Solution

You can distinguish the cause of a signal by installing a signal handler with a SA_SIGINFO flag and a sa_sigaction member of the struct sigaction, and then use the si_ of the siginfo_t * passed to the signal handler code element. If it is SI_TIMER, the signal is generated by the timer expiration.

Related Problems and Solutions