1 // RUN: %clangxx_tsan %s %link_libcxx_tsan -o %t
2 // RUN: %run %t 2>&1 | FileCheck %s --implicit-check-not='ThreadSanitizer'
3 
4 #include <dispatch/dispatch.h>
5 
6 #include <memory>
7 #include <stdatomic.h>
8 #include <cstdio>
9 
10 _Atomic(long) destructor_counter = 0;
11 
12 struct MyStruct {
~MyStructMyStruct13   virtual ~MyStruct() {
14     usleep(10000);
15     atomic_fetch_add_explicit(&destructor_counter, 1, memory_order_relaxed);
16   }
17 };
18 
main(int argc,const char * argv[])19 int main(int argc, const char *argv[]) {
20   fprintf(stderr, "Hello world.\n");
21 
22   dispatch_queue_t q = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
23   dispatch_group_t g = dispatch_group_create();
24 
25   for (int i = 0; i < 100; i++) {
26     std::shared_ptr<MyStruct> shared(new MyStruct());
27 
28     dispatch_group_async(g, q, ^{
29       shared.get(); // just to make sure the object is captured by the block
30     });
31   }
32 
33   dispatch_group_wait(g, DISPATCH_TIME_FOREVER);
34 
35   if (destructor_counter != 100) {
36     abort();
37   }
38 
39   fprintf(stderr, "Done.\n");
40 }
41 
42 // CHECK: Hello world.
43 // CHECK: Done.
44