Merge branch 'power-to-the-peanut-people-rah-rah' into connected-subchannel

reviewable/pr4232/r3
Craig Tiller 9 years ago
commit c28f52ff37
  1. 4
      BUILD
  2. 36
      Makefile
  3. 1
      binding.gyp
  4. 10
      build.yaml
  5. 2
      gRPC.podspec
  6. 91
      include/grpc/support/avl.h
  7. 20
      src/core/iomgr/tcp_server.h
  8. 150
      src/core/iomgr/tcp_server_posix.c
  9. 121
      src/core/iomgr/tcp_server_windows.c
  10. 4
      src/core/security/server_secure_chttp2.c
  11. 288
      src/core/support/avl.c
  12. 4
      src/core/surface/server_chttp2.c
  13. 3671
      test/core/support/avl_test.c
  14. 4
      test/core/util/reconnect_server.c
  15. 22
      test/proto/benchmarks/control.proto
  16. 14
      test/proto/benchmarks/services.proto
  17. 8
      test/proto/benchmarks/stats.proto
  18. 1
      tools/doxygen/Doxyfile.core
  19. 2
      tools/doxygen/Doxyfile.core.internal
  20. 14
      tools/run_tests/run_tests.py
  21. 15
      tools/run_tests/sources_and_headers.json
  22. 18
      tools/run_tests/tests.json
  23. 25
      vsprojects/buildtests_c.sln
  24. 3
      vsprojects/vcxproj/gpr/gpr.vcxproj
  25. 6
      vsprojects/vcxproj/gpr/gpr.vcxproj.filters
  26. 178
      vsprojects/vcxproj/test/gpr_avl_test/gpr_avl_test.vcxproj
  27. 21
      vsprojects/vcxproj/test/gpr_avl_test/gpr_avl_test.vcxproj.filters

@ -57,6 +57,7 @@ cc_library(
"src/core/profiling/basic_timers.c", "src/core/profiling/basic_timers.c",
"src/core/profiling/stap_timers.c", "src/core/profiling/stap_timers.c",
"src/core/support/alloc.c", "src/core/support/alloc.c",
"src/core/support/avl.c",
"src/core/support/cmdline.c", "src/core/support/cmdline.c",
"src/core/support/cpu_iphone.c", "src/core/support/cpu_iphone.c",
"src/core/support/cpu_linux.c", "src/core/support/cpu_linux.c",
@ -101,6 +102,7 @@ cc_library(
"include/grpc/support/atm_gcc_atomic.h", "include/grpc/support/atm_gcc_atomic.h",
"include/grpc/support/atm_gcc_sync.h", "include/grpc/support/atm_gcc_sync.h",
"include/grpc/support/atm_win32.h", "include/grpc/support/atm_win32.h",
"include/grpc/support/avl.h",
"include/grpc/support/cmdline.h", "include/grpc/support/cmdline.h",
"include/grpc/support/cpu.h", "include/grpc/support/cpu.h",
"include/grpc/support/histogram.h", "include/grpc/support/histogram.h",
@ -981,6 +983,7 @@ objc_library(
"src/core/profiling/basic_timers.c", "src/core/profiling/basic_timers.c",
"src/core/profiling/stap_timers.c", "src/core/profiling/stap_timers.c",
"src/core/support/alloc.c", "src/core/support/alloc.c",
"src/core/support/avl.c",
"src/core/support/cmdline.c", "src/core/support/cmdline.c",
"src/core/support/cpu_iphone.c", "src/core/support/cpu_iphone.c",
"src/core/support/cpu_linux.c", "src/core/support/cpu_linux.c",
@ -1025,6 +1028,7 @@ objc_library(
"include/grpc/support/atm_gcc_atomic.h", "include/grpc/support/atm_gcc_atomic.h",
"include/grpc/support/atm_gcc_sync.h", "include/grpc/support/atm_gcc_sync.h",
"include/grpc/support/atm_win32.h", "include/grpc/support/atm_win32.h",
"include/grpc/support/avl.h",
"include/grpc/support/cmdline.h", "include/grpc/support/cmdline.h",
"include/grpc/support/cpu.h", "include/grpc/support/cpu.h",
"include/grpc/support/histogram.h", "include/grpc/support/histogram.h",

File diff suppressed because one or more lines are too long

@ -97,6 +97,7 @@
'src/core/profiling/basic_timers.c', 'src/core/profiling/basic_timers.c',
'src/core/profiling/stap_timers.c', 'src/core/profiling/stap_timers.c',
'src/core/support/alloc.c', 'src/core/support/alloc.c',
'src/core/support/avl.c',
'src/core/support/cmdline.c', 'src/core/support/cmdline.c',
'src/core/support/cpu_iphone.c', 'src/core/support/cpu_iphone.c',
'src/core/support/cpu_linux.c', 'src/core/support/cpu_linux.c',

@ -376,6 +376,7 @@ libs:
- include/grpc/support/atm_gcc_atomic.h - include/grpc/support/atm_gcc_atomic.h
- include/grpc/support/atm_gcc_sync.h - include/grpc/support/atm_gcc_sync.h
- include/grpc/support/atm_win32.h - include/grpc/support/atm_win32.h
- include/grpc/support/avl.h
- include/grpc/support/cmdline.h - include/grpc/support/cmdline.h
- include/grpc/support/cpu.h - include/grpc/support/cpu.h
- include/grpc/support/histogram.h - include/grpc/support/histogram.h
@ -413,6 +414,7 @@ libs:
- src/core/profiling/basic_timers.c - src/core/profiling/basic_timers.c
- src/core/profiling/stap_timers.c - src/core/profiling/stap_timers.c
- src/core/support/alloc.c - src/core/support/alloc.c
- src/core/support/avl.c
- src/core/support/cmdline.c - src/core/support/cmdline.c
- src/core/support/cpu_iphone.c - src/core/support/cpu_iphone.c
- src/core/support/cpu_linux.c - src/core/support/cpu_linux.c
@ -972,6 +974,14 @@ targets:
src: src:
- tools/codegen/core/gen_legal_metadata_characters.c - tools/codegen/core/gen_legal_metadata_characters.c
deps: [] deps: []
- name: gpr_avl_test
build: test
language: c
src:
- test/core/support/avl_test.c
deps:
- gpr_test_util
- gpr
- name: gpr_cmdline_test - name: gpr_cmdline_test
build: test build: test
language: c language: c

@ -78,6 +78,7 @@ Pod::Spec.new do |s|
'include/grpc/support/atm_gcc_atomic.h', 'include/grpc/support/atm_gcc_atomic.h',
'include/grpc/support/atm_gcc_sync.h', 'include/grpc/support/atm_gcc_sync.h',
'include/grpc/support/atm_win32.h', 'include/grpc/support/atm_win32.h',
'include/grpc/support/avl.h',
'include/grpc/support/cmdline.h', 'include/grpc/support/cmdline.h',
'include/grpc/support/cpu.h', 'include/grpc/support/cpu.h',
'include/grpc/support/histogram.h', 'include/grpc/support/histogram.h',
@ -103,6 +104,7 @@ Pod::Spec.new do |s|
'src/core/profiling/basic_timers.c', 'src/core/profiling/basic_timers.c',
'src/core/profiling/stap_timers.c', 'src/core/profiling/stap_timers.c',
'src/core/support/alloc.c', 'src/core/support/alloc.c',
'src/core/support/avl.c',
'src/core/support/cmdline.c', 'src/core/support/cmdline.c',
'src/core/support/cpu_iphone.c', 'src/core/support/cpu_iphone.c',
'src/core/support/cpu_linux.c', 'src/core/support/cpu_linux.c',

@ -0,0 +1,91 @@
/*
*
* 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.
*
*/
#ifndef GRPC_SUPPORT_AVL_H
#define GRPC_SUPPORT_AVL_H
#include <grpc/support/sync.h>
/** internal node of an AVL tree */
typedef struct gpr_avl_node {
gpr_refcount refs;
void *key;
void *value;
struct gpr_avl_node *left;
struct gpr_avl_node *right;
long height;
} gpr_avl_node;
typedef struct gpr_avl_vtable {
/** destroy a key */
void (*destroy_key)(void *key);
/** copy a key, returning new value */
void *(*copy_key)(void *key);
/** compare key1, key2; return <0 if key1 < key2,
>0 if key1 > key2, 0 if key1 == key2 */
long (*compare_keys)(void *key1, void *key2);
/** destroy a value */
void (*destroy_value)(void *value);
/** copy a value */
void *(*copy_value)(void *value);
} gpr_avl_vtable;
/** "pointer" to an AVL tree - this is a reference
counted object - use gpr_avl_ref to add a reference,
gpr_avl_unref when done with a reference */
typedef struct gpr_avl {
const gpr_avl_vtable *vtable;
gpr_avl_node *root;
} gpr_avl;
/** create an immutable AVL tree */
gpr_avl gpr_avl_create(const gpr_avl_vtable *vtable);
/** add a reference to an existing tree - returns
the tree as a convenience */
gpr_avl gpr_avl_ref(gpr_avl avl);
/** remove a reference to a tree - destroying it if there
are no references left */
void gpr_avl_unref(gpr_avl avl);
/** return a new tree with (key, value) added to avl.
implicitly unrefs avl to allow easy chaining.
if key exists in avl, the new tree's key entry updated
(i.e. a duplicate is not created) */
gpr_avl gpr_avl_add(gpr_avl avl, void *key, void *value);
/** return a new tree with key deleted */
gpr_avl gpr_avl_remove(gpr_avl avl, void *key);
/** lookup key, and return the associated value.
does not mutate avl.
returns NULL if key is not found. */
void *gpr_avl_get(gpr_avl avl, void *key);
#endif

@ -39,6 +39,9 @@
/* Forward decl of grpc_tcp_server */ /* Forward decl of grpc_tcp_server */
typedef struct grpc_tcp_server grpc_tcp_server; typedef struct grpc_tcp_server grpc_tcp_server;
/* Forward decl of grpc_tcp_listener */
typedef struct grpc_tcp_listener grpc_tcp_listener;
/* Called for newly connected TCP connections. */ /* Called for newly connected TCP connections. */
typedef void (*grpc_tcp_server_cb)(grpc_exec_ctx *exec_ctx, void *arg, typedef void (*grpc_tcp_server_cb)(grpc_exec_ctx *exec_ctx, void *arg,
grpc_endpoint *ep); grpc_endpoint *ep);
@ -51,19 +54,18 @@ void grpc_tcp_server_start(grpc_exec_ctx *exec_ctx, grpc_tcp_server *server,
grpc_pollset **pollsets, size_t pollset_count, grpc_pollset **pollsets, size_t pollset_count,
grpc_tcp_server_cb on_accept_cb, void *cb_arg); grpc_tcp_server_cb on_accept_cb, void *cb_arg);
/* Add a port to the server, returning port number on success, or negative /* Add a port to the server, returning the newly created listener on success,
on failure. or a null pointer on failure.
The :: and 0.0.0.0 wildcard addresses are treated identically, accepting The :: and 0.0.0.0 wildcard addresses are treated identically, accepting
both IPv4 and IPv6 connections, but :: is the preferred style. This usually both IPv4 and IPv6 connections, but :: is the preferred style. This usually
creates one socket, but possibly two on systems which support IPv6, creates one socket, but possibly two on systems which support IPv6,
but not dualstack sockets. but not dualstack sockets. */
For raw access to the underlying sockets, see grpc_tcp_server_get_fd(). */
/* TODO(ctiller): deprecate this, and make grpc_tcp_server_add_ports to handle /* TODO(ctiller): deprecate this, and make grpc_tcp_server_add_ports to handle
all of the multiple socket port matching logic in one place */ all of the multiple socket port matching logic in one place */
int grpc_tcp_server_add_port(grpc_tcp_server *s, const void *addr, grpc_tcp_listener *grpc_tcp_server_add_port(grpc_tcp_server *s,
size_t addr_len); const void *addr,
size_t addr_len);
/* Returns the file descriptor of the Nth listening socket on this server, /* Returns the file descriptor of the Nth listening socket on this server,
or -1 if the index is out of bounds. or -1 if the index is out of bounds.
@ -75,4 +77,8 @@ int grpc_tcp_server_get_fd(grpc_tcp_server *s, unsigned index);
void grpc_tcp_server_destroy(grpc_exec_ctx *exec_ctx, grpc_tcp_server *server, void grpc_tcp_server_destroy(grpc_exec_ctx *exec_ctx, grpc_tcp_server *server,
grpc_closure *closure); grpc_closure *closure);
int grpc_tcp_listener_get_port(grpc_tcp_listener *listener);
void grpc_tcp_listener_ref(grpc_tcp_listener *listener);
void grpc_tcp_listener_unref(grpc_tcp_listener *listener);
#endif /* GRPC_INTERNAL_CORE_IOMGR_TCP_SERVER_H */ #endif /* GRPC_INTERNAL_CORE_IOMGR_TCP_SERVER_H */

@ -67,14 +67,13 @@
#include <grpc/support/sync.h> #include <grpc/support/sync.h>
#include <grpc/support/time.h> #include <grpc/support/time.h>
#define INIT_PORT_CAP 2
#define MIN_SAFE_ACCEPT_QUEUE_SIZE 100 #define MIN_SAFE_ACCEPT_QUEUE_SIZE 100
static gpr_once s_init_max_accept_queue_size; static gpr_once s_init_max_accept_queue_size;
static int s_max_accept_queue_size; static int s_max_accept_queue_size;
/* one listening port */ /* one listening port */
typedef struct { struct grpc_tcp_listener {
int fd; int fd;
grpc_fd *emfd; grpc_fd *emfd;
grpc_tcp_server *server; grpc_tcp_server *server;
@ -84,9 +83,18 @@ typedef struct {
struct sockaddr_un un; struct sockaddr_un un;
} addr; } addr;
size_t addr_len; size_t addr_len;
int port;
grpc_closure read_closure; grpc_closure read_closure;
grpc_closure destroyed_closure; grpc_closure destroyed_closure;
} server_port; gpr_refcount refs;
struct grpc_tcp_listener *next;
/* When we add a listener, more than one can be created, mainly because of
IPv6. A sibling will still be in the normal list, but will be flagged
as such. Any action, such as ref or unref, will affect all of the
siblings in the list. */
struct grpc_tcp_listener *sibling;
int is_sibling;
};
static void unlink_if_unix_domain_socket(const struct sockaddr_un *un) { static void unlink_if_unix_domain_socket(const struct sockaddr_un *un) {
struct stat st; struct stat st;
@ -112,10 +120,9 @@ struct grpc_tcp_server {
/* is this server shutting down? (boolean) */ /* is this server shutting down? (boolean) */
int shutdown; int shutdown;
/* all listening ports */ /* linked list of server ports */
server_port *ports; grpc_tcp_listener *head;
size_t nports; unsigned nports;
size_t port_capacity;
/* shutdown callback */ /* shutdown callback */
grpc_closure *shutdown_complete; grpc_closure *shutdown_complete;
@ -134,9 +141,8 @@ grpc_tcp_server *grpc_tcp_server_create(void) {
s->shutdown = 0; s->shutdown = 0;
s->on_accept_cb = NULL; s->on_accept_cb = NULL;
s->on_accept_cb_arg = NULL; s->on_accept_cb_arg = NULL;
s->ports = gpr_malloc(sizeof(server_port) * INIT_PORT_CAP); s->head = NULL;
s->nports = 0; s->nports = 0;
s->port_capacity = INIT_PORT_CAP;
return s; return s;
} }
@ -145,7 +151,12 @@ static void finish_shutdown(grpc_exec_ctx *exec_ctx, grpc_tcp_server *s) {
gpr_mu_destroy(&s->mu); gpr_mu_destroy(&s->mu);
gpr_free(s->ports); while (s->head) {
grpc_tcp_listener *sp = s->head;
s->head = sp->next;
grpc_tcp_listener_unref(sp);
}
gpr_free(s); gpr_free(s);
} }
@ -166,8 +177,6 @@ static void destroyed_port(grpc_exec_ctx *exec_ctx, void *server, int success) {
events will be received on them - at this point it's safe to destroy events will be received on them - at this point it's safe to destroy
things */ things */
static void deactivated_all_ports(grpc_exec_ctx *exec_ctx, grpc_tcp_server *s) { static void deactivated_all_ports(grpc_exec_ctx *exec_ctx, grpc_tcp_server *s) {
size_t i;
/* delete ALL the things */ /* delete ALL the things */
gpr_mu_lock(&s->mu); gpr_mu_lock(&s->mu);
@ -176,9 +185,9 @@ static void deactivated_all_ports(grpc_exec_ctx *exec_ctx, grpc_tcp_server *s) {
return; return;
} }
if (s->nports) { if (s->head) {
for (i = 0; i < s->nports; i++) { grpc_tcp_listener *sp;
server_port *sp = &s->ports[i]; for (sp = s->head; sp; sp = sp->next) {
if (sp->addr.sockaddr.sa_family == AF_UNIX) { if (sp->addr.sockaddr.sa_family == AF_UNIX) {
unlink_if_unix_domain_socket(&sp->addr.un); unlink_if_unix_domain_socket(&sp->addr.un);
} }
@ -196,7 +205,6 @@ static void deactivated_all_ports(grpc_exec_ctx *exec_ctx, grpc_tcp_server *s) {
void grpc_tcp_server_destroy(grpc_exec_ctx *exec_ctx, grpc_tcp_server *s, void grpc_tcp_server_destroy(grpc_exec_ctx *exec_ctx, grpc_tcp_server *s,
grpc_closure *closure) { grpc_closure *closure) {
size_t i;
gpr_mu_lock(&s->mu); gpr_mu_lock(&s->mu);
GPR_ASSERT(!s->shutdown); GPR_ASSERT(!s->shutdown);
@ -206,8 +214,9 @@ void grpc_tcp_server_destroy(grpc_exec_ctx *exec_ctx, grpc_tcp_server *s,
/* shutdown all fd's */ /* shutdown all fd's */
if (s->active_ports) { if (s->active_ports) {
for (i = 0; i < s->nports; i++) { grpc_tcp_listener *sp;
grpc_fd_shutdown(exec_ctx, s->ports[i].emfd); for (sp = s->head; sp; sp = sp->next) {
grpc_fd_shutdown(exec_ctx, sp->emfd);
} }
gpr_mu_unlock(&s->mu); gpr_mu_unlock(&s->mu);
} else { } else {
@ -298,7 +307,7 @@ error:
/* event manager callback when reads are ready */ /* event manager callback when reads are ready */
static void on_read(grpc_exec_ctx *exec_ctx, void *arg, int success) { static void on_read(grpc_exec_ctx *exec_ctx, void *arg, int success) {
server_port *sp = arg; grpc_tcp_listener *sp = arg;
grpc_fd *fdobj; grpc_fd *fdobj;
size_t i; size_t i;
@ -364,9 +373,10 @@ error:
} }
} }
static int add_socket_to_server(grpc_tcp_server *s, int fd, static grpc_tcp_listener *add_socket_to_server(grpc_tcp_server *s, int fd,
const struct sockaddr *addr, size_t addr_len) { const struct sockaddr *addr,
server_port *sp; size_t addr_len) {
grpc_tcp_listener *sp = NULL;
int port; int port;
char *addr_str; char *addr_str;
char *name; char *name;
@ -376,32 +386,35 @@ static int add_socket_to_server(grpc_tcp_server *s, int fd,
grpc_sockaddr_to_string(&addr_str, (struct sockaddr *)&addr, 1); grpc_sockaddr_to_string(&addr_str, (struct sockaddr *)&addr, 1);
gpr_asprintf(&name, "tcp-server-listener:%s", addr_str); gpr_asprintf(&name, "tcp-server-listener:%s", addr_str);
gpr_mu_lock(&s->mu); gpr_mu_lock(&s->mu);
s->nports++;
GPR_ASSERT(!s->on_accept_cb && "must add ports before starting server"); GPR_ASSERT(!s->on_accept_cb && "must add ports before starting server");
/* append it to the list under a lock */ sp = gpr_malloc(sizeof(grpc_tcp_listener));
if (s->nports == s->port_capacity) { sp->next = s->head;
s->port_capacity *= 2; s->head = sp;
s->ports = gpr_realloc(s->ports, sizeof(server_port) * s->port_capacity);
}
sp = &s->ports[s->nports++];
sp->server = s; sp->server = s;
sp->fd = fd; sp->fd = fd;
sp->emfd = grpc_fd_create(fd, name); sp->emfd = grpc_fd_create(fd, name);
memcpy(sp->addr.untyped, addr, addr_len); memcpy(sp->addr.untyped, addr, addr_len);
sp->addr_len = addr_len; sp->addr_len = addr_len;
sp->port = port;
sp->is_sibling = 0;
sp->sibling = NULL;
gpr_ref_init(&sp->refs, 1);
GPR_ASSERT(sp->emfd); GPR_ASSERT(sp->emfd);
gpr_mu_unlock(&s->mu); gpr_mu_unlock(&s->mu);
gpr_free(addr_str); gpr_free(addr_str);
gpr_free(name); gpr_free(name);
} }
return port; return sp;
} }
int grpc_tcp_server_add_port(grpc_tcp_server *s, const void *addr, grpc_tcp_listener *grpc_tcp_server_add_port(grpc_tcp_server *s,
size_t addr_len) { const void *addr,
int allocated_port1 = -1; size_t addr_len) {
int allocated_port2 = -1; int allocated_port = -1;
unsigned i; grpc_tcp_listener *sp;
grpc_tcp_listener *sp2 = NULL;
int fd; int fd;
grpc_dualstack_mode dsmode; grpc_dualstack_mode dsmode;
struct sockaddr_in6 addr6_v4mapped; struct sockaddr_in6 addr6_v4mapped;
@ -420,9 +433,9 @@ int grpc_tcp_server_add_port(grpc_tcp_server *s, const void *addr,
/* Check if this is a wildcard port, and if so, try to keep the port the same /* Check if this is a wildcard port, and if so, try to keep the port the same
as some previously created listener. */ as some previously created listener. */
if (grpc_sockaddr_get_port(addr) == 0) { if (grpc_sockaddr_get_port(addr) == 0) {
for (i = 0; i < s->nports; i++) { for (sp = s->head; sp; sp = sp->next) {
sockname_len = sizeof(sockname_temp); sockname_len = sizeof(sockname_temp);
if (0 == getsockname(s->ports[i].fd, (struct sockaddr *)&sockname_temp, if (0 == getsockname(sp->fd, (struct sockaddr *)&sockname_temp,
&sockname_len)) { &sockname_len)) {
port = grpc_sockaddr_get_port((struct sockaddr *)&sockname_temp); port = grpc_sockaddr_get_port((struct sockaddr *)&sockname_temp);
if (port > 0) { if (port > 0) {
@ -436,6 +449,8 @@ int grpc_tcp_server_add_port(grpc_tcp_server *s, const void *addr,
} }
} }
sp = NULL;
if (grpc_sockaddr_to_v4mapped(addr, &addr6_v4mapped)) { if (grpc_sockaddr_to_v4mapped(addr, &addr6_v4mapped)) {
addr = (const struct sockaddr *)&addr6_v4mapped; addr = (const struct sockaddr *)&addr6_v4mapped;
addr_len = sizeof(addr6_v4mapped); addr_len = sizeof(addr6_v4mapped);
@ -449,14 +464,16 @@ int grpc_tcp_server_add_port(grpc_tcp_server *s, const void *addr,
addr = (struct sockaddr *)&wild6; addr = (struct sockaddr *)&wild6;
addr_len = sizeof(wild6); addr_len = sizeof(wild6);
fd = grpc_create_dualstack_socket(addr, SOCK_STREAM, 0, &dsmode); fd = grpc_create_dualstack_socket(addr, SOCK_STREAM, 0, &dsmode);
allocated_port1 = add_socket_to_server(s, fd, addr, addr_len); sp = add_socket_to_server(s, fd, addr, addr_len);
allocated_port = sp->port;
if (fd >= 0 && dsmode == GRPC_DSMODE_DUALSTACK) { if (fd >= 0 && dsmode == GRPC_DSMODE_DUALSTACK) {
goto done; goto done;
} }
/* If we didn't get a dualstack socket, also listen on 0.0.0.0. */ /* If we didn't get a dualstack socket, also listen on 0.0.0.0. */
if (port == 0 && allocated_port1 > 0) { if (port == 0 && allocated_port > 0) {
grpc_sockaddr_set_port((struct sockaddr *)&wild4, allocated_port1); grpc_sockaddr_set_port((struct sockaddr *)&wild4, allocated_port);
sp2 = sp;
} }
addr = (struct sockaddr *)&wild4; addr = (struct sockaddr *)&wild4;
addr_len = sizeof(wild4); addr_len = sizeof(wild4);
@ -471,22 +488,31 @@ int grpc_tcp_server_add_port(grpc_tcp_server *s, const void *addr,
addr = (struct sockaddr *)&addr4_copy; addr = (struct sockaddr *)&addr4_copy;
addr_len = sizeof(addr4_copy); addr_len = sizeof(addr4_copy);
} }
allocated_port2 = add_socket_to_server(s, fd, addr, addr_len); sp = add_socket_to_server(s, fd, addr, addr_len);
sp->sibling = sp2;
if (sp2) sp2->is_sibling = 1;
done: done:
gpr_free(allocated_addr); gpr_free(allocated_addr);
return allocated_port1 >= 0 ? allocated_port1 : allocated_port2; return sp;
} }
int grpc_tcp_server_get_fd(grpc_tcp_server *s, unsigned port_index) { int grpc_tcp_server_get_fd(grpc_tcp_server *s, unsigned port_index) {
return (port_index < s->nports) ? s->ports[port_index].fd : -1; grpc_tcp_listener *sp;
for (sp = s->head; sp && port_index != 0; sp = sp->next, port_index--);
if (port_index == 0 && sp) {
return sp->fd;
} else {
return -1;
}
} }
void grpc_tcp_server_start(grpc_exec_ctx *exec_ctx, grpc_tcp_server *s, void grpc_tcp_server_start(grpc_exec_ctx *exec_ctx, grpc_tcp_server *s,
grpc_pollset **pollsets, size_t pollset_count, grpc_pollset **pollsets, size_t pollset_count,
grpc_tcp_server_cb on_accept_cb, grpc_tcp_server_cb on_accept_cb,
void *on_accept_cb_arg) { void *on_accept_cb_arg) {
size_t i, j; size_t i;
grpc_tcp_listener *sp;
GPR_ASSERT(on_accept_cb); GPR_ASSERT(on_accept_cb);
gpr_mu_lock(&s->mu); gpr_mu_lock(&s->mu);
GPR_ASSERT(!s->on_accept_cb); GPR_ASSERT(!s->on_accept_cb);
@ -495,17 +521,41 @@ void grpc_tcp_server_start(grpc_exec_ctx *exec_ctx, grpc_tcp_server *s,
s->on_accept_cb_arg = on_accept_cb_arg; s->on_accept_cb_arg = on_accept_cb_arg;
s->pollsets = pollsets; s->pollsets = pollsets;
s->pollset_count = pollset_count; s->pollset_count = pollset_count;
for (i = 0; i < s->nports; i++) { for (sp = s->head; sp; sp = sp->next) {
for (j = 0; j < pollset_count; j++) { for (i = 0; i < pollset_count; i++) {
grpc_pollset_add_fd(exec_ctx, pollsets[j], s->ports[i].emfd); grpc_pollset_add_fd(exec_ctx, pollsets[i], sp->emfd);
} }
s->ports[i].read_closure.cb = on_read; sp->read_closure.cb = on_read;
s->ports[i].read_closure.cb_arg = &s->ports[i]; sp->read_closure.cb_arg = sp;
grpc_fd_notify_on_read(exec_ctx, s->ports[i].emfd, grpc_fd_notify_on_read(exec_ctx, sp->emfd,
&s->ports[i].read_closure); &sp->read_closure);
s->active_ports++; s->active_ports++;
} }
gpr_mu_unlock(&s->mu); gpr_mu_unlock(&s->mu);
} }
int grpc_tcp_listener_get_port(grpc_tcp_listener *listener) {
grpc_tcp_listener *sp = listener;
return sp->port;
}
void grpc_tcp_listener_ref(grpc_tcp_listener *listener) {
grpc_tcp_listener *sp = listener;
gpr_ref(&sp->refs);
}
void grpc_tcp_listener_unref(grpc_tcp_listener *listener) {
grpc_tcp_listener *sp = listener;
if (sp->is_sibling) return;
if (gpr_unref(&sp->refs)) {
grpc_tcp_listener *sibling = sp->sibling;
while (sibling) {
sp = sibling;
sibling = sp->sibling;
gpr_free(sp);
}
gpr_free(listener);
}
}
#endif #endif

@ -35,7 +35,8 @@
#ifdef GPR_WINSOCK_SOCKET #ifdef GPR_WINSOCK_SOCKET
#define _GNU_SOURCE #include <io.h>
#include "src/core/iomgr/sockaddr_utils.h" #include "src/core/iomgr/sockaddr_utils.h"
#include <grpc/support/alloc.h> #include <grpc/support/alloc.h>
@ -51,25 +52,29 @@
#include "src/core/iomgr/tcp_server.h" #include "src/core/iomgr/tcp_server.h"
#include "src/core/iomgr/tcp_windows.h" #include "src/core/iomgr/tcp_windows.h"
#define INIT_PORT_CAP 2
#define MIN_SAFE_ACCEPT_QUEUE_SIZE 100 #define MIN_SAFE_ACCEPT_QUEUE_SIZE 100
/* one listening port */ /* one listening port */
typedef struct server_port { struct grpc_tcp_listener {
/* This seemingly magic number comes from AcceptEx's documentation. each /* This seemingly magic number comes from AcceptEx's documentation. each
address buffer needs to have at least 16 more bytes at their end. */ address buffer needs to have at least 16 more bytes at their end. */
gpr_uint8 addresses[(sizeof(struct sockaddr_in6) + 16) * 2]; gpr_uint8 addresses[(sizeof(struct sockaddr_in6) + 16) * 2];
/* This will hold the socket for the next accept. */ /* This will hold the socket for the next accept. */
SOCKET new_socket; SOCKET new_socket;
/* The listener winsocked. */ /* The listener winsocket. */
grpc_winsocket *socket; grpc_winsocket *socket;
/* The actual TCP port number. */
int port;
grpc_tcp_server *server; grpc_tcp_server *server;
/* The cached AcceptEx for that port. */ /* The cached AcceptEx for that port. */
LPFN_ACCEPTEX AcceptEx; LPFN_ACCEPTEX AcceptEx;
int shutting_down; int shutting_down;
/* closure for socket notification of accept being ready */ /* closure for socket notification of accept being ready */
grpc_closure on_accept; grpc_closure on_accept;
} server_port; gpr_refcount refs;
/* linked list */
struct grpc_tcp_listener *next;
};
/* the overall server */ /* the overall server */
struct grpc_tcp_server { struct grpc_tcp_server {
@ -82,10 +87,8 @@ struct grpc_tcp_server {
/* active port count: how many ports are actually still listening */ /* active port count: how many ports are actually still listening */
int active_ports; int active_ports;
/* all listening ports */ /* linked list of server ports */
server_port *ports; grpc_tcp_listener *head;
size_t nports;
size_t port_capacity;
/* shutdown callback */ /* shutdown callback */
grpc_closure *shutdown_complete; grpc_closure *shutdown_complete;
@ -99,9 +102,7 @@ grpc_tcp_server *grpc_tcp_server_create(void) {
s->active_ports = 0; s->active_ports = 0;
s->on_accept_cb = NULL; s->on_accept_cb = NULL;
s->on_accept_cb_arg = NULL; s->on_accept_cb_arg = NULL;
s->ports = gpr_malloc(sizeof(server_port) * INIT_PORT_CAP); s->head = NULL;
s->nports = 0;
s->port_capacity = INIT_PORT_CAP;
s->shutdown_complete = NULL; s->shutdown_complete = NULL;
return s; return s;
} }
@ -109,26 +110,26 @@ grpc_tcp_server *grpc_tcp_server_create(void) {
static void dont_care_about_shutdown_completion(void *arg) {} static void dont_care_about_shutdown_completion(void *arg) {}
static void finish_shutdown(grpc_exec_ctx *exec_ctx, grpc_tcp_server *s) { static void finish_shutdown(grpc_exec_ctx *exec_ctx, grpc_tcp_server *s) {
size_t i;
grpc_exec_ctx_enqueue(exec_ctx, s->shutdown_complete, 1); grpc_exec_ctx_enqueue(exec_ctx, s->shutdown_complete, 1);
/* Now that the accepts have been aborted, we can destroy the sockets. /* Now that the accepts have been aborted, we can destroy the sockets.
The IOCP won't get notified on these, so we can flag them as already The IOCP won't get notified on these, so we can flag them as already
closed by the system. */ closed by the system. */
for (i = 0; i < s->nports; i++) { while (s->head) {
server_port *sp = &s->ports[i]; grpc_tcp_listener *sp = s->head;
s->head = sp->next;
sp->next = NULL;
grpc_winsocket_destroy(sp->socket); grpc_winsocket_destroy(sp->socket);
grpc_tcp_listener_unref(sp);
} }
gpr_free(s->ports);
gpr_free(s); gpr_free(s);
} }
/* Public function. Stops and destroys a grpc_tcp_server. */ /* Public function. Stops and destroys a grpc_tcp_server. */
void grpc_tcp_server_destroy(grpc_exec_ctx *exec_ctx, grpc_tcp_server *s, void grpc_tcp_server_destroy(grpc_exec_ctx *exec_ctx, grpc_tcp_server *s,
grpc_closure *shutdown_complete) { grpc_closure *shutdown_complete) {
size_t i;
int immediately_done = 0; int immediately_done = 0;
grpc_tcp_listener *sp;
gpr_mu_lock(&s->mu); gpr_mu_lock(&s->mu);
s->shutdown_complete = shutdown_complete; s->shutdown_complete = shutdown_complete;
@ -138,8 +139,7 @@ void grpc_tcp_server_destroy(grpc_exec_ctx *exec_ctx, grpc_tcp_server *s,
if (s->active_ports == 0) { if (s->active_ports == 0) {
immediately_done = 1; immediately_done = 1;
} }
for (i = 0; i < s->nports; i++) { for (sp = s->head; sp; sp = sp->next) {
server_port *sp = &s->ports[i];
sp->shutting_down = 1; sp->shutting_down = 1;
grpc_winsocket_shutdown(sp->socket); grpc_winsocket_shutdown(sp->socket);
} }
@ -199,7 +199,7 @@ error:
} }
static void decrement_active_ports_and_notify(grpc_exec_ctx *exec_ctx, static void decrement_active_ports_and_notify(grpc_exec_ctx *exec_ctx,
server_port *sp) { grpc_tcp_listener *sp) {
int notify = 0; int notify = 0;
sp->shutting_down = 0; sp->shutting_down = 0;
gpr_mu_lock(&sp->server->mu); gpr_mu_lock(&sp->server->mu);
@ -216,7 +216,7 @@ static void decrement_active_ports_and_notify(grpc_exec_ctx *exec_ctx,
/* In order to do an async accept, we need to create a socket first which /* In order to do an async accept, we need to create a socket first which
will be the one assigned to the new incoming connection. */ will be the one assigned to the new incoming connection. */
static void start_accept(grpc_exec_ctx *exec_ctx, server_port *port) { static void start_accept(grpc_exec_ctx *exec_ctx, grpc_tcp_listener *port) {
SOCKET sock = INVALID_SOCKET; SOCKET sock = INVALID_SOCKET;
char *message; char *message;
char *utf8_message; char *utf8_message;
@ -276,7 +276,7 @@ failure:
/* Event manager callback when reads are ready. */ /* Event manager callback when reads are ready. */
static void on_accept(grpc_exec_ctx *exec_ctx, void *arg, int from_iocp) { static void on_accept(grpc_exec_ctx *exec_ctx, void *arg, int from_iocp) {
server_port *sp = arg; grpc_tcp_listener *sp = arg;
SOCKET sock = sp->new_socket; SOCKET sock = sp->new_socket;
grpc_winsocket_callback_info *info = &sp->socket->read_info; grpc_winsocket_callback_info *info = &sp->socket->read_info;
grpc_endpoint *ep = NULL; grpc_endpoint *ep = NULL;
@ -351,16 +351,17 @@ static void on_accept(grpc_exec_ctx *exec_ctx, void *arg, int from_iocp) {
start_accept(exec_ctx, sp); start_accept(exec_ctx, sp);
} }
static int add_socket_to_server(grpc_tcp_server *s, SOCKET sock, static grpc_tcp_listener *add_socket_to_server(grpc_tcp_server *s, SOCKET sock,
const struct sockaddr *addr, size_t addr_len) { const struct sockaddr *addr,
server_port *sp; size_t addr_len) {
grpc_tcp_listener *sp = NULL;
int port; int port;
int status; int status;
GUID guid = WSAID_ACCEPTEX; GUID guid = WSAID_ACCEPTEX;
DWORD ioctl_num_bytes; DWORD ioctl_num_bytes;
LPFN_ACCEPTEX AcceptEx; LPFN_ACCEPTEX AcceptEx;
if (sock == INVALID_SOCKET) return -1; if (sock == INVALID_SOCKET) return NULL;
/* We need to grab the AcceptEx pointer for that port, as it may be /* We need to grab the AcceptEx pointer for that port, as it may be
interface-dependent. We'll cache it to avoid doing that again. */ interface-dependent. We'll cache it to avoid doing that again. */
@ -373,37 +374,35 @@ static int add_socket_to_server(grpc_tcp_server *s, SOCKET sock,
gpr_log(GPR_ERROR, "on_connect error: %s", utf8_message); gpr_log(GPR_ERROR, "on_connect error: %s", utf8_message);
gpr_free(utf8_message); gpr_free(utf8_message);
closesocket(sock); closesocket(sock);
return -1; return NULL;
} }
port = prepare_socket(sock, addr, addr_len); port = prepare_socket(sock, addr, addr_len);
if (port >= 0) { if (port >= 0) {
gpr_mu_lock(&s->mu); gpr_mu_lock(&s->mu);
GPR_ASSERT(!s->on_accept_cb && "must add ports before starting server"); GPR_ASSERT(!s->on_accept_cb && "must add ports before starting server");
/* append it to the list under a lock */ sp = gpr_malloc(sizeof(grpc_tcp_listener));
if (s->nports == s->port_capacity) { sp->next = s->head;
/* too many ports, and we need to store their address in a closure */ s->head = sp;
/* TODO(ctiller): make server_port a linked list */
abort();
}
sp = &s->ports[s->nports++];
sp->server = s; sp->server = s;
sp->socket = grpc_winsocket_create(sock, "listener"); sp->socket = grpc_winsocket_create(sock, "listener");
sp->shutting_down = 0; sp->shutting_down = 0;
sp->AcceptEx = AcceptEx; sp->AcceptEx = AcceptEx;
sp->new_socket = INVALID_SOCKET; sp->new_socket = INVALID_SOCKET;
sp->port = port;
gpr_ref_init(&sp->refs, 1);
grpc_closure_init(&sp->on_accept, on_accept, sp); grpc_closure_init(&sp->on_accept, on_accept, sp);
GPR_ASSERT(sp->socket); GPR_ASSERT(sp->socket);
gpr_mu_unlock(&s->mu); gpr_mu_unlock(&s->mu);
} }
return port; return sp;
} }
int grpc_tcp_server_add_port(grpc_tcp_server *s, const void *addr, grpc_tcp_listener *grpc_tcp_server_add_port(grpc_tcp_server *s,
size_t addr_len) { const void *addr,
int allocated_port = -1; size_t addr_len) {
unsigned i; grpc_tcp_listener *sp;
SOCKET sock; SOCKET sock;
struct sockaddr_in6 addr6_v4mapped; struct sockaddr_in6 addr6_v4mapped;
struct sockaddr_in6 wildcard; struct sockaddr_in6 wildcard;
@ -415,9 +414,9 @@ int grpc_tcp_server_add_port(grpc_tcp_server *s, const void *addr,
/* Check if this is a wildcard port, and if so, try to keep the port the same /* Check if this is a wildcard port, and if so, try to keep the port the same
as some previously created listener. */ as some previously created listener. */
if (grpc_sockaddr_get_port(addr) == 0) { if (grpc_sockaddr_get_port(addr) == 0) {
for (i = 0; i < s->nports; i++) { for (sp = s->head; sp; sp = sp->next) {
sockname_len = sizeof(sockname_temp); sockname_len = sizeof(sockname_temp);
if (0 == getsockname(s->ports[i].socket->socket, if (0 == getsockname(sp->socket->socket,
(struct sockaddr *)&sockname_temp, &sockname_len)) { (struct sockaddr *)&sockname_temp, &sockname_len)) {
port = grpc_sockaddr_get_port((struct sockaddr *)&sockname_temp); port = grpc_sockaddr_get_port((struct sockaddr *)&sockname_temp);
if (port > 0) { if (port > 0) {
@ -452,33 +451,55 @@ int grpc_tcp_server_add_port(grpc_tcp_server *s, const void *addr,
gpr_free(utf8_message); gpr_free(utf8_message);
} }
allocated_port = add_socket_to_server(s, sock, addr, addr_len); sp = add_socket_to_server(s, sock, addr, addr_len);
gpr_free(allocated_addr); gpr_free(allocated_addr);
return allocated_port; return sp;
} }
SOCKET int grpc_tcp_server_get_fd(grpc_tcp_server *s, unsigned port_index) {
grpc_tcp_server_get_socket(grpc_tcp_server *s, unsigned index) { grpc_tcp_listener *sp;
return (index < s->nports) ? s->ports[index].socket->socket : INVALID_SOCKET; for (sp = s->head; sp && port_index != 0; sp = sp->next, port_index--);
if (port_index == 0 && sp) {
return _open_osfhandle(sp->socket->socket, 0);
} else {
return -1;
}
} }
void grpc_tcp_server_start(grpc_exec_ctx *exec_ctx, grpc_tcp_server *s, void grpc_tcp_server_start(grpc_exec_ctx *exec_ctx, grpc_tcp_server *s,
grpc_pollset **pollset, size_t pollset_count, grpc_pollset **pollset, size_t pollset_count,
grpc_tcp_server_cb on_accept_cb, grpc_tcp_server_cb on_accept_cb,
void *on_accept_cb_arg) { void *on_accept_cb_arg) {
size_t i; grpc_tcp_listener *sp;
GPR_ASSERT(on_accept_cb); GPR_ASSERT(on_accept_cb);
gpr_mu_lock(&s->mu); gpr_mu_lock(&s->mu);
GPR_ASSERT(!s->on_accept_cb); GPR_ASSERT(!s->on_accept_cb);
GPR_ASSERT(s->active_ports == 0); GPR_ASSERT(s->active_ports == 0);
s->on_accept_cb = on_accept_cb; s->on_accept_cb = on_accept_cb;
s->on_accept_cb_arg = on_accept_cb_arg; s->on_accept_cb_arg = on_accept_cb_arg;
for (i = 0; i < s->nports; i++) { for (sp = s->head; sp; sp = sp->next) {
start_accept(exec_ctx, s->ports + i); start_accept(exec_ctx, sp);
s->active_ports++; s->active_ports++;
} }
gpr_mu_unlock(&s->mu); gpr_mu_unlock(&s->mu);
} }
int grpc_tcp_listener_get_port(grpc_tcp_listener *listener) {
grpc_tcp_listener *sp = listener;
return sp->port;
}
void grpc_tcp_listener_ref(grpc_tcp_listener *listener) {
grpc_tcp_listener *sp = listener;
gpr_ref(&sp->refs);
}
void grpc_tcp_listener_unref(grpc_tcp_listener *listener) {
grpc_tcp_listener *sp = listener;
if (gpr_unref(&sp->refs)) {
gpr_free(listener);
}
}
#endif /* GPR_WINSOCK_SOCKET */ #endif /* GPR_WINSOCK_SOCKET */

@ -247,9 +247,11 @@ int grpc_server_add_secure_http2_port(grpc_server *server, const char *addr,
} }
for (i = 0; i < resolved->naddrs; i++) { for (i = 0; i < resolved->naddrs; i++) {
port_temp = grpc_tcp_server_add_port( grpc_tcp_listener *listener;
listener = grpc_tcp_server_add_port(
tcp, (struct sockaddr *)&resolved->addrs[i].addr, tcp, (struct sockaddr *)&resolved->addrs[i].addr,
resolved->addrs[i].len); resolved->addrs[i].len);
port_temp = grpc_tcp_listener_get_port(listener);
if (port_temp >= 0) { if (port_temp >= 0) {
if (port_num == -1) { if (port_num == -1) {
port_num = port_temp; port_num = port_temp;

@ -0,0 +1,288 @@
/*
*
* 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 <grpc/support/avl.h>
#include <assert.h>
#include <stdlib.h>
#include <grpc/support/alloc.h>
#include <grpc/support/string_util.h>
#include <grpc/support/useful.h>
gpr_avl gpr_avl_create(const gpr_avl_vtable *vtable) {
gpr_avl out;
out.vtable = vtable;
out.root = NULL;
return out;
}
static gpr_avl_node *ref_node(gpr_avl_node *node) {
if (node) {
gpr_ref(&node->refs);
}
return node;
}
static void unref_node(const gpr_avl_vtable *vtable, gpr_avl_node *node) {
if (node == NULL) {
return;
}
if (gpr_unref(&node->refs)) {
vtable->destroy_key(node->key);
vtable->destroy_value(node->value);
unref_node(vtable, node->left);
unref_node(vtable, node->right);
gpr_free(node);
}
}
static long node_height(gpr_avl_node *node) {
return node == NULL ? 0 : node->height;
}
#ifndef NDEBUG
static long calculate_height(gpr_avl_node *node) {
return node == NULL ? 0 : 1 + GPR_MAX(calculate_height(node->left),
calculate_height(node->right));
}
static gpr_avl_node *assert_invariants(gpr_avl_node *n) {
if (n == NULL) return NULL;
assert_invariants(n->left);
assert_invariants(n->right);
assert(calculate_height(n) == n->height);
assert(labs(node_height(n->left) - node_height(n->right)) <= 1);
return n;
}
#else
static gpr_avl_node *assert_invariants(gpr_avl_node *n) { return n; }
#endif
gpr_avl_node *new_node(void *key, void *value, gpr_avl_node *left,
gpr_avl_node *right) {
gpr_avl_node *node = gpr_malloc(sizeof(*node));
gpr_ref_init(&node->refs, 1);
node->key = key;
node->value = value;
node->left = assert_invariants(left);
node->right = assert_invariants(right);
node->height = 1 + GPR_MAX(node_height(left), node_height(right));
return node;
}
static gpr_avl_node *get(const gpr_avl_vtable *vtable, gpr_avl_node *node,
void *key) {
long cmp;
if (node == NULL) {
return NULL;
}
cmp = vtable->compare_keys(node->key, key);
if (cmp == 0) {
return node;
} else if (cmp > 0) {
return get(vtable, node->left, key);
} else {
return get(vtable, node->right, key);
}
}
void *gpr_avl_get(gpr_avl avl, void *key) {
gpr_avl_node *node = get(avl.vtable, avl.root, key);
return node ? node->value : NULL;
}
static gpr_avl_node *rotate_left(const gpr_avl_vtable *vtable, void *key,
void *value, gpr_avl_node *left,
gpr_avl_node *right) {
gpr_avl_node *n =
new_node(vtable->copy_key(right->key), vtable->copy_value(right->value),
new_node(key, value, left, ref_node(right->left)),
ref_node(right->right));
unref_node(vtable, right);
return n;
}
static gpr_avl_node *rotate_right(const gpr_avl_vtable *vtable, void *key,
void *value, gpr_avl_node *left,
gpr_avl_node *right) {
gpr_avl_node *n = new_node(
vtable->copy_key(left->key), vtable->copy_value(left->value),
ref_node(left->left), new_node(key, value, ref_node(left->right), right));
unref_node(vtable, left);
return n;
}
static gpr_avl_node *rotate_left_right(const gpr_avl_vtable *vtable, void *key,
void *value, gpr_avl_node *left,
gpr_avl_node *right) {
/* rotate_right(..., rotate_left(left), right) */
gpr_avl_node *n = new_node(
vtable->copy_key(left->right->key),
vtable->copy_value(left->right->value),
new_node(vtable->copy_key(left->key), vtable->copy_value(left->value),
ref_node(left->left), ref_node(left->right->left)),
new_node(key, value, ref_node(left->right->right), right));
unref_node(vtable, left);
return n;
}
static gpr_avl_node *rotate_right_left(const gpr_avl_vtable *vtable, void *key,
void *value, gpr_avl_node *left,
gpr_avl_node *right) {
/* rotate_left(..., left, rotate_right(right)) */
gpr_avl_node *n = new_node(
vtable->copy_key(right->left->key),
vtable->copy_value(right->left->value),
new_node(key, value, left, ref_node(right->left->left)),
new_node(vtable->copy_key(right->key), vtable->copy_key(right->value),
ref_node(right->left->right), ref_node(right->right)));
unref_node(vtable, right);
return n;
}
static gpr_avl_node *rebalance(const gpr_avl_vtable *vtable, void *key,
void *value, gpr_avl_node *left,
gpr_avl_node *right) {
switch (node_height(left) - node_height(right)) {
case 2:
if (node_height(left->left) - node_height(left->right) == -1) {
return assert_invariants(
rotate_left_right(vtable, key, value, left, right));
} else {
return assert_invariants(rotate_right(vtable, key, value, left, right));
}
case -2:
if (node_height(right->left) - node_height(right->right) == 1) {
return assert_invariants(
rotate_right_left(vtable, key, value, left, right));
} else {
return assert_invariants(rotate_left(vtable, key, value, left, right));
}
default:
return assert_invariants(new_node(key, value, left, right));
}
}
static gpr_avl_node *add(const gpr_avl_vtable *vtable, gpr_avl_node *node,
void *key, void *value) {
long cmp;
if (node == NULL) {
return new_node(key, value, NULL, NULL);
}
cmp = vtable->compare_keys(node->key, key);
if (cmp == 0) {
return new_node(key, value, ref_node(node->left), ref_node(node->right));
} else if (cmp > 0) {
return rebalance(
vtable, vtable->copy_key(node->key), vtable->copy_value(node->value),
add(vtable, node->left, key, value), ref_node(node->right));
} else {
return rebalance(vtable, vtable->copy_key(node->key),
vtable->copy_value(node->value), ref_node(node->left),
add(vtable, node->right, key, value));
}
}
gpr_avl gpr_avl_add(gpr_avl avl, void *key, void *value) {
gpr_avl_node *old_root = avl.root;
avl.root = add(avl.vtable, avl.root, key, value);
assert_invariants(avl.root);
unref_node(avl.vtable, old_root);
return avl;
}
static gpr_avl_node *in_order_head(gpr_avl_node *node) {
while (node->left != NULL) {
node = node->left;
}
return node;
}
static gpr_avl_node *in_order_tail(gpr_avl_node *node) {
while (node->right != NULL) {
node = node->right;
}
return node;
}
static gpr_avl_node *remove(const gpr_avl_vtable *vtable, gpr_avl_node *node,
void *key) {
long cmp;
if (node == NULL) {
return NULL;
}
cmp = vtable->compare_keys(node->key, key);
if (cmp == 0) {
if (node->left == NULL) {
return ref_node(node->right);
} else if (node->right == NULL) {
return ref_node(node->left);
} else if (node->left->height < node->right->height) {
gpr_avl_node *h = in_order_head(node->right);
return rebalance(vtable, vtable->copy_key(h->key),
vtable->copy_value(h->value), ref_node(node->left),
remove(vtable, node->right, h->key));
} else {
gpr_avl_node *h = in_order_tail(node->left);
return rebalance(
vtable, vtable->copy_key(h->key), vtable->copy_value(h->value),
remove(vtable, node->left, h->key), ref_node(node->right));
}
} else if (cmp > 0) {
return rebalance(vtable, vtable->copy_key(node->key),
vtable->copy_value(node->value),
remove(vtable, node->left, key), ref_node(node->right));
} else {
return rebalance(vtable, vtable->copy_key(node->key),
vtable->copy_value(node->value), ref_node(node->left),
remove(vtable, node->right, key));
}
}
gpr_avl gpr_avl_remove(gpr_avl avl, void *key) {
gpr_avl_node *old_root = avl.root;
avl.root = remove(avl.vtable, avl.root, key);
assert_invariants(avl.root);
unref_node(avl.vtable, old_root);
return avl;
}
gpr_avl gpr_avl_ref(gpr_avl avl) {
ref_node(avl.root);
return avl;
}
void gpr_avl_unref(gpr_avl avl) { unref_node(avl.vtable, avl.root); }

@ -106,9 +106,11 @@ int grpc_server_add_insecure_http2_port(grpc_server *server, const char *addr) {
} }
for (i = 0; i < resolved->naddrs; i++) { for (i = 0; i < resolved->naddrs; i++) {
port_temp = grpc_tcp_server_add_port( grpc_tcp_listener *listener;
listener = grpc_tcp_server_add_port(
tcp, (struct sockaddr *)&resolved->addrs[i].addr, tcp, (struct sockaddr *)&resolved->addrs[i].addr,
resolved->addrs[i].len); resolved->addrs[i].len);
port_temp = grpc_tcp_listener_get_port(listener);
if (port_temp >= 0) { if (port_temp >= 0) {
if (port_num == -1) { if (port_num == -1) {
port_num = port_temp; port_num = port_temp;

File diff suppressed because it is too large Load Diff

@ -113,6 +113,7 @@ void reconnect_server_init(reconnect_server *server) {
void reconnect_server_start(reconnect_server *server, int port) { void reconnect_server_start(reconnect_server *server, int port) {
struct sockaddr_in addr; struct sockaddr_in addr;
grpc_tcp_listener *listener;
int port_added; int port_added;
grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT; grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
@ -121,8 +122,9 @@ void reconnect_server_start(reconnect_server *server, int port) {
memset(&addr.sin_addr, 0, sizeof(addr.sin_addr)); memset(&addr.sin_addr, 0, sizeof(addr.sin_addr));
server->tcp_server = grpc_tcp_server_create(); server->tcp_server = grpc_tcp_server_create();
port_added = listener =
grpc_tcp_server_add_port(server->tcp_server, &addr, sizeof(addr)); grpc_tcp_server_add_port(server->tcp_server, &addr, sizeof(addr));
port_added = grpc_tcp_listener_get_port(listener);
GPR_ASSERT(port_added == port); GPR_ASSERT(port_added == port);
grpc_tcp_server_start(&exec_ctx, server->tcp_server, server->pollsets, 1, grpc_tcp_server_start(&exec_ctx, server->tcp_server, server->pollsets, 1,

@ -49,7 +49,10 @@ enum RpcType {
STREAMING = 1; STREAMING = 1;
} }
// Parameters of poisson process distribution, which is a good representation
// of activity coming in from independent identical stationary sources.
message PoissonParams { message PoissonParams {
// The rate of arrivals (a.k.a. lambda parameter of the exp distribution).
double offered_load = 1; double offered_load = 1;
} }
@ -67,6 +70,8 @@ message ParetoParams {
double alpha = 2; double alpha = 2;
} }
// Once an RPC finishes, immediately start a new one.
// No configuration parameters needed.
message ClosedLoopParams { message ClosedLoopParams {
} }
@ -87,14 +92,20 @@ message SecurityParams {
} }
message ClientConfig { message ClientConfig {
// List of targets to connect to. At least one target needs to be specified.
repeated string server_targets = 1; repeated string server_targets = 1;
ClientType client_type = 2; ClientType client_type = 2;
SecurityParams security_params = 3; SecurityParams security_params = 3;
// How many concurrent RPCs to start for each channel.
// For synchronous client, use a separate thread for each outstanding RPC.
int32 outstanding_rpcs_per_channel = 4; int32 outstanding_rpcs_per_channel = 4;
// Number of independent client channels to create.
// i-th channel will connect to server_target[i % server_targets.size()]
int32 client_channels = 5; int32 client_channels = 5;
// only for async client: // Only for async client. Number of threads to use to start/manage RPCs.
int32 async_client_threads = 7; int32 async_client_threads = 7;
RpcType rpc_type = 8; RpcType rpc_type = 8;
// The requested load for the entire client (aggregated over all the threads).
LoadParams load_params = 10; LoadParams load_params = 10;
PayloadConfig payload_config = 11; PayloadConfig payload_config = 11;
HistogramParams histogram_params = 12; HistogramParams histogram_params = 12;
@ -106,6 +117,7 @@ message ClientStatus {
// Request current stats // Request current stats
message Mark { message Mark {
// if true, the stats will be reset after taking their snapshot.
bool reset = 1; bool reset = 1;
} }
@ -119,11 +131,13 @@ message ClientArgs {
message ServerConfig { message ServerConfig {
ServerType server_type = 1; ServerType server_type = 1;
SecurityParams security_params = 2; SecurityParams security_params = 2;
// Host on which to listen.
string host = 3; string host = 3;
// Port on which to listen. Zero means pick unused port.
int32 port = 4; int32 port = 4;
// only for async server // Only for async server. Number of threads used to serve the requests.
int32 async_server_threads = 7; int32 async_server_threads = 7;
// restrict core usage // restrict core usage, currently unused
int32 core_limit = 8; int32 core_limit = 8;
PayloadConfig payload_config = 9; PayloadConfig payload_config = 9;
} }
@ -137,6 +151,8 @@ message ServerArgs {
message ServerStatus { message ServerStatus {
ServerStats stats = 1; ServerStats stats = 1;
// the port bound by the server
int32 port = 2; int32 port = 2;
// Number of cores on the server. See gpr_cpu_num_cores.
int32 cores = 3; int32 cores = 3;
} }

@ -47,9 +47,19 @@ service BenchmarkService {
} }
service WorkerService { service WorkerService {
// Start server with specified workload // Start server with specified workload.
// First request sent specifies the ServerConfig followed by ServerStatus
// response. After that, a "Mark" can be sent anytime to request the latest
// stats. Closing the stream will initiate shutdown of the test server
// and once the shutdown has finished, the OK status is sent to terminate
// this RPC.
rpc RunServer(stream ServerArgs) returns (stream ServerStatus); rpc RunServer(stream ServerArgs) returns (stream ServerStatus);
// Start client with specified workload // Start client with specified workload.
// First request sent specifies the ClientConfig followed by ClientStatus
// response. After that, a "Mark" can be sent anytime to request the latest
// stats. Closing the stream will initiate shutdown of the test client
// and once the shutdown has finished, the OK status is sent to terminate
// this RPC.
rpc RunClient(stream ClientArgs) returns (stream ClientStatus); rpc RunClient(stream ClientArgs) returns (stream ClientStatus);
} }

@ -32,14 +32,14 @@ syntax = "proto3";
package grpc.testing; package grpc.testing;
message ServerStats { message ServerStats {
// wall clock time change since last reset // wall clock time change in seconds since last reset
double time_elapsed = 1; double time_elapsed = 1;
// change in user time used by the server since last reset // change in user time (in seconds) used by the server since last reset
double time_user = 2; double time_user = 2;
// change in server time used by the server process and all threads since // change in server time (in seconds) used by the server process and all
// last reset // threads since last reset
double time_system = 3; double time_system = 3;
} }

@ -772,6 +772,7 @@ include/grpc/support/atm.h \
include/grpc/support/atm_gcc_atomic.h \ include/grpc/support/atm_gcc_atomic.h \
include/grpc/support/atm_gcc_sync.h \ include/grpc/support/atm_gcc_sync.h \
include/grpc/support/atm_win32.h \ include/grpc/support/atm_win32.h \
include/grpc/support/avl.h \
include/grpc/support/cmdline.h \ include/grpc/support/cmdline.h \
include/grpc/support/cpu.h \ include/grpc/support/cpu.h \
include/grpc/support/histogram.h \ include/grpc/support/histogram.h \

@ -1053,6 +1053,7 @@ include/grpc/support/atm.h \
include/grpc/support/atm_gcc_atomic.h \ include/grpc/support/atm_gcc_atomic.h \
include/grpc/support/atm_gcc_sync.h \ include/grpc/support/atm_gcc_sync.h \
include/grpc/support/atm_win32.h \ include/grpc/support/atm_win32.h \
include/grpc/support/avl.h \
include/grpc/support/cmdline.h \ include/grpc/support/cmdline.h \
include/grpc/support/cpu.h \ include/grpc/support/cpu.h \
include/grpc/support/histogram.h \ include/grpc/support/histogram.h \
@ -1088,6 +1089,7 @@ src/core/support/time_precise.h \
src/core/profiling/basic_timers.c \ src/core/profiling/basic_timers.c \
src/core/profiling/stap_timers.c \ src/core/profiling/stap_timers.c \
src/core/support/alloc.c \ src/core/support/alloc.c \
src/core/support/avl.c \
src/core/support/cmdline.c \ src/core/support/cmdline.c \
src/core/support/cpu_iphone.c \ src/core/support/cpu_iphone.c \
src/core/support/cpu_linux.c \ src/core/support/cpu_linux.c \

@ -624,10 +624,15 @@ build_configs = set(cfg.build_config for cfg in run_configs)
if args.travis: if args.travis:
_FORCE_ENVIRON_FOR_WRAPPERS = {'GRPC_TRACE': 'api'} _FORCE_ENVIRON_FOR_WRAPPERS = {'GRPC_TRACE': 'api'}
languages = set(_LANGUAGES[l] if 'all' in args.language:
for l in itertools.chain.from_iterable( lang_list = _LANGUAGES.keys()
_LANGUAGES.iterkeys() if x == 'all' else [x] else:
for x in args.language)) lang_list = args.language
# We don't support code coverage on ObjC
if 'gcov' in args.config and 'objc' in lang_list:
lang_list.remove('objc')
languages = set(_LANGUAGES[l] for l in lang_list)
if len(build_configs) > 1: if len(build_configs) > 1:
for language in languages: for language in languages:
@ -840,6 +845,7 @@ def _calculate_num_runs_failures(list_of_results):
num_failures += jobresult.num_failures num_failures += jobresult.num_failures
return num_runs, num_failures return num_runs, num_failures
def _build_and_run( def _build_and_run(
check_cancelled, newline_on_success, cache, xml_report=None): check_cancelled, newline_on_success, cache, xml_report=None):
"""Do one pass of building & running tests.""" """Do one pass of building & running tests."""

@ -218,6 +218,18 @@
"tools/codegen/core/gen_legal_metadata_characters.c" "tools/codegen/core/gen_legal_metadata_characters.c"
] ]
}, },
{
"deps": [
"gpr",
"gpr_test_util"
],
"headers": [],
"language": "c",
"name": "gpr_avl_test",
"src": [
"test/core/support/avl_test.c"
]
},
{ {
"deps": [ "deps": [
"gpr", "gpr",
@ -14175,6 +14187,7 @@
"include/grpc/support/atm_gcc_atomic.h", "include/grpc/support/atm_gcc_atomic.h",
"include/grpc/support/atm_gcc_sync.h", "include/grpc/support/atm_gcc_sync.h",
"include/grpc/support/atm_win32.h", "include/grpc/support/atm_win32.h",
"include/grpc/support/avl.h",
"include/grpc/support/cmdline.h", "include/grpc/support/cmdline.h",
"include/grpc/support/cpu.h", "include/grpc/support/cpu.h",
"include/grpc/support/histogram.h", "include/grpc/support/histogram.h",
@ -14216,6 +14229,7 @@
"include/grpc/support/atm_gcc_atomic.h", "include/grpc/support/atm_gcc_atomic.h",
"include/grpc/support/atm_gcc_sync.h", "include/grpc/support/atm_gcc_sync.h",
"include/grpc/support/atm_win32.h", "include/grpc/support/atm_win32.h",
"include/grpc/support/avl.h",
"include/grpc/support/cmdline.h", "include/grpc/support/cmdline.h",
"include/grpc/support/cpu.h", "include/grpc/support/cpu.h",
"include/grpc/support/histogram.h", "include/grpc/support/histogram.h",
@ -14242,6 +14256,7 @@
"src/core/profiling/stap_timers.c", "src/core/profiling/stap_timers.c",
"src/core/profiling/timers.h", "src/core/profiling/timers.h",
"src/core/support/alloc.c", "src/core/support/alloc.c",
"src/core/support/avl.c",
"src/core/support/block_annotate.h", "src/core/support/block_annotate.h",
"src/core/support/cmdline.c", "src/core/support/cmdline.c",
"src/core/support/cpu_iphone.c", "src/core/support/cpu_iphone.c",

@ -207,6 +207,24 @@
"posix" "posix"
] ]
}, },
{
"ci_platforms": [
"linux",
"mac",
"posix",
"windows"
],
"exclude_configs": [],
"flaky": false,
"language": "c",
"name": "gpr_avl_test",
"platforms": [
"linux",
"mac",
"posix",
"windows"
]
},
{ {
"ci_platforms": [ "ci_platforms": [
"linux", "linux",

@ -732,6 +732,15 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "gen_legal_metadata_characte
lib = "False" lib = "False"
EndProjectSection EndProjectSection
EndProject EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "gpr_avl_test", "vcxproj\test\gpr_avl_test\gpr_avl_test.vcxproj", "{144D8CFF-2737-A18A-DCFD-01603533D63F}"
ProjectSection(myProperties) = preProject
lib = "False"
EndProjectSection
ProjectSection(ProjectDependencies) = postProject
{EAB0A629-17A9-44DB-B5FF-E91A721FE037} = {EAB0A629-17A9-44DB-B5FF-E91A721FE037}
{B23D3D1A-9438-4EDA-BEB6-9A0A03D17792} = {B23D3D1A-9438-4EDA-BEB6-9A0A03D17792}
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "gpr_cmdline_test", "vcxproj\test\gpr_cmdline_test\gpr_cmdline_test.vcxproj", "{10668A5D-65CD-F530-22D0-747B395B4C26}" Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "gpr_cmdline_test", "vcxproj\test\gpr_cmdline_test\gpr_cmdline_test.vcxproj", "{10668A5D-65CD-F530-22D0-747B395B4C26}"
ProjectSection(myProperties) = preProject ProjectSection(myProperties) = preProject
lib = "False" lib = "False"
@ -10592,6 +10601,22 @@ Global
{A635DE99-B131-CA00-2D3B-8691D60B76C2}.Release-DLL|Win32.Build.0 = Release|Win32 {A635DE99-B131-CA00-2D3B-8691D60B76C2}.Release-DLL|Win32.Build.0 = Release|Win32
{A635DE99-B131-CA00-2D3B-8691D60B76C2}.Release-DLL|x64.ActiveCfg = Release|x64 {A635DE99-B131-CA00-2D3B-8691D60B76C2}.Release-DLL|x64.ActiveCfg = Release|x64
{A635DE99-B131-CA00-2D3B-8691D60B76C2}.Release-DLL|x64.Build.0 = Release|x64 {A635DE99-B131-CA00-2D3B-8691D60B76C2}.Release-DLL|x64.Build.0 = Release|x64
{144D8CFF-2737-A18A-DCFD-01603533D63F}.Debug|Win32.ActiveCfg = Debug|Win32
{144D8CFF-2737-A18A-DCFD-01603533D63F}.Debug|x64.ActiveCfg = Debug|x64
{144D8CFF-2737-A18A-DCFD-01603533D63F}.Release|Win32.ActiveCfg = Release|Win32
{144D8CFF-2737-A18A-DCFD-01603533D63F}.Release|x64.ActiveCfg = Release|x64
{144D8CFF-2737-A18A-DCFD-01603533D63F}.Debug|Win32.Build.0 = Debug|Win32
{144D8CFF-2737-A18A-DCFD-01603533D63F}.Debug|x64.Build.0 = Debug|x64
{144D8CFF-2737-A18A-DCFD-01603533D63F}.Release|Win32.Build.0 = Release|Win32
{144D8CFF-2737-A18A-DCFD-01603533D63F}.Release|x64.Build.0 = Release|x64
{144D8CFF-2737-A18A-DCFD-01603533D63F}.Debug-DLL|Win32.ActiveCfg = Debug|Win32
{144D8CFF-2737-A18A-DCFD-01603533D63F}.Debug-DLL|Win32.Build.0 = Debug|Win32
{144D8CFF-2737-A18A-DCFD-01603533D63F}.Debug-DLL|x64.ActiveCfg = Debug|x64
{144D8CFF-2737-A18A-DCFD-01603533D63F}.Debug-DLL|x64.Build.0 = Debug|x64
{144D8CFF-2737-A18A-DCFD-01603533D63F}.Release-DLL|Win32.ActiveCfg = Release|Win32
{144D8CFF-2737-A18A-DCFD-01603533D63F}.Release-DLL|Win32.Build.0 = Release|Win32
{144D8CFF-2737-A18A-DCFD-01603533D63F}.Release-DLL|x64.ActiveCfg = Release|x64
{144D8CFF-2737-A18A-DCFD-01603533D63F}.Release-DLL|x64.Build.0 = Release|x64
{10668A5D-65CD-F530-22D0-747B395B4C26}.Debug|Win32.ActiveCfg = Debug|Win32 {10668A5D-65CD-F530-22D0-747B395B4C26}.Debug|Win32.ActiveCfg = Debug|Win32
{10668A5D-65CD-F530-22D0-747B395B4C26}.Debug|x64.ActiveCfg = Debug|x64 {10668A5D-65CD-F530-22D0-747B395B4C26}.Debug|x64.ActiveCfg = Debug|x64
{10668A5D-65CD-F530-22D0-747B395B4C26}.Release|Win32.ActiveCfg = Release|Win32 {10668A5D-65CD-F530-22D0-747B395B4C26}.Release|Win32.ActiveCfg = Release|Win32

@ -139,6 +139,7 @@
<ClInclude Include="..\..\..\include\grpc\support\atm_gcc_atomic.h" /> <ClInclude Include="..\..\..\include\grpc\support\atm_gcc_atomic.h" />
<ClInclude Include="..\..\..\include\grpc\support\atm_gcc_sync.h" /> <ClInclude Include="..\..\..\include\grpc\support\atm_gcc_sync.h" />
<ClInclude Include="..\..\..\include\grpc\support\atm_win32.h" /> <ClInclude Include="..\..\..\include\grpc\support\atm_win32.h" />
<ClInclude Include="..\..\..\include\grpc\support\avl.h" />
<ClInclude Include="..\..\..\include\grpc\support\cmdline.h" /> <ClInclude Include="..\..\..\include\grpc\support\cmdline.h" />
<ClInclude Include="..\..\..\include\grpc\support\cpu.h" /> <ClInclude Include="..\..\..\include\grpc\support\cpu.h" />
<ClInclude Include="..\..\..\include\grpc\support\histogram.h" /> <ClInclude Include="..\..\..\include\grpc\support\histogram.h" />
@ -181,6 +182,8 @@
</ClCompile> </ClCompile>
<ClCompile Include="..\..\..\src\core\support\alloc.c"> <ClCompile Include="..\..\..\src\core\support\alloc.c">
</ClCompile> </ClCompile>
<ClCompile Include="..\..\..\src\core\support\avl.c">
</ClCompile>
<ClCompile Include="..\..\..\src\core\support\cmdline.c"> <ClCompile Include="..\..\..\src\core\support\cmdline.c">
</ClCompile> </ClCompile>
<ClCompile Include="..\..\..\src\core\support\cpu_iphone.c"> <ClCompile Include="..\..\..\src\core\support\cpu_iphone.c">

@ -10,6 +10,9 @@
<ClCompile Include="..\..\..\src\core\support\alloc.c"> <ClCompile Include="..\..\..\src\core\support\alloc.c">
<Filter>src\core\support</Filter> <Filter>src\core\support</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="..\..\..\src\core\support\avl.c">
<Filter>src\core\support</Filter>
</ClCompile>
<ClCompile Include="..\..\..\src\core\support\cmdline.c"> <ClCompile Include="..\..\..\src\core\support\cmdline.c">
<Filter>src\core\support</Filter> <Filter>src\core\support</Filter>
</ClCompile> </ClCompile>
@ -138,6 +141,9 @@
<ClInclude Include="..\..\..\include\grpc\support\atm_win32.h"> <ClInclude Include="..\..\..\include\grpc\support\atm_win32.h">
<Filter>include\grpc\support</Filter> <Filter>include\grpc\support</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="..\..\..\include\grpc\support\avl.h">
<Filter>include\grpc\support</Filter>
</ClInclude>
<ClInclude Include="..\..\..\include\grpc\support\cmdline.h"> <ClInclude Include="..\..\..\include\grpc\support\cmdline.h">
<Filter>include\grpc\support</Filter> <Filter>include\grpc\support</Filter>
</ClInclude> </ClInclude>

@ -0,0 +1,178 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="..\..\..\..\vsprojects\packages\grpc.dependencies.openssl.1.0.2.3\build\native\grpc.dependencies.openssl.props" Condition="Exists('..\..\..\..\vsprojects\packages\grpc.dependencies.openssl.1.0.2.3\build\native\1.0.2.3.props')" />
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|x64">
<Configuration>Debug</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|x64">
<Configuration>Release</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<ProjectGuid>{144D8CFF-2737-A18A-DCFD-01603533D63F}</ProjectGuid>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(VisualStudioVersion)' == '10.0'" Label="Configuration">
<PlatformToolset>v100</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(VisualStudioVersion)' == '11.0'" Label="Configuration">
<PlatformToolset>v110</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(VisualStudioVersion)' == '12.0'" Label="Configuration">
<PlatformToolset>v120</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)'=='Debug'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)'=='Release'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
<Import Project="..\..\..\..\vsprojects\global.props" />
<Import Project="..\..\..\..\vsprojects\openssl.props" />
<Import Project="..\..\..\..\vsprojects\winsock.props" />
<Import Project="..\..\..\..\vsprojects\zlib.props" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup Condition="'$(Configuration)'=='Debug'">
<TargetName>gpr_avl_test</TargetName>
<Linkage-grpc_dependencies_zlib>static</Linkage-grpc_dependencies_zlib>
<Configuration-grpc_dependencies_zlib>Debug</Configuration-grpc_dependencies_zlib>
<Configuration-grpc_dependencies_openssl>Debug</Configuration-grpc_dependencies_openssl>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)'=='Release'">
<TargetName>gpr_avl_test</TargetName>
<Linkage-grpc_dependencies_zlib>static</Linkage-grpc_dependencies_zlib>
<Configuration-grpc_dependencies_zlib>Debug</Configuration-grpc_dependencies_zlib>
<Configuration-grpc_dependencies_openssl>Debug</Configuration-grpc_dependencies_openssl>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<PrecompiledHeader>NotUsing</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization>
<PreprocessorDefinitions>WIN32;_DEBUG;_LIB;_USE_32BIT_TIME_T;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<SDLCheck>true</SDLCheck>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
<TreatWarningAsError>true</TreatWarningAsError>
<DebugInformationFormat Condition="$(Jenkins)">None</DebugInformationFormat>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<GenerateDebugInformation Condition="!$(Jenkins)">true</GenerateDebugInformation>
<GenerateDebugInformation Condition="$(Jenkins)">false</GenerateDebugInformation>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<ClCompile>
<PrecompiledHeader>NotUsing</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization>
<PreprocessorDefinitions>WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<SDLCheck>true</SDLCheck>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
<TreatWarningAsError>true</TreatWarningAsError>
<DebugInformationFormat Condition="$(Jenkins)">None</DebugInformationFormat>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<GenerateDebugInformation Condition="!$(Jenkins)">true</GenerateDebugInformation>
<GenerateDebugInformation Condition="$(Jenkins)">false</GenerateDebugInformation>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<PrecompiledHeader>NotUsing</PrecompiledHeader>
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>WIN32;NDEBUG;_LIB;_USE_32BIT_TIME_T;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<SDLCheck>true</SDLCheck>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
<TreatWarningAsError>true</TreatWarningAsError>
<DebugInformationFormat Condition="$(Jenkins)">None</DebugInformationFormat>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<GenerateDebugInformation Condition="!$(Jenkins)">true</GenerateDebugInformation>
<GenerateDebugInformation Condition="$(Jenkins)">false</GenerateDebugInformation>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<PrecompiledHeader>NotUsing</PrecompiledHeader>
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<SDLCheck>true</SDLCheck>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
<TreatWarningAsError>true</TreatWarningAsError>
<DebugInformationFormat Condition="$(Jenkins)">None</DebugInformationFormat>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<GenerateDebugInformation Condition="!$(Jenkins)">true</GenerateDebugInformation>
<GenerateDebugInformation Condition="$(Jenkins)">false</GenerateDebugInformation>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
</Link>
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="..\..\..\..\test\core\support\avl_test.c">
</ClCompile>
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\..\..\vsprojects\vcxproj\.\gpr_test_util\gpr_test_util.vcxproj">
<Project>{EAB0A629-17A9-44DB-B5FF-E91A721FE037}</Project>
</ProjectReference>
<ProjectReference Include="..\..\..\..\vsprojects\vcxproj\.\gpr\gpr.vcxproj">
<Project>{B23D3D1A-9438-4EDA-BEB6-9A0A03D17792}</Project>
</ProjectReference>
</ItemGroup>
<ItemGroup>
<None Include="packages.config" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
<Import Project="..\..\..\..\vsprojects\packages\grpc.dependencies.zlib.redist.1.2.8.9\build\native\grpc.dependencies.zlib.redist.targets" Condition="Exists('..\..\..\..\vsprojects\packages\grpc.dependencies.zlib.redist.1.2.8.9\build\native\grpc.dependencies\grpc.dependencies.zlib.targets')" />
<Import Project="..\..\..\..\vsprojects\packages\grpc.dependencies.zlib.1.2.8.9\build\native\grpc.dependencies.zlib.targets" Condition="Exists('..\..\..\..\vsprojects\packages\grpc.dependencies.zlib.1.2.8.9\build\native\grpc.dependencies\grpc.dependencies.zlib.targets')" />
<Import Project="..\..\..\..\vsprojects\packages\grpc.dependencies.openssl.redist.1.0.2.3\build\native\grpc.dependencies.openssl.redist.targets" Condition="Exists('..\..\..\..\vsprojects\packages\grpc.dependencies.openssl.redist.1.0.2.3\build\native\grpc.dependencies\grpc.dependencies.openssl.targets')" />
<Import Project="..\..\..\..\vsprojects\packages\grpc.dependencies.openssl.1.0.2.3\build\native\grpc.dependencies.openssl.targets" Condition="Exists('..\..\..\..\vsprojects\packages\grpc.dependencies.openssl.1.0.2.3\build\native\grpc.dependencies\grpc.dependencies.openssl.targets')" />
</ImportGroup>
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
<PropertyGroup>
<ErrorText>This project references NuGet package(s) that are missing on this computer. Enable NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>
</PropertyGroup>
<Error Condition="!Exists('..\..\..\..\vsprojects\packages\grpc.dependencies.zlib.redist.1.2.8.9\build\native\grpc.dependencies.zlib.redist.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\..\vsprojects\packages\grpc.dependencies.zlib.redist.1.2.8.9\build\native\grpc.dependencies.zlib.redist.targets')" />
<Error Condition="!Exists('..\..\..\..\vsprojects\packages\grpc.dependencies.zlib.1.2.8.9\build\native\grpc.dependencies.zlib.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\..\vsprojects\packages\grpc.dependencies.zlib.1.2.8.9\build\native\grpc.dependencies.zlib.targets')" />
<Error Condition="!Exists('..\..\..\..\vsprojects\packages\grpc.dependencies.openssl.redist.1.0.2.3\build\native\grpc.dependencies.openssl.redist.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\..\vsprojects\packages\grpc.dependencies.openssl.redist.1.0.2.3\build\native\grpc.dependencies.openssl.redist.targets')" />
<Error Condition="!Exists('..\..\..\..\vsprojects\packages\grpc.dependencies.openssl.1.0.2.3\build\native\grpc.dependencies.openssl.props')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\..\vsprojects\packages\grpc.dependencies.openssl.1.0.2.3\build\native\grpc.dependencies.openssl.props')" />
<Error Condition="!Exists('..\..\..\..\vsprojects\packages\grpc.dependencies.openssl.1.0.2.3\build\native\grpc.dependencies.openssl.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\..\vsprojects\packages\grpc.dependencies.openssl.1.0.2.3\build\native\grpc.dependencies.openssl.targets')" />
</Target>
</Project>

@ -0,0 +1,21 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<ClCompile Include="..\..\..\..\test\core\support\avl_test.c">
<Filter>test\core\support</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<Filter Include="test">
<UniqueIdentifier>{36d067be-341d-9b6e-8ebc-bc48318fa916}</UniqueIdentifier>
</Filter>
<Filter Include="test\core">
<UniqueIdentifier>{4f3292f9-bb3f-e90c-324d-120ff96d394a}</UniqueIdentifier>
</Filter>
<Filter Include="test\core\support">
<UniqueIdentifier>{d02b711f-14e2-086b-d3a5-48e2d82145ee}</UniqueIdentifier>
</Filter>
</ItemGroup>
</Project>
Loading…
Cancel
Save