1 // Copyright 2016 The Fuchsia Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #include <string.h>
6 
7 #include <zircon/syscalls.h>
8 #include <zircon/syscalls/object.h>
9 #include <unittest/unittest.h>
10 
check_signals_state(zx_handle_t h,zx_signals_t satisfied)11 static void check_signals_state(zx_handle_t h, zx_signals_t satisfied) {
12     zx_signals_t pending = 0;
13     EXPECT_EQ(zx_object_wait_one(h, 0u, 0u, &pending), ZX_ERR_TIMED_OUT, "wrong wait result");
14     EXPECT_EQ(pending, satisfied, "wrong satisfied state");
15 }
16 
create_test(void)17 static bool create_test(void) {
18     BEGIN_TEST;
19 
20     {
21         zx_handle_t h[2] = {ZX_HANDLE_INVALID, ZX_HANDLE_INVALID};
22         ASSERT_EQ(zx_eventpair_create(0, &h[0], &h[1]), ZX_OK, "eventpair_create failed");
23         ASSERT_NE(h[0], ZX_HANDLE_INVALID, "invalid handle from eventpair_create");
24         ASSERT_NE(h[1], ZX_HANDLE_INVALID, "invalid handle from eventpair_create");
25 
26         zx_info_handle_basic_t info[2] = {};
27         zx_status_t status = zx_object_get_info(h[0], ZX_INFO_HANDLE_BASIC, &info[0], sizeof(info[0]), NULL, NULL);
28         ASSERT_EQ(status, ZX_OK, "");
29         EXPECT_EQ(info[0].rights, ZX_RIGHTS_BASIC | ZX_RIGHT_SIGNAL | ZX_RIGHT_SIGNAL_PEER,
30                   "wrong rights");
31         EXPECT_EQ(info[0].type, (uint32_t)ZX_OBJ_TYPE_EVENTPAIR, "wrong type");
32         status = zx_object_get_info(h[1], ZX_INFO_HANDLE_BASIC, &info[1], sizeof(info[1]), NULL, NULL);
33         ASSERT_EQ(status, ZX_OK, "");
34         EXPECT_EQ(info[1].rights, ZX_RIGHTS_BASIC | ZX_RIGHT_SIGNAL | ZX_RIGHT_SIGNAL_PEER,
35                   "wrong rights");
36         EXPECT_EQ(info[1].type, (uint32_t)ZX_OBJ_TYPE_EVENTPAIR, "wrong type");
37 
38 
39         // Check that koids line up.
40         ASSERT_NE(info[0].koid, 0u, "zero koid!");
41         ASSERT_NE(info[0].related_koid, 0u, "zero peer koid!");
42         ASSERT_NE(info[1].koid, 0u, "zero koid!");
43         ASSERT_NE(info[1].related_koid, 0u, "zero peer koid!");
44         ASSERT_EQ(info[0].koid, info[1].related_koid, "mismatched koids!");
45         ASSERT_EQ(info[1].koid, info[0].related_koid, "mismatched koids!");
46 
47         EXPECT_EQ(zx_handle_close(h[0]), ZX_OK, "failed to close event pair handle");
48         EXPECT_EQ(zx_handle_close(h[1]), ZX_OK, "failed to close event pair handle");
49     }
50 
51     // Currently no flags are supported.
52     {
53         zx_handle_t h[2] = {ZX_HANDLE_INVALID, ZX_HANDLE_INVALID};
54         EXPECT_EQ(zx_eventpair_create(1u, &h[0], &h[1]), ZX_ERR_NOT_SUPPORTED, "eventpair_create failed to fail");
55         EXPECT_EQ(h[0], ZX_HANDLE_INVALID, "valid handle from failed eventpair_create?");
56         EXPECT_EQ(h[1], ZX_HANDLE_INVALID, "valid handle from failed eventpair_create?");
57     }
58 
59     END_TEST;
60 }
61 
signal_test(void)62 static bool signal_test(void) {
63     BEGIN_TEST;
64     zx_handle_t h[2] = {ZX_HANDLE_INVALID, ZX_HANDLE_INVALID};
65     ASSERT_EQ(zx_eventpair_create(0, &h[0], &h[1]), ZX_OK, "eventpair_create failed");
66     ASSERT_NE(h[0], ZX_HANDLE_INVALID, "invalid handle from eventpair_create");
67     ASSERT_NE(h[1], ZX_HANDLE_INVALID, "invalid handle from eventpair_create");
68 
69     check_signals_state(h[0], 0u);
70     check_signals_state(h[1], 0u);
71 
72     EXPECT_EQ(zx_object_signal(h[0], 0u, ZX_USER_SIGNAL_0), ZX_OK, "object_signal failed");
73     check_signals_state(h[1], 0u);
74     check_signals_state(h[0], ZX_USER_SIGNAL_0);
75 
76     EXPECT_EQ(zx_object_signal(h[0], ZX_USER_SIGNAL_0, 0u), ZX_OK, "object_signal failed");
77     check_signals_state(h[1], 0u);
78     check_signals_state(h[0], 0u);
79 
80     EXPECT_EQ(zx_handle_close(h[0]), ZX_OK, "failed to close event pair handle");
81     check_signals_state(h[1], ZX_EVENTPAIR_PEER_CLOSED);
82     EXPECT_EQ(zx_handle_close(h[1]), ZX_OK, "failed to close event pair handle");
83     END_TEST;
84 }
85 
signal_peer_test(void)86 static bool signal_peer_test(void) {
87     BEGIN_TEST;
88 
89     zx_handle_t h[2] = {ZX_HANDLE_INVALID, ZX_HANDLE_INVALID};
90     ASSERT_EQ(zx_eventpair_create(0, &h[0], &h[1]), ZX_OK, "eventpair_create failed");
91     ASSERT_NE(h[0], ZX_HANDLE_INVALID, "invalid handle from eventpair_create");
92     ASSERT_NE(h[1], ZX_HANDLE_INVALID, "invalid handle from eventpair_create");
93 
94     EXPECT_EQ(zx_object_signal_peer(h[0], 0u, ZX_USER_SIGNAL_0), ZX_OK, "object_signal failed");
95     check_signals_state(h[0], 0u);
96     check_signals_state(h[1], ZX_USER_SIGNAL_0);
97 
98     EXPECT_EQ(zx_object_signal_peer(h[1], 0u, ZX_USER_SIGNAL_1 | ZX_USER_SIGNAL_2), ZX_OK,
99               "object_signal failed");
100     check_signals_state(h[0], ZX_USER_SIGNAL_1 | ZX_USER_SIGNAL_2);
101     check_signals_state(h[1], ZX_USER_SIGNAL_0);
102 
103     EXPECT_EQ(zx_object_signal_peer(h[0], ZX_USER_SIGNAL_0, ZX_USER_SIGNAL_3 | ZX_USER_SIGNAL_4),
104               ZX_OK, "object_signal failed");
105     check_signals_state(h[0], ZX_USER_SIGNAL_1 | ZX_USER_SIGNAL_2);
106     check_signals_state(h[1], ZX_USER_SIGNAL_3 | ZX_USER_SIGNAL_4);
107 
108     EXPECT_EQ(zx_handle_close(h[0]), ZX_OK, "failed to close event pair handle");
109 
110     // Signaled flags should remain satisfied but now should now also get peer closed (and
111     // unsignaled flags should be unsatisfiable).
112     check_signals_state(h[1],
113         ZX_EVENTPAIR_PEER_CLOSED | ZX_USER_SIGNAL_3 | ZX_USER_SIGNAL_4);
114 
115     EXPECT_EQ(zx_handle_close(h[1]), ZX_OK, "failed to close event pair handle");
116 
117     END_TEST;
118 }
119 
signal_peer_closed_test(void)120 static bool signal_peer_closed_test(void) {
121     BEGIN_TEST;
122 
123     zx_handle_t eventpair[2];
124     ASSERT_EQ(zx_eventpair_create(0, &eventpair[0], &eventpair[1]), ZX_OK, "");
125     ASSERT_EQ(zx_handle_close(eventpair[1]), ZX_OK, "");
126     ASSERT_EQ(zx_object_signal_peer(eventpair[0], 0u, ZX_USER_SIGNAL_0), ZX_ERR_PEER_CLOSED, "");
127     ASSERT_EQ(zx_handle_close(eventpair[0]), ZX_OK, "");
128 
129     END_TEST;
130 }
131 
132 BEGIN_TEST_CASE(eventpair_tests)
RUN_TEST(create_test)133 RUN_TEST(create_test)
134 RUN_TEST(signal_test)
135 RUN_TEST(signal_peer_test)
136 RUN_TEST(signal_peer_closed_test)
137 END_TEST_CASE(eventpair_tests)
138 
139 #ifndef BUILD_COMBINED_TESTS
140 int main(int argc, char** argv) {
141     return unittest_run_all_tests(argc, argv) ? 0 : -1;
142 }
143 #endif
144