60 lines · c
1// RUN: %clang_tsan -O1 %s -o %t && %run %t 2>&1 | FileCheck %s2 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(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(&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(1000000);42 43 // Signal the thread, this should run the signal handler and unblock the read44 // below.45 pthread_kill(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, "PASS\n");55 return 0;56}57 58// CHECK-NOT: WARNING: ThreadSanitizer:59// CHECK: PASS60