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