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