1// RUN: %clang_tsan -O1 %s -o %t && %run %t 2>&1 | FileCheck %s
2
3#include "test.h"
4
5#include <assert.h>
6#include <errno.h>
7#include <pthread.h>
8#include <signal.h>
9#include <stdio.h>
10#include <stdlib.h>
11#include <unistd.h>
12
13static int SignalPipeFd[] = {-1, -1};
14static int BlockingPipeFd[] = {-1, -1};
15
16static void Handler(int _) { assert(write(SignalPipeFd[1], ".", 1) == 1); }
17
18static void *ThreadFunc(void *_) {
19 char C;
20 assert(read(BlockingPipeFd[0], &C, sizeof(C)) == 1);
21 assert(C == '.');
22 return 0;
23}
24
25int main() {
26 alarm(seconds: 60); // Kill the test if it hangs.
27
28 assert(pipe(SignalPipeFd) == 0);
29 assert(pipe(BlockingPipeFd) == 0);
30
31 struct sigaction act;
32 sigemptyset(set: &act.sa_mask);
33 act.sa_flags = SA_RESTART;
34 act.sa_handler = Handler;
35 assert(sigaction(SIGUSR1, &act, 0) == 0);
36
37 pthread_t Thr;
38 assert(pthread_create(&Thr, 0, ThreadFunc, 0) == 0);
39
40 // Give the thread enough time to block in the read call.
41 usleep(useconds: 1000000);
42
43 // Signal the thread, this should run the signal handler and unblock the read
44 // below.
45 pthread_kill(threadid: Thr, SIGUSR1);
46 char C;
47 assert(read(SignalPipeFd[0], &C, 1) == 1);
48
49 // Unblock the thread and join it.
50 assert(write(BlockingPipeFd[1], &C, 1) == 1);
51 void *_ = 0;
52 assert(pthread_join(Thr, &_) == 0);
53
54 fprintf(stderr, format: "PASS\n");
55 return 0;
56}
57
58// CHECK-NOT: WARNING: ThreadSanitizer:
59// CHECK: PASS
60

source code of compiler-rt/test/tsan/signal_in_read.c