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 11static 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 17static 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, 30 ZX_RIGHTS_BASIC | ZX_RIGHT_READ | 31 ZX_RIGHT_WRITE | ZX_RIGHT_SIGNAL | ZX_RIGHT_SIGNAL_PEER, 32 "wrong rights"); 33 EXPECT_EQ(info[0].type, (uint32_t)ZX_OBJ_TYPE_EVENTPAIR, "wrong type"); 34 status = zx_object_get_info(h[1], ZX_INFO_HANDLE_BASIC, &info[1], sizeof(info[1]), NULL, NULL); 35 ASSERT_EQ(status, ZX_OK, ""); 36 EXPECT_EQ(info[1].rights, 37 ZX_RIGHTS_BASIC | ZX_RIGHT_READ | 38 ZX_RIGHT_WRITE | ZX_RIGHT_SIGNAL | ZX_RIGHT_SIGNAL_PEER, 39 "wrong rights"); 40 EXPECT_EQ(info[1].type, (uint32_t)ZX_OBJ_TYPE_EVENTPAIR, "wrong type"); 41 42 43 // Check that koids line up. 44 ASSERT_NE(info[0].koid, 0u, "zero koid!"); 45 ASSERT_NE(info[0].related_koid, 0u, "zero peer koid!"); 46 ASSERT_NE(info[1].koid, 0u, "zero koid!"); 47 ASSERT_NE(info[1].related_koid, 0u, "zero peer koid!"); 48 ASSERT_EQ(info[0].koid, info[1].related_koid, "mismatched koids!"); 49 ASSERT_EQ(info[1].koid, info[0].related_koid, "mismatched koids!"); 50 51 EXPECT_EQ(zx_handle_close(h[0]), ZX_OK, "failed to close event pair handle"); 52 EXPECT_EQ(zx_handle_close(h[1]), ZX_OK, "failed to close event pair handle"); 53 } 54 55 // Currently no flags are supported. 56 { 57 zx_handle_t h[2] = {ZX_HANDLE_INVALID, ZX_HANDLE_INVALID}; 58 EXPECT_EQ(zx_eventpair_create(1u, &h[0], &h[1]), ZX_ERR_NOT_SUPPORTED, "eventpair_create failed to fail"); 59 EXPECT_EQ(h[0], ZX_HANDLE_INVALID, "valid handle from failed eventpair_create?"); 60 EXPECT_EQ(h[1], ZX_HANDLE_INVALID, "valid handle from failed eventpair_create?"); 61 } 62 63 END_TEST; 64} 65 66static bool signal_test(void) { 67 BEGIN_TEST; 68 zx_handle_t h[2] = {ZX_HANDLE_INVALID, ZX_HANDLE_INVALID}; 69 ASSERT_EQ(zx_eventpair_create(0, &h[0], &h[1]), ZX_OK, "eventpair_create failed"); 70 ASSERT_NE(h[0], ZX_HANDLE_INVALID, "invalid handle from eventpair_create"); 71 ASSERT_NE(h[1], ZX_HANDLE_INVALID, "invalid handle from eventpair_create"); 72 73 check_signals_state(h[0], 0u); 74 check_signals_state(h[1], 0u); 75 76 EXPECT_EQ(zx_object_signal(h[0], 0u, ZX_USER_SIGNAL_0), ZX_OK, "object_signal failed"); 77 check_signals_state(h[1], 0u); 78 check_signals_state(h[0], ZX_USER_SIGNAL_0); 79 80 EXPECT_EQ(zx_object_signal(h[0], ZX_USER_SIGNAL_0, 0u), ZX_OK, "object_signal failed"); 81 check_signals_state(h[1], 0u); 82 check_signals_state(h[0], 0u); 83 84 EXPECT_EQ(zx_handle_close(h[0]), ZX_OK, "failed to close event pair handle"); 85 check_signals_state(h[1], ZX_EVENTPAIR_PEER_CLOSED); 86 EXPECT_EQ(zx_handle_close(h[1]), ZX_OK, "failed to close event pair handle"); 87 END_TEST; 88} 89 90static bool signal_peer_test(void) { 91 BEGIN_TEST; 92 93 zx_handle_t h[2] = {ZX_HANDLE_INVALID, ZX_HANDLE_INVALID}; 94 ASSERT_EQ(zx_eventpair_create(0, &h[0], &h[1]), ZX_OK, "eventpair_create failed"); 95 ASSERT_NE(h[0], ZX_HANDLE_INVALID, "invalid handle from eventpair_create"); 96 ASSERT_NE(h[1], ZX_HANDLE_INVALID, "invalid handle from eventpair_create"); 97 98 EXPECT_EQ(zx_object_signal_peer(h[0], 0u, ZX_USER_SIGNAL_0), ZX_OK, "object_signal failed"); 99 check_signals_state(h[0], 0u); 100 check_signals_state(h[1], ZX_USER_SIGNAL_0); 101 102 EXPECT_EQ(zx_object_signal_peer(h[1], 0u, ZX_USER_SIGNAL_1 | ZX_USER_SIGNAL_2), ZX_OK, 103 "object_signal failed"); 104 check_signals_state(h[0], ZX_USER_SIGNAL_1 | ZX_USER_SIGNAL_2); 105 check_signals_state(h[1], ZX_USER_SIGNAL_0); 106 107 EXPECT_EQ(zx_object_signal_peer(h[0], ZX_USER_SIGNAL_0, ZX_USER_SIGNAL_3 | ZX_USER_SIGNAL_4), 108 ZX_OK, "object_signal failed"); 109 check_signals_state(h[0], ZX_USER_SIGNAL_1 | ZX_USER_SIGNAL_2); 110 check_signals_state(h[1], ZX_USER_SIGNAL_3 | ZX_USER_SIGNAL_4); 111 112 EXPECT_EQ(zx_handle_close(h[0]), ZX_OK, "failed to close event pair handle"); 113 114 // Signaled flags should remain satisfied but now should now also get peer closed (and 115 // unsignaled flags should be unsatisfiable). 116 check_signals_state(h[1], 117 ZX_EVENTPAIR_PEER_CLOSED | ZX_USER_SIGNAL_3 | ZX_USER_SIGNAL_4); 118 119 EXPECT_EQ(zx_handle_close(h[1]), ZX_OK, "failed to close event pair handle"); 120 121 END_TEST; 122} 123 124static bool signal_peer_closed_test(void) { 125 BEGIN_TEST; 126 127 zx_handle_t eventpair[2]; 128 ASSERT_EQ(zx_eventpair_create(0, &eventpair[0], &eventpair[1]), ZX_OK, ""); 129 ASSERT_EQ(zx_handle_close(eventpair[1]), ZX_OK, ""); 130 ASSERT_EQ(zx_object_signal_peer(eventpair[0], 0u, ZX_USER_SIGNAL_0), ZX_ERR_PEER_CLOSED, ""); 131 ASSERT_EQ(zx_handle_close(eventpair[0]), ZX_OK, ""); 132 133 END_TEST; 134} 135 136BEGIN_TEST_CASE(eventpair_tests) 137RUN_TEST(create_test) 138RUN_TEST(signal_test) 139RUN_TEST(signal_peer_test) 140RUN_TEST(signal_peer_closed_test) 141END_TEST_CASE(eventpair_tests) 142 143#ifndef BUILD_COMBINED_TESTS 144int main(int argc, char** argv) { 145 return unittest_run_all_tests(argc, argv) ? 0 : -1; 146} 147#endif 148