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#include <stdlib.h>
8
9dispatch_queue_t queue;
10dispatch_data_t data;
11dispatch_semaphore_t sem;
12const char *path;
13
14long my_global = 0;
15
16void test_dispatch_io_write() {
17 dispatch_io_t channel = dispatch_io_create_with_path(DISPATCH_IO_STREAM, path, O_CREAT | O_WRONLY, 0666, queue, ^(int error) { });
18 if (! channel) abort();
19 dispatch_io_set_high_water(channel, 1);
20
21 my_global++;
22 dispatch_io_write(channel, 0, data, queue, ^(bool done, dispatch_data_t remainingData, int error) {
23 if (error) abort();
24 my_global++;
25 dispatch_async(queue, ^{
26 my_global++;
27 if (done) {
28 dispatch_semaphore_signal(sem);
29 }
30 });
31 });
32
33 dispatch_semaphore_wait(sem, DISPATCH_TIME_FOREVER);
34 my_global++;
35 dispatch_io_close(channel, 0);
36}
37
38void test_dispatch_write() {
39 dispatch_fd_t fd = open(path, O_CREAT | O_WRONLY, 0666);
40 if (fd == -1) abort();
41
42 my_global++;
43 dispatch_write(fd, data, queue, ^(dispatch_data_t data, int error) {
44 if (error) abort();
45 my_global++;
46 dispatch_async(queue, ^{
47 my_global++;
48
49 dispatch_semaphore_signal(sem);
50 });
51 });
52
53 dispatch_semaphore_wait(sem, DISPATCH_TIME_FOREVER);
54 my_global++;
55 close(fd);
56}
57
58void test_dispatch_io_read() {
59 dispatch_io_t channel = dispatch_io_create_with_path(DISPATCH_IO_STREAM, path, O_RDONLY,
60 0, queue, ^(int error) { });
61 dispatch_io_set_high_water(channel, 1);
62
63 my_global++;
64 dispatch_io_read(channel, 0, SIZE_MAX, queue, ^(bool done, dispatch_data_t remainingData, int error) {
65 if (error) abort();
66 my_global++;
67 dispatch_async(queue, ^{
68 my_global++;
69 if (done) {
70 dispatch_semaphore_signal(sem);
71 }
72 });
73 });
74
75 dispatch_semaphore_wait(sem, DISPATCH_TIME_FOREVER);
76 my_global++;
77 dispatch_io_close(channel, 0);
78}
79
80void test_dispatch_read() {
81 dispatch_fd_t fd = open(path, O_RDONLY, 0);
82 if (fd == -1) abort();
83
84 my_global++;
85 dispatch_read(fd, SIZE_MAX, queue, ^(dispatch_data_t data, int error) {
86 if (error) abort();
87 my_global++;
88 dispatch_async(queue, ^{
89 my_global++;
90 dispatch_semaphore_signal(sem);
91 });
92 });
93
94 dispatch_semaphore_wait(sem, DISPATCH_TIME_FOREVER);
95 my_global++;
96 close(fd);
97}
98
99int main(int argc, const char *argv[]) {
100 fprintf(stderr, format: "Hello world.\n");
101
102 queue = dispatch_queue_create("my.queue", DISPATCH_QUEUE_SERIAL);
103 sem = dispatch_semaphore_create(0);
104 path = tempnam(NULL, pfx: "libdispatch-io-");
105 char buf[1000];
106 data = dispatch_data_create(buf, sizeof(buf), NULL, DISPATCH_DATA_DESTRUCTOR_DEFAULT);
107
108 test_dispatch_io_write();
109 test_dispatch_write();
110 test_dispatch_io_read();
111 test_dispatch_read();
112
113 fprintf(stderr, format: "Done.\n");
114 return 0;
115}
116
117// CHECK: Hello world.
118// CHECK: Done.
119

source code of compiler-rt/test/tsan/libdispatch/io.c