xref: /llvm-project/compiler-rt/test/tsan/libdispatch/fd.c (revision a59dad920ffb7a01f8e275ac4b6596048621fd20)
1 // RUN: %clang_tsan %s -o %t
2 // RUN: %run %t 2>&1 | FileCheck %s --implicit-check-not='ThreadSanitizer'
3 
4 #include <dispatch/dispatch.h>
5 
6 #include <stdio.h>
7 
8 long my_global = 0;
9 
main(int argc,const char * argv[])10 int main(int argc, const char *argv[]) {
11   fprintf(stderr, "Hello world.\n");
12 
13   dispatch_queue_t queue = dispatch_queue_create("my.queue", DISPATCH_QUEUE_SERIAL);
14   dispatch_semaphore_t sem = dispatch_semaphore_create(0);
15 
16   const char *path = tempnam(NULL, "libdispatch-fd-");
17 
18   dispatch_io_t channel = dispatch_io_create_with_path(DISPATCH_IO_STREAM, path, O_CREAT | O_WRONLY,
19       0666, queue, ^(int error) { });
20   dispatch_io_set_high_water(channel, 1);
21 
22   char buf[1000];
23   dispatch_data_t data = dispatch_data_create(buf, sizeof(buf), NULL, DISPATCH_DATA_DESTRUCTOR_DEFAULT);
24 
25   my_global++;
26   dispatch_io_write(channel, 0, data, queue, ^(bool done, dispatch_data_t remainingData, int error) {
27     my_global++;
28     dispatch_async(queue, ^{
29       my_global++;
30       if (done) {
31         dispatch_semaphore_signal(sem);
32       }
33     });
34   });
35 
36   dispatch_semaphore_wait(sem, DISPATCH_TIME_FOREVER);
37   my_global++;
38   dispatch_io_close(channel, 0);
39   channel = dispatch_io_create_with_path(DISPATCH_IO_STREAM, path, O_RDONLY,
40       0, queue, ^(int error) { });
41   dispatch_io_set_high_water(channel, 1);
42 
43   my_global++;
44   dispatch_io_read(channel, 0, SIZE_MAX, queue, ^(bool done, dispatch_data_t remainingData, int error) {
45     my_global++;
46     dispatch_async(queue, ^{
47       my_global++;
48       if (done) {
49         dispatch_semaphore_signal(sem);
50       }
51     });
52   });
53 
54   dispatch_semaphore_wait(sem, DISPATCH_TIME_FOREVER);
55   my_global++;
56   fprintf(stderr, "Done.\n");
57   return 0;
58 }
59 
60 // CHECK: Hello world.
61 // CHECK: Done.
62