1*7c3d14c8STreehugger Robot// RUN: %clang_tsan %s -o %t -framework Foundation 2*7c3d14c8STreehugger Robot// RUN: %env_tsan_opts=ignore_interceptors_accesses=1 %deflake %run %t 2>&1 | FileCheck %s 3*7c3d14c8STreehugger Robot 4*7c3d14c8STreehugger Robot#import <Foundation/Foundation.h> 5*7c3d14c8STreehugger Robot#import <xpc/xpc.h> 6*7c3d14c8STreehugger Robot 7*7c3d14c8STreehugger Robot#import "../test.h" 8*7c3d14c8STreehugger Robot 9*7c3d14c8STreehugger Robotlong global; 10*7c3d14c8STreehugger Robot 11*7c3d14c8STreehugger Robotlong received_msgs; 12*7c3d14c8STreehugger Robotxpc_connection_t server_conn; 13*7c3d14c8STreehugger Robotxpc_connection_t client_conns[2]; 14*7c3d14c8STreehugger Robot 15*7c3d14c8STreehugger Robotint main(int argc, const char *argv[]) { 16*7c3d14c8STreehugger Robot @autoreleasepool { 17*7c3d14c8STreehugger Robot NSLog(@"Hello world."); 18*7c3d14c8STreehugger Robot barrier_init(&barrier, 2); 19*7c3d14c8STreehugger Robot 20*7c3d14c8STreehugger Robot dispatch_queue_t server_q = dispatch_queue_create("server.queue", DISPATCH_QUEUE_CONCURRENT); 21*7c3d14c8STreehugger Robot 22*7c3d14c8STreehugger Robot server_conn = xpc_connection_create(NULL, server_q); 23*7c3d14c8STreehugger Robot 24*7c3d14c8STreehugger Robot xpc_connection_set_event_handler(server_conn, ^(xpc_object_t client) { 25*7c3d14c8STreehugger Robot NSLog(@"server event handler, client = %@", client); 26*7c3d14c8STreehugger Robot 27*7c3d14c8STreehugger Robot if (client == XPC_ERROR_CONNECTION_INTERRUPTED || client == XPC_ERROR_CONNECTION_INVALID) { 28*7c3d14c8STreehugger Robot return; 29*7c3d14c8STreehugger Robot } 30*7c3d14c8STreehugger Robot xpc_connection_set_event_handler(client, ^(xpc_object_t object) { 31*7c3d14c8STreehugger Robot NSLog(@"received message: %@", object); 32*7c3d14c8STreehugger Robot 33*7c3d14c8STreehugger Robot barrier_wait(&barrier); 34*7c3d14c8STreehugger Robot global = 42; 35*7c3d14c8STreehugger Robot 36*7c3d14c8STreehugger Robot dispatch_sync(dispatch_get_main_queue(), ^{ 37*7c3d14c8STreehugger Robot received_msgs++; 38*7c3d14c8STreehugger Robot 39*7c3d14c8STreehugger Robot if (received_msgs >= 2) { 40*7c3d14c8STreehugger Robot xpc_connection_cancel(client_conns[0]); 41*7c3d14c8STreehugger Robot xpc_connection_cancel(client_conns[1]); 42*7c3d14c8STreehugger Robot xpc_connection_cancel(server_conn); 43*7c3d14c8STreehugger Robot CFRunLoopStop(CFRunLoopGetCurrent()); 44*7c3d14c8STreehugger Robot } 45*7c3d14c8STreehugger Robot }); 46*7c3d14c8STreehugger Robot }); 47*7c3d14c8STreehugger Robot 48*7c3d14c8STreehugger Robot xpc_connection_resume(client); 49*7c3d14c8STreehugger Robot }); 50*7c3d14c8STreehugger Robot xpc_connection_resume(server_conn); 51*7c3d14c8STreehugger Robot xpc_endpoint_t endpoint = xpc_endpoint_create(server_conn); 52*7c3d14c8STreehugger Robot 53*7c3d14c8STreehugger Robot for (int i = 0; i < 2; i++) { 54*7c3d14c8STreehugger Robot client_conns[i] = xpc_connection_create_from_endpoint(endpoint); 55*7c3d14c8STreehugger Robot xpc_connection_set_event_handler(client_conns[i], ^(xpc_object_t event) { 56*7c3d14c8STreehugger Robot NSLog(@"client event handler, event = %@", event); 57*7c3d14c8STreehugger Robot }); 58*7c3d14c8STreehugger Robot 59*7c3d14c8STreehugger Robot xpc_object_t msg = xpc_dictionary_create(NULL, NULL, 0); 60*7c3d14c8STreehugger Robot xpc_dictionary_set_string(msg, "hello", "world"); 61*7c3d14c8STreehugger Robot NSLog(@"sending message: %@", msg); 62*7c3d14c8STreehugger Robot 63*7c3d14c8STreehugger Robot xpc_connection_send_message(client_conns[i], msg); 64*7c3d14c8STreehugger Robot xpc_connection_resume(client_conns[i]); 65*7c3d14c8STreehugger Robot } 66*7c3d14c8STreehugger Robot 67*7c3d14c8STreehugger Robot CFRunLoopRun(); 68*7c3d14c8STreehugger Robot 69*7c3d14c8STreehugger Robot NSLog(@"Done."); 70*7c3d14c8STreehugger Robot } 71*7c3d14c8STreehugger Robot return 0; 72*7c3d14c8STreehugger Robot} 73*7c3d14c8STreehugger Robot 74*7c3d14c8STreehugger Robot// CHECK: Hello world. 75*7c3d14c8STreehugger Robot// CHECK: WARNING: ThreadSanitizer: data race 76*7c3d14c8STreehugger Robot// CHECK: Write of size 8 77*7c3d14c8STreehugger Robot// CHECK: #0 {{.*}}xpc-race.mm:34 78*7c3d14c8STreehugger Robot// CHECK: Previous write of size 8 79*7c3d14c8STreehugger Robot// CHECK: #0 {{.*}}xpc-race.mm:34 80*7c3d14c8STreehugger Robot// CHECK: Location is global 'global' 81*7c3d14c8STreehugger Robot// CHECK: Done. 82