Merge remote-tracking branch 'upstream/master' into extend_thd_stack_size

pull/19393/head
Yunjia Wang 6 years ago
commit 7567bd7892
  1. 4
      BUILD
  2. 84
      CMakeLists.txt
  3. 76
      Makefile
  4. 4
      Rakefile
  5. 32
      bazel/grpc_deps.bzl
  6. 4
      build.yaml
  7. 3
      doc/g_stands_for.md
  8. 44
      examples/python/compression/BUILD.bazel
  9. 58
      examples/python/compression/README.md
  10. 76
      examples/python/compression/client.py
  11. 109
      examples/python/compression/server.py
  12. 62
      examples/python/compression/test/compression_example_test.py
  13. 4
      examples/python/multiprocessing/BUILD
  14. 2
      examples/python/multiprocessing/server.py
  15. 4
      gRPC-C++.podspec
  16. 2
      gRPC-Core.podspec
  17. 2
      gRPC-ProtoRPC.podspec
  18. 2
      gRPC-RxLibrary.podspec
  19. 2
      gRPC.podspec
  20. 2
      grpc.gemspec
  21. 51
      include/grpcpp/impl/codegen/client_callback.h
  22. 60
      include/grpcpp/impl/codegen/server_callback.h
  23. 10
      include/grpcpp/impl/codegen/server_interceptor.h
  24. 2
      include/grpcpp/server_impl.h
  25. 4
      package.xml
  26. 4
      src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc
  27. 117
      src/core/ext/filters/client_channel/lb_policy/pick_first/pick_first.cc
  28. 4
      src/core/ext/filters/client_channel/lb_policy/xds/xds.cc
  29. 5
      src/core/ext/filters/client_channel/retry_throttle.h
  30. 2
      src/core/ext/filters/http/client/http_client_filter.cc
  31. 4
      src/core/ext/filters/http/client_authority_filter.cc
  32. 254
      src/core/ext/filters/http/message_compress/message_compress_filter.cc
  33. 10
      src/core/ext/transport/chttp2/transport/hpack_parser.cc
  34. 6
      src/core/ext/transport/chttp2/transport/hpack_table.cc
  35. 2
      src/core/ext/transport/inproc/inproc_transport.cc
  36. 3
      src/core/lib/compression/compression.cc
  37. 19
      src/core/lib/compression/compression_args.cc
  38. 5
      src/core/lib/compression/compression_args.h
  39. 2
      src/core/lib/compression/compression_internal.cc
  40. 35
      src/core/lib/gprpp/memory.h
  41. 24
      src/core/lib/iomgr/error.cc
  42. 49
      src/core/lib/slice/slice.cc
  43. 10
      src/core/lib/slice/slice_hash_table.h
  44. 15
      src/core/lib/slice/slice_internal.h
  45. 9
      src/core/lib/slice/slice_weak_hash_table.h
  46. 11
      src/core/lib/surface/call.cc
  47. 2
      src/core/lib/surface/version.cc
  48. 11
      src/core/lib/transport/error_utils.cc
  49. 7
      src/core/lib/transport/timeout_encoding.cc
  50. 5
      src/core/lib/transport/timeout_encoding.h
  51. 9
      src/core/tsi/ssl/session_cache/ssl_session_cache.h
  52. 2
      src/cpp/common/version_cc.cc
  53. 4
      src/csharp/Grpc.Core.Api/VersionInfo.cs
  54. 4
      src/csharp/Grpc.Core.Tests/ContextPropagationTest.cs
  55. 2
      src/csharp/Grpc.Core.Tests/TimeoutsTest.cs
  56. 2
      src/csharp/build/dependencies.props
  57. 2
      src/csharp/build_unitypackage.bat
  58. 4
      src/objective-c/!ProtoCompiler-gRPCPlugin.podspec
  59. 2
      src/objective-c/!ProtoCompiler.podspec
  60. 2
      src/objective-c/GRPCClient/private/version.h
  61. 8
      src/objective-c/tests/UnitTests/GRPCClientTests.m
  62. 66
      src/objective-c/tests/run_one_test.sh
  63. 2
      src/objective-c/tests/version.h
  64. 2
      src/php/composer.json
  65. 2
      src/php/ext/grpc/version.h
  66. 2
      src/python/grpcio/grpc/_grpcio_metadata.py
  67. 2
      src/python/grpcio/grpc_version.py
  68. 2
      src/python/grpcio_channelz/grpc_version.py
  69. 2
      src/python/grpcio_health_checking/grpc_version.py
  70. 2
      src/python/grpcio_reflection/grpc_version.py
  71. 2
      src/python/grpcio_status/grpc_version.py
  72. 2
      src/python/grpcio_testing/grpc_version.py
  73. 2
      src/python/grpcio_tests/grpc_version.py
  74. 2
      src/ruby/lib/grpc/version.rb
  75. 2
      src/ruby/tools/version.rb
  76. 2
      templates/grpc.gemspec.template
  77. 2
      templates/src/objective-c/!ProtoCompiler-gRPCPlugin.podspec.template
  78. 2
      templates/tools/dockerfile/bazel.include
  79. 2
      test/core/bad_client/gen_build_yaml.py
  80. 2
      test/core/bad_client/generate_tests.bzl
  81. 132
      test/core/bad_client/tests/bad_streaming_id.cc
  82. 112
      test/core/bad_client/tests/out_of_bounds.cc
  83. 15
      test/core/compression/algorithm_test.cc
  84. 4
      test/core/compression/compression_test.cc
  85. 10
      test/core/end2end/fixtures/h2_compress.cc
  86. 10
      test/core/end2end/tests/compressed_payload.cc
  87. 12
      test/core/end2end/tests/stream_compression_compressed_payload.cc
  88. 10
      test/core/end2end/tests/stream_compression_payload.cc
  89. 10
      test/core/end2end/tests/stream_compression_ping_pong_streaming.cc
  90. 4
      test/core/end2end/tests/workaround_cronet_compression.cc
  91. 3
      test/core/transport/timeout_encoding_test.cc
  92. 6
      test/cpp/end2end/BUILD
  93. 1
      test/cpp/ext/filters/census/BUILD
  94. 2
      test/cpp/naming/BUILD
  95. 4
      test/cpp/naming/generate_resolver_component_tests.bzl
  96. 1
      test/cpp/server/load_reporter/BUILD
  97. 2
      third_party/googletest
  98. 42
      third_party/gtest.BUILD
  99. 2
      tools/bazel
  100. 6
      tools/bazel.rc
  101. Some files were not shown because too many files have changed in this diff Show More

@ -74,11 +74,11 @@ config_setting(
)
# This should be updated along with build.yaml
g_stands_for = "gale"
g_stands_for = "gangnam"
core_version = "7.0.0"
version = "1.22.0-dev"
version = "1.23.0-dev"
GPR_PUBLIC_HDRS = [
"include/grpc/support/alloc.h",

@ -24,7 +24,7 @@
cmake_minimum_required(VERSION 2.8)
set(PACKAGE_NAME "grpc")
set(PACKAGE_VERSION "1.22.0-dev")
set(PACKAGE_VERSION "1.23.0-dev")
set(PACKAGE_STRING "${PACKAGE_NAME} ${PACKAGE_VERSION}")
set(PACKAGE_TARNAME "${PACKAGE_NAME}-${PACKAGE_VERSION}")
set(PACKAGE_BUGREPORT "https://github.com/grpc/grpc/issues/")
@ -724,6 +724,7 @@ if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX)
add_dependencies(buildtests_cxx writes_per_rpc_test)
endif()
add_dependencies(buildtests_cxx xds_end2end_test)
add_dependencies(buildtests_cxx bad_streaming_id_bad_client_test)
add_dependencies(buildtests_cxx badreq_bad_client_test)
add_dependencies(buildtests_cxx connection_prefix_bad_client_test)
add_dependencies(buildtests_cxx duplicate_header_bad_client_test)
@ -731,6 +732,7 @@ add_dependencies(buildtests_cxx head_of_line_blocking_bad_client_test)
add_dependencies(buildtests_cxx headers_bad_client_test)
add_dependencies(buildtests_cxx initial_settings_frame_bad_client_test)
add_dependencies(buildtests_cxx large_metadata_bad_client_test)
add_dependencies(buildtests_cxx out_of_bounds_bad_client_test)
add_dependencies(buildtests_cxx server_registered_method_bad_client_test)
add_dependencies(buildtests_cxx simple_request_bad_client_test)
add_dependencies(buildtests_cxx unknown_frame_bad_client_test)
@ -17030,6 +17032,46 @@ target_link_libraries(gen_percent_encoding_tables
if (gRPC_BUILD_TESTS)
add_executable(bad_streaming_id_bad_client_test
test/core/bad_client/tests/bad_streaming_id.cc
third_party/googletest/googletest/src/gtest-all.cc
third_party/googletest/googlemock/src/gmock-all.cc
)
target_include_directories(bad_streaming_id_bad_client_test
PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
PRIVATE ${_gRPC_SSL_INCLUDE_DIR}
PRIVATE ${_gRPC_PROTOBUF_INCLUDE_DIR}
PRIVATE ${_gRPC_ZLIB_INCLUDE_DIR}
PRIVATE ${_gRPC_BENCHMARK_INCLUDE_DIR}
PRIVATE ${_gRPC_CARES_INCLUDE_DIR}
PRIVATE ${_gRPC_GFLAGS_INCLUDE_DIR}
PRIVATE ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR}
PRIVATE ${_gRPC_NANOPB_INCLUDE_DIR}
PRIVATE third_party/googletest/googletest/include
PRIVATE third_party/googletest/googletest
PRIVATE third_party/googletest/googlemock/include
PRIVATE third_party/googletest/googlemock
PRIVATE ${_gRPC_PROTO_GENS_DIR}
)
target_link_libraries(bad_streaming_id_bad_client_test
${_gRPC_SSL_LIBRARIES}
${_gRPC_PROTOBUF_LIBRARIES}
${_gRPC_ALLTARGETS_LIBRARIES}
bad_client_test
grpc_test_util_unsecure
grpc_unsecure
gpr
${_gRPC_GFLAGS_LIBRARIES}
)
endif (gRPC_BUILD_TESTS)
if (gRPC_BUILD_TESTS)
add_executable(badreq_bad_client_test
test/core/bad_client/tests/badreq.cc
third_party/googletest/googletest/src/gtest-all.cc
@ -17307,6 +17349,46 @@ target_link_libraries(large_metadata_bad_client_test
)
endif (gRPC_BUILD_TESTS)
if (gRPC_BUILD_TESTS)
add_executable(out_of_bounds_bad_client_test
test/core/bad_client/tests/out_of_bounds.cc
third_party/googletest/googletest/src/gtest-all.cc
third_party/googletest/googlemock/src/gmock-all.cc
)
target_include_directories(out_of_bounds_bad_client_test
PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
PRIVATE ${_gRPC_SSL_INCLUDE_DIR}
PRIVATE ${_gRPC_PROTOBUF_INCLUDE_DIR}
PRIVATE ${_gRPC_ZLIB_INCLUDE_DIR}
PRIVATE ${_gRPC_BENCHMARK_INCLUDE_DIR}
PRIVATE ${_gRPC_CARES_INCLUDE_DIR}
PRIVATE ${_gRPC_GFLAGS_INCLUDE_DIR}
PRIVATE ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR}
PRIVATE ${_gRPC_NANOPB_INCLUDE_DIR}
PRIVATE third_party/googletest/googletest/include
PRIVATE third_party/googletest/googletest
PRIVATE third_party/googletest/googlemock/include
PRIVATE third_party/googletest/googlemock
PRIVATE ${_gRPC_PROTO_GENS_DIR}
)
target_link_libraries(out_of_bounds_bad_client_test
${_gRPC_SSL_LIBRARIES}
${_gRPC_PROTOBUF_LIBRARIES}
${_gRPC_ALLTARGETS_LIBRARIES}
bad_client_test
grpc_test_util_unsecure
grpc_unsecure
gpr
${_gRPC_GFLAGS_LIBRARIES}
)
endif (gRPC_BUILD_TESTS)
if (gRPC_BUILD_TESTS)

@ -460,8 +460,8 @@ Q = @
endif
CORE_VERSION = 7.0.0
CPP_VERSION = 1.22.0-dev
CSHARP_VERSION = 1.22.0-dev
CPP_VERSION = 1.23.0-dev
CSHARP_VERSION = 1.23.0-dev
CPPFLAGS_NO_ARCH += $(addprefix -I, $(INCLUDES)) $(addprefix -D, $(DEFINES))
CPPFLAGS += $(CPPFLAGS_NO_ARCH) $(ARCH_FLAGS)
@ -1291,6 +1291,7 @@ gen_legal_metadata_characters: $(BINDIR)/$(CONFIG)/gen_legal_metadata_characters
gen_percent_encoding_tables: $(BINDIR)/$(CONFIG)/gen_percent_encoding_tables
boringssl_ssl_test: $(BINDIR)/$(CONFIG)/boringssl_ssl_test
boringssl_crypto_test: $(BINDIR)/$(CONFIG)/boringssl_crypto_test
bad_streaming_id_bad_client_test: $(BINDIR)/$(CONFIG)/bad_streaming_id_bad_client_test
badreq_bad_client_test: $(BINDIR)/$(CONFIG)/badreq_bad_client_test
connection_prefix_bad_client_test: $(BINDIR)/$(CONFIG)/connection_prefix_bad_client_test
duplicate_header_bad_client_test: $(BINDIR)/$(CONFIG)/duplicate_header_bad_client_test
@ -1298,6 +1299,7 @@ head_of_line_blocking_bad_client_test: $(BINDIR)/$(CONFIG)/head_of_line_blocking
headers_bad_client_test: $(BINDIR)/$(CONFIG)/headers_bad_client_test
initial_settings_frame_bad_client_test: $(BINDIR)/$(CONFIG)/initial_settings_frame_bad_client_test
large_metadata_bad_client_test: $(BINDIR)/$(CONFIG)/large_metadata_bad_client_test
out_of_bounds_bad_client_test: $(BINDIR)/$(CONFIG)/out_of_bounds_bad_client_test
server_registered_method_bad_client_test: $(BINDIR)/$(CONFIG)/server_registered_method_bad_client_test
simple_request_bad_client_test: $(BINDIR)/$(CONFIG)/simple_request_bad_client_test
unknown_frame_bad_client_test: $(BINDIR)/$(CONFIG)/unknown_frame_bad_client_test
@ -1751,6 +1753,7 @@ buildtests_cxx: privatelibs_cxx \
$(BINDIR)/$(CONFIG)/xds_end2end_test \
$(BINDIR)/$(CONFIG)/boringssl_ssl_test \
$(BINDIR)/$(CONFIG)/boringssl_crypto_test \
$(BINDIR)/$(CONFIG)/bad_streaming_id_bad_client_test \
$(BINDIR)/$(CONFIG)/badreq_bad_client_test \
$(BINDIR)/$(CONFIG)/connection_prefix_bad_client_test \
$(BINDIR)/$(CONFIG)/duplicate_header_bad_client_test \
@ -1758,6 +1761,7 @@ buildtests_cxx: privatelibs_cxx \
$(BINDIR)/$(CONFIG)/headers_bad_client_test \
$(BINDIR)/$(CONFIG)/initial_settings_frame_bad_client_test \
$(BINDIR)/$(CONFIG)/large_metadata_bad_client_test \
$(BINDIR)/$(CONFIG)/out_of_bounds_bad_client_test \
$(BINDIR)/$(CONFIG)/server_registered_method_bad_client_test \
$(BINDIR)/$(CONFIG)/simple_request_bad_client_test \
$(BINDIR)/$(CONFIG)/unknown_frame_bad_client_test \
@ -1910,6 +1914,7 @@ buildtests_cxx: privatelibs_cxx \
$(BINDIR)/$(CONFIG)/transport_security_common_api_test \
$(BINDIR)/$(CONFIG)/writes_per_rpc_test \
$(BINDIR)/$(CONFIG)/xds_end2end_test \
$(BINDIR)/$(CONFIG)/bad_streaming_id_bad_client_test \
$(BINDIR)/$(CONFIG)/badreq_bad_client_test \
$(BINDIR)/$(CONFIG)/connection_prefix_bad_client_test \
$(BINDIR)/$(CONFIG)/duplicate_header_bad_client_test \
@ -1917,6 +1922,7 @@ buildtests_cxx: privatelibs_cxx \
$(BINDIR)/$(CONFIG)/headers_bad_client_test \
$(BINDIR)/$(CONFIG)/initial_settings_frame_bad_client_test \
$(BINDIR)/$(CONFIG)/large_metadata_bad_client_test \
$(BINDIR)/$(CONFIG)/out_of_bounds_bad_client_test \
$(BINDIR)/$(CONFIG)/server_registered_method_bad_client_test \
$(BINDIR)/$(CONFIG)/simple_request_bad_client_test \
$(BINDIR)/$(CONFIG)/unknown_frame_bad_client_test \
@ -2441,6 +2447,8 @@ test_cxx: buildtests_cxx
$(Q) $(BINDIR)/$(CONFIG)/writes_per_rpc_test || ( echo test writes_per_rpc_test failed ; exit 1 )
$(E) "[RUN] Testing xds_end2end_test"
$(Q) $(BINDIR)/$(CONFIG)/xds_end2end_test || ( echo test xds_end2end_test failed ; exit 1 )
$(E) "[RUN] Testing bad_streaming_id_bad_client_test"
$(Q) $(BINDIR)/$(CONFIG)/bad_streaming_id_bad_client_test || ( echo test bad_streaming_id_bad_client_test failed ; exit 1 )
$(E) "[RUN] Testing badreq_bad_client_test"
$(Q) $(BINDIR)/$(CONFIG)/badreq_bad_client_test || ( echo test badreq_bad_client_test failed ; exit 1 )
$(E) "[RUN] Testing connection_prefix_bad_client_test"
@ -2455,6 +2463,8 @@ test_cxx: buildtests_cxx
$(Q) $(BINDIR)/$(CONFIG)/initial_settings_frame_bad_client_test || ( echo test initial_settings_frame_bad_client_test failed ; exit 1 )
$(E) "[RUN] Testing large_metadata_bad_client_test"
$(Q) $(BINDIR)/$(CONFIG)/large_metadata_bad_client_test || ( echo test large_metadata_bad_client_test failed ; exit 1 )
$(E) "[RUN] Testing out_of_bounds_bad_client_test"
$(Q) $(BINDIR)/$(CONFIG)/out_of_bounds_bad_client_test || ( echo test out_of_bounds_bad_client_test failed ; exit 1 )
$(E) "[RUN] Testing server_registered_method_bad_client_test"
$(Q) $(BINDIR)/$(CONFIG)/server_registered_method_bad_client_test || ( echo test server_registered_method_bad_client_test failed ; exit 1 )
$(E) "[RUN] Testing simple_request_bad_client_test"
@ -20323,6 +20333,37 @@ ifneq ($(NO_DEPS),true)
endif
BAD_STREAMING_ID_BAD_CLIENT_TEST_SRC = \
test/core/bad_client/tests/bad_streaming_id.cc \
BAD_STREAMING_ID_BAD_CLIENT_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(BAD_STREAMING_ID_BAD_CLIENT_TEST_SRC))))
ifeq ($(NO_PROTOBUF),true)
# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.5.0+.
$(BINDIR)/$(CONFIG)/bad_streaming_id_bad_client_test: protobuf_dep_error
else
$(BINDIR)/$(CONFIG)/bad_streaming_id_bad_client_test: $(PROTOBUF_DEP) $(BAD_STREAMING_ID_BAD_CLIENT_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libbad_client_test.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr.a
$(E) "[LD] Linking $@"
$(Q) mkdir -p `dirname $@`
$(Q) $(LDXX) $(LDFLAGS) $(BAD_STREAMING_ID_BAD_CLIENT_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libbad_client_test.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/bad_streaming_id_bad_client_test
endif
$(OBJDIR)/$(CONFIG)/test/core/bad_client/tests/bad_streaming_id.o: $(LIBDIR)/$(CONFIG)/libbad_client_test.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr.a
deps_bad_streaming_id_bad_client_test: $(BAD_STREAMING_ID_BAD_CLIENT_TEST_OBJS:.o=.dep)
ifneq ($(NO_DEPS),true)
-include $(BAD_STREAMING_ID_BAD_CLIENT_TEST_OBJS:.o=.dep)
endif
BADREQ_BAD_CLIENT_TEST_SRC = \
test/core/bad_client/tests/badreq.cc \
@ -20540,6 +20581,37 @@ ifneq ($(NO_DEPS),true)
endif
OUT_OF_BOUNDS_BAD_CLIENT_TEST_SRC = \
test/core/bad_client/tests/out_of_bounds.cc \
OUT_OF_BOUNDS_BAD_CLIENT_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(OUT_OF_BOUNDS_BAD_CLIENT_TEST_SRC))))
ifeq ($(NO_PROTOBUF),true)
# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.5.0+.
$(BINDIR)/$(CONFIG)/out_of_bounds_bad_client_test: protobuf_dep_error
else
$(BINDIR)/$(CONFIG)/out_of_bounds_bad_client_test: $(PROTOBUF_DEP) $(OUT_OF_BOUNDS_BAD_CLIENT_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libbad_client_test.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr.a
$(E) "[LD] Linking $@"
$(Q) mkdir -p `dirname $@`
$(Q) $(LDXX) $(LDFLAGS) $(OUT_OF_BOUNDS_BAD_CLIENT_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libbad_client_test.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/out_of_bounds_bad_client_test
endif
$(OBJDIR)/$(CONFIG)/test/core/bad_client/tests/out_of_bounds.o: $(LIBDIR)/$(CONFIG)/libbad_client_test.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr.a
deps_out_of_bounds_bad_client_test: $(OUT_OF_BOUNDS_BAD_CLIENT_TEST_OBJS:.o=.dep)
ifneq ($(NO_DEPS),true)
-include $(OUT_OF_BOUNDS_BAD_CLIENT_TEST_OBJS:.o=.dep)
endif
SERVER_REGISTERED_METHOD_BAD_CLIENT_TEST_SRC = \
test/core/bad_client/tests/server_registered_method.cc \

@ -124,10 +124,10 @@ task 'gem:native' do
"invoked on macos with ruby #{RUBY_VERSION}. The ruby macos artifact " \
"build should be running on ruby 2.5."
end
system "rake cross native gem RUBY_CC_VERSION=2.6.0:2.5.0:2.4.0:2.3.0:2.2.2 V=#{verbose} GRPC_CONFIG=#{grpc_config}"
system "rake cross native gem RUBY_CC_VERSION=2.6.0:2.5.0:2.4.0:2.3.0 V=#{verbose} GRPC_CONFIG=#{grpc_config}"
else
Rake::Task['dlls'].execute
docker_for_windows "gem update --system --no-document && bundle && rake cross native gem RUBY_CC_VERSION=2.6.0:2.5.0:2.4.0:2.3.0:2.2.2 V=#{verbose} GRPC_CONFIG=#{grpc_config}"
docker_for_windows "gem update --system --no-document && bundle && rake cross native gem RUBY_CC_VERSION=2.6.0:2.5.0:2.4.0:2.3.0 V=#{verbose} GRPC_CONFIG=#{grpc_config}"
end
end

@ -66,11 +66,6 @@ def grpc_deps():
actual = "@com_github_google_googletest//:gtest",
)
native.bind(
name = "gmock",
actual = "@com_github_google_googletest//:gmock",
)
native.bind(
name = "benchmark",
actual = "@com_github_google_benchmark//:benchmark",
@ -144,10 +139,9 @@ def grpc_deps():
if "com_github_google_googletest" not in native.existing_rules():
http_archive(
name = "com_github_google_googletest",
build_file = "@com_github_grpc_grpc//third_party:gtest.BUILD",
sha256 = "175a22300b3450e27e5f2e6f95cc9abca74617cbc21a1e0ed19bdfbd22ea0305",
strip_prefix = "googletest-ec44c6c1675c25b9827aacd08c02433cccde7780",
url = "https://github.com/google/googletest/archive/ec44c6c1675c25b9827aacd08c02433cccde7780.tar.gz",
sha256 = "d0d447b4feeedca837a0d46a289d4223089b32ac2f84545fa4982755cc8919be",
strip_prefix = "googletest-2fe3bd994b3189899d93f1d5a881e725e046fdc2",
url = "https://github.com/google/googletest/archive/2fe3bd994b3189899d93f1d5a881e725e046fdc2.tar.gz",
)
if "com_github_gflags_gflags" not in native.existing_rules():
@ -178,19 +172,19 @@ def grpc_deps():
if "com_google_absl" not in native.existing_rules():
http_archive(
name = "com_google_absl",
sha256 = "5fe2a3a8f8378e81d4d3db6541f48030e04233ccd2d6c7e9d981ed577b314ae8",
strip_prefix = "abseil-cpp-308ce31528a7edfa39f5f6d36142278a0ae1bf45",
url = "https://github.com/abseil/abseil-cpp/archive/308ce31528a7edfa39f5f6d36142278a0ae1bf45.tar.gz",
sha256 = "7ddf863ddced6fa5bf7304103f9c7aa619c20a2fcf84475512c8d3834b9d14fa",
strip_prefix = "abseil-cpp-61c9bf3e3e1c28a4aa6d7f1be4b37fd473bb5529",
url = "https://github.com/abseil/abseil-cpp/archive/61c9bf3e3e1c28a4aa6d7f1be4b37fd473bb5529.tar.gz",
)
if "bazel_toolchains" not in native.existing_rules():
http_archive(
name = "bazel_toolchains",
sha256 = "88e818f9f03628eef609c8429c210ecf265ffe46c2af095f36c7ef8b1855fef5",
strip_prefix = "bazel-toolchains-92dd8a7a518a2fb7ba992d47c8b38299fe0be825",
sha256 = "d968b414b32aa99c86977e1171645d31da2b52ac88060de3ac1e49932d5dcbf1",
strip_prefix = "bazel-toolchains-4bd5df80d77aa7f4fb943dfdfad5c9056a62fb47",
urls = [
"https://mirror.bazel.build/github.com/bazelbuild/bazel-toolchains/archive/92dd8a7a518a2fb7ba992d47c8b38299fe0be825.tar.gz",
"https://github.com/bazelbuild/bazel-toolchains/archive/92dd8a7a518a2fb7ba992d47c8b38299fe0be825.tar.gz",
"https://mirror.bazel.build/github.com/bazelbuild/bazel-toolchains/archive/4bd5df80d77aa7f4fb943dfdfad5c9056a62fb47.tar.gz",
"https://github.com/bazelbuild/bazel-toolchains/archive/4bd5df80d77aa7f4fb943dfdfad5c9056a62fb47.tar.gz",
],
)
@ -205,9 +199,9 @@ def grpc_deps():
if "io_opencensus_cpp" not in native.existing_rules():
http_archive(
name = "io_opencensus_cpp",
sha256 = "3436ca23dc1b3345186defd0f46d64244079ba3d3234a0c5d6ef5e8d5d06c8b5",
strip_prefix = "opencensus-cpp-9b1e354e89bf3d92aedc00af45b418ce870f3d77",
url = "https://github.com/census-instrumentation/opencensus-cpp/archive/9b1e354e89bf3d92aedc00af45b418ce870f3d77.tar.gz",
sha256 = "90d6fafa8b1a2ea613bf662731d3086e1c2ed286f458a95c81744df2dbae41b1",
strip_prefix = "opencensus-cpp-c9a4da319bc669a772928ffc55af4a61be1a1176",
url = "https://github.com/census-instrumentation/opencensus-cpp/archive/c9a4da319bc669a772928ffc55af4a61be1a1176.tar.gz",
)
if "upb" not in native.existing_rules():

@ -13,8 +13,8 @@ settings:
'#09': Per-language overrides are possible with (eg) ruby_version tag here
'#10': See the expand_version.py for all the quirks here
core_version: 7.0.0
g_stands_for: gale
version: 1.22.0-dev
g_stands_for: gangnam
version: 1.23.0-dev
filegroups:
- name: alts_proto
headers:

@ -21,4 +21,5 @@
- 1.19 'g' stands for ['gold'](https://github.com/grpc/grpc/tree/v1.19.x)
- 1.20 'g' stands for ['godric'](https://github.com/grpc/grpc/tree/v1.20.x)
- 1.21 'g' stands for ['gandalf'](https://github.com/grpc/grpc/tree/v1.21.x)
- 1.22 'g' stands for ['gale'](https://github.com/grpc/grpc/tree/master)
- 1.22 'g' stands for ['gale'](https://github.com/grpc/grpc/tree/v1.22.x)
- 1.23 'g' stands for ['gangnam'](https://github.com/grpc/grpc/tree/master)

@ -0,0 +1,44 @@
# Copyright 2019 The gRPC Authors
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
py_binary(
name = "server",
srcs = ["server.py"],
deps = [
"//src/python/grpcio/grpc:grpcio",
"//examples:py_helloworld",
],
srcs_version = "PY2AND3",
)
py_binary(
name = "client",
srcs = ["client.py"],
deps = [
"//src/python/grpcio/grpc:grpcio",
"//examples:py_helloworld",
],
srcs_version = "PY2AND3",
)
py_test(
name = "test/compression_example_test",
srcs = ["test/compression_example_test.py"],
srcs_version = "PY2AND3",
data = [
":client",
":server",
],
size = "small",
)

@ -0,0 +1,58 @@
## Compression with gRPC Python
gRPC offers lossless compression options in order to decrease the number of bits
transferred over the wire. Three levels of compression are available:
- `grpc.Compression.NoCompression` - No compression is applied to the payload. (default)
- `grpc.Compression.Deflate` - The "Deflate" algorithm is applied to the payload.
- `grpc.Compression.Gzip` - The Gzip algorithm is applied to the payload.
The default option on both clients and servers is `grpc.Compression.NoCompression`.
See [the gRPC Compression Spec](https://github.com/grpc/grpc/blob/master/doc/compression.md)
for more information.
### Client Side Compression
Compression may be set at two levels on the client side.
#### At the channel level
```python
with grpc.insecure_channel('foo.bar:1234', compression=grpc.Compression.Gzip) as channel:
use_channel(channel)
```
#### At the call level
Setting the compression method at the call level will override any settings on
the channel level.
```python
stub = helloworld_pb2_grpc.GreeterStub(channel)
response = stub.SayHello(helloworld_pb2.HelloRequest(name='you'),
compression=grpc.Compression.Deflate)
```
### Server Side Compression
Additionally, compression may be set at two levels on the server side.
#### On the entire server
```python
server = grpc.server(futures.ThreadPoolExecutor(),
compression=grpc.Compression.Gzip)
```
#### For an individual RPC
```python
def SayHello(self, request, context):
context.set_response_compression(grpc.Compression.NoCompression)
return helloworld_pb2.HelloReply(message='Hello, %s!' % request.name)
```
Setting the compression method for an individual RPC will override any setting
supplied at server creation time.

@ -0,0 +1,76 @@
# Copyright 2019 the gRPC authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""An example of compression on the client side with gRPC."""
from __future__ import absolute_import
from __future__ import division
from __future__ import print_function
import argparse
import logging
import grpc
from examples import helloworld_pb2
from examples import helloworld_pb2_grpc
_DESCRIPTION = 'A client capable of compression.'
_COMPRESSION_OPTIONS = {
"none": grpc.Compression.NoCompression,
"deflate": grpc.Compression.Deflate,
"gzip": grpc.Compression.Gzip,
}
_LOGGER = logging.getLogger(__name__)
def run_client(channel_compression, call_compression, target):
with grpc.insecure_channel(
target, compression=channel_compression) as channel:
stub = helloworld_pb2_grpc.GreeterStub(channel)
response = stub.SayHello(
helloworld_pb2.HelloRequest(name='you'),
compression=call_compression,
wait_for_ready=True)
print("Response: {}".format(response))
def main():
parser = argparse.ArgumentParser(description=_DESCRIPTION)
parser.add_argument(
'--channel_compression',
default='none',
nargs='?',
choices=_COMPRESSION_OPTIONS.keys(),
help='The compression method to use for the channel.')
parser.add_argument(
'--call_compression',
default='none',
nargs='?',
choices=_COMPRESSION_OPTIONS.keys(),
help='The compression method to use for an individual call.')
parser.add_argument(
'--server',
default='localhost:50051',
type=str,
nargs='?',
help='The host-port pair at which to reach the server.')
args = parser.parse_args()
channel_compression = _COMPRESSION_OPTIONS[args.channel_compression]
call_compression = _COMPRESSION_OPTIONS[args.call_compression]
run_client(channel_compression, call_compression, args.server)
if __name__ == "__main__":
logging.basicConfig()
main()

@ -0,0 +1,109 @@
# Copyright 2019 the gRPC authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""An example of compression on the server side with gRPC."""
from __future__ import absolute_import
from __future__ import division
from __future__ import print_function
from concurrent import futures
import argparse
import logging
import threading
import time
import grpc
from examples import helloworld_pb2
from examples import helloworld_pb2_grpc
_DESCRIPTION = 'A server capable of compression.'
_COMPRESSION_OPTIONS = {
"none": grpc.Compression.NoCompression,
"deflate": grpc.Compression.Deflate,
"gzip": grpc.Compression.Gzip,
}
_LOGGER = logging.getLogger(__name__)
_SERVER_HOST = 'localhost'
_ONE_DAY_IN_SECONDS = 60 * 60 * 24
class Greeter(helloworld_pb2_grpc.GreeterServicer):
def __init__(self, no_compress_every_n):
super(Greeter, self).__init__()
self._no_compress_every_n = 0
self._request_counter = 0
self._counter_lock = threading.RLock()
def _should_suppress_compression(self):
suppress_compression = False
with self._counter_lock:
if self._no_compress_every_n and self._request_counter % self._no_compress_every_n == 0:
suppress_compression = True
self._request_counter += 1
return suppress_compression
def SayHello(self, request, context):
if self._should_suppress_compression():
context.set_response_compression(grpc.Compression.NoCompression)
return helloworld_pb2.HelloReply(message='Hello, %s!' % request.name)
def run_server(server_compression, no_compress_every_n, port):
server = grpc.server(
futures.ThreadPoolExecutor(),
compression=server_compression,
options=(('grpc.so_reuseport', 1),))
helloworld_pb2_grpc.add_GreeterServicer_to_server(
Greeter(no_compress_every_n), server)
address = '{}:{}'.format(_SERVER_HOST, port)
server.add_insecure_port(address)
server.start()
print("Server listening at '{}'".format(address))
try:
while True:
time.sleep(_ONE_DAY_IN_SECONDS)
except KeyboardInterrupt:
server.stop(None)
def main():
parser = argparse.ArgumentParser(description=_DESCRIPTION)
parser.add_argument(
'--server_compression',
default='none',
nargs='?',
choices=_COMPRESSION_OPTIONS.keys(),
help='The default compression method for the server.')
parser.add_argument(
'--no_compress_every_n',
type=int,
default=0,
nargs='?',
help='If set, every nth reply will be uncompressed.')
parser.add_argument(
'--port',
type=int,
default=50051,
nargs='?',
help='The port on which the server will listen.')
args = parser.parse_args()
run_server(_COMPRESSION_OPTIONS[args.server_compression],
args.no_compress_every_n, args.port)
if __name__ == "__main__":
logging.basicConfig()
main()

@ -0,0 +1,62 @@
# Copyright 2019 the gRPC authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""Test for compression example."""
import contextlib
import os
import socket
import subprocess
import unittest
_BINARY_DIR = os.path.realpath(
os.path.join(os.path.dirname(os.path.abspath(__file__)), '..'))
_SERVER_PATH = os.path.join(_BINARY_DIR, 'server')
_CLIENT_PATH = os.path.join(_BINARY_DIR, 'client')
@contextlib.contextmanager
def _get_port():
sock = socket.socket(socket.AF_INET6, socket.SOCK_STREAM)
sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEPORT, 1)
if sock.getsockopt(socket.SOL_SOCKET, socket.SO_REUSEPORT) == 0:
raise RuntimeError("Failed to set SO_REUSEPORT.")
sock.bind(('', 0))
try:
yield sock.getsockname()[1]
finally:
sock.close()
class CompressionExampleTest(unittest.TestCase):
def test_compression_example(self):
with _get_port() as test_port:
server_process = subprocess.Popen((_SERVER_PATH, '--port',
str(test_port),
'--server_compression', 'gzip'))
try:
server_target = 'localhost:{}'.format(test_port)
client_process = subprocess.Popen(
(_CLIENT_PATH, '--server', server_target,
'--channel_compression', 'gzip'))
client_return_code = client_process.wait()
self.assertEqual(0, client_return_code)
self.assertIsNone(server_process.poll())
finally:
server_process.kill()
server_process.wait()
if __name__ == '__main__':
unittest.main(verbosity=2)

@ -36,7 +36,7 @@ py_binary(
"//src/python/grpcio/grpc:grpcio",
":prime_proto_pb2",
],
default_python_version = "PY3",
srcs_version = "PY3",
)
py_binary(
@ -50,7 +50,7 @@ py_binary(
"//conditions:default": [requirement("futures")],
"//:python3": [],
}),
default_python_version = "PY3",
srcs_version = "PY3",
)
py_test(

@ -87,7 +87,7 @@ def _reserve_port():
"""Find and reserve a port for all subprocesses to use."""
sock = socket.socket(socket.AF_INET6, socket.SOCK_STREAM)
sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEPORT, 1)
if sock.getsockopt(socket.SOL_SOCKET, socket.SO_REUSEPORT) != 1:
if sock.getsockopt(socket.SOL_SOCKET, socket.SO_REUSEPORT) == 0:
raise RuntimeError("Failed to set SO_REUSEPORT.")
sock.bind(('', 0))
try:

@ -23,7 +23,7 @@
Pod::Spec.new do |s|
s.name = 'gRPC-C++'
# TODO (mxyan): use version that match gRPC version when pod is stabilized
# version = '1.22.0-dev'
# version = '1.23.0-dev'
version = '0.0.9-dev'
s.version = version
s.summary = 'gRPC C++ library'
@ -31,7 +31,7 @@ Pod::Spec.new do |s|
s.license = 'Apache License, Version 2.0'
s.authors = { 'The gRPC contributors' => 'grpc-packages@google.com' }
grpc_version = '1.22.0-dev'
grpc_version = '1.23.0-dev'
s.source = {
:git => 'https://github.com/grpc/grpc.git',

@ -22,7 +22,7 @@
Pod::Spec.new do |s|
s.name = 'gRPC-Core'
version = '1.22.0-dev'
version = '1.23.0-dev'
s.version = version
s.summary = 'Core cross-platform gRPC library, written in C'
s.homepage = 'https://grpc.io'

@ -21,7 +21,7 @@
Pod::Spec.new do |s|
s.name = 'gRPC-ProtoRPC'
version = '1.22.0-dev'
version = '1.23.0-dev'
s.version = version
s.summary = 'RPC library for Protocol Buffers, based on gRPC'
s.homepage = 'https://grpc.io'

@ -21,7 +21,7 @@
Pod::Spec.new do |s|
s.name = 'gRPC-RxLibrary'
version = '1.22.0-dev'
version = '1.23.0-dev'
s.version = version
s.summary = 'Reactive Extensions library for iOS/OSX.'
s.homepage = 'https://grpc.io'

@ -20,7 +20,7 @@
Pod::Spec.new do |s|
s.name = 'gRPC'
version = '1.22.0-dev'
version = '1.23.0-dev'
s.version = version
s.summary = 'gRPC client library for iOS/OSX'
s.homepage = 'https://grpc.io'

@ -13,7 +13,7 @@ Gem::Specification.new do |s|
s.description = 'Send RPCs from Ruby using GRPC'
s.license = 'Apache-2.0'
s.required_ruby_version = '>= 2.0.0'
s.required_ruby_version = '>= 2.3.0'
s.files = %w( Makefile .yardopts )
s.files += %w( etc/roots.pem )

@ -19,6 +19,7 @@
#ifndef GRPCPP_IMPL_CODEGEN_CLIENT_CALLBACK_H
#define GRPCPP_IMPL_CODEGEN_CLIENT_CALLBACK_H
#include <atomic>
#include <functional>
#include <grpcpp/impl/codegen/call.h>
@ -419,7 +420,8 @@ class ClientCallbackReaderWriterImpl
static void operator delete(void*, void*) { assert(0); }
void MaybeFinish() {
if (--callbacks_outstanding_ == 0) {
if (GPR_UNLIKELY(callbacks_outstanding_.fetch_sub(
1, std::memory_order_acq_rel) == 1)) {
Status s = std::move(finish_status_);
auto* reactor = reactor_;
auto* call = call_.call();
@ -489,7 +491,7 @@ class ClientCallbackReaderWriterImpl
void Read(Response* msg) override {
read_ops_.RecvMessage(msg);
callbacks_outstanding_++;
callbacks_outstanding_.fetch_add(1, std::memory_order_relaxed);
if (started_) {
call_.PerformOps(&read_ops_);
} else {
@ -510,7 +512,7 @@ class ClientCallbackReaderWriterImpl
}
// TODO(vjpai): don't assert
GPR_CODEGEN_ASSERT(write_ops_.SendMessagePtr(msg, options).ok());
callbacks_outstanding_++;
callbacks_outstanding_.fetch_add(1, std::memory_order_relaxed);
if (started_) {
call_.PerformOps(&write_ops_);
} else {
@ -531,7 +533,7 @@ class ClientCallbackReaderWriterImpl
},
&writes_done_ops_);
writes_done_ops_.set_core_cq_tag(&writes_done_tag_);
callbacks_outstanding_++;
callbacks_outstanding_.fetch_add(1, std::memory_order_relaxed);
if (started_) {
call_.PerformOps(&writes_done_ops_);
} else {
@ -539,8 +541,10 @@ class ClientCallbackReaderWriterImpl
}
}
virtual void AddHold(int holds) override { callbacks_outstanding_ += holds; }
virtual void RemoveHold() override { MaybeFinish(); }
void AddHold(int holds) override {
callbacks_outstanding_.fetch_add(holds, std::memory_order_relaxed);
}
void RemoveHold() override { MaybeFinish(); }
private:
friend class ClientCallbackReaderWriterFactory<Request, Response>;
@ -581,7 +585,7 @@ class ClientCallbackReaderWriterImpl
bool read_ops_at_start_{false};
// Minimum of 2 callbacks to pre-register for start and finish
std::atomic_int callbacks_outstanding_{2};
std::atomic<intptr_t> callbacks_outstanding_{2};
bool started_{false};
};
@ -619,7 +623,8 @@ class ClientCallbackReaderImpl
static void operator delete(void*, void*) { assert(0); }
void MaybeFinish() {
if (--callbacks_outstanding_ == 0) {
if (GPR_UNLIKELY(callbacks_outstanding_.fetch_sub(
1, std::memory_order_acq_rel) == 1)) {
Status s = std::move(finish_status_);
auto* reactor = reactor_;
auto* call = call_.call();
@ -669,7 +674,7 @@ class ClientCallbackReaderImpl
void Read(Response* msg) override {
read_ops_.RecvMessage(msg);
callbacks_outstanding_++;
callbacks_outstanding_.fetch_add(1, std::memory_order_relaxed);
if (started_) {
call_.PerformOps(&read_ops_);
} else {
@ -677,8 +682,10 @@ class ClientCallbackReaderImpl
}
}
virtual void AddHold(int holds) override { callbacks_outstanding_ += holds; }
virtual void RemoveHold() override { MaybeFinish(); }
void AddHold(int holds) override {
callbacks_outstanding_.fetch_add(holds, std::memory_order_relaxed);
}
void RemoveHold() override { MaybeFinish(); }
private:
friend class ClientCallbackReaderFactory<Response>;
@ -712,7 +719,7 @@ class ClientCallbackReaderImpl
bool read_ops_at_start_{false};
// Minimum of 2 callbacks to pre-register for start and finish
std::atomic_int callbacks_outstanding_{2};
std::atomic<intptr_t> callbacks_outstanding_{2};
bool started_{false};
};
@ -750,7 +757,8 @@ class ClientCallbackWriterImpl
static void operator delete(void*, void*) { assert(0); }
void MaybeFinish() {
if (--callbacks_outstanding_ == 0) {
if (GPR_UNLIKELY(callbacks_outstanding_.fetch_sub(
1, std::memory_order_acq_rel) == 1)) {
Status s = std::move(finish_status_);
auto* reactor = reactor_;
auto* call = call_.call();
@ -819,7 +827,7 @@ class ClientCallbackWriterImpl
}
// TODO(vjpai): don't assert
GPR_CODEGEN_ASSERT(write_ops_.SendMessagePtr(msg, options).ok());
callbacks_outstanding_++;
callbacks_outstanding_.fetch_add(1, std::memory_order_relaxed);
if (started_) {
call_.PerformOps(&write_ops_);
} else {
@ -840,7 +848,7 @@ class ClientCallbackWriterImpl
},
&writes_done_ops_);
writes_done_ops_.set_core_cq_tag(&writes_done_tag_);
callbacks_outstanding_++;
callbacks_outstanding_.fetch_add(1, std::memory_order_relaxed);
if (started_) {
call_.PerformOps(&writes_done_ops_);
} else {
@ -848,8 +856,10 @@ class ClientCallbackWriterImpl
}
}
virtual void AddHold(int holds) override { callbacks_outstanding_ += holds; }
virtual void RemoveHold() override { MaybeFinish(); }
void AddHold(int holds) override {
callbacks_outstanding_.fetch_add(holds, std::memory_order_relaxed);
}
void RemoveHold() override { MaybeFinish(); }
private:
friend class ClientCallbackWriterFactory<Request>;
@ -889,7 +899,7 @@ class ClientCallbackWriterImpl
bool writes_done_ops_at_start_{false};
// Minimum of 2 callbacks to pre-register for start and finish
std::atomic_int callbacks_outstanding_{2};
std::atomic<intptr_t> callbacks_outstanding_{2};
bool started_{false};
};
@ -951,7 +961,8 @@ class ClientCallbackUnaryImpl final
}
void MaybeFinish() {
if (--callbacks_outstanding_ == 0) {
if (GPR_UNLIKELY(callbacks_outstanding_.fetch_sub(
1, std::memory_order_acq_rel) == 1)) {
Status s = std::move(finish_status_);
auto* reactor = reactor_;
auto* call = call_.call();
@ -991,7 +1002,7 @@ class ClientCallbackUnaryImpl final
Status finish_status_;
// This call will have 2 callbacks: start and finish
std::atomic_int callbacks_outstanding_{2};
std::atomic<intptr_t> callbacks_outstanding_{2};
bool started_{false};
};

@ -68,13 +68,13 @@ class ServerReactor {
// remain unmet.
void MaybeCallOnCancel() {
if (on_cancel_conditions_remaining_.fetch_sub(
1, std::memory_order_acq_rel) == 1) {
if (GPR_UNLIKELY(on_cancel_conditions_remaining_.fetch_sub(
1, std::memory_order_acq_rel) == 1)) {
OnCancel();
}
}
std::atomic_int on_cancel_conditions_remaining_{2};
std::atomic<intptr_t> on_cancel_conditions_remaining_{2};
};
template <class Request, class Response>
@ -174,7 +174,7 @@ class ServerCallbackReader {
protected:
template <class Response>
void BindReactor(ServerReadReactor<Request, Response>* reactor) {
reactor->BindReader(this);
reactor->InternalBindReader(this);
}
};
@ -196,7 +196,7 @@ class ServerCallbackWriter {
protected:
template <class Request>
void BindReactor(ServerWriteReactor<Request, Response>* reactor) {
reactor->BindWriter(this);
reactor->InternalBindWriter(this);
}
};
@ -218,7 +218,7 @@ class ServerCallbackReaderWriter {
protected:
void BindReactor(ServerBidiReactor<Request, Response>* reactor) {
reactor->BindStream(this);
reactor->InternalBindStream(this);
}
};
@ -348,7 +348,9 @@ class ServerBidiReactor : public internal::ServerReactor {
private:
friend class ServerCallbackReaderWriter<Request, Response>;
virtual void BindStream(
// May be overridden by internal implementation details. This is not a public
// customization point.
virtual void InternalBindStream(
ServerCallbackReaderWriter<Request, Response>* stream) {
stream_ = stream;
}
@ -383,7 +385,9 @@ class ServerReadReactor : public internal::ServerReactor {
private:
friend class ServerCallbackReader<Request>;
virtual void BindReader(ServerCallbackReader<Request>* reader) {
// May be overridden by internal implementation details. This is not a public
// customization point.
virtual void InternalBindReader(ServerCallbackReader<Request>* reader) {
reader_ = reader;
}
@ -427,7 +431,9 @@ class ServerWriteReactor : public internal::ServerReactor {
private:
friend class ServerCallbackWriter<Response>;
virtual void BindWriter(ServerCallbackWriter<Response>* writer) {
// May be overridden by internal implementation details. This is not a public
// customization point.
virtual void InternalBindWriter(ServerCallbackWriter<Response>* writer) {
writer_ = writer;
}
@ -568,7 +574,7 @@ class CallbackUnaryHandler : public MethodHandler {
void SendInitialMetadata(std::function<void(bool)> f) override {
GPR_CODEGEN_ASSERT(!ctx_->sent_initial_metadata_);
callbacks_outstanding_++;
callbacks_outstanding_.fetch_add(1, std::memory_order_relaxed);
// TODO(vjpai): Consider taking f as a move-capture if we adopt C++14
// and if performance of this operation matters
meta_tag_.Set(call_.call(),
@ -618,7 +624,8 @@ class CallbackUnaryHandler : public MethodHandler {
ResponseType* response() { return allocator_state_->response(); }
void MaybeDone() {
if (--callbacks_outstanding_ == 0) {
if (GPR_UNLIKELY(callbacks_outstanding_.fetch_sub(
1, std::memory_order_acq_rel) == 1)) {
grpc_call* call = call_.call();
auto call_requester = std::move(call_requester_);
allocator_state_->Release();
@ -640,7 +647,7 @@ class CallbackUnaryHandler : public MethodHandler {
experimental::MessageHolder<RequestType, ResponseType>* const
allocator_state_;
std::function<void()> call_requester_;
std::atomic_int callbacks_outstanding_{
std::atomic<intptr_t> callbacks_outstanding_{
2}; // reserve for Finish and CompletionOp
};
};
@ -712,7 +719,7 @@ class CallbackClientStreamingHandler : public MethodHandler {
void SendInitialMetadata() override {
GPR_CODEGEN_ASSERT(!ctx_->sent_initial_metadata_);
callbacks_outstanding_++;
callbacks_outstanding_.fetch_add(1, std::memory_order_relaxed);
meta_tag_.Set(call_.call(),
[this](bool ok) {
reactor_->OnSendInitialMetadataDone(ok);
@ -730,7 +737,7 @@ class CallbackClientStreamingHandler : public MethodHandler {
}
void Read(RequestType* req) override {
callbacks_outstanding_++;
callbacks_outstanding_.fetch_add(1, std::memory_order_relaxed);
read_ops_.RecvMessage(req);
call_.PerformOps(&read_ops_);
}
@ -761,7 +768,8 @@ class CallbackClientStreamingHandler : public MethodHandler {
ResponseType* response() { return &resp_; }
void MaybeDone() {
if (--callbacks_outstanding_ == 0) {
if (GPR_UNLIKELY(callbacks_outstanding_.fetch_sub(
1, std::memory_order_acq_rel) == 1)) {
reactor_->OnDone();
grpc_call* call = call_.call();
auto call_requester = std::move(call_requester_);
@ -785,7 +793,7 @@ class CallbackClientStreamingHandler : public MethodHandler {
ResponseType resp_;
std::function<void()> call_requester_;
experimental::ServerReadReactor<RequestType, ResponseType>* reactor_;
std::atomic_int callbacks_outstanding_{
std::atomic<intptr_t> callbacks_outstanding_{
3}; // reserve for OnStarted, Finish, and CompletionOp
};
};
@ -867,7 +875,7 @@ class CallbackServerStreamingHandler : public MethodHandler {
void SendInitialMetadata() override {
GPR_CODEGEN_ASSERT(!ctx_->sent_initial_metadata_);
callbacks_outstanding_++;
callbacks_outstanding_.fetch_add(1, std::memory_order_relaxed);
meta_tag_.Set(call_.call(),
[this](bool ok) {
reactor_->OnSendInitialMetadataDone(ok);
@ -885,7 +893,7 @@ class CallbackServerStreamingHandler : public MethodHandler {
}
void Write(const ResponseType* resp, WriteOptions options) override {
callbacks_outstanding_++;
callbacks_outstanding_.fetch_add(1, std::memory_order_relaxed);
if (options.is_last_message()) {
options.set_buffer_hint();
}
@ -939,7 +947,8 @@ class CallbackServerStreamingHandler : public MethodHandler {
const RequestType* request() { return req_; }
void MaybeDone() {
if (--callbacks_outstanding_ == 0) {
if (GPR_UNLIKELY(callbacks_outstanding_.fetch_sub(
1, std::memory_order_acq_rel) == 1)) {
reactor_->OnDone();
grpc_call* call = call_.call();
auto call_requester = std::move(call_requester_);
@ -963,7 +972,7 @@ class CallbackServerStreamingHandler : public MethodHandler {
const RequestType* req_;
std::function<void()> call_requester_;
experimental::ServerWriteReactor<RequestType, ResponseType>* reactor_;
std::atomic_int callbacks_outstanding_{
std::atomic<intptr_t> callbacks_outstanding_{
3}; // reserve for OnStarted, Finish, and CompletionOp
};
};
@ -1031,7 +1040,7 @@ class CallbackBidiHandler : public MethodHandler {
void SendInitialMetadata() override {
GPR_CODEGEN_ASSERT(!ctx_->sent_initial_metadata_);
callbacks_outstanding_++;
callbacks_outstanding_.fetch_add(1, std::memory_order_relaxed);
meta_tag_.Set(call_.call(),
[this](bool ok) {
reactor_->OnSendInitialMetadataDone(ok);
@ -1049,7 +1058,7 @@ class CallbackBidiHandler : public MethodHandler {
}
void Write(const ResponseType* resp, WriteOptions options) override {
callbacks_outstanding_++;
callbacks_outstanding_.fetch_add(1, std::memory_order_relaxed);
if (options.is_last_message()) {
options.set_buffer_hint();
}
@ -1077,7 +1086,7 @@ class CallbackBidiHandler : public MethodHandler {
}
void Read(RequestType* req) override {
callbacks_outstanding_++;
callbacks_outstanding_.fetch_add(1, std::memory_order_relaxed);
read_ops_.RecvMessage(req);
call_.PerformOps(&read_ops_);
}
@ -1112,7 +1121,8 @@ class CallbackBidiHandler : public MethodHandler {
~ServerCallbackReaderWriterImpl() {}
void MaybeDone() {
if (--callbacks_outstanding_ == 0) {
if (GPR_UNLIKELY(callbacks_outstanding_.fetch_sub(
1, std::memory_order_acq_rel) == 1)) {
reactor_->OnDone();
grpc_call* call = call_.call();
auto call_requester = std::move(call_requester_);
@ -1137,7 +1147,7 @@ class CallbackBidiHandler : public MethodHandler {
Call call_;
std::function<void()> call_requester_;
experimental::ServerBidiReactor<RequestType, ResponseType>* reactor_;
std::atomic_int callbacks_outstanding_{
std::atomic<intptr_t> callbacks_outstanding_{
3}; // reserve for OnStarted, Finish, and CompletionOp
};
};

@ -98,9 +98,7 @@ class ServerRpcInfo {
ServerRpcInfo(grpc_impl::ServerContext* ctx, const char* method,
internal::RpcMethod::RpcType type)
: ctx_(ctx), method_(method), type_(static_cast<Type>(type)) {
ref_.store(1);
}
: ctx_(ctx), method_(method), type_(static_cast<Type>(type)) {}
// Runs interceptor at pos \a pos.
void RunInterceptor(
@ -122,9 +120,9 @@ class ServerRpcInfo {
}
}
void Ref() { ref_++; }
void Ref() { ref_.fetch_add(1, std::memory_order_relaxed); }
void Unref() {
if (--ref_ == 0) {
if (GPR_UNLIKELY(ref_.fetch_sub(1, std::memory_order_acq_rel) == 1)) {
delete this;
}
}
@ -132,7 +130,7 @@ class ServerRpcInfo {
grpc_impl::ServerContext* ctx_ = nullptr;
const char* method_ = nullptr;
const Type type_;
std::atomic_int ref_;
std::atomic<intptr_t> ref_{1};
std::vector<std::unique_ptr<experimental::Interceptor>> interceptors_;
friend class internal::InterceptorBatchMethodsImpl;

@ -342,7 +342,7 @@ class Server : public grpc::ServerInterface, private grpc::GrpcLibraryCodegen {
// during decreasing load, so it is less performance-critical.
grpc::internal::Mutex callback_reqs_mu_;
grpc::internal::CondVar callback_reqs_done_cv_;
std::atomic_int callback_reqs_outstanding_{0};
std::atomic<intptr_t> callback_reqs_outstanding_{0};
std::shared_ptr<GlobalCallbacks> global_callbacks_;

@ -13,8 +13,8 @@
<date>2018-01-19</date>
<time>16:06:07</time>
<version>
<release>1.22.0dev</release>
<api>1.22.0dev</api>
<release>1.23.0dev</release>
<api>1.23.0dev</api>
</version>
<stability>
<release>beta</release>

@ -161,9 +161,7 @@ class GrpcLb : public LoadBalancingPolicy {
bool seen_serverlist() const { return seen_serverlist_; }
private:
// So Delete() can access our private dtor.
template <typename T>
friend void grpc_core::Delete(T*);
GRPC_ALLOW_CLASS_TO_USE_NON_PUBLIC_DELETE
~BalancerCallState();

@ -128,6 +128,10 @@ class PickFirst : public LoadBalancingPolicy {
void ShutdownLocked() override;
void AttemptToConnectUsingLatestUpdateArgsLocked();
// Lateset update args.
UpdateArgs latest_update_args_;
// All our subchannels.
OrphanablePtr<PickFirstSubchannelList> subchannel_list_;
// Latest pending subchannel list.
@ -167,18 +171,7 @@ void PickFirst::ExitIdleLocked() {
if (shutdown_) return;
if (idle_) {
idle_ = false;
if (subchannel_list_ == nullptr ||
subchannel_list_->num_subchannels() == 0) {
grpc_error* error = grpc_error_set_int(
GRPC_ERROR_CREATE_FROM_STATIC_STRING("No addresses to connect to"),
GRPC_ERROR_INT_GRPC_STATUS, GRPC_STATUS_UNAVAILABLE);
channel_control_helper()->UpdateState(
GRPC_CHANNEL_TRANSIENT_FAILURE,
UniquePtr<SubchannelPicker>(New<TransientFailurePicker>(error)));
} else {
subchannel_list_->subchannel(0)
->CheckConnectivityStateAndStartWatchingLocked();
}
AttemptToConnectUsingLatestUpdateArgsLocked();
}
}
@ -189,36 +182,26 @@ void PickFirst::ResetBackoffLocked() {
}
}
void PickFirst::UpdateLocked(UpdateArgs args) {
if (GRPC_TRACE_FLAG_ENABLED(grpc_lb_pick_first_trace)) {
gpr_log(GPR_INFO,
"Pick First %p received update with %" PRIuPTR " addresses", this,
args.addresses.size());
}
grpc_arg new_arg = grpc_channel_arg_integer_create(
const_cast<char*>(GRPC_ARG_INHIBIT_HEALTH_CHECKING), 1);
grpc_channel_args* new_args =
grpc_channel_args_copy_and_add(args.args, &new_arg, 1);
void PickFirst::AttemptToConnectUsingLatestUpdateArgsLocked() {
// Create a subchannel list from the latest_update_args_.
auto subchannel_list = MakeOrphanable<PickFirstSubchannelList>(
this, &grpc_lb_pick_first_trace, args.addresses, combiner(), *new_args);
grpc_channel_args_destroy(new_args);
this, &grpc_lb_pick_first_trace, latest_update_args_.addresses,
combiner(), *latest_update_args_.args);
// Empty update or no valid subchannels.
if (subchannel_list->num_subchannels() == 0) {
// Empty update or no valid subchannels. Unsubscribe from all current
// subchannels.
// Unsubscribe from all current subchannels.
subchannel_list_ = std::move(subchannel_list); // Empty list.
selected_ = nullptr;
// If not idle, put the channel in TRANSIENT_FAILURE.
// (If we are idle, then this will happen in ExitIdleLocked() if we
// haven't gotten a non-empty update by the time the application tries
// to start a new call.)
if (!idle_) {
grpc_error* error = grpc_error_set_int(
GRPC_ERROR_CREATE_FROM_STATIC_STRING("Empty update"),
GRPC_ERROR_INT_GRPC_STATUS, GRPC_STATUS_UNAVAILABLE);
channel_control_helper()->UpdateState(
GRPC_CHANNEL_TRANSIENT_FAILURE,
UniquePtr<SubchannelPicker>(New<TransientFailurePicker>(error)));
}
grpc_error* error =
grpc_error_set_int(GRPC_ERROR_CREATE_FROM_STATIC_STRING("Empty update"),
GRPC_ERROR_INT_GRPC_STATUS, GRPC_STATUS_UNAVAILABLE);
channel_control_helper()->UpdateState(
GRPC_CHANNEL_TRANSIENT_FAILURE,
UniquePtr<SubchannelPicker>(New<TransientFailurePicker>(error)));
return;
}
// If one of the subchannels in the new list is already in state
@ -226,8 +209,6 @@ void PickFirst::UpdateLocked(UpdateArgs args) {
// currently selected subchannel is also present in the update. It
// can also happen if one of the subchannels in the update is already
// in the global subchannel pool because it's in use by another channel.
// TODO(roth): If we're in IDLE state, we should probably defer this
// check and instead do it in ExitIdleLocked().
for (size_t i = 0; i < subchannel_list->num_subchannels(); ++i) {
PickFirstSubchannelData* sd = subchannel_list->subchannel(i);
grpc_connectivity_state state = sd->CheckConnectivityStateLocked();
@ -239,10 +220,6 @@ void PickFirst::UpdateLocked(UpdateArgs args) {
// not have contained the currently selected subchannel), drop
// it, so that it doesn't override what we've done here.
latest_pending_subchannel_list_.reset();
// Make sure that subsequent calls to ExitIdleLocked() don't cause
// us to start watching a subchannel other than the one we've
// selected.
idle_ = false;
return;
}
}
@ -252,13 +229,11 @@ void PickFirst::UpdateLocked(UpdateArgs args) {
subchannel_list_ = std::move(subchannel_list);
// If we're not in IDLE state, start trying to connect to the first
// subchannel in the new list.
if (!idle_) {
// Note: No need to use CheckConnectivityStateAndStartWatchingLocked()
// here, since we've already checked the initial connectivity
// state of all subchannels above.
subchannel_list_->subchannel(0)->StartConnectivityWatchLocked();
subchannel_list_->subchannel(0)->subchannel()->AttemptToConnect();
}
// Note: No need to use CheckConnectivityStateAndStartWatchingLocked()
// here, since we've already checked the initial connectivity
// state of all subchannels above.
subchannel_list_->subchannel(0)->StartConnectivityWatchLocked();
subchannel_list_->subchannel(0)->subchannel()->AttemptToConnect();
} else {
// We do have a selected subchannel (which means it's READY), so keep
// using it until one of the subchannels in the new list reports READY.
@ -274,16 +249,35 @@ void PickFirst::UpdateLocked(UpdateArgs args) {
latest_pending_subchannel_list_ = std::move(subchannel_list);
// If we're not in IDLE state, start trying to connect to the first
// subchannel in the new list.
if (!idle_) {
// Note: No need to use CheckConnectivityStateAndStartWatchingLocked()
// here, since we've already checked the initial connectivity
// state of all subchannels above.
latest_pending_subchannel_list_->subchannel(0)
->StartConnectivityWatchLocked();
latest_pending_subchannel_list_->subchannel(0)
->subchannel()
->AttemptToConnect();
}
// Note: No need to use CheckConnectivityStateAndStartWatchingLocked()
// here, since we've already checked the initial connectivity
// state of all subchannels above.
latest_pending_subchannel_list_->subchannel(0)
->StartConnectivityWatchLocked();
latest_pending_subchannel_list_->subchannel(0)
->subchannel()
->AttemptToConnect();
}
}
void PickFirst::UpdateLocked(UpdateArgs args) {
if (GRPC_TRACE_FLAG_ENABLED(grpc_lb_pick_first_trace)) {
gpr_log(GPR_INFO,
"Pick First %p received update with %" PRIuPTR " addresses", this,
args.addresses.size());
}
// Update the latest_update_args_
grpc_arg new_arg = grpc_channel_arg_integer_create(
const_cast<char*>(GRPC_ARG_INHIBIT_HEALTH_CHECKING), 1);
const grpc_channel_args* new_args =
grpc_channel_args_copy_and_add(args.args, &new_arg, 1);
GPR_SWAP(const grpc_channel_args*, new_args, args.args);
grpc_channel_args_destroy(new_args);
latest_update_args_ = std::move(args);
// If we are not in idle, start connection attempt immediately.
// Otherwise, we defer the attempt into ExitIdleLocked().
if (!idle_) {
AttemptToConnectUsingLatestUpdateArgsLocked();
}
}
@ -338,10 +332,12 @@ void PickFirst::PickFirstSubchannelData::ProcessConnectivityChangeLocked(
// also set the channel state to IDLE. The reason is that if the new
// state is TRANSIENT_FAILURE due to a GOAWAY reception we don't want
// to connect to the re-resolved backends until we leave IDLE state.
// TODO(qianchengz): We may want to request re-resolution in
// ExitIdleLocked().
p->idle_ = true;
p->channel_control_helper()->RequestReresolution();
p->selected_ = nullptr;
CancelConnectivityWatchLocked("selected subchannel failed; going IDLE");
p->subchannel_list_.reset();
p->channel_control_helper()->UpdateState(
GRPC_CHANNEL_IDLE, UniquePtr<SubchannelPicker>(New<QueuePicker>(
p->Ref(DEBUG_LOCATION, "QueuePicker"))));
@ -454,6 +450,11 @@ void PickFirst::PickFirstSubchannelData::ProcessUnselectedReadyLocked() {
if (GRPC_TRACE_FLAG_ENABLED(grpc_lb_pick_first_trace)) {
gpr_log(GPR_INFO, "Pick First %p selected subchannel %p", p, subchannel());
}
for (size_t i = 0; i < subchannel_list()->num_subchannels(); ++i) {
if (i != Index()) {
subchannel_list()->subchannel(i)->ShutdownLocked();
}
}
}
void PickFirst::PickFirstSubchannelData::

@ -185,9 +185,7 @@ class XdsLb : public LoadBalancingPolicy {
bool seen_initial_response() const { return seen_initial_response_; }
private:
// So Delete() can access our private dtor.
template <typename T>
friend void grpc_core::Delete(T*);
GRPC_ALLOW_CLASS_TO_USE_NON_PUBLIC_DELETE
~BalancerCallState();

@ -21,6 +21,7 @@
#include <grpc/support/port_platform.h>
#include "src/core/lib/gprpp/memory.h"
#include "src/core/lib/gprpp/ref_counted.h"
namespace grpc_core {
@ -42,9 +43,7 @@ class ServerRetryThrottleData : public RefCounted<ServerRetryThrottleData> {
intptr_t milli_token_ratio() const { return milli_token_ratio_; }
private:
// So Delete() can call our private dtor.
template <typename T>
friend void grpc_core::Delete(T*);
GRPC_ALLOW_CLASS_TO_USE_NON_PUBLIC_DELETE
~ServerRetryThrottleData();

@ -558,7 +558,7 @@ static grpc_slice user_agent_from_args(const grpc_channel_args* args,
tmp = gpr_strvec_flatten(&v, nullptr);
gpr_strvec_destroy(&v);
result = grpc_slice_intern(grpc_slice_from_static_string(tmp));
result = grpc_slice_intern(grpc_slice_from_static_string_internal(tmp));
gpr_free(tmp);
return result;

@ -101,8 +101,8 @@ grpc_error* init_channel_elem(grpc_channel_element* elem,
return GRPC_ERROR_CREATE_FROM_STATIC_STRING(
"GRPC_ARG_DEFAULT_AUTHORITY channel arg. must be a string");
}
chand->default_authority =
grpc_slice_intern(grpc_slice_from_static_string(default_authority_str));
chand->default_authority = grpc_slice_intern(
grpc_slice_from_static_string_internal(default_authority_str));
chand->default_authority_mdelem = grpc_mdelem_create(
GRPC_MDSTR_AUTHORITY, chand->default_authority, nullptr);
GPR_ASSERT(!args->is_last);

@ -45,18 +45,30 @@ static void send_message_on_complete(void* arg, grpc_error* error);
static void on_send_message_next_done(void* arg, grpc_error* error);
namespace {
enum initial_metadata_state {
// Initial metadata not yet seen.
INITIAL_METADATA_UNSEEN = 0,
// Initial metadata seen; compression algorithm set.
HAS_COMPRESSION_ALGORITHM,
// Initial metadata seen; no compression algorithm set.
NO_COMPRESSION_ALGORITHM,
struct channel_data {
/** The default, channel-level, compression algorithm */
grpc_compression_algorithm default_compression_algorithm;
/** Bitset of enabled compression algorithms */
uint32_t enabled_compression_algorithms_bitset;
/** Bitset of enabled message compression algorithms */
uint32_t enabled_message_compression_algorithms_bitset;
/** Bitset of enabled stream compression algorithms */
uint32_t enabled_stream_compression_algorithms_bitset;
};
struct call_data {
call_data(grpc_call_element* elem, const grpc_call_element_args& args)
: call_combiner(args.call_combiner) {
channel_data* channeld = static_cast<channel_data*>(elem->channel_data);
// The call's message compression algorithm is set to channel's default
// setting. It can be overridden later by initial metadata.
if (GPR_LIKELY(GPR_BITGET(channeld->enabled_compression_algorithms_bitset,
channeld->default_compression_algorithm))) {
message_compression_algorithm =
grpc_compression_algorithm_to_message_compression_algorithm(
channeld->default_compression_algorithm);
}
GRPC_CLOSURE_INIT(&start_send_message_batch_in_call_combiner,
start_send_message_batch, elem,
grpc_schedule_on_exec_ctx);
@ -73,15 +85,13 @@ struct call_data {
}
grpc_core::CallCombiner* call_combiner;
grpc_linked_mdelem compression_algorithm_storage;
grpc_linked_mdelem message_compression_algorithm_storage;
grpc_linked_mdelem stream_compression_algorithm_storage;
grpc_linked_mdelem accept_encoding_storage;
grpc_linked_mdelem accept_stream_encoding_storage;
/** Compression algorithm we'll try to use. It may be given by incoming
* metadata, or by the channel's default compression settings. */
grpc_message_compression_algorithm message_compression_algorithm =
GRPC_MESSAGE_COMPRESS_NONE;
initial_metadata_state send_initial_metadata_state = INITIAL_METADATA_UNSEEN;
bool seen_initial_metadata = false;
grpc_error* cancel_error = GRPC_ERROR_NONE;
grpc_closure start_send_message_batch_in_call_combiner;
grpc_transport_stream_op_batch* send_message_batch = nullptr;
@ -93,130 +103,104 @@ struct call_data {
grpc_closure on_send_message_next_done;
};
struct channel_data {
/** The default, channel-level, compression algorithm */
grpc_compression_algorithm default_compression_algorithm;
/** Bitset of enabled compression algorithms */
uint32_t enabled_algorithms_bitset;
/** Supported compression algorithms */
uint32_t supported_message_compression_algorithms;
/** Supported stream compression algorithms */
uint32_t supported_stream_compression_algorithms;
};
} // namespace
static bool skip_compression(grpc_call_element* elem, uint32_t flags,
bool has_compression_algorithm) {
// Returns true if we should skip message compression for the current message.
static bool skip_message_compression(grpc_call_element* elem) {
call_data* calld = static_cast<call_data*>(elem->call_data);
channel_data* channeld = static_cast<channel_data*>(elem->channel_data);
// If the flags of this message indicate that it shouldn't be compressed, we
// skip message compression.
uint32_t flags =
calld->send_message_batch->payload->send_message.send_message->flags();
if (flags & (GRPC_WRITE_NO_COMPRESS | GRPC_WRITE_INTERNAL_COMPRESS)) {
return true;
}
if (has_compression_algorithm) {
if (calld->message_compression_algorithm == GRPC_MESSAGE_COMPRESS_NONE) {
return true;
}
return false; /* we have an actual call-specific algorithm */
// If this call doesn't have any message compression algorithm set, skip
// message compression.
return calld->message_compression_algorithm == GRPC_MESSAGE_COMPRESS_NONE;
}
// Determines the compression algorithm from the initial metadata and the
// channel's default setting.
static grpc_compression_algorithm find_compression_algorithm(
grpc_metadata_batch* initial_metadata, channel_data* channeld) {
if (initial_metadata->idx.named.grpc_internal_encoding_request == nullptr) {
return channeld->default_compression_algorithm;
}
/* no per-call compression override */
return channeld->default_compression_algorithm == GRPC_COMPRESS_NONE;
grpc_compression_algorithm compression_algorithm;
// Parse the compression algorithm from the initial metadata.
grpc_mdelem md =
initial_metadata->idx.named.grpc_internal_encoding_request->md;
GPR_ASSERT(grpc_compression_algorithm_parse(GRPC_MDVALUE(md),
&compression_algorithm));
// Remove this metadata since it's an internal one (i.e., it won't be
// transmitted out).
grpc_metadata_batch_remove(
initial_metadata,
initial_metadata->idx.named.grpc_internal_encoding_request);
// Check if that algorithm is enabled. Note that GRPC_COMPRESS_NONE is always
// enabled.
// TODO(juanlishen): Maybe use channel default or abort() if the algorithm
// from the initial metadata is disabled.
if (GPR_LIKELY(GPR_BITGET(channeld->enabled_compression_algorithms_bitset,
compression_algorithm))) {
return compression_algorithm;
}
const char* algorithm_name;
GPR_ASSERT(
grpc_compression_algorithm_name(compression_algorithm, &algorithm_name));
gpr_log(GPR_ERROR,
"Invalid compression algorithm from initial metadata: '%s' "
"(previously disabled). "
"Will not compress.",
algorithm_name);
return GRPC_COMPRESS_NONE;
}
/** Filter initial metadata */
static grpc_error* process_send_initial_metadata(
grpc_call_element* elem, grpc_metadata_batch* initial_metadata,
bool* has_compression_algorithm) GRPC_MUST_USE_RESULT;
grpc_call_element* elem,
grpc_metadata_batch* initial_metadata) GRPC_MUST_USE_RESULT;
static grpc_error* process_send_initial_metadata(
grpc_call_element* elem, grpc_metadata_batch* initial_metadata,
bool* has_compression_algorithm) {
grpc_call_element* elem, grpc_metadata_batch* initial_metadata) {
call_data* calld = static_cast<call_data*>(elem->call_data);
channel_data* channeld = static_cast<channel_data*>(elem->channel_data);
*has_compression_algorithm = false;
grpc_compression_algorithm compression_algorithm;
// Find the compression algorithm.
grpc_compression_algorithm compression_algorithm =
find_compression_algorithm(initial_metadata, channeld);
// Note that at most one of the following algorithms can be set.
calld->message_compression_algorithm =
grpc_compression_algorithm_to_message_compression_algorithm(
compression_algorithm);
grpc_stream_compression_algorithm stream_compression_algorithm =
GRPC_STREAM_COMPRESS_NONE;
if (initial_metadata->idx.named.grpc_internal_encoding_request != nullptr) {
grpc_mdelem md =
initial_metadata->idx.named.grpc_internal_encoding_request->md;
if (GPR_UNLIKELY(!grpc_compression_algorithm_parse(
GRPC_MDVALUE(md), &compression_algorithm))) {
char* val = grpc_slice_to_c_string(GRPC_MDVALUE(md));
gpr_log(GPR_ERROR,
"Invalid compression algorithm: '%s' (unknown). Ignoring.", val);
gpr_free(val);
calld->message_compression_algorithm = GRPC_MESSAGE_COMPRESS_NONE;
stream_compression_algorithm = GRPC_STREAM_COMPRESS_NONE;
}
if (GPR_UNLIKELY(!GPR_BITGET(channeld->enabled_algorithms_bitset,
compression_algorithm))) {
char* val = grpc_slice_to_c_string(GRPC_MDVALUE(md));
gpr_log(GPR_ERROR,
"Invalid compression algorithm: '%s' (previously disabled). "
"Ignoring.",
val);
gpr_free(val);
calld->message_compression_algorithm = GRPC_MESSAGE_COMPRESS_NONE;
stream_compression_algorithm = GRPC_STREAM_COMPRESS_NONE;
}
*has_compression_algorithm = true;
grpc_metadata_batch_remove(
initial_metadata,
initial_metadata->idx.named.grpc_internal_encoding_request);
calld->message_compression_algorithm =
grpc_compression_algorithm_to_message_compression_algorithm(
compression_algorithm);
stream_compression_algorithm =
grpc_compression_algorithm_to_stream_compression_algorithm(
compression_algorithm);
} else {
/* If no algorithm was found in the metadata and we aren't
* exceptionally skipping compression, fall back to the channel
* default */
if (channeld->default_compression_algorithm != GRPC_COMPRESS_NONE) {
calld->message_compression_algorithm =
grpc_compression_algorithm_to_message_compression_algorithm(
channeld->default_compression_algorithm);
stream_compression_algorithm =
grpc_compression_algorithm_to_stream_compression_algorithm(
channeld->default_compression_algorithm);
}
*has_compression_algorithm = true;
}
grpc_compression_algorithm_to_stream_compression_algorithm(
compression_algorithm);
// Hint compression algorithm.
grpc_error* error = GRPC_ERROR_NONE;
/* hint compression algorithm */
if (stream_compression_algorithm != GRPC_STREAM_COMPRESS_NONE) {
if (calld->message_compression_algorithm != GRPC_MESSAGE_COMPRESS_NONE) {
error = grpc_metadata_batch_add_tail(
initial_metadata, &calld->stream_compression_algorithm_storage,
grpc_stream_compression_encoding_mdelem(stream_compression_algorithm));
} else if (calld->message_compression_algorithm !=
GRPC_MESSAGE_COMPRESS_NONE) {
error = grpc_metadata_batch_add_tail(
initial_metadata, &calld->compression_algorithm_storage,
initial_metadata, &calld->message_compression_algorithm_storage,
grpc_message_compression_encoding_mdelem(
calld->message_compression_algorithm));
} else if (stream_compression_algorithm != GRPC_STREAM_COMPRESS_NONE) {
error = grpc_metadata_batch_add_tail(
initial_metadata, &calld->stream_compression_algorithm_storage,
grpc_stream_compression_encoding_mdelem(stream_compression_algorithm));
}
if (error != GRPC_ERROR_NONE) return error;
/* convey supported compression algorithms */
// Convey supported compression algorithms.
error = grpc_metadata_batch_add_tail(
initial_metadata, &calld->accept_encoding_storage,
GRPC_MDELEM_ACCEPT_ENCODING_FOR_ALGORITHMS(
channeld->supported_message_compression_algorithms));
channeld->enabled_message_compression_algorithms_bitset));
if (error != GRPC_ERROR_NONE) return error;
/* Do not overwrite accept-encoding header if it already presents (e.g. added
* by some proxy). */
// Do not overwrite accept-encoding header if it already presents (e.g., added
// by some proxy).
if (!initial_metadata->idx.named.accept_encoding) {
error = grpc_metadata_batch_add_tail(
initial_metadata, &calld->accept_stream_encoding_storage,
GRPC_MDELEM_ACCEPT_STREAM_ENCODING_FOR_ALGORITHMS(
channeld->supported_stream_compression_algorithms));
channeld->enabled_stream_compression_algorithms_bitset));
}
return error;
}
@ -358,12 +342,7 @@ static void on_send_message_next_done(void* arg, grpc_error* error) {
static void start_send_message_batch(void* arg, grpc_error* unused) {
grpc_call_element* elem = static_cast<grpc_call_element*>(arg);
call_data* calld = static_cast<call_data*>(elem->call_data);
if (skip_compression(
elem,
calld->send_message_batch->payload->send_message.send_message
->flags(),
calld->send_initial_metadata_state == HAS_COMPRESSION_ALGORITHM)) {
if (skip_message_compression(elem)) {
send_message_batch_continue(elem);
} else {
continue_reading_send_message(elem);
@ -380,7 +359,7 @@ static void compress_start_transport_stream_op_batch(
calld->cancel_error =
GRPC_ERROR_REF(batch->payload->cancel_stream.cancel_error);
if (calld->send_message_batch != nullptr) {
if (calld->send_initial_metadata_state == INITIAL_METADATA_UNSEEN) {
if (!calld->seen_initial_metadata) {
GRPC_CALL_COMBINER_START(
calld->call_combiner,
GRPC_CLOSURE_CREATE(fail_send_message_batch_in_call_combiner, calld,
@ -398,19 +377,15 @@ static void compress_start_transport_stream_op_batch(
}
// Handle send_initial_metadata.
if (batch->send_initial_metadata) {
GPR_ASSERT(calld->send_initial_metadata_state == INITIAL_METADATA_UNSEEN);
bool has_compression_algorithm;
GPR_ASSERT(!calld->seen_initial_metadata);
grpc_error* error = process_send_initial_metadata(
elem, batch->payload->send_initial_metadata.send_initial_metadata,
&has_compression_algorithm);
elem, batch->payload->send_initial_metadata.send_initial_metadata);
if (error != GRPC_ERROR_NONE) {
grpc_transport_stream_op_batch_finish_with_failure(batch, error,
calld->call_combiner);
return;
}
calld->send_initial_metadata_state = has_compression_algorithm
? HAS_COMPRESSION_ALGORITHM
: NO_COMPRESSION_ALGORITHM;
calld->seen_initial_metadata = true;
// If we had previously received a batch containing a send_message op,
// handle it now. Note that we need to re-enter the call combiner
// for this, since we can't send two batches down while holding the
@ -431,7 +406,7 @@ static void compress_start_transport_stream_op_batch(
// wait. We save the batch in calld and then drop the call
// combiner, which we'll have to pick up again later when we get
// send_initial_metadata.
if (calld->send_initial_metadata_state == INITIAL_METADATA_UNSEEN) {
if (!calld->seen_initial_metadata) {
GRPC_CALL_COMBINER_STOP(
calld->call_combiner,
"send_message batch pending send_initial_metadata");
@ -463,34 +438,29 @@ static void destroy_call_elem(grpc_call_element* elem,
static grpc_error* init_channel_elem(grpc_channel_element* elem,
grpc_channel_element_args* args) {
channel_data* channeld = static_cast<channel_data*>(elem->channel_data);
channeld->enabled_algorithms_bitset =
// Get the enabled and the default algorithms from channel args.
channeld->enabled_compression_algorithms_bitset =
grpc_channel_args_compression_algorithm_get_states(args->channel_args);
channeld->default_compression_algorithm =
grpc_channel_args_get_compression_algorithm(args->channel_args);
/* Make sure the default isn't disabled. */
if (!GPR_BITGET(channeld->enabled_algorithms_bitset,
grpc_channel_args_get_channel_default_compression_algorithm(
args->channel_args);
// Make sure the default is enabled.
if (!GPR_BITGET(channeld->enabled_compression_algorithms_bitset,
channeld->default_compression_algorithm)) {
gpr_log(GPR_DEBUG,
"compression algorithm %d not enabled: switching to none",
channeld->default_compression_algorithm);
const char* name;
GPR_ASSERT(grpc_compression_algorithm_name(
channeld->default_compression_algorithm, &name) == 1);
gpr_log(GPR_ERROR,
"default compression algorithm %s not enabled: switching to none",
name);
channeld->default_compression_algorithm = GRPC_COMPRESS_NONE;
}
uint32_t supported_compression_algorithms =
(((1u << GRPC_COMPRESS_ALGORITHMS_COUNT) - 1) &
channeld->enabled_algorithms_bitset) |
1u;
channeld->supported_message_compression_algorithms =
channeld->enabled_message_compression_algorithms_bitset =
grpc_compression_bitset_to_message_bitset(
supported_compression_algorithms);
channeld->supported_stream_compression_algorithms =
channeld->enabled_compression_algorithms_bitset);
channeld->enabled_stream_compression_algorithms_bitset =
grpc_compression_bitset_to_stream_bitset(
supported_compression_algorithms);
channeld->enabled_compression_algorithms_bitset);
GPR_ASSERT(!args->is_last);
return GRPC_ERROR_NONE;
}

@ -670,7 +670,7 @@ static grpc_slice take_string(grpc_chttp2_hpack_parser* p,
str->copied = true;
str->data.referenced = grpc_empty_slice();
} else if (intern) {
s = grpc_slice_intern(grpc_slice_from_static_buffer(
s = grpc_slice_intern(grpc_slice_from_static_buffer_internal(
str->data.copied.str, str->data.copied.length));
} else {
s = grpc_slice_from_copied_buffer(str->data.copied.str,
@ -1496,14 +1496,14 @@ static grpc_error* parse_key_string(grpc_chttp2_hpack_parser* p,
static bool is_binary_literal_header(grpc_chttp2_hpack_parser* p) {
/* We know that either argument here is a reference counter slice.
* 1. If a result of grpc_slice_from_static_buffer, the refcount is set to
* NoopRefcount.
* 1. If a result of grpc_slice_from_static_buffer_internal, the refcount is
* set to kNoopRefcount.
* 2. If it's p->key.data.referenced, then p->key.copied was set to false,
* which occurs in begin_parse_string() - where the refcount is set to
* p->current_slice_refcount, which is not null. */
return grpc_is_refcounted_slice_binary_header(
p->key.copied ? grpc_slice_from_static_buffer(p->key.data.copied.str,
p->key.data.copied.length)
p->key.copied ? grpc_slice_from_static_buffer_internal(
p->key.data.copied.str, p->key.data.copied.length)
: p->key.data.referenced);
}

@ -29,6 +29,7 @@
#include "src/core/lib/debug/trace.h"
#include "src/core/lib/gpr/murmur_hash.h"
#include "src/core/lib/slice/slice_internal.h"
#include "src/core/lib/surface/validate_metadata.h"
#include "src/core/lib/transport/static_metadata.h"
@ -182,9 +183,10 @@ void grpc_chttp2_hptbl_init(grpc_chttp2_hptbl* tbl) {
memset(tbl->ents, 0, sizeof(*tbl->ents) * tbl->cap_entries);
for (i = 1; i <= GRPC_CHTTP2_LAST_STATIC_ENTRY; i++) {
tbl->static_ents[i - 1] = grpc_mdelem_from_slices(
grpc_slice_intern(grpc_slice_from_static_string(static_table[i].key)),
grpc_slice_intern(
grpc_slice_from_static_string(static_table[i].value)));
grpc_slice_from_static_string_internal(static_table[i].key)),
grpc_slice_intern(
grpc_slice_from_static_string_internal(static_table[i].value)));
}
}

@ -1203,7 +1203,7 @@ void inproc_transports_create(grpc_transport** server_transport,
*/
void grpc_inproc_transport_init(void) {
grpc_core::ExecCtx exec_ctx;
g_empty_slice = grpc_slice_from_static_buffer(nullptr, 0);
g_empty_slice = grpc_slice_from_static_buffer_internal(nullptr, 0);
grpc_slice key_tmp = grpc_slice_from_static_string(":path");
g_fake_path_key = grpc_slice_intern(key_tmp);

@ -59,12 +59,11 @@ int grpc_compression_algorithm_parse(grpc_slice name,
} else {
return 0;
}
return 0;
}
int grpc_compression_algorithm_name(grpc_compression_algorithm algorithm,
const char** name) {
GRPC_API_TRACE("grpc_compression_algorithm_parse(algorithm=%d, name=%p)", 2,
GRPC_API_TRACE("grpc_compression_algorithm_name(algorithm=%d, name=%p)", 2,
((int)algorithm, name));
switch (algorithm) {
case GRPC_COMPRESS_NONE:

@ -32,21 +32,25 @@
#include "src/core/lib/gpr/string.h"
#include "src/core/lib/gpr/useful.h"
grpc_compression_algorithm grpc_channel_args_get_compression_algorithm(
grpc_compression_algorithm
grpc_channel_args_get_channel_default_compression_algorithm(
const grpc_channel_args* a) {
size_t i;
if (a == nullptr) return GRPC_COMPRESS_NONE;
for (i = 0; i < a->num_args; ++i) {
if (a->args[i].type == GRPC_ARG_INTEGER &&
!strcmp(GRPC_COMPRESSION_CHANNEL_DEFAULT_ALGORITHM, a->args[i].key)) {
return static_cast<grpc_compression_algorithm>(a->args[i].value.integer);
break;
grpc_compression_algorithm default_algorithm =
static_cast<grpc_compression_algorithm>(a->args[i].value.integer);
return default_algorithm < GRPC_COMPRESS_ALGORITHMS_COUNT
? default_algorithm
: GRPC_COMPRESS_NONE;
}
}
return GRPC_COMPRESS_NONE;
}
grpc_channel_args* grpc_channel_args_set_compression_algorithm(
grpc_channel_args* grpc_channel_args_set_channel_default_compression_algorithm(
grpc_channel_args* a, grpc_compression_algorithm algorithm) {
GPR_ASSERT(algorithm < GRPC_COMPRESS_ALGORITHMS_COUNT);
grpc_arg tmp;
@ -68,7 +72,9 @@ static int find_compression_algorithm_states_bitset(const grpc_channel_args* a,
!strcmp(GRPC_COMPRESSION_CHANNEL_ENABLED_ALGORITHMS_BITSET,
a->args[i].key)) {
*states_arg = &a->args[i].value.integer;
**states_arg |= 0x1; /* forcefully enable support for no compression */
**states_arg =
(**states_arg & ((1 << GRPC_COMPRESS_ALGORITHMS_COUNT) - 1)) |
0x1; /* forcefully enable support for no compression */
return 1;
}
}
@ -83,7 +89,8 @@ grpc_channel_args* grpc_channel_args_compression_algorithm_set_state(
const int states_arg_found =
find_compression_algorithm_states_bitset(*a, &states_arg);
if (grpc_channel_args_get_compression_algorithm(*a) == algorithm &&
if (grpc_channel_args_get_channel_default_compression_algorithm(*a) ==
algorithm &&
state == 0) {
const char* algo_name = nullptr;
GPR_ASSERT(grpc_compression_algorithm_name(algorithm, &algo_name) != 0);

@ -25,13 +25,14 @@
#include <grpc/impl/codegen/grpc_types.h>
/** Returns the compression algorithm set in \a a. */
grpc_compression_algorithm grpc_channel_args_get_compression_algorithm(
grpc_compression_algorithm
grpc_channel_args_get_channel_default_compression_algorithm(
const grpc_channel_args* a);
/** Returns a channel arg instance with compression enabled. If \a a is
* non-NULL, its args are copied. N.B. GRPC_COMPRESS_NONE disables compression
* for the channel. */
grpc_channel_args* grpc_channel_args_set_compression_algorithm(
grpc_channel_args* grpc_channel_args_set_channel_default_compression_algorithm(
grpc_channel_args* a, grpc_compression_algorithm algorithm);
/** Sets the support for the given compression algorithm. By default, all

@ -171,7 +171,7 @@ int grpc_compression_algorithm_from_message_stream_compression_algorithm(
int grpc_message_compression_algorithm_name(
grpc_message_compression_algorithm algorithm, const char** name) {
GRPC_API_TRACE(
"grpc_message_compression_algorithm_parse(algorithm=%d, name=%p)", 2,
"grpc_message_compression_algorithm_name(algorithm=%d, name=%p)", 2,
((int)algorithm, name));
switch (algorithm) {
case GRPC_MESSAGE_COMPRESS_NONE:

@ -22,6 +22,7 @@
#include <grpc/support/port_platform.h>
#include <grpc/support/alloc.h>
#include <grpc/support/log.h>
#include <limits>
#include <memory>
@ -29,14 +30,17 @@
// Add this to a class that want to use Delete(), but has a private or
// protected destructor.
#define GRPC_ALLOW_CLASS_TO_USE_NON_PUBLIC_DELETE \
template <typename T> \
friend void grpc_core::Delete(T*);
#define GRPC_ALLOW_CLASS_TO_USE_NON_PUBLIC_DELETE \
template <typename _Delete_T, bool _Delete_can_be_null> \
friend void ::grpc_core::Delete(_Delete_T*); \
template <typename _Delete_T> \
friend void ::grpc_core::Delete(_Delete_T*);
// Add this to a class that want to use New(), but has a private or
// protected constructor.
#define GRPC_ALLOW_CLASS_TO_USE_NON_PUBLIC_NEW \
template <typename T, typename... Args> \
friend T* grpc_core::New(Args&&...);
#define GRPC_ALLOW_CLASS_TO_USE_NON_PUBLIC_NEW \
template <typename _New_T, typename... _New_Args> \
friend _New_T* grpc_core::New(_New_Args&&...);
namespace grpc_core {
@ -48,17 +52,30 @@ inline T* New(Args&&... args) {
}
// Alternative to delete, since we cannot use it (for fear of libstdc++)
template <typename T>
// We cannot add a default value for can_be_null, because they are used as
// as friend template methods where we cannot define a default value.
// Instead we simply define two variants, one with and one without the boolean
// argument.
template <typename T, bool can_be_null>
inline void Delete(T* p) {
if (p == nullptr) return;
GPR_DEBUG_ASSERT(can_be_null || p != nullptr);
if (can_be_null && p == nullptr) return;
p->~T();
gpr_free(p);
}
template <typename T>
inline void Delete(T* p) {
Delete<T, /*can_be_null=*/true>(p);
}
template <typename T>
class DefaultDelete {
public:
void operator()(T* p) { Delete(p); }
void operator()(T* p) {
// std::unique_ptr is gauranteed not to call the deleter
// if the pointer is nullptr.
Delete<T, /*can_be_null=*/false>(p);
}
};
template <typename T, typename Deleter = DefaultDelete<T>>

@ -447,13 +447,17 @@ grpc_error* grpc_error_set_int(grpc_error* src, grpc_error_ints which,
typedef struct {
grpc_status_code code;
const char* msg;
size_t len;
} special_error_status_map;
static const special_error_status_map error_status_map[] = {
{GRPC_STATUS_OK, ""}, // GRPC_ERROR_NONE
{GRPC_STATUS_INVALID_ARGUMENT, ""}, // GRPC_ERROR_RESERVED_1
{GRPC_STATUS_RESOURCE_EXHAUSTED, "Out of memory"}, // GRPC_ERROR_OOM
{GRPC_STATUS_INVALID_ARGUMENT, ""}, // GRPC_ERROR_RESERVED_2
{GRPC_STATUS_CANCELLED, "Cancelled"}, // GRPC_ERROR_CANCELLED
const special_error_status_map error_status_map[] = {
{GRPC_STATUS_OK, "", 0}, // GRPC_ERROR_NONE
{GRPC_STATUS_INVALID_ARGUMENT, "", 0}, // GRPC_ERROR_RESERVED_1
{GRPC_STATUS_RESOURCE_EXHAUSTED, "Out of memory",
strlen("Out of memory")}, // GRPC_ERROR_OOM
{GRPC_STATUS_INVALID_ARGUMENT, "", 0}, // GRPC_ERROR_RESERVED_2
{GRPC_STATUS_CANCELLED, "Cancelled",
strlen("Cancelled")}, // GRPC_ERROR_CANCELLED
};
bool grpc_error_get_int(grpc_error* err, grpc_error_ints which, intptr_t* p) {
@ -483,8 +487,12 @@ bool grpc_error_get_str(grpc_error* err, grpc_error_strs which,
grpc_slice* str) {
if (grpc_error_is_special(err)) {
if (which != GRPC_ERROR_STR_GRPC_MESSAGE) return false;
*str = grpc_slice_from_static_string(
error_status_map[reinterpret_cast<size_t>(err)].msg);
const special_error_status_map& msg =
error_status_map[reinterpret_cast<size_t>(err)];
str->refcount = &grpc_core::kNoopRefcount;
str->data.refcounted.bytes =
reinterpret_cast<uint8_t*>(const_cast<char*>(msg.msg));
str->data.refcounted.length = msg.len;
return true;
}
uint8_t slot = err->strs[which];

@ -66,32 +66,13 @@ void grpc_slice_unref(grpc_slice slice) {
}
}
namespace grpc_core {
/* grpc_slice_from_static_string support structure - a refcount that does
nothing */
static grpc_slice_refcount NoopRefcount =
grpc_slice_refcount(grpc_slice_refcount::Type::NOP);
size_t grpc_slice_memory_usage(grpc_slice s) {
if (s.refcount == nullptr || s.refcount == &NoopRefcount) {
return 0;
} else {
return s.data.refcounted.length;
}
}
grpc_slice grpc_slice_from_static_buffer(const void* s, size_t len) {
grpc_slice slice;
slice.refcount = &NoopRefcount;
slice.data.refcounted.bytes = (uint8_t*)s;
slice.data.refcounted.length = len;
return slice;
}
grpc_slice grpc_slice_from_static_string(const char* s) {
return grpc_slice_from_static_buffer(s, strlen(s));
}
namespace grpc_core {
grpc_slice_refcount kNoopRefcount(grpc_slice_refcount::Type::NOP);
static_assert(std::is_trivially_destructible<decltype(kNoopRefcount)>::value,
"kNoopRefcount must be trivially destructible.");
/* grpc_slice_new support structures - we create a refcount object extended
with the user provided data pointer & destroy function */
@ -122,6 +103,22 @@ class NewSliceRefcount {
} // namespace grpc_core
size_t grpc_slice_memory_usage(grpc_slice s) {
if (s.refcount == nullptr || s.refcount == &grpc_core::kNoopRefcount) {
return 0;
} else {
return s.data.refcounted.length;
}
}
grpc_slice grpc_slice_from_static_buffer(const void* s, size_t len) {
return grpc_slice_from_static_buffer_internal(s, len);
}
grpc_slice grpc_slice_from_static_string(const char* s) {
return grpc_slice_from_static_buffer_internal(s, strlen(s));
}
grpc_slice grpc_slice_new_with_user_data(void* p, size_t len,
void (*destroy)(void*),
void* user_data) {
@ -375,10 +372,10 @@ grpc_slice grpc_slice_split_tail_maybe_ref(grpc_slice* source, size_t split,
switch (ref_whom) {
case GRPC_SLICE_REF_TAIL:
tail.refcount = source->refcount->sub_refcount();
source->refcount = &NoopRefcount;
source->refcount = &grpc_core::kNoopRefcount;
break;
case GRPC_SLICE_REF_HEAD:
tail.refcount = &NoopRefcount;
tail.refcount = &grpc_core::kNoopRefcount;
source->refcount = source->refcount->sub_refcount();
break;
case GRPC_SLICE_REF_BOTH:

@ -25,6 +25,7 @@
#include <grpc/support/log.h>
#include "src/core/lib/gpr/useful.h"
#include "src/core/lib/gprpp/memory.h"
#include "src/core/lib/gprpp/ref_counted.h"
#include "src/core/lib/gprpp/ref_counted_ptr.h"
#include "src/core/lib/slice/slice_internal.h"
@ -77,13 +78,8 @@ class SliceHashTable : public RefCounted<SliceHashTable<T>> {
static int Cmp(const SliceHashTable& a, const SliceHashTable& b);
private:
// So New() can call our private ctor.
template <typename T2, typename... Args>
friend T2* New(Args&&... args);
// So Delete() can call our private dtor.
template <typename T2>
friend void Delete(T2*);
GRPC_ALLOW_CLASS_TO_USE_NON_PUBLIC_DELETE
GRPC_ALLOW_CLASS_TO_USE_NON_PUBLIC_NEW
SliceHashTable(size_t num_entries, Entry* entries, ValueCmp value_cmp);
virtual ~SliceHashTable();

@ -171,6 +171,8 @@ struct grpc_slice_refcount {
namespace grpc_core {
extern grpc_slice_refcount kNoopRefcount;
struct InternedSliceRefcount {
static void Destroy(void* arg) {
auto* rc = static_cast<InternedSliceRefcount*>(arg);
@ -312,4 +314,17 @@ grpc_slice grpc_slice_from_moved_string(grpc_core::UniquePtr<char> p);
// 0. All other slices will return the size of the allocated chars.
size_t grpc_slice_memory_usage(grpc_slice s);
inline grpc_slice grpc_slice_from_static_buffer_internal(const void* s,
size_t len) {
grpc_slice slice;
slice.refcount = &grpc_core::kNoopRefcount;
slice.data.refcounted.bytes = (uint8_t*)s;
slice.data.refcounted.length = len;
return slice;
}
inline grpc_slice grpc_slice_from_static_string_internal(const char* s) {
return grpc_slice_from_static_buffer_internal(s, strlen(s));
}
#endif /* GRPC_CORE_LIB_SLICE_SLICE_INTERNAL_H */

@ -61,13 +61,8 @@ class SliceWeakHashTable : public RefCounted<SliceWeakHashTable<T, Size>> {
}
private:
// So New() can call our private ctor.
template <typename T2, typename... Args>
friend T2* New(Args&&... args);
// So Delete() can call our private dtor.
template <typename T2>
friend void Delete(T2*);
GRPC_ALLOW_CLASS_TO_USE_NON_PUBLIC_NEW
GRPC_ALLOW_CLASS_TO_USE_NON_PUBLIC_DELETE
SliceWeakHashTable() = default;
~SliceWeakHashTable() = default;

@ -1568,6 +1568,10 @@ static grpc_call_error call_start_batch(grpc_call* call, const grpc_op* ops,
error = GRPC_CALL_ERROR_TOO_MANY_OPERATIONS;
goto done_with_error;
}
// TODO(juanlishen): If the user has already specified a compression
// algorithm by setting the initial metadata with key of
// GRPC_COMPRESSION_REQUEST_ALGORITHM_MD_KEY, we shouldn't override that
// with the compression algorithm mapped from compression level.
/* process compression level */
grpc_metadata& compression_md = call->compression_md;
compression_md.key = grpc_empty_slice();
@ -1589,17 +1593,18 @@ static grpc_call_error call_start_batch(grpc_call* call, const grpc_op* ops,
effective_compression_level = copts.default_level.level;
}
}
// Currently, only server side supports compression level setting.
if (level_set && !call->is_client) {
const grpc_compression_algorithm calgo =
compression_algorithm_for_level_locked(
call, effective_compression_level);
/* the following will be picked up by the compress filter and used
* as the call's compression algorithm. */
// The following metadata will be checked and removed by the message
// compression filter. It will be used as the call's compression
// algorithm.
compression_md.key = GRPC_MDSTR_GRPC_INTERNAL_ENCODING_REQUEST;
compression_md.value = grpc_compression_algorithm_slice(calgo);
additional_metadata_count++;
}
if (op->data.send_initial_metadata.count + additional_metadata_count >
INT_MAX) {
error = GRPC_CALL_ERROR_INVALID_METADATA;

@ -25,4 +25,4 @@
const char* grpc_version_string(void) { return "7.0.0"; }
const char* grpc_g_stands_for(void) { return "gale"; }
const char* grpc_g_stands_for(void) { return "gangnam"; }

@ -22,6 +22,7 @@
#include <grpc/support/string_util.h>
#include "src/core/lib/iomgr/error_internal.h"
#include "src/core/lib/slice/slice_internal.h"
#include "src/core/lib/transport/status_conversion.h"
static grpc_error* recursively_find_error_with_field(grpc_error* error,
@ -52,7 +53,15 @@ void grpc_error_get_status(grpc_error* error, grpc_millis deadline,
if (GPR_LIKELY(error == GRPC_ERROR_NONE)) {
if (code != nullptr) *code = GRPC_STATUS_OK;
if (slice != nullptr) {
grpc_error_get_str(error, GRPC_ERROR_STR_GRPC_MESSAGE, slice);
// Normally, we call grpc_error_get_str(
// error, GRPC_ERROR_STR_GRPC_MESSAGE, slice).
// We can fastpath since we know that:
// 1) Error is null
// 2) which == GRPC_ERROR_STR_GRPC_MESSAGE
// 3) The resulting slice is statically known.
// 4) Said resulting slice is of length 0 ("").
// This means 3 movs, instead of 10s of instructions and a strlen.
*slice = grpc_slice_from_static_string_internal("");
}
if (http_error != nullptr) {
*http_error = GRPC_HTTP2_NO_ERROR;

@ -44,6 +44,9 @@ static int64_t round_up_to_three_sig_figs(int64_t x) {
/* encode our minimum viable timeout value */
static void enc_tiny(char* buffer) { memcpy(buffer, "1n", 3); }
/* encode our maximum timeout value, about 1157 days */
static void enc_huge(char* buffer) { memcpy(buffer, "99999999S", 10); }
static void enc_ext(char* buffer, int64_t value, char ext) {
int n = int64_ttoa(value, buffer);
buffer[n] = ext;
@ -51,6 +54,7 @@ static void enc_ext(char* buffer, int64_t value, char ext) {
}
static void enc_seconds(char* buffer, int64_t sec) {
sec = round_up_to_three_sig_figs(sec);
if (sec % 3600 == 0) {
enc_ext(buffer, sec / 3600, 'H');
} else if (sec % 60 == 0) {
@ -74,10 +78,13 @@ static void enc_millis(char* buffer, int64_t x) {
}
void grpc_http2_encode_timeout(grpc_millis timeout, char* buffer) {
const grpc_millis kMaxTimeout = 99999999000;
if (timeout <= 0) {
enc_tiny(buffer);
} else if (timeout < 1000 * GPR_MS_PER_SEC) {
enc_millis(buffer, timeout);
} else if (timeout >= kMaxTimeout) {
enc_huge(buffer);
} else {
enc_seconds(buffer,
timeout / GPR_MS_PER_SEC + (timeout % GPR_MS_PER_SEC != 0));

@ -27,10 +27,11 @@
#include "src/core/lib/gpr/string.h"
#include "src/core/lib/iomgr/exec_ctx.h"
#define GRPC_HTTP2_TIMEOUT_ENCODE_MIN_BUFSIZE (GPR_LTOA_MIN_BUFSIZE + 1)
#define GRPC_HTTP2_TIMEOUT_ENCODE_MIN_BUFSIZE 10
/* Encode/decode timeouts to the GRPC over HTTP/2 format;
encoding may round up arbitrarily */
encoding may round up arbitrarily. If the timeout is larger than about 1157
days, it will be capped and "99999999S" will be sent on the wire. */
void grpc_http2_encode_timeout(grpc_millis timeout, char* buffer);
int grpc_http2_decode_timeout(const grpc_slice& text, grpc_millis* timeout);

@ -67,13 +67,8 @@ class SslSessionLRUCache : public grpc_core::RefCounted<SslSessionLRUCache> {
SslSessionPtr Get(const char* key);
private:
// So New() can call our private ctor.
template <typename T, typename... Args>
friend T* grpc_core::New(Args&&... args);
// So Delete() can call our private dtor.
template <typename T>
friend void grpc_core::Delete(T*);
GRPC_ALLOW_CLASS_TO_USE_NON_PUBLIC_NEW
GRPC_ALLOW_CLASS_TO_USE_NON_PUBLIC_DELETE
class Node;

@ -22,5 +22,5 @@
#include <grpcpp/grpcpp.h>
namespace grpc {
grpc::string Version() { return "1.22.0-dev"; }
grpc::string Version() { return "1.23.0-dev"; }
} // namespace grpc

@ -33,11 +33,11 @@ namespace Grpc.Core
/// <summary>
/// Current <c>AssemblyFileVersion</c> of gRPC C# assemblies
/// </summary>
public const string CurrentAssemblyFileVersion = "1.22.0.0";
public const string CurrentAssemblyFileVersion = "1.23.0.0";
/// <summary>
/// Current version of gRPC C#
/// </summary>
public const string CurrentVersion = "1.22.0-dev";
public const string CurrentVersion = "1.23.0-dev";
}
}

@ -108,8 +108,8 @@ namespace Grpc.Core.Tests
var deadline = DateTime.UtcNow.AddDays(7);
helper.UnaryHandler = new UnaryServerMethod<string, string>((request, context) =>
{
Assert.IsTrue(context.Deadline < deadline.AddMinutes(1));
Assert.IsTrue(context.Deadline > deadline.AddMinutes(-1));
Assert.IsTrue(context.Deadline < deadline.AddHours(1));
Assert.IsTrue(context.Deadline > deadline.AddHours(-1));
return Task.FromResult("PASS");
});

@ -80,7 +80,7 @@ namespace Grpc.Core.Tests
// A fairly relaxed check that the deadline set by client and deadline seen by server
// are in agreement. C core takes care of the work with transferring deadline over the wire,
// so we don't need an exact check here.
Assert.IsTrue(Math.Abs((clientDeadline - context.Deadline).TotalMilliseconds) < 5000);
Assert.IsTrue(Math.Abs((clientDeadline - context.Deadline).TotalHours) < 1);
return Task.FromResult("PASS");
});
Calls.BlockingUnaryCall(helper.CreateUnaryCall(new CallOptions(deadline: clientDeadline)), "abc");

@ -1,7 +1,7 @@
<!-- This file is generated -->
<Project>
<PropertyGroup>
<GrpcCsharpVersion>1.22.0-dev</GrpcCsharpVersion>
<GrpcCsharpVersion>1.23.0-dev</GrpcCsharpVersion>
<GoogleProtobufVersion>3.7.0</GoogleProtobufVersion>
</PropertyGroup>
</Project>

@ -13,7 +13,7 @@
@rem limitations under the License.
@rem Current package versions
set VERSION=1.22.0-dev
set VERSION=1.23.0-dev
@rem Adjust the location of nuget.exe
set NUGET=C:\nuget\nuget.exe

@ -42,7 +42,7 @@ Pod::Spec.new do |s|
# exclamation mark ensures that other "regular" pods will be able to find it as it'll be installed
# before them.
s.name = '!ProtoCompiler-gRPCPlugin'
v = '1.22.0-dev'
v = '1.23.0-dev'
s.version = v
s.summary = 'The gRPC ProtoC plugin generates Objective-C files from .proto services.'
s.description = <<-DESC
@ -101,7 +101,7 @@ Pod::Spec.new do |s|
s.preserve_paths = plugin
# Restrict the protoc version to the one supported by this plugin.
s.dependency '!ProtoCompiler', '3.7.0'
s.dependency '!ProtoCompiler', '3.8.0'
# For the Protobuf dependency not to complain:
s.ios.deployment_target = '7.0'
s.osx.deployment_target = '10.9'

@ -36,7 +36,7 @@ Pod::Spec.new do |s|
# exclamation mark ensures that other "regular" pods will be able to find it as it'll be installed
# before them.
s.name = '!ProtoCompiler'
v = '3.7.0'
v = '3.8.0'
s.version = v
s.summary = 'The Protobuf Compiler (protoc) generates Objective-C files from .proto files'
s.description = <<-DESC

@ -22,4 +22,4 @@
// instead. This file can be regenerated from the template by running
// `tools/buildgen/generate_projects.sh`.
#define GRPC_OBJC_VERSION_STRING @"1.22.0-dev"
#define GRPC_OBJC_VERSION_STRING @"1.23.0-dev"

@ -37,10 +37,14 @@
#define TEST_TIMEOUT 16
static NSString *const kHostAddress = @"localhost:5050";
// The server address is derived from preprocessor macro, which is
// in turn derived from environment variable of the same name.
#define NSStringize_helper(x) #x
#define NSStringize(x) @NSStringize_helper(x)
static NSString *const kHostAddress = NSStringize(HOST_PORT_LOCAL);
static NSString *const kPackage = @"grpc.testing";
static NSString *const kService = @"TestService";
static NSString *const kRemoteSSLHost = @"grpc-test.sandbox.googleapis.com";
static NSString *const kRemoteSSLHost = NSStringize(HOST_PORT_REMOTE);
static GRPCProtoMethod *kInexistentMethod;
static GRPCProtoMethod *kEmptyCallMethod;

@ -0,0 +1,66 @@
#!/bin/bash
# Copyright 2019 gRPC authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# Don't run this script standalone. Instead, run from the repository root:
# ./tools/run_tests/run_tests.py -l objc
set -ev
cd $(dirname $0)
BINDIR=../../../bins/$CONFIG
[ -f $BINDIR/interop_server ] || {
echo >&2 "Can't find the test server. Make sure run_tests.py is making" \
"interop_server before calling this script."
exit 1
}
[ -z "$(ps aux |egrep 'port_server\.py.*-p\s32766')" ] && {
echo >&2 "Can't find the port server. Start port server with tools/run_tests/start_port_server.py."
exit 1
}
PLAIN_PORT=$(curl localhost:32766/get)
TLS_PORT=$(curl localhost:32766/get)
$BINDIR/interop_server --port=$PLAIN_PORT --max_send_message_size=8388608 &
$BINDIR/interop_server --port=$TLS_PORT --max_send_message_size=8388608 --use_tls &
trap 'kill -9 `jobs -p` ; echo "EXIT TIME: $(date)"' EXIT
set -o pipefail
XCODEBUILD_FILTER='(^CompileC |^Ld |^ *[^ ]*clang |^ *cd |^ *export |^Libtool |^ *[^ ]*libtool |^CpHeader |^ *builtin-copy )'
if [ -z $PLATFORM ]; then
DESTINATION='name=iPhone 8'
elif [ $PLATFORM == ios ]; then
DESTINATION='name=iPhone 8'
elif [ $PLATFORM == macos ]; then
DESTINATION='platform=macOS'
fi
xcodebuild \
-workspace Tests.xcworkspace \
-scheme $SCHEME \
-destination "$DESTINATION" \
HOST_PORT_LOCALSSL=localhost:$TLS_PORT \
HOST_PORT_LOCAL=localhost:$PLAIN_PORT \
HOST_PORT_REMOTE=grpc-test.sandbox.googleapis.com \
test \
| egrep -v "$XCODEBUILD_FILTER" \
| egrep -v '^$' \
| egrep -v "(GPBDictionary|GPBArray)" -

@ -22,5 +22,5 @@
// instead. This file can be regenerated from the template by running
// `tools/buildgen/generate_projects.sh`.
#define GRPC_OBJC_VERSION_STRING @"1.22.0-dev"
#define GRPC_OBJC_VERSION_STRING @"1.23.0-dev"
#define GRPC_C_VERSION_STRING @"7.0.0"

@ -2,7 +2,7 @@
"name": "grpc/grpc-dev",
"description": "gRPC library for PHP - for Developement use only",
"license": "Apache-2.0",
"version": "1.22.0",
"version": "1.23.0",
"require": {
"php": ">=5.5.0",
"google/protobuf": "^v3.3.0"

@ -20,6 +20,6 @@
#ifndef VERSION_H
#define VERSION_H
#define PHP_GRPC_VERSION "1.22.0dev"
#define PHP_GRPC_VERSION "1.23.0dev"
#endif /* VERSION_H */

@ -14,4 +14,4 @@
# AUTO-GENERATED FROM `$REPO_ROOT/templates/src/python/grpcio/grpc/_grpcio_metadata.py.template`!!!
__version__ = """1.22.0.dev0"""
__version__ = """1.23.0.dev0"""

@ -14,4 +14,4 @@
# AUTO-GENERATED FROM `$REPO_ROOT/templates/src/python/grpcio/grpc_version.py.template`!!!
VERSION = '1.22.0.dev0'
VERSION = '1.23.0.dev0'

@ -14,4 +14,4 @@
# AUTO-GENERATED FROM `$REPO_ROOT/templates/src/python/grpcio_channelz/grpc_version.py.template`!!!
VERSION = '1.22.0.dev0'
VERSION = '1.23.0.dev0'

@ -14,4 +14,4 @@
# AUTO-GENERATED FROM `$REPO_ROOT/templates/src/python/grpcio_health_checking/grpc_version.py.template`!!!
VERSION = '1.22.0.dev0'
VERSION = '1.23.0.dev0'

@ -14,4 +14,4 @@
# AUTO-GENERATED FROM `$REPO_ROOT/templates/src/python/grpcio_reflection/grpc_version.py.template`!!!
VERSION = '1.22.0.dev0'
VERSION = '1.23.0.dev0'

@ -14,4 +14,4 @@
# AUTO-GENERATED FROM `$REPO_ROOT/templates/src/python/grpcio_status/grpc_version.py.template`!!!
VERSION = '1.22.0.dev0'
VERSION = '1.23.0.dev0'

@ -14,4 +14,4 @@
# AUTO-GENERATED FROM `$REPO_ROOT/templates/src/python/grpcio_testing/grpc_version.py.template`!!!
VERSION = '1.22.0.dev0'
VERSION = '1.23.0.dev0'

@ -14,4 +14,4 @@
# AUTO-GENERATED FROM `$REPO_ROOT/templates/src/python/grpcio_tests/grpc_version.py.template`!!!
VERSION = '1.22.0.dev0'
VERSION = '1.23.0.dev0'

@ -14,5 +14,5 @@
# GRPC contains the General RPC module.
module GRPC
VERSION = '1.22.0.dev'
VERSION = '1.23.0.dev'
end

@ -14,6 +14,6 @@
module GRPC
module Tools
VERSION = '1.22.0.dev'
VERSION = '1.23.0.dev'
end
end

@ -15,7 +15,7 @@
s.description = 'Send RPCs from Ruby using GRPC'
s.license = 'Apache-2.0'
s.required_ruby_version = '>= 2.0.0'
s.required_ruby_version = '>= 2.3.0'
s.files = %w( Makefile .yardopts )
s.files += %w( etc/roots.pem )

@ -103,7 +103,7 @@
s.preserve_paths = plugin
# Restrict the protoc version to the one supported by this plugin.
s.dependency '!ProtoCompiler', '3.7.0'
s.dependency '!ProtoCompiler', '3.8.0'
# For the Protobuf dependency not to complain:
s.ios.deployment_target = '7.0'
s.osx.deployment_target = '10.9'

@ -2,7 +2,7 @@
# Bazel installation
# Must be in sync with tools/bazel
ENV BAZEL_VERSION 0.24.1
ENV BAZEL_VERSION 0.26.0
# The correct bazel version is already preinstalled, no need to use //tools/bazel wrapper.
ENV DISABLE_BAZEL_WRAPPER 1

@ -27,12 +27,14 @@ default_test_options = TestOptions(False, 1.0)
# maps test names to options
BAD_CLIENT_TESTS = {
'badreq': default_test_options,
'bad_streaming_id': default_test_options,
'connection_prefix': default_test_options._replace(cpu_cost=0.2),
'duplicate_header': default_test_options,
'headers': default_test_options._replace(cpu_cost=0.2),
'initial_settings_frame': default_test_options._replace(cpu_cost=0.2),
'head_of_line_blocking': default_test_options,
'large_metadata': default_test_options,
'out_of_bounds': default_test_options,
'server_registered_method': default_test_options,
'simple_request': default_test_options,
'window_overflow': default_test_options,

@ -25,12 +25,14 @@ def test_options():
# maps test names to options
BAD_CLIENT_TESTS = {
'badreq': test_options(),
'bad_streaming_id': test_options(),
'connection_prefix': test_options(),
'duplicate_header': test_options(),
'headers': test_options(),
'initial_settings_frame': test_options(),
'head_of_line_blocking': test_options(),
'large_metadata': test_options(),
'out_of_bounds': test_options(),
'server_registered_method': test_options(),
'simple_request': test_options(),
'window_overflow': test_options(),

@ -0,0 +1,132 @@
/*
*
* Copyright 2019 gRPC authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
#include <string>
#include <gtest/gtest.h>
#include <grpc/support/string_util.h>
#include "src/core/lib/surface/server.h"
#include "test/core/bad_client/bad_client.h"
#define HEADER_FRAME_ID_1 \
"\x00\x00\xc9\x01\x05\x00\x00\x00\x01" /* headers: generated from \
simple_request.headers in this \
directory */ \
"\x10\x05:path\x08/foo/bar" \
"\x10\x07:scheme\x04http" \
"\x10\x07:method\x04POST" \
"\x10\x0a:authority\x09localhost" \
"\x10\x0c" \
"content-type\x10" \
"application/grpc" \
"\x10\x14grpc-accept-encoding\x15" \
"deflate,identity,gzip" \
"\x10\x02te\x08trailers" \
"\x10\x0auser-agent\"bad-client grpc-c/0.12.0.0 (linux)"
#define HEADER_FRAME_ID_2 \
"\x00\x00\xc9\x01\x05\x00\x00\x00\x02" /* headers: generated from \
simple_request.headers in this \
directory */ \
"\x10\x05:path\x08/foo/bar" \
"\x10\x07:scheme\x04http" \
"\x10\x07:method\x04POST" \
"\x10\x0a:authority\x09localhost" \
"\x10\x0c" \
"content-type\x10" \
"application/grpc" \
"\x10\x14grpc-accept-encoding\x15" \
"deflate,identity,gzip" \
"\x10\x02te\x08trailers" \
"\x10\x0auser-agent\"bad-client grpc-c/0.12.0.0 (linux)"
#define HEADER_FRAME_ID_3 \
"\x00\x00\xc9\x01\x05\x00\x00\x00\x03" /* headers: generated from \
simple_request.headers in this \
directory */ \
"\x10\x05:path\x08/foo/bar" \
"\x10\x07:scheme\x04http" \
"\x10\x07:method\x04POST" \
"\x10\x0a:authority\x09localhost" \
"\x10\x0c" \
"content-type\x10" \
"application/grpc" \
"\x10\x14grpc-accept-encoding\x15" \
"deflate,identity,gzip" \
"\x10\x02te\x08trailers" \
"\x10\x0auser-agent\"bad-client grpc-c/0.12.0.0 (linux)"
namespace {
void verifier(grpc_server* server, grpc_completion_queue* cq,
void* registered_method) {
while (grpc_server_has_open_connections(server)) {
GPR_ASSERT(grpc_completion_queue_next(
cq, grpc_timeout_milliseconds_to_deadline(20), nullptr)
.type == GRPC_QUEUE_TIMEOUT);
}
}
TEST(BadStreamingId, RegularHeader) {
grpc_bad_client_arg args[2];
args[0] = connection_preface_arg;
args[1].client_validator = nullptr;
args[1].client_payload = HEADER_FRAME_ID_1;
args[1].client_payload_length = sizeof(HEADER_FRAME_ID_1) - 1;
grpc_run_bad_client_test(verifier, args, 2, GRPC_BAD_CLIENT_DISCONNECT);
}
TEST(BadStreamingId, NonClientStreamId) {
grpc_bad_client_arg args[2];
args[0] = connection_preface_arg;
// send a header frame with non-client stream id 2
args[1].client_validator = nullptr;
args[1].client_payload = HEADER_FRAME_ID_2;
args[1].client_payload_length = sizeof(HEADER_FRAME_ID_2) - 1;
grpc_run_bad_client_test(verifier, args, 2, GRPC_BAD_CLIENT_DISCONNECT);
}
TEST(BadStreamingId, ClosedStreamId) {
grpc_bad_client_arg args[4];
args[0] = connection_preface_arg;
// send a header frame with stream id 1
args[1].client_validator = nullptr;
args[1].client_payload = HEADER_FRAME_ID_1;
args[1].client_payload_length = sizeof(HEADER_FRAME_ID_1) - 1;
// send a header frame with stream id 3
args[2].client_validator = nullptr;
args[2].client_payload = HEADER_FRAME_ID_3;
args[2].client_payload_length = sizeof(HEADER_FRAME_ID_3) - 1;
// send a header frame with closed stream id 1 again
args[3].client_validator = nullptr;
args[3].client_payload = HEADER_FRAME_ID_1;
args[3].client_payload_length = sizeof(HEADER_FRAME_ID_1) - 1;
grpc_run_bad_client_test(verifier, args, 4, GRPC_BAD_CLIENT_DISCONNECT);
}
} // namespace
int main(int argc, char** argv) {
grpc_init();
grpc::testing::TestEnvironment env(argc, argv);
::testing::InitGoogleTest(&argc, argv);
int retval = RUN_ALL_TESTS();
grpc_shutdown();
return retval;
}

@ -0,0 +1,112 @@
/*
*
* Copyright 2019 gRPC authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
#include <string>
#include <gtest/gtest.h>
#include <grpc/support/string_util.h>
#include "src/core/lib/surface/server.h"
#include "test/core/bad_client/bad_client.h"
#define APPEND_BUFFER(string, to_append) \
((string).append((to_append), sizeof(to_append) - 1))
namespace {
void verifier(grpc_server* server, grpc_completion_queue* cq,
void* registered_method) {
while (grpc_server_has_open_connections(server)) {
GPR_ASSERT(grpc_completion_queue_next(
cq, grpc_timeout_milliseconds_to_deadline(20), nullptr)
.type == GRPC_QUEUE_TIMEOUT);
}
}
void FrameVerifier(const std::string& attack_vector) {
grpc_bad_client_arg args[2];
args[0] = connection_preface_arg;
args[1].client_validator = nullptr;
args[1].client_payload = attack_vector.c_str();
args[1].client_payload_length = attack_vector.size();
grpc_run_bad_client_test(verifier, args, 2, GRPC_BAD_CLIENT_DISCONNECT);
}
TEST(OutOfBounds, MaxFrameSizeDataFrame) {
std::string out_of_bounds_data;
// Send a data frame larger than 2^14
APPEND_BUFFER(out_of_bounds_data, "\x01\x00\x00\x00\x00\x00\x00\x00\x01");
out_of_bounds_data.append(1 << 16, 'a');
FrameVerifier(out_of_bounds_data);
}
TEST(OutOfBounds, BadSizePriorityFrame) {
std::string bad_size_priority_frame;
// Priority Frame should be a length of 5 octets
APPEND_BUFFER(bad_size_priority_frame,
"\x00\x00\x03\x02\x00\x00\x00\x00\x01"
"\x11\x11\x12");
FrameVerifier(bad_size_priority_frame);
}
TEST(OutOfBounds, BadSizeRstStream) {
std::string bad_size_rst_stream;
// Rst Stream Frame should have a length of 4 octets
APPEND_BUFFER(bad_size_rst_stream,
"\x00\x00\x02\x03\x00\x00\x00\x00\x01"
"\x11\x11");
FrameVerifier(bad_size_rst_stream);
}
TEST(OutOfBounds, BadSizeSettings) {
std::string bad_size_settings;
// Settings Frame should have a length which is a multiple of 6 octets
APPEND_BUFFER(bad_size_settings,
"\x00\x00\x05\x04\x00\x00\x00\x00\x00"
"\x11\x11\x11\x11\x11");
FrameVerifier(bad_size_settings);
}
TEST(OutOfBounds, BadSizePing) {
std::string bad_size_ping;
// Rst Stream Frame should have a length of 8 octets
APPEND_BUFFER(bad_size_ping,
"\x00\x00\x05\x06\x00\x00\x00\x00\x00"
"\x11\x11\x11\x11\x11");
FrameVerifier(bad_size_ping);
}
TEST(OutOfBounds, WindowUpdate) {
std::string bad_size_window_update;
// Window Update Frame should have a length of 4 octets
APPEND_BUFFER(bad_size_window_update,
"\x00\x00\x01\x08\x00\x00\x00\x00\x00"
"\x11");
FrameVerifier(bad_size_window_update);
}
} // namespace
int main(int argc, char** argv) {
grpc_init();
grpc::testing::TestEnvironment env(argc, argv);
::testing::InitGoogleTest(&argc, argv);
int retval = RUN_ALL_TESTS();
grpc_shutdown();
return retval;
}

@ -80,20 +80,20 @@ static void test_algorithm_mesh(void) {
}
static void test_algorithm_failure(void) {
grpc_core::ExecCtx exec_ctx;
grpc_slice mdstr;
gpr_log(GPR_DEBUG, "test_algorithm_failure");
// Test invalid algorithm name
grpc_slice mdstr =
grpc_slice_from_static_string("this-is-an-invalid-algorithm");
GPR_ASSERT(grpc_compression_algorithm_from_slice(mdstr) ==
GRPC_COMPRESS_ALGORITHMS_COUNT);
grpc_slice_unref_internal(mdstr);
// Test invalid algorithm enum entry.
GPR_ASSERT(grpc_compression_algorithm_name(GRPC_COMPRESS_ALGORITHMS_COUNT,
nullptr) == 0);
GPR_ASSERT(
grpc_compression_algorithm_name(static_cast<grpc_compression_algorithm>(
GRPC_COMPRESS_ALGORITHMS_COUNT + 1),
nullptr) == 0);
mdstr = grpc_slice_from_static_string("this-is-an-invalid-algorithm");
GPR_ASSERT(grpc_compression_algorithm_from_slice(mdstr) ==
GRPC_COMPRESS_ALGORITHMS_COUNT);
GPR_ASSERT(grpc_slice_eq(
grpc_compression_algorithm_slice(GRPC_COMPRESS_ALGORITHMS_COUNT),
grpc_empty_slice()));
@ -101,7 +101,6 @@ static void test_algorithm_failure(void) {
grpc_compression_algorithm_slice(static_cast<grpc_compression_algorithm>(
static_cast<int>(GRPC_COMPRESS_ALGORITHMS_COUNT) + 1)),
grpc_empty_slice()));
grpc_slice_unref_internal(mdstr);
}
int main(int argc, char** argv) {

@ -265,8 +265,8 @@ static void test_channel_args_set_compression_algorithm(void) {
grpc_core::ExecCtx exec_ctx;
grpc_channel_args* ch_args;
ch_args =
grpc_channel_args_set_compression_algorithm(nullptr, GRPC_COMPRESS_GZIP);
ch_args = grpc_channel_args_set_channel_default_compression_algorithm(
nullptr, GRPC_COMPRESS_GZIP);
GPR_ASSERT(ch_args->num_args == 1);
GPR_ASSERT(strcmp(ch_args->args[0].key,
GRPC_COMPRESSION_CHANNEL_DEFAULT_ALGORITHM) == 0);

@ -69,8 +69,9 @@ void chttp2_init_client_fullstack_compression(grpc_end2end_test_fixture* f,
grpc_core::ExecCtx exec_ctx;
grpc_channel_args_destroy(ffd->client_args_compression);
}
ffd->client_args_compression = grpc_channel_args_set_compression_algorithm(
client_args, GRPC_COMPRESS_GZIP);
ffd->client_args_compression =
grpc_channel_args_set_channel_default_compression_algorithm(
client_args, GRPC_COMPRESS_GZIP);
f->client = grpc_insecure_channel_create(
ffd->localaddr, ffd->client_args_compression, nullptr);
}
@ -83,8 +84,9 @@ void chttp2_init_server_fullstack_compression(grpc_end2end_test_fixture* f,
grpc_core::ExecCtx exec_ctx;
grpc_channel_args_destroy(ffd->server_args_compression);
}
ffd->server_args_compression = grpc_channel_args_set_compression_algorithm(
server_args, GRPC_COMPRESS_GZIP);
ffd->server_args_compression =
grpc_channel_args_set_channel_default_compression_algorithm(
server_args, GRPC_COMPRESS_GZIP);
if (f->server) {
grpc_server_destroy(f->server);
}

@ -124,10 +124,10 @@ static void request_for_disabled_algorithm(
request_payload_slice = grpc_slice_from_copied_string(str);
request_payload = grpc_raw_byte_buffer_create(&request_payload_slice, 1);
client_args = grpc_channel_args_set_compression_algorithm(
client_args = grpc_channel_args_set_channel_default_compression_algorithm(
nullptr, requested_client_compression_algorithm);
server_args =
grpc_channel_args_set_compression_algorithm(nullptr, GRPC_COMPRESS_NONE);
server_args = grpc_channel_args_set_channel_default_compression_algorithm(
nullptr, GRPC_COMPRESS_NONE);
{
grpc_core::ExecCtx exec_ctx;
server_args = grpc_channel_args_compression_algorithm_set_state(
@ -308,9 +308,9 @@ static void request_with_payload_template(
grpc_slice response_payload_slice =
grpc_slice_from_copied_string(response_str);
client_args = grpc_channel_args_set_compression_algorithm(
client_args = grpc_channel_args_set_channel_default_compression_algorithm(
nullptr, default_client_channel_compression_algorithm);
server_args = grpc_channel_args_set_compression_algorithm(
server_args = grpc_channel_args_set_channel_default_compression_algorithm(
nullptr, default_server_channel_compression_algorithm);
f = begin_test(config, test_name, client_args, server_args);

@ -124,10 +124,10 @@ static void request_for_disabled_algorithm(
request_payload_slice = grpc_slice_from_copied_string(str);
request_payload = grpc_raw_byte_buffer_create(&request_payload_slice, 1);
client_args = grpc_channel_args_set_compression_algorithm(
client_args = grpc_channel_args_set_channel_default_compression_algorithm(
nullptr, requested_client_compression_algorithm);
server_args =
grpc_channel_args_set_compression_algorithm(nullptr, GRPC_COMPRESS_NONE);
server_args = grpc_channel_args_set_channel_default_compression_algorithm(
nullptr, GRPC_COMPRESS_NONE);
{
grpc_core::ExecCtx exec_ctx;
server_args = grpc_channel_args_compression_algorithm_set_state(
@ -310,13 +310,13 @@ static void request_with_payload_template(
grpc_slice response_payload_slice =
grpc_slice_from_copied_string(response_str);
client_args = grpc_channel_args_set_compression_algorithm(
client_args = grpc_channel_args_set_channel_default_compression_algorithm(
nullptr, default_client_channel_compression_algorithm);
if (set_default_server_message_compression_algorithm) {
server_args = grpc_channel_args_set_compression_algorithm(
server_args = grpc_channel_args_set_channel_default_compression_algorithm(
nullptr, default_server_message_compression_algorithm);
} else {
server_args = grpc_channel_args_set_compression_algorithm(
server_args = grpc_channel_args_set_channel_default_compression_algorithm(
nullptr, default_server_channel_compression_algorithm);
}

@ -263,10 +263,12 @@ static void request_response_with_payload(grpc_end2end_test_config config,
payload and status. */
static void test_invoke_request_response_with_payload(
grpc_end2end_test_config config) {
grpc_channel_args* client_args = grpc_channel_args_set_compression_algorithm(
nullptr, GRPC_COMPRESS_STREAM_GZIP);
grpc_channel_args* server_args = grpc_channel_args_set_compression_algorithm(
nullptr, GRPC_COMPRESS_STREAM_GZIP);
grpc_channel_args* client_args =
grpc_channel_args_set_channel_default_compression_algorithm(
nullptr, GRPC_COMPRESS_STREAM_GZIP);
grpc_channel_args* server_args =
grpc_channel_args_set_channel_default_compression_algorithm(
nullptr, GRPC_COMPRESS_STREAM_GZIP);
grpc_end2end_test_fixture f =
begin_test(config, "test_invoke_request_response_with_payload",
client_args, server_args);

@ -91,10 +91,12 @@ static void end_test(grpc_end2end_test_fixture* f) {
/* Client pings and server pongs. Repeat messages rounds before finishing. */
static void test_pingpong_streaming(grpc_end2end_test_config config,
int messages) {
grpc_channel_args* client_args = grpc_channel_args_set_compression_algorithm(
nullptr, GRPC_COMPRESS_STREAM_GZIP);
grpc_channel_args* server_args = grpc_channel_args_set_compression_algorithm(
nullptr, GRPC_COMPRESS_STREAM_GZIP);
grpc_channel_args* client_args =
grpc_channel_args_set_channel_default_compression_algorithm(
nullptr, GRPC_COMPRESS_STREAM_GZIP);
grpc_channel_args* server_args =
grpc_channel_args_set_channel_default_compression_algorithm(
nullptr, GRPC_COMPRESS_STREAM_GZIP);
grpc_end2end_test_fixture f =
begin_test(config, "test_pingpong_streaming", client_args, server_args);
grpc_call* c;

@ -136,9 +136,9 @@ static void request_with_payload_template(
grpc_slice response_payload_slice =
grpc_slice_from_copied_string(response_str);
client_args = grpc_channel_args_set_compression_algorithm(
client_args = grpc_channel_args_set_channel_default_compression_algorithm(
nullptr, default_client_channel_compression_algorithm);
server_args = grpc_channel_args_set_compression_algorithm(
server_args = grpc_channel_args_set_channel_default_compression_algorithm(
nullptr, default_server_channel_compression_algorithm);
if (user_agent_override) {

@ -62,6 +62,9 @@ void test_encoding(void) {
assert_encodes_as(20 * 60 * GPR_MS_PER_SEC, "20M");
assert_encodes_as(60 * 60 * GPR_MS_PER_SEC, "1H");
assert_encodes_as(10 * 60 * 60 * GPR_MS_PER_SEC, "10H");
assert_encodes_as(60 * 60 * GPR_MS_PER_SEC - 100, "1H");
assert_encodes_as(100 * 60 * 60 * GPR_MS_PER_SEC, "100H");
assert_encodes_as(100000000000, "99999999S");
}
static void assert_decodes_as(const char* buffer, grpc_millis expected) {

@ -369,7 +369,6 @@ grpc_cc_test(
name = "mock_test",
srcs = ["mock_test.cc"],
external_deps = [
"gmock",
"gtest",
],
deps = [
@ -406,7 +405,6 @@ grpc_cc_test(
name = "client_lb_end2end_test",
srcs = ["client_lb_end2end_test.cc"],
external_deps = [
"gmock",
"gtest",
],
deps = [
@ -427,7 +425,6 @@ grpc_cc_test(
name = "service_config_end2end_test",
srcs = ["service_config_end2end_test.cc"],
external_deps = [
"gmock",
"gtest",
],
deps = [
@ -447,7 +444,6 @@ grpc_cc_test(
name = "grpclb_end2end_test",
srcs = ["grpclb_end2end_test.cc"],
external_deps = [
"gmock",
"gtest",
],
deps = [
@ -469,7 +465,6 @@ grpc_cc_test(
name = "xds_end2end_test",
srcs = ["xds_end2end_test.cc"],
external_deps = [
"gmock",
"gtest",
],
deps = [
@ -594,7 +589,6 @@ grpc_cc_test(
srcs = ["server_load_reporting_end2end_test.cc"],
external_deps = [
"gtest",
"gmock",
],
deps = [
"//:grpcpp_server_load_reporting",

@ -26,7 +26,6 @@ grpc_cc_test(
],
external_deps = [
"gtest",
"gmock",
"opencensus-stats-test",
],
language = "C++",

@ -37,7 +37,7 @@ grpc_py_binary(
grpc_cc_test(
name = "cancel_ares_query_test",
srcs = ["cancel_ares_query_test.cc"],
external_deps = ["gmock"],
external_deps = ["gtest"],
deps = [
":dns_test_util",
"//:gpr",

@ -23,7 +23,7 @@ def generate_resolver_component_tests():
"address_sorting_test.cc",
],
external_deps = [
"gmock",
"gtest",
],
deps = [
"//test/cpp/util:test_util%s" % unsecure_build_config_suffix,
@ -43,7 +43,7 @@ def generate_resolver_component_tests():
"resolver_component_test.cc",
],
external_deps = [
"gmock",
"gtest",
],
deps = [
":dns_test_util",

@ -35,7 +35,6 @@ grpc_cc_test(
srcs = ["load_reporter_test.cc"],
external_deps = [
"gtest",
"gmock",
"opencensus-stats-test",
],
deps = [

@ -1 +1 @@
Subproject commit ec44c6c1675c25b9827aacd08c02433cccde7780
Subproject commit 2fe3bd994b3189899d93f1d5a881e725e046fdc2

@ -1,42 +0,0 @@
cc_library(
name = "gtest",
srcs = [
"googletest/src/gtest-all.cc",
],
hdrs = glob([
"googletest/include/**/*.h",
"googletest/src/*.cc",
"googletest/src/*.h",
]),
includes = [
"googletest",
"googletest/include",
],
linkstatic = 1,
visibility = [
"//visibility:public",
],
)
cc_library(
name = "gmock",
srcs = [
"googlemock/src/gmock-all.cc"
],
hdrs = glob([
"googlemock/include/**/*.h",
"googlemock/src/*.cc",
"googlemock/src/*.h"
]),
includes = [
"googlemock",
"googlemock/include",
],
deps = [
":gtest",
],
linkstatic = 1,
visibility = [
"//visibility:public",
],
)

@ -32,7 +32,7 @@ then
exec -a "$0" "${BAZEL_REAL}" "$@"
fi
VERSION=0.24.1
VERSION=0.26.0
echo "INFO: Running bazel wrapper (see //tools/bazel for details), bazel version $VERSION will be used instead of system-wide bazel installation."

@ -51,6 +51,10 @@ build:ubsan --copt=-DUNDEFINED_BEHAVIOR_SANITIZER # used by absl
build:ubsan --copt=-fno-sanitize=function,vptr
build:ubsan --linkopt=-fsanitize=undefined
build:ubsan --action_env=UBSAN_OPTIONS=halt_on_error=1:print_stacktrace=1:suppressions=test/core/util/ubsan_suppressions.txt
# For some reasons, these two stopped being propagated, so, redeclaring them here.
# That's a hack that needs to be removed once we understand what's going on.
build:ubsan --copt=-DPB_FIELD_32BIT=1
build:ubsan --copt=-DGRPC_PORT_ISOLATED_RUNTIME=1
build:basicprof --strip=never
build:basicprof --copt=-DNDEBUG
@ -59,5 +63,5 @@ build:basicprof --copt=-DGRPC_BASIC_PROFILER
build:basicprof --copt=-DGRPC_TIMERS_RDTSC
build:python3 --python_path=python3
build:python3 --force_python=PY3
build:python3 --python_version=PY3
build:python3 --action_env=PYTHON_BIN_PATH=python3

Some files were not shown because too many files have changed in this diff Show More

Loading…
Cancel
Save