45 lines · c
1// RUN: %clang_tsan %s -o %t -undefined dynamic_lookup2// RUN: %run %t 2>&1 | FileCheck %s --implicit-check-not='ThreadSanitizer'3 4#include "dispatch/dispatch.h"5 6#include <stdio.h>7 8// Allow compilation with pre-macOS 10.14 (and aligned) SDKs9API_AVAILABLE(macos(10.14), ios(12.0), tvos(12.0), watchos(5.0))10DISPATCH_EXPORT DISPATCH_NONNULL_ALL DISPATCH_NOTHROW11void dispatch_async_and_wait(dispatch_queue_t queue,12 DISPATCH_NOESCAPE dispatch_block_t block);13 14long global;15 16int main() {17 // Guard execution on pre-macOS 10.14 (and aligned) platforms18 if (dispatch_async_and_wait == NULL) {19 fprintf(stderr, "Done.\n");20 return 0;21 }22 23 dispatch_queue_t q = dispatch_queue_create("my.queue", DISPATCH_QUEUE_SERIAL);24 dispatch_semaphore_t s = dispatch_semaphore_create(0);25 26 // Force queue to context switch onto separate thread.27 dispatch_async(q, ^{28 dispatch_semaphore_wait(s, DISPATCH_TIME_FOREVER);29 });30 dispatch_semaphore_signal(s);31 32 global++;33 dispatch_async_and_wait(q, ^{34 // The queue continues to execute on separate thread. This would cause a35 // race if we had used `dispatch_async()` without the `_and_wait` part.36 global++;37 });38 global++;39 40 fprintf(stderr, "Done.\n");41 return 0;42}43 44// CHECK: Done.45