1*7c3d14c8STreehugger Robot// RUN: %clang_tsan %s -o %t -framework Foundation 2*7c3d14c8STreehugger Robot// RUN: %env_tsan_opts=ignore_interceptors_accesses=1 %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 Robotlong global; 8*7c3d14c8STreehugger Robot 9*7c3d14c8STreehugger Robotint main(int argc, const char *argv[]) { 10*7c3d14c8STreehugger Robot @autoreleasepool { 11*7c3d14c8STreehugger Robot NSLog(@"Hello world."); 12*7c3d14c8STreehugger Robot 13*7c3d14c8STreehugger Robot dispatch_queue_t server_q = dispatch_queue_create("server.queue", DISPATCH_QUEUE_CONCURRENT); 14*7c3d14c8STreehugger Robot dispatch_queue_t client_q = dispatch_queue_create("client.queue", DISPATCH_QUEUE_CONCURRENT); 15*7c3d14c8STreehugger Robot 16*7c3d14c8STreehugger Robot xpc_connection_t server_conn = xpc_connection_create(NULL, server_q); 17*7c3d14c8STreehugger Robot 18*7c3d14c8STreehugger Robot global = 42; 19*7c3d14c8STreehugger Robot 20*7c3d14c8STreehugger Robot xpc_connection_set_event_handler(server_conn, ^(xpc_object_t client) { 21*7c3d14c8STreehugger Robot NSLog(@"global = %ld", global); 22*7c3d14c8STreehugger Robot NSLog(@"server event handler, client = %@", client); 23*7c3d14c8STreehugger Robot 24*7c3d14c8STreehugger Robot if (client == XPC_ERROR_CONNECTION_INTERRUPTED || client == XPC_ERROR_CONNECTION_INVALID) { 25*7c3d14c8STreehugger Robot return; 26*7c3d14c8STreehugger Robot } 27*7c3d14c8STreehugger Robot xpc_connection_set_event_handler(client, ^(xpc_object_t object) { 28*7c3d14c8STreehugger Robot NSLog(@"received message: %@", object); 29*7c3d14c8STreehugger Robot 30*7c3d14c8STreehugger Robot xpc_object_t reply = xpc_dictionary_create_reply(object); 31*7c3d14c8STreehugger Robot if (!reply) 32*7c3d14c8STreehugger Robot return; 33*7c3d14c8STreehugger Robot xpc_dictionary_set_string(reply, "reply", "value"); 34*7c3d14c8STreehugger Robot 35*7c3d14c8STreehugger Robot xpc_connection_t remote = xpc_dictionary_get_remote_connection(object); 36*7c3d14c8STreehugger Robot xpc_connection_send_message(remote, reply); 37*7c3d14c8STreehugger Robot }); 38*7c3d14c8STreehugger Robot 39*7c3d14c8STreehugger Robot xpc_connection_resume(client); 40*7c3d14c8STreehugger Robot }); 41*7c3d14c8STreehugger Robot xpc_connection_resume(server_conn); 42*7c3d14c8STreehugger Robot xpc_endpoint_t endpoint = xpc_endpoint_create(server_conn); 43*7c3d14c8STreehugger Robot 44*7c3d14c8STreehugger Robot xpc_connection_t client_conn = xpc_connection_create_from_endpoint(endpoint); 45*7c3d14c8STreehugger Robot xpc_connection_set_event_handler(client_conn, ^(xpc_object_t event) { 46*7c3d14c8STreehugger Robot NSLog(@"client event handler, event = %@", event); 47*7c3d14c8STreehugger Robot }); 48*7c3d14c8STreehugger Robot 49*7c3d14c8STreehugger Robot xpc_object_t msg = xpc_dictionary_create(NULL, NULL, 0); 50*7c3d14c8STreehugger Robot xpc_dictionary_set_string(msg, "hello", "world"); 51*7c3d14c8STreehugger Robot NSLog(@"sending message: %@", msg); 52*7c3d14c8STreehugger Robot 53*7c3d14c8STreehugger Robot xpc_connection_send_message_with_reply( 54*7c3d14c8STreehugger Robot client_conn, msg, client_q, ^(xpc_object_t object) { 55*7c3d14c8STreehugger Robot NSLog(@"received reply: %@", object); 56*7c3d14c8STreehugger Robot 57*7c3d14c8STreehugger Robot xpc_connection_cancel(client_conn); 58*7c3d14c8STreehugger Robot xpc_connection_cancel(server_conn); 59*7c3d14c8STreehugger Robot 60*7c3d14c8STreehugger Robot dispatch_sync(dispatch_get_main_queue(), ^{ 61*7c3d14c8STreehugger Robot CFRunLoopStop(CFRunLoopGetCurrent()); 62*7c3d14c8STreehugger Robot }); 63*7c3d14c8STreehugger Robot }); 64*7c3d14c8STreehugger Robot xpc_connection_resume(client_conn); 65*7c3d14c8STreehugger Robot 66*7c3d14c8STreehugger Robot CFRunLoopRun(); 67*7c3d14c8STreehugger Robot 68*7c3d14c8STreehugger Robot NSLog(@"Done."); 69*7c3d14c8STreehugger Robot } 70*7c3d14c8STreehugger Robot return 0; 71*7c3d14c8STreehugger Robot} 72*7c3d14c8STreehugger Robot 73*7c3d14c8STreehugger Robot// CHECK: Done. 74*7c3d14c8STreehugger Robot// CHECK-NOT: WARNING: ThreadSanitizer 75