posix timer sends synchronous signals?
I want to handle a timer event in a thread instead of a signal handler by using sigwait. However, the thread waiting on the signal (SIGRTMIN) doesn't recieve the timer signal set by timer_settime and the program aborts with SIGRTMIN. If I modify the program to not set the timer and I send SIGRTMIN asyncronously using kill at the command line, then the thread receives it. This leads me to conclude that timer_settime() generates syncronous signals, as syncronous sigs which are not caught by a sig handler abort the program. But this cannot be correct behavior; it defeats the purpose of having sigwait() available. (It also contradicts the suggested usage mentioned in the man page for thr_sigsetmask()). Anyone else have this problem? I'm using Solaris 8/SPARC.
Here is a simple program that is SUPPOSED to print 'got it!!' once per second, based on timer expirations. Due to the strange behavior of timer_settime(), it instead simply aborts with SIGRTMIN.
I compiled it with cc sigtest.c -lrt -lthread. Any advice on how to get this working? Please pardon the indentation. Thanks.
/* sigtest.c */
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <signal.h>
#include <time.h>
pthread_t handler_thrid;
sigset_t blocked_sigs;
timer_t timerid;
struct sigevent sigspec;
struct itimerspec timer_spec;
void handler_thr(void a)
{
int sig;
sigset_t set;
printf("handle thr created\n");
sigemptyset(&set);
sigaddset(&set, SIGRTMIN);
while (1)
{
sigwait(&set);
printf("got it!!\n");
}
}
int main()
{
/* block SIGRTMIN */
pthread_sigmask(0, 0, &blocked_sigs);
sigaddset(&blocked_sigs, SIGRTMIN);
pthread_sigmask(SIG_BLOCK, &blocked_sigs, NULL);
/* create timer that sends SIGRTMIN */
sigspec.sigev_notify = SIGEV_SIGNAL;
sigspec.sigev_signo = SIGRTMIN;
timer_create(CLOCK_REALTIME, &sigspec, &timerid);
/* start thread */
pthread_create(&handler_thrid, NULL, handler_thr, NULL);
/* start timer */
timer_spec.it_value.tv_sec = 1;
timer_spec.it_value.tv_nsec = 0;
timer_spec.it_interval.tv_sec = 1;
timer_spec.it_interval.tv_nsec = 0;
timer_settime(timerid, 0, &timer_spec, NULL);
pthread_join(handler_thrid, NULL);
}