Merge github.com:grpc/grpc into epex4

pull/10712/head
Craig Tiller 8 years ago
commit 1fb0c39168
  1. 75
      BUILD
  2. 32
      CMakeLists.txt
  3. 36
      Makefile
  4. 9
      README.md
  5. 11
      WORKSPACE
  6. 4
      bazel/BUILD
  7. 2
      bazel/cc_grpc_library.bzl
  8. 6
      bazel/generate_cc.bzl
  9. 16
      bazel/grpc_build_system.bzl
  10. 10
      build.yaml
  11. 6
      doc/interop-test-descriptions.md
  12. 21
      doc/service_config.md
  13. 1
      src/compiler/objective_c_plugin.cc
  14. 27
      src/core/ext/filters/client_channel/client_channel.c
  15. 24
      src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.c
  16. 2
      src/core/ext/filters/http/message_compress/message_compress_filter.c
  17. 11
      src/core/ext/filters/message_size/message_size_filter.c
  18. 2
      src/core/ext/transport/chttp2/server/chttp2_server.c
  19. 68
      src/core/lib/slice/slice_hash_table.c
  20. 19
      src/core/lib/slice/slice_hash_table.h
  21. 6
      src/core/lib/support/stack_lockfree.c
  22. 8
      src/core/lib/support/time_posix.c
  23. 20
      src/core/lib/support/tmpfile_posix.c
  24. 1
      src/core/lib/surface/call.c
  25. 2
      src/core/lib/surface/server.c
  26. 19
      src/core/lib/transport/service_config.c
  27. 4
      src/core/lib/transport/service_config.h
  28. 7
      src/objective-c/GRPCClient/GRPCCall.h
  29. 16
      src/objective-c/GRPCClient/GRPCCall.m
  30. 4
      src/objective-c/RxLibrary/GRXConcurrentWriteable.h
  31. 10
      src/objective-c/RxLibrary/GRXConcurrentWriteable.m
  32. 55
      src/objective-c/tests/GRPCClientTests.m
  33. 4
      src/proto/grpc/status/BUILD
  34. 2
      src/python/grpcio_tests/tests/http2/negative_http2_client.py
  35. 52
      test/core/end2end/fixtures/http_proxy_fixture.c
  36. 9
      test/core/end2end/tests/cancel_after_invoke.c
  37. 23
      test/core/slice/BUILD
  38. 138
      test/core/slice/slice_hash_table_test.c
  39. 2
      test/cpp/interop/http2_client.cc
  40. 2
      test/cpp/microbenchmarks/bm_call_create.cc
  41. 4
      test/cpp/microbenchmarks/helpers.cc
  42. 3
      test/cpp/microbenchmarks/helpers.h
  43. 9
      test/cpp/util/BUILD
  44. 13
      tools/grpcz/BUILD
  45. 2
      tools/profiling/microbenchmarks/bm2bq.py
  46. 1
      tools/profiling/microbenchmarks/bm_diff.py
  47. 17
      tools/run_tests/generated/sources_and_headers.json
  48. 22
      tools/run_tests/generated/tests.json
  49. 27
      vsprojects/buildtests_c.sln
  50. 199
      vsprojects/vcxproj/test/slice_hash_table_test/slice_hash_table_test.vcxproj
  51. 21
      vsprojects/vcxproj/test/slice_hash_table_test/slice_hash_table_test.vcxproj.filters

75
BUILD

@ -35,7 +35,8 @@ exports_files(["LICENSE"])
package(default_visibility = ["//visibility:public"])
load("//bazel:grpc_build_system.bzl", "grpc_cc_library", "grpc_proto_plugin")
load("//bazel:grpc_build_system.bzl", "grpc_cc_library",
"grpc_proto_plugin", "grpc_cc_libraries")
# This should be updated along with build.yaml
g_stands_for = "gentle"
@ -53,33 +54,46 @@ grpc_cc_library(
],
)
grpc_cc_library(
name = "grpc",
grpc_cc_libraries(
name_list = ["grpc", "grpc_unsecure",],
srcs = [
"src/core/lib/surface/init.c",
"src/core/plugin_registry/grpc_plugin_registry.c",
],
additional_src_list = [
[
"src/core/plugin_registry/grpc_plugin_registry.c",
],
[
"src/core/lib/surface/init_unsecure.c",
"src/core/plugin_registry/grpc_unsecure_plugin_registry.c",
],
],
language = "c",
standalone = True,
deps = [
"census",
"grpc_base",
"grpc_lb_policy_grpclb_secure",
"grpc_lb_policy_pick_first",
"grpc_lb_policy_round_robin",
"grpc_load_reporting",
"grpc_max_age_filter",
"grpc_resolver_dns_ares",
"grpc_resolver_dns_native",
"grpc_resolver_sockaddr",
"grpc_secure",
"grpc_transport_chttp2_client_insecure",
"grpc_transport_chttp2_client_secure",
"grpc_transport_chttp2_server_insecure",
"grpc_transport_chttp2_server_secure",
"grpc_message_size_filter",
"grpc_deadline_filter",
],
additional_dep_list = [
[
"grpc_secure",
"grpc_resolver_dns_ares",
"grpc_lb_policy_grpclb_secure",
"grpc_transport_chttp2_client_secure",
"grpc_transport_chttp2_server_secure",
],
[],
],
)
grpc_cc_library(
@ -97,32 +111,6 @@ grpc_cc_library(
],
)
grpc_cc_library(
name = "grpc_unsecure",
srcs = [
"src/core/lib/surface/init.c",
"src/core/lib/surface/init_unsecure.c",
"src/core/plugin_registry/grpc_unsecure_plugin_registry.c",
],
language = "c",
standalone = True,
deps = [
"census",
"grpc_base",
"grpc_lb_policy_grpclb",
"grpc_lb_policy_pick_first",
"grpc_lb_policy_round_robin",
"grpc_load_reporting",
"grpc_max_age_filter",
"grpc_resolver_dns_native",
"grpc_resolver_sockaddr",
"grpc_transport_chttp2_client_insecure",
"grpc_transport_chttp2_server_insecure",
"grpc_message_size_filter",
"grpc_deadline_filter",
],
)
grpc_cc_library(
name = "grpc++",
srcs = [
@ -163,7 +151,7 @@ grpc_cc_library(
standalone = True,
deps = [
"gpr",
"grpc++_base",
"grpc++_base_unsecure",
"grpc++_codegen_base",
"grpc++_codegen_base_src",
"grpc_unsecure",
@ -1233,8 +1221,12 @@ grpc_cc_library(
],
)
grpc_cc_library(
name = "grpc++_base",
grpc_cc_libraries(
name_list = ["grpc++_base", "grpc++_base_unsecure"],
additional_dep_list = [
["grpc", ],
["grpc_unsecure", ],
],
srcs = [
"src/cpp/client/channel_cc.cc",
"src/cpp/client/client_context.cc",
@ -1269,7 +1261,7 @@ grpc_cc_library(
"src/cpp/util/status.cc",
"src/cpp/util/string_ref.cc",
"src/cpp/util/time_cc.cc",
],
],
hdrs = [
"src/cpp/client/create_channel_internal.h",
"src/cpp/common/channel_filter.h",
@ -1278,7 +1270,7 @@ grpc_cc_library(
"src/cpp/server/health/health.pb.h",
"src/cpp/server/thread_pool_interface.h",
"src/cpp/thread_manager/thread_manager.h",
],
],
language = "c++",
public_hdrs = [
"include/grpc++/alarm.h",
@ -1328,9 +1320,8 @@ grpc_cc_library(
"include/grpc++/support/stub_options.h",
"include/grpc++/support/sync_stream.h",
"include/grpc++/support/time.h",
],
],
deps = [
"grpc",
"grpc++_codegen_base",
],
)

@ -495,6 +495,7 @@ add_dependencies(buildtests_c sequential_connectivity_test)
add_dependencies(buildtests_c server_chttp2_test)
add_dependencies(buildtests_c server_test)
add_dependencies(buildtests_c slice_buffer_test)
add_dependencies(buildtests_c slice_hash_table_test)
add_dependencies(buildtests_c slice_string_helpers_test)
add_dependencies(buildtests_c slice_test)
add_dependencies(buildtests_c sockaddr_resolver_test)
@ -8012,6 +8013,37 @@ target_link_libraries(slice_buffer_test
endif (gRPC_BUILD_TESTS)
if (gRPC_BUILD_TESTS)
add_executable(slice_hash_table_test
test/core/slice/slice_hash_table_test.c
)
target_include_directories(slice_hash_table_test
PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
PRIVATE ${BORINGSSL_ROOT_DIR}/include
PRIVATE ${PROTOBUF_ROOT_DIR}/src
PRIVATE ${BENCHMARK_ROOT_DIR}/include
PRIVATE ${ZLIB_ROOT_DIR}
PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
PRIVATE ${CARES_BUILD_INCLUDE_DIR}
PRIVATE ${CARES_INCLUDE_DIR}
PRIVATE ${CARES_PLATFORM_INCLUDE_DIR}
PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/cares/cares
PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
)
target_link_libraries(slice_hash_table_test
${_gRPC_ALLTARGETS_LIBRARIES}
grpc_test_util
grpc
gpr_test_util
gpr
)
endif (gRPC_BUILD_TESTS)
if (gRPC_BUILD_TESTS)
add_executable(slice_string_helpers_test
test/core/slice/slice_string_helpers_test.c
)

@ -1082,6 +1082,7 @@ server_chttp2_test: $(BINDIR)/$(CONFIG)/server_chttp2_test
server_fuzzer: $(BINDIR)/$(CONFIG)/server_fuzzer
server_test: $(BINDIR)/$(CONFIG)/server_test
slice_buffer_test: $(BINDIR)/$(CONFIG)/slice_buffer_test
slice_hash_table_test: $(BINDIR)/$(CONFIG)/slice_hash_table_test
slice_string_helpers_test: $(BINDIR)/$(CONFIG)/slice_string_helpers_test
slice_test: $(BINDIR)/$(CONFIG)/slice_test
sockaddr_resolver_test: $(BINDIR)/$(CONFIG)/sockaddr_resolver_test
@ -1452,6 +1453,7 @@ buildtests_c: privatelibs_c \
$(BINDIR)/$(CONFIG)/server_chttp2_test \
$(BINDIR)/$(CONFIG)/server_test \
$(BINDIR)/$(CONFIG)/slice_buffer_test \
$(BINDIR)/$(CONFIG)/slice_hash_table_test \
$(BINDIR)/$(CONFIG)/slice_string_helpers_test \
$(BINDIR)/$(CONFIG)/slice_test \
$(BINDIR)/$(CONFIG)/sockaddr_resolver_test \
@ -1924,6 +1926,8 @@ test_c: buildtests_c
$(Q) $(BINDIR)/$(CONFIG)/server_test || ( echo test server_test failed ; exit 1 )
$(E) "[RUN] Testing slice_buffer_test"
$(Q) $(BINDIR)/$(CONFIG)/slice_buffer_test || ( echo test slice_buffer_test failed ; exit 1 )
$(E) "[RUN] Testing slice_hash_table_test"
$(Q) $(BINDIR)/$(CONFIG)/slice_hash_table_test || ( echo test slice_hash_table_test failed ; exit 1 )
$(E) "[RUN] Testing slice_string_helpers_test"
$(Q) $(BINDIR)/$(CONFIG)/slice_string_helpers_test || ( echo test slice_string_helpers_test failed ; exit 1 )
$(E) "[RUN] Testing slice_test"
@ -12361,6 +12365,38 @@ endif
endif
SLICE_HASH_TABLE_TEST_SRC = \
test/core/slice/slice_hash_table_test.c \
SLICE_HASH_TABLE_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(SLICE_HASH_TABLE_TEST_SRC))))
ifeq ($(NO_SECURE),true)
# You can't build secure targets if you don't have OpenSSL.
$(BINDIR)/$(CONFIG)/slice_hash_table_test: openssl_dep_error
else
$(BINDIR)/$(CONFIG)/slice_hash_table_test: $(SLICE_HASH_TABLE_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
$(E) "[LD] Linking $@"
$(Q) mkdir -p `dirname $@`
$(Q) $(LD) $(LDFLAGS) $(SLICE_HASH_TABLE_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/slice_hash_table_test
endif
$(OBJDIR)/$(CONFIG)/test/core/slice/slice_hash_table_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
deps_slice_hash_table_test: $(SLICE_HASH_TABLE_TEST_OBJS:.o=.dep)
ifneq ($(NO_SECURE),true)
ifneq ($(NO_DEPS),true)
-include $(SLICE_HASH_TABLE_TEST_OBJS:.o=.dep)
endif
endif
SLICE_STRING_HELPERS_TEST_SRC = \
test/core/slice/slice_string_helpers_test.c \

@ -21,7 +21,7 @@ See [Performance dashboard](http://performance-dot-grpc-testing.appspot.com/expl
# Repository Structure & Status
This repository contains source code for gRPC libraries for multiple languages written on top of shared C core library [src/core] (src/core).
This repository contains source code for gRPC libraries for multiple languages written on top of shared C core library [src/core](src/core).
Libraries in different languages may be in different states of development. We are seeking contributions for all of these libraries.
@ -36,10 +36,9 @@ Libraries in different languages may be in different states of development. We a
| C# | [src/csharp](src/csharp) | 1.0 |
| Objective-C | [src/objective-c](src/objective-c) | 1.0 |
<small>
Java source code is in the [grpc-java](http://github.com/grpc/grpc-java) repository.
Go source code is in the [grpc-go](http://github.com/grpc/grpc-go) repository.
</small>
Java source code is in the [grpc-java](http://github.com/grpc/grpc-java)
repository. Go source code is in the
[grpc-go](http://github.com/grpc/grpc-go) repository.
See [MANIFEST.md](MANIFEST.md) for a listing of top-level items in the
repository.

@ -15,17 +15,17 @@ bind(
bind(
name = "protobuf",
actual = "@submodule_protobuf//:protobuf",
actual = "@com_google_protobuf//:protobuf",
)
bind(
name = "protobuf_clib",
actual = "@submodule_protobuf//:protoc_lib",
actual = "@com_google_protobuf//:protoc_lib",
)
bind(
name = "protocol_compiler",
actual = "@submodule_protobuf//:protoc",
actual = "@com_google_protobuf//:protoc",
)
bind(
@ -48,9 +48,8 @@ bind(
actual = "@com_github_gflags_gflags//:gflags",
)
new_local_repository(
local_repository(
name = "submodule_boringssl",
build_file = "third_party/boringssl-with-bazel/BUILD",
path = "third_party/boringssl-with-bazel",
)
@ -61,7 +60,7 @@ new_local_repository(
)
new_local_repository(
name = "submodule_protobuf",
name = "com_google_protobuf",
build_file = "third_party/protobuf/BUILD",
path = "third_party/protobuf",
)

@ -35,12 +35,12 @@ load(":cc_grpc_library.bzl", "cc_grpc_library")
proto_library(
name = "well_known_protos_list",
srcs = ["@submodule_protobuf//:well_known_protos"],
srcs = ["@com_google_protobuf//:well_known_protos"],
)
cc_grpc_library(
name = "well_known_protos",
srcs = "well_known_protos_list",
deps = [],
proto_only = True,
deps = [],
)

@ -14,7 +14,7 @@ def cc_grpc_library(name, srcs, deps, proto_only, well_known_protos, use_externa
the compiled code of any message that the services depend on.
well_known_protos: The target from protobuf library that exports well
known protos. Currently it will only work if the value is
"@submodule_protobuf//:well_known_protos"
"@com_google_protobuf//:well_known_protos"
use_external: When True the grpc deps are prefixed with //external. This
allows grpc to be used as a dependency in other bazel projects.
**kwargs: rest of arguments, e.g., compatible_with and visibility.

@ -35,10 +35,10 @@ def generate_cc_impl(ctx):
well_known_proto_files = []
if ctx.attr.well_known_protos:
f = ctx.attr.well_known_protos.files.to_list()[0].dirname
if f != "external/submodule_protobuf/src/google/protobuf":
print("Error: Only @submodule_protobuf//:well_known_protos is supported")
if f != "external/com_google_protobuf/src/google/protobuf":
print("Error: Only @com_google_protobuf//:well_known_protos is supported")
else:
# f points to "external/submodule_protobuf/src/google/protobuf"
# f points to "external/com_google_protobuf/src/google/protobuf"
# add -I argument to protoc so it knows where to look for the proto files.
arguments += ["-I{0}".format(f + "/../..")]
well_known_proto_files = [f for f in ctx.attr.well_known_protos.files]

@ -49,6 +49,22 @@ def grpc_cc_library(name, srcs = [], public_hdrs = [], hdrs = [], external_deps
]
)
def grpc_cc_libraries(name_list, additional_src_list = [], additional_dep_list = [], srcs = [], public_hdrs = [], hdrs = [], external_deps = [], deps = [], standalone = False, language="C++"):
names = len(name_list)
asl = additional_src_list + [[]]*(names - len(additional_src_list))
adl = additional_dep_list + [[]]*(names - len(additional_dep_list))
for i in range(names):
grpc_cc_library(
name = name_list[i],
srcs = srcs + asl[i],
hdrs = hdrs,
public_hdrs = public_hdrs,
deps = deps + adl[i],
external_deps = external_deps,
standalone = standalone,
language = language
)
def grpc_proto_plugin(name, srcs = [], deps = []):
native.cc_binary(
name = name,

@ -2812,6 +2812,16 @@ targets:
- grpc
- gpr_test_util
- gpr
- name: slice_hash_table_test
build: test
language: c
src:
- test/core/slice/slice_hash_table_test.c
deps:
- grpc_test_util
- grpc
- gpr_test_util
- gpr
- name: slice_string_helpers_test
build: test
language: c

@ -81,9 +81,8 @@ Procedure:
Client marks the request as cacheable by setting the cacheable flag in the
request context. Longer term this should be driven by the method option
specified in the proto file itself.
2. Client calls CacheableUnaryCall with `SimpleRequest` request again
immediately with the same payload as the previous request. Cacheable flag is
also set for this request's context.
2. Client calls CacheableUnaryCall again immediately with the same request and
configuration as the previous call.
Client asserts:
* Both calls were successful
@ -986,6 +985,7 @@ for the `SimpleRequest.response_type`. If the server does not support the
`response_type`, then it should fail the RPC with `INVALID_ARGUMENT`.
### CacheableUnaryCall
[CacheableUnaryCall]: #cacheableunarycall
Server gets the default SimpleRequest proto as the request. The content of the
request is ignored. It returns the SimpleResponse proto with the payload set

@ -13,12 +13,21 @@ The service config is a JSON string of the following form:
```
{
// Load balancing policy name.
// Supported values are 'round_robin' and 'grpclb'.
// Optional; if unset, the default behavior is pick the first available
// backend.
// Note that if the resolver returns only balancer addresses and no
// backend addresses, gRPC will always use the 'grpclb' policy,
// regardless of what this field is set to.
// Currently, the only selectable client-side policy provided with gRPC
// is 'round_robin', but third parties may add their own policies.
// This field is optional; if unset, the default behavior is to pick
// the first available backend.
// If the policy name is set via the client API, that value overrides
// the value specified here.
//
// Note that if the resolver returns at least one balancer address (as
// opposed to backend addresses), gRPC will use grpclb (see
// https://github.com/grpc/grpc/blob/master/doc/load-balancing.md),
// regardless of what LB policy is requested either here or via the
// client API. However, if the resolver returns at least one backend
// address in addition to the balancer address(es), the client may fall
// back to the requested policy if it is unable to reach any of the
// grpclb load balancers.
'loadBalancingPolicy': string,
// Per-method configuration. Optional.

@ -68,6 +68,7 @@ class ObjectiveCGrpcGenerator : public grpc::protobuf::compiler::CodeGenerator {
::grpc::string imports = ::grpc::string("#import \"") + file_name +
".pbobjc.h\"\n\n"
"#import <ProtoRPC/ProtoService.h>\n"
"#import <ProtoRPC/ProtoRPC.h>\n"
"#import <RxLibrary/GRXWriteable.h>\n"
"#import <RxLibrary/GRXWriter.h>\n";

@ -96,17 +96,10 @@ static void method_parameters_unref(method_parameters *method_params) {
}
}
static void *method_parameters_copy(void *value) {
return method_parameters_ref(value);
}
static void method_parameters_free(grpc_exec_ctx *exec_ctx, void *value) {
method_parameters_unref(value);
}
static const grpc_slice_hash_table_vtable method_parameters_vtable = {
method_parameters_free, method_parameters_copy};
static bool parse_wait_for_ready(grpc_json *field,
wait_for_ready_value *wait_for_ready) {
if (field->type != GRPC_JSON_TRUE && field->type != GRPC_JSON_FALSE) {
@ -407,26 +400,24 @@ static void on_resolver_result_changed_locked(grpc_exec_ctx *exec_ctx,
GPR_ASSERT(channel_arg->type == GRPC_ARG_STRING);
lb_policy_name = channel_arg->value.string;
}
// Special case: If all of the addresses are balancer addresses,
// assume that we should use the grpclb policy, regardless of what the
// resolver actually specified.
// Special case: If at least one balancer address is present, we use
// the grpclb policy, regardless of what the resolver actually specified.
channel_arg =
grpc_channel_args_find(chand->resolver_result, GRPC_ARG_LB_ADDRESSES);
if (channel_arg != NULL && channel_arg->type == GRPC_ARG_POINTER) {
grpc_lb_addresses *addresses = channel_arg->value.pointer.p;
bool found_backend_address = false;
bool found_balancer_address = false;
for (size_t i = 0; i < addresses->num_addresses; ++i) {
if (!addresses->addresses[i].is_balancer) {
found_backend_address = true;
if (addresses->addresses[i].is_balancer) {
found_balancer_address = true;
break;
}
}
if (!found_backend_address) {
if (found_balancer_address) {
if (lb_policy_name != NULL && strcmp(lb_policy_name, "grpclb") != 0) {
gpr_log(GPR_INFO,
"resolver requested LB policy %s but provided only balancer "
"addresses, no backend addresses -- forcing use of grpclb LB "
"policy",
"resolver requested LB policy %s but provided at least one "
"balancer address -- forcing use of grpclb LB policy",
lb_policy_name);
}
lb_policy_name = "grpclb";
@ -472,7 +463,7 @@ static void on_resolver_result_changed_locked(grpc_exec_ctx *exec_ctx,
grpc_uri_destroy(uri);
method_params_table = grpc_service_config_create_method_config_table(
exec_ctx, service_config, method_parameters_create_from_json,
&method_parameters_vtable);
method_parameters_free);
grpc_service_config_destroy(service_config);
}
}

@ -750,18 +750,11 @@ static void destroy_balancer_name(grpc_exec_ctx *exec_ctx,
gpr_free(balancer_name);
}
static void *copy_balancer_name(void *balancer_name) {
return gpr_strdup(balancer_name);
}
static grpc_slice_hash_table_entry targets_info_entry_create(
const char *address, const char *balancer_name) {
static const grpc_slice_hash_table_vtable vtable = {destroy_balancer_name,
copy_balancer_name};
grpc_slice_hash_table_entry entry;
entry.key = grpc_slice_from_copied_string(address);
entry.value = (void *)balancer_name;
entry.vtable = &vtable;
entry.value = gpr_strdup(balancer_name);
return entry;
}
@ -825,11 +818,8 @@ static char *get_lb_uri_target_addresses(grpc_exec_ctx *exec_ctx,
uri_path);
gpr_free(uri_path);
*targets_info =
grpc_slice_hash_table_create(num_grpclb_addrs, targets_info_entries);
for (size_t i = 0; i < num_grpclb_addrs; i++) {
grpc_slice_unref_internal(exec_ctx, targets_info_entries[i].key);
}
*targets_info = grpc_slice_hash_table_create(
num_grpclb_addrs, targets_info_entries, destroy_balancer_name);
gpr_free(targets_info_entries);
return target_uri_str;
@ -841,10 +831,10 @@ static grpc_lb_policy *glb_create(grpc_exec_ctx *exec_ctx,
/* Count the number of gRPC-LB addresses. There must be at least one.
* TODO(roth): For now, we ignore non-balancer addresses, but in the
* future, we may change the behavior such that we fall back to using
* the non-balancer addresses if we cannot reach any balancers. At that
* time, this should be changed to allow a list with no balancer addresses,
* since the resolver might fail to return a balancer address even when
* this is the right LB policy to use. */
* the non-balancer addresses if we cannot reach any balancers. In the
* fallback case, we should use the LB policy indicated by
* GRPC_ARG_LB_POLICY_NAME (although if that specifies grpclb or is
* unset, we should default to pick_first). */
const grpc_arg *arg =
grpc_channel_args_find(args->args, GRPC_ARG_LB_ADDRESSES);
if (arg == NULL || arg->type != GRPC_ARG_POINTER) {

@ -49,8 +49,6 @@
#include "src/core/lib/support/string.h"
#include "src/core/lib/transport/static_metadata.h"
int grpc_compression_trace = 0;
#define INITIAL_METADATA_UNSEEN 0
#define HAS_COMPRESSION_ALGORITHM 2
#define NO_COMPRESSION_ALGORITHM 4

@ -50,19 +50,10 @@ typedef struct message_size_limits {
int max_recv_size;
} message_size_limits;
static void* message_size_limits_copy(void* value) {
void* new_value = gpr_malloc(sizeof(message_size_limits));
memcpy(new_value, value, sizeof(message_size_limits));
return new_value;
}
static void message_size_limits_free(grpc_exec_ctx* exec_ctx, void* value) {
gpr_free(value);
}
static const grpc_slice_hash_table_vtable message_size_limits_vtable = {
message_size_limits_free, message_size_limits_copy};
static void* message_size_limits_create_from_json(const grpc_json* json) {
int max_request_message_bytes = -1;
int max_response_message_bytes = -1;
@ -257,7 +248,7 @@ static grpc_error* init_channel_elem(grpc_exec_ctx* exec_ctx,
chand->method_limit_table =
grpc_service_config_create_method_config_table(
exec_ctx, service_config, message_size_limits_create_from_json,
&message_size_limits_vtable);
message_size_limits_free);
grpc_service_config_destroy(service_config);
}
}

@ -80,7 +80,7 @@ static void on_handshake_done(grpc_exec_ctx *exec_ctx, void *arg,
gpr_mu_lock(&connection_state->server_state->mu);
if (error != GRPC_ERROR_NONE || connection_state->server_state->shutdown) {
const char *error_str = grpc_error_string(error);
gpr_log(GPR_ERROR, "Handshaking failed: %s", error_str);
gpr_log(GPR_DEBUG, "Handshaking failed: %s", error_str);
if (error == GRPC_ERROR_NONE && args->endpoint != NULL) {
// We were shut down after handshaking completed successfully, so

@ -42,56 +42,47 @@
struct grpc_slice_hash_table {
gpr_refcount refs;
void (*destroy_value)(grpc_exec_ctx* exec_ctx, void* value);
size_t size;
size_t max_num_probes;
grpc_slice_hash_table_entry* entries;
};
static bool is_empty(grpc_slice_hash_table_entry* entry) {
return entry->vtable == NULL;
return entry->value == NULL;
}
// Helper function for insert and get operations that performs quadratic
// probing (https://en.wikipedia.org/wiki/Quadratic_probing).
static size_t grpc_slice_hash_table_find_index(
const grpc_slice_hash_table* table, const grpc_slice key, bool find_empty) {
size_t hash = grpc_slice_hash(key);
for (size_t i = 0; i < table->size; ++i) {
const size_t idx = (hash + i * i) % table->size;
static void grpc_slice_hash_table_add(grpc_slice_hash_table* table,
grpc_slice key, void* value) {
GPR_ASSERT(value != NULL);
const size_t hash = grpc_slice_hash(key);
for (size_t offset = 0; offset < table->size; ++offset) {
const size_t idx = (hash + offset) % table->size;
if (is_empty(&table->entries[idx])) {
return find_empty ? idx : table->size;
}
if (grpc_slice_eq(table->entries[idx].key, key)) {
return idx;
table->entries[idx].key = key;
table->entries[idx].value = value;
// Keep track of the maximum number of probes needed, since this
// provides an upper bound for lookups.
if (offset > table->max_num_probes) table->max_num_probes = offset;
return;
}
}
return table->size; // Not found.
}
static void grpc_slice_hash_table_add(
grpc_slice_hash_table* table, grpc_slice key, void* value,
const grpc_slice_hash_table_vtable* vtable) {
GPR_ASSERT(value != NULL);
const size_t idx =
grpc_slice_hash_table_find_index(table, key, true /* find_empty */);
GPR_ASSERT(idx != table->size); // Table should never be full.
grpc_slice_hash_table_entry* entry = &table->entries[idx];
entry->key = grpc_slice_ref_internal(key);
entry->value = vtable->copy_value(value);
entry->vtable = vtable;
GPR_ASSERT(false); // Table should never be full.
}
grpc_slice_hash_table* grpc_slice_hash_table_create(
size_t num_entries, grpc_slice_hash_table_entry* entries) {
size_t num_entries, grpc_slice_hash_table_entry* entries,
void (*destroy_value)(grpc_exec_ctx* exec_ctx, void* value)) {
grpc_slice_hash_table* table = gpr_zalloc(sizeof(*table));
gpr_ref_init(&table->refs, 1);
// Quadratic probing gets best performance when the table is no more
// than half full.
table->destroy_value = destroy_value;
// Keep load factor low to improve performance of lookups.
table->size = num_entries * 2;
const size_t entry_size = sizeof(grpc_slice_hash_table_entry) * table->size;
table->entries = gpr_zalloc(entry_size);
for (size_t i = 0; i < num_entries; ++i) {
grpc_slice_hash_table_entry* entry = &entries[i];
grpc_slice_hash_table_add(table, entry->key, entry->value, entry->vtable);
grpc_slice_hash_table_add(table, entry->key, entry->value);
}
return table;
}
@ -108,7 +99,7 @@ void grpc_slice_hash_table_unref(grpc_exec_ctx* exec_ctx,
grpc_slice_hash_table_entry* entry = &table->entries[i];
if (!is_empty(entry)) {
grpc_slice_unref_internal(exec_ctx, entry->key);
entry->vtable->destroy_value(exec_ctx, entry->value);
table->destroy_value(exec_ctx, entry->value);
}
}
gpr_free(table->entries);
@ -118,8 +109,15 @@ void grpc_slice_hash_table_unref(grpc_exec_ctx* exec_ctx,
void* grpc_slice_hash_table_get(const grpc_slice_hash_table* table,
const grpc_slice key) {
const size_t idx =
grpc_slice_hash_table_find_index(table, key, false /* find_empty */);
if (idx == table->size) return NULL; // Not found.
return table->entries[idx].value;
const size_t hash = grpc_slice_hash(key);
// We cap the number of probes at the max number recorded when
// populating the table.
for (size_t offset = 0; offset <= table->max_num_probes; ++offset) {
const size_t idx = (hash + offset) % table->size;
if (is_empty(&table->entries[idx])) break;
if (grpc_slice_eq(table->entries[idx].key, key)) {
return table->entries[idx].value;
}
}
return NULL; // Not found.
}

@ -37,33 +37,28 @@
/** Hash table implementation.
*
* This implementation uses open addressing
* (https://en.wikipedia.org/wiki/Open_addressing) with quadratic
* probing (https://en.wikipedia.org/wiki/Quadratic_probing).
* (https://en.wikipedia.org/wiki/Open_addressing) with linear
* probing (https://en.wikipedia.org/wiki/Linear_probing).
*
* The keys are \a grpc_slice objects. The values are arbitrary pointers
* with a common vtable.
* with a common destroy function.
*
* Hash tables are intentionally immutable, to avoid the need for locking.
*/
typedef struct grpc_slice_hash_table grpc_slice_hash_table;
typedef struct grpc_slice_hash_table_vtable {
void (*destroy_value)(grpc_exec_ctx *exec_ctx, void *value);
void *(*copy_value)(void *value);
} grpc_slice_hash_table_vtable;
typedef struct grpc_slice_hash_table_entry {
grpc_slice key;
void *value; /* Must not be NULL. */
const grpc_slice_hash_table_vtable *vtable;
} grpc_slice_hash_table_entry;
/** Creates a new hash table of containing \a entries, which is an array
of length \a num_entries.
Creates its own copy of all keys and values from \a entries. */
of length \a num_entries. Takes ownership of all keys and values in
\a entries. Values will be cleaned up via \a destroy_value(). */
grpc_slice_hash_table *grpc_slice_hash_table_create(
size_t num_entries, grpc_slice_hash_table_entry *entries);
size_t num_entries, grpc_slice_hash_table_entry *entries,
void (*destroy_value)(grpc_exec_ctx *exec_ctx, void *value));
grpc_slice_hash_table *grpc_slice_hash_table_ref(grpc_slice_hash_table *table);
void grpc_slice_hash_table_unref(grpc_exec_ctx *exec_ctx,

@ -76,13 +76,13 @@ struct gpr_stack_lockfree {
gpr_stack_lockfree *gpr_stack_lockfree_create(size_t entries) {
gpr_stack_lockfree *stack;
stack = gpr_malloc(sizeof(*stack));
stack = (gpr_stack_lockfree *)gpr_malloc(sizeof(*stack));
/* Since we only allocate 16 bits to represent an entry number,
* make sure that we are within the desired range */
/* Reserve the highest entry number as a dummy */
GPR_ASSERT(entries < INVALID_ENTRY_INDEX);
stack->entries = gpr_malloc_aligned(entries * sizeof(stack->entries[0]),
ENTRY_ALIGNMENT_BITS);
stack->entries = (lockfree_node *)gpr_malloc_aligned(
entries * sizeof(stack->entries[0]), ENTRY_ALIGNMENT_BITS);
/* Clear out all entries */
memset(stack->entries, 0, entries * sizeof(stack->entries[0]));
memset(&stack->head, 0, sizeof(stack->head));

@ -42,6 +42,7 @@
#ifdef __linux__
#include <sys/syscall.h>
#endif
#include <grpc/support/atm.h>
#include <grpc/support/log.h>
#include <grpc/support/time.h>
#include "src/core/lib/support/block_annotate.h"
@ -144,7 +145,14 @@ static gpr_timespec now_impl(gpr_clock_type clock) {
gpr_timespec (*gpr_now_impl)(gpr_clock_type clock_type) = now_impl;
#ifdef GPR_LOW_LEVEL_COUNTERS
gpr_atm gpr_now_call_count;
#endif
gpr_timespec gpr_now(gpr_clock_type clock_type) {
#ifdef GPR_LOW_LEVEL_COUNTERS
__atomic_fetch_add(&gpr_now_call_count, 1, __ATOMIC_RELAXED);
#endif
return gpr_now_impl(clock_type);
}

@ -50,34 +50,34 @@
FILE *gpr_tmpfile(const char *prefix, char **tmp_filename) {
FILE *result = NULL;
char *template;
char *filename_template;
int fd;
if (tmp_filename != NULL) *tmp_filename = NULL;
gpr_asprintf(&template, "/tmp/%s_XXXXXX", prefix);
GPR_ASSERT(template != NULL);
gpr_asprintf(&filename_template, "/tmp/%s_XXXXXX", prefix);
GPR_ASSERT(filename_template != NULL);
fd = mkstemp(template);
fd = mkstemp(filename_template);
if (fd == -1) {
gpr_log(GPR_ERROR, "mkstemp failed for template %s with error %s.",
template, strerror(errno));
gpr_log(GPR_ERROR, "mkstemp failed for filename_template %s with error %s.",
filename_template, strerror(errno));
goto end;
}
result = fdopen(fd, "w+");
if (result == NULL) {
gpr_log(GPR_ERROR, "Could not open file %s from fd %d (error = %s).",
template, fd, strerror(errno));
unlink(template);
filename_template, fd, strerror(errno));
unlink(filename_template);
close(fd);
goto end;
}
end:
if (result != NULL && tmp_filename != NULL) {
*tmp_filename = template;
*tmp_filename = filename_template;
} else {
gpr_free(template);
gpr_free(filename_template);
}
return result;
}

@ -245,6 +245,7 @@ struct grpc_call {
};
int grpc_call_error_trace = 0;
int grpc_compression_trace = 0;
#define CALL_STACK_FROM_CALL(call) ((grpc_call_stack *)((call) + 1))
#define CALL_FROM_CALL_STACK(call_stack) (((grpc_call *)(call_stack)) - 1)

@ -1033,8 +1033,6 @@ grpc_server *grpc_server_create(const grpc_channel_args *args, void *reserved) {
grpc_server *server = gpr_zalloc(sizeof(grpc_server));
GPR_ASSERT(grpc_is_initialized() && "call grpc_init()");
gpr_mu_init(&server->mu_global);
gpr_mu_init(&server->mu_call);
gpr_cv_init(&server->starting_cv);

@ -162,7 +162,6 @@ static char* parse_json_method_name(grpc_json* json) {
static bool parse_json_method_config(
grpc_exec_ctx* exec_ctx, grpc_json* json,
void* (*create_value)(const grpc_json* method_config_json),
const grpc_slice_hash_table_vtable* vtable,
grpc_slice_hash_table_entry* entries, size_t* idx) {
// Construct value.
void* method_config = create_value(json);
@ -185,13 +184,11 @@ static bool parse_json_method_config(
// Add entry for each path.
for (size_t i = 0; i < paths.count; ++i) {
entries[*idx].key = grpc_slice_from_copied_string(paths.strs[i]);
entries[*idx].value = vtable->copy_value(method_config);
entries[*idx].vtable = vtable;
entries[*idx].value = method_config;
++*idx;
}
success = true;
done:
vtable->destroy_value(exec_ctx, method_config);
gpr_strvec_destroy(&paths);
return success;
}
@ -199,7 +196,7 @@ done:
grpc_slice_hash_table* grpc_service_config_create_method_config_table(
grpc_exec_ctx* exec_ctx, const grpc_service_config* service_config,
void* (*create_value)(const grpc_json* method_config_json),
const grpc_slice_hash_table_vtable* vtable) {
void (*destroy_value)(grpc_exec_ctx* exec_ctx, void* value)) {
const grpc_json* json = service_config->json_tree;
// Traverse parsed JSON tree.
if (json->type != GRPC_JSON_OBJECT || json->key != NULL) return NULL;
@ -220,8 +217,8 @@ grpc_slice_hash_table* grpc_service_config_create_method_config_table(
size_t idx = 0;
for (grpc_json* method = field->child; method != NULL;
method = method->next) {
if (!parse_json_method_config(exec_ctx, method, create_value, vtable,
entries, &idx)) {
if (!parse_json_method_config(exec_ctx, method, create_value, entries,
&idx)) {
return NULL;
}
}
@ -231,12 +228,8 @@ grpc_slice_hash_table* grpc_service_config_create_method_config_table(
// Instantiate method config table.
grpc_slice_hash_table* method_config_table = NULL;
if (entries != NULL) {
method_config_table = grpc_slice_hash_table_create(num_entries, entries);
// Clean up.
for (size_t i = 0; i < num_entries; ++i) {
grpc_slice_unref_internal(exec_ctx, entries[i].key);
vtable->destroy_value(exec_ctx, entries[i].value);
}
method_config_table =
grpc_slice_hash_table_create(num_entries, entries, destroy_value);
gpr_free(entries);
}
return method_config_table;

@ -57,12 +57,12 @@ const char* grpc_service_config_get_lb_policy_name(
/// Creates a method config table based on the data in \a json.
/// The table's keys are request paths. The table's value type is
/// returned by \a create_value(), based on data parsed from the JSON tree.
/// \a vtable provides methods used to manage the values.
/// \a destroy_value is used to clean up values.
/// Returns NULL on error.
grpc_slice_hash_table* grpc_service_config_create_method_config_table(
grpc_exec_ctx* exec_ctx, const grpc_service_config* service_config,
void* (*create_value)(const grpc_json* method_config_json),
const grpc_slice_hash_table_vtable* vtable);
void (*destroy_value)(grpc_exec_ctx* exec_ctx, void* value));
/// A helper function for looking up values in the table returned by
/// \a grpc_service_config_create_method_config_table().

@ -253,6 +253,13 @@ extern id const kGRPCTrailersKey;
*/
+ (void)setCallSafety:(GRPCCallSafety)callSafety host:(NSString *)host path:(NSString *)path;
/**
* Set the dispatch queue to be used for callbacks.
*
* This configuration is only effective before the call starts.
*/
- (void)setResponseDispatchQueue:(dispatch_queue_t)queue;
// TODO(jcanizales): Let specify a deadline. As a category of GRXWriter?
@end

@ -113,6 +113,10 @@ static NSMutableDictionary *callFlags;
// the SendClose op is added.
BOOL _unaryCall;
NSMutableArray *_unaryOpBatch;
// The dispatch queue to be used for enqueuing responses to user. Defaulted to the main dispatch
// queue
dispatch_queue_t _responseQueue;
}
@synthesize state = _state;
@ -175,10 +179,19 @@ static NSMutableDictionary *callFlags;
_unaryCall = YES;
_unaryOpBatch = [NSMutableArray arrayWithCapacity:kMaxClientBatch];
}
_responseQueue = dispatch_get_main_queue();
}
return self;
}
- (void)setResponseDispatchQueue:(dispatch_queue_t)queue {
if (_state != GRXWriterStateNotStarted) {
return;
}
_responseQueue = queue;
}
#pragma mark Finish
- (void)finishWithError:(NSError *)errorOrNil {
@ -424,7 +437,8 @@ static NSMutableDictionary *callFlags;
// that the life of the instance is determined by this retain cycle.
_retainSelf = self;
_responseWriteable = [[GRXConcurrentWriteable alloc] initWithWriteable:writeable];
_responseWriteable = [[GRXConcurrentWriteable alloc] initWithWriteable:writeable
dispatchQueue:_responseQueue];
_wrappedCall = [[GRPCWrappedCall alloc] initWithHost:_host path:_path];
NSAssert(_wrappedCall, @"Error allocating RPC objects. Low memory?");

@ -53,7 +53,9 @@
* The GRXWriteable instance is retained until writesFinishedWithError: is sent to it, and released
* after that.
*/
- (instancetype)initWithWriteable:(id<GRXWriteable>)writeable NS_DESIGNATED_INITIALIZER;
- (instancetype)initWithWriteable:(id<GRXWriteable>)writeable
dispatchQueue:(dispatch_queue_t)queue NS_DESIGNATED_INITIALIZER;
- (instancetype)initWithWriteable:(id<GRXWriteable>)writeable;
/**
* Enqueues writeValue: to be sent to the writeable in the main thread.

@ -51,14 +51,20 @@
}
// Designated initializer
- (instancetype)initWithWriteable:(id<GRXWriteable>)writeable {
- (instancetype)initWithWriteable:(id<GRXWriteable>)writeable
dispatchQueue:(dispatch_queue_t)queue {
if (self = [super init]) {
_writeableQueue = dispatch_get_main_queue();
_writeableQueue = queue;
_writeable = writeable;
}
return self;
}
- (instancetype)initWithWriteable:(id<GRXWriteable>)writeable {
return [self initWithWriteable:writeable
dispatchQueue:dispatch_get_main_queue()];
}
- (void)enqueueValue:(id)value completionHandler:(void (^)())handler {
dispatch_async(_writeableQueue, ^{
// We're racing a possible cancellation performed by another thread. To turn all already-

@ -353,4 +353,59 @@ static GRPCProtoMethod *kUnaryCallMethod;
[self waitForExpectationsWithTimeout:TEST_TIMEOUT handler:nil];
}
- (void)testAlternateDispatchQueue {
const int32_t kPayloadSize = 100;
RMTSimpleRequest *request = [RMTSimpleRequest message];
request.responseSize = kPayloadSize;
__weak XCTestExpectation *expectation1 = [self expectationWithDescription:@"AlternateDispatchQueue1"];
// Use default (main) dispatch queue
NSString *main_queue_label = [NSString stringWithUTF8String:dispatch_queue_get_label(dispatch_get_main_queue())];
GRXWriter *requestsWriter1 = [GRXWriter writerWithValue:[request data]];
GRPCCall *call1 = [[GRPCCall alloc] initWithHost:kHostAddress
path:kUnaryCallMethod.HTTPPath
requestsWriter:requestsWriter1];
id<GRXWriteable> responsesWriteable1 = [[GRXWriteable alloc] initWithValueHandler:^(NSData *value) {
NSString *label = [NSString stringWithUTF8String:dispatch_queue_get_label(DISPATCH_CURRENT_QUEUE_LABEL)];
XCTAssert([label isEqualToString:main_queue_label]);
[expectation1 fulfill];
} completionHandler:^(NSError *errorOrNil) {
}];
[call1 startWithWriteable:responsesWriteable1];
[self waitForExpectationsWithTimeout:TEST_TIMEOUT handler:nil];
// Use a custom queue
__weak XCTestExpectation *expectation2 = [self expectationWithDescription:@"AlternateDispatchQueue2"];
NSString *queue_label = @"test.queue1";
dispatch_queue_t queue = dispatch_queue_create([queue_label UTF8String], DISPATCH_QUEUE_SERIAL);
GRXWriter *requestsWriter2 = [GRXWriter writerWithValue:[request data]];
GRPCCall *call2 = [[GRPCCall alloc] initWithHost:kHostAddress
path:kUnaryCallMethod.HTTPPath
requestsWriter:requestsWriter2];
[call2 setResponseDispatchQueue:queue];
id<GRXWriteable> responsesWriteable2 = [[GRXWriteable alloc] initWithValueHandler:^(NSData *value) {
NSString *label = [NSString stringWithUTF8String:dispatch_queue_get_label(DISPATCH_CURRENT_QUEUE_LABEL)];
XCTAssert([label isEqualToString:queue_label]);
[expectation2 fulfill];
} completionHandler:^(NSError *errorOrNil) {
}];
[call2 startWithWriteable:responsesWriteable2];
[self waitForExpectationsWithTimeout:TEST_TIMEOUT handler:nil];
}
@end

@ -37,7 +37,5 @@ grpc_proto_library(
name = "status_proto",
srcs = ["status.proto"],
has_services = False,
well_known_protos = "@submodule_protobuf//:well_known_protos",
well_known_protos = "@com_google_protobuf//:well_known_protos",
)

@ -96,8 +96,6 @@ def _rst_during_data(stub):
def _rst_after_data(stub):
resp_future = stub.UnaryCall.future(_SIMPLE_REQUEST)
_validate_payload_type_and_length(
next(resp_future), messages_pb2.COMPRESSABLE, _RESPONSE_SIZE)
_validate_status_code_and_details(resp_future, grpc.StatusCode.INTERNAL,
"Received RST_STREAM with error code 0")

@ -59,6 +59,7 @@
#include "src/core/lib/iomgr/sockaddr_utils.h"
#include "src/core/lib/iomgr/tcp_client.h"
#include "src/core/lib/iomgr/tcp_server.h"
#include "src/core/lib/iomgr/timer.h"
#include "src/core/lib/slice/slice_internal.h"
#include "test/core/util/port.h"
@ -69,7 +70,7 @@ struct grpc_end2end_http_proxy {
grpc_channel_args* channel_args;
gpr_mu* mu;
grpc_pollset* pollset;
gpr_atm shutdown;
gpr_refcount users;
};
//
@ -77,6 +78,8 @@ struct grpc_end2end_http_proxy {
//
typedef struct proxy_connection {
grpc_end2end_http_proxy* proxy;
grpc_endpoint* client_endpoint;
grpc_endpoint* server_endpoint;
@ -103,13 +106,20 @@ typedef struct proxy_connection {
grpc_http_request http_request;
} proxy_connection;
static void proxy_connection_ref(proxy_connection* conn, const char* reason) {
gpr_ref(&conn->refcount);
}
// Helper function to destroy the proxy connection.
static void proxy_connection_unref(grpc_exec_ctx* exec_ctx,
proxy_connection* conn) {
proxy_connection* conn, const char* reason) {
if (gpr_unref(&conn->refcount)) {
gpr_log(GPR_DEBUG, "endpoints: %p %p", conn->client_endpoint,
conn->server_endpoint);
grpc_endpoint_destroy(exec_ctx, conn->client_endpoint);
if (conn->server_endpoint != NULL)
if (conn->server_endpoint != NULL) {
grpc_endpoint_destroy(exec_ctx, conn->server_endpoint);
}
grpc_pollset_set_destroy(exec_ctx, conn->pollset_set);
grpc_slice_buffer_destroy_internal(exec_ctx, &conn->client_read_buffer);
grpc_slice_buffer_destroy_internal(exec_ctx,
@ -121,6 +131,7 @@ static void proxy_connection_unref(grpc_exec_ctx* exec_ctx,
grpc_slice_buffer_destroy_internal(exec_ctx, &conn->server_write_buffer);
grpc_http_parser_destroy(&conn->http_parser);
grpc_http_request_destroy(&conn->http_request);
gpr_unref(&conn->proxy->users);
gpr_free(conn);
}
}
@ -139,7 +150,7 @@ static void proxy_connection_failed(grpc_exec_ctx* exec_ctx,
grpc_endpoint_shutdown(exec_ctx, conn->server_endpoint,
GRPC_ERROR_REF(error));
}
proxy_connection_unref(exec_ctx, conn);
proxy_connection_unref(exec_ctx, conn, "conn_failed");
}
// Callback for writing proxy data to the client.
@ -163,7 +174,7 @@ static void on_client_write_done(grpc_exec_ctx* exec_ctx, void* arg,
&conn->on_client_write_done);
} else {
// No more writes. Unref the connection.
proxy_connection_unref(exec_ctx, conn);
proxy_connection_unref(exec_ctx, conn, "write_done");
}
}
@ -188,7 +199,7 @@ static void on_server_write_done(grpc_exec_ctx* exec_ctx, void* arg,
&conn->on_server_write_done);
} else {
// No more writes. Unref the connection.
proxy_connection_unref(exec_ctx, conn);
proxy_connection_unref(exec_ctx, conn, "server_write");
}
}
@ -214,7 +225,7 @@ static void on_client_read_done(grpc_exec_ctx* exec_ctx, void* arg,
} else {
grpc_slice_buffer_move_into(&conn->client_read_buffer,
&conn->server_write_buffer);
gpr_ref(&conn->refcount);
proxy_connection_ref(conn, "client_read");
grpc_endpoint_write(exec_ctx, conn->server_endpoint,
&conn->server_write_buffer,
&conn->on_server_write_done);
@ -246,7 +257,7 @@ static void on_server_read_done(grpc_exec_ctx* exec_ctx, void* arg,
} else {
grpc_slice_buffer_move_into(&conn->server_read_buffer,
&conn->client_write_buffer);
gpr_ref(&conn->refcount);
proxy_connection_ref(conn, "server_read");
grpc_endpoint_write(exec_ctx, conn->client_endpoint,
&conn->client_write_buffer,
&conn->on_client_write_done);
@ -270,7 +281,9 @@ static void on_write_response_done(grpc_exec_ctx* exec_ctx, void* arg,
// Start reading from both client and server. One of the read
// requests inherits our ref to conn, but we need to take a new ref
// for the other one.
gpr_ref(&conn->refcount);
proxy_connection_ref(conn, "client_read");
proxy_connection_ref(conn, "server_read");
proxy_connection_unref(exec_ctx, conn, "write_response");
grpc_endpoint_read(exec_ctx, conn->client_endpoint, &conn->client_read_buffer,
&conn->on_client_read_done);
grpc_endpoint_read(exec_ctx, conn->server_endpoint, &conn->server_read_buffer,
@ -312,6 +325,8 @@ static void on_server_connect_done(grpc_exec_ctx* exec_ctx, void* arg,
static void on_read_request_done(grpc_exec_ctx* exec_ctx, void* arg,
grpc_error* error) {
proxy_connection* conn = arg;
gpr_log(GPR_DEBUG, "on_read_request_done: %p %s", conn,
grpc_error_string(error));
if (error != GRPC_ERROR_NONE) {
proxy_connection_failed(exec_ctx, conn, true /* is_client */,
"HTTP proxy read request", error);
@ -376,12 +391,14 @@ static void on_accept(grpc_exec_ctx* exec_ctx, void* arg,
gpr_free(acceptor);
grpc_end2end_http_proxy* proxy = arg;
// Instantiate proxy_connection.
proxy_connection* conn = gpr_malloc(sizeof(*conn));
memset(conn, 0, sizeof(*conn));
proxy_connection* conn = gpr_zalloc(sizeof(*conn));
gpr_ref(&proxy->users);
conn->client_endpoint = endpoint;
conn->proxy = proxy;
gpr_ref_init(&conn->refcount, 1);
conn->pollset_set = grpc_pollset_set_create();
grpc_pollset_set_add_pollset(exec_ctx, conn->pollset_set, proxy->pollset);
grpc_endpoint_add_to_pollset_set(exec_ctx, endpoint, conn->pollset_set);
grpc_closure_init(&conn->on_read_request_done, on_read_request_done, conn,
grpc_schedule_on_exec_ctx);
grpc_closure_init(&conn->on_server_connect_done, on_server_connect_done, conn,
@ -416,6 +433,7 @@ static void thread_main(void* arg) {
grpc_end2end_http_proxy* proxy = arg;
grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
do {
gpr_ref(&proxy->users);
const gpr_timespec now = gpr_now(GPR_CLOCK_MONOTONIC);
const gpr_timespec deadline =
gpr_time_add(now, gpr_time_from_seconds(1, GPR_TIMESPAN));
@ -426,7 +444,7 @@ static void thread_main(void* arg) {
grpc_pollset_work(&exec_ctx, proxy->pollset, &worker, now, deadline));
gpr_mu_unlock(proxy->mu);
grpc_exec_ctx_flush(&exec_ctx);
} while (!gpr_atm_acq_load(&proxy->shutdown));
} while (!gpr_unref(&proxy->users));
grpc_exec_ctx_finish(&exec_ctx);
}
@ -434,6 +452,7 @@ grpc_end2end_http_proxy* grpc_end2end_http_proxy_create(void) {
grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
grpc_end2end_http_proxy* proxy = gpr_malloc(sizeof(*proxy));
memset(proxy, 0, sizeof(*proxy));
gpr_ref_init(&proxy->users, 1);
// Construct proxy address.
const int proxy_port = grpc_pick_unused_port_or_die();
gpr_join_host_port(&proxy->proxy_name, "localhost", proxy_port);
@ -474,17 +493,16 @@ static void destroy_pollset(grpc_exec_ctx* exec_ctx, void* arg,
}
void grpc_end2end_http_proxy_destroy(grpc_end2end_http_proxy* proxy) {
gpr_atm_rel_store(&proxy->shutdown, 1); // Signal proxy thread to shutdown.
gpr_unref(&proxy->users); // Signal proxy thread to shutdown.
grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
gpr_thd_join(proxy->thd);
grpc_tcp_server_shutdown_listeners(&exec_ctx, proxy->server);
grpc_tcp_server_unref(&exec_ctx, proxy->server);
gpr_free(proxy->proxy_name);
grpc_channel_args_destroy(&exec_ctx, proxy->channel_args);
grpc_closure destroyed;
grpc_closure_init(&destroyed, destroy_pollset, proxy->pollset,
grpc_schedule_on_exec_ctx);
grpc_pollset_shutdown(&exec_ctx, proxy->pollset, &destroyed);
grpc_pollset_shutdown(&exec_ctx, proxy->pollset,
grpc_closure_create(destroy_pollset, proxy->pollset,
grpc_schedule_on_exec_ctx));
gpr_free(proxy);
grpc_exec_ctx_finish(&exec_ctx);
}

@ -49,11 +49,12 @@ static void *tag(intptr_t t) { return (void *)t; }
static grpc_end2end_test_fixture begin_test(grpc_end2end_test_config config,
const char *test_name,
cancellation_mode mode,
size_t test_ops,
grpc_channel_args *client_args,
grpc_channel_args *server_args) {
grpc_end2end_test_fixture f;
gpr_log(GPR_INFO, "Running test: %s/%s/%s", test_name, config.name,
mode.name);
gpr_log(GPR_INFO, "Running test: %s/%s/%s [%" PRIdPTR " ops]", test_name,
config.name, mode.name, test_ops);
f = config.create_fixture(client_args, server_args);
config.init_server(&f, server_args);
config.init_client(&f, client_args);
@ -108,8 +109,8 @@ static void test_cancel_after_invoke(grpc_end2end_test_config config,
grpc_op ops[6];
grpc_op *op;
grpc_call *c;
grpc_end2end_test_fixture f =
begin_test(config, "test_cancel_after_invoke", mode, NULL, NULL);
grpc_end2end_test_fixture f = begin_test(config, "test_cancel_after_invoke",
mode, test_ops, NULL, NULL);
cq_verifier *cqv = cq_verifier_create(f.cq);
grpc_metadata_array initial_metadata_recv;
grpc_metadata_array trailing_metadata_recv;

@ -47,12 +47,33 @@ cc_test(
)
cc_test(
name = "slice_buffer_test",
name = "slice_test",
srcs = ["slice_test.c"],
deps = ["//:grpc", "//test/core/util:grpc_test_util", "//:gpr", "//test/core/util:gpr_test_util"],
copts = ['-std=c99']
)
cc_test(
name = "slice_string_helpers_test",
srcs = ["slice_string_helpers_test.c"],
deps = ["//:grpc", "//test/core/util:grpc_test_util", "//:gpr", "//test/core/util:gpr_test_util"],
copts = ['-std=c99']
)
cc_test(
name = "slice_buffer_test",
srcs = ["slice_buffer_test.c"],
deps = ["//:grpc", "//test/core/util:grpc_test_util", "//:gpr", "//test/core/util:gpr_test_util"],
copts = ['-std=c99']
)
cc_test(
name = "slice_hash_table_test",
srcs = ["slice_hash_table_test.c"],
deps = ["//:grpc", "//test/core/util:grpc_test_util", "//:gpr", "//test/core/util:gpr_test_util"],
copts = ['-std=c99']
)
cc_test(
name = "b64_test",
srcs = ["b64_test.c"],

@ -0,0 +1,138 @@
/*
*
* Copyright 2017, 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/slice/slice_hash_table.h"
#include <string.h>
#include <grpc/support/alloc.h>
#include <grpc/support/log.h>
#include <grpc/support/string_util.h>
#include "src/core/lib/slice/slice_internal.h"
#include "test/core/util/test_config.h"
typedef struct {
char* key;
char* value;
} test_entry;
static void populate_entries(const test_entry* input, size_t num_entries,
grpc_slice_hash_table_entry* output) {
for (size_t i = 0; i < num_entries; ++i) {
output[i].key = grpc_slice_from_copied_string(input[i].key);
output[i].value = gpr_strdup(input[i].value);
}
}
static void check_values(const test_entry* input, size_t num_entries,
grpc_slice_hash_table* table) {
for (size_t i = 0; i < num_entries; ++i) {
grpc_slice key = grpc_slice_from_static_string(input[i].key);
char* actual = grpc_slice_hash_table_get(table, key);
GPR_ASSERT(actual != NULL);
GPR_ASSERT(strcmp(actual, input[i].value) == 0);
grpc_slice_unref(key);
}
}
static void check_non_existent_value(const char* key_string,
grpc_slice_hash_table* table) {
grpc_slice key = grpc_slice_from_static_string(key_string);
GPR_ASSERT(grpc_slice_hash_table_get(table, key) == NULL);
grpc_slice_unref(key);
}
static void destroy_string(grpc_exec_ctx* exec_ctx, void* value) {
gpr_free(value);
}
static void test_slice_hash_table() {
const test_entry test_entries[] = {
{"key_0", "value_0"}, {"key_1", "value_1"}, {"key_2", "value_2"},
{"key_3", "value_3"}, {"key_4", "value_4"}, {"key_5", "value_5"},
{"key_6", "value_6"}, {"key_7", "value_7"}, {"key_8", "value_8"},
{"key_9", "value_9"}, {"key_10", "value_10"}, {"key_11", "value_11"},
{"key_12", "value_12"}, {"key_13", "value_13"}, {"key_14", "value_14"},
{"key_15", "value_15"}, {"key_16", "value_16"}, {"key_17", "value_17"},
{"key_18", "value_18"}, {"key_19", "value_19"}, {"key_20", "value_20"},
{"key_21", "value_21"}, {"key_22", "value_22"}, {"key_23", "value_23"},
{"key_24", "value_24"}, {"key_25", "value_25"}, {"key_26", "value_26"},
{"key_27", "value_27"}, {"key_28", "value_28"}, {"key_29", "value_29"},
{"key_30", "value_30"}, {"key_31", "value_31"}, {"key_32", "value_32"},
{"key_33", "value_33"}, {"key_34", "value_34"}, {"key_35", "value_35"},
{"key_36", "value_36"}, {"key_37", "value_37"}, {"key_38", "value_38"},
{"key_39", "value_39"}, {"key_40", "value_40"}, {"key_41", "value_41"},
{"key_42", "value_42"}, {"key_43", "value_43"}, {"key_44", "value_44"},
{"key_45", "value_45"}, {"key_46", "value_46"}, {"key_47", "value_47"},
{"key_48", "value_48"}, {"key_49", "value_49"}, {"key_50", "value_50"},
{"key_51", "value_51"}, {"key_52", "value_52"}, {"key_53", "value_53"},
{"key_54", "value_54"}, {"key_55", "value_55"}, {"key_56", "value_56"},
{"key_57", "value_57"}, {"key_58", "value_58"}, {"key_59", "value_59"},
{"key_60", "value_60"}, {"key_61", "value_61"}, {"key_62", "value_62"},
{"key_63", "value_63"}, {"key_64", "value_64"}, {"key_65", "value_65"},
{"key_66", "value_66"}, {"key_67", "value_67"}, {"key_68", "value_68"},
{"key_69", "value_69"}, {"key_70", "value_70"}, {"key_71", "value_71"},
{"key_72", "value_72"}, {"key_73", "value_73"}, {"key_74", "value_74"},
{"key_75", "value_75"}, {"key_76", "value_76"}, {"key_77", "value_77"},
{"key_78", "value_78"}, {"key_79", "value_79"}, {"key_80", "value_80"},
{"key_81", "value_81"}, {"key_82", "value_82"}, {"key_83", "value_83"},
{"key_84", "value_84"}, {"key_85", "value_85"}, {"key_86", "value_86"},
{"key_87", "value_87"}, {"key_88", "value_88"}, {"key_89", "value_89"},
{"key_90", "value_90"}, {"key_91", "value_91"}, {"key_92", "value_92"},
{"key_93", "value_93"}, {"key_94", "value_94"}, {"key_95", "value_95"},
{"key_96", "value_96"}, {"key_97", "value_97"}, {"key_98", "value_98"},
{"key_99", "value_99"},
};
const size_t num_entries = GPR_ARRAY_SIZE(test_entries);
// Construct table.
grpc_slice_hash_table_entry* entries =
gpr_zalloc(sizeof(*entries) * num_entries);
populate_entries(test_entries, num_entries, entries);
grpc_slice_hash_table* table =
grpc_slice_hash_table_create(num_entries, entries, destroy_string);
gpr_free(entries);
// Check contents of table.
check_values(test_entries, num_entries, table);
check_non_existent_value("XX", table);
// Clean up.
grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
grpc_slice_hash_table_unref(&exec_ctx, table);
grpc_exec_ctx_finish(&exec_ctx);
}
int main(int argc, char** argv) {
grpc_test_init(argc, argv);
test_slice_hash_table();
return 0;
}

@ -108,7 +108,7 @@ bool Http2Client::DoRstAfterData() {
SimpleResponse response;
AssertStatusCode(SendUnaryCall(&response), grpc::StatusCode::INTERNAL);
GPR_ASSERT(response.has_payload()); // data should be received
// There is no guarantee that data would be received.
gpr_log(GPR_DEBUG, "Done testing reset stream after data");
return true;

@ -68,10 +68,12 @@ auto &force_library_initialization = Library::get();
void BM_Zalloc(benchmark::State &state) {
// speed of light for call creation is zalloc, so benchmark a few interesting
// sizes
TrackCounters track_counters;
size_t sz = state.range(0);
while (state.KeepRunning()) {
gpr_free(gpr_zalloc(sz));
}
track_counters.Finish(state);
}
BENCHMARK(BM_Zalloc)
->Arg(64)

@ -57,6 +57,10 @@ void TrackCounters::AddToLabel(std::ostream &out, benchmark::State &state) {
<< ((double)(gpr_atm_no_barrier_load(&gpr_counter_atm_add) -
atm_add_at_start_) /
(double)state.iterations())
<< " nows/iter:"
<< ((double)(gpr_atm_no_barrier_load(&gpr_now_call_count) -
now_calls_at_start_) /
(double)state.iterations())
<< " allocs/iter:"
<< ((double)(counters_at_end.total_allocs_absolute -
counters_at_start_.total_allocs_absolute) /

@ -72,6 +72,7 @@ class Library {
extern "C" gpr_atm gpr_mu_locks;
extern "C" gpr_atm gpr_counter_atm_cas;
extern "C" gpr_atm gpr_counter_atm_add;
extern "C" gpr_atm gpr_now_call_count;
#endif
class TrackCounters {
@ -86,6 +87,8 @@ class TrackCounters {
gpr_atm_no_barrier_load(&gpr_counter_atm_cas);
const size_t atm_add_at_start_ =
gpr_atm_no_barrier_load(&gpr_counter_atm_add);
const size_t now_calls_at_start_ =
gpr_atm_no_barrier_load(&gpr_now_call_count);
grpc_memory_counters counters_at_start_ = grpc_memory_counters_snapshot();
#endif
};

@ -29,6 +29,15 @@
licenses(["notice"]) # 3-clause BSD
# The following builds a shared-object to confirm that grpc++_unsecure
# builds properly. Build-only is sufficient here
cc_binary(
name = "testso.so",
srcs = [],
deps = ["//:grpc++_unsecure"],
linkshared = 1,
)
cc_library(
name = "test_config",
srcs = [

@ -33,30 +33,31 @@ package(default_visibility = ["//visibility:public"])
load("//:bazel/grpc_build_system.bzl", "grpc_proto_library")
grpc_proto_library (
grpc_proto_library(
name = "monitoring_proto",
srcs = [
"monitoring.proto",
],
well_known_protos = "@com_google_protobuf//:well_known_protos",
deps = [
":census_proto",
],
well_known_protos = "@submodule_protobuf//:well_known_protos",
)
grpc_proto_library (
grpc_proto_library(
name = "census_proto",
srcs = [
"census.proto",
],
well_known_protos = "@submodule_protobuf//:well_known_protos",
well_known_protos = "@com_google_protobuf//:well_known_protos",
)
cc_binary(
name = "grpcz_client",
srcs = ["grpcz_client.cc",],
srcs = ["grpcz_client.cc"],
deps = [
"//external:gflags",
"monitoring_proto",
"//external:gflags",
"@mongoose_repo//:mongoose_lib",
],
)

@ -71,6 +71,7 @@ columns = [
('end_of_stream', 'boolean'),
('header_bytes_per_iteration', 'float'),
('framing_bytes_per_iteration', 'float'),
('nows_per_iteration', 'float'),
]
SANITIZE = {
@ -103,4 +104,3 @@ for row in bm_json.expand_json(js, js2):
if row[name] == '': continue
sane_row[name] = SANITIZE[sql_type](row[name])
writer.writerow(sane_row)

@ -56,6 +56,7 @@ _INTERESTING = (
'writes_per_iteration',
'atm_cas_per_iteration',
'atm_add_per_iteration',
'nows_per_iteration',
)
def changed_ratio(n, o):

@ -1978,6 +1978,23 @@
"third_party": false,
"type": "target"
},
{
"deps": [
"gpr",
"gpr_test_util",
"grpc",
"grpc_test_util"
],
"headers": [],
"is_filegroup": false,
"language": "c",
"name": "slice_hash_table_test",
"src": [
"test/core/slice/slice_hash_table_test.c"
],
"third_party": false,
"type": "target"
},
{
"deps": [
"gpr",

@ -2071,6 +2071,28 @@
"windows"
]
},
{
"args": [],
"ci_platforms": [
"linux",
"mac",
"posix",
"windows"
],
"cpu_cost": 1.0,
"exclude_configs": [],
"exclude_iomgrs": [],
"flaky": false,
"gtest": false,
"language": "c",
"name": "slice_hash_table_test",
"platforms": [
"linux",
"mac",
"posix",
"windows"
]
},
{
"args": [],
"ci_platforms": [

@ -1440,6 +1440,17 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "slice_buffer_test", "vcxpro
{B23D3D1A-9438-4EDA-BEB6-9A0A03D17792} = {B23D3D1A-9438-4EDA-BEB6-9A0A03D17792}
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "slice_hash_table_test", "vcxproj\test\slice_hash_table_test\slice_hash_table_test.vcxproj", "{B3BC3481-FCD3-BA52-C975-E65CDB1CE9A9}"
ProjectSection(myProperties) = preProject
lib = "False"
EndProjectSection
ProjectSection(ProjectDependencies) = postProject
{17BCAFC0-5FDC-4C94-AEB9-95F3E220614B} = {17BCAFC0-5FDC-4C94-AEB9-95F3E220614B}
{29D16885-7228-4C31-81ED-5F9187C7F2A9} = {29D16885-7228-4C31-81ED-5F9187C7F2A9}
{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}") = "slice_string_helpers_test", "vcxproj\test\slice_string_helpers_test\slice_string_helpers_test.vcxproj", "{419167BB-C3F5-DDEA-403A-394D1902DE65}"
ProjectSection(myProperties) = preProject
lib = "False"
@ -3823,6 +3834,22 @@ Global
{F0FA4A41-5695-580A-DCDA-EC719CB041B0}.Release-DLL|Win32.Build.0 = Release|Win32
{F0FA4A41-5695-580A-DCDA-EC719CB041B0}.Release-DLL|x64.ActiveCfg = Release|x64
{F0FA4A41-5695-580A-DCDA-EC719CB041B0}.Release-DLL|x64.Build.0 = Release|x64
{B3BC3481-FCD3-BA52-C975-E65CDB1CE9A9}.Debug|Win32.ActiveCfg = Debug|Win32
{B3BC3481-FCD3-BA52-C975-E65CDB1CE9A9}.Debug|x64.ActiveCfg = Debug|x64
{B3BC3481-FCD3-BA52-C975-E65CDB1CE9A9}.Release|Win32.ActiveCfg = Release|Win32
{B3BC3481-FCD3-BA52-C975-E65CDB1CE9A9}.Release|x64.ActiveCfg = Release|x64
{B3BC3481-FCD3-BA52-C975-E65CDB1CE9A9}.Debug|Win32.Build.0 = Debug|Win32
{B3BC3481-FCD3-BA52-C975-E65CDB1CE9A9}.Debug|x64.Build.0 = Debug|x64
{B3BC3481-FCD3-BA52-C975-E65CDB1CE9A9}.Release|Win32.Build.0 = Release|Win32
{B3BC3481-FCD3-BA52-C975-E65CDB1CE9A9}.Release|x64.Build.0 = Release|x64
{B3BC3481-FCD3-BA52-C975-E65CDB1CE9A9}.Debug-DLL|Win32.ActiveCfg = Debug|Win32
{B3BC3481-FCD3-BA52-C975-E65CDB1CE9A9}.Debug-DLL|Win32.Build.0 = Debug|Win32
{B3BC3481-FCD3-BA52-C975-E65CDB1CE9A9}.Debug-DLL|x64.ActiveCfg = Debug|x64
{B3BC3481-FCD3-BA52-C975-E65CDB1CE9A9}.Debug-DLL|x64.Build.0 = Debug|x64
{B3BC3481-FCD3-BA52-C975-E65CDB1CE9A9}.Release-DLL|Win32.ActiveCfg = Release|Win32
{B3BC3481-FCD3-BA52-C975-E65CDB1CE9A9}.Release-DLL|Win32.Build.0 = Release|Win32
{B3BC3481-FCD3-BA52-C975-E65CDB1CE9A9}.Release-DLL|x64.ActiveCfg = Release|x64
{B3BC3481-FCD3-BA52-C975-E65CDB1CE9A9}.Release-DLL|x64.Build.0 = Release|x64
{419167BB-C3F5-DDEA-403A-394D1902DE65}.Debug|Win32.ActiveCfg = Debug|Win32
{419167BB-C3F5-DDEA-403A-394D1902DE65}.Debug|x64.ActiveCfg = Debug|x64
{419167BB-C3F5-DDEA-403A-394D1902DE65}.Release|Win32.ActiveCfg = Release|Win32

@ -0,0 +1,199 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.openssl.1.0.204.1\build\native\grpc.dependencies.openssl.props" Condition="Exists('$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.openssl.1.0.204.1\build\native\1.0.204.1.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>{B3BC3481-FCD3-BA52-C975-E65CDB1CE9A9}</ProjectGuid>
<IgnoreWarnIntDirInTempDetected>true</IgnoreWarnIntDirInTempDetected>
<IntDir>$(SolutionDir)IntDir\$(MSBuildProjectName)\</IntDir>
</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="'$(VisualStudioVersion)' == '14.0'" Label="Configuration">
<PlatformToolset>v140</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="$(SolutionDir)\..\vsprojects\global.props" />
<Import Project="$(SolutionDir)\..\vsprojects\openssl.props" />
<Import Project="$(SolutionDir)\..\vsprojects\winsock.props" />
<Import Project="$(SolutionDir)\..\vsprojects\zlib.props" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup Condition="'$(Configuration)'=='Debug'">
<TargetName>slice_hash_table_test</TargetName>
<Linkage-grpc_dependencies_zlib>static</Linkage-grpc_dependencies_zlib>
<Configuration-grpc_dependencies_zlib>Debug</Configuration-grpc_dependencies_zlib>
<Linkage-grpc_dependencies_openssl>static</Linkage-grpc_dependencies_openssl>
<Configuration-grpc_dependencies_openssl>Debug</Configuration-grpc_dependencies_openssl>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)'=='Release'">
<TargetName>slice_hash_table_test</TargetName>
<Linkage-grpc_dependencies_zlib>static</Linkage-grpc_dependencies_zlib>
<Configuration-grpc_dependencies_zlib>Release</Configuration-grpc_dependencies_zlib>
<Linkage-grpc_dependencies_openssl>static</Linkage-grpc_dependencies_openssl>
<Configuration-grpc_dependencies_openssl>Release</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;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<SDLCheck>true</SDLCheck>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
<TreatWarningAsError>true</TreatWarningAsError>
<DebugInformationFormat Condition="$(Jenkins)">None</DebugInformationFormat>
<MinimalRebuild Condition="$(Jenkins)">false</MinimalRebuild>
</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>
<MinimalRebuild Condition="$(Jenkins)">false</MinimalRebuild>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<GenerateDebugInformation Condition="!$(Jenkins)">true</GenerateDebugInformation>
<GenerateDebugInformation Condition="$(Jenkins)">false</GenerateDebugInformation>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<PrecompiledHeader>NotUsing</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<Optimization>MaxSpeed</Optimization>
<PreprocessorDefinitions>WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<SDLCheck>true</SDLCheck>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
<TreatWarningAsError>true</TreatWarningAsError>
<DebugInformationFormat Condition="$(Jenkins)">None</DebugInformationFormat>
<MinimalRebuild Condition="$(Jenkins)">false</MinimalRebuild>
</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>
<PrecompiledHeader>NotUsing</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<Optimization>MaxSpeed</Optimization>
<PreprocessorDefinitions>WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<SDLCheck>true</SDLCheck>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
<TreatWarningAsError>true</TreatWarningAsError>
<DebugInformationFormat Condition="$(Jenkins)">None</DebugInformationFormat>
<MinimalRebuild Condition="$(Jenkins)">false</MinimalRebuild>
</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="$(SolutionDir)\..\test\core\slice\slice_hash_table_test.c">
</ClCompile>
</ItemGroup>
<ItemGroup>
<ProjectReference Include="$(SolutionDir)\..\vsprojects\vcxproj\.\grpc_test_util\grpc_test_util.vcxproj">
<Project>{17BCAFC0-5FDC-4C94-AEB9-95F3E220614B}</Project>
</ProjectReference>
<ProjectReference Include="$(SolutionDir)\..\vsprojects\vcxproj\.\grpc\grpc.vcxproj">
<Project>{29D16885-7228-4C31-81ED-5F9187C7F2A9}</Project>
</ProjectReference>
<ProjectReference Include="$(SolutionDir)\..\vsprojects\vcxproj\.\gpr_test_util\gpr_test_util.vcxproj">
<Project>{EAB0A629-17A9-44DB-B5FF-E91A721FE037}</Project>
</ProjectReference>
<ProjectReference Include="$(SolutionDir)\..\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="$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.zlib.redist.1.2.8.10\build\native\grpc.dependencies.zlib.redist.targets" Condition="Exists('$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.zlib.redist.1.2.8.10\build\native\grpc.dependencies\grpc.dependencies.zlib.targets')" />
<Import Project="$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.zlib.1.2.8.10\build\native\grpc.dependencies.zlib.targets" Condition="Exists('$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.zlib.1.2.8.10\build\native\grpc.dependencies\grpc.dependencies.zlib.targets')" />
<Import Project="$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.openssl.redist.1.0.204.1\build\native\grpc.dependencies.openssl.redist.targets" Condition="Exists('$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.openssl.redist.1.0.204.1\build\native\grpc.dependencies\grpc.dependencies.openssl.targets')" />
<Import Project="$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.openssl.1.0.204.1\build\native\grpc.dependencies.openssl.targets" Condition="Exists('$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.openssl.1.0.204.1\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('$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.zlib.redist.1.2.8.10\build\native\grpc.dependencies.zlib.redist.targets')" Text="$([System.String]::Format('$(ErrorText)', '$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.zlib.redist.1.2.8.10\build\native\grpc.dependencies.zlib.redist.targets')" />
<Error Condition="!Exists('$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.zlib.1.2.8.10\build\native\grpc.dependencies.zlib.targets')" Text="$([System.String]::Format('$(ErrorText)', '$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.zlib.1.2.8.10\build\native\grpc.dependencies.zlib.targets')" />
<Error Condition="!Exists('$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.openssl.redist.1.0.204.1\build\native\grpc.dependencies.openssl.redist.targets')" Text="$([System.String]::Format('$(ErrorText)', '$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.openssl.redist.1.0.204.1\build\native\grpc.dependencies.openssl.redist.targets')" />
<Error Condition="!Exists('$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.openssl.1.0.204.1\build\native\grpc.dependencies.openssl.props')" Text="$([System.String]::Format('$(ErrorText)', '$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.openssl.1.0.204.1\build\native\grpc.dependencies.openssl.props')" />
<Error Condition="!Exists('$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.openssl.1.0.204.1\build\native\grpc.dependencies.openssl.targets')" Text="$([System.String]::Format('$(ErrorText)', '$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.openssl.1.0.204.1\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="$(SolutionDir)\..\test\core\slice\slice_hash_table_test.c">
<Filter>test\core\slice</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<Filter Include="test">
<UniqueIdentifier>{e11f5007-84da-0229-9118-2a2bb17f956c}</UniqueIdentifier>
</Filter>
<Filter Include="test\core">
<UniqueIdentifier>{a11f4770-5e13-eb1a-a848-8667dde98812}</UniqueIdentifier>
</Filter>
<Filter Include="test\core\slice">
<UniqueIdentifier>{fb1262a8-0a70-bc85-579a-6ebfffbf25b5}</UniqueIdentifier>
</Filter>
</ItemGroup>
</Project>
Loading…
Cancel
Save