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