1// RUN: %clangxx_tsan %s -o %t && %run %t 2>&1 | FileCheck %s
2
3#include <pthread.h>
4#include <stdio.h>
5#include <stdlib.h>
6#include <signal.h>
7#include <sys/types.h>
8#include <sys/time.h>
9#include <unistd.h>
10#include <errno.h>
11
12volatile bool signal_delivered;
13
14static void handler(int sig) {
15 if (sig == SIGALRM)
16 signal_delivered = true;
17}
18
19static void* thr(void *p) {
20 sigset_t sigset;
21 sigemptyset(set: &sigset);
22 sigaddset(set: &sigset, SIGALRM);
23 int ret = pthread_sigmask(SIG_UNBLOCK, newmask: &sigset, NULL);
24 if (ret) abort();
25
26 struct sigaction act = {};
27 act.sa_handler = &handler;
28 if (sigaction(SIGALRM, act: &act, oact: 0)) {
29 perror(s: "sigaction");
30 exit(status: 1);
31 }
32
33 itimerval t;
34 t.it_value.tv_sec = 0;
35 t.it_value.tv_usec = 10000;
36 t.it_interval = t.it_value;
37 if (setitimer(ITIMER_REAL, new: &t, old: 0)) {
38 perror(s: "setitimer");
39 exit(status: 1);
40 }
41
42 while (!signal_delivered) {
43 usleep(useconds: 1000);
44 }
45
46 t.it_value.tv_usec = 0;
47 if (setitimer(ITIMER_REAL, new: &t, old: 0)) {
48 perror(s: "setitimer");
49 exit(status: 1);
50 }
51
52 fprintf(stderr, format: "SIGNAL DELIVERED\n");
53
54 return 0;
55}
56
57int main() {
58 sigset_t sigset;
59 sigemptyset(set: &sigset);
60 sigaddset(set: &sigset, SIGALRM);
61 int ret = pthread_sigmask(SIG_BLOCK, newmask: &sigset, NULL);
62 if (ret) abort();
63
64 pthread_t th;
65 pthread_create(newthread: &th, attr: 0, start_routine: thr, arg: 0);
66 pthread_join(th: th, thread_return: 0);
67
68 fprintf(stderr, format: "DONE\n");
69 return 0;
70}
71
72// CHECK-NOT: WARNING: ThreadSanitizer:
73// CHECK: SIGNAL DELIVERED
74// CHECK: DONE
75// CHECK-NOT: WARNING: ThreadSanitizer:
76

source code of compiler-rt/test/tsan/Darwin/signals-blocked.cpp