diff options
author | David Klempner <klempner@google.com> | 2016-05-13 13:11:28 -0700 |
---|---|---|
committer | David Klempner <klempner@google.com> | 2016-05-13 13:11:28 -0700 |
commit | 2754c91fee5cbe57cee540e08f72e111a80911e0 (patch) | |
tree | 6abb54cfcf8cd002196a1b8751622a3e71e5e3b7 | |
parent | a709afe241d8b264a1c326315f757b4a8d330207 (diff) |
Add an API to return an unused port to the portserver
-rw-r--r-- | test/core/util/port.h | 6 | ||||
-rw-r--r-- | test/core/util/port_posix.c | 29 | ||||
-rw-r--r-- | test/core/util/port_windows.c | 29 |
3 files changed, 64 insertions, 0 deletions
diff --git a/test/core/util/port.h b/test/core/util/port.h index 93788bcab2..4b70fdc978 100644 --- a/test/core/util/port.h +++ b/test/core/util/port.h @@ -45,6 +45,12 @@ int grpc_pick_unused_port(); on failure. */ int grpc_pick_unused_port_or_die(); +/* Return a port which was previously returned by grpc_pick_unused_port(). + * Implementations of grpc_pick_unused_port() backed by a portserver may limit + * the total number of ports available; this lets a binary return its allocated + * ports back to the server if it is going to allocate a large number. */ +void grpc_recycle_unused_port(); + #ifdef __cplusplus } #endif diff --git a/test/core/util/port_posix.c b/test/core/util/port_posix.c index eabd62fafc..32b1849ec4 100644 --- a/test/core/util/port_posix.c +++ b/test/core/util/port_posix.c @@ -68,6 +68,31 @@ static int has_port_been_chosen(int port) { return 0; } +static int free_chosen_port(int port) { + size_t i; + int found = 0; + size_t found_at = 0; + char *env = gpr_getenv("GRPC_TEST_PORT_SERVER"); + if (env != NULL) { + /* Find the port and erase it from the list, then tell the server it can be + freed. */ + for (i = 0; i < num_chosen_ports; i++) { + if (chosen_ports[i] == port) { + GPR_ASSERT(found == 0); + found = 1; + found_at = i; + } + } + if (found) { + chosen_ports[found_at] = chosen_ports[num_chosen_ports - 1]; + grpc_free_port_using_server(env, port); + num_chosen_ports--; + chosen_ports = gpr_realloc(chosen_ports, sizeof(int) * num_chosen_ports); + } + } + return found; +} + static void free_chosen_ports(void) { char *env = gpr_getenv("GRPC_TEST_PORT_SERVER"); if (env != NULL) { @@ -210,4 +235,8 @@ int grpc_pick_unused_port_or_die(void) { return port; } +void grpc_recycle_unused_port(int port) { + GPR_ASSERT(free_chosen_port(port)); +} + #endif /* GPR_POSIX_SOCKET && GRPC_TEST_PICK_PORT */ diff --git a/test/core/util/port_windows.c b/test/core/util/port_windows.c index 154d607ec7..29f3404b2a 100644 --- a/test/core/util/port_windows.c +++ b/test/core/util/port_windows.c @@ -71,6 +71,31 @@ static int has_port_been_chosen(int port) { return 0; } +static int free_chosen_port(int port) { + size_t i; + int found = 0; + size_t found_at = 0; + char *env = gpr_getenv("GRPC_TEST_PORT_SERVER"); + if (env != NULL) { + /* Find the port and erase it from the list, then tell the server it can be + freed. */ + for (i = 0; i < num_chosen_ports; i++) { + if (chosen_ports[i] == port) { + GPR_ASSERT(found == 0); + found = 1; + found_at = i; + } + } + if (found) { + chosen_ports[found_at] = chosen_ports[num_chosen_ports - 1]; + grpc_free_port_using_server(env, port); + num_chosen_ports--; + chosen_ports = gpr_realloc(chosen_ports, sizeof(int) * num_chosen_ports); + } + } + return found; +} + static void free_chosen_ports(void) { char *env = gpr_getenv("GRPC_TEST_PORT_SERVER"); if (env != NULL) { @@ -216,4 +241,8 @@ int grpc_pick_unused_port_or_die(void) { return port; } +void grpc_recycle_unused_port(int port) { + GPR_ASSERT(free_chosen_port(port)); +} + #endif /* GPR_WINSOCK_SOCKET && GRPC_TEST_PICK_PORT */ |