blob: 0c9c0d87d66e38b97de085e48fe692a736d948a3 [file] [log] [blame]
murgatroid99c36f6ea2016-10-03 09:24:09 -07001/*
2 *
3 * Copyright 2015, Google Inc.
4 * All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions are
8 * met:
9 *
10 * * Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * * Redistributions in binary form must reproduce the above
13 * copyright notice, this list of conditions and the following disclaimer
14 * in the documentation and/or other materials provided with the
15 * distribution.
16 * * Neither the name of Google Inc. nor the names of its
17 * contributors may be used to endorse or promote products derived from
18 * this software without specific prior written permission.
19 *
20 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
23 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
24 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
25 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
26 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
30 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 *
32 */
33
34#include "src/core/lib/iomgr/port.h"
35#include "test/core/util/test_config.h"
36#if defined(GRPC_UV) && defined(GRPC_TEST_PICK_PORT)
37
murgatroid992c287ca2016-10-07 09:55:35 -070038#include <grpc/support/alloc.h>
murgatroid99c36f6ea2016-10-03 09:24:09 -070039#include <grpc/support/log.h>
40
murgatroid992c287ca2016-10-07 09:55:35 -070041#include "src/core/lib/support/env.h"
murgatroid99c36f6ea2016-10-03 09:24:09 -070042#include "test/core/util/port.h"
murgatroid992c287ca2016-10-07 09:55:35 -070043#include "test/core/util/port_server_client.h"
44
45// Almost everything in this file has been copied from port_posix.c
46
47static int *chosen_ports = NULL;
48static size_t num_chosen_ports = 0;
49
50static int free_chosen_port(int port) {
51 size_t i;
52 int found = 0;
53 size_t found_at = 0;
54 char *env = gpr_getenv("GRPC_TEST_PORT_SERVER");
55 /* Find the port and erase it from the list, then tell the server it can be
56 freed. */
57 for (i = 0; i < num_chosen_ports; i++) {
58 if (chosen_ports[i] == port) {
59 GPR_ASSERT(found == 0);
60 found = 1;
61 found_at = i;
62 }
63 }
64 if (found) {
65 chosen_ports[found_at] = chosen_ports[num_chosen_ports - 1];
66 num_chosen_ports--;
67 if (env) {
68 grpc_free_port_using_server(env, port);
69 }
70 }
71 gpr_free(env);
72 return found;
73}
74
75static void free_chosen_ports(void) {
76 char *env = gpr_getenv("GRPC_TEST_PORT_SERVER");
77 if (env != NULL) {
78 size_t i;
79 for (i = 0; i < num_chosen_ports; i++) {
80 grpc_free_port_using_server(env, chosen_ports[i]);
81 }
82 gpr_free(env);
83 }
84
85 gpr_free(chosen_ports);
86}
87
88static void chose_port(int port) {
89 if (chosen_ports == NULL) {
90 atexit(free_chosen_ports);
91 }
92 num_chosen_ports++;
93 chosen_ports = gpr_realloc(chosen_ports, sizeof(int) * num_chosen_ports);
94 chosen_ports[num_chosen_ports - 1] = port;
95}
murgatroid99c36f6ea2016-10-03 09:24:09 -070096
97int grpc_pick_unused_port(void) {
murgatroid992c287ca2016-10-07 09:55:35 -070098 // Currently only works with the port server
99 char *env = gpr_getenv("GRPC_TEST_PORT_SERVER");
100 GPR_ASSERT(env);
101 int port = grpc_pick_port_using_server(env);
102 gpr_free(env);
103 if (port != 0) {
104 chose_port(port);
105 }
106 return port;
murgatroid99c36f6ea2016-10-03 09:24:09 -0700107}
108
109int grpc_pick_unused_port_or_die(void) {
110 int port = grpc_pick_unused_port();
111 GPR_ASSERT(port > 0);
112 return port;
113}
114
murgatroid99aa9c5782016-10-10 12:16:13 -0700115void grpc_recycle_unused_port(int port) { GPR_ASSERT(free_chosen_port(port)); }
murgatroid99c36f6ea2016-10-03 09:24:09 -0700116
117#endif /* GRPC_UV && GRPC_TEST_PICK_PORT */