1*bcaeed49SFangrui Song // RUN: %clang_tsan -O1 %s -o %t && %run %t 2>&1 | FileCheck %s
2*bcaeed49SFangrui Song 
3*bcaeed49SFangrui Song // Test that pause loop handles signals.
4*bcaeed49SFangrui Song 
5*bcaeed49SFangrui Song #include "test.h"
6*bcaeed49SFangrui Song #include <signal.h>
7*bcaeed49SFangrui Song #include <errno.h>
8*bcaeed49SFangrui Song 
handler(int signum)9*bcaeed49SFangrui Song void handler(int signum) {
10*bcaeed49SFangrui Song   write(2, "DONE\n", 5);
11*bcaeed49SFangrui Song   _exit(0);
12*bcaeed49SFangrui Song }
13*bcaeed49SFangrui Song 
thread(void * arg)14*bcaeed49SFangrui Song void *thread(void *arg) {
15*bcaeed49SFangrui Song   for (;;)
16*bcaeed49SFangrui Song     pause();
17*bcaeed49SFangrui Song   return 0;
18*bcaeed49SFangrui Song }
19*bcaeed49SFangrui Song 
main(int argc,char ** argv)20*bcaeed49SFangrui Song int main(int argc, char** argv) {
21*bcaeed49SFangrui Song   struct sigaction act = {};
22*bcaeed49SFangrui Song   act.sa_handler = &handler;
23*bcaeed49SFangrui Song   if (sigaction(SIGUSR1, &act, 0)) {
24*bcaeed49SFangrui Song     fprintf(stderr, "sigaction failed %d\n", errno);
25*bcaeed49SFangrui Song     return 1;
26*bcaeed49SFangrui Song   }
27*bcaeed49SFangrui Song   pthread_t th;
28*bcaeed49SFangrui Song   pthread_create(&th, 0, thread, 0);
29*bcaeed49SFangrui Song   sleep(1);  // give it time to block in pause
30*bcaeed49SFangrui Song   pthread_kill(th, SIGUSR1);
31*bcaeed49SFangrui Song   sleep(10);  // signal handler must exit the process while we are here
32*bcaeed49SFangrui Song   return 0;
33*bcaeed49SFangrui Song }
34*bcaeed49SFangrui Song 
35*bcaeed49SFangrui Song // CHECK: DONE
36