1// Check that calling dispatch_once from a report callback works.
2
3// RUN: %clang_tsan %s -o %t -framework Foundation
4// RUN: %env_tsan_opts=ignore_interceptors_accesses=1 not %run %t 2>&1 | FileCheck %s
5
6#import <Foundation/Foundation.h>
7#import <pthread.h>
8
9long g = 0;
10long h = 0;
11void f() {
12  static dispatch_once_t onceToken;
13  dispatch_once(&onceToken, ^{
14    g++;
15  });
16  h++;
17}
18
19extern "C" void __tsan_on_report() {
20  fprintf(stderr, "Report.\n");
21  f();
22}
23
24int main() {
25  fprintf(stderr, "Hello world.\n");
26
27  f();
28
29  pthread_mutex_t mutex = {0};
30  pthread_mutex_lock(&mutex);
31
32  fprintf(stderr, "g = %ld.\n", g);
33  fprintf(stderr, "h = %ld.\n", h);
34  fprintf(stderr, "Done.\n");
35}
36
37// CHECK: Hello world.
38// CHECK: Report.
39// CHECK: g = 1
40// CHECK: h = 2
41// CHECK: Done.
42