diff options
author | Craig Tiller <ctiller@google.com> | 2015-09-24 11:33:04 -0700 |
---|---|---|
committer | Craig Tiller <ctiller@google.com> | 2015-09-24 11:33:04 -0700 |
commit | f8b14ca5f24448767c8627bb11508ba91ce608a0 (patch) | |
tree | 9c674d6529e8da204ca26021ca50d005211bc27f /test/core/util/port_posix.c | |
parent | b9d3596cb1cf9406ea6b1c67eda04a497857f6b4 (diff) | |
parent | 9e71674ab942c748f24e945327424163c15b5e66 (diff) |
Merge github.com:grpc/grpc into come-out-of-the-shadow
Diffstat (limited to 'test/core/util/port_posix.c')
-rw-r--r-- | test/core/util/port_posix.c | 92 |
1 files changed, 85 insertions, 7 deletions
diff --git a/test/core/util/port_posix.c b/test/core/util/port_posix.c index be45bae496..03f4c4912e 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,70 @@ 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_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(env); + } + + gpr_free(chosen_ports); +} static void chose_port(int port) { if (chosen_ports == NULL) { @@ -131,6 +195,9 @@ static int is_port_available(int *port, int is_tcp) { typedef struct portreq { grpc_pollset pollset; int port; + int retries; + char *server; + grpc_httpcli_context *ctx; } portreq; static void got_port_from_server(void *arg, @@ -138,6 +205,19 @@ static void got_port_from_server(void *arg, size_t i; int port = 0; portreq *pr = arg; + if (!response || response->status != 200) { + grpc_httpcli_request req; + memset(&req, 0, sizeof(req)); + GPR_ASSERT(pr->retries < 10); + pr->retries++; + req.host = pr->server; + req.path = "/get"; + gpr_log(GPR_DEBUG, "failed port pick from server: retrying"); + sleep(1); + grpc_httpcli_get(pr->ctx, &pr->pollset, &req, GRPC_TIMEOUT_SECONDS_TO_DEADLINE(10), + got_port_from_server, pr); + return; + } GPR_ASSERT(response); GPR_ASSERT(response->status == 200); for (i = 0; i < response->body_length; i++) { @@ -151,11 +231,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; @@ -167,6 +242,8 @@ static int pick_port_using_server(char *server) { memset(&req, 0, sizeof(req)); grpc_pollset_init(&pr.pollset); pr.port = -1; + pr.server = server; + pr.ctx = &context; req.host = server; req.path = "/get"; @@ -211,8 +288,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 (;;) { |