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 <atomic>
7#include <cstdio>
8#include <memory>
9
10std::atomic<long> destructor_counter(0);
11
12struct MyStruct {
13 virtual ~MyStruct() {
14 usleep(10000);
15 std::atomic_fetch_add_explicit(&destructor_counter, 1, std::memory_order_relaxed);
16 }
17};
18
19int main(int argc, const char *argv[]) {
20 std::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 std::abort();
37 }
38
39 std::fprintf(stderr, "Done.\n");
40}
41
42// CHECK: Hello world.
43// CHECK: Done.
44

source code of compiler-rt/test/tsan/libdispatch/groups-destructor.cpp