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