15d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines// RUN: %clang_tsan -O1 %s -o %t && %deflake %run %t | FileCheck %s
22d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines// Regression test for
32d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines// https://code.google.com/p/thread-sanitizer/issues/detail?id=61
42d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines// When the data race was reported, pthread_atfork() handler used to be
52d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines// executed which caused another race report in the same thread, which resulted
62d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines// in a deadlock.
72d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#include <pthread.h>
82d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#include <stdio.h>
92d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#include <unistd.h>
102d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
112d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hinesint glob = 0;
122d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
132d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hinesvoid *worker(void *unused) {
142d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  sleep(1);
152d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  glob++;
162d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  return NULL;
172d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines}
182d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
192d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hinesvoid atfork() {
202d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  fprintf(stderr, "ATFORK\n");
212d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  glob++;
222d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines}
232d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
242d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hinesint main() {
252d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  pthread_atfork(atfork, NULL, NULL);
262d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  pthread_t t;
272d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  pthread_create(&t, NULL, worker, NULL);
282d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  glob++;
292d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  pthread_join(t, NULL);
302d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  // CHECK: ThreadSanitizer: data race
312d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  // CHECK-NOT: ATFORK
322d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  return 0;
332d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines}
34