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