diff options
Diffstat (limited to 'test/core/util/port_posix.c')
-rw-r--r-- | test/core/util/port_posix.c | 75 |
1 files changed, 68 insertions, 7 deletions
diff --git a/test/core/util/port_posix.c b/test/core/util/port_posix.c index be45bae496..5c09388254 100644 --- a/test/core/util/port_posix.c +++ b/test/core/util/port_posix.c @@ -47,6 +47,7 @@ #include <grpc/grpc.h> #include <grpc/support/alloc.h> #include <grpc/support/log.h> +#include <grpc/support/string_util.h> #include "src/core/httpcli/httpcli.h" #include "src/core/support/env.h" @@ -66,7 +67,71 @@ static int has_port_been_chosen(int port) { return 0; } -static void free_chosen_ports() { gpr_free(chosen_ports); } +typedef struct freereq { + grpc_pollset pollset; + int done; +} freereq; + +static void destroy_pollset_and_shutdown(void *p) { + grpc_pollset_destroy(p); + grpc_shutdown(); +} + +static void freed_port_from_server(void *arg, + const grpc_httpcli_response *response) { + freereq *pr = arg; + GPR_ASSERT(response); + GPR_ASSERT(response->status == 200); + gpr_mu_lock(GRPC_POLLSET_MU(&pr->pollset)); + pr->done = 1; + grpc_pollset_kick(&pr->pollset, NULL); + gpr_mu_unlock(GRPC_POLLSET_MU(&pr->pollset)); +} + +static void free_port_using_server(char *server, int port) { + grpc_httpcli_context context; + grpc_httpcli_request req; + freereq pr; + char *path; + + grpc_init(); + + memset(&pr, 0, sizeof(pr)); + memset(&req, 0, sizeof(req)); + grpc_pollset_init(&pr.pollset); + + req.host = server; + gpr_asprintf(&path, "/drop/%d", port); + req.path = path; + + grpc_httpcli_context_init(&context); + grpc_httpcli_get(&context, &pr.pollset, &req, + GRPC_TIMEOUT_SECONDS_TO_DEADLINE(10), freed_port_from_server, + &pr); + gpr_mu_lock(GRPC_POLLSET_MU(&pr.pollset)); + while (!pr.done) { + grpc_pollset_worker worker; + grpc_pollset_work(&pr.pollset, &worker, gpr_now(GPR_CLOCK_MONOTONIC), + GRPC_TIMEOUT_SECONDS_TO_DEADLINE(1)); + } + gpr_mu_unlock(GRPC_POLLSET_MU(&pr.pollset)); + + grpc_httpcli_context_destroy(&context); + grpc_pollset_shutdown(&pr.pollset, destroy_pollset_and_shutdown, &pr.pollset); + gpr_free(path); +} + +static void free_chosen_ports() { + char *env = gpr_getenv("GRPC_TEST_PORT_SERVER"); + if (env != NULL) { + size_t i; + for (i = 0; i < num_chosen_ports; i++) { + free_port_using_server(env, chosen_ports[i]); + } + } + + gpr_free(chosen_ports); +} static void chose_port(int port) { if (chosen_ports == NULL) { @@ -151,11 +216,6 @@ static void got_port_from_server(void *arg, gpr_mu_unlock(GRPC_POLLSET_MU(&pr->pollset)); } -static void destroy_pollset_and_shutdown(void *p) { - grpc_pollset_destroy(p); - grpc_shutdown(); -} - static int pick_port_using_server(char *server) { grpc_httpcli_context context; grpc_httpcli_request req; @@ -211,8 +271,9 @@ int grpc_pick_unused_port(void) { int port = pick_port_using_server(env); gpr_free(env); if (port != 0) { - return port; + chose_port(port); } + return port; } for (;;) { |