I have 2 timers to deliver different signals to the same application. One signal is received, but the other is not. If I manually send it the missing signal, it is received and handled.
There's other questions relating to missing signals, but the answers agree with my code. This leaves me thinking it's a timer issue... but that means one is not working, even though setup the same way that one works. How can this be?
Operating system is QNX 6.6 (Posix 1003.1)
For the code below, the system log output contains only "Logger received USR2 signal".
static void setSignalHandler ()
{
sigset_t setBlk;
sigemptyset(&setBlk);
// mask SIGUSR1 and SIGUSR2 on entering signal handler
sigaddset(&setBlk, SIGUSR1);
sigaddset(&setBlk, SIGUSR2);
struct sigaction act;
act.sa_handler = signalHandler;
act.sa_mask = setBlk;
act.sa_flags = 0;
setSignalAction(SIGHUP, &act); // Hangup
setSignalAction(SIGINT, &act); // Interrupt
setSignalAction(SIGQUIT, &act); // Quit
setSignalAction(SIGABRT, &act); // Abort
setSignalAction(SIGUSR1, &act); // User signal 1
setSignalAction(SIGUSR2, &act); // User signal 2
setSignalAction(SIGTSTP, &act); // Stopped (user)
}
static void setSignalAction (int sig, const struct sigaction * act)
{
if (sigaction(sig, act, NULL) == -1)
{
// error
perror("Set signal action");
}
}
static void signalHandler (int sig)
{
switch (sig)
{
case SIGUSR1:
slogf(_SLOG_SETCODE(_SLOGC_LOGGER, 0), _SLOG_NOTICE, "Logger received USR1 signal");
...
return;
case SIGUSR2:
slogf(_SLOG_SETCODE(_SLOGC_LOGGER, 0), _SLOG_NOTICE, "Logger received USR2 signal");
...
return;
default:
slogf(_SLOG_SETCODE(_SLOGC_LOGGER, 0), _SLOG_NOTICE, "Logger received signal %d", sig);
break;
}
}
Here is the timer setup code. If I comment out the one for SIGUSR2, still SIGUSR1 is not seen.
static void setupTimer ()
{
struct sigevent ev;
ev.sigev_notify = SIGEV_SIGNAL;
ev.sigev_signo = SIGUSR2;
ev.sigev_priority = getprio(0);
if (timer_create(CLOCK_MONOTONIC, &ev, &timerTS) == -1)
{
perror("Failed to setup timer");
slogf(_SLOG_SETCODE(_SLOGC_LOGGER, 0), _SLOG_ERROR, "Logger failed to setup timestamp timer.");
}
struct sigevent ev2;
ev2.sigev_notify = SIGEV_SIGNAL;
ev2.sigev_signo = SIGUSR1;
ev2.sigev_priority = getprio(0);
if (timer_create(CLOCK_MONOTONIC, &ev2, &timer2) == -1)
{
perror("Failed to setup timer");
slogf(_SLOG_SETCODE(_SLOGC_LOGGER, 0), _SLOG_ERROR, "Logger failed to setup timer 2.");
}
}
static void startTimer ()
{
struct itimerspec ts;
ts.it_value.tv_sec = timestampInterval; // this is usually 60
ts.it_value.tv_nsec = 0;
ts.it_interval.tv_sec = timestampInterval;
ts.it_interval.tv_nsec = 0;
if (timer_settime(timerTS, 0, &ts, NULL) == -1)
{
perror("Failed to start timestamp timer");
slogf(_SLOG_SETCODE(_SLOGC_LOGGER, 0), _SLOG_ERROR, "Logger failed to start timestamp timer.");
}
ts.it_value.tv_sec = 0;
ts.it_value.tv_nsec = 0;
ts.it_interval.tv_sec = TIMER2_INTERVAL_SEC; // this is 60
ts.it_interval.tv_nsec = 0;
if (timer_settime(timer2, 0, &ts, NULL) == -1)
{
perror("Failed to start timer2");
slogf(_SLOG_SETCODE(_SLOGC_LOGGER, 0), _SLOG_ERROR, "Logger failed to start timer2.");
}
}
Seems probable that the issue is with timer_settime setting for the second timer. Try setting ts.it_value to something nonzero before timer_settime for timer2? It looks like you're setting up the timer to be disabled.