2

I'm using a pthread to schedule some tasks on my application. I copied the code from my old C version of the same application and it worked perfectly. Now I'm coding with C++ and it doesn't work anymore (basically it doesn't trigger the sigevent executing the given function). All creation and starting functions exit with rc 0, even when i use the timer_gettime.

I simplified a lot the code to narrow down the issue but I could't find it yet:

#include <signal.h>
#include <time.h>

int main (void)

{
char Mytimer[5] = "myt";
timer_t Ti_coarse;
Tcreate(Mytimer, &Ti_coarse, 1000, 1000);
while (1)
{

}
return 0;

static int Tcreate( char *name, timer_t *timerID, int expireMS, int intervalMS )
{
   struct sigevent         te;
   struct itimerspec       its;
   struct sigaction        sa;
   int                     sigNo = SIGRTMIN;

   sa.sa_flags = SA_SIGINFO;
   sa.sa_sigaction = app;
   sigemptyset(&sa.sa_mask);
   if (sigaction(sigNo, &sa, NULL) == -1)
   {
       perror("sigaction");
   }

   /* Set and enable alarm */
   te.sigev_notify = SIGEV_SIGNAL;
   te.sigev_signo = sigNo;
   te.sigev_value.sival_ptr = timerID;
   timer_create(CLOCK_REALTIME, &te, timerID);

   its.it_interval.tv_sec = 0;
   its.it_interval.tv_nsec = intervalMS * 1000000;
   its.it_value.tv_sec = 0;
   its.it_value.tv_nsec = expireMS * 1000000;
   timer_settime(*timerID, 0, &its, NULL);

   return 1;
}

static void app(int sig, siginfo_t *si, void *uc)
{
    //do nothing
}

I expected to see the "THIS IS THE TIMERS" every second, but I don't get any output. If I check the expiration time of a 5 mins clock with printf("%d", its.it_value) I always get 299, no matter how much time passed.

Could you possible help me to spot the problem ?

Podarce
  • 473
  • 1
  • 6
  • 22

1 Answers1

2

First, you have not provided a full example that anyone can use to reproduce your problem. See How to create a Minimal, Complete, and Verifiable example.

But the code you posted does have one serious problem. You can't safely use cout in a signal handler. Your signal handler can result in undefined behavior:

static void app(int sig, siginfo_t *si, void *uc)
{
    cout << "THIS IS THE TIMER" << endl;
}

Per the POSIX standard:

The following table defines a set of functions that shall be async-signal-safe. Therefore, applications can call them, without restriction, from signal-catching functions. ...

(large table of functions that are safe to call in a signal handler)

Implementations may make other interfaces async-signal-safe. In the presence of signals, all functions defined by this volume of POSIX.1-2008 shall behave as defined when called from or interrupted by a signal-catching function, with the exception that when a signal interrupts an unsafe function or equivalent (such as the processing equivalent to exit() performed after a return from the initial call to main()) and the signal-catching function calls an unsafe function, the behavior is undefined.

Using cout is not in the table of async-signal-safe functions, so calling it from a signal handler can cause undefined behavior.

Andrew Henle
  • 32,625
  • 3
  • 24
  • 56
  • Thanks for the int about the cout, sir. Regarding the code I think I missed the timer_t Ti_coarse declaration and the #include. I'm sorry If I didn't create my example well. – Podarce Aug 11 '17 at 12:20
  • @Podarce The C `write()` call is async-signal safe. In C++, `::write( STDERR_FILENO, "THIS IS THE TIMER\n", ::strlen( "THIS IS THE TIMER\n" ) );` is safe. Note also that it's to `stderr` instead of `stdout` to avoid any interaction with the `stdout` and/or `cout` buffers. – Andrew Henle Aug 11 '17 at 14:18
  • Thanks sir, I tried using a function on the async-signal safe list, but still no luck getting it to work. I'm thinking about building an Object timer and simplify a bit the code, since I need only 1 second minimum time resolution. – Podarce Aug 11 '17 at 14:23