In setupPulseAndTimer() you see the code where we define the type of timer and notification scheme. When we talked about the timer function calls in the text above, I said that the timer could deliver a signal, a pulse, or cause a thread to be created. That decision is made here (in setupPulseAndTimer()).
Notice that we used the macro SIGEV_PULSE_INIT(). By using this macro, we're effectively assigning the value SIGEV_PULSE to the sigev_notify member. (Had we used one of the SIGEV_SIGNAL*_INIT() macros instead, it would have delivered the specified signal.) Notice that, for the pulse, we set the connection back to ourselves via the ConnectAttach() call, and give it a code that uniquely identifies it (we chose the manifest constant CODE_TIMER, something that we defined). The final parameter in the initialization of the event structure is the priority of the pulse; we chose SIGEV_PULSE_PRIO_INHERIT (the constant -1). This tells the kernel not to change the priority of the receiving thread when the pulse arrives.
Near the bottom of this function, we call timer_create() to create a timer object within the kernel, and then we fill it in with data saying that it should go off in one second (the it_value member) and that it should reload with one-second repeats (the it_interval member). Note that the timer is activated only when we call timer_settime(), not when we create it.
/*
* setupPulseAndTimer
*
* This routine is responsible for setting up a pulse so it
* sends a message with code MT_TIMER. It then sets up a
* periodic timer that fires once per second.
*/
void
setupPulseAndTimer (void)
{
timer_t timerid; // timer ID for timer
struct sigevent event; // event to deliver
struct itimerspec timer; // the timer data structure
int coid; // connection back to ourselves
// create a connection back to ourselves
coid = ConnectAttach (0, 0, chid, 0, 0);
if (coid == -1) {
fprintf (stderr, "%s: couldn't ConnectAttach to self!\n",
progname);
perror (NULL);
exit (EXIT_FAILURE);
}
// set up the kind of event that we want to deliver -- a pulse
SIGEV_PULSE_INIT (&event, coid,
SIGEV_PULSE_PRIO_INHERIT, CODE_TIMER, 0);
// create the timer, binding it to the event
if (timer_create (CLOCK_REALTIME, &event, &timerid) == -1) {
fprintf (stderr, "%s: couldn't create a timer, errno %d\n",
progname, errno);
perror (NULL);
exit (EXIT_FAILURE);
}
// setup the timer (1s delay, 1s reload)
timer.it_value.tv_sec = 1;
timer.it_value.tv_nsec = 0;
timer.it_interval.tv_sec = 1;
timer.it_interval.tv_nsec = 0;
// and start it!
timer_settime (timerid, 0, &timer, NULL);
}