aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorGravatar David Klempner <klempner@google.com>2016-05-13 13:11:28 -0700
committerGravatar David Klempner <klempner@google.com>2016-05-13 13:11:28 -0700
commit2754c91fee5cbe57cee540e08f72e111a80911e0 (patch)
tree6abb54cfcf8cd002196a1b8751622a3e71e5e3b7
parenta709afe241d8b264a1c326315f757b4a8d330207 (diff)
Add an API to return an unused port to the portserver
-rw-r--r--test/core/util/port.h6
-rw-r--r--test/core/util/port_posix.c29
-rw-r--r--test/core/util/port_windows.c29
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 */