aboutsummaryrefslogtreecommitdiffhomepage
path: root/test/core/iomgr
diff options
context:
space:
mode:
Diffstat (limited to 'test/core/iomgr')
-rw-r--r--test/core/iomgr/combiner_test.c165
-rw-r--r--test/core/iomgr/endpoint_pair_test.c6
-rw-r--r--test/core/iomgr/ev_epoll_linux_test.c8
-rw-r--r--test/core/iomgr/fd_conservation_posix_test.c6
-rw-r--r--test/core/iomgr/fd_posix_test.c11
-rw-r--r--test/core/iomgr/resolve_address_test.c1
-rw-r--r--test/core/iomgr/resource_quota_test.c749
-rw-r--r--test/core/iomgr/sockaddr_utils_test.c162
-rw-r--r--test/core/iomgr/socket_utils_test.c12
-rw-r--r--test/core/iomgr/tcp_client_posix_test.c39
-rw-r--r--test/core/iomgr/tcp_posix_test.c47
-rw-r--r--test/core/iomgr/tcp_server_posix_test.c100
-rw-r--r--test/core/iomgr/timer_heap_test.c11
-rw-r--r--test/core/iomgr/udp_server_test.c70
-rw-r--r--test/core/iomgr/wakeup_fd_cv_test.c250
15 files changed, 1463 insertions, 174 deletions
diff --git a/test/core/iomgr/combiner_test.c b/test/core/iomgr/combiner_test.c
new file mode 100644
index 0000000000..f7d5809be7
--- /dev/null
+++ b/test/core/iomgr/combiner_test.c
@@ -0,0 +1,165 @@
+/*
+ *
+ * Copyright 2015, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include "src/core/lib/iomgr/combiner.h"
+
+#include <grpc/grpc.h>
+#include <grpc/support/alloc.h>
+#include <grpc/support/log.h>
+#include <grpc/support/thd.h>
+#include <grpc/support/useful.h>
+
+#include "test/core/util/test_config.h"
+
+static void test_no_op(void) {
+ gpr_log(GPR_DEBUG, "test_no_op");
+ grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
+ grpc_combiner_destroy(&exec_ctx, grpc_combiner_create(NULL));
+ grpc_exec_ctx_finish(&exec_ctx);
+}
+
+static void set_bool_to_true(grpc_exec_ctx *exec_ctx, void *value,
+ grpc_error *error) {
+ *(bool *)value = true;
+}
+
+static void test_execute_one(void) {
+ gpr_log(GPR_DEBUG, "test_execute_one");
+
+ grpc_combiner *lock = grpc_combiner_create(NULL);
+ bool done = false;
+ grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
+ grpc_combiner_execute(&exec_ctx, lock,
+ grpc_closure_create(set_bool_to_true, &done),
+ GRPC_ERROR_NONE, false);
+ grpc_exec_ctx_flush(&exec_ctx);
+ GPR_ASSERT(done);
+ grpc_combiner_destroy(&exec_ctx, lock);
+ grpc_exec_ctx_finish(&exec_ctx);
+}
+
+typedef struct {
+ size_t ctr;
+ grpc_combiner *lock;
+} thd_args;
+
+typedef struct {
+ size_t *ctr;
+ size_t value;
+} ex_args;
+
+static void check_one(grpc_exec_ctx *exec_ctx, void *a, grpc_error *error) {
+ ex_args *args = a;
+ GPR_ASSERT(*args->ctr == args->value - 1);
+ *args->ctr = args->value;
+ gpr_free(a);
+}
+
+static void execute_many_loop(void *a) {
+ thd_args *args = a;
+ grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
+ size_t n = 1;
+ for (size_t i = 0; i < 10; i++) {
+ for (size_t j = 0; j < 10000; j++) {
+ ex_args *c = gpr_malloc(sizeof(*c));
+ c->ctr = &args->ctr;
+ c->value = n++;
+ grpc_combiner_execute(&exec_ctx, args->lock,
+ grpc_closure_create(check_one, c), GRPC_ERROR_NONE,
+ false);
+ grpc_exec_ctx_flush(&exec_ctx);
+ }
+ // sleep for a little bit, to test a combiner draining and another thread
+ // picking it up
+ gpr_sleep_until(GRPC_TIMEOUT_MILLIS_TO_DEADLINE(100));
+ }
+ grpc_exec_ctx_finish(&exec_ctx);
+}
+
+static void test_execute_many(void) {
+ gpr_log(GPR_DEBUG, "test_execute_many");
+
+ grpc_combiner *lock = grpc_combiner_create(NULL);
+ gpr_thd_id thds[100];
+ thd_args ta[GPR_ARRAY_SIZE(thds)];
+ for (size_t i = 0; i < GPR_ARRAY_SIZE(thds); i++) {
+ gpr_thd_options options = gpr_thd_options_default();
+ gpr_thd_options_set_joinable(&options);
+ ta[i].ctr = 0;
+ ta[i].lock = lock;
+ GPR_ASSERT(gpr_thd_new(&thds[i], execute_many_loop, &ta[i], &options));
+ }
+ for (size_t i = 0; i < GPR_ARRAY_SIZE(thds); i++) {
+ gpr_thd_join(thds[i]);
+ }
+ grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
+ grpc_combiner_destroy(&exec_ctx, lock);
+ grpc_exec_ctx_finish(&exec_ctx);
+}
+
+static bool got_in_finally = false;
+
+static void in_finally(grpc_exec_ctx *exec_ctx, void *arg, grpc_error *error) {
+ got_in_finally = true;
+}
+
+static void add_finally(grpc_exec_ctx *exec_ctx, void *arg, grpc_error *error) {
+ grpc_combiner_execute_finally(exec_ctx, arg,
+ grpc_closure_create(in_finally, NULL),
+ GRPC_ERROR_NONE, false);
+}
+
+static void test_execute_finally(void) {
+ gpr_log(GPR_DEBUG, "test_execute_finally");
+
+ grpc_combiner *lock = grpc_combiner_create(NULL);
+ grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
+ grpc_combiner_execute(&exec_ctx, lock, grpc_closure_create(add_finally, lock),
+ GRPC_ERROR_NONE, false);
+ grpc_exec_ctx_flush(&exec_ctx);
+ GPR_ASSERT(got_in_finally);
+ grpc_combiner_destroy(&exec_ctx, lock);
+ grpc_exec_ctx_finish(&exec_ctx);
+}
+
+int main(int argc, char **argv) {
+ grpc_test_init(argc, argv);
+ grpc_init();
+ test_no_op();
+ test_execute_one();
+ test_execute_finally();
+ test_execute_many();
+ grpc_shutdown();
+
+ return 0;
+}
diff --git a/test/core/iomgr/endpoint_pair_test.c b/test/core/iomgr/endpoint_pair_test.c
index 99b86b6213..2a257a7cea 100644
--- a/test/core/iomgr/endpoint_pair_test.c
+++ b/test/core/iomgr/endpoint_pair_test.c
@@ -49,7 +49,11 @@ static grpc_endpoint_test_fixture create_fixture_endpoint_pair(
size_t slice_size) {
grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
grpc_endpoint_test_fixture f;
- grpc_endpoint_pair p = grpc_iomgr_create_endpoint_pair("test", slice_size);
+ grpc_resource_quota *resource_quota =
+ grpc_resource_quota_create("endpoint_pair_test");
+ grpc_endpoint_pair p =
+ grpc_iomgr_create_endpoint_pair("test", resource_quota, slice_size);
+ grpc_resource_quota_unref(resource_quota);
f.client_ep = p.client;
f.server_ep = p.server;
diff --git a/test/core/iomgr/ev_epoll_linux_test.c b/test/core/iomgr/ev_epoll_linux_test.c
index 2547dc9871..564b05d7f4 100644
--- a/test/core/iomgr/ev_epoll_linux_test.c
+++ b/test/core/iomgr/ev_epoll_linux_test.c
@@ -30,10 +30,10 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
-#include <grpc/support/port_platform.h>
+#include "src/core/lib/iomgr/port.h"
/* This test only relevant on linux systems where epoll() is available */
-#ifdef GPR_LINUX_EPOLL
+#ifdef GRPC_LINUX_EPOLL
#include "src/core/lib/iomgr/ev_epoll_linux.h"
#include "src/core/lib/iomgr/ev_posix.h"
@@ -239,6 +239,6 @@ int main(int argc, char **argv) {
grpc_iomgr_shutdown();
return 0;
}
-#else /* defined(GPR_LINUX_EPOLL) */
+#else /* defined(GRPC_LINUX_EPOLL) */
int main(int argc, char **argv) { return 0; }
-#endif /* !defined(GPR_LINUX_EPOLL) */
+#endif /* !defined(GRPC_LINUX_EPOLL) */
diff --git a/test/core/iomgr/fd_conservation_posix_test.c b/test/core/iomgr/fd_conservation_posix_test.c
index bbb3f46497..652b37eb6f 100644
--- a/test/core/iomgr/fd_conservation_posix_test.c
+++ b/test/core/iomgr/fd_conservation_posix_test.c
@@ -52,15 +52,19 @@ int main(int argc, char **argv) {
of descriptors */
rlim.rlim_cur = rlim.rlim_max = 10;
GPR_ASSERT(0 == setrlimit(RLIMIT_NOFILE, &rlim));
+ grpc_resource_quota *resource_quota =
+ grpc_resource_quota_create("fd_conservation_posix_test");
for (i = 0; i < 100; i++) {
grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
- p = grpc_iomgr_create_endpoint_pair("test", 1);
+ p = grpc_iomgr_create_endpoint_pair("test", resource_quota, 1);
grpc_endpoint_destroy(&exec_ctx, p.client);
grpc_endpoint_destroy(&exec_ctx, p.server);
grpc_exec_ctx_finish(&exec_ctx);
}
+ grpc_resource_quota_unref(resource_quota);
+
grpc_iomgr_shutdown();
return 0;
}
diff --git a/test/core/iomgr/fd_posix_test.c b/test/core/iomgr/fd_posix_test.c
index 62dc24d85a..6166699fe6 100644
--- a/test/core/iomgr/fd_posix_test.c
+++ b/test/core/iomgr/fd_posix_test.c
@@ -31,6 +31,11 @@
*
*/
+#include "src/core/lib/iomgr/port.h"
+
+// This test won't work except with posix sockets enabled
+#ifdef GRPC_POSIX_SOCKET
+
#include "src/core/lib/iomgr/ev_posix.h"
#include <ctype.h>
@@ -548,3 +553,9 @@ int main(int argc, char **argv) {
grpc_iomgr_shutdown();
return 0;
}
+
+#else /* GRPC_POSIX_SOCKET */
+
+int main(int argc, char **argv) { return 1; }
+
+#endif /* GRPC_POSIX_SOCKET */
diff --git a/test/core/iomgr/resolve_address_test.c b/test/core/iomgr/resolve_address_test.c
index 4417d96043..2dd0d88b3f 100644
--- a/test/core/iomgr/resolve_address_test.c
+++ b/test/core/iomgr/resolve_address_test.c
@@ -36,6 +36,7 @@
#include <grpc/support/sync.h>
#include <grpc/support/time.h>
#include "src/core/lib/iomgr/executor.h"
+#include "src/core/lib/iomgr/iomgr.h"
#include "test/core/util/test_config.h"
static gpr_timespec test_deadline(void) {
diff --git a/test/core/iomgr/resource_quota_test.c b/test/core/iomgr/resource_quota_test.c
new file mode 100644
index 0000000000..34dee1aee1
--- /dev/null
+++ b/test/core/iomgr/resource_quota_test.c
@@ -0,0 +1,749 @@
+/*
+ *
+ * Copyright 2016, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include "src/core/lib/iomgr/resource_quota.h"
+
+#include <grpc/support/alloc.h>
+#include <grpc/support/log.h>
+
+#include "test/core/util/test_config.h"
+
+static void inc_int_cb(grpc_exec_ctx *exec_ctx, void *a, grpc_error *error) {
+ ++*(int *)a;
+}
+
+static void set_bool_cb(grpc_exec_ctx *exec_ctx, void *a, grpc_error *error) {
+ *(bool *)a = true;
+}
+grpc_closure *set_bool(bool *p) { return grpc_closure_create(set_bool_cb, p); }
+
+typedef struct {
+ size_t size;
+ grpc_resource_user *resource_user;
+ grpc_closure *then;
+} reclaimer_args;
+static void reclaimer_cb(grpc_exec_ctx *exec_ctx, void *args,
+ grpc_error *error) {
+ GPR_ASSERT(error == GRPC_ERROR_NONE);
+ reclaimer_args *a = args;
+ grpc_resource_user_free(exec_ctx, a->resource_user, a->size);
+ grpc_resource_user_finish_reclamation(exec_ctx, a->resource_user);
+ grpc_closure_run(exec_ctx, a->then, GRPC_ERROR_NONE);
+ gpr_free(a);
+}
+grpc_closure *make_reclaimer(grpc_resource_user *resource_user, size_t size,
+ grpc_closure *then) {
+ reclaimer_args *a = gpr_malloc(sizeof(*a));
+ a->size = size;
+ a->resource_user = resource_user;
+ a->then = then;
+ return grpc_closure_create(reclaimer_cb, a);
+}
+
+static void unused_reclaimer_cb(grpc_exec_ctx *exec_ctx, void *arg,
+ grpc_error *error) {
+ GPR_ASSERT(error == GRPC_ERROR_CANCELLED);
+ grpc_closure_run(exec_ctx, arg, GRPC_ERROR_NONE);
+}
+grpc_closure *make_unused_reclaimer(grpc_closure *then) {
+ return grpc_closure_create(unused_reclaimer_cb, then);
+}
+
+static void destroy_user(grpc_resource_user *usr) {
+ grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
+ bool done = false;
+ grpc_resource_user_shutdown(&exec_ctx, usr, set_bool(&done));
+ grpc_exec_ctx_flush(&exec_ctx);
+ GPR_ASSERT(done);
+ grpc_resource_user_destroy(&exec_ctx, usr);
+ grpc_exec_ctx_finish(&exec_ctx);
+}
+
+static void test_no_op(void) {
+ gpr_log(GPR_INFO, "** test_no_op **");
+ grpc_resource_quota_unref(grpc_resource_quota_create("test_no_op"));
+}
+
+static void test_resize_then_destroy(void) {
+ gpr_log(GPR_INFO, "** test_resize_then_destroy **");
+ grpc_resource_quota *q =
+ grpc_resource_quota_create("test_resize_then_destroy");
+ grpc_resource_quota_resize(q, 1024 * 1024);
+ grpc_resource_quota_unref(q);
+}
+
+static void test_resource_user_no_op(void) {
+ gpr_log(GPR_INFO, "** test_resource_user_no_op **");
+ grpc_resource_quota *q =
+ grpc_resource_quota_create("test_resource_user_no_op");
+ grpc_resource_user usr;
+ grpc_resource_user_init(&usr, q, "usr");
+ grpc_resource_quota_unref(q);
+ destroy_user(&usr);
+}
+
+static void test_instant_alloc_then_free(void) {
+ gpr_log(GPR_INFO, "** test_instant_alloc_then_free **");
+ grpc_resource_quota *q =
+ grpc_resource_quota_create("test_instant_alloc_then_free");
+ grpc_resource_quota_resize(q, 1024 * 1024);
+ grpc_resource_user usr;
+ grpc_resource_user_init(&usr, q, "usr");
+ {
+ grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
+ grpc_resource_user_alloc(&exec_ctx, &usr, 1024, NULL);
+ grpc_exec_ctx_finish(&exec_ctx);
+ }
+ {
+ grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
+ grpc_resource_user_free(&exec_ctx, &usr, 1024);
+ grpc_exec_ctx_finish(&exec_ctx);
+ }
+ grpc_resource_quota_unref(q);
+ destroy_user(&usr);
+}
+
+static void test_instant_alloc_free_pair(void) {
+ gpr_log(GPR_INFO, "** test_instant_alloc_free_pair **");
+ grpc_resource_quota *q =
+ grpc_resource_quota_create("test_instant_alloc_free_pair");
+ grpc_resource_quota_resize(q, 1024 * 1024);
+ grpc_resource_user usr;
+ grpc_resource_user_init(&usr, q, "usr");
+ {
+ grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
+ grpc_resource_user_alloc(&exec_ctx, &usr, 1024, NULL);
+ grpc_resource_user_free(&exec_ctx, &usr, 1024);
+ grpc_exec_ctx_finish(&exec_ctx);
+ }
+ grpc_resource_quota_unref(q);
+ destroy_user(&usr);
+}
+
+static void test_simple_async_alloc(void) {
+ gpr_log(GPR_INFO, "** test_simple_async_alloc **");
+ grpc_resource_quota *q =
+ grpc_resource_quota_create("test_simple_async_alloc");
+ grpc_resource_quota_resize(q, 1024 * 1024);
+ grpc_resource_user usr;
+ grpc_resource_user_init(&usr, q, "usr");
+ {
+ bool done = false;
+ grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
+ grpc_resource_user_alloc(&exec_ctx, &usr, 1024, set_bool(&done));
+ grpc_exec_ctx_finish(&exec_ctx);
+ GPR_ASSERT(done);
+ }
+ {
+ grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
+ grpc_resource_user_free(&exec_ctx, &usr, 1024);
+ grpc_exec_ctx_finish(&exec_ctx);
+ }
+ grpc_resource_quota_unref(q);
+ destroy_user(&usr);
+}
+
+static void test_async_alloc_blocked_by_size(void) {
+ gpr_log(GPR_INFO, "** test_async_alloc_blocked_by_size **");
+ grpc_resource_quota *q =
+ grpc_resource_quota_create("test_async_alloc_blocked_by_size");
+ grpc_resource_quota_resize(q, 1);
+ grpc_resource_user usr;
+ grpc_resource_user_init(&usr, q, "usr");
+ bool done = false;
+ {
+ grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
+ grpc_resource_user_alloc(&exec_ctx, &usr, 1024, set_bool(&done));
+ grpc_exec_ctx_finish(&exec_ctx);
+ GPR_ASSERT(!done);
+ }
+ grpc_resource_quota_resize(q, 1024);
+ GPR_ASSERT(done);
+ {
+ grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
+ grpc_resource_user_free(&exec_ctx, &usr, 1024);
+ grpc_exec_ctx_finish(&exec_ctx);
+ }
+ grpc_resource_quota_unref(q);
+ destroy_user(&usr);
+}
+
+static void test_scavenge(void) {
+ gpr_log(GPR_INFO, "** test_scavenge **");
+ grpc_resource_quota *q = grpc_resource_quota_create("test_scavenge");
+ grpc_resource_quota_resize(q, 1024);
+ grpc_resource_user usr1;
+ grpc_resource_user usr2;
+ grpc_resource_user_init(&usr1, q, "usr1");
+ grpc_resource_user_init(&usr2, q, "usr2");
+ {
+ bool done = false;
+ grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
+ grpc_resource_user_alloc(&exec_ctx, &usr1, 1024, set_bool(&done));
+ grpc_exec_ctx_finish(&exec_ctx);
+ GPR_ASSERT(done);
+ }
+ {
+ grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
+ grpc_resource_user_free(&exec_ctx, &usr1, 1024);
+ grpc_exec_ctx_finish(&exec_ctx);
+ }
+ {
+ bool done = false;
+ grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
+ grpc_resource_user_alloc(&exec_ctx, &usr2, 1024, set_bool(&done));
+ grpc_exec_ctx_finish(&exec_ctx);
+ GPR_ASSERT(done);
+ }
+ {
+ grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
+ grpc_resource_user_free(&exec_ctx, &usr2, 1024);
+ grpc_exec_ctx_finish(&exec_ctx);
+ }
+ grpc_resource_quota_unref(q);
+ destroy_user(&usr1);
+ destroy_user(&usr2);
+}
+
+static void test_scavenge_blocked(void) {
+ gpr_log(GPR_INFO, "** test_scavenge_blocked **");
+ grpc_resource_quota *q = grpc_resource_quota_create("test_scavenge_blocked");
+ grpc_resource_quota_resize(q, 1024);
+ grpc_resource_user usr1;
+ grpc_resource_user usr2;
+ grpc_resource_user_init(&usr1, q, "usr1");
+ grpc_resource_user_init(&usr2, q, "usr2");
+ bool done;
+ {
+ done = false;
+ grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
+ grpc_resource_user_alloc(&exec_ctx, &usr1, 1024, set_bool(&done));
+ grpc_exec_ctx_finish(&exec_ctx);
+ GPR_ASSERT(done);
+ }
+ {
+ done = false;
+ grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
+ grpc_resource_user_alloc(&exec_ctx, &usr2, 1024, set_bool(&done));
+ grpc_exec_ctx_finish(&exec_ctx);
+ GPR_ASSERT(!done);
+ }
+ {
+ grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
+ grpc_resource_user_free(&exec_ctx, &usr1, 1024);
+ grpc_exec_ctx_finish(&exec_ctx);
+ GPR_ASSERT(done);
+ }
+ {
+ grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
+ grpc_resource_user_free(&exec_ctx, &usr2, 1024);
+ grpc_exec_ctx_finish(&exec_ctx);
+ }
+ grpc_resource_quota_unref(q);
+ destroy_user(&usr1);
+ destroy_user(&usr2);
+}
+
+static void test_blocked_until_scheduled_reclaim(void) {
+ gpr_log(GPR_INFO, "** test_blocked_until_scheduled_reclaim **");
+ grpc_resource_quota *q =
+ grpc_resource_quota_create("test_blocked_until_scheduled_reclaim");
+ grpc_resource_quota_resize(q, 1024);
+ grpc_resource_user usr;
+ grpc_resource_user_init(&usr, q, "usr");
+ {
+ bool done = false;
+ grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
+ grpc_resource_user_alloc(&exec_ctx, &usr, 1024, set_bool(&done));
+ grpc_exec_ctx_finish(&exec_ctx);
+ GPR_ASSERT(done);
+ }
+ bool reclaim_done = false;
+ {
+ grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
+ grpc_resource_user_post_reclaimer(
+ &exec_ctx, &usr, false,
+ make_reclaimer(&usr, 1024, set_bool(&reclaim_done)));
+ grpc_exec_ctx_finish(&exec_ctx);
+ }
+ {
+ bool done = false;
+ grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
+ grpc_resource_user_alloc(&exec_ctx, &usr, 1024, set_bool(&done));
+ grpc_exec_ctx_finish(&exec_ctx);
+ GPR_ASSERT(reclaim_done);
+ GPR_ASSERT(done);
+ }
+ {
+ grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
+ grpc_resource_user_free(&exec_ctx, &usr, 1024);
+ grpc_exec_ctx_finish(&exec_ctx);
+ }
+ grpc_resource_quota_unref(q);
+ destroy_user(&usr);
+}
+
+static void test_blocked_until_scheduled_reclaim_and_scavenge(void) {
+ gpr_log(GPR_INFO, "** test_blocked_until_scheduled_reclaim_and_scavenge **");
+ grpc_resource_quota *q = grpc_resource_quota_create(
+ "test_blocked_until_scheduled_reclaim_and_scavenge");
+ grpc_resource_quota_resize(q, 1024);
+ grpc_resource_user usr1;
+ grpc_resource_user usr2;
+ grpc_resource_user_init(&usr1, q, "usr1");
+ grpc_resource_user_init(&usr2, q, "usr2");
+ {
+ bool done = false;
+ grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
+ grpc_resource_user_alloc(&exec_ctx, &usr1, 1024, set_bool(&done));
+ grpc_exec_ctx_finish(&exec_ctx);
+ GPR_ASSERT(done);
+ }
+ bool reclaim_done = false;
+ {
+ grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
+ grpc_resource_user_post_reclaimer(
+ &exec_ctx, &usr1, false,
+ make_reclaimer(&usr1, 1024, set_bool(&reclaim_done)));
+ grpc_exec_ctx_finish(&exec_ctx);
+ }
+ {
+ bool done = false;
+ grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
+ grpc_resource_user_alloc(&exec_ctx, &usr2, 1024, set_bool(&done));
+ grpc_exec_ctx_finish(&exec_ctx);
+ GPR_ASSERT(reclaim_done);
+ GPR_ASSERT(done);
+ }
+ {
+ grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
+ grpc_resource_user_free(&exec_ctx, &usr2, 1024);
+ grpc_exec_ctx_finish(&exec_ctx);
+ }
+ grpc_resource_quota_unref(q);
+ destroy_user(&usr1);
+ destroy_user(&usr2);
+}
+
+static void test_blocked_until_scheduled_destructive_reclaim(void) {
+ gpr_log(GPR_INFO, "** test_blocked_until_scheduled_destructive_reclaim **");
+ grpc_resource_quota *q = grpc_resource_quota_create(
+ "test_blocked_until_scheduled_destructive_reclaim");
+ grpc_resource_quota_resize(q, 1024);
+ grpc_resource_user usr;
+ grpc_resource_user_init(&usr, q, "usr");
+ {
+ bool done = false;
+ grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
+ grpc_resource_user_alloc(&exec_ctx, &usr, 1024, set_bool(&done));
+ grpc_exec_ctx_finish(&exec_ctx);
+ GPR_ASSERT(done);
+ }
+ bool reclaim_done = false;
+ {
+ grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
+ grpc_resource_user_post_reclaimer(
+ &exec_ctx, &usr, true,
+ make_reclaimer(&usr, 1024, set_bool(&reclaim_done)));
+ grpc_exec_ctx_finish(&exec_ctx);
+ }
+ {
+ bool done = false;
+ grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
+ grpc_resource_user_alloc(&exec_ctx, &usr, 1024, set_bool(&done));
+ grpc_exec_ctx_finish(&exec_ctx);
+ GPR_ASSERT(reclaim_done);
+ GPR_ASSERT(done);
+ }
+ {
+ grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
+ grpc_resource_user_free(&exec_ctx, &usr, 1024);
+ grpc_exec_ctx_finish(&exec_ctx);
+ }
+ grpc_resource_quota_unref(q);
+ destroy_user(&usr);
+}
+
+static void test_unused_reclaim_is_cancelled(void) {
+ gpr_log(GPR_INFO, "** test_unused_reclaim_is_cancelled **");
+ grpc_resource_quota *q =
+ grpc_resource_quota_create("test_unused_reclaim_is_cancelled");
+ grpc_resource_quota_resize(q, 1024);
+ grpc_resource_user usr;
+ grpc_resource_user_init(&usr, q, "usr");
+ bool benign_done = false;
+ bool destructive_done = false;
+ {
+ grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
+ grpc_resource_user_post_reclaimer(
+ &exec_ctx, &usr, false, make_unused_reclaimer(set_bool(&benign_done)));
+ grpc_resource_user_post_reclaimer(
+ &exec_ctx, &usr, true,
+ make_unused_reclaimer(set_bool(&destructive_done)));
+ grpc_exec_ctx_finish(&exec_ctx);
+ GPR_ASSERT(!benign_done);
+ GPR_ASSERT(!destructive_done);
+ }
+ grpc_resource_quota_unref(q);
+ destroy_user(&usr);
+ GPR_ASSERT(benign_done);
+ GPR_ASSERT(destructive_done);
+}
+
+static void test_benign_reclaim_is_preferred(void) {
+ gpr_log(GPR_INFO, "** test_benign_reclaim_is_preferred **");
+ grpc_resource_quota *q =
+ grpc_resource_quota_create("test_benign_reclaim_is_preferred");
+ grpc_resource_quota_resize(q, 1024);
+ grpc_resource_user usr;
+ grpc_resource_user_init(&usr, q, "usr");
+ bool benign_done = false;
+ bool destructive_done = false;
+ {
+ bool done = false;
+ grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
+ grpc_resource_user_alloc(&exec_ctx, &usr, 1024, set_bool(&done));
+ grpc_exec_ctx_finish(&exec_ctx);
+ GPR_ASSERT(done);
+ }
+ {
+ grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
+ grpc_resource_user_post_reclaimer(
+ &exec_ctx, &usr, false,
+ make_reclaimer(&usr, 1024, set_bool(&benign_done)));
+ grpc_resource_user_post_reclaimer(
+ &exec_ctx, &usr, true,
+ make_unused_reclaimer(set_bool(&destructive_done)));
+ grpc_exec_ctx_finish(&exec_ctx);
+ GPR_ASSERT(!benign_done);
+ GPR_ASSERT(!destructive_done);
+ }
+ {
+ bool done = false;
+ grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
+ grpc_resource_user_alloc(&exec_ctx, &usr, 1024, set_bool(&done));
+ grpc_exec_ctx_finish(&exec_ctx);
+ GPR_ASSERT(benign_done);
+ GPR_ASSERT(!destructive_done);
+ GPR_ASSERT(done);
+ }
+ {
+ grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
+ grpc_resource_user_free(&exec_ctx, &usr, 1024);
+ grpc_exec_ctx_finish(&exec_ctx);
+ }
+ grpc_resource_quota_unref(q);
+ destroy_user(&usr);
+ GPR_ASSERT(benign_done);
+ GPR_ASSERT(destructive_done);
+}
+
+static void test_multiple_reclaims_can_be_triggered(void) {
+ gpr_log(GPR_INFO, "** test_multiple_reclaims_can_be_triggered **");
+ grpc_resource_quota *q =
+ grpc_resource_quota_create("test_multiple_reclaims_can_be_triggered");
+ grpc_resource_quota_resize(q, 1024);
+ grpc_resource_user usr;
+ grpc_resource_user_init(&usr, q, "usr");
+ bool benign_done = false;
+ bool destructive_done = false;
+ {
+ bool done = false;
+ grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
+ grpc_resource_user_alloc(&exec_ctx, &usr, 1024, set_bool(&done));
+ grpc_exec_ctx_finish(&exec_ctx);
+ GPR_ASSERT(done);
+ }
+ {
+ grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
+ grpc_resource_user_post_reclaimer(
+ &exec_ctx, &usr, false,
+ make_reclaimer(&usr, 512, set_bool(&benign_done)));
+ grpc_resource_user_post_reclaimer(
+ &exec_ctx, &usr, true,
+ make_reclaimer(&usr, 512, set_bool(&destructive_done)));
+ grpc_exec_ctx_finish(&exec_ctx);
+ GPR_ASSERT(!benign_done);
+ GPR_ASSERT(!destructive_done);
+ }
+ {
+ bool done = false;
+ grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
+ grpc_resource_user_alloc(&exec_ctx, &usr, 1024, set_bool(&done));
+ grpc_exec_ctx_finish(&exec_ctx);
+ GPR_ASSERT(benign_done);
+ GPR_ASSERT(destructive_done);
+ GPR_ASSERT(done);
+ }
+ {
+ grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
+ grpc_resource_user_free(&exec_ctx, &usr, 1024);
+ grpc_exec_ctx_finish(&exec_ctx);
+ }
+ grpc_resource_quota_unref(q);
+ destroy_user(&usr);
+ GPR_ASSERT(benign_done);
+ GPR_ASSERT(destructive_done);
+}
+
+static void test_resource_user_stays_allocated_until_memory_released(void) {
+ gpr_log(GPR_INFO,
+ "** test_resource_user_stays_allocated_until_memory_released **");
+ grpc_resource_quota *q = grpc_resource_quota_create(
+ "test_resource_user_stays_allocated_until_memory_released");
+ grpc_resource_quota_resize(q, 1024 * 1024);
+ grpc_resource_user usr;
+ grpc_resource_user_init(&usr, q, "usr");
+ bool done = false;
+ {
+ grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
+ grpc_resource_user_alloc(&exec_ctx, &usr, 1024, NULL);
+ grpc_exec_ctx_finish(&exec_ctx);
+ }
+ {
+ grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
+ grpc_resource_quota_unref(q);
+ grpc_resource_user_shutdown(&exec_ctx, &usr, set_bool(&done));
+ grpc_exec_ctx_finish(&exec_ctx);
+ GPR_ASSERT(!done);
+ }
+ {
+ grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
+ grpc_resource_user_free(&exec_ctx, &usr, 1024);
+ grpc_exec_ctx_finish(&exec_ctx);
+ GPR_ASSERT(done);
+ }
+ {
+ grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
+ grpc_resource_user_destroy(&exec_ctx, &usr);
+ grpc_exec_ctx_finish(&exec_ctx);
+ }
+}
+
+static void
+test_resource_user_stays_allocated_and_reclaimers_unrun_until_memory_released(
+ void) {
+ gpr_log(GPR_INFO,
+ "** "
+ "test_resource_user_stays_allocated_and_reclaimers_unrun_until_"
+ "memory_released **");
+ grpc_resource_quota *q = grpc_resource_quota_create(
+ "test_resource_user_stays_allocated_and_reclaimers_unrun_until_memory_"
+ "released");
+ grpc_resource_quota_resize(q, 1024);
+ for (int i = 0; i < 10; i++) {
+ grpc_resource_user usr;
+ grpc_resource_user_init(&usr, q, "usr");
+ bool done = false;
+ bool reclaimer_cancelled = false;
+ {
+ grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
+ grpc_resource_user_post_reclaimer(
+ &exec_ctx, &usr, false,
+ make_unused_reclaimer(set_bool(&reclaimer_cancelled)));
+ grpc_exec_ctx_finish(&exec_ctx);
+ GPR_ASSERT(!reclaimer_cancelled);
+ }
+ {
+ bool allocated = false;
+ grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
+ grpc_resource_user_alloc(&exec_ctx, &usr, 1024, set_bool(&allocated));
+ grpc_exec_ctx_finish(&exec_ctx);
+ GPR_ASSERT(allocated);
+ GPR_ASSERT(!reclaimer_cancelled);
+ }
+ {
+ grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
+ grpc_resource_user_shutdown(&exec_ctx, &usr, set_bool(&done));
+ grpc_exec_ctx_finish(&exec_ctx);
+ GPR_ASSERT(!done);
+ GPR_ASSERT(!reclaimer_cancelled);
+ }
+ {
+ grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
+ grpc_resource_user_free(&exec_ctx, &usr, 1024);
+ grpc_exec_ctx_finish(&exec_ctx);
+ GPR_ASSERT(done);
+ GPR_ASSERT(reclaimer_cancelled);
+ }
+ {
+ grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
+ grpc_resource_user_destroy(&exec_ctx, &usr);
+ grpc_exec_ctx_finish(&exec_ctx);
+ }
+ }
+ grpc_resource_quota_unref(q);
+}
+
+static void test_reclaimers_can_be_posted_repeatedly(void) {
+ gpr_log(GPR_INFO, "** test_reclaimers_can_be_posted_repeatedly **");
+ grpc_resource_quota *q =
+ grpc_resource_quota_create("test_reclaimers_can_be_posted_repeatedly");
+ grpc_resource_quota_resize(q, 1024);
+ grpc_resource_user usr;
+ grpc_resource_user_init(&usr, q, "usr");
+ {
+ bool allocated = false;
+ grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
+ grpc_resource_user_alloc(&exec_ctx, &usr, 1024, set_bool(&allocated));
+ grpc_exec_ctx_finish(&exec_ctx);
+ GPR_ASSERT(allocated);
+ }
+ for (int i = 0; i < 10; i++) {
+ bool reclaimer_done = false;
+ {
+ grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
+ grpc_resource_user_post_reclaimer(
+ &exec_ctx, &usr, false,
+ make_reclaimer(&usr, 1024, set_bool(&reclaimer_done)));
+ grpc_exec_ctx_finish(&exec_ctx);
+ GPR_ASSERT(!reclaimer_done);
+ }
+ {
+ bool allocated = false;
+ grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
+ grpc_resource_user_alloc(&exec_ctx, &usr, 1024, set_bool(&allocated));
+ grpc_exec_ctx_finish(&exec_ctx);
+ GPR_ASSERT(allocated);
+ GPR_ASSERT(reclaimer_done);
+ }
+ }
+ {
+ grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
+ grpc_resource_user_free(&exec_ctx, &usr, 1024);
+ grpc_exec_ctx_finish(&exec_ctx);
+ }
+ destroy_user(&usr);
+ grpc_resource_quota_unref(q);
+}
+
+static void test_one_slice(void) {
+ gpr_log(GPR_INFO, "** test_one_slice **");
+
+ grpc_resource_quota *q = grpc_resource_quota_create("test_one_slice");
+ grpc_resource_quota_resize(q, 1024);
+
+ grpc_resource_user usr;
+ grpc_resource_user_init(&usr, q, "usr");
+
+ grpc_resource_user_slice_allocator alloc;
+ int num_allocs = 0;
+ grpc_resource_user_slice_allocator_init(&alloc, &usr, inc_int_cb,
+ &num_allocs);
+
+ gpr_slice_buffer buffer;
+ gpr_slice_buffer_init(&buffer);
+
+ {
+ const int start_allocs = num_allocs;
+ grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
+ grpc_resource_user_alloc_slices(&exec_ctx, &alloc, 1024, 1, &buffer);
+ grpc_exec_ctx_finish(&exec_ctx);
+ GPR_ASSERT(num_allocs == start_allocs + 1);
+ }
+
+ gpr_slice_buffer_destroy(&buffer);
+ destroy_user(&usr);
+ grpc_resource_quota_unref(q);
+}
+
+static void test_one_slice_deleted_late(void) {
+ gpr_log(GPR_INFO, "** test_one_slice_deleted_late **");
+
+ grpc_resource_quota *q =
+ grpc_resource_quota_create("test_one_slice_deleted_late");
+ grpc_resource_quota_resize(q, 1024);
+
+ grpc_resource_user usr;
+ grpc_resource_user_init(&usr, q, "usr");
+
+ grpc_resource_user_slice_allocator alloc;
+ int num_allocs = 0;
+ grpc_resource_user_slice_allocator_init(&alloc, &usr, inc_int_cb,
+ &num_allocs);
+
+ gpr_slice_buffer buffer;
+ gpr_slice_buffer_init(&buffer);
+
+ {
+ const int start_allocs = num_allocs;
+ grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
+ grpc_resource_user_alloc_slices(&exec_ctx, &alloc, 1024, 1, &buffer);
+ grpc_exec_ctx_finish(&exec_ctx);
+ GPR_ASSERT(num_allocs == start_allocs + 1);
+ }
+
+ bool done = false;
+ {
+ grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
+ grpc_resource_user_shutdown(&exec_ctx, &usr, set_bool(&done));
+ grpc_exec_ctx_finish(&exec_ctx);
+ GPR_ASSERT(!done);
+ }
+
+ grpc_resource_quota_unref(q);
+ gpr_slice_buffer_destroy(&buffer);
+ GPR_ASSERT(done);
+ {
+ grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
+ grpc_resource_user_destroy(&exec_ctx, &usr);
+ grpc_exec_ctx_finish(&exec_ctx);
+ }
+}
+
+int main(int argc, char **argv) {
+ grpc_test_init(argc, argv);
+ grpc_init();
+ test_no_op();
+ test_resize_then_destroy();
+ test_resource_user_no_op();
+ test_instant_alloc_then_free();
+ test_instant_alloc_free_pair();
+ test_simple_async_alloc();
+ test_async_alloc_blocked_by_size();
+ test_scavenge();
+ test_scavenge_blocked();
+ test_blocked_until_scheduled_reclaim();
+ test_blocked_until_scheduled_reclaim_and_scavenge();
+ test_blocked_until_scheduled_destructive_reclaim();
+ test_unused_reclaim_is_cancelled();
+ test_benign_reclaim_is_preferred();
+ test_multiple_reclaims_can_be_triggered();
+ test_resource_user_stays_allocated_until_memory_released();
+ test_resource_user_stays_allocated_and_reclaimers_unrun_until_memory_released();
+ test_reclaimers_can_be_posted_repeatedly();
+ test_one_slice();
+ test_one_slice_deleted_late();
+ grpc_shutdown();
+ return 0;
+}
diff --git a/test/core/iomgr/sockaddr_utils_test.c b/test/core/iomgr/sockaddr_utils_test.c
index a330314443..8569c697fe 100644
--- a/test/core/iomgr/sockaddr_utils_test.c
+++ b/test/core/iomgr/sockaddr_utils_test.c
@@ -31,6 +31,11 @@
*
*/
+/* With the addition of a libuv endpoint, sockaddr.h now includes uv.h when
+ using that endpoint. Because of various transitive includes in uv.h,
+ including windows.h on Windows, uv.h must be included before other system
+ headers. Therefore, sockaddr.h must always be included first */
+#include "src/core/lib/iomgr/sockaddr.h"
#include "src/core/lib/iomgr/sockaddr_utils.h"
#include <errno.h>
@@ -41,24 +46,28 @@
#include <grpc/support/port_platform.h>
#include "test/core/util/test_config.h"
-static struct sockaddr_in make_addr4(const uint8_t *data, size_t data_len) {
- struct sockaddr_in addr4;
- memset(&addr4, 0, sizeof(addr4));
- addr4.sin_family = AF_INET;
- GPR_ASSERT(data_len == sizeof(addr4.sin_addr.s_addr));
- memcpy(&addr4.sin_addr.s_addr, data, data_len);
- addr4.sin_port = htons(12345);
- return addr4;
+static grpc_resolved_address make_addr4(const uint8_t *data, size_t data_len) {
+ grpc_resolved_address resolved_addr4;
+ struct sockaddr_in *addr4 = (struct sockaddr_in *)resolved_addr4.addr;
+ memset(&resolved_addr4, 0, sizeof(resolved_addr4));
+ addr4->sin_family = AF_INET;
+ GPR_ASSERT(data_len == sizeof(addr4->sin_addr.s_addr));
+ memcpy(&addr4->sin_addr.s_addr, data, data_len);
+ addr4->sin_port = htons(12345);
+ resolved_addr4.len = sizeof(struct sockaddr_in);
+ return resolved_addr4;
}
-static struct sockaddr_in6 make_addr6(const uint8_t *data, size_t data_len) {
- struct sockaddr_in6 addr6;
- memset(&addr6, 0, sizeof(addr6));
- addr6.sin6_family = AF_INET6;
- GPR_ASSERT(data_len == sizeof(addr6.sin6_addr.s6_addr));
- memcpy(&addr6.sin6_addr.s6_addr, data, data_len);
- addr6.sin6_port = htons(12345);
- return addr6;
+static grpc_resolved_address make_addr6(const uint8_t *data, size_t data_len) {
+ grpc_resolved_address resolved_addr6;
+ struct sockaddr_in6 *addr6 = (struct sockaddr_in6 *)resolved_addr6.addr;
+ memset(&resolved_addr6, 0, sizeof(resolved_addr6));
+ addr6->sin6_family = AF_INET6;
+ GPR_ASSERT(data_len == sizeof(addr6->sin6_addr.s6_addr));
+ memcpy(&addr6->sin6_addr.s6_addr, data, data_len);
+ addr6->sin6_port = htons(12345);
+ resolved_addr6.len = sizeof(struct sockaddr_in6);
+ return resolved_addr6;
}
static const uint8_t kMapped[] = {0, 0, 0, 0, 0, 0, 0, 0,
@@ -72,102 +81,96 @@ static const uint8_t kIPv6[] = {0x20, 0x01, 0x0d, 0xb8, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 1};
static void test_sockaddr_is_v4mapped(void) {
- struct sockaddr_in input4;
- struct sockaddr_in6 input6;
- struct sockaddr_in output4;
- struct sockaddr_in expect4;
+ grpc_resolved_address input4;
+ grpc_resolved_address input6;
+ grpc_resolved_address output4;
+ grpc_resolved_address expect4;
gpr_log(GPR_INFO, "%s", "test_sockaddr_is_v4mapped");
/* v4mapped input should succeed. */
input6 = make_addr6(kMapped, sizeof(kMapped));
- GPR_ASSERT(grpc_sockaddr_is_v4mapped((const struct sockaddr *)&input6, NULL));
- GPR_ASSERT(
- grpc_sockaddr_is_v4mapped((const struct sockaddr *)&input6, &output4));
+ GPR_ASSERT(grpc_sockaddr_is_v4mapped(&input6, NULL));
+ GPR_ASSERT(grpc_sockaddr_is_v4mapped(&input6, &output4));
expect4 = make_addr4(kIPv4, sizeof(kIPv4));
GPR_ASSERT(memcmp(&expect4, &output4, sizeof(expect4)) == 0);
/* Non-v4mapped input should fail. */
input6 = make_addr6(kNotQuiteMapped, sizeof(kNotQuiteMapped));
- GPR_ASSERT(
- !grpc_sockaddr_is_v4mapped((const struct sockaddr *)&input6, NULL));
- GPR_ASSERT(
- !grpc_sockaddr_is_v4mapped((const struct sockaddr *)&input6, &output4));
+ GPR_ASSERT(!grpc_sockaddr_is_v4mapped(&input6, NULL));
+ GPR_ASSERT(!grpc_sockaddr_is_v4mapped(&input6, &output4));
/* Output is unchanged. */
GPR_ASSERT(memcmp(&expect4, &output4, sizeof(expect4)) == 0);
/* Plain IPv4 input should also fail. */
input4 = make_addr4(kIPv4, sizeof(kIPv4));
- GPR_ASSERT(
- !grpc_sockaddr_is_v4mapped((const struct sockaddr *)&input4, NULL));
+ GPR_ASSERT(!grpc_sockaddr_is_v4mapped(&input4, NULL));
}
static void test_sockaddr_to_v4mapped(void) {
- struct sockaddr_in input4;
- struct sockaddr_in6 input6;
- struct sockaddr_in6 output6;
- struct sockaddr_in6 expect6;
+ grpc_resolved_address input4;
+ grpc_resolved_address input6;
+ grpc_resolved_address output6;
+ grpc_resolved_address expect6;
gpr_log(GPR_INFO, "%s", "test_sockaddr_to_v4mapped");
/* IPv4 input should succeed. */
input4 = make_addr4(kIPv4, sizeof(kIPv4));
- GPR_ASSERT(
- grpc_sockaddr_to_v4mapped((const struct sockaddr *)&input4, &output6));
+ GPR_ASSERT(grpc_sockaddr_to_v4mapped(&input4, &output6));
expect6 = make_addr6(kMapped, sizeof(kMapped));
GPR_ASSERT(memcmp(&expect6, &output6, sizeof(output6)) == 0);
/* IPv6 input should fail. */
input6 = make_addr6(kIPv6, sizeof(kIPv6));
- GPR_ASSERT(
- !grpc_sockaddr_to_v4mapped((const struct sockaddr *)&input6, &output6));
+ GPR_ASSERT(!grpc_sockaddr_to_v4mapped(&input6, &output6));
/* Output is unchanged. */
GPR_ASSERT(memcmp(&expect6, &output6, sizeof(output6)) == 0);
/* Already-v4mapped input should also fail. */
input6 = make_addr6(kMapped, sizeof(kMapped));
- GPR_ASSERT(
- !grpc_sockaddr_to_v4mapped((const struct sockaddr *)&input6, &output6));
+ GPR_ASSERT(!grpc_sockaddr_to_v4mapped(&input6, &output6));
}
static void test_sockaddr_is_wildcard(void) {
- struct sockaddr_in wild4;
- struct sockaddr_in6 wild6;
- struct sockaddr_in6 wild_mapped;
- struct sockaddr dummy;
+ grpc_resolved_address wild4;
+ grpc_resolved_address wild6;
+ grpc_resolved_address wild_mapped;
+ grpc_resolved_address dummy;
+ struct sockaddr_in *wild4_addr;
+ struct sockaddr_in6 *wild6_addr;
+ struct sockaddr_in6 *wild_mapped_addr;
int port;
gpr_log(GPR_INFO, "%s", "test_sockaddr_is_wildcard");
/* Generate wildcards. */
grpc_sockaddr_make_wildcards(555, &wild4, &wild6);
- GPR_ASSERT(
- grpc_sockaddr_to_v4mapped((const struct sockaddr *)&wild4, &wild_mapped));
+ GPR_ASSERT(grpc_sockaddr_to_v4mapped(&wild4, &wild_mapped));
/* Test 0.0.0.0:555 */
port = -1;
- GPR_ASSERT(grpc_sockaddr_is_wildcard((const struct sockaddr *)&wild4, &port));
+ GPR_ASSERT(grpc_sockaddr_is_wildcard(&wild4, &port));
GPR_ASSERT(port == 555);
- memset(&wild4.sin_addr.s_addr, 0xbd, 1);
- GPR_ASSERT(
- !grpc_sockaddr_is_wildcard((const struct sockaddr *)&wild4, &port));
+ wild4_addr = (struct sockaddr_in *)&wild4.addr;
+ memset(&wild4_addr->sin_addr.s_addr, 0xbd, 1);
+ GPR_ASSERT(!grpc_sockaddr_is_wildcard(&wild4, &port));
/* Test [::]:555 */
port = -1;
- GPR_ASSERT(grpc_sockaddr_is_wildcard((const struct sockaddr *)&wild6, &port));
+ GPR_ASSERT(grpc_sockaddr_is_wildcard(&wild6, &port));
GPR_ASSERT(port == 555);
- memset(&wild6.sin6_addr.s6_addr, 0xbd, 1);
- GPR_ASSERT(
- !grpc_sockaddr_is_wildcard((const struct sockaddr *)&wild6, &port));
+ wild6_addr = (struct sockaddr_in6 *)&wild6.addr;
+ memset(&wild6_addr->sin6_addr.s6_addr, 0xbd, 1);
+ GPR_ASSERT(!grpc_sockaddr_is_wildcard(&wild6, &port));
/* Test [::ffff:0.0.0.0]:555 */
port = -1;
- GPR_ASSERT(
- grpc_sockaddr_is_wildcard((const struct sockaddr *)&wild_mapped, &port));
+ GPR_ASSERT(grpc_sockaddr_is_wildcard(&wild_mapped, &port));
GPR_ASSERT(port == 555);
- memset(&wild_mapped.sin6_addr.s6_addr, 0xbd, 1);
- GPR_ASSERT(
- !grpc_sockaddr_is_wildcard((const struct sockaddr *)&wild_mapped, &port));
+ wild_mapped_addr = (struct sockaddr_in6 *)&wild_mapped.addr;
+ memset(&wild_mapped_addr->sin6_addr.s6_addr, 0xbd, 1);
+ GPR_ASSERT(!grpc_sockaddr_is_wildcard(&wild_mapped, &port));
/* Test AF_UNSPEC. */
port = -1;
@@ -176,12 +179,12 @@ static void test_sockaddr_is_wildcard(void) {
GPR_ASSERT(port == -1);
}
-static void expect_sockaddr_str(const char *expected, void *addr,
- int normalize) {
+static void expect_sockaddr_str(const char *expected,
+ grpc_resolved_address *addr, int normalize) {
int result;
char *str;
gpr_log(GPR_INFO, " expect_sockaddr_str(%s)", expected);
- result = grpc_sockaddr_to_string(&str, (struct sockaddr *)addr, normalize);
+ result = grpc_sockaddr_to_string(&str, addr, normalize);
GPR_ASSERT(str != NULL);
GPR_ASSERT(result >= 0);
GPR_ASSERT((size_t)result == strlen(str));
@@ -189,19 +192,21 @@ static void expect_sockaddr_str(const char *expected, void *addr,
gpr_free(str);
}
-static void expect_sockaddr_uri(const char *expected, void *addr) {
+static void expect_sockaddr_uri(const char *expected,
+ grpc_resolved_address *addr) {
char *str;
gpr_log(GPR_INFO, " expect_sockaddr_uri(%s)", expected);
- str = grpc_sockaddr_to_uri((struct sockaddr *)addr);
+ str = grpc_sockaddr_to_uri(addr);
GPR_ASSERT(str != NULL);
GPR_ASSERT(strcmp(expected, str) == 0);
gpr_free(str);
}
static void test_sockaddr_to_string(void) {
- struct sockaddr_in input4;
- struct sockaddr_in6 input6;
- struct sockaddr dummy;
+ grpc_resolved_address input4;
+ grpc_resolved_address input6;
+ grpc_resolved_address dummy;
+ struct sockaddr *dummy_addr;
gpr_log(GPR_INFO, "%s", "test_sockaddr_to_string");
@@ -228,7 +233,8 @@ static void test_sockaddr_to_string(void) {
expect_sockaddr_uri("ipv6:[::fffe:c000:263]:12345", &input6);
memset(&dummy, 0, sizeof(dummy));
- dummy.sa_family = 123;
+ dummy_addr = (struct sockaddr *)dummy.addr;
+ dummy_addr->sa_family = 123;
expect_sockaddr_str("(sockaddr family=123)", &dummy, 0);
expect_sockaddr_str("(sockaddr family=123)", &dummy, 1);
GPR_ASSERT(grpc_sockaddr_to_uri(&dummy) == NULL);
@@ -237,24 +243,26 @@ static void test_sockaddr_to_string(void) {
}
static void test_sockaddr_set_get_port(void) {
- struct sockaddr_in input4;
- struct sockaddr_in6 input6;
- struct sockaddr dummy;
+ grpc_resolved_address input4;
+ grpc_resolved_address input6;
+ grpc_resolved_address dummy;
+ struct sockaddr *dummy_addr;
gpr_log(GPR_DEBUG, "test_sockaddr_set_get_port");
input4 = make_addr4(kIPv4, sizeof(kIPv4));
- GPR_ASSERT(grpc_sockaddr_get_port((struct sockaddr *)&input4) == 12345);
- GPR_ASSERT(grpc_sockaddr_set_port((struct sockaddr *)&input4, 54321));
- GPR_ASSERT(grpc_sockaddr_get_port((struct sockaddr *)&input4) == 54321);
+ GPR_ASSERT(grpc_sockaddr_get_port(&input4) == 12345);
+ GPR_ASSERT(grpc_sockaddr_set_port(&input4, 54321));
+ GPR_ASSERT(grpc_sockaddr_get_port(&input4) == 54321);
input6 = make_addr6(kIPv6, sizeof(kIPv6));
- GPR_ASSERT(grpc_sockaddr_get_port((struct sockaddr *)&input6) == 12345);
- GPR_ASSERT(grpc_sockaddr_set_port((struct sockaddr *)&input6, 54321));
- GPR_ASSERT(grpc_sockaddr_get_port((struct sockaddr *)&input6) == 54321);
+ GPR_ASSERT(grpc_sockaddr_get_port(&input6) == 12345);
+ GPR_ASSERT(grpc_sockaddr_set_port(&input6, 54321));
+ GPR_ASSERT(grpc_sockaddr_get_port(&input6) == 54321);
memset(&dummy, 0, sizeof(dummy));
- dummy.sa_family = 123;
+ dummy_addr = (struct sockaddr *)dummy.addr;
+ dummy_addr->sa_family = 123;
GPR_ASSERT(grpc_sockaddr_get_port(&dummy) == 0);
GPR_ASSERT(grpc_sockaddr_set_port(&dummy, 1234) == 0);
}
diff --git a/test/core/iomgr/socket_utils_test.c b/test/core/iomgr/socket_utils_test.c
index 297531c44d..67bc914c15 100644
--- a/test/core/iomgr/socket_utils_test.c
+++ b/test/core/iomgr/socket_utils_test.c
@@ -31,7 +31,11 @@
*
*/
-#include <grpc/support/port_platform.h>
+#include "src/core/lib/iomgr/port.h"
+
+// This test won't work except with posix sockets enabled
+#ifdef GRPC_POSIX_SOCKET
+
#include "src/core/lib/iomgr/socket_utils_posix.h"
#include <errno.h>
@@ -68,3 +72,9 @@ int main(int argc, char **argv) {
return 0;
}
+
+#else /* GRPC_POSIX_SOCKET */
+
+int main(int argc, char **argv) { return 1; }
+
+#endif /* GRPC_POSIX_SOCKET */
diff --git a/test/core/iomgr/tcp_client_posix_test.c b/test/core/iomgr/tcp_client_posix_test.c
index d0c1047423..5fab826fb7 100644
--- a/test/core/iomgr/tcp_client_posix_test.c
+++ b/test/core/iomgr/tcp_client_posix_test.c
@@ -85,8 +85,8 @@ static void must_fail(grpc_exec_ctx *exec_ctx, void *arg, grpc_error *error) {
}
void test_succeeds(void) {
- struct sockaddr_in addr;
- socklen_t addr_len = sizeof(addr);
+ grpc_resolved_address resolved_addr;
+ struct sockaddr_in *addr = (struct sockaddr_in *)resolved_addr.addr;
int svr_fd;
int r;
int connections_complete_before;
@@ -95,13 +95,15 @@ void test_succeeds(void) {
gpr_log(GPR_DEBUG, "test_succeeds");
- memset(&addr, 0, sizeof(addr));
- addr.sin_family = AF_INET;
+ memset(&resolved_addr, 0, sizeof(resolved_addr));
+ resolved_addr.len = sizeof(struct sockaddr_in);
+ addr->sin_family = AF_INET;
/* create a dummy server */
svr_fd = socket(AF_INET, SOCK_STREAM, 0);
GPR_ASSERT(svr_fd >= 0);
- GPR_ASSERT(0 == bind(svr_fd, (struct sockaddr *)&addr, addr_len));
+ GPR_ASSERT(
+ 0 == bind(svr_fd, (struct sockaddr *)addr, (socklen_t)resolved_addr.len));
GPR_ASSERT(0 == listen(svr_fd, 1));
gpr_mu_lock(g_mu);
@@ -109,16 +111,17 @@ void test_succeeds(void) {
gpr_mu_unlock(g_mu);
/* connect to it */
- GPR_ASSERT(getsockname(svr_fd, (struct sockaddr *)&addr, &addr_len) == 0);
+ GPR_ASSERT(getsockname(svr_fd, (struct sockaddr *)addr,
+ (socklen_t *)&resolved_addr.len) == 0);
grpc_closure_init(&done, must_succeed, NULL);
- grpc_tcp_client_connect(&exec_ctx, &done, &g_connecting, g_pollset_set,
- (struct sockaddr *)&addr, addr_len,
- gpr_inf_future(GPR_CLOCK_REALTIME));
+ grpc_tcp_client_connect(&exec_ctx, &done, &g_connecting, g_pollset_set, NULL,
+ &resolved_addr, gpr_inf_future(GPR_CLOCK_REALTIME));
/* await the connection */
do {
- addr_len = sizeof(addr);
- r = accept(svr_fd, (struct sockaddr *)&addr, &addr_len);
+ resolved_addr.len = sizeof(addr);
+ r = accept(svr_fd, (struct sockaddr *)addr,
+ (socklen_t *)&resolved_addr.len);
} while (r == -1 && errno == EINTR);
GPR_ASSERT(r >= 0);
close(r);
@@ -143,16 +146,17 @@ void test_succeeds(void) {
}
void test_fails(void) {
- struct sockaddr_in addr;
- socklen_t addr_len = sizeof(addr);
+ grpc_resolved_address resolved_addr;
+ struct sockaddr_in *addr = (struct sockaddr_in *)resolved_addr.addr;
int connections_complete_before;
grpc_closure done;
grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
gpr_log(GPR_DEBUG, "test_fails");
- memset(&addr, 0, sizeof(addr));
- addr.sin_family = AF_INET;
+ memset(&resolved_addr, 0, sizeof(resolved_addr));
+ resolved_addr.len = sizeof(struct sockaddr_in);
+ addr->sin_family = AF_INET;
gpr_mu_lock(g_mu);
connections_complete_before = g_connections_complete;
@@ -160,9 +164,8 @@ void test_fails(void) {
/* connect to a broken address */
grpc_closure_init(&done, must_fail, NULL);
- grpc_tcp_client_connect(&exec_ctx, &done, &g_connecting, g_pollset_set,
- (struct sockaddr *)&addr, addr_len,
- gpr_inf_future(GPR_CLOCK_REALTIME));
+ grpc_tcp_client_connect(&exec_ctx, &done, &g_connecting, g_pollset_set, NULL,
+ &resolved_addr, gpr_inf_future(GPR_CLOCK_REALTIME));
gpr_mu_lock(g_mu);
diff --git a/test/core/iomgr/tcp_posix_test.c b/test/core/iomgr/tcp_posix_test.c
index 42614567ca..29f12a5afb 100644
--- a/test/core/iomgr/tcp_posix_test.c
+++ b/test/core/iomgr/tcp_posix_test.c
@@ -31,6 +31,11 @@
*
*/
+#include "src/core/lib/iomgr/port.h"
+
+// This test won't work except with posix sockets enabled
+#ifdef GRPC_POSIX_SOCKET
+
#include "src/core/lib/iomgr/tcp_posix.h"
#include <errno.h>
@@ -176,7 +181,10 @@ static void read_test(size_t num_bytes, size_t slice_size) {
create_sockets(sv);
- ep = grpc_tcp_create(grpc_fd_create(sv[1], "read_test"), slice_size, "test");
+ grpc_resource_quota *resource_quota = grpc_resource_quota_create("read_test");
+ ep = grpc_tcp_create(grpc_fd_create(sv[1], "read_test"), resource_quota,
+ slice_size, "test");
+ grpc_resource_quota_internal_unref(&exec_ctx, resource_quota);
grpc_endpoint_add_to_pollset(&exec_ctx, ep, g_pollset);
written_bytes = fill_socket_partial(sv[0], num_bytes);
@@ -223,8 +231,11 @@ static void large_read_test(size_t slice_size) {
create_sockets(sv);
- ep = grpc_tcp_create(grpc_fd_create(sv[1], "large_read_test"), slice_size,
- "test");
+ grpc_resource_quota *resource_quota =
+ grpc_resource_quota_create("large_read_test");
+ ep = grpc_tcp_create(grpc_fd_create(sv[1], "large_read_test"), resource_quota,
+ slice_size, "test");
+ grpc_resource_quota_internal_unref(&exec_ctx, resource_quota);
grpc_endpoint_add_to_pollset(&exec_ctx, ep, g_pollset);
written_bytes = fill_socket(sv[0]);
@@ -359,8 +370,11 @@ static void write_test(size_t num_bytes, size_t slice_size) {
create_sockets(sv);
- ep = grpc_tcp_create(grpc_fd_create(sv[1], "write_test"),
+ grpc_resource_quota *resource_quota =
+ grpc_resource_quota_create("write_test");
+ ep = grpc_tcp_create(grpc_fd_create(sv[1], "write_test"), resource_quota,
GRPC_TCP_DEFAULT_READ_SLICE_SIZE, "test");
+ grpc_resource_quota_internal_unref(&exec_ctx, resource_quota);
grpc_endpoint_add_to_pollset(&exec_ctx, ep, g_pollset);
state.ep = ep;
@@ -423,8 +437,12 @@ static void release_fd_test(size_t num_bytes, size_t slice_size) {
create_sockets(sv);
- ep = grpc_tcp_create(grpc_fd_create(sv[1], "read_test"), slice_size, "test");
+ grpc_resource_quota *resource_quota =
+ grpc_resource_quota_create("release_fd_test");
+ ep = grpc_tcp_create(grpc_fd_create(sv[1], "read_test"), resource_quota,
+ slice_size, "test");
GPR_ASSERT(grpc_tcp_fd(ep) == sv[1] && sv[1] >= 0);
+ grpc_resource_quota_internal_unref(&exec_ctx, resource_quota);
grpc_endpoint_add_to_pollset(&exec_ctx, ep, g_pollset);
written_bytes = fill_socket_partial(sv[0], num_bytes);
@@ -445,8 +463,10 @@ static void release_fd_test(size_t num_bytes, size_t slice_size) {
"pollset_work",
grpc_pollset_work(&exec_ctx, g_pollset, &worker,
gpr_now(GPR_CLOCK_MONOTONIC), deadline)));
+ gpr_log(GPR_DEBUG, "wakeup: read=%" PRIdPTR " target=%" PRIdPTR,
+ state.read_bytes, state.target_read_bytes);
gpr_mu_unlock(g_mu);
- grpc_exec_ctx_finish(&exec_ctx);
+ grpc_exec_ctx_flush(&exec_ctx);
gpr_mu_lock(g_mu);
}
GPR_ASSERT(state.read_bytes == state.target_read_bytes);
@@ -454,6 +474,7 @@ static void release_fd_test(size_t num_bytes, size_t slice_size) {
gpr_slice_buffer_destroy(&state.incoming);
grpc_tcp_destroy_and_release_fd(&exec_ctx, ep, &fd, &fd_released_cb);
+ grpc_exec_ctx_flush(&exec_ctx);
gpr_mu_lock(g_mu);
while (!fd_released_done) {
grpc_pollset_worker *worker = NULL;
@@ -461,6 +482,7 @@ static void release_fd_test(size_t num_bytes, size_t slice_size) {
"pollset_work",
grpc_pollset_work(&exec_ctx, g_pollset, &worker,
gpr_now(GPR_CLOCK_MONOTONIC), deadline)));
+ gpr_log(GPR_DEBUG, "wakeup: fd_released_done=%d", fd_released_done);
}
gpr_mu_unlock(g_mu);
GPR_ASSERT(fd_released_done == 1);
@@ -506,10 +528,13 @@ static grpc_endpoint_test_fixture create_fixture_tcp_socketpair(
grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
create_sockets(sv);
+ grpc_resource_quota *resource_quota =
+ grpc_resource_quota_create("tcp_posix_test_socketpair");
f.client_ep = grpc_tcp_create(grpc_fd_create(sv[0], "fixture:client"),
- slice_size, "test");
+ resource_quota, slice_size, "test");
f.server_ep = grpc_tcp_create(grpc_fd_create(sv[1], "fixture:server"),
- slice_size, "test");
+ resource_quota, slice_size, "test");
+ grpc_resource_quota_internal_unref(&exec_ctx, resource_quota);
grpc_endpoint_add_to_pollset(&exec_ctx, f.client_ep, g_pollset);
grpc_endpoint_add_to_pollset(&exec_ctx, f.server_ep, g_pollset);
@@ -544,3 +569,9 @@ int main(int argc, char **argv) {
return 0;
}
+
+#else /* GRPC_POSIX_SOCKET */
+
+int main(int argc, char **argv) { return 1; }
+
+#endif /* GRPC_POSIX_SOCKET */
diff --git a/test/core/iomgr/tcp_server_posix_test.c b/test/core/iomgr/tcp_server_posix_test.c
index 6e2d1d0fc9..1b8a39c1be 100644
--- a/test/core/iomgr/tcp_server_posix_test.c
+++ b/test/core/iomgr/tcp_server_posix_test.c
@@ -31,6 +31,11 @@
*
*/
+#include "src/core/lib/iomgr/port.h"
+
+// This test won't work except with posix sockets enabled
+#ifdef GRPC_POSIX_SOCKET
+
#include "src/core/lib/iomgr/tcp_server.h"
#include <errno.h>
@@ -46,6 +51,7 @@
#include <grpc/support/time.h>
#include "src/core/lib/iomgr/iomgr.h"
+#include "src/core/lib/iomgr/resolve_address.h"
#include "src/core/lib/iomgr/sockaddr_utils.h"
#include "test/core/util/port.h"
#include "test/core/util/test_config.h"
@@ -118,8 +124,11 @@ static void on_connect(grpc_exec_ctx *exec_ctx, void *arg, grpc_endpoint *tcp,
grpc_endpoint_shutdown(exec_ctx, tcp);
grpc_endpoint_destroy(exec_ctx, tcp);
+ on_connect_result temp_result;
+ on_connect_result_set(&temp_result, acceptor);
+
gpr_mu_lock(g_mu);
- on_connect_result_set(&g_result, acceptor);
+ g_result = temp_result;
g_nconnects++;
GPR_ASSERT(
GRPC_LOG_IF_ERROR("pollset_kick", grpc_pollset_kick(g_pollset, NULL)));
@@ -129,7 +138,8 @@ static void on_connect(grpc_exec_ctx *exec_ctx, void *arg, grpc_endpoint *tcp,
static void test_no_op(void) {
grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
grpc_tcp_server *s;
- GPR_ASSERT(GRPC_ERROR_NONE == grpc_tcp_server_create(NULL, NULL, &s));
+ GPR_ASSERT(GRPC_ERROR_NONE ==
+ grpc_tcp_server_create(&exec_ctx, NULL, NULL, &s));
grpc_tcp_server_unref(&exec_ctx, s);
grpc_exec_ctx_finish(&exec_ctx);
}
@@ -137,7 +147,8 @@ static void test_no_op(void) {
static void test_no_op_with_start(void) {
grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
grpc_tcp_server *s;
- GPR_ASSERT(GRPC_ERROR_NONE == grpc_tcp_server_create(NULL, NULL, &s));
+ GPR_ASSERT(GRPC_ERROR_NONE ==
+ grpc_tcp_server_create(&exec_ctx, NULL, NULL, &s));
LOG_TEST("test_no_op_with_start");
grpc_tcp_server_start(&exec_ctx, s, NULL, 0, on_connect, NULL);
grpc_tcp_server_unref(&exec_ctx, s);
@@ -146,16 +157,19 @@ static void test_no_op_with_start(void) {
static void test_no_op_with_port(void) {
grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
- struct sockaddr_in addr;
+ grpc_resolved_address resolved_addr;
+ struct sockaddr_in *addr = (struct sockaddr_in *)resolved_addr.addr;
grpc_tcp_server *s;
- GPR_ASSERT(GRPC_ERROR_NONE == grpc_tcp_server_create(NULL, NULL, &s));
+ GPR_ASSERT(GRPC_ERROR_NONE ==
+ grpc_tcp_server_create(&exec_ctx, NULL, NULL, &s));
LOG_TEST("test_no_op_with_port");
- memset(&addr, 0, sizeof(addr));
- addr.sin_family = AF_INET;
+ memset(&resolved_addr, 0, sizeof(resolved_addr));
+ resolved_addr.len = sizeof(struct sockaddr_in);
+ addr->sin_family = AF_INET;
int port;
- GPR_ASSERT(grpc_tcp_server_add_port(s, (struct sockaddr *)&addr, sizeof(addr),
- &port) == GRPC_ERROR_NONE &&
+ GPR_ASSERT(grpc_tcp_server_add_port(s, &resolved_addr, &port) ==
+ GRPC_ERROR_NONE &&
port > 0);
grpc_tcp_server_unref(&exec_ctx, s);
@@ -164,16 +178,19 @@ static void test_no_op_with_port(void) {
static void test_no_op_with_port_and_start(void) {
grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
- struct sockaddr_in addr;
+ grpc_resolved_address resolved_addr;
+ struct sockaddr_in *addr = (struct sockaddr_in *)resolved_addr.addr;
grpc_tcp_server *s;
- GPR_ASSERT(GRPC_ERROR_NONE == grpc_tcp_server_create(NULL, NULL, &s));
+ GPR_ASSERT(GRPC_ERROR_NONE ==
+ grpc_tcp_server_create(&exec_ctx, NULL, NULL, &s));
LOG_TEST("test_no_op_with_port_and_start");
int port;
- memset(&addr, 0, sizeof(addr));
- addr.sin_family = AF_INET;
- GPR_ASSERT(grpc_tcp_server_add_port(s, (struct sockaddr *)&addr, sizeof(addr),
- &port) == GRPC_ERROR_NONE &&
+ memset(&resolved_addr, 0, sizeof(resolved_addr));
+ resolved_addr.len = sizeof(struct sockaddr_in);
+ addr->sin_family = AF_INET;
+ GPR_ASSERT(grpc_tcp_server_add_port(s, &resolved_addr, &port) ==
+ GRPC_ERROR_NONE &&
port > 0);
grpc_tcp_server_start(&exec_ctx, s, NULL, 0, on_connect, NULL);
@@ -218,33 +235,37 @@ static void tcp_connect(grpc_exec_ctx *exec_ctx, const struct sockaddr *remote,
the same port should be tested. */
static void test_connect(unsigned n) {
grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
- struct sockaddr_storage addr;
- struct sockaddr_storage addr1;
- socklen_t addr_len = sizeof(addr);
+ grpc_resolved_address resolved_addr;
+ grpc_resolved_address resolved_addr1;
+ struct sockaddr_storage *addr = (struct sockaddr_storage *)resolved_addr.addr;
+ struct sockaddr_storage *addr1 =
+ (struct sockaddr_storage *)resolved_addr1.addr;
unsigned svr_fd_count;
int svr_port;
unsigned svr1_fd_count;
int svr1_port;
grpc_tcp_server *s;
- GPR_ASSERT(GRPC_ERROR_NONE == grpc_tcp_server_create(NULL, NULL, &s));
+ GPR_ASSERT(GRPC_ERROR_NONE ==
+ grpc_tcp_server_create(&exec_ctx, NULL, NULL, &s));
unsigned i;
server_weak_ref weak_ref;
server_weak_ref_init(&weak_ref);
LOG_TEST("test_connect");
gpr_log(GPR_INFO, "clients=%d", n);
- memset(&addr, 0, sizeof(addr));
- memset(&addr1, 0, sizeof(addr1));
- addr.ss_family = addr1.ss_family = AF_INET;
+ memset(&resolved_addr, 0, sizeof(resolved_addr));
+ memset(&resolved_addr1, 0, sizeof(resolved_addr1));
+ resolved_addr.len = sizeof(struct sockaddr_storage);
+ resolved_addr1.len = sizeof(struct sockaddr_storage);
+ addr->ss_family = addr1->ss_family = AF_INET;
GPR_ASSERT(GRPC_ERROR_NONE ==
- grpc_tcp_server_add_port(s, (struct sockaddr *)&addr, addr_len,
- &svr_port));
+ grpc_tcp_server_add_port(s, &resolved_addr, &svr_port));
GPR_ASSERT(svr_port > 0);
/* Cannot use wildcard (port==0), because add_port() will try to reuse the
same port as a previous add_port(). */
svr1_port = grpc_pick_unused_port_or_die();
- grpc_sockaddr_set_port((struct sockaddr *)&addr1, svr1_port);
- GPR_ASSERT(grpc_tcp_server_add_port(s, (struct sockaddr *)&addr1, addr_len,
- &svr_port) == GRPC_ERROR_NONE &&
+ grpc_sockaddr_set_port(&resolved_addr1, svr1_port);
+ GPR_ASSERT(grpc_tcp_server_add_port(s, &resolved_addr1, &svr_port) ==
+ GRPC_ERROR_NONE &&
svr_port == svr1_port);
/* Bad port_index. */
@@ -265,16 +286,18 @@ static void test_connect(unsigned n) {
int fd = grpc_tcp_server_port_fd(s, 0, i);
GPR_ASSERT(fd >= 0);
if (i == 0) {
- GPR_ASSERT(getsockname(fd, (struct sockaddr *)&addr, &addr_len) == 0);
- GPR_ASSERT(addr_len <= sizeof(addr));
+ GPR_ASSERT(getsockname(fd, (struct sockaddr *)addr,
+ (socklen_t *)&resolved_addr.len) == 0);
+ GPR_ASSERT(resolved_addr.len <= sizeof(*addr));
}
}
for (i = 0; i < svr1_fd_count; ++i) {
int fd = grpc_tcp_server_port_fd(s, 1, i);
GPR_ASSERT(fd >= 0);
if (i == 0) {
- GPR_ASSERT(getsockname(fd, (struct sockaddr *)&addr1, &addr_len) == 0);
- GPR_ASSERT(addr_len <= sizeof(addr1));
+ GPR_ASSERT(getsockname(fd, (struct sockaddr *)addr1,
+ (socklen_t *)&resolved_addr1.len) == 0);
+ GPR_ASSERT(resolved_addr1.len <= sizeof(*addr1));
}
}
@@ -284,7 +307,8 @@ static void test_connect(unsigned n) {
on_connect_result result;
int svr_fd;
on_connect_result_init(&result);
- tcp_connect(&exec_ctx, (struct sockaddr *)&addr, addr_len, &result);
+ tcp_connect(&exec_ctx, (struct sockaddr *)addr,
+ (socklen_t)resolved_addr.len, &result);
GPR_ASSERT(result.server_fd >= 0);
svr_fd = result.server_fd;
GPR_ASSERT(grpc_tcp_server_port_fd(s, result.port_index, result.fd_index) ==
@@ -298,7 +322,8 @@ static void test_connect(unsigned n) {
grpc_tcp_server_unref(&exec_ctx, result.server);
on_connect_result_init(&result);
- tcp_connect(&exec_ctx, (struct sockaddr *)&addr1, addr_len, &result);
+ tcp_connect(&exec_ctx, (struct sockaddr *)addr1,
+ (socklen_t)resolved_addr1.len, &result);
GPR_ASSERT(result.server_fd >= 0);
GPR_ASSERT(result.server_fd != svr_fd);
GPR_ASSERT(grpc_tcp_server_port_fd(s, result.port_index, result.fd_index) ==
@@ -314,11 +339,10 @@ static void test_connect(unsigned n) {
GPR_ASSERT(grpc_tcp_server_port_fd(s, 0, 0) >= 0);
grpc_tcp_server_unref(&exec_ctx, s);
+ grpc_exec_ctx_finish(&exec_ctx);
/* Weak ref lost. */
GPR_ASSERT(weak_ref.server == NULL);
-
- grpc_exec_ctx_finish(&exec_ctx);
}
static void destroy_pollset(grpc_exec_ctx *exec_ctx, void *p,
@@ -348,3 +372,9 @@ int main(int argc, char **argv) {
gpr_free(g_pollset);
return 0;
}
+
+#else /* GRPC_POSIX_SOCKET */
+
+int main(int argc, char **argv) { return 1; }
+
+#endif /* GRPC_POSIX_SOCKET */
diff --git a/test/core/iomgr/timer_heap_test.c b/test/core/iomgr/timer_heap_test.c
index d1cb0047f2..410d972313 100644
--- a/test/core/iomgr/timer_heap_test.c
+++ b/test/core/iomgr/timer_heap_test.c
@@ -31,6 +31,11 @@
*
*/
+#include "src/core/lib/iomgr/port.h"
+
+// This test only works with the generic timer implementation
+#ifdef GRPC_TIMER_USE_GENERIC
+
#include "src/core/lib/iomgr/timer_heap.h"
#include <stdlib.h>
@@ -315,3 +320,9 @@ int main(int argc, char **argv) {
return 0;
}
+
+#else /* GRPC_TIMER_USE_GENERIC */
+
+int main(int argc, char **argv) { return 1; }
+
+#endif /* GRPC_TIMER_USE_GENERIC */
diff --git a/test/core/iomgr/udp_server_test.c b/test/core/iomgr/udp_server_test.c
index a959a7e07f..9bea229466 100644
--- a/test/core/iomgr/udp_server_test.c
+++ b/test/core/iomgr/udp_server_test.c
@@ -31,6 +31,11 @@
*
*/
+#include "src/core/lib/iomgr/port.h"
+
+// This test won't work except with posix sockets enabled
+#ifdef GRPC_POSIX_SOCKET
+
#include "src/core/lib/iomgr/udp_server.h"
#include <netinet/in.h>
@@ -48,8 +53,6 @@
#include "src/core/lib/iomgr/iomgr.h"
#include "test/core/util/test_config.h"
-#ifdef GRPC_NEED_UDP
-
#define LOG_TEST(x) gpr_log(GPR_INFO, "%s", #x)
static grpc_pollset *g_pollset;
@@ -100,14 +103,16 @@ static void test_no_op_with_start(void) {
static void test_no_op_with_port(void) {
g_number_of_orphan_calls = 0;
grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
- struct sockaddr_in addr;
+ grpc_resolved_address resolved_addr;
+ struct sockaddr_in *addr = (struct sockaddr_in *)resolved_addr.addr;
grpc_udp_server *s = grpc_udp_server_create();
LOG_TEST("test_no_op_with_port");
- memset(&addr, 0, sizeof(addr));
- addr.sin_family = AF_INET;
- GPR_ASSERT(grpc_udp_server_add_port(s, (struct sockaddr *)&addr, sizeof(addr),
- on_read, on_fd_orphaned));
+ memset(&resolved_addr, 0, sizeof(resolved_addr));
+ resolved_addr.len = sizeof(struct sockaddr_in);
+ addr->sin_family = AF_INET;
+ GPR_ASSERT(
+ grpc_udp_server_add_port(s, &resolved_addr, on_read, on_fd_orphaned));
grpc_udp_server_destroy(&exec_ctx, s, NULL);
grpc_exec_ctx_finish(&exec_ctx);
@@ -119,28 +124,31 @@ static void test_no_op_with_port(void) {
static void test_no_op_with_port_and_start(void) {
g_number_of_orphan_calls = 0;
grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
- struct sockaddr_in addr;
+ grpc_resolved_address resolved_addr;
+ struct sockaddr_in *addr = (struct sockaddr_in *)resolved_addr.addr;
grpc_udp_server *s = grpc_udp_server_create();
LOG_TEST("test_no_op_with_port_and_start");
- memset(&addr, 0, sizeof(addr));
- addr.sin_family = AF_INET;
- GPR_ASSERT(grpc_udp_server_add_port(s, (struct sockaddr *)&addr, sizeof(addr),
- on_read, on_fd_orphaned));
+ memset(&resolved_addr, 0, sizeof(resolved_addr));
+ resolved_addr.len = sizeof(struct sockaddr_in);
+ addr->sin_family = AF_INET;
+ GPR_ASSERT(
+ grpc_udp_server_add_port(s, &resolved_addr, on_read, on_fd_orphaned));
grpc_udp_server_start(&exec_ctx, s, NULL, 0, NULL);
grpc_udp_server_destroy(&exec_ctx, s, NULL);
grpc_exec_ctx_finish(&exec_ctx);
- /* The server had a single FD, which should have been orphaned. */
- GPR_ASSERT(g_number_of_orphan_calls == 1);
+ /* The server had a single FD, which is orphaned once in *
+ * deactivated_all_ports, and once in grpc_udp_server_destroy. */
+ GPR_ASSERT(g_number_of_orphan_calls == 2);
}
static void test_receive(int number_of_clients) {
grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
- struct sockaddr_storage addr;
- socklen_t addr_len = sizeof(addr);
+ grpc_resolved_address resolved_addr;
+ struct sockaddr_storage *addr = (struct sockaddr_storage *)resolved_addr.addr;
int clifd, svrfd;
grpc_udp_server *s = grpc_udp_server_create();
int i;
@@ -153,15 +161,17 @@ static void test_receive(int number_of_clients) {
g_number_of_bytes_read = 0;
g_number_of_orphan_calls = 0;
- memset(&addr, 0, sizeof(addr));
- addr.ss_family = AF_INET;
- GPR_ASSERT(grpc_udp_server_add_port(s, (struct sockaddr *)&addr, addr_len,
- on_read, on_fd_orphaned));
+ memset(&resolved_addr, 0, sizeof(resolved_addr));
+ resolved_addr.len = sizeof(struct sockaddr_storage);
+ addr->ss_family = AF_INET;
+ GPR_ASSERT(
+ grpc_udp_server_add_port(s, &resolved_addr, on_read, on_fd_orphaned));
svrfd = grpc_udp_server_get_fd(s, 0);
GPR_ASSERT(svrfd >= 0);
- GPR_ASSERT(getsockname(svrfd, (struct sockaddr *)&addr, &addr_len) == 0);
- GPR_ASSERT(addr_len <= sizeof(addr));
+ GPR_ASSERT(getsockname(svrfd, (struct sockaddr *)addr,
+ (socklen_t *)&resolved_addr.len) == 0);
+ GPR_ASSERT(resolved_addr.len <= sizeof(struct sockaddr_storage));
pollsets[0] = g_pollset;
grpc_udp_server_start(&exec_ctx, s, pollsets, 1, NULL);
@@ -173,9 +183,10 @@ static void test_receive(int number_of_clients) {
number_of_reads_before = g_number_of_reads;
/* Create a socket, send a packet to the UDP server. */
- clifd = socket(addr.ss_family, SOCK_DGRAM, 0);
+ clifd = socket(addr->ss_family, SOCK_DGRAM, 0);
GPR_ASSERT(clifd >= 0);
- GPR_ASSERT(connect(clifd, (struct sockaddr *)&addr, addr_len) == 0);
+ GPR_ASSERT(connect(clifd, (struct sockaddr *)addr,
+ (socklen_t)resolved_addr.len) == 0);
GPR_ASSERT(5 == write(clifd, "hello", 5));
while (g_number_of_reads == number_of_reads_before &&
gpr_time_cmp(deadline, gpr_now(deadline.clock_type)) > 0) {
@@ -198,8 +209,9 @@ static void test_receive(int number_of_clients) {
grpc_udp_server_destroy(&exec_ctx, s, NULL);
grpc_exec_ctx_finish(&exec_ctx);
- /* The server had a single FD, which should have been orphaned. */
- GPR_ASSERT(g_number_of_orphan_calls == 1);
+ /* The server had a single FD, which is orphaned once in *
+ * deactivated_all_ports, and once in grpc_udp_server_destroy. */
+ GPR_ASSERT(g_number_of_orphan_calls == 2);
}
static void destroy_pollset(grpc_exec_ctx *exec_ctx, void *p,
@@ -230,8 +242,8 @@ int main(int argc, char **argv) {
return 0;
}
-#else
+#else /* GRPC_POSIX_SOCKET */
-int main(int argc, char **argv) { return 0; }
+int main(int argc, char **argv) { return 1; }
-#endif
+#endif /* GRPC_POSIX_SOCKET */
diff --git a/test/core/iomgr/wakeup_fd_cv_test.c b/test/core/iomgr/wakeup_fd_cv_test.c
new file mode 100644
index 0000000000..82452d2157
--- /dev/null
+++ b/test/core/iomgr/wakeup_fd_cv_test.c
@@ -0,0 +1,250 @@
+/*
+ *
+ * Copyright 2016, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include "src/core/lib/iomgr/port.h"
+
+#ifdef GRPC_POSIX_SOCKET
+
+#include <pthread.h>
+
+#include <grpc/support/log.h>
+#include <grpc/support/thd.h>
+#include <grpc/support/time.h>
+#include <grpc/support/useful.h>
+
+#include "src/core/lib/iomgr/ev_posix.h"
+#include "src/core/lib/iomgr/iomgr_posix.h"
+#include "src/core/lib/support/env.h"
+
+typedef struct poll_args {
+ struct pollfd *fds;
+ nfds_t nfds;
+ int timeout;
+ int result;
+} poll_args;
+
+gpr_cv poll_cv;
+gpr_mu poll_mu;
+static int socket_event = 0;
+
+// Trigger a "socket" POLLIN in mock_poll()
+void trigger_socket_event() {
+ gpr_mu_lock(&poll_mu);
+ socket_event = 1;
+ gpr_cv_broadcast(&poll_cv);
+ gpr_mu_unlock(&poll_mu);
+}
+
+void reset_socket_event() {
+ gpr_mu_lock(&poll_mu);
+ socket_event = 0;
+ gpr_mu_unlock(&poll_mu);
+}
+
+// Mocks posix poll() function
+int mock_poll(struct pollfd *fds, nfds_t nfds, int timeout) {
+ int res = 0;
+ gpr_timespec poll_time;
+ gpr_mu_lock(&poll_mu);
+ GPR_ASSERT(nfds == 3);
+ GPR_ASSERT(fds[0].fd == 20);
+ GPR_ASSERT(fds[1].fd == 30);
+ GPR_ASSERT(fds[2].fd == 50);
+ GPR_ASSERT(fds[0].events == (POLLIN | POLLHUP));
+ GPR_ASSERT(fds[1].events == (POLLIN | POLLHUP));
+ GPR_ASSERT(fds[2].events == POLLIN);
+
+ if (timeout < 0) {
+ poll_time = gpr_inf_future(GPR_CLOCK_REALTIME);
+ } else {
+ poll_time = gpr_time_add(gpr_now(GPR_CLOCK_REALTIME),
+ gpr_time_from_millis(timeout, GPR_TIMESPAN));
+ }
+
+ if (socket_event || !gpr_cv_wait(&poll_cv, &poll_mu, poll_time)) {
+ fds[0].revents = POLLIN;
+ res = 1;
+ }
+ gpr_mu_unlock(&poll_mu);
+ return res;
+}
+
+void background_poll(void *args) {
+ poll_args *pargs = (poll_args *)args;
+ pargs->result = grpc_poll_function(pargs->fds, pargs->nfds, pargs->timeout);
+}
+
+void test_many_fds(void) {
+ int i;
+ grpc_wakeup_fd fd[1000];
+ for (i = 0; i < 1000; i++) {
+ GPR_ASSERT(grpc_wakeup_fd_init(&fd[i]) == GRPC_ERROR_NONE);
+ }
+ for (i = 0; i < 1000; i++) {
+ grpc_wakeup_fd_destroy(&fd[i]);
+ }
+}
+
+void test_poll_cv_trigger(void) {
+ grpc_wakeup_fd cvfd1, cvfd2, cvfd3;
+ struct pollfd pfds[6];
+ poll_args pargs;
+ gpr_thd_id t_id;
+ gpr_thd_options opt;
+
+ GPR_ASSERT(grpc_wakeup_fd_init(&cvfd1) == GRPC_ERROR_NONE);
+ GPR_ASSERT(grpc_wakeup_fd_init(&cvfd2) == GRPC_ERROR_NONE);
+ GPR_ASSERT(grpc_wakeup_fd_init(&cvfd3) == GRPC_ERROR_NONE);
+ GPR_ASSERT(cvfd1.read_fd < 0);
+ GPR_ASSERT(cvfd2.read_fd < 0);
+ GPR_ASSERT(cvfd3.read_fd < 0);
+ GPR_ASSERT(cvfd1.read_fd != cvfd2.read_fd);
+ GPR_ASSERT(cvfd2.read_fd != cvfd3.read_fd);
+ GPR_ASSERT(cvfd1.read_fd != cvfd3.read_fd);
+
+ pfds[0].fd = cvfd1.read_fd;
+ pfds[1].fd = cvfd2.read_fd;
+ pfds[2].fd = 20;
+ pfds[3].fd = 30;
+ pfds[4].fd = cvfd3.read_fd;
+ pfds[5].fd = 50;
+
+ pfds[0].events = 0;
+ pfds[1].events = POLLIN;
+ pfds[2].events = POLLIN | POLLHUP;
+ pfds[3].events = POLLIN | POLLHUP;
+ pfds[4].events = POLLIN;
+ pfds[5].events = POLLIN;
+
+ pargs.fds = pfds;
+ pargs.nfds = 6;
+ pargs.timeout = 1000;
+ pargs.result = -2;
+
+ opt = gpr_thd_options_default();
+ gpr_thd_options_set_joinable(&opt);
+ gpr_thd_new(&t_id, &background_poll, &pargs, &opt);
+
+ // Wakeup wakeup_fd not listening for events
+ GPR_ASSERT(grpc_wakeup_fd_wakeup(&cvfd1) == GRPC_ERROR_NONE);
+ gpr_thd_join(t_id);
+ GPR_ASSERT(pargs.result == 0);
+ GPR_ASSERT(pfds[0].revents == 0);
+ GPR_ASSERT(pfds[1].revents == 0);
+ GPR_ASSERT(pfds[2].revents == 0);
+ GPR_ASSERT(pfds[3].revents == 0);
+ GPR_ASSERT(pfds[4].revents == 0);
+ GPR_ASSERT(pfds[5].revents == 0);
+
+ // Pollin on socket fd
+ pargs.timeout = -1;
+ pargs.result = -2;
+ gpr_thd_new(&t_id, &background_poll, &pargs, &opt);
+ trigger_socket_event();
+ gpr_thd_join(t_id);
+ GPR_ASSERT(pargs.result == 1);
+ GPR_ASSERT(pfds[0].revents == 0);
+ GPR_ASSERT(pfds[1].revents == 0);
+ GPR_ASSERT(pfds[2].revents == POLLIN);
+ GPR_ASSERT(pfds[3].revents == 0);
+ GPR_ASSERT(pfds[4].revents == 0);
+ GPR_ASSERT(pfds[5].revents == 0);
+
+ // Pollin on wakeup fd
+ reset_socket_event();
+ pargs.result = -2;
+ gpr_thd_new(&t_id, &background_poll, &pargs, &opt);
+ GPR_ASSERT(grpc_wakeup_fd_wakeup(&cvfd2) == GRPC_ERROR_NONE);
+ gpr_thd_join(t_id);
+
+ GPR_ASSERT(pargs.result == 1);
+ GPR_ASSERT(pfds[0].revents == 0);
+ GPR_ASSERT(pfds[1].revents == POLLIN);
+ GPR_ASSERT(pfds[2].revents == 0);
+ GPR_ASSERT(pfds[3].revents == 0);
+ GPR_ASSERT(pfds[4].revents == 0);
+ GPR_ASSERT(pfds[5].revents == 0);
+
+ // Pollin on wakeup fd + socket fd
+ trigger_socket_event();
+ pargs.result = -2;
+ gpr_thd_new(&t_id, &background_poll, &pargs, &opt);
+ gpr_thd_join(t_id);
+
+ GPR_ASSERT(pargs.result == 2);
+ GPR_ASSERT(pfds[0].revents == 0);
+ GPR_ASSERT(pfds[1].revents == POLLIN);
+ GPR_ASSERT(pfds[2].revents == POLLIN);
+ GPR_ASSERT(pfds[3].revents == 0);
+ GPR_ASSERT(pfds[4].revents == 0);
+ GPR_ASSERT(pfds[5].revents == 0);
+
+ // No Events
+ pargs.result = -2;
+ pargs.timeout = 1000;
+ reset_socket_event();
+ GPR_ASSERT(grpc_wakeup_fd_consume_wakeup(&cvfd1) == GRPC_ERROR_NONE);
+ GPR_ASSERT(grpc_wakeup_fd_consume_wakeup(&cvfd2) == GRPC_ERROR_NONE);
+ gpr_thd_new(&t_id, &background_poll, &pargs, &opt);
+ gpr_thd_join(t_id);
+
+ GPR_ASSERT(pargs.result == 0);
+ GPR_ASSERT(pfds[0].revents == 0);
+ GPR_ASSERT(pfds[1].revents == 0);
+ GPR_ASSERT(pfds[2].revents == 0);
+ GPR_ASSERT(pfds[3].revents == 0);
+ GPR_ASSERT(pfds[4].revents == 0);
+ GPR_ASSERT(pfds[5].revents == 0);
+}
+
+int main(int argc, char **argv) {
+ gpr_setenv("GRPC_POLL_STRATEGY", "poll-cv");
+ grpc_poll_function = &mock_poll;
+ gpr_mu_init(&poll_mu);
+ gpr_cv_init(&poll_cv);
+
+ grpc_iomgr_platform_init();
+ test_many_fds();
+ grpc_iomgr_platform_shutdown();
+
+ grpc_iomgr_platform_init();
+ test_poll_cv_trigger();
+ grpc_iomgr_platform_shutdown();
+ return 0;
+}
+
+#else /* GRPC_POSIX_SOCKET */
+
+int main(int argc, char **argv) { return 1; }
+
+#endif /* GRPC_POSIX_SOCKET */