1// Copyright 2018 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 <unittest/unittest.h> 6 7#include <zircon/syscalls.h> 8#include <zircon/syscalls/object.h> 9 10#define kNumEventpairs 4u 11#define kGap 2u 12 13static bool handle_close_many_test(void) { 14 BEGIN_TEST; 15 16 // Layout: 0 1 2 3 : 0 1 2 3 17 zx_handle_t eventpairs[kNumEventpairs * 2]; 18 19 for (size_t idx = 0u; idx < kNumEventpairs; ++idx) { 20 ASSERT_EQ(zx_eventpair_create(0u, &eventpairs[idx], &eventpairs[idx + kNumEventpairs]), ZX_OK, ""); 21 } 22 23 ASSERT_EQ(zx_handle_close_many(&eventpairs[0u], kNumEventpairs), ZX_OK, ""); 24 25 // Assert that every handle in the preceeding close call was in 26 // fact closed, by waiting on the PEER_CLOSED signal. 27 for (size_t idx = kNumEventpairs; idx < 8u; ++idx) { 28 zx_signals_t signals; 29 ASSERT_EQ(zx_object_wait_one(eventpairs[idx], ZX_EVENTPAIR_PEER_CLOSED, 30 0u, &signals), ZX_OK, ""); 31 ASSERT_EQ(signals & ZX_EVENTPAIR_PEER_CLOSED, ZX_EVENTPAIR_PEER_CLOSED, ""); 32 } 33 34 ASSERT_EQ(zx_handle_close_many(&eventpairs[kNumEventpairs], kNumEventpairs), ZX_OK, ""); 35 36 END_TEST; 37} 38 39static bool handle_close_many_invalid_test(void) { 40 BEGIN_TEST; 41 42 // Layout: 0 1 2 3 : invalid invalid : 0 1 2 3 43 zx_handle_t eventpairs[kNumEventpairs * 2 + kGap]; 44 45 for (size_t idx = 0u; idx < kNumEventpairs; ++idx) { 46 ASSERT_EQ(zx_eventpair_create(0u, &eventpairs[idx], 47 &eventpairs[idx + kNumEventpairs + kGap]), ZX_OK, ""); 48 } 49 eventpairs[kNumEventpairs] = ZX_HANDLE_INVALID; 50 eventpairs[kNumEventpairs + 1] = ZX_HANDLE_INVALID; 51 52 ASSERT_EQ(zx_handle_close_many(&eventpairs[0u], kNumEventpairs + kGap), ZX_OK, ""); 53 54 // Assert that every handle in the preceeding close call was in 55 // fact closed, by waiting on the PEER_CLOSED signal. 56 for (size_t idx = kNumEventpairs + kGap; idx < 10u; ++idx) { 57 zx_signals_t signals; 58 ASSERT_EQ(zx_object_wait_one(eventpairs[idx], ZX_EVENTPAIR_PEER_CLOSED, 59 0u, &signals), ZX_OK, ""); 60 ASSERT_EQ(signals & ZX_EVENTPAIR_PEER_CLOSED, ZX_EVENTPAIR_PEER_CLOSED, ""); 61 } 62 63 ASSERT_EQ(zx_handle_close_many(&eventpairs[kNumEventpairs + kGap], kNumEventpairs), ZX_OK, ""); 64 65 END_TEST; 66} 67 68static bool handle_close_many_duplicate_test(void) { 69 BEGIN_TEST; 70 71 // Layout: 0 1 0 1 2 3 : 0 1 2 3 72 zx_handle_t eventpairs[kNumEventpairs * 2 + kGap]; 73 74 for (size_t idx = kGap; idx < kGap + kNumEventpairs; ++idx) { 75 ASSERT_EQ(zx_eventpair_create(0u, &eventpairs[idx], 76 &eventpairs[idx + kNumEventpairs]), ZX_OK, ""); 77 } 78 // Duplicate the values at the start. 79 eventpairs[0u] = eventpairs[kGap]; 80 eventpairs[1u] = eventpairs[kGap + 1u]; 81 82 // Note that this returns an error value: the duplicated handles 83 // can't be closed twice. Despite this, all handles were closed. 84 ASSERT_EQ(zx_handle_close_many(&eventpairs[0u], kNumEventpairs + kGap), ZX_ERR_BAD_HANDLE, ""); 85 86 // Assert that every handle in the preceeding close call was in 87 // fact closed, by waiting on the PEER_CLOSED signal. 88 for (size_t idx = kNumEventpairs + kGap; idx < 10u; ++idx) { 89 zx_signals_t signals; 90 ASSERT_EQ(zx_object_wait_one(eventpairs[idx], ZX_EVENTPAIR_PEER_CLOSED, 91 0u, &signals), ZX_OK, ""); 92 ASSERT_EQ(signals & ZX_EVENTPAIR_PEER_CLOSED, ZX_EVENTPAIR_PEER_CLOSED, ""); 93 } 94 95 ASSERT_EQ(zx_handle_close_many(&eventpairs[kNumEventpairs + kGap], kNumEventpairs), ZX_OK, ""); 96 97 END_TEST; 98} 99 100BEGIN_TEST_CASE(handle_close_tests) 101RUN_TEST(handle_close_many_test) 102RUN_TEST(handle_close_many_invalid_test) 103RUN_TEST(handle_close_many_duplicate_test) 104END_TEST_CASE(handle_close_tests) 105 106#ifndef BUILD_COMBINED_TESTS 107int main(int argc, char** argv) { 108 return unittest_run_all_tests(argc, argv) ? 0 : -1; 109} 110#endif 111