aboutsummaryrefslogtreecommitdiffhomepage
path: root/test/core/util/port_posix.c
diff options
context:
space:
mode:
authorGravatar Craig Tiller <ctiller@google.com>2015-09-24 11:33:04 -0700
committerGravatar Craig Tiller <ctiller@google.com>2015-09-24 11:33:04 -0700
commitf8b14ca5f24448767c8627bb11508ba91ce608a0 (patch)
tree9c674d6529e8da204ca26021ca50d005211bc27f /test/core/util/port_posix.c
parentb9d3596cb1cf9406ea6b1c67eda04a497857f6b4 (diff)
parent9e71674ab942c748f24e945327424163c15b5e66 (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.c92
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 (;;) {