Home | History | Annotate | Download | only in Darwin
      1 // RUN: %clang_tsan %s -o %t -framework Foundation
      2 // RUN: %env_tsan_opts=ignore_interceptors_accesses=1 %run %t 2>&1 | FileCheck %s
      3 
      4 #import <Foundation/Foundation.h>
      5 
      6 dispatch_queue_t queue;
      7 dispatch_data_t data;
      8 dispatch_semaphore_t sem;
      9 const char *path;
     10 
     11 long my_global = 0;
     12 
     13 void test_dispatch_io_write() {
     14   dispatch_io_t channel = dispatch_io_create_with_path(DISPATCH_IO_STREAM, path, O_CREAT | O_WRONLY, 0666, queue, ^(int error) { });
     15   if (! channel) abort();
     16   dispatch_io_set_high_water(channel, 1);
     17   
     18   my_global++;
     19   dispatch_io_write(channel, 0, data, queue, ^(bool done, dispatch_data_t remainingData, int error) {
     20     if (error) abort();
     21     my_global++;
     22     dispatch_async(queue, ^{
     23       my_global++;
     24       if (done) {
     25         dispatch_semaphore_signal(sem);
     26       }
     27     });
     28   });
     29   
     30   dispatch_semaphore_wait(sem, DISPATCH_TIME_FOREVER);
     31   my_global++;
     32   dispatch_io_close(channel, 0);
     33 }
     34 
     35 void test_dispatch_write() {
     36   dispatch_fd_t fd = open(path, O_CREAT | O_WRONLY, 0666);
     37   if (fd == -1) abort();
     38   
     39   my_global++;
     40   dispatch_write(fd, data, queue, ^(dispatch_data_t data, int error) {
     41     if (error) abort();
     42     my_global++;
     43     dispatch_async(queue, ^{
     44       my_global++;
     45       
     46       dispatch_semaphore_signal(sem);
     47     });
     48   });
     49   
     50   dispatch_semaphore_wait(sem, DISPATCH_TIME_FOREVER);
     51   my_global++;
     52   close(fd);
     53 }
     54 
     55 void test_dispatch_io_read() {
     56   dispatch_io_t channel = dispatch_io_create_with_path(DISPATCH_IO_STREAM, path, O_RDONLY,
     57                        0, queue, ^(int error) { });
     58   dispatch_io_set_high_water(channel, 1);
     59   
     60   my_global++;
     61   dispatch_io_read(channel, 0, SIZE_MAX, queue, ^(bool done, dispatch_data_t remainingData, int error) {
     62     if (error) abort();
     63     my_global++;
     64     dispatch_async(queue, ^{
     65       my_global++;
     66       if (done) {
     67         dispatch_semaphore_signal(sem);
     68       }
     69     });
     70   });
     71   
     72   dispatch_semaphore_wait(sem, DISPATCH_TIME_FOREVER);
     73   my_global++;
     74   dispatch_io_close(channel, 0);
     75 }
     76 
     77 void test_dispatch_read() {
     78   dispatch_fd_t fd = open(path, O_RDONLY, 0);
     79   if (fd == -1) abort();
     80   
     81   my_global++;
     82   dispatch_read(fd, SIZE_MAX, queue, ^(dispatch_data_t data, int error) {
     83     if (error) abort();
     84     my_global++;
     85     dispatch_async(queue, ^{
     86       my_global++;
     87       dispatch_semaphore_signal(sem);
     88     });
     89   });
     90   
     91   dispatch_semaphore_wait(sem, DISPATCH_TIME_FOREVER);
     92   my_global++;
     93   close(fd);
     94 }
     95 
     96 int main(int argc, const char *argv[]) {
     97   fprintf(stderr, "Hello world.\n");
     98   
     99   queue = dispatch_queue_create("my.queue", DISPATCH_QUEUE_SERIAL);
    100   sem = dispatch_semaphore_create(0);
    101   NSString *ns_path = [NSTemporaryDirectory() stringByAppendingPathComponent:[NSString stringWithFormat:@"temp-gcd-io.%d", getpid()]];
    102   path = ns_path.fileSystemRepresentation;
    103   NSData *ns_data = [NSMutableData dataWithLength:1000];
    104   data = dispatch_data_create(ns_data.bytes, ns_data.length, NULL, DISPATCH_DATA_DESTRUCTOR_DEFAULT);
    105   
    106   test_dispatch_io_write();
    107   test_dispatch_write();
    108   test_dispatch_io_read();
    109   test_dispatch_read();
    110   
    111   fprintf(stderr, "Done.\n");
    112   return 0;
    113 }
    114 
    115 // CHECK: Hello world.
    116 // CHECK-NOT: WARNING: ThreadSanitizer
    117 // CHECK: Done.
    118