Search code examples
ctimersignalsqnx

C Signal not received from timer


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.");
}
}

Solution

  • 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.