#include "apue.h"
#include <pthread.h>
sigset_t mask;
struct sigaction ignore, saveintr, savequit, sigusr1_act, sigusr2_act;
int usr1_count;
int usr2_count;
pthread_t tid1;
pthread_t tid2;
void * thr_fn1(void *arg);
void * thr_fn2(void *arg);
static void sigusr1_handler(int sign);
static void sigusr2_handler(int sign);
void * thr_fn1(void *arg)
{
int err, signo;
int i ;
sigaction(SIGUSR1, &sigusr1_act, NULL);
pthread_detach(pthread_self());
for (;;)
{
if ( pthread_kill(tid2, SIGUSR2) == 0)
{
}
err = sigwait(&mask, &signo);
if (err != 0)
err_exit(err, "sigwait failed");
switch (signo)
{
case SIGUSR1:
printf("\nget SIGUSR1...,usr1_count=%d \n",usr1_count--);
break;
default:
printf("unexpected signal %d\n", signo);
exit(1);
}
}
}
void * thr_fn2(void *arg)
{
int err, signo;
int i ;
sigaction(SIGQUIT, &savequit, NULL);
sigaction(SIGUSR1, &sigusr1_act, NULL);
pthread_detach(pthread_self());
for (;;)
{
if ( pthread_kill(tid1, SIGUSR1) == 0)
{
}
err = sigwait(&mask, &signo);
if (err != 0)
err_exit(err, "sigwait failed");
switch (signo) {
case SIGUSR2:
printf("\nget SIGUSR2...,usr1_count=%d \n",usr1_count++);
break;
default:
printf("unexpected signal %d\n", signo);
exit(1);
}
}
}
static void sigusr1_handler(int sign)
{
usr1_count ++;
}
static void sigusr2_handler(int sign)
{
usr1_count ++;
}
int main(void)
{
int err;
sigset_t oldmask;
sigemptyset(&mask);
sigaddset(&mask, SIGQUIT);
sigaddset(&mask, SIGUSR1);
sigaddset(&mask, SIGUSR2);
sigusr1_act.sa_handler = sigusr1_handler;
sigusr2_act.sa_handler = sigusr2_handler;
if ((err = pthread_sigmask(SIG_BLOCK, &mask, &oldmask)) != 0)
err_exit(err, "SIG_BLOCK error");
err = pthread_create(&tid1, NULL, thr_fn1, 0);
if (err != 0) err_exit(err, "can't create thread");
err = pthread_create(&tid2, NULL, thr_fn2, 0);
if (err != 0) err_exit(err, "can't create thread");
sleep (10);
/* reset signal mask which unblocks SIGQUIT */
if (sigprocmask(SIG_SETMASK, &oldmask, NULL) < 0)
{
err_sys("SIG_SETMASK error");
}
exit(0);
}