Linux実装は pthread*のマスクと sigprocmask()とは同じって書いてた。。
#include <sys/mman.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/syscall.h>
#include <fcntl.h>
#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
#include <pthread.h>
#include <signal.h>
#define gettid() syscall(SYS_gettid)
// 0: sigprocmask at process, 1:thr1,
#define DF_CHGMASK_ID 2
//#define DF_USE_PTHREADMASK
//#define DF_INITIAL_MASK (SIGSEGV)
//#define DF_INITIAL_MASK (SIGABRT)
#define DF_INITIAL_MASK (12)
void abt_handler(int n, siginfo_t *pSigInf, void *pContext)
{
struct sigaction sa;
printf("I am dead...[%d][parent:%d][tid=%d][thread_id=%ld]", getpid(), getppid(), gettid(), (long)pthread_self());
memset(&sa,0,sizeof(struct sigaction));
//_exit(1);
sigemptyset(&sa.sa_mask);
// sa.sa_flags |= SA_SIGINFO ;
sa.sa_handler = SIG_DFL;
// sigaction(SIGABRT,&sa,NULL);
// raise(SIGABRT);
}
void register_handler()
{
struct sigaction sa;
memset(&sa,0,sizeof(struct sigaction));
sigemptyset(&sa.sa_mask);
sa.sa_flags |= SA_SIGINFO ;
sa.sa_sigaction = abt_handler;
// sigaction(SIGABRT,&sa,NULL);
sigaction( 12,&sa,NULL);
}
struct st_signals_st {
int signo;
const char *pcSignal ;
} st_signals[] = {
{SIGHUP, "SIGHUP"},
{SIGINT, "SIGINT"},
{SIGQUIT, "SIGQUIT"},
{SIGILL, "SIGILL"},
{SIGTRAP, "SIGTRAP"},
{SIGABRT, "SIGABRT"},
{SIGIOT, "SIGIOT"},
{SIGBUS, "SIGBUS"},
{SIGFPE, "SIGFPE"},
{SIGKILL, "SIGKILL"},
{SIGUSR1, "SIGUSR1"},
{SIGSEGV, "SIGSEGV"},
{SIGUSR2, "SIGUSR2"},
{SIGPIPE, "SIGPIPE"},
{SIGALRM, "SIGALRM"},
{SIGTERM, "SIGTERM"},
{SIGSTKFLT, "SIGSTKFLT"},
{SIGCHLD, "SIGCHLD"},
{SIGCONT, "SIGCONT"},
{SIGSTOP, "SIGSTOP"},
{SIGTSTP, "SIGTSTP"},
{SIGTTIN, "SIGTTIN"},
{SIGTTOU, "SIGTTOU"},
{SIGURG, "SIGURG"},
{SIGXCPU, "SIGXCPU"},
{SIGXFSZ, "SIGXFSZ"},
{SIGVTALRM, "SIGVTALRM"},
{SIGPROF, "SIGPROF"},
{SIGWINCH, "SIGWINCH"},
{SIGIO, "SIGIO"},
{SIGPOLL, "SIGPOLL"},
{SIGPWR, "SIGPWR"},
{SIGSYS, "SIGSYS"},
{0, NULL}
} ;
void dump_sigmask(const char* pMsg, sigset_t* sig_mask)
{
struct st_signals_st* pStSignal = st_signals ;
int i;
puts(pMsg);
while( pStSignal->pcSignal ){
if (sigismember( sig_mask, pStSignal->signo )) {
putchar('1');
}
else {
putchar('0');
}
pStSignal++;
}
putchar('_');
for (i=SIGRTMIN; i<=SIGRTMAX; i++) {
if (sigismember( sig_mask, i )) {
putchar('1');
}
else {
putchar('0');
}
}
puts("");
return ;
}
void* thr1(void* arg)
{
sigset_t sig_mask ;
sleep(1);
printf("[%d/ppid=%d/tid=%d/self=%ld] wakeup thr1!\n", getpid(), getppid(), gettid(), (long)pthread_self());
pthread_sigmask(SIG_UNBLOCK, NULL, &sig_mask);
dump_sigmask("thr1", &sig_mask);
#if (DF_CHGMASK_ID==1)
sigfillset(&sig_mask);
#ifdef DF_USE_PTHREADMASK
if (pthread_sigmask(SIG_SETMASK, &sig_mask, NULL)) {
#else
if (sigprocmask(SIG_SETMASK, &sig_mask, NULL)) {
#endif
perror ("main(): failure set...");
}
#endif
sleep(4);
pthread_sigmask(SIG_UNBLOCK, NULL, &sig_mask);
dump_sigmask("thr1", &sig_mask);
#if (DF_CHGMASK_ID==1)
sigemptyset(&sig_mask);
#ifdef DF_USE_PTHREADMASK
if (pthread_sigmask(SIG_SETMASK, &sig_mask, NULL)) {
#else
if (sigprocmask(SIG_SETMASK, &sig_mask, NULL)) {
#endif
perror ("main(): failure set...");
}
#endif
sleep(4);
pthread_sigmask(SIG_UNBLOCK, NULL, &sig_mask);
dump_sigmask("thr1", &sig_mask);
sleep(10);
}
void* thr2(void* arg)
{
sigset_t sig_mask ;
register_handler();
// sigaddset(&sig_mask, DF_INITIAL_MASK) ;
sigemptyset(&sig_mask);
sigaddset(&sig_mask, 12) ;
#ifdef DF_USE_PTHREADMASK
if (pthread_sigmask(SIG_UNBLOCK, &sig_mask, NULL)) {
#else
if (sigprocmask(SIG_UNBLOCK, &sig_mask, NULL)) {
#endif
perror ("thr2(): Dead set...");
}
sleep(2);
printf("[%d/ppid=%d/tid=%d/self=%ld] wakeup thr2!\n", getpid(), getppid(), gettid(), (long)pthread_self());
pthread_sigmask(SIG_UNBLOCK, NULL, &sig_mask);
dump_sigmask("thr2", &sig_mask);
sleep(4);
pthread_sigmask(SIG_UNBLOCK, NULL, &sig_mask);
dump_sigmask("thr2", &sig_mask);
sleep(4);
pthread_sigmask(SIG_UNBLOCK, NULL, &sig_mask);
dump_sigmask("thr2", &sig_mask);
system("echo thr2 is spawn $$ ; sleep 17");
sleep(3);
}
int
main(int argc, char *argv[])
{
int status=0;
int fd;
pthread_t child[2];
sigset_t sig_mask ;
sigfillset(&sig_mask);
if (sigprocmask(SIG_BLOCK, &sig_mask, NULL)) {
perror ("main(): Dead set...");
}
/*
sigaddset(&sig_mask, DF_INITIAL_MASK) ;
if (sigprocmask(SIG_UNBLOCK, &sig_mask, NULL)) {
perror ("main(): Dead set...");
}
*/
// register_handler();
if (sigprocmask(SIG_UNBLOCK, NULL, &sig_mask)) {
perror ("main(): Dead get...");
}
dump_sigmask("main", &sig_mask);
/* スレッド生成 */
pthread_create(&child[0], NULL, thr1, NULL );
pthread_create(&child[1], NULL, thr2, NULL );
sleep(4);
#if (DF_CHGMASK_ID==0)
sigemptyset(&sig_mask);
if (sigprocmask(SIG_SETMASK, &sig_mask, NULL)) {
perror ("main(): failure set...");
}
#endif
if (sigprocmask(SIG_UNBLOCK, NULL, &sig_mask)) {
perror ("main(): Dead get...");
}
dump_sigmask("main", &sig_mask);
sleep(4);
#if (DF_CHGMASK_ID==0)
sigfillset(&sig_mask);
if (sigprocmask(SIG_SETMASK, &sig_mask, NULL)) {
perror ("main(): failure set...");
}
#endif
if (sigprocmask(SIG_UNBLOCK, NULL, &sig_mask)) {
perror ("main(): Dead get...");
}
dump_sigmask("main", &sig_mask);
sleep(4);
if (sigprocmask(SIG_UNBLOCK, NULL, &sig_mask)) {
perror ("main(): Dead get...");
}
dump_sigmask("main", &sig_mask);
status = pthread_join(child[0], NULL);
if (status<0) {
printf("pthread_join(0) returns: %d\n", status);
}
status = pthread_join(child[1], NULL);
if (status<0) {
printf("pthread_join(0) returns: %d\n", status);
}
return 0;
}