Merge branch 'master' into svc_cfg2

reviewable/pr18746/r1
Yash Tibrewal 6 years ago
commit c3ae72c089
  1. 4
      .pylintrc
  2. 27
      BUILD
  3. 6
      BUILD.gn
  4. 53
      CMakeLists.txt
  5. 61
      Makefile
  6. 26
      WORKSPACE
  7. 5
      bazel/grpc_build_system.bzl
  8. 12
      bazel/grpc_deps.bzl
  9. 5
      build.yaml
  10. 1
      config.m4
  11. 1
      config.w32
  12. 2
      doc/core/grpc-polling-engines.md
  13. 10
      doc/environment_variables.md
  14. 6
      doc/python/sphinx/grpc.rst
  15. 2
      examples/csharp/HelloworldXamarin/iOS/AppDelegate.cs
  16. 32
      examples/python/wait_for_ready/BUILD.bazel
  17. 32
      examples/python/wait_for_ready/README.md
  18. 26
      examples/python/wait_for_ready/test/_wait_for_ready_example_test.py
  19. 114
      examples/python/wait_for_ready/wait_for_ready_example.py
  20. 2
      examples/ruby/without_protobuf/echo_client.rb
  21. 5
      gRPC-C++.podspec
  22. 3
      gRPC-Core.podspec
  23. 2
      grpc.gemspec
  24. 4
      grpc.gyp
  25. 2
      include/grpc/grpc_security.h
  26. 10
      include/grpc/impl/codegen/port_platform.h
  27. 2
      include/grpc/slice.h
  28. 88
      include/grpcpp/channel.h
  29. 117
      include/grpcpp/channel_impl.h
  30. 6
      include/grpcpp/create_channel_impl.h
  31. 2
      include/grpcpp/generic/generic_stub_impl.h
  32. 10
      include/grpcpp/impl/codegen/async_generic_service.h
  33. 16
      include/grpcpp/impl/codegen/async_stream.h
  34. 1
      include/grpcpp/impl/codegen/async_unary_call.h
  35. 14
      include/grpcpp/impl/codegen/call.h
  36. 1
      include/grpcpp/impl/codegen/call_op_set.h
  37. 16
      include/grpcpp/impl/codegen/channel_interface.h
  38. 6
      include/grpcpp/impl/codegen/client_callback.h
  39. 14
      include/grpcpp/impl/codegen/client_context.h
  40. 6
      include/grpcpp/impl/codegen/client_interceptor.h
  41. 2
      include/grpcpp/impl/codegen/client_unary_call.h
  42. 379
      include/grpcpp/impl/codegen/completion_queue.h
  43. 422
      include/grpcpp/impl/codegen/completion_queue_impl.h
  44. 13
      include/grpcpp/impl/codegen/intercepted_channel.h
  45. 38
      include/grpcpp/impl/codegen/server_callback.h
  46. 11
      include/grpcpp/impl/codegen/server_context.h
  47. 77
      include/grpcpp/impl/codegen/server_interface.h
  48. 9
      include/grpcpp/impl/codegen/service_type.h
  49. 17
      include/grpcpp/impl/codegen/sync.h
  50. 6
      include/grpcpp/impl/codegen/sync_stream.h
  51. 2
      include/grpcpp/impl/server_initializer_impl.h
  52. 19
      include/grpcpp/security/credentials.h
  53. 4
      include/grpcpp/security/server_credentials.h
  54. 4
      include/grpcpp/security/server_credentials_impl.h
  55. 328
      include/grpcpp/server.h
  56. 6
      include/grpcpp/server_builder.h
  57. 6
      include/grpcpp/server_builder_impl.h
  58. 1
      include/grpcpp/server_impl.h
  59. 2
      package.xml
  60. 55
      src/compiler/cpp_generator.cc
  61. 4
      src/compiler/cpp_generator.h
  62. 10
      src/compiler/cpp_plugin.cc
  63. 16
      src/compiler/objective_c_generator.cc
  64. 9
      src/compiler/protobuf_plugin.h
  65. 1
      src/compiler/schema_interface.h
  66. 1041
      src/core/ext/filters/client_channel/client_channel.cc
  67. 5
      src/core/ext/filters/client_channel/client_channel_channelz.cc
  68. 1
      src/core/ext/filters/client_channel/lb_policy.h
  69. 24
      src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc
  70. 67
      src/core/ext/filters/client_channel/lb_policy/pick_first/pick_first.cc
  71. 48
      src/core/ext/filters/client_channel/lb_policy/round_robin/round_robin.cc
  72. 12
      src/core/ext/filters/client_channel/lb_policy/subchannel_list.h
  73. 22
      src/core/ext/filters/client_channel/lb_policy/xds/xds.cc
  74. 8
      src/core/ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.cc
  75. 24
      src/core/ext/filters/client_channel/resolving_lb_policy.cc
  76. 40
      src/core/ext/filters/client_channel/subchannel.cc
  77. 5
      src/core/ext/filters/client_channel/subchannel.h
  78. 1
      src/core/ext/filters/http/message_compress/message_compress_filter.cc
  79. 18
      src/core/ext/transport/chttp2/transport/chttp2_transport.cc
  80. 8
      src/core/ext/transport/cronet/transport/cronet_transport.cc
  81. 6
      src/core/ext/transport/inproc/inproc_transport.cc
  82. 105
      src/core/ext/upb-generated/envoy/api/v2/endpoint/load_report.upb.c
  83. 299
      src/core/ext/upb-generated/envoy/api/v2/endpoint/load_report.upb.h
  84. 52
      src/core/ext/upb-generated/envoy/service/load_stats/v2/lrs.upb.c
  85. 132
      src/core/ext/upb-generated/envoy/service/load_stats/v2/lrs.upb.h
  86. 101
      src/core/lib/channel/channel_args.cc
  87. 37
      src/core/lib/channel/channel_args.h
  88. 127
      src/core/lib/compression/compression_args.cc
  89. 55
      src/core/lib/compression/compression_args.h
  90. 50
      src/core/lib/gpr/arena.cc
  91. 2
      src/core/lib/gpr/arena.h
  92. 2
      src/core/lib/iomgr/ev_epoll1_linux.cc
  93. 3
      src/core/lib/iomgr/iomgr_custom.cc
  94. 2
      src/core/lib/iomgr/iomgr_custom.h
  95. 9
      src/core/lib/iomgr/port.h
  96. 4
      src/core/lib/iomgr/socket_utils_common_posix.cc
  97. 14
      src/core/lib/iomgr/tcp_windows.cc
  98. 5
      src/core/lib/security/security_connector/ssl/ssl_security_connector.cc
  99. 1
      src/core/lib/surface/init.cc
  100. 42
      src/core/lib/transport/connectivity_state.cc
  101. Some files were not shown because too many files have changed in this diff Show More

@ -6,6 +6,8 @@ ignore=
src/python/grpcio/grpc/framework/foundation,
src/python/grpcio/grpc/framework/interfaces,
extension-pkg-whitelist=grpc._cython.cygrpc
[VARIABLES]
# TODO(https://github.com/PyCQA/pylint/issues/1345): How does the inspection
@ -17,7 +19,7 @@ dummy-variables-rgx=^ignored_|^unused_
# NOTE(nathaniel): Not particularly attached to this value; it just seems to
# be what works for us at the moment (excepting the dead-code-walking Beta
# API).
max-args=6
max-args=7
[MISCELLANEOUS]

27
BUILD

@ -216,7 +216,6 @@ GRPCXX_PUBLIC_HDRS = [
"include/grpcpp/alarm.h",
"include/grpcpp/alarm_impl.h",
"include/grpcpp/channel.h",
"include/grpcpp/channel_impl.h",
"include/grpcpp/client_context.h",
"include/grpcpp/completion_queue.h",
"include/grpcpp/create_channel.h",
@ -256,7 +255,6 @@ GRPCXX_PUBLIC_HDRS = [
"include/grpcpp/security/server_credentials.h",
"include/grpcpp/security/server_credentials_impl.h",
"include/grpcpp/server.h",
"include/grpcpp/server_impl.h",
"include/grpcpp/server_builder.h",
"include/grpcpp/server_builder_impl.h",
"include/grpcpp/server_context.h",
@ -738,6 +736,7 @@ grpc_cc_library(
"src/core/lib/channel/handshaker_registry.cc",
"src/core/lib/channel/status_util.cc",
"src/core/lib/compression/compression.cc",
"src/core/lib/compression/compression_args.cc",
"src/core/lib/compression/compression_internal.cc",
"src/core/lib/compression/message_compress.cc",
"src/core/lib/compression/stream_compression.cc",
@ -893,6 +892,7 @@ grpc_cc_library(
"src/core/lib/channel/handshaker_registry.h",
"src/core/lib/channel/status_util.h",
"src/core/lib/compression/algorithm_metadata.h",
"src/core/lib/compression/compression_args.h",
"src/core/lib/compression/compression_internal.h",
"src/core/lib/compression/message_compress.h",
"src/core/lib/compression/stream_compression.h",
@ -2132,7 +2132,6 @@ grpc_cc_library(
"include/grpcpp/impl/codegen/client_interceptor.h",
"include/grpcpp/impl/codegen/client_unary_call.h",
"include/grpcpp/impl/codegen/completion_queue.h",
"include/grpcpp/impl/codegen/completion_queue_impl.h",
"include/grpcpp/impl/codegen/completion_queue_tag.h",
"include/grpcpp/impl/codegen/config.h",
"include/grpcpp/impl/codegen/core_codegen_interface.h",
@ -2333,6 +2332,28 @@ grpc_cc_library(
)
#TODO: Get this into build.yaml once we start using it.
grpc_cc_library(
name = "envoy_lrs_upb",
srcs = [
"src/core/ext/upb-generated/envoy/api/v2/endpoint/load_report.upb.c",
"src/core/ext/upb-generated/envoy/service/load_stats/v2/lrs.upb.c",
],
hdrs = [
"src/core/ext/upb-generated/envoy/api/v2/endpoint/load_report.upb.h",
"src/core/ext/upb-generated/envoy/service/load_stats/v2/lrs.upb.h",
],
language = "c++",
external_deps = [
"upb_lib",
],
deps = [
":envoy_core_upb",
":google_api_upb",
":proto_gen_validate_upb",
],
tags = ["no_windows"],
)
grpc_cc_library(
name = "envoy_ads_upb",
srcs = [

@ -447,6 +447,8 @@ config("grpc_config") {
"src/core/lib/channel/status_util.h",
"src/core/lib/compression/algorithm_metadata.h",
"src/core/lib/compression/compression.cc",
"src/core/lib/compression/compression_args.cc",
"src/core/lib/compression/compression_args.h",
"src/core/lib/compression/compression_internal.cc",
"src/core/lib/compression/compression_internal.h",
"src/core/lib/compression/message_compress.cc",
@ -1005,7 +1007,6 @@ config("grpc_config") {
"include/grpcpp/alarm.h",
"include/grpcpp/alarm_impl.h",
"include/grpcpp/channel.h",
"include/grpcpp/channel_impl.h",
"include/grpcpp/client_context.h",
"include/grpcpp/completion_queue.h",
"include/grpcpp/create_channel.h",
@ -1037,7 +1038,6 @@ config("grpc_config") {
"include/grpcpp/impl/codegen/client_interceptor.h",
"include/grpcpp/impl/codegen/client_unary_call.h",
"include/grpcpp/impl/codegen/completion_queue.h",
"include/grpcpp/impl/codegen/completion_queue_impl.h",
"include/grpcpp/impl/codegen/completion_queue_tag.h",
"include/grpcpp/impl/codegen/config.h",
"include/grpcpp/impl/codegen/config_protobuf.h",
@ -1094,7 +1094,6 @@ config("grpc_config") {
"include/grpcpp/server_builder.h",
"include/grpcpp/server_builder_impl.h",
"include/grpcpp/server_context.h",
"include/grpcpp/server_impl.h",
"include/grpcpp/server_posix.h",
"include/grpcpp/server_posix_impl.h",
"include/grpcpp/support/async_stream.h",
@ -1132,6 +1131,7 @@ config("grpc_config") {
"src/core/lib/channel/handshaker_registry.h",
"src/core/lib/channel/status_util.h",
"src/core/lib/compression/algorithm_metadata.h",
"src/core/lib/compression/compression_args.h",
"src/core/lib/compression/compression_internal.h",
"src/core/lib/compression/message_compress.h",
"src/core/lib/compression/stream_compression.h",

@ -484,6 +484,7 @@ add_dependencies(buildtests_c h2_sockpair+trace_test)
add_dependencies(buildtests_c h2_sockpair_1byte_test)
add_dependencies(buildtests_c h2_spiffe_test)
add_dependencies(buildtests_c h2_ssl_test)
add_dependencies(buildtests_c h2_ssl_cred_reload_test)
add_dependencies(buildtests_c h2_ssl_proxy_test)
if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX)
add_dependencies(buildtests_c h2_uds_test)
@ -982,6 +983,7 @@ add_library(grpc
src/core/lib/channel/handshaker_registry.cc
src/core/lib/channel/status_util.cc
src/core/lib/compression/compression.cc
src/core/lib/compression/compression_args.cc
src/core/lib/compression/compression_internal.cc
src/core/lib/compression/message_compress.cc
src/core/lib/compression/stream_compression.cc
@ -1409,6 +1411,7 @@ add_library(grpc_cronet
src/core/lib/channel/handshaker_registry.cc
src/core/lib/channel/status_util.cc
src/core/lib/compression/compression.cc
src/core/lib/compression/compression_args.cc
src/core/lib/compression/compression_internal.cc
src/core/lib/compression/message_compress.cc
src/core/lib/compression/stream_compression.cc
@ -1821,6 +1824,7 @@ add_library(grpc_test_util
src/core/lib/channel/handshaker_registry.cc
src/core/lib/channel/status_util.cc
src/core/lib/compression/compression.cc
src/core/lib/compression/compression_args.cc
src/core/lib/compression/compression_internal.cc
src/core/lib/compression/message_compress.cc
src/core/lib/compression/stream_compression.cc
@ -2146,6 +2150,7 @@ add_library(grpc_test_util_unsecure
src/core/lib/channel/handshaker_registry.cc
src/core/lib/channel/status_util.cc
src/core/lib/compression/compression.cc
src/core/lib/compression/compression_args.cc
src/core/lib/compression/compression_internal.cc
src/core/lib/compression/message_compress.cc
src/core/lib/compression/stream_compression.cc
@ -2447,6 +2452,7 @@ add_library(grpc_unsecure
src/core/lib/channel/handshaker_registry.cc
src/core/lib/channel/status_util.cc
src/core/lib/compression/compression.cc
src/core/lib/compression/compression_args.cc
src/core/lib/compression/compression_internal.cc
src/core/lib/compression/message_compress.cc
src/core/lib/compression/stream_compression.cc
@ -3003,7 +3009,6 @@ foreach(_hdr
include/grpcpp/alarm.h
include/grpcpp/alarm_impl.h
include/grpcpp/channel.h
include/grpcpp/channel_impl.h
include/grpcpp/client_context.h
include/grpcpp/completion_queue.h
include/grpcpp/create_channel.h
@ -3044,7 +3049,6 @@ foreach(_hdr
include/grpcpp/server_builder.h
include/grpcpp/server_builder_impl.h
include/grpcpp/server_context.h
include/grpcpp/server_impl.h
include/grpcpp/server_posix.h
include/grpcpp/server_posix_impl.h
include/grpcpp/support/async_stream.h
@ -3162,7 +3166,6 @@ foreach(_hdr
include/grpcpp/impl/codegen/client_interceptor.h
include/grpcpp/impl/codegen/client_unary_call.h
include/grpcpp/impl/codegen/completion_queue.h
include/grpcpp/impl/codegen/completion_queue_impl.h
include/grpcpp/impl/codegen/completion_queue_tag.h
include/grpcpp/impl/codegen/config.h
include/grpcpp/impl/codegen/core_codegen_interface.h
@ -3350,6 +3353,7 @@ add_library(grpc++_cronet
src/core/lib/channel/handshaker_registry.cc
src/core/lib/channel/status_util.cc
src/core/lib/compression/compression.cc
src/core/lib/compression/compression_args.cc
src/core/lib/compression/compression_internal.cc
src/core/lib/compression/message_compress.cc
src/core/lib/compression/stream_compression.cc
@ -3610,7 +3614,6 @@ foreach(_hdr
include/grpcpp/alarm.h
include/grpcpp/alarm_impl.h
include/grpcpp/channel.h
include/grpcpp/channel_impl.h
include/grpcpp/client_context.h
include/grpcpp/completion_queue.h
include/grpcpp/create_channel.h
@ -3651,7 +3654,6 @@ foreach(_hdr
include/grpcpp/server_builder.h
include/grpcpp/server_builder_impl.h
include/grpcpp/server_context.h
include/grpcpp/server_impl.h
include/grpcpp/server_posix.h
include/grpcpp/server_posix_impl.h
include/grpcpp/support/async_stream.h
@ -3769,7 +3771,6 @@ foreach(_hdr
include/grpcpp/impl/codegen/client_interceptor.h
include/grpcpp/impl/codegen/client_unary_call.h
include/grpcpp/impl/codegen/completion_queue.h
include/grpcpp/impl/codegen/completion_queue_impl.h
include/grpcpp/impl/codegen/completion_queue_tag.h
include/grpcpp/impl/codegen/config.h
include/grpcpp/impl/codegen/core_codegen_interface.h
@ -4203,7 +4204,6 @@ foreach(_hdr
include/grpcpp/impl/codegen/client_interceptor.h
include/grpcpp/impl/codegen/client_unary_call.h
include/grpcpp/impl/codegen/completion_queue.h
include/grpcpp/impl/codegen/completion_queue_impl.h
include/grpcpp/impl/codegen/completion_queue_tag.h
include/grpcpp/impl/codegen/config.h
include/grpcpp/impl/codegen/core_codegen_interface.h
@ -4401,7 +4401,6 @@ foreach(_hdr
include/grpcpp/impl/codegen/client_interceptor.h
include/grpcpp/impl/codegen/client_unary_call.h
include/grpcpp/impl/codegen/completion_queue.h
include/grpcpp/impl/codegen/completion_queue_impl.h
include/grpcpp/impl/codegen/completion_queue_tag.h
include/grpcpp/impl/codegen/config.h
include/grpcpp/impl/codegen/core_codegen_interface.h
@ -4594,7 +4593,6 @@ foreach(_hdr
include/grpcpp/alarm.h
include/grpcpp/alarm_impl.h
include/grpcpp/channel.h
include/grpcpp/channel_impl.h
include/grpcpp/client_context.h
include/grpcpp/completion_queue.h
include/grpcpp/create_channel.h
@ -4635,7 +4633,6 @@ foreach(_hdr
include/grpcpp/server_builder.h
include/grpcpp/server_builder_impl.h
include/grpcpp/server_context.h
include/grpcpp/server_impl.h
include/grpcpp/server_posix.h
include/grpcpp/server_posix_impl.h
include/grpcpp/support/async_stream.h
@ -4753,7 +4750,6 @@ foreach(_hdr
include/grpcpp/impl/codegen/client_interceptor.h
include/grpcpp/impl/codegen/client_unary_call.h
include/grpcpp/impl/codegen/completion_queue.h
include/grpcpp/impl/codegen/completion_queue_impl.h
include/grpcpp/impl/codegen/completion_queue_tag.h
include/grpcpp/impl/codegen/config.h
include/grpcpp/impl/codegen/core_codegen_interface.h
@ -17695,6 +17691,41 @@ target_link_libraries(h2_ssl_test
endif (gRPC_BUILD_TESTS)
if (gRPC_BUILD_TESTS)
add_executable(h2_ssl_cred_reload_test
test/core/end2end/fixtures/h2_ssl_cred_reload.cc
)
target_include_directories(h2_ssl_cred_reload_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}
)
target_link_libraries(h2_ssl_cred_reload_test
${_gRPC_ALLTARGETS_LIBRARIES}
end2end_tests
grpc_test_util
grpc
gpr
)
# avoid dependency on libstdc++
if (_gRPC_CORE_NOSTDCXX_FLAGS)
set_target_properties(h2_ssl_cred_reload_test PROPERTIES LINKER_LANGUAGE C)
target_compile_options(h2_ssl_cred_reload_test PRIVATE $<$<COMPILE_LANGUAGE:CXX>:${_gRPC_CORE_NOSTDCXX_FLAGS}>)
endif()
endif (gRPC_BUILD_TESTS)
if (gRPC_BUILD_TESTS)
add_executable(h2_ssl_proxy_test
test/core/end2end/fixtures/h2_ssl_proxy.cc
)

@ -478,11 +478,11 @@ LDFLAGS += $(EXTRA_LDFLAGS)
DEFINES += $(EXTRA_DEFINES)
LDLIBS += $(EXTRA_LDLIBS)
HOST_CPPFLAGS = $(CPPFLAGS)
HOST_CFLAGS = $(CFLAGS)
HOST_CXXFLAGS = $(CXXFLAGS)
HOST_LDFLAGS = $(LDFLAGS)
HOST_LDLIBS = $(LDLIBS)
HOST_CPPFLAGS += $(CPPFLAGS)
HOST_CFLAGS += $(CFLAGS)
HOST_CXXFLAGS += $(CXXFLAGS)
HOST_LDFLAGS += $(LDFLAGS)
HOST_LDLIBS += $(LDLIBS)
# These are automatically computed variables.
# There shouldn't be any need to change anything from now on.
@ -1316,6 +1316,7 @@ h2_sockpair+trace_test: $(BINDIR)/$(CONFIG)/h2_sockpair+trace_test
h2_sockpair_1byte_test: $(BINDIR)/$(CONFIG)/h2_sockpair_1byte_test
h2_spiffe_test: $(BINDIR)/$(CONFIG)/h2_spiffe_test
h2_ssl_test: $(BINDIR)/$(CONFIG)/h2_ssl_test
h2_ssl_cred_reload_test: $(BINDIR)/$(CONFIG)/h2_ssl_cred_reload_test
h2_ssl_proxy_test: $(BINDIR)/$(CONFIG)/h2_ssl_proxy_test
h2_uds_test: $(BINDIR)/$(CONFIG)/h2_uds_test
inproc_test: $(BINDIR)/$(CONFIG)/inproc_test
@ -1579,6 +1580,7 @@ buildtests_c: privatelibs_c \
$(BINDIR)/$(CONFIG)/h2_sockpair_1byte_test \
$(BINDIR)/$(CONFIG)/h2_spiffe_test \
$(BINDIR)/$(CONFIG)/h2_ssl_test \
$(BINDIR)/$(CONFIG)/h2_ssl_cred_reload_test \
$(BINDIR)/$(CONFIG)/h2_ssl_proxy_test \
$(BINDIR)/$(CONFIG)/h2_uds_test \
$(BINDIR)/$(CONFIG)/inproc_test \
@ -3437,6 +3439,7 @@ LIBGRPC_SRC = \
src/core/lib/channel/handshaker_registry.cc \
src/core/lib/channel/status_util.cc \
src/core/lib/compression/compression.cc \
src/core/lib/compression/compression_args.cc \
src/core/lib/compression/compression_internal.cc \
src/core/lib/compression/message_compress.cc \
src/core/lib/compression/stream_compression.cc \
@ -3858,6 +3861,7 @@ LIBGRPC_CRONET_SRC = \
src/core/lib/channel/handshaker_registry.cc \
src/core/lib/channel/status_util.cc \
src/core/lib/compression/compression.cc \
src/core/lib/compression/compression_args.cc \
src/core/lib/compression/compression_internal.cc \
src/core/lib/compression/message_compress.cc \
src/core/lib/compression/stream_compression.cc \
@ -4263,6 +4267,7 @@ LIBGRPC_TEST_UTIL_SRC = \
src/core/lib/channel/handshaker_registry.cc \
src/core/lib/channel/status_util.cc \
src/core/lib/compression/compression.cc \
src/core/lib/compression/compression_args.cc \
src/core/lib/compression/compression_internal.cc \
src/core/lib/compression/message_compress.cc \
src/core/lib/compression/stream_compression.cc \
@ -4575,6 +4580,7 @@ LIBGRPC_TEST_UTIL_UNSECURE_SRC = \
src/core/lib/channel/handshaker_registry.cc \
src/core/lib/channel/status_util.cc \
src/core/lib/compression/compression.cc \
src/core/lib/compression/compression_args.cc \
src/core/lib/compression/compression_internal.cc \
src/core/lib/compression/message_compress.cc \
src/core/lib/compression/stream_compression.cc \
@ -4850,6 +4856,7 @@ LIBGRPC_UNSECURE_SRC = \
src/core/lib/channel/handshaker_registry.cc \
src/core/lib/channel/status_util.cc \
src/core/lib/compression/compression.cc \
src/core/lib/compression/compression_args.cc \
src/core/lib/compression/compression_internal.cc \
src/core/lib/compression/message_compress.cc \
src/core/lib/compression/stream_compression.cc \
@ -5338,7 +5345,6 @@ PUBLIC_HEADERS_CXX += \
include/grpcpp/alarm.h \
include/grpcpp/alarm_impl.h \
include/grpcpp/channel.h \
include/grpcpp/channel_impl.h \
include/grpcpp/client_context.h \
include/grpcpp/completion_queue.h \
include/grpcpp/create_channel.h \
@ -5379,7 +5385,6 @@ PUBLIC_HEADERS_CXX += \
include/grpcpp/server_builder.h \
include/grpcpp/server_builder_impl.h \
include/grpcpp/server_context.h \
include/grpcpp/server_impl.h \
include/grpcpp/server_posix.h \
include/grpcpp/server_posix_impl.h \
include/grpcpp/support/async_stream.h \
@ -5497,7 +5502,6 @@ PUBLIC_HEADERS_CXX += \
include/grpcpp/impl/codegen/client_interceptor.h \
include/grpcpp/impl/codegen/client_unary_call.h \
include/grpcpp/impl/codegen/completion_queue.h \
include/grpcpp/impl/codegen/completion_queue_impl.h \
include/grpcpp/impl/codegen/completion_queue_tag.h \
include/grpcpp/impl/codegen/config.h \
include/grpcpp/impl/codegen/core_codegen_interface.h \
@ -5729,6 +5733,7 @@ LIBGRPC++_CRONET_SRC = \
src/core/lib/channel/handshaker_registry.cc \
src/core/lib/channel/status_util.cc \
src/core/lib/compression/compression.cc \
src/core/lib/compression/compression_args.cc \
src/core/lib/compression/compression_internal.cc \
src/core/lib/compression/message_compress.cc \
src/core/lib/compression/stream_compression.cc \
@ -5953,7 +5958,6 @@ PUBLIC_HEADERS_CXX += \
include/grpcpp/alarm.h \
include/grpcpp/alarm_impl.h \
include/grpcpp/channel.h \
include/grpcpp/channel_impl.h \
include/grpcpp/client_context.h \
include/grpcpp/completion_queue.h \
include/grpcpp/create_channel.h \
@ -5994,7 +5998,6 @@ PUBLIC_HEADERS_CXX += \
include/grpcpp/server_builder.h \
include/grpcpp/server_builder_impl.h \
include/grpcpp/server_context.h \
include/grpcpp/server_impl.h \
include/grpcpp/server_posix.h \
include/grpcpp/server_posix_impl.h \
include/grpcpp/support/async_stream.h \
@ -6112,7 +6115,6 @@ PUBLIC_HEADERS_CXX += \
include/grpcpp/impl/codegen/client_interceptor.h \
include/grpcpp/impl/codegen/client_unary_call.h \
include/grpcpp/impl/codegen/completion_queue.h \
include/grpcpp/impl/codegen/completion_queue_impl.h \
include/grpcpp/impl/codegen/completion_queue_tag.h \
include/grpcpp/impl/codegen/config.h \
include/grpcpp/impl/codegen/core_codegen_interface.h \
@ -6518,7 +6520,6 @@ PUBLIC_HEADERS_CXX += \
include/grpcpp/impl/codegen/client_interceptor.h \
include/grpcpp/impl/codegen/client_unary_call.h \
include/grpcpp/impl/codegen/completion_queue.h \
include/grpcpp/impl/codegen/completion_queue_impl.h \
include/grpcpp/impl/codegen/completion_queue_tag.h \
include/grpcpp/impl/codegen/config.h \
include/grpcpp/impl/codegen/core_codegen_interface.h \
@ -6687,7 +6688,6 @@ PUBLIC_HEADERS_CXX += \
include/grpcpp/impl/codegen/client_interceptor.h \
include/grpcpp/impl/codegen/client_unary_call.h \
include/grpcpp/impl/codegen/completion_queue.h \
include/grpcpp/impl/codegen/completion_queue_impl.h \
include/grpcpp/impl/codegen/completion_queue_tag.h \
include/grpcpp/impl/codegen/config.h \
include/grpcpp/impl/codegen/core_codegen_interface.h \
@ -6886,7 +6886,6 @@ PUBLIC_HEADERS_CXX += \
include/grpcpp/alarm.h \
include/grpcpp/alarm_impl.h \
include/grpcpp/channel.h \
include/grpcpp/channel_impl.h \
include/grpcpp/client_context.h \
include/grpcpp/completion_queue.h \
include/grpcpp/create_channel.h \
@ -6927,7 +6926,6 @@ PUBLIC_HEADERS_CXX += \
include/grpcpp/server_builder.h \
include/grpcpp/server_builder_impl.h \
include/grpcpp/server_context.h \
include/grpcpp/server_impl.h \
include/grpcpp/server_posix.h \
include/grpcpp/server_posix_impl.h \
include/grpcpp/support/async_stream.h \
@ -7045,7 +7043,6 @@ PUBLIC_HEADERS_CXX += \
include/grpcpp/impl/codegen/client_interceptor.h \
include/grpcpp/impl/codegen/client_unary_call.h \
include/grpcpp/impl/codegen/completion_queue.h \
include/grpcpp/impl/codegen/completion_queue_impl.h \
include/grpcpp/impl/codegen/completion_queue_tag.h \
include/grpcpp/impl/codegen/config.h \
include/grpcpp/impl/codegen/core_codegen_interface.h \
@ -20683,6 +20680,38 @@ endif
endif
H2_SSL_CRED_RELOAD_TEST_SRC = \
test/core/end2end/fixtures/h2_ssl_cred_reload.cc \
H2_SSL_CRED_RELOAD_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(H2_SSL_CRED_RELOAD_TEST_SRC))))
ifeq ($(NO_SECURE),true)
# You can't build secure targets if you don't have OpenSSL.
$(BINDIR)/$(CONFIG)/h2_ssl_cred_reload_test: openssl_dep_error
else
$(BINDIR)/$(CONFIG)/h2_ssl_cred_reload_test: $(H2_SSL_CRED_RELOAD_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a
$(E) "[LD] Linking $@"
$(Q) mkdir -p `dirname $@`
$(Q) $(LD) $(LDFLAGS) $(H2_SSL_CRED_RELOAD_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/h2_ssl_cred_reload_test
endif
$(OBJDIR)/$(CONFIG)/test/core/end2end/fixtures/h2_ssl_cred_reload.o: $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a
deps_h2_ssl_cred_reload_test: $(H2_SSL_CRED_RELOAD_TEST_OBJS:.o=.dep)
ifneq ($(NO_SECURE),true)
ifneq ($(NO_DEPS),true)
-include $(H2_SSL_CRED_RELOAD_TEST_OBJS:.o=.dep)
endif
endif
H2_SSL_PROXY_TEST_SRC = \
test/core/end2end/fixtures/h2_ssl_proxy.cc \

@ -9,13 +9,12 @@ grpc_deps()
grpc_test_only_deps()
register_execution_platforms(
"//third_party/toolchains:rbe_ubuntu1604",
"//third_party/toolchains:rbe_ubuntu1604_large",
"//third_party/toolchains:local",
"//third_party/toolchains:local_large",
"//third_party/toolchains:rbe_windows",
)
register_toolchains(
"//third_party/toolchains:cc-toolchain-clang-x86_64-default",
"//third_party/toolchains/bazel_0.23.2_rbe_windows:cc-toolchain-x64_windows",
)
@ -52,3 +51,24 @@ http_archive(
load("//bazel:grpc_python_deps.bzl", "grpc_python_deps")
grpc_python_deps()
load("@bazel_toolchains//rules:rbe_repo.bzl", "rbe_autoconfig")
# Create toolchain configuration for remote execution.
rbe_autoconfig(
name = "rbe_default",
)
load("@bazel_toolchains//rules:environments.bzl", "clang_env")
load("@bazel_skylib//lib:dicts.bzl", "dicts")
# Create msan toolchain configuration for remote execution.
rbe_autoconfig(
name = "rbe_msan",
env = dicts.add(
clang_env(),
{
"BAZEL_LINKOPTS": "-lc++:-lc++abi:-lm",
},
),
)

@ -112,10 +112,7 @@ def grpc_cc_library(
visibility = visibility,
testonly = testonly,
linkopts = linkopts,
includes = [
"include",
"src/core/ext/upb-generated",
],
includes = ["include"] + if_not_windows(["src/core/ext/upb-generated"]),
alwayslink = alwayslink,
data = data,
tags = tags,

@ -173,15 +173,15 @@ def grpc_deps():
url = "https://github.com/abseil/abseil-cpp/archive/308ce31528a7edfa39f5f6d36142278a0ae1bf45.tar.gz",
)
if "com_github_bazelbuild_bazeltoolchains" not in native.existing_rules():
if "bazel_toolchains" not in native.existing_rules():
http_archive(
name = "com_github_bazelbuild_bazeltoolchains",
strip_prefix = "bazel-toolchains-37419a124bdb9af2fec5b99a973d359b6b899b61",
name = "bazel_toolchains",
strip_prefix = "bazel-toolchains-cddc376d428ada2927ad359211c3e356bd9c9fbb",
urls = [
"https://mirror.bazel.build/github.com/bazelbuild/bazel-toolchains/archive/37419a124bdb9af2fec5b99a973d359b6b899b61.tar.gz",
"https://github.com/bazelbuild/bazel-toolchains/archive/37419a124bdb9af2fec5b99a973d359b6b899b61.tar.gz",
"https://mirror.bazel.build/github.com/bazelbuild/bazel-toolchains/archive/cddc376d428ada2927ad359211c3e356bd9c9fbb.tar.gz",
"https://github.com/bazelbuild/bazel-toolchains/archive/cddc376d428ada2927ad359211c3e356bd9c9fbb.tar.gz",
],
sha256 = "ee854b5de299138c1f4a2edb5573d22b21d975acfc7aa938f36d30b49ef97498",
sha256 = "67335b3563d9b67dc2550b8f27cc689b64fadac491e69ce78763d9ba894cc5cc",
)
if "bazel_skylib" not in native.existing_rules():

@ -245,6 +245,7 @@ filegroups:
- src/core/lib/channel/handshaker_registry.cc
- src/core/lib/channel/status_util.cc
- src/core/lib/compression/compression.cc
- src/core/lib/compression/compression_args.cc
- src/core/lib/compression/compression_internal.cc
- src/core/lib/compression/message_compress.cc
- src/core/lib/compression/stream_compression.cc
@ -418,6 +419,7 @@ filegroups:
- src/core/lib/channel/handshaker_registry.h
- src/core/lib/channel/status_util.h
- src/core/lib/compression/algorithm_metadata.h
- src/core/lib/compression/compression_args.h
- src/core/lib/compression/compression_internal.h
- src/core/lib/compression/message_compress.h
- src/core/lib/compression/stream_compression.h
@ -1250,7 +1252,6 @@ filegroups:
- include/grpcpp/impl/codegen/client_interceptor.h
- include/grpcpp/impl/codegen/client_unary_call.h
- include/grpcpp/impl/codegen/completion_queue.h
- include/grpcpp/impl/codegen/completion_queue_impl.h
- include/grpcpp/impl/codegen/completion_queue_tag.h
- include/grpcpp/impl/codegen/config.h
- include/grpcpp/impl/codegen/core_codegen_interface.h
@ -1347,7 +1348,6 @@ filegroups:
- include/grpcpp/alarm.h
- include/grpcpp/alarm_impl.h
- include/grpcpp/channel.h
- include/grpcpp/channel_impl.h
- include/grpcpp/client_context.h
- include/grpcpp/completion_queue.h
- include/grpcpp/create_channel.h
@ -1388,7 +1388,6 @@ filegroups:
- include/grpcpp/server_builder.h
- include/grpcpp/server_builder_impl.h
- include/grpcpp/server_context.h
- include/grpcpp/server_impl.h
- include/grpcpp/server_posix.h
- include/grpcpp/server_posix_impl.h
- include/grpcpp/support/async_stream.h

@ -97,6 +97,7 @@ if test "$PHP_GRPC" != "no"; then
src/core/lib/channel/handshaker_registry.cc \
src/core/lib/channel/status_util.cc \
src/core/lib/compression/compression.cc \
src/core/lib/compression/compression_args.cc \
src/core/lib/compression/compression_internal.cc \
src/core/lib/compression/message_compress.cc \
src/core/lib/compression/stream_compression.cc \

@ -72,6 +72,7 @@ if (PHP_GRPC != "no") {
"src\\core\\lib\\channel\\handshaker_registry.cc " +
"src\\core\\lib\\channel\\status_util.cc " +
"src\\core\\lib\\compression\\compression.cc " +
"src\\core\\lib\\compression\\compression_args.cc " +
"src\\core\\lib\\compression\\compression_internal.cc " +
"src\\core\\lib\\compression\\message_compress.cc " +
"src\\core\\lib\\compression\\stream_compression.cc " +

@ -135,7 +135,7 @@ Code at `src/core/lib/iomgr/ev_epollex_posix.cc`
- The same FD can be in multiple `Pollable`s (even if one of the `Pollable`s is of type PO_FD)
- There cannot be two `Pollable`s of type PO_FD for the same fd
- Why do we need `Pollable` of type PO_FD and PO_EMTPY ?
- Why do we need `Pollable` of type PO_FD and PO_EMPTY ?
- The main reason is the Sync client API
- We create one new completion queue per call. If we didn’t have PO_EMPTY and PO_FD type pollables, then every call on a given channel will effectively have to create a `Pollable` and hence an epollset. This is because every completion queue automatically creates a pollset and the channel fd will have to be put in that pollset. This clearly requires an epollset to put that fd. Creating an epollset per call (even if we delete the epollset once the call is completed) would mean a lot of sys calls to create/delete epoll fds. This is clearly not a good idea.
- With these new types of `Pollable`s, all pollsets (corresponding to the new per-call completion queue) will initially point to PO_EMPTY global epollset. Then once the channel fd is added to the pollset, the pollset will point to the `Pollable` of type PO_FD containing just that fd (i.e it will reuse the existing `Pollable`). This way, the epoll fd creation/deletion churn is avoided.

@ -145,13 +145,3 @@ some configuration as environment variables that can be set.
* grpc_cfstream
set to 1 to turn on CFStream experiment. With this experiment gRPC uses CFStream API to make TCP
connections. The option is only available on iOS platform and when macro GRPC_CFSTREAM is defined.
* GRPC_ARENA_INIT_STRATEGY
Selects the initialization strategy for blocks allocated in the arena. Valid
values are:
- no_init (default): Do not initialize the arena block.
- zero_init: Initialize the arena blocks with 0.
- non_zero_init: Initialize the arena blocks with a non-zero value.
NOTE: This environment variable is experimental and will be removed. Thus, it
should not be relied upon.

@ -172,3 +172,9 @@ Future Interfaces
.. autoexception:: FutureTimeoutError
.. autoexception:: FutureCancelledError
.. autoclass:: Future
Compression
^^^^^^^^^^^
.. autoclass:: Compression

@ -53,7 +53,7 @@ namespace HelloworldXamarin.iOS
public override void DidEnterBackground(UIApplication application)
{
// Use this method to release shared resources, save user data, invalidate timers and store the application state.
// If your application supports background exection this method is called instead of WillTerminate when the user quits.
// If your application supports background execution this method is called instead of WillTerminate when the user quits.
}
public override void WillEnterForeground(UIApplication application)

@ -0,0 +1,32 @@
# 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.
load("@grpc_python_dependencies//:requirements.bzl", "requirement")
py_library(
name = "wait_for_ready_example",
testonly = 1,
srcs = ["wait_for_ready_example.py"],
deps = [
"//src/python/grpcio/grpc:grpcio",
"//examples:py_helloworld",
],
)
py_test(
name = "test/_wait_for_ready_example_test",
srcs = ["test/_wait_for_ready_example_test.py"],
deps = [":wait_for_ready_example",],
size = "small",
)

@ -0,0 +1,32 @@
# gRPC Python Example for Wait-for-ready
The default behavior of an RPC is to fail instantly if the server is not ready yet. This example demonstrates how to change that behavior.
### Definition of 'wait-for-ready' semantics
> If an RPC is issued but the channel is in TRANSIENT_FAILURE or SHUTDOWN states, the RPC is unable to be transmitted promptly. By default, gRPC implementations SHOULD fail such RPCs immediately. This is known as "fail fast," but the usage of the term is historical. RPCs SHOULD NOT fail as a result of the channel being in other states (CONNECTING, READY, or IDLE).
>
> gRPC implementations MAY provide a per-RPC option to not fail RPCs as a result of the channel being in TRANSIENT_FAILURE state. Instead, the implementation queues the RPCs until the channel is READY. This is known as "wait for ready." The RPCs SHOULD still fail before READY if there are unrelated reasons, such as the channel is SHUTDOWN or the RPC's deadline is reached.
>
> From https://github.com/grpc/grpc/blob/master/doc/wait-for-ready.md
### Use cases for 'wait-for-ready'
When developers spin up gRPC clients and servers at the same time, it is very like to fail first couple RPC calls due to unavailability of the server. If developers failed to prepare for this situation, the result can be catastrophic. But with 'wait-for-ready' semantics, developers can initialize the client and server in any order, especially useful in testing.
Also, developers may ensure the server is up before starting client. But in some cases like transient network failure may result in a temporary unavailability of the server. With 'wait-for-ready' semantics, those RPC calls will automatically wait until the server is ready to accept incoming requests.
### DEMO Snippets
```Python
# Per RPC level
stub = ...Stub(...)
stub.important_transaction_1(..., wait_for_ready=True)
stub.unimportant_transaction_2(...)
stub.important_transaction_3(..., wait_for_ready=True)
stub.unimportant_transaction_4(...)
# The unimportant transactions can be status report, or health check, etc.
```

@ -1,5 +1,4 @@
#!/bin/sh
# Copyright 2019 gRPC authors.
# 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.
@ -12,18 +11,21 @@
# 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.
"""Tests of the wait-for-ready example."""
set -e
import unittest
import logging
cd "$(dirname "$0")/../../.."
from examples.python.wait_for_ready import wait_for_ready_example
#
# Prevent the use of synchronization and threading constructs from std:: since
# the code should be using grpc_core::Mutex, grpc::internal::Mutex,
# grpc_core::Thread, etc.
#
egrep -Irn \
'std::(mutex|condition_variable|lock_guard|unique_lock|thread)' \
include/grpc include/grpcpp src/core src/cpp | diff - /dev/null
class WaitForReadyExampleTest(unittest.TestCase):
def test_wait_for_ready_example(self):
wait_for_ready_example.main()
# No unhandled exception raised, no deadlock, test passed!
if __name__ == '__main__':
logging.basicConfig()
unittest.main(verbosity=2)

@ -0,0 +1,114 @@
# 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.
"""The Python example of utilizing wait-for-ready flag."""
from __future__ import print_function
import logging
from concurrent import futures
from contextlib import contextmanager
import socket
import threading
import grpc
from examples.protos import helloworld_pb2
from examples.protos import helloworld_pb2_grpc
_LOGGER = logging.getLogger(__name__)
_LOGGER.setLevel(logging.INFO)
_ONE_DAY_IN_SECONDS = 60 * 60 * 24
@contextmanager
def get_free_loopback_tcp_port():
tcp_socket = socket.socket(socket.AF_INET6)
tcp_socket.bind(('', 0))
address_tuple = tcp_socket.getsockname()
yield "[::1]:%s" % (address_tuple[1])
tcp_socket.close()
class Greeter(helloworld_pb2_grpc.GreeterServicer):
def SayHello(self, request, unused_context):
return helloworld_pb2.HelloReply(message='Hello, %s!' % request.name)
def create_server(server_address):
server = grpc.server(futures.ThreadPoolExecutor())
helloworld_pb2_grpc.add_GreeterServicer_to_server(Greeter(), server)
bound_port = server.add_insecure_port(server_address)
assert bound_port == int(server_address.split(':')[-1])
return server
def process(stub, wait_for_ready=None):
try:
response = stub.SayHello(
helloworld_pb2.HelloRequest(name='you'),
wait_for_ready=wait_for_ready)
message = response.message
except grpc.RpcError as rpc_error:
assert rpc_error.code() == grpc.StatusCode.UNAVAILABLE
assert not wait_for_ready
message = rpc_error
else:
assert wait_for_ready
_LOGGER.info("Wait-for-ready %s, client received: %s", "enabled"
if wait_for_ready else "disabled", message)
def main():
# Pick a random free port
with get_free_loopback_tcp_port() as server_address:
# Register connectivity event to notify main thread
transient_failure_event = threading.Event()
def wait_for_transient_failure(channel_connectivity):
if channel_connectivity == grpc.ChannelConnectivity.TRANSIENT_FAILURE:
transient_failure_event.set()
# Create gRPC channel
channel = grpc.insecure_channel(server_address)
channel.subscribe(wait_for_transient_failure)
stub = helloworld_pb2_grpc.GreeterStub(channel)
# Fire an RPC without wait_for_ready
thread_disabled_wait_for_ready = threading.Thread(
target=process, args=(stub, False))
thread_disabled_wait_for_ready.start()
# Fire an RPC with wait_for_ready
thread_enabled_wait_for_ready = threading.Thread(
target=process, args=(stub, True))
thread_enabled_wait_for_ready.start()
# Wait for the channel entering TRANSIENT FAILURE state.
transient_failure_event.wait()
server = create_server(server_address)
server.start()
# Expected to fail with StatusCode.UNAVAILABLE.
thread_disabled_wait_for_ready.join()
# Expected to success.
thread_enabled_wait_for_ready.join()
server.stop(None)
channel.close()
if __name__ == '__main__':
logging.basicConfig(level=logging.INFO)
main()

@ -28,7 +28,7 @@ def main
stub = EchoWithoutProtobuf::Stub.new('localhost:50051', :this_channel_is_insecure)
user = ARGV.size > 0 ? ARGV[0] : 'world'
message = stub.echo("hello #{user}")
p "Reponse: #{message}"
p "Response: #{message}"
end
main

@ -82,7 +82,6 @@ Pod::Spec.new do |s|
ss.source_files = 'include/grpcpp/alarm.h',
'include/grpcpp/alarm_impl.h',
'include/grpcpp/channel.h',
'include/grpcpp/channel_impl.h',
'include/grpcpp/client_context.h',
'include/grpcpp/completion_queue.h',
'include/grpcpp/create_channel.h',
@ -123,7 +122,6 @@ Pod::Spec.new do |s|
'include/grpcpp/server_builder.h',
'include/grpcpp/server_builder_impl.h',
'include/grpcpp/server_context.h',
'include/grpcpp/server_impl.h',
'include/grpcpp/server_posix.h',
'include/grpcpp/server_posix_impl.h',
'include/grpcpp/support/async_stream.h',
@ -160,7 +158,6 @@ Pod::Spec.new do |s|
'include/grpcpp/impl/codegen/client_interceptor.h',
'include/grpcpp/impl/codegen/client_unary_call.h',
'include/grpcpp/impl/codegen/completion_queue.h',
'include/grpcpp/impl/codegen/completion_queue_impl.h',
'include/grpcpp/impl/codegen/completion_queue_tag.h',
'include/grpcpp/impl/codegen/config.h',
'include/grpcpp/impl/codegen/core_codegen_interface.h',
@ -415,6 +412,7 @@ Pod::Spec.new do |s|
'src/core/lib/channel/handshaker_registry.h',
'src/core/lib/channel/status_util.h',
'src/core/lib/compression/algorithm_metadata.h',
'src/core/lib/compression/compression_args.h',
'src/core/lib/compression/compression_internal.h',
'src/core/lib/compression/message_compress.h',
'src/core/lib/compression/stream_compression.h',
@ -607,6 +605,7 @@ Pod::Spec.new do |s|
'src/core/lib/channel/handshaker_registry.h',
'src/core/lib/channel/status_util.h',
'src/core/lib/compression/algorithm_metadata.h',
'src/core/lib/compression/compression_args.h',
'src/core/lib/compression/compression_internal.h',
'src/core/lib/compression/message_compress.h',
'src/core/lib/compression/stream_compression.h',

@ -394,6 +394,7 @@ Pod::Spec.new do |s|
'src/core/lib/channel/handshaker_registry.h',
'src/core/lib/channel/status_util.h',
'src/core/lib/compression/algorithm_metadata.h',
'src/core/lib/compression/compression_args.h',
'src/core/lib/compression/compression_internal.h',
'src/core/lib/compression/message_compress.h',
'src/core/lib/compression/stream_compression.h',
@ -548,6 +549,7 @@ Pod::Spec.new do |s|
'src/core/lib/channel/handshaker_registry.cc',
'src/core/lib/channel/status_util.cc',
'src/core/lib/compression/compression.cc',
'src/core/lib/compression/compression_args.cc',
'src/core/lib/compression/compression_internal.cc',
'src/core/lib/compression/message_compress.cc',
'src/core/lib/compression/stream_compression.cc',
@ -1036,6 +1038,7 @@ Pod::Spec.new do |s|
'src/core/lib/channel/handshaker_registry.h',
'src/core/lib/channel/status_util.h',
'src/core/lib/compression/algorithm_metadata.h',
'src/core/lib/compression/compression_args.h',
'src/core/lib/compression/compression_internal.h',
'src/core/lib/compression/message_compress.h',
'src/core/lib/compression/stream_compression.h',

@ -328,6 +328,7 @@ Gem::Specification.new do |s|
s.files += %w( src/core/lib/channel/handshaker_registry.h )
s.files += %w( src/core/lib/channel/status_util.h )
s.files += %w( src/core/lib/compression/algorithm_metadata.h )
s.files += %w( src/core/lib/compression/compression_args.h )
s.files += %w( src/core/lib/compression/compression_internal.h )
s.files += %w( src/core/lib/compression/message_compress.h )
s.files += %w( src/core/lib/compression/stream_compression.h )
@ -482,6 +483,7 @@ Gem::Specification.new do |s|
s.files += %w( src/core/lib/channel/handshaker_registry.cc )
s.files += %w( src/core/lib/channel/status_util.cc )
s.files += %w( src/core/lib/compression/compression.cc )
s.files += %w( src/core/lib/compression/compression_args.cc )
s.files += %w( src/core/lib/compression/compression_internal.cc )
s.files += %w( src/core/lib/compression/message_compress.cc )
s.files += %w( src/core/lib/compression/stream_compression.cc )

@ -279,6 +279,7 @@
'src/core/lib/channel/handshaker_registry.cc',
'src/core/lib/channel/status_util.cc',
'src/core/lib/compression/compression.cc',
'src/core/lib/compression/compression_args.cc',
'src/core/lib/compression/compression_internal.cc',
'src/core/lib/compression/message_compress.cc',
'src/core/lib/compression/stream_compression.cc',
@ -647,6 +648,7 @@
'src/core/lib/channel/handshaker_registry.cc',
'src/core/lib/channel/status_util.cc',
'src/core/lib/compression/compression.cc',
'src/core/lib/compression/compression_args.cc',
'src/core/lib/compression/compression_internal.cc',
'src/core/lib/compression/message_compress.cc',
'src/core/lib/compression/stream_compression.cc',
@ -892,6 +894,7 @@
'src/core/lib/channel/handshaker_registry.cc',
'src/core/lib/channel/status_util.cc',
'src/core/lib/compression/compression.cc',
'src/core/lib/compression/compression_args.cc',
'src/core/lib/compression/compression_internal.cc',
'src/core/lib/compression/message_compress.cc',
'src/core/lib/compression/stream_compression.cc',
@ -1113,6 +1116,7 @@
'src/core/lib/channel/handshaker_registry.cc',
'src/core/lib/channel/status_util.cc',
'src/core/lib/compression/compression.cc',
'src/core/lib/compression/compression_args.cc',
'src/core/lib/compression/compression_internal.cc',
'src/core/lib/compression/message_compress.cc',
'src/core/lib/compression/stream_compression.cc',

@ -264,7 +264,7 @@ GRPCAPI grpc_call_credentials* grpc_google_refresh_token_credentials_create(
const char* json_refresh_token, void* reserved);
/** Creates an Oauth2 Access Token credentials with an access token that was
aquired by an out of band mechanism. */
acquired by an out of band mechanism. */
GRPCAPI grpc_call_credentials* grpc_access_token_credentials_create(
const char* access_token, void* reserved);

@ -115,6 +115,7 @@
#define GPR_POSIX_SUBPROCESS 1
#define GPR_POSIX_SYNC 1
#define GPR_POSIX_TIME 1
#define GPR_HAS_PTHREAD_H 1
#define GPR_GETPID_IN_UNISTD_H 1
#ifdef _LP64
#define GPR_ARCH_64 1
@ -144,6 +145,7 @@
#define GPR_POSIX_SUBPROCESS 1
#define GPR_POSIX_SYNC 1
#define GPR_POSIX_TIME 1
#define GPR_HAS_PTHREAD_H 1
#define GPR_GETPID_IN_UNISTD_H 1
#define GPR_SUPPORT_CHANNELS_FROM_FD 1
#elif defined(__linux__)
@ -170,6 +172,7 @@
#define GPR_POSIX_SUBPROCESS 1
#define GPR_POSIX_SYNC 1
#define GPR_POSIX_TIME 1
#define GPR_HAS_PTHREAD_H 1
#define GPR_GETPID_IN_UNISTD_H 1
#ifdef _LP64
#define GPR_ARCH_64 1
@ -235,6 +238,7 @@
#define GPR_POSIX_SUBPROCESS 1
#define GPR_POSIX_SYNC 1
#define GPR_POSIX_TIME 1
#define GPR_HAS_PTHREAD_H 1
#define GPR_GETPID_IN_UNISTD_H 1
#ifndef GRPC_CFSTREAM
#define GPR_SUPPORT_CHANNELS_FROM_FD 1
@ -260,6 +264,7 @@
#define GPR_POSIX_SUBPROCESS 1
#define GPR_POSIX_SYNC 1
#define GPR_POSIX_TIME 1
#define GPR_HAS_PTHREAD_H 1
#define GPR_GETPID_IN_UNISTD_H 1
#define GPR_SUPPORT_CHANNELS_FROM_FD 1
#ifdef _LP64
@ -283,6 +288,7 @@
#define GPR_POSIX_SUBPROCESS 1
#define GPR_POSIX_SYNC 1
#define GPR_POSIX_TIME 1
#define GPR_HAS_PTHREAD_H 1
#define GPR_GETPID_IN_UNISTD_H 1
#define GPR_SUPPORT_CHANNELS_FROM_FD 1
#ifdef _LP64
@ -303,6 +309,7 @@
#define GPR_POSIX_SUBPROCESS 1
#define GPR_POSIX_SYNC 1
#define GPR_POSIX_TIME 1
#define GPR_HAS_PTHREAD_H 1
#define GPR_GETPID_IN_UNISTD_H 1
#ifdef _LP64
#define GPR_ARCH_64 1
@ -325,6 +332,7 @@
#define GPR_POSIX_SUBPROCESS 1
#define GPR_POSIX_SYNC 1
#define GPR_POSIX_TIME 1
#define GPR_HAS_PTHREAD_H 1
#define GPR_GETPID_IN_UNISTD_H 1
#ifdef _LP64
#define GPR_ARCH_64 1
@ -353,6 +361,7 @@
#define GPR_POSIX_SUBPROCESS 1
#define GPR_POSIX_SYNC 1
#define GPR_POSIX_TIME 1
#define GPR_HAS_PTHREAD_H 1
#define GPR_GETPID_IN_UNISTD_H 1
#ifdef _LP64
#define GPR_ARCH_64 1
@ -378,6 +387,7 @@
#define GPR_POSIX_SYNC 1
#define GPR_POSIX_STRING 1
#define GPR_POSIX_TIME 1
#define GPR_HAS_PTHREAD_H 1
#define GPR_GETPID_IN_UNISTD_H 1
#else
#error "Could not auto-detect platform"

@ -147,7 +147,7 @@ GPRAPI int grpc_slice_buf_start_eq(grpc_slice a, const void* b, size_t blen);
GPRAPI int grpc_slice_rchr(grpc_slice s, char c);
GPRAPI int grpc_slice_chr(grpc_slice s, char c);
/** return the index of the first occurance of \a needle in \a haystack, or -1
/** return the index of the first occurrence of \a needle in \a haystack, or -1
if it's not found */
GPRAPI int grpc_slice_slice(grpc_slice haystack, grpc_slice needle);

@ -19,15 +19,97 @@
#ifndef GRPCPP_CHANNEL_H
#define GRPCPP_CHANNEL_H
#include <grpcpp/channel_impl.h>
#include <memory>
#include <mutex>
namespace grpc {
#include <grpc/grpc.h>
#include <grpcpp/impl/call.h>
#include <grpcpp/impl/codegen/channel_interface.h>
#include <grpcpp/impl/codegen/client_interceptor.h>
#include <grpcpp/impl/codegen/config.h>
#include <grpcpp/impl/codegen/grpc_library.h>
#include <grpcpp/impl/codegen/sync.h>
struct grpc_channel;
typedef ::grpc_impl::Channel Channel;
namespace grpc {
namespace experimental {
/// Resets the channel's connection backoff.
/// TODO(roth): Once we see whether this proves useful, either create a gRFC
/// and change this to be a method of the Channel class, or remove it.
void ChannelResetConnectionBackoff(Channel* channel);
} // namespace experimental
/// Channels represent a connection to an endpoint. Created by \a CreateChannel.
class Channel final : public ChannelInterface,
public internal::CallHook,
public std::enable_shared_from_this<Channel>,
private GrpcLibraryCodegen {
public:
~Channel();
/// Get the current channel state. If the channel is in IDLE and
/// \a try_to_connect is set to true, try to connect.
grpc_connectivity_state GetState(bool try_to_connect) override;
/// Returns the LB policy name, or the empty string if not yet available.
grpc::string GetLoadBalancingPolicyName() const;
/// Returns the service config in JSON form, or the empty string if
/// not available.
grpc::string GetServiceConfigJSON() const;
private:
template <class InputMessage, class OutputMessage>
friend class internal::BlockingUnaryCallImpl;
friend void experimental::ChannelResetConnectionBackoff(Channel* channel);
friend std::shared_ptr<Channel> CreateChannelInternal(
const grpc::string& host, grpc_channel* c_channel,
std::vector<
std::unique_ptr<experimental::ClientInterceptorFactoryInterface>>
interceptor_creators);
friend class internal::InterceptedChannel;
Channel(const grpc::string& host, grpc_channel* c_channel,
std::vector<
std::unique_ptr<experimental::ClientInterceptorFactoryInterface>>
interceptor_creators);
internal::Call CreateCall(const internal::RpcMethod& method,
ClientContext* context,
CompletionQueue* cq) override;
void PerformOpsOnCall(internal::CallOpSetInterface* ops,
internal::Call* call) override;
void* RegisterMethod(const char* method) override;
void NotifyOnStateChangeImpl(grpc_connectivity_state last_observed,
gpr_timespec deadline, CompletionQueue* cq,
void* tag) override;
bool WaitForStateChangeImpl(grpc_connectivity_state last_observed,
gpr_timespec deadline) override;
CompletionQueue* CallbackCQ() override;
internal::Call CreateCallInternal(const internal::RpcMethod& method,
ClientContext* context, CompletionQueue* cq,
size_t interceptor_pos) override;
const grpc::string host_;
grpc_channel* const c_channel_; // owned
// mu_ protects callback_cq_ (the per-channel callbackable completion queue)
grpc::internal::Mutex mu_;
// callback_cq_ references the callbackable completion queue associated
// with this channel (if any). It is set on the first call to CallbackCQ().
// It is _not owned_ by the channel; ownership belongs with its internal
// shutdown callback tag (invoked when the CQ is fully shutdown).
CompletionQueue* callback_cq_ = nullptr;
std::vector<std::unique_ptr<experimental::ClientInterceptorFactoryInterface>>
interceptor_creators_;
};
} // namespace grpc
#endif // GRPCPP_CHANNEL_H

@ -1,117 +0,0 @@
/*
*
* Copyright 2015 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.
*
*/
#ifndef GRPCPP_CHANNEL_IMPL_H
#define GRPCPP_CHANNEL_IMPL_H
#include <memory>
#include <mutex>
#include <grpc/grpc.h>
#include <grpcpp/impl/call.h>
#include <grpcpp/impl/codegen/channel_interface.h>
#include <grpcpp/impl/codegen/client_interceptor.h>
#include <grpcpp/impl/codegen/config.h>
#include <grpcpp/impl/codegen/grpc_library.h>
#include <grpcpp/impl/codegen/sync.h>
struct grpc_channel;
namespace grpc_impl {
class CompletionQueue;
namespace experimental {
/// Resets the channel's connection backoff.
/// TODO(roth): Once we see whether this proves useful, either create a gRFC
/// and change this to be a method of the Channel class, or remove it.
void ChannelResetConnectionBackoff(Channel* channel);
} // namespace experimental
/// Channels represent a connection to an endpoint. Created by \a CreateChannel.
class Channel final : public ::grpc::ChannelInterface,
public ::grpc::internal::CallHook,
public std::enable_shared_from_this<Channel>,
private ::grpc::GrpcLibraryCodegen {
public:
~Channel();
/// Get the current channel state. If the channel is in IDLE and
/// \a try_to_connect is set to true, try to connect.
grpc_connectivity_state GetState(bool try_to_connect) override;
/// Returns the LB policy name, or the empty string if not yet available.
grpc::string GetLoadBalancingPolicyName() const;
/// Returns the service config in JSON form, or the empty string if
/// not available.
grpc::string GetServiceConfigJSON() const;
private:
template <class InputMessage, class OutputMessage>
friend class ::grpc::internal::BlockingUnaryCallImpl;
friend void experimental::ChannelResetConnectionBackoff(Channel* channel);
friend std::shared_ptr<Channel> CreateChannelInternal(
const grpc::string& host, grpc_channel* c_channel,
std::vector<std::unique_ptr<
::grpc::experimental::ClientInterceptorFactoryInterface>>
interceptor_creators);
friend class ::grpc::internal::InterceptedChannel;
Channel(const grpc::string& host, grpc_channel* c_channel,
std::vector<std::unique_ptr<
::grpc::experimental::ClientInterceptorFactoryInterface>>
interceptor_creators);
::grpc::internal::Call CreateCall(const ::grpc::internal::RpcMethod& method,
::grpc::ClientContext* context,
CompletionQueue* cq) override;
void PerformOpsOnCall(::grpc::internal::CallOpSetInterface* ops,
::grpc::internal::Call* call) override;
void* RegisterMethod(const char* method) override;
void NotifyOnStateChangeImpl(grpc_connectivity_state last_observed,
gpr_timespec deadline, CompletionQueue* cq,
void* tag) override;
bool WaitForStateChangeImpl(grpc_connectivity_state last_observed,
gpr_timespec deadline) override;
CompletionQueue* CallbackCQ() override;
::grpc::internal::Call CreateCallInternal(
const ::grpc::internal::RpcMethod& method, ::grpc::ClientContext* context,
CompletionQueue* cq, size_t interceptor_pos) override;
const grpc::string host_;
grpc_channel* const c_channel_; // owned
// mu_ protects callback_cq_ (the per-channel callbackable completion queue)
grpc::internal::Mutex mu_;
// callback_cq_ references the callbackable completion queue associated
// with this channel (if any). It is set on the first call to CallbackCQ().
// It is _not owned_ by the channel; ownership belongs with its internal
// shutdown callback tag (invoked when the CQ is fully shutdown).
CompletionQueue* callback_cq_ = nullptr;
std::vector<
std::unique_ptr<::grpc::experimental::ClientInterceptorFactoryInterface>>
interceptor_creators_;
};
} // namespace grpc_impl
#endif // GRPCPP_CHANNEL_IMPL_H

@ -35,7 +35,7 @@ namespace grpc_impl {
/// \param creds Credentials to use for the created channel. If it does not
/// hold an object or is invalid, a lame channel (one on which all operations
/// fail) is returned.
std::shared_ptr<Channel> CreateChannel(
std::shared_ptr<grpc::Channel> CreateChannel(
const grpc::string& target,
const std::shared_ptr<grpc::ChannelCredentials>& creds);
@ -49,7 +49,7 @@ std::shared_ptr<Channel> CreateChannel(
/// hold an object or is invalid, a lame channel (one on which all operations
/// fail) is returned.
/// \param args Options for channel creation.
std::shared_ptr<Channel> CreateCustomChannel(
std::shared_ptr<grpc::Channel> CreateCustomChannel(
const grpc::string& target,
const std::shared_ptr<grpc::ChannelCredentials>& creds,
const grpc::ChannelArguments& args);
@ -66,7 +66,7 @@ namespace experimental {
/// hold an object or is invalid, a lame channel (one on which all operations
/// fail) is returned.
/// \param args Options for channel creation.
std::shared_ptr<Channel> CreateCustomChannelWithInterceptors(
std::shared_ptr<grpc::Channel> CreateCustomChannelWithInterceptors(
const grpc::string& target,
const std::shared_ptr<grpc::ChannelCredentials>& creds,
const grpc::ChannelArguments& args,

@ -29,12 +29,12 @@
namespace grpc {
class CompletionQueue;
typedef ClientAsyncReaderWriter<ByteBuffer, ByteBuffer>
GenericClientAsyncReaderWriter;
typedef ClientAsyncResponseReader<ByteBuffer> GenericClientAsyncResponseReader;
} // namespace grpc
namespace grpc_impl {
class CompletionQueue;
/// Generic stubs provide a type-unsafe interface to call gRPC methods
/// by name.

@ -39,7 +39,7 @@ class GenericServerContext final : public ServerContext {
const grpc::string& host() const { return host_; }
private:
friend class grpc_impl::Server;
friend class Server;
friend class ServerInterface;
void Clear() {
@ -79,8 +79,8 @@ class AsyncGenericService final {
ServerCompletionQueue* notification_cq, void* tag);
private:
friend class grpc_impl::Server;
grpc_impl::Server* server_;
friend class Server;
Server* server_;
};
namespace experimental {
@ -135,14 +135,14 @@ class CallbackGenericService {
}
private:
friend class ::grpc_impl::Server;
friend class ::grpc::Server;
internal::CallbackBidiHandler<ByteBuffer, ByteBuffer>* Handler() {
return new internal::CallbackBidiHandler<ByteBuffer, ByteBuffer>(
[this] { return CreateReactor(); });
}
grpc_impl::Server* server_{nullptr};
Server* server_{nullptr};
};
} // namespace experimental
} // namespace grpc

@ -28,6 +28,8 @@
namespace grpc {
class CompletionQueue;
namespace internal {
/// Common interface for all client side asynchronous streaming.
class ClientAsyncStreamingInterface {
@ -659,7 +661,7 @@ class ServerAsyncReaderInterface
/// some failure occurred when trying to do so.
///
/// gRPC doesn't take ownership or a reference to \a msg or \a status, so it
/// is safe to to deallocate once Finish returns.
/// is safe to deallocate once Finish returns.
///
/// \param[in] tag Tag identifying this request.
/// \param[in] status To be sent to the client as the result of this call.
@ -733,7 +735,7 @@ class ServerAsyncReader final : public ServerAsyncReaderInterface<W, R> {
/// Note: \a msg is not sent if \a status has a non-OK code.
///
/// gRPC doesn't take ownership or a reference to \a msg and \a status, so it
/// is safe to to deallocate once Finish returns.
/// is safe to deallocate once Finish returns.
void Finish(const W& msg, const Status& status, void* tag) override {
finish_ops_.set_output_tag(tag);
if (!ctx_->sent_initial_metadata_) {
@ -828,7 +830,7 @@ class ServerAsyncWriterInterface
/// in a single step.
///
/// gRPC doesn't take ownership or a reference to \a msg and \a status, so it
/// is safe to to deallocate once WriteAndFinish returns.
/// is safe to deallocate once WriteAndFinish returns.
///
/// \param[in] msg The message to be written.
/// \param[in] options The WriteOptions to be used to write this message.
@ -895,7 +897,7 @@ class ServerAsyncWriter final : public ServerAsyncWriterInterface<W> {
/// Note: \a status must have an OK code.
///
/// gRPC doesn't take ownership or a reference to \a msg and \a status, so it
/// is safe to to deallocate once WriteAndFinish returns.
/// is safe to deallocate once WriteAndFinish returns.
void WriteAndFinish(const W& msg, WriteOptions options, const Status& status,
void* tag) override {
write_ops_.set_output_tag(tag);
@ -991,7 +993,7 @@ class ServerAsyncReaderWriterInterface
/// single step.
///
/// gRPC doesn't take ownership or a reference to \a msg and \a status, so it
/// is safe to to deallocate once WriteAndFinish returns.
/// is safe to deallocate once WriteAndFinish returns.
///
/// \param[in] msg The message to be written.
/// \param[in] options The WriteOptions to be used to write this message.
@ -1066,7 +1068,7 @@ class ServerAsyncReaderWriter final
/// Note: \a status must have an OK code.
//
/// gRPC doesn't take ownership or a reference to \a msg and \a status, so it
/// is safe to to deallocate once WriteAndFinish returns.
/// is safe to deallocate once WriteAndFinish returns.
void WriteAndFinish(const W& msg, WriteOptions options, const Status& status,
void* tag) override {
write_ops_.set_output_tag(tag);
@ -1097,7 +1099,7 @@ class ServerAsyncReaderWriter final
}
private:
friend class ::grpc_impl::Server;
friend class ::grpc::Server;
void BindCall(::grpc::internal::Call* call) override { call_ = *call; }

@ -29,6 +29,7 @@
namespace grpc {
class CompletionQueue;
extern CoreCodegenInterface* g_core_codegen_interface;
/// An interface relevant for async client side unary RPCs (which send

@ -21,11 +21,9 @@
#include <grpc/impl/codegen/grpc_types.h>
#include <grpcpp/impl/codegen/call_hook.h>
namespace grpc_impl {
namespace grpc {
class CompletionQueue;
}
namespace grpc {
namespace experimental {
class ClientRpcInfo;
class ServerRpcInfo;
@ -43,13 +41,13 @@ class Call final {
call_(nullptr),
max_receive_message_size_(-1) {}
/** call is owned by the caller */
Call(grpc_call* call, CallHook* call_hook, ::grpc_impl::CompletionQueue* cq)
Call(grpc_call* call, CallHook* call_hook, CompletionQueue* cq)
: call_hook_(call_hook),
cq_(cq),
call_(call),
max_receive_message_size_(-1) {}
Call(grpc_call* call, CallHook* call_hook, ::grpc_impl::CompletionQueue* cq,
Call(grpc_call* call, CallHook* call_hook, CompletionQueue* cq,
experimental::ClientRpcInfo* rpc_info)
: call_hook_(call_hook),
cq_(cq),
@ -57,7 +55,7 @@ class Call final {
max_receive_message_size_(-1),
client_rpc_info_(rpc_info) {}
Call(grpc_call* call, CallHook* call_hook, ::grpc_impl::CompletionQueue* cq,
Call(grpc_call* call, CallHook* call_hook, CompletionQueue* cq,
int max_receive_message_size, experimental::ServerRpcInfo* rpc_info)
: call_hook_(call_hook),
cq_(cq),
@ -70,7 +68,7 @@ class Call final {
}
grpc_call* call() const { return call_; }
::grpc_impl::CompletionQueue* cq() const { return cq_; }
CompletionQueue* cq() const { return cq_; }
int max_receive_message_size() const { return max_receive_message_size_; }
@ -84,7 +82,7 @@ class Call final {
private:
CallHook* call_hook_;
::grpc_impl::CompletionQueue* cq_;
CompletionQueue* cq_;
grpc_call* call_;
int max_receive_message_size_;
experimental::ClientRpcInfo* client_rpc_info_ = nullptr;

@ -48,6 +48,7 @@
namespace grpc {
class CompletionQueue;
extern CoreCodegenInterface* g_core_codegen_interface;
namespace internal {

@ -24,13 +24,10 @@
#include <grpcpp/impl/codegen/status.h>
#include <grpcpp/impl/codegen/time.h>
namespace grpc_impl {
class CompletionQueue;
}
namespace grpc {
class ChannelInterface;
class ClientContext;
class CompletionQueue;
template <class R>
class ClientReader;
@ -76,7 +73,7 @@ class ChannelInterface {
/// deadline expires. \a GetState needs to called to get the current state.
template <typename T>
void NotifyOnStateChange(grpc_connectivity_state last_observed, T deadline,
::grpc_impl::CompletionQueue* cq, void* tag) {
CompletionQueue* cq, void* tag) {
TimePoint<T> deadline_tp(deadline);
NotifyOnStateChangeImpl(last_observed, deadline_tp.raw_time(), cq, tag);
}
@ -128,14 +125,13 @@ class ChannelInterface {
friend class ::grpc::internal::InterceptedChannel;
virtual internal::Call CreateCall(const internal::RpcMethod& method,
ClientContext* context,
::grpc_impl::CompletionQueue* cq) = 0;
CompletionQueue* cq) = 0;
virtual void PerformOpsOnCall(internal::CallOpSetInterface* ops,
internal::Call* call) = 0;
virtual void* RegisterMethod(const char* method) = 0;
virtual void NotifyOnStateChangeImpl(grpc_connectivity_state last_observed,
gpr_timespec deadline,
::grpc_impl::CompletionQueue* cq,
void* tag) = 0;
CompletionQueue* cq, void* tag) = 0;
virtual bool WaitForStateChangeImpl(grpc_connectivity_state last_observed,
gpr_timespec deadline) = 0;
@ -148,7 +144,7 @@ class ChannelInterface {
// change (even though this is private and non-API)
virtual internal::Call CreateCallInternal(const internal::RpcMethod& method,
ClientContext* context,
::grpc_impl::CompletionQueue* cq,
CompletionQueue* cq,
size_t interceptor_pos) {
return internal::Call();
}
@ -161,7 +157,7 @@ class ChannelInterface {
// Returns nullptr (rather than being pure) since this is a post-1.0 method
// and adding a new pure method to an interface would be a breaking change
// (even though this is private and non-API)
virtual ::grpc_impl::CompletionQueue* CallbackCQ() { return nullptr; }
virtual CompletionQueue* CallbackCQ() { return nullptr; }
};
} // namespace grpc

@ -29,13 +29,11 @@
#include <grpcpp/impl/codegen/core_codegen_interface.h>
#include <grpcpp/impl/codegen/status.h>
namespace grpc_impl {
class Channel;
}
namespace grpc {
class Channel;
class ClientContext;
class CompletionQueue;
namespace internal {
class RpcMethod;

@ -57,14 +57,11 @@
struct census_context;
struct grpc_call;
namespace grpc_impl {
class Channel;
}
namespace grpc {
class Channel;
class ChannelInterface;
class CompletionQueue;
class CallCredentials;
class ClientContext;
@ -395,7 +392,7 @@ class ClientContext {
friend class ::grpc::testing::InteropClientContextInspector;
friend class ::grpc::internal::CallOpClientRecvStatus;
friend class ::grpc::internal::CallOpRecvInitialMetadata;
friend class ::grpc_impl::Channel;
friend class Channel;
template <class R>
friend class ::grpc::ClientReader;
template <class W>
@ -427,8 +424,7 @@ class ClientContext {
}
grpc_call* call() const { return call_; }
void set_call(grpc_call* call,
const std::shared_ptr<::grpc_impl::Channel>& channel);
void set_call(grpc_call* call, const std::shared_ptr<Channel>& channel);
experimental::ClientRpcInfo* set_client_rpc_info(
const char* method, internal::RpcMethod::RpcType type,
@ -461,7 +457,7 @@ class ClientContext {
bool wait_for_ready_explicitly_set_;
bool idempotent_;
bool cacheable_;
std::shared_ptr<::grpc_impl::Channel> channel_;
std::shared_ptr<Channel> channel_;
grpc::internal::Mutex mu_;
grpc_call* call_;
bool call_canceled_;

@ -26,14 +26,10 @@
#include <grpcpp/impl/codegen/rpc_method.h>
#include <grpcpp/impl/codegen/string_ref.h>
namespace grpc_impl {
class Channel;
}
namespace grpc {
class ClientContext;
class Channel;
namespace internal {
class InterceptorBatchMethodsImpl;

@ -27,7 +27,9 @@
namespace grpc {
class Channel;
class ClientContext;
class CompletionQueue;
namespace internal {
class RpcMethod;

@ -32,12 +32,385 @@
#ifndef GRPCPP_IMPL_CODEGEN_COMPLETION_QUEUE_H
#define GRPCPP_IMPL_CODEGEN_COMPLETION_QUEUE_H
#include <grpcpp/impl/codegen/completion_queue_impl.h>
#include <grpc/impl/codegen/atm.h>
#include <grpcpp/impl/codegen/completion_queue_tag.h>
#include <grpcpp/impl/codegen/core_codegen_interface.h>
#include <grpcpp/impl/codegen/grpc_library.h>
#include <grpcpp/impl/codegen/status.h>
#include <grpcpp/impl/codegen/time.h>
struct grpc_completion_queue;
namespace grpc_impl {
class ServerBuilder;
}
namespace grpc {
typedef ::grpc_impl::CompletionQueue CompletionQueue;
typedef ::grpc_impl::ServerCompletionQueue ServerCompletionQueue;
template <class R>
class ClientReader;
template <class W>
class ClientWriter;
template <class W, class R>
class ClientReaderWriter;
template <class R>
class ServerReader;
template <class W>
class ServerWriter;
namespace internal {
template <class W, class R>
class ServerReaderWriterBody;
} // namespace internal
class Channel;
class ChannelInterface;
class ClientContext;
class CompletionQueue;
class Server;
class ServerContext;
class ServerInterface;
namespace internal {
class CompletionQueueTag;
class RpcMethod;
template <class ServiceType, class RequestType, class ResponseType>
class RpcMethodHandler;
template <class ServiceType, class RequestType, class ResponseType>
class ClientStreamingHandler;
template <class ServiceType, class RequestType, class ResponseType>
class ServerStreamingHandler;
template <class ServiceType, class RequestType, class ResponseType>
class BidiStreamingHandler;
template <class Streamer, bool WriteNeeded>
class TemplatedBidiStreamingHandler;
template <StatusCode code>
class ErrorMethodHandler;
template <class InputMessage, class OutputMessage>
class BlockingUnaryCallImpl;
template <class Op1, class Op2, class Op3, class Op4, class Op5, class Op6>
class CallOpSet;
} // namespace internal
extern CoreCodegenInterface* g_core_codegen_interface;
/// A thin wrapper around \ref grpc_completion_queue (see \ref
/// src/core/lib/surface/completion_queue.h).
/// See \ref doc/cpp/perf_notes.md for notes on best practices for high
/// performance servers.
class CompletionQueue : private GrpcLibraryCodegen {
public:
/// Default constructor. Implicitly creates a \a grpc_completion_queue
/// instance.
CompletionQueue()
: CompletionQueue(grpc_completion_queue_attributes{
GRPC_CQ_CURRENT_VERSION, GRPC_CQ_NEXT, GRPC_CQ_DEFAULT_POLLING,
nullptr}) {}
/// Wrap \a take, taking ownership of the instance.
///
/// \param take The completion queue instance to wrap. Ownership is taken.
explicit CompletionQueue(grpc_completion_queue* take);
/// Destructor. Destroys the owned wrapped completion queue / instance.
~CompletionQueue() {
g_core_codegen_interface->grpc_completion_queue_destroy(cq_);
}
/// Tri-state return for AsyncNext: SHUTDOWN, GOT_EVENT, TIMEOUT.
enum NextStatus {
SHUTDOWN, ///< The completion queue has been shutdown and fully-drained
GOT_EVENT, ///< Got a new event; \a tag will be filled in with its
///< associated value; \a ok indicating its success.
TIMEOUT ///< deadline was reached.
};
/// Read from the queue, blocking until an event is available or the queue is
/// shutting down.
///
/// \param tag [out] Updated to point to the read event's tag.
/// \param ok [out] true if read a successful event, false otherwise.
///
/// Note that each tag sent to the completion queue (through RPC operations
/// or alarms) will be delivered out of the completion queue by a call to
/// Next (or a related method), regardless of whether the operation succeeded
/// or not. Success here means that this operation completed in the normal
/// valid manner.
///
/// Server-side RPC request: \a ok indicates that the RPC has indeed
/// been started. If it is false, the server has been Shutdown
/// before this particular call got matched to an incoming RPC.
///
/// Client-side StartCall/RPC invocation: \a ok indicates that the RPC is
/// going to go to the wire. If it is false, it not going to the wire. This
/// would happen if the channel is either permanently broken or
/// transiently broken but with the fail-fast option. (Note that async unary
/// RPCs don't post a CQ tag at this point, nor do client-streaming
/// or bidi-streaming RPCs that have the initial metadata corked option set.)
///
/// Client-side Write, Client-side WritesDone, Server-side Write,
/// Server-side Finish, Server-side SendInitialMetadata (which is
/// typically included in Write or Finish when not done explicitly):
/// \a ok means that the data/metadata/status/etc is going to go to the
/// wire. If it is false, it not going to the wire because the call
/// is already dead (i.e., canceled, deadline expired, other side
/// dropped the channel, etc).
///
/// Client-side Read, Server-side Read, Client-side
/// RecvInitialMetadata (which is typically included in Read if not
/// done explicitly): \a ok indicates whether there is a valid message
/// that got read. If not, you know that there are certainly no more
/// messages that can ever be read from this stream. For the client-side
/// operations, this only happens because the call is dead. For the
/// server-sider operation, though, this could happen because the client
/// has done a WritesDone already.
///
/// Client-side Finish: \a ok should always be true
///
/// Server-side AsyncNotifyWhenDone: \a ok should always be true
///
/// Alarm: \a ok is true if it expired, false if it was canceled
///
/// \return true if got an event, false if the queue is fully drained and
/// shut down.
bool Next(void** tag, bool* ok) {
return (AsyncNextInternal(tag, ok,
g_core_codegen_interface->gpr_inf_future(
GPR_CLOCK_REALTIME)) != SHUTDOWN);
}
/// Read from the queue, blocking up to \a deadline (or the queue's shutdown).
/// Both \a tag and \a ok are updated upon success (if an event is available
/// within the \a deadline). A \a tag points to an arbitrary location usually
/// employed to uniquely identify an event.
///
/// \param tag [out] Upon success, updated to point to the event's tag.
/// \param ok [out] Upon success, true if a successful event, false otherwise
/// See documentation for CompletionQueue::Next for explanation of ok
/// \param deadline [in] How long to block in wait for an event.
///
/// \return The type of event read.
template <typename T>
NextStatus AsyncNext(void** tag, bool* ok, const T& deadline) {
TimePoint<T> deadline_tp(deadline);
return AsyncNextInternal(tag, ok, deadline_tp.raw_time());
}
/// EXPERIMENTAL
/// First executes \a F, then reads from the queue, blocking up to
/// \a deadline (or the queue's shutdown).
/// Both \a tag and \a ok are updated upon success (if an event is available
/// within the \a deadline). A \a tag points to an arbitrary location usually
/// employed to uniquely identify an event.
///
/// \param f [in] Function to execute before calling AsyncNext on this queue.
/// \param tag [out] Upon success, updated to point to the event's tag.
/// \param ok [out] Upon success, true if read a regular event, false
/// otherwise.
/// \param deadline [in] How long to block in wait for an event.
///
/// \return The type of event read.
template <typename T, typename F>
NextStatus DoThenAsyncNext(F&& f, void** tag, bool* ok, const T& deadline) {
CompletionQueueTLSCache cache = CompletionQueueTLSCache(this);
f();
if (cache.Flush(tag, ok)) {
return GOT_EVENT;
} else {
return AsyncNext(tag, ok, deadline);
}
}
/// Request the shutdown of the queue.
///
/// \warning This method must be called at some point if this completion queue
/// is accessed with Next or AsyncNext. \a Next will not return false
/// until this method has been called and all pending tags have been drained.
/// (Likewise for \a AsyncNext returning \a NextStatus::SHUTDOWN .)
/// Only once either one of these methods does that (that is, once the queue
/// has been \em drained) can an instance of this class be destroyed.
/// Also note that applications must ensure that no work is enqueued on this
/// completion queue after this method is called.
void Shutdown();
/// Returns a \em raw pointer to the underlying \a grpc_completion_queue
/// instance.
///
/// \warning Remember that the returned instance is owned. No transfer of
/// owership is performed.
grpc_completion_queue* cq() { return cq_; }
protected:
/// Private constructor of CompletionQueue only visible to friend classes
CompletionQueue(const grpc_completion_queue_attributes& attributes) {
cq_ = g_core_codegen_interface->grpc_completion_queue_create(
g_core_codegen_interface->grpc_completion_queue_factory_lookup(
&attributes),
&attributes, NULL);
InitialAvalanching(); // reserve this for the future shutdown
}
private:
// Friend synchronous wrappers so that they can access Pluck(), which is
// a semi-private API geared towards the synchronous implementation.
template <class R>
friend class ::grpc::ClientReader;
template <class W>
friend class ::grpc::ClientWriter;
template <class W, class R>
friend class ::grpc::ClientReaderWriter;
template <class R>
friend class ::grpc::ServerReader;
template <class W>
friend class ::grpc::ServerWriter;
template <class W, class R>
friend class ::grpc::internal::ServerReaderWriterBody;
template <class ServiceType, class RequestType, class ResponseType>
friend class ::grpc::internal::RpcMethodHandler;
template <class ServiceType, class RequestType, class ResponseType>
friend class ::grpc::internal::ClientStreamingHandler;
template <class ServiceType, class RequestType, class ResponseType>
friend class ::grpc::internal::ServerStreamingHandler;
template <class Streamer, bool WriteNeeded>
friend class ::grpc::internal::TemplatedBidiStreamingHandler;
template <StatusCode code>
friend class ::grpc::internal::ErrorMethodHandler;
friend class ::grpc::Server;
friend class ::grpc::ServerContext;
friend class ::grpc::ServerInterface;
template <class InputMessage, class OutputMessage>
friend class ::grpc::internal::BlockingUnaryCallImpl;
// Friends that need access to constructor for callback CQ
friend class ::grpc::Channel;
// For access to Register/CompleteAvalanching
template <class Op1, class Op2, class Op3, class Op4, class Op5, class Op6>
friend class ::grpc::internal::CallOpSet;
/// EXPERIMENTAL
/// Creates a Thread Local cache to store the first event
/// On this completion queue queued from this thread. Once
/// initialized, it must be flushed on the same thread.
class CompletionQueueTLSCache {
public:
CompletionQueueTLSCache(CompletionQueue* cq);
~CompletionQueueTLSCache();
bool Flush(void** tag, bool* ok);
private:
CompletionQueue* cq_;
bool flushed_;
};
NextStatus AsyncNextInternal(void** tag, bool* ok, gpr_timespec deadline);
/// Wraps \a grpc_completion_queue_pluck.
/// \warning Must not be mixed with calls to \a Next.
bool Pluck(internal::CompletionQueueTag* tag) {
auto deadline =
g_core_codegen_interface->gpr_inf_future(GPR_CLOCK_REALTIME);
while (true) {
auto ev = g_core_codegen_interface->grpc_completion_queue_pluck(
cq_, tag, deadline, nullptr);
bool ok = ev.success != 0;
void* ignored = tag;
if (tag->FinalizeResult(&ignored, &ok)) {
GPR_CODEGEN_ASSERT(ignored == tag);
return ok;
}
}
}
/// Performs a single polling pluck on \a tag.
/// \warning Must not be mixed with calls to \a Next.
///
/// TODO: sreek - This calls tag->FinalizeResult() even if the cq_ is already
/// shutdown. This is most likely a bug and if it is a bug, then change this
/// implementation to simple call the other TryPluck function with a zero
/// timeout. i.e:
/// TryPluck(tag, gpr_time_0(GPR_CLOCK_REALTIME))
void TryPluck(internal::CompletionQueueTag* tag) {
auto deadline = g_core_codegen_interface->gpr_time_0(GPR_CLOCK_REALTIME);
auto ev = g_core_codegen_interface->grpc_completion_queue_pluck(
cq_, tag, deadline, nullptr);
if (ev.type == GRPC_QUEUE_TIMEOUT) return;
bool ok = ev.success != 0;
void* ignored = tag;
// the tag must be swallowed if using TryPluck
GPR_CODEGEN_ASSERT(!tag->FinalizeResult(&ignored, &ok));
}
/// Performs a single polling pluck on \a tag. Calls tag->FinalizeResult if
/// the pluck() was successful and returned the tag.
///
/// This exects tag->FinalizeResult (if called) to return 'false' i.e expects
/// that the tag is internal not something that is returned to the user.
void TryPluck(internal::CompletionQueueTag* tag, gpr_timespec deadline) {
auto ev = g_core_codegen_interface->grpc_completion_queue_pluck(
cq_, tag, deadline, nullptr);
if (ev.type == GRPC_QUEUE_TIMEOUT || ev.type == GRPC_QUEUE_SHUTDOWN) {
return;
}
bool ok = ev.success != 0;
void* ignored = tag;
GPR_CODEGEN_ASSERT(!tag->FinalizeResult(&ignored, &ok));
}
/// Manage state of avalanching operations : completion queue tags that
/// trigger other completion queue operations. The underlying core completion
/// queue should not really shutdown until all avalanching operations have
/// been finalized. Note that we maintain the requirement that an avalanche
/// registration must take place before CQ shutdown (which must be maintained
/// elsewhere)
void InitialAvalanching() {
gpr_atm_rel_store(&avalanches_in_flight_, static_cast<gpr_atm>(1));
}
void RegisterAvalanching() {
gpr_atm_no_barrier_fetch_add(&avalanches_in_flight_,
static_cast<gpr_atm>(1));
}
void CompleteAvalanching() {
if (gpr_atm_no_barrier_fetch_add(&avalanches_in_flight_,
static_cast<gpr_atm>(-1)) == 1) {
g_core_codegen_interface->grpc_completion_queue_shutdown(cq_);
}
}
grpc_completion_queue* cq_; // owned
gpr_atm avalanches_in_flight_;
};
/// A specific type of completion queue used by the processing of notifications
/// by servers. Instantiated by \a ServerBuilder.
class ServerCompletionQueue : public CompletionQueue {
public:
bool IsFrequentlyPolled() { return polling_type_ != GRPC_CQ_NON_LISTENING; }
protected:
/// Default constructor
ServerCompletionQueue() : polling_type_(GRPC_CQ_DEFAULT_POLLING) {}
private:
/// \param completion_type indicates whether this is a NEXT or CALLBACK
/// completion queue.
/// \param polling_type Informs the GRPC library about the type of polling
/// allowed on this completion queue. See grpc_cq_polling_type's description
/// in grpc_types.h for more details.
/// \param shutdown_cb is the shutdown callback used for CALLBACK api queues
ServerCompletionQueue(grpc_cq_completion_type completion_type,
grpc_cq_polling_type polling_type,
grpc_experimental_completion_queue_functor* shutdown_cb)
: CompletionQueue(grpc_completion_queue_attributes{
GRPC_CQ_CURRENT_VERSION, completion_type, polling_type,
shutdown_cb}),
polling_type_(polling_type) {}
grpc_cq_polling_type polling_type_;
friend class ::grpc_impl::ServerBuilder;
friend class Server;
};
} // namespace grpc

@ -1,422 +0,0 @@
/*
*
* Copyright 2015-2016 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.
*
*/
/// A completion queue implements a concurrent producer-consumer queue, with
/// two main API-exposed methods: \a Next and \a AsyncNext. These
/// methods are the essential component of the gRPC C++ asynchronous API.
/// There is also a \a Shutdown method to indicate that a given completion queue
/// will no longer have regular events. This must be called before the
/// completion queue is destroyed.
/// All completion queue APIs are thread-safe and may be used concurrently with
/// any other completion queue API invocation; it is acceptable to have
/// multiple threads calling \a Next or \a AsyncNext on the same or different
/// completion queues, or to call these methods concurrently with a \a Shutdown
/// elsewhere.
/// \remark{All other API calls on completion queue should be completed before
/// a completion queue destructor is called.}
#ifndef GRPCPP_IMPL_CODEGEN_COMPLETION_QUEUE_IMPL_H
#define GRPCPP_IMPL_CODEGEN_COMPLETION_QUEUE_IMPL_H
#include <grpc/impl/codegen/atm.h>
#include <grpcpp/impl/codegen/completion_queue_tag.h>
#include <grpcpp/impl/codegen/core_codegen_interface.h>
#include <grpcpp/impl/codegen/grpc_library.h>
#include <grpcpp/impl/codegen/status.h>
#include <grpcpp/impl/codegen/time.h>
struct grpc_completion_queue;
namespace grpc_impl {
class Channel;
class Server;
class ServerBuilder;
} // namespace grpc_impl
namespace grpc {
template <class R>
class ClientReader;
template <class W>
class ClientWriter;
template <class W, class R>
class ClientReaderWriter;
template <class R>
class ServerReader;
template <class W>
class ServerWriter;
namespace internal {
template <class W, class R>
class ServerReaderWriterBody;
} // namespace internal
class ChannelInterface;
class ClientContext;
class ServerContext;
class ServerInterface;
namespace internal {
class CompletionQueueTag;
class RpcMethod;
template <class ServiceType, class RequestType, class ResponseType>
class RpcMethodHandler;
template <class ServiceType, class RequestType, class ResponseType>
class ClientStreamingHandler;
template <class ServiceType, class RequestType, class ResponseType>
class ServerStreamingHandler;
template <class ServiceType, class RequestType, class ResponseType>
class BidiStreamingHandler;
template <class Streamer, bool WriteNeeded>
class TemplatedBidiStreamingHandler;
template <StatusCode code>
class ErrorMethodHandler;
template <class InputMessage, class OutputMessage>
class BlockingUnaryCallImpl;
template <class Op1, class Op2, class Op3, class Op4, class Op5, class Op6>
class CallOpSet;
} // namespace internal
extern CoreCodegenInterface* g_core_codegen_interface;
} // namespace grpc
namespace grpc_impl {
/// A thin wrapper around \ref grpc_completion_queue (see \ref
/// src/core/lib/surface/completion_queue.h).
/// See \ref doc/cpp/perf_notes.md for notes on best practices for high
/// performance servers.
class CompletionQueue : private ::grpc::GrpcLibraryCodegen {
public:
/// Default constructor. Implicitly creates a \a grpc_completion_queue
/// instance.
CompletionQueue()
: CompletionQueue(grpc_completion_queue_attributes{
GRPC_CQ_CURRENT_VERSION, GRPC_CQ_NEXT, GRPC_CQ_DEFAULT_POLLING,
nullptr}) {}
/// Wrap \a take, taking ownership of the instance.
///
/// \param take The completion queue instance to wrap. Ownership is taken.
explicit CompletionQueue(grpc_completion_queue* take);
/// Destructor. Destroys the owned wrapped completion queue / instance.
~CompletionQueue() {
::grpc::g_core_codegen_interface->grpc_completion_queue_destroy(cq_);
}
/// Tri-state return for AsyncNext: SHUTDOWN, GOT_EVENT, TIMEOUT.
enum NextStatus {
SHUTDOWN, ///< The completion queue has been shutdown and fully-drained
GOT_EVENT, ///< Got a new event; \a tag will be filled in with its
///< associated value; \a ok indicating its success.
TIMEOUT ///< deadline was reached.
};
/// Read from the queue, blocking until an event is available or the queue is
/// shutting down.
///
/// \param tag [out] Updated to point to the read event's tag.
/// \param ok [out] true if read a successful event, false otherwise.
///
/// Note that each tag sent to the completion queue (through RPC operations
/// or alarms) will be delivered out of the completion queue by a call to
/// Next (or a related method), regardless of whether the operation succeeded
/// or not. Success here means that this operation completed in the normal
/// valid manner.
///
/// Server-side RPC request: \a ok indicates that the RPC has indeed
/// been started. If it is false, the server has been Shutdown
/// before this particular call got matched to an incoming RPC.
///
/// Client-side StartCall/RPC invocation: \a ok indicates that the RPC is
/// going to go to the wire. If it is false, it not going to the wire. This
/// would happen if the channel is either permanently broken or
/// transiently broken but with the fail-fast option. (Note that async unary
/// RPCs don't post a CQ tag at this point, nor do client-streaming
/// or bidi-streaming RPCs that have the initial metadata corked option set.)
///
/// Client-side Write, Client-side WritesDone, Server-side Write,
/// Server-side Finish, Server-side SendInitialMetadata (which is
/// typically included in Write or Finish when not done explicitly):
/// \a ok means that the data/metadata/status/etc is going to go to the
/// wire. If it is false, it not going to the wire because the call
/// is already dead (i.e., canceled, deadline expired, other side
/// dropped the channel, etc).
///
/// Client-side Read, Server-side Read, Client-side
/// RecvInitialMetadata (which is typically included in Read if not
/// done explicitly): \a ok indicates whether there is a valid message
/// that got read. If not, you know that there are certainly no more
/// messages that can ever be read from this stream. For the client-side
/// operations, this only happens because the call is dead. For the
/// server-sider operation, though, this could happen because the client
/// has done a WritesDone already.
///
/// Client-side Finish: \a ok should always be true
///
/// Server-side AsyncNotifyWhenDone: \a ok should always be true
///
/// Alarm: \a ok is true if it expired, false if it was canceled
///
/// \return true if got an event, false if the queue is fully drained and
/// shut down.
bool Next(void** tag, bool* ok) {
return (AsyncNextInternal(tag, ok,
::grpc::g_core_codegen_interface->gpr_inf_future(
GPR_CLOCK_REALTIME)) != SHUTDOWN);
}
/// Read from the queue, blocking up to \a deadline (or the queue's shutdown).
/// Both \a tag and \a ok are updated upon success (if an event is available
/// within the \a deadline). A \a tag points to an arbitrary location usually
/// employed to uniquely identify an event.
///
/// \param tag [out] Upon sucess, updated to point to the event's tag.
/// \param ok [out] Upon sucess, true if a successful event, false otherwise
/// See documentation for CompletionQueue::Next for explanation of ok
/// \param deadline [in] How long to block in wait for an event.
///
/// \return The type of event read.
template <typename T>
NextStatus AsyncNext(void** tag, bool* ok, const T& deadline) {
::grpc::TimePoint<T> deadline_tp(deadline);
return AsyncNextInternal(tag, ok, deadline_tp.raw_time());
}
/// EXPERIMENTAL
/// First executes \a F, then reads from the queue, blocking up to
/// \a deadline (or the queue's shutdown).
/// Both \a tag and \a ok are updated upon success (if an event is available
/// within the \a deadline). A \a tag points to an arbitrary location usually
/// employed to uniquely identify an event.
///
/// \param f [in] Function to execute before calling AsyncNext on this queue.
/// \param tag [out] Upon sucess, updated to point to the event's tag.
/// \param ok [out] Upon sucess, true if read a regular event, false
/// otherwise.
/// \param deadline [in] How long to block in wait for an event.
///
/// \return The type of event read.
template <typename T, typename F>
NextStatus DoThenAsyncNext(F&& f, void** tag, bool* ok, const T& deadline) {
CompletionQueueTLSCache cache = CompletionQueueTLSCache(this);
f();
if (cache.Flush(tag, ok)) {
return GOT_EVENT;
} else {
return AsyncNext(tag, ok, deadline);
}
}
/// Request the shutdown of the queue.
///
/// \warning This method must be called at some point if this completion queue
/// is accessed with Next or AsyncNext. \a Next will not return false
/// until this method has been called and all pending tags have been drained.
/// (Likewise for \a AsyncNext returning \a NextStatus::SHUTDOWN .)
/// Only once either one of these methods does that (that is, once the queue
/// has been \em drained) can an instance of this class be destroyed.
/// Also note that applications must ensure that no work is enqueued on this
/// completion queue after this method is called.
void Shutdown();
/// Returns a \em raw pointer to the underlying \a grpc_completion_queue
/// instance.
///
/// \warning Remember that the returned instance is owned. No transfer of
/// owership is performed.
grpc_completion_queue* cq() { return cq_; }
protected:
/// Private constructor of CompletionQueue only visible to friend classes
CompletionQueue(const grpc_completion_queue_attributes& attributes) {
cq_ = ::grpc::g_core_codegen_interface->grpc_completion_queue_create(
::grpc::g_core_codegen_interface->grpc_completion_queue_factory_lookup(
&attributes),
&attributes, NULL);
InitialAvalanching(); // reserve this for the future shutdown
}
private:
// Friend synchronous wrappers so that they can access Pluck(), which is
// a semi-private API geared towards the synchronous implementation.
template <class R>
friend class ::grpc::ClientReader;
template <class W>
friend class ::grpc::ClientWriter;
template <class W, class R>
friend class ::grpc::ClientReaderWriter;
template <class R>
friend class ::grpc::ServerReader;
template <class W>
friend class ::grpc::ServerWriter;
template <class W, class R>
friend class ::grpc::internal::ServerReaderWriterBody;
template <class ServiceType, class RequestType, class ResponseType>
friend class ::grpc::internal::RpcMethodHandler;
template <class ServiceType, class RequestType, class ResponseType>
friend class ::grpc::internal::ClientStreamingHandler;
template <class ServiceType, class RequestType, class ResponseType>
friend class ::grpc::internal::ServerStreamingHandler;
template <class Streamer, bool WriteNeeded>
friend class ::grpc::internal::TemplatedBidiStreamingHandler;
template <::grpc::StatusCode code>
friend class ::grpc::internal::ErrorMethodHandler;
friend class ::grpc_impl::Server;
friend class ::grpc::ServerContext;
friend class ::grpc::ServerInterface;
template <class InputMessage, class OutputMessage>
friend class ::grpc::internal::BlockingUnaryCallImpl;
// Friends that need access to constructor for callback CQ
friend class ::grpc_impl::Channel;
// For access to Register/CompleteAvalanching
template <class Op1, class Op2, class Op3, class Op4, class Op5, class Op6>
friend class ::grpc::internal::CallOpSet;
/// EXPERIMENTAL
/// Creates a Thread Local cache to store the first event
/// On this completion queue queued from this thread. Once
/// initialized, it must be flushed on the same thread.
class CompletionQueueTLSCache {
public:
CompletionQueueTLSCache(CompletionQueue* cq);
~CompletionQueueTLSCache();
bool Flush(void** tag, bool* ok);
private:
CompletionQueue* cq_;
bool flushed_;
};
NextStatus AsyncNextInternal(void** tag, bool* ok, gpr_timespec deadline);
/// Wraps \a grpc_completion_queue_pluck.
/// \warning Must not be mixed with calls to \a Next.
bool Pluck(::grpc::internal::CompletionQueueTag* tag) {
auto deadline =
::grpc::g_core_codegen_interface->gpr_inf_future(GPR_CLOCK_REALTIME);
while (true) {
auto ev = ::grpc::g_core_codegen_interface->grpc_completion_queue_pluck(
cq_, tag, deadline, nullptr);
bool ok = ev.success != 0;
void* ignored = tag;
if (tag->FinalizeResult(&ignored, &ok)) {
GPR_CODEGEN_ASSERT(ignored == tag);
return ok;
}
}
}
/// Performs a single polling pluck on \a tag.
/// \warning Must not be mixed with calls to \a Next.
///
/// TODO: sreek - This calls tag->FinalizeResult() even if the cq_ is already
/// shutdown. This is most likely a bug and if it is a bug, then change this
/// implementation to simple call the other TryPluck function with a zero
/// timeout. i.e:
/// TryPluck(tag, gpr_time_0(GPR_CLOCK_REALTIME))
void TryPluck(::grpc::internal::CompletionQueueTag* tag) {
auto deadline =
::grpc::g_core_codegen_interface->gpr_time_0(GPR_CLOCK_REALTIME);
auto ev = ::grpc::g_core_codegen_interface->grpc_completion_queue_pluck(
cq_, tag, deadline, nullptr);
if (ev.type == GRPC_QUEUE_TIMEOUT) return;
bool ok = ev.success != 0;
void* ignored = tag;
// the tag must be swallowed if using TryPluck
GPR_CODEGEN_ASSERT(!tag->FinalizeResult(&ignored, &ok));
}
/// Performs a single polling pluck on \a tag. Calls tag->FinalizeResult if
/// the pluck() was successful and returned the tag.
///
/// This exects tag->FinalizeResult (if called) to return 'false' i.e expects
/// that the tag is internal not something that is returned to the user.
void TryPluck(::grpc::internal::CompletionQueueTag* tag,
gpr_timespec deadline) {
auto ev = ::grpc::g_core_codegen_interface->grpc_completion_queue_pluck(
cq_, tag, deadline, nullptr);
if (ev.type == GRPC_QUEUE_TIMEOUT || ev.type == GRPC_QUEUE_SHUTDOWN) {
return;
}
bool ok = ev.success != 0;
void* ignored = tag;
GPR_CODEGEN_ASSERT(!tag->FinalizeResult(&ignored, &ok));
}
/// Manage state of avalanching operations : completion queue tags that
/// trigger other completion queue operations. The underlying core completion
/// queue should not really shutdown until all avalanching operations have
/// been finalized. Note that we maintain the requirement that an avalanche
/// registration must take place before CQ shutdown (which must be maintained
/// elsehwere)
void InitialAvalanching() {
gpr_atm_rel_store(&avalanches_in_flight_, static_cast<gpr_atm>(1));
}
void RegisterAvalanching() {
gpr_atm_no_barrier_fetch_add(&avalanches_in_flight_,
static_cast<gpr_atm>(1));
}
void CompleteAvalanching() {
if (gpr_atm_no_barrier_fetch_add(&avalanches_in_flight_,
static_cast<gpr_atm>(-1)) == 1) {
::grpc::g_core_codegen_interface->grpc_completion_queue_shutdown(cq_);
}
}
grpc_completion_queue* cq_; // owned
gpr_atm avalanches_in_flight_;
};
/// A specific type of completion queue used by the processing of notifications
/// by servers. Instantiated by \a ServerBuilder.
class ServerCompletionQueue : public CompletionQueue {
public:
bool IsFrequentlyPolled() { return polling_type_ != GRPC_CQ_NON_LISTENING; }
protected:
/// Default constructor
ServerCompletionQueue() : polling_type_(GRPC_CQ_DEFAULT_POLLING) {}
private:
/// \param completion_type indicates whether this is a NEXT or CALLBACK
/// completion queue.
/// \param polling_type Informs the GRPC library about the type of polling
/// allowed on this completion queue. See grpc_cq_polling_type's description
/// in grpc_types.h for more details.
/// \param shutdown_cb is the shutdown callback used for CALLBACK api queues
ServerCompletionQueue(grpc_cq_completion_type completion_type,
grpc_cq_polling_type polling_type,
grpc_experimental_completion_queue_functor* shutdown_cb)
: CompletionQueue(grpc_completion_queue_attributes{
GRPC_CQ_CURRENT_VERSION, completion_type, polling_type,
shutdown_cb}),
polling_type_(polling_type) {}
grpc_cq_polling_type polling_type_;
friend class ::grpc_impl::ServerBuilder;
friend class ::grpc_impl::Server;
};
} // namespace grpc_impl
#endif // GRPCPP_IMPL_CODEGEN_COMPLETION_QUEUE_IMPL_H

@ -21,10 +21,6 @@
#include <grpcpp/impl/codegen/channel_interface.h>
namespace grpc_impl {
class CompletionQueue;
}
namespace grpc {
namespace internal {
@ -50,7 +46,7 @@ class InterceptedChannel : public ChannelInterface {
: channel_(channel), interceptor_pos_(pos) {}
Call CreateCall(const RpcMethod& method, ClientContext* context,
::grpc_impl::CompletionQueue* cq) override {
CompletionQueue* cq) override {
return channel_->CreateCallInternal(method, context, cq, interceptor_pos_);
}
@ -62,8 +58,7 @@ class InterceptedChannel : public ChannelInterface {
}
void NotifyOnStateChangeImpl(grpc_connectivity_state last_observed,
gpr_timespec deadline,
::grpc_impl::CompletionQueue* cq,
gpr_timespec deadline, CompletionQueue* cq,
void* tag) override {
return channel_->NotifyOnStateChangeImpl(last_observed, deadline, cq, tag);
}
@ -72,9 +67,7 @@ class InterceptedChannel : public ChannelInterface {
return channel_->WaitForStateChangeImpl(last_observed, deadline);
}
::grpc_impl::CompletionQueue* CallbackCQ() override {
return channel_->CallbackCQ();
}
CompletionQueue* CallbackCQ() override { return channel_->CallbackCQ(); }
ChannelInterface* channel_;
size_t interceptor_pos_;

@ -37,11 +37,43 @@ namespace grpc {
// Declare base class of all reactors as internal
namespace internal {
// Forward declarations
template <class Request, class Response>
class CallbackClientStreamingHandler;
template <class Request, class Response>
class CallbackServerStreamingHandler;
template <class Request, class Response>
class CallbackBidiHandler;
class ServerReactor {
public:
virtual ~ServerReactor() = default;
virtual void OnDone() = 0;
virtual void OnCancel() = 0;
private:
friend class ::grpc::ServerContext;
template <class Request, class Response>
friend class CallbackClientStreamingHandler;
template <class Request, class Response>
friend class CallbackServerStreamingHandler;
template <class Request, class Response>
friend class CallbackBidiHandler;
// The ServerReactor is responsible for tracking when it is safe to call
// OnCancel. This function should not be called until after OnStarted is done
// and the RPC has completed with a cancellation. This is tracked by counting
// how many of these conditions have been met and calling OnCancel when none
// remain unmet.
void MaybeCallOnCancel() {
if (on_cancel_conditions_remaining_.fetch_sub(
1, std::memory_order_acq_rel) == 1) {
OnCancel();
}
}
std::atomic_int on_cancel_conditions_remaining_{2};
};
} // namespace internal
@ -590,6 +622,8 @@ class CallbackClientStreamingHandler : public MethodHandler {
reader->BindReactor(reactor);
reactor->OnStarted(param.server_context, reader->response());
// The earliest that OnCancel can be called is after OnStarted is done.
reactor->MaybeCallOnCancel();
reader->MaybeDone();
}
@ -732,6 +766,8 @@ class CallbackServerStreamingHandler : public MethodHandler {
std::move(param.call_requester), reactor);
writer->BindReactor(reactor);
reactor->OnStarted(param.server_context, writer->request());
// The earliest that OnCancel can be called is after OnStarted is done.
reactor->MaybeCallOnCancel();
writer->MaybeDone();
}
@ -908,6 +944,8 @@ class CallbackBidiHandler : public MethodHandler {
stream->BindReactor(reactor);
reactor->OnStarted(param.server_context);
// The earliest that OnCancel can be called is after OnStarted is done.
reactor->MaybeCallOnCancel();
stream->MaybeDone();
}

@ -41,13 +41,11 @@ struct grpc_metadata;
struct grpc_call;
struct census_context;
namespace grpc_impl {
class CompletionQueue;
class Server;
} // namespace grpc_impl
namespace grpc {
class ClientContext;
class GenericServerContext;
class CompletionQueue;
class Server;
class ServerInterface;
template <class W, class R>
class ServerAsyncReader;
@ -89,7 +87,6 @@ class Call;
class ServerReactor;
} // namespace internal
class ServerInterface;
namespace testing {
class InteropServerContextInspector;
class ServerContextTestSpouse;
@ -272,7 +269,7 @@ class ServerContext {
friend class ::grpc::testing::InteropServerContextInspector;
friend class ::grpc::testing::ServerContextTestSpouse;
friend class ::grpc::ServerInterface;
friend class ::grpc_impl::Server;
friend class ::grpc::Server;
template <class W, class R>
friend class ::grpc::ServerAsyncReader;
template <class W>
@ -354,7 +351,7 @@ class ServerContext {
gpr_timespec deadline_;
grpc_call* call_;
::grpc_impl::CompletionQueue* cq_;
CompletionQueue* cq_;
bool sent_initial_metadata_;
mutable std::shared_ptr<const AuthContext> auth_context_;
mutable internal::MetadataMap client_metadata_;

@ -29,14 +29,15 @@
#include <grpcpp/impl/codegen/server_context.h>
namespace grpc_impl {
class CompletionQueue;
class ServerCompletionQueue;
class ServerCredentials;
} // namespace grpc_impl
}
namespace grpc {
class AsyncGenericService;
class Channel;
class GenericServerContext;
class ServerCompletionQueue;
class ServerContext;
class Service;
@ -148,7 +149,7 @@ class ServerInterface : public internal::CallHook {
/// 192.168.1.1:31416, [::1]:27182, etc.).
/// \params creds The credentials associated with the server.
///
/// \return bound port number on sucess, 0 on failure.
/// \return bound port number on success, 0 on failure.
///
/// \warning It's an error to call this method on an already started server.
virtual int AddListeningPort(const grpc::string& addr,
@ -160,8 +161,7 @@ class ServerInterface : public internal::CallHook {
/// caller is required to keep all completion queues live until the server is
/// destroyed.
/// \param num_cqs How many completion queues does \a cqs hold.
virtual void Start(::grpc_impl::ServerCompletionQueue** cqs,
size_t num_cqs) = 0;
virtual void Start(ServerCompletionQueue** cqs, size_t num_cqs) = 0;
virtual void ShutdownInternal(gpr_timespec deadline) = 0;
@ -176,9 +176,9 @@ class ServerInterface : public internal::CallHook {
public:
BaseAsyncRequest(ServerInterface* server, ServerContext* context,
internal::ServerAsyncStreamingInterface* stream,
::grpc_impl::CompletionQueue* call_cq,
::grpc_impl::ServerCompletionQueue* notification_cq,
void* tag, bool delete_on_finalize);
CompletionQueue* call_cq,
ServerCompletionQueue* notification_cq, void* tag,
bool delete_on_finalize);
virtual ~BaseAsyncRequest();
bool FinalizeResult(void** tag, bool* status) override;
@ -190,8 +190,8 @@ class ServerInterface : public internal::CallHook {
ServerInterface* const server_;
ServerContext* const context_;
internal::ServerAsyncStreamingInterface* const stream_;
::grpc_impl::CompletionQueue* const call_cq_;
::grpc_impl::ServerCompletionQueue* const notification_cq_;
CompletionQueue* const call_cq_;
ServerCompletionQueue* const notification_cq_;
void* const tag_;
const bool delete_on_finalize_;
grpc_call* call_;
@ -205,17 +205,16 @@ class ServerInterface : public internal::CallHook {
public:
RegisteredAsyncRequest(ServerInterface* server, ServerContext* context,
internal::ServerAsyncStreamingInterface* stream,
::grpc_impl::CompletionQueue* call_cq,
::grpc_impl::ServerCompletionQueue* notification_cq,
void* tag, const char* name,
internal::RpcMethod::RpcType type);
CompletionQueue* call_cq,
ServerCompletionQueue* notification_cq, void* tag,
const char* name, internal::RpcMethod::RpcType type);
virtual bool FinalizeResult(void** tag, bool* status) override {
/* If we are done intercepting, then there is nothing more for us to do */
if (done_intercepting_) {
return BaseAsyncRequest::FinalizeResult(tag, status);
}
call_wrapper_ = ::grpc::internal::Call(
call_wrapper_ = internal::Call(
call_, server_, call_cq_, server_->max_receive_message_size(),
context_->set_server_rpc_info(name_, type_,
*server_->interceptor_creators()));
@ -224,7 +223,7 @@ class ServerInterface : public internal::CallHook {
protected:
void IssueRequest(void* registered_method, grpc_byte_buffer** payload,
::grpc_impl::ServerCompletionQueue* notification_cq);
ServerCompletionQueue* notification_cq);
const char* name_;
const internal::RpcMethod::RpcType type_;
};
@ -234,9 +233,8 @@ class ServerInterface : public internal::CallHook {
NoPayloadAsyncRequest(internal::RpcServiceMethod* registered_method,
ServerInterface* server, ServerContext* context,
internal::ServerAsyncStreamingInterface* stream,
::grpc_impl::CompletionQueue* call_cq,
::grpc_impl::ServerCompletionQueue* notification_cq,
void* tag)
CompletionQueue* call_cq,
ServerCompletionQueue* notification_cq, void* tag)
: RegisteredAsyncRequest(
server, context, stream, call_cq, notification_cq, tag,
registered_method->name(), registered_method->method_type()) {
@ -252,9 +250,9 @@ class ServerInterface : public internal::CallHook {
PayloadAsyncRequest(internal::RpcServiceMethod* registered_method,
ServerInterface* server, ServerContext* context,
internal::ServerAsyncStreamingInterface* stream,
::grpc_impl::CompletionQueue* call_cq,
::grpc_impl::ServerCompletionQueue* notification_cq,
void* tag, Message* request)
CompletionQueue* call_cq,
ServerCompletionQueue* notification_cq, void* tag,
Message* request)
: RegisteredAsyncRequest(
server, context, stream, call_cq, notification_cq, tag,
registered_method->name(), registered_method->method_type()),
@ -309,9 +307,9 @@ class ServerInterface : public internal::CallHook {
ServerInterface* const server_;
ServerContext* const context_;
internal::ServerAsyncStreamingInterface* const stream_;
::grpc_impl::CompletionQueue* const call_cq_;
CompletionQueue* const call_cq_;
::grpc_impl::ServerCompletionQueue* const notification_cq_;
ServerCompletionQueue* const notification_cq_;
void* const tag_;
Message* const request_;
ByteBuffer payload_;
@ -321,9 +319,9 @@ class ServerInterface : public internal::CallHook {
public:
GenericAsyncRequest(ServerInterface* server, GenericServerContext* context,
internal::ServerAsyncStreamingInterface* stream,
::grpc_impl::CompletionQueue* call_cq,
::grpc_impl::ServerCompletionQueue* notification_cq,
void* tag, bool delete_on_finalize);
CompletionQueue* call_cq,
ServerCompletionQueue* notification_cq, void* tag,
bool delete_on_finalize);
bool FinalizeResult(void** tag, bool* status) override;
@ -335,9 +333,9 @@ class ServerInterface : public internal::CallHook {
void RequestAsyncCall(internal::RpcServiceMethod* method,
ServerContext* context,
internal::ServerAsyncStreamingInterface* stream,
::grpc_impl::CompletionQueue* call_cq,
::grpc_impl::ServerCompletionQueue* notification_cq,
void* tag, Message* message) {
CompletionQueue* call_cq,
ServerCompletionQueue* notification_cq, void* tag,
Message* message) {
GPR_CODEGEN_ASSERT(method);
new PayloadAsyncRequest<Message>(method, this, context, stream, call_cq,
notification_cq, tag, message);
@ -346,19 +344,18 @@ class ServerInterface : public internal::CallHook {
void RequestAsyncCall(internal::RpcServiceMethod* method,
ServerContext* context,
internal::ServerAsyncStreamingInterface* stream,
::grpc_impl::CompletionQueue* call_cq,
::grpc_impl::ServerCompletionQueue* notification_cq,
void* tag) {
CompletionQueue* call_cq,
ServerCompletionQueue* notification_cq, void* tag) {
GPR_CODEGEN_ASSERT(method);
new NoPayloadAsyncRequest(method, this, context, stream, call_cq,
notification_cq, tag);
}
void RequestAsyncGenericCall(
GenericServerContext* context,
internal::ServerAsyncStreamingInterface* stream,
::grpc_impl::CompletionQueue* call_cq,
::grpc_impl::ServerCompletionQueue* notification_cq, void* tag) {
void RequestAsyncGenericCall(GenericServerContext* context,
internal::ServerAsyncStreamingInterface* stream,
CompletionQueue* call_cq,
ServerCompletionQueue* notification_cq,
void* tag) {
new GenericAsyncRequest(this, context, stream, call_cq, notification_cq,
tag, true);
}
@ -383,7 +380,7 @@ class ServerInterface : public internal::CallHook {
// Returns nullptr (rather than being pure) since this is a post-1.0 method
// and adding a new pure method to an interface would be a breaking change
// (even though this is private and non-API)
virtual ::grpc_impl::CompletionQueue* CallbackCQ() { return nullptr; }
virtual CompletionQueue* CallbackCQ() { return nullptr; }
};
} // namespace grpc

@ -26,13 +26,12 @@
#include <grpcpp/impl/codegen/server_interface.h>
#include <grpcpp/impl/codegen/status.h>
namespace grpc_impl {
class Server;
} // namespace grpc_impl
namespace grpc {
class CompletionQueue;
class Server;
class ServerInterface;
class ServerCompletionQueue;
class ServerContext;
namespace internal {
@ -229,7 +228,7 @@ class Service {
}
private:
friend class grpc_impl::Server;
friend class Server;
friend class ServerInterface;
ServerInterface* server_;
std::vector<std::unique_ptr<internal::RpcServiceMethod>> methods_;

@ -19,8 +19,15 @@
#ifndef GRPCPP_IMPL_CODEGEN_SYNC_H
#define GRPCPP_IMPL_CODEGEN_SYNC_H
#include <grpc/impl/codegen/log.h>
#include <grpc/impl/codegen/port_platform.h>
#ifdef GPR_HAS_PTHREAD_H
#include <pthread.h>
#endif
#include <mutex>
#include <grpc/impl/codegen/log.h>
#include <grpc/impl/codegen/sync.h>
#include <grpcpp/impl/codegen/core_codegen_interface.h>
@ -49,7 +56,13 @@ class Mutex {
const gpr_mu* get() const { return &mu_; }
private:
gpr_mu mu_;
union {
gpr_mu mu_;
std::mutex do_not_use_sth_;
#ifdef GPR_HAS_PTHREAD_H
pthread_mutex_t do_not_use_pth_;
#endif
};
};
// MutexLock is a std::

@ -180,7 +180,7 @@ class ClientReader final : public ClientReaderInterface<R> {
///
// Side effect:
/// Once complete, the initial metadata read from
/// the server will be accessable through the \a ClientContext used to
/// the server will be accessible through the \a ClientContext used to
/// construct this object.
void WaitForInitialMetadata() override {
GPR_CODEGEN_ASSERT(!context_->initial_metadata_received_);
@ -298,7 +298,7 @@ class ClientWriter : public ClientWriterInterface<W> {
///
// Side effect:
/// Once complete, the initial metadata read from the server will be
/// accessable through the \a ClientContext used to construct this object.
/// accessible through the \a ClientContext used to construct this object.
void WaitForInitialMetadata() {
GPR_CODEGEN_ASSERT(!context_->initial_metadata_received_);
@ -449,7 +449,7 @@ class ClientReaderWriter final : public ClientReaderWriterInterface<W, R> {
/// with or after the \a Finish method.
///
/// Once complete, the initial metadata read from the server will be
/// accessable through the \a ClientContext used to construct this object.
/// accessible through the \a ClientContext used to construct this object.
void WaitForInitialMetadata() override {
GPR_CODEGEN_ASSERT(!context_->initial_metadata_received_);

@ -26,10 +26,10 @@
namespace grpc {
class Server;
class Service;
} // namespace grpc
namespace grpc_impl {
class Server;
class ServerInitializer {
public:

@ -32,26 +32,20 @@
struct grpc_call;
namespace grpc_impl {
class Channel;
} // namespace grpc_impl
namespace grpc {
class CallCredentials;
class ChannelArguments;
class ChannelCredentials;
class SecureCallCredentials;
class SecureChannelCredentials;
} // namespace grpc
namespace grpc_impl {
std::shared_ptr<Channel> CreateCustomChannel(
std::shared_ptr<grpc::Channel> CreateCustomChannel(
const grpc::string& target,
const std::shared_ptr<grpc::ChannelCredentials>& creds,
const grpc::ChannelArguments& args);
namespace experimental {
std::shared_ptr<Channel> CreateCustomChannelWithInterceptors(
std::shared_ptr<grpc::Channel> CreateCustomChannelWithInterceptors(
const grpc::string& target,
const std::shared_ptr<grpc::ChannelCredentials>& creds,
const grpc::ChannelArguments& args,
@ -61,6 +55,7 @@ std::shared_ptr<Channel> CreateCustomChannelWithInterceptors(
} // namespace experimental
} // namespace grpc_impl
namespace grpc {
class Channel;
class SecureChannelCredentials;
class SecureCallCredentials;
@ -83,12 +78,12 @@ class ChannelCredentials : private GrpcLibraryCodegen {
virtual SecureChannelCredentials* AsSecureCredentials() = 0;
private:
friend std::shared_ptr<::grpc_impl::Channel> grpc_impl::CreateCustomChannel(
friend std::shared_ptr<Channel> grpc_impl::CreateCustomChannel(
const grpc::string& target,
const std::shared_ptr<ChannelCredentials>& creds,
const grpc::ChannelArguments& args);
friend std::shared_ptr<::grpc_impl::Channel>
friend std::shared_ptr<Channel>
grpc_impl::experimental::CreateCustomChannelWithInterceptors(
const grpc::string& target,
const std::shared_ptr<ChannelCredentials>& creds,
@ -97,12 +92,12 @@ class ChannelCredentials : private GrpcLibraryCodegen {
grpc::experimental::ClientInterceptorFactoryInterface>>
interceptor_creators);
virtual std::shared_ptr<::grpc_impl::Channel> CreateChannel(
virtual std::shared_ptr<Channel> CreateChannel(
const grpc::string& target, const ChannelArguments& args) = 0;
// This function should have been a pure virtual function, but it is
// implemented as a virtual function so that it does not break API.
virtual std::shared_ptr<::grpc_impl::Channel> CreateChannelWithInterceptors(
virtual std::shared_ptr<Channel> CreateChannelWithInterceptors(
const grpc::string& target, const ChannelArguments& args,
std::vector<
std::unique_ptr<experimental::ClientInterceptorFactoryInterface>>

@ -21,10 +21,6 @@
#include <grpcpp/security/server_credentials_impl.h>
namespace grpc_impl {
class Server;
} // namespace grpc_impl
namespace grpc {
typedef ::grpc_impl::ServerCredentials ServerCredentials;

@ -30,10 +30,10 @@ struct grpc_server;
namespace grpc {
class Server;
struct SslServerCredentialsOptions;
} // namespace grpc
namespace grpc_impl {
class Server;
/// Wrapper around \a grpc_server_credentials, a way to authenticate a server.
class ServerCredentials {
@ -46,7 +46,7 @@ class ServerCredentials {
const std::shared_ptr<grpc::AuthMetadataProcessor>& processor) = 0;
private:
friend class ::grpc_impl::Server;
friend class ::grpc::Server;
/// Tries to bind \a server to the given \a addr (eg, localhost:1234,
/// 192.168.1.1:31416, [::1]:27182, etc.)

@ -1,6 +1,6 @@
/*
*
* Copyright 2019 gRPC authors.
* Copyright 2015 gRPC authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -19,11 +19,333 @@
#ifndef GRPCPP_SERVER_H
#define GRPCPP_SERVER_H
#include <grpcpp/server_impl.h>
#include <condition_variable>
#include <list>
#include <memory>
#include <mutex>
#include <vector>
#include <grpc/compression.h>
#include <grpc/support/atm.h>
#include <grpcpp/completion_queue.h>
#include <grpcpp/health_check_service_interface.h>
#include <grpcpp/impl/call.h>
#include <grpcpp/impl/codegen/client_interceptor.h>
#include <grpcpp/impl/codegen/grpc_library.h>
#include <grpcpp/impl/codegen/server_interface.h>
#include <grpcpp/impl/rpc_service_method.h>
#include <grpcpp/security/server_credentials.h>
#include <grpcpp/support/channel_arguments.h>
#include <grpcpp/support/config.h>
#include <grpcpp/support/status.h>
struct grpc_server;
namespace grpc_impl {
class ServerInitializer;
}
namespace grpc {
typedef ::grpc_impl::Server Server;
class AsyncGenericService;
class ServerContext;
/// Represents a gRPC server.
///
/// Use a \a grpc::ServerBuilder to create, configure, and start
/// \a Server instances.
class Server : public ServerInterface, private GrpcLibraryCodegen {
public:
~Server();
/// Block until the server shuts down.
///
/// \warning The server must be either shutting down or some other thread must
/// call \a Shutdown for this function to ever return.
void Wait() override;
/// Global callbacks are a set of hooks that are called when server
/// events occur. \a SetGlobalCallbacks method is used to register
/// the hooks with gRPC. Note that
/// the \a GlobalCallbacks instance will be shared among all
/// \a Server instances in an application and can be set exactly
/// once per application.
class GlobalCallbacks {
public:
virtual ~GlobalCallbacks() {}
/// Called before server is created.
virtual void UpdateArguments(ChannelArguments* args) {}
/// Called before application callback for each synchronous server request
virtual void PreSynchronousRequest(ServerContext* context) = 0;
/// Called after application callback for each synchronous server request
virtual void PostSynchronousRequest(ServerContext* context) = 0;
/// Called before server is started.
virtual void PreServerStart(Server* server) {}
/// Called after a server port is added.
virtual void AddPort(Server* server, const grpc::string& addr,
ServerCredentials* creds, int port) {}
};
/// Set the global callback object. Can only be called once per application.
/// Does not take ownership of callbacks, and expects the pointed to object
/// to be alive until all server objects in the process have been destroyed.
/// The same \a GlobalCallbacks object will be used throughout the
/// application and is shared among all \a Server objects.
static void SetGlobalCallbacks(GlobalCallbacks* callbacks);
/// Returns a \em raw pointer to the underlying \a grpc_server instance.
/// EXPERIMENTAL: for internal/test use only
grpc_server* c_server();
/// Returns the health check service.
HealthCheckServiceInterface* GetHealthCheckService() const {
return health_check_service_.get();
}
/// Establish a channel for in-process communication
std::shared_ptr<Channel> InProcessChannel(const ChannelArguments& args);
/// NOTE: class experimental_type is not part of the public API of this class.
/// TODO(yashykt): Integrate into public API when this is no longer
/// experimental.
class experimental_type {
public:
explicit experimental_type(Server* server) : server_(server) {}
/// Establish a channel for in-process communication with client
/// interceptors
std::shared_ptr<Channel> InProcessChannelWithInterceptors(
const ChannelArguments& args,
std::vector<
std::unique_ptr<experimental::ClientInterceptorFactoryInterface>>
interceptor_creators);
private:
Server* server_;
};
/// NOTE: The function experimental() is not stable public API. It is a view
/// to the experimental components of this class. It may be changed or removed
/// at any time.
experimental_type experimental() { return experimental_type(this); }
protected:
/// Register a service. This call does not take ownership of the service.
/// The service must exist for the lifetime of the Server instance.
bool RegisterService(const grpc::string* host, Service* service) override;
/// Try binding the server to the given \a addr endpoint
/// (port, and optionally including IP address to bind to).
///
/// It can be invoked multiple times. Should be used before
/// starting the server.
///
/// \param addr The address to try to bind to the server (eg, localhost:1234,
/// 192.168.1.1:31416, [::1]:27182, etc.).
/// \param creds The credentials associated with the server.
///
/// \return bound port number on success, 0 on failure.
///
/// \warning It is an error to call this method on an already started server.
int AddListeningPort(const grpc::string& addr,
ServerCredentials* creds) override;
/// NOTE: This is *NOT* a public API. The server constructors are supposed to
/// be used by \a ServerBuilder class only. The constructor will be made
/// 'private' very soon.
///
/// Server constructors. To be used by \a ServerBuilder only.
///
/// \param max_message_size Maximum message length that the channel can
/// receive.
///
/// \param args The channel args
///
/// \param sync_server_cqs The completion queues to use if the server is a
/// synchronous server (or a hybrid server). The server polls for new RPCs on
/// these queues
///
/// \param min_pollers The minimum number of polling threads per server
/// completion queue (in param sync_server_cqs) to use for listening to
/// incoming requests (used only in case of sync server)
///
/// \param max_pollers The maximum number of polling threads per server
/// completion queue (in param sync_server_cqs) to use for listening to
/// incoming requests (used only in case of sync server)
///
/// \param sync_cq_timeout_msec The timeout to use when calling AsyncNext() on
/// server completion queues passed via sync_server_cqs param.
Server(int max_message_size, ChannelArguments* args,
std::shared_ptr<std::vector<std::unique_ptr<ServerCompletionQueue>>>
sync_server_cqs,
int min_pollers, int max_pollers, int sync_cq_timeout_msec,
grpc_resource_quota* server_rq = nullptr,
std::vector<
std::unique_ptr<experimental::ServerInterceptorFactoryInterface>>
interceptor_creators = std::vector<std::unique_ptr<
experimental::ServerInterceptorFactoryInterface>>());
/// Start the server.
///
/// \param cqs Completion queues for handling asynchronous services. The
/// caller is required to keep all completion queues live until the server is
/// destroyed.
/// \param num_cqs How many completion queues does \a cqs hold.
void Start(ServerCompletionQueue** cqs, size_t num_cqs) override;
grpc_server* server() override { return server_; }
private:
std::vector<std::unique_ptr<experimental::ServerInterceptorFactoryInterface>>*
interceptor_creators() override {
return &interceptor_creators_;
}
friend class AsyncGenericService;
friend class grpc_impl::ServerBuilder;
friend class grpc_impl::ServerInitializer;
class SyncRequest;
class CallbackRequestBase;
template <class ServerContextType>
class CallbackRequest;
class UnimplementedAsyncRequest;
class UnimplementedAsyncResponse;
/// SyncRequestThreadManager is an implementation of ThreadManager. This class
/// is responsible for polling for incoming RPCs and calling the RPC handlers.
/// This is only used in case of a Sync server (i.e a server exposing a sync
/// interface)
class SyncRequestThreadManager;
/// Register a generic service. This call does not take ownership of the
/// service. The service must exist for the lifetime of the Server instance.
void RegisterAsyncGenericService(AsyncGenericService* service) override;
/// NOTE: class experimental_registration_type is not part of the public API
/// of this class
/// TODO(vjpai): Move these contents to the public API of Server when
/// they are no longer experimental
class experimental_registration_type final
: public experimental_registration_interface {
public:
explicit experimental_registration_type(Server* server) : server_(server) {}
void RegisterCallbackGenericService(
experimental::CallbackGenericService* service) override {
server_->RegisterCallbackGenericService(service);
}
private:
Server* server_;
};
/// TODO(vjpai): Mark this override when experimental type above is deleted
void RegisterCallbackGenericService(
experimental::CallbackGenericService* service);
/// NOTE: The function experimental_registration() is not stable public API.
/// It is a view to the experimental components of this class. It may be
/// changed or removed at any time.
experimental_registration_interface* experimental_registration() override {
return &experimental_registration_;
}
void PerformOpsOnCall(internal::CallOpSetInterface* ops,
internal::Call* call) override;
void ShutdownInternal(gpr_timespec deadline) override;
int max_receive_message_size() const override {
return max_receive_message_size_;
}
CompletionQueue* CallbackCQ() override;
grpc_impl::ServerInitializer* initializer();
// A vector of interceptor factory objects.
// This should be destroyed after health_check_service_ and this requirement
// is satisfied by declaring interceptor_creators_ before
// health_check_service_. (C++ mandates that member objects be destroyed in
// the reverse order of initialization.)
std::vector<std::unique_ptr<experimental::ServerInterceptorFactoryInterface>>
interceptor_creators_;
const int max_receive_message_size_;
/// The following completion queues are ONLY used in case of Sync API
/// i.e. if the server has any services with sync methods. The server uses
/// these completion queues to poll for new RPCs
std::shared_ptr<std::vector<std::unique_ptr<ServerCompletionQueue>>>
sync_server_cqs_;
/// List of \a ThreadManager instances (one for each cq in
/// the \a sync_server_cqs)
std::vector<std::unique_ptr<SyncRequestThreadManager>> sync_req_mgrs_;
// Outstanding unmatched callback requests, indexed by method.
// NOTE: Using a gpr_atm rather than atomic_int because atomic_int isn't
// copyable or movable and thus will cause compilation errors. We
// actually only want to extend the vector before the threaded use
// starts, but this is still a limitation.
std::vector<gpr_atm> callback_unmatched_reqs_count_;
// List of callback requests to start when server actually starts.
std::list<CallbackRequestBase*> callback_reqs_to_start_;
// For registering experimental callback generic service; remove when that
// method longer experimental
experimental_registration_type experimental_registration_{this};
// Server status
grpc::internal::Mutex mu_;
bool started_;
bool shutdown_;
bool shutdown_notified_; // Was notify called on the shutdown_cv_
grpc::internal::CondVar shutdown_cv_;
// It is ok (but not required) to nest callback_reqs_mu_ under mu_ .
// Incrementing callback_reqs_outstanding_ is ok without a lock but it must be
// decremented under the lock in case it is the last request and enables the
// server shutdown. The increment is performance-critical since it happens
// during periods of increasing load; the decrement happens only when memory
// is maxed out, during server shutdown, or (possibly in a future version)
// 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::shared_ptr<GlobalCallbacks> global_callbacks_;
std::vector<grpc::string> services_;
bool has_async_generic_service_{false};
bool has_callback_generic_service_{false};
// Pointer to the wrapped grpc_server.
grpc_server* server_;
std::unique_ptr<grpc_impl::ServerInitializer> server_initializer_;
std::unique_ptr<HealthCheckServiceInterface> health_check_service_;
bool health_check_service_disabled_;
// When appropriate, use a default callback generic service to handle
// unimplemented methods
std::unique_ptr<experimental::CallbackGenericService> unimplemented_service_;
// A special handler for resource exhausted in sync case
std::unique_ptr<internal::MethodHandler> resource_exhausted_handler_;
// Handler for callback generic service, if any
std::unique_ptr<internal::MethodHandler> generic_handler_;
// callback_cq_ references the callbackable completion queue associated
// with this server (if any). It is set on the first call to CallbackCQ().
// It is _not owned_ by the server; ownership belongs with its internal
// shutdown callback tag (invoked when the CQ is fully shutdown).
// It is protected by mu_
CompletionQueue* callback_cq_ = nullptr;
};
} // namespace grpc

@ -21,6 +21,12 @@
#include <grpcpp/server_builder_impl.h>
namespace grpc_impl {
class ServerCredentials;
class ResourceQuota;
} // namespace grpc_impl
namespace grpc {
typedef ::grpc_impl::ServerBuilder ServerBuilder;

@ -31,21 +31,21 @@
#include <grpcpp/impl/codegen/server_interceptor.h>
#include <grpcpp/impl/server_builder_option.h>
#include <grpcpp/impl/server_builder_plugin.h>
#include <grpcpp/server.h>
#include <grpcpp/support/config.h>
struct grpc_resource_quota;
namespace grpc_impl {
class CompletionQueue;
class ResourceQuota;
class ServerCompletionQueue;
class ServerCredentials;
} // namespace grpc_impl
namespace grpc {
class AsyncGenericService;
class CompletionQueue;
class Server;
class ServerCompletionQueue;
class Service;
namespace testing {

@ -27,7 +27,6 @@
#include <grpc/compression.h>
#include <grpc/support/atm.h>
#include <grpcpp/channel.h>
#include <grpcpp/completion_queue.h>
#include <grpcpp/impl/call.h>
#include <grpcpp/impl/codegen/client_interceptor.h>

@ -333,6 +333,7 @@
<file baseinstalldir="/" name="src/core/lib/channel/handshaker_registry.h" role="src" />
<file baseinstalldir="/" name="src/core/lib/channel/status_util.h" role="src" />
<file baseinstalldir="/" name="src/core/lib/compression/algorithm_metadata.h" role="src" />
<file baseinstalldir="/" name="src/core/lib/compression/compression_args.h" role="src" />
<file baseinstalldir="/" name="src/core/lib/compression/compression_internal.h" role="src" />
<file baseinstalldir="/" name="src/core/lib/compression/message_compress.h" role="src" />
<file baseinstalldir="/" name="src/core/lib/compression/stream_compression.h" role="src" />
@ -487,6 +488,7 @@
<file baseinstalldir="/" name="src/core/lib/channel/handshaker_registry.cc" role="src" />
<file baseinstalldir="/" name="src/core/lib/channel/status_util.cc" role="src" />
<file baseinstalldir="/" name="src/core/lib/compression/compression.cc" role="src" />
<file baseinstalldir="/" name="src/core/lib/compression/compression_args.cc" role="src" />
<file baseinstalldir="/" name="src/core/lib/compression/compression_internal.cc" role="src" />
<file baseinstalldir="/" name="src/core/lib/compression/message_compress.cc" role="src" />
<file baseinstalldir="/" name="src/core/lib/compression/stream_compression.cc" role="src" />

@ -84,7 +84,7 @@ void PrintIncludes(grpc_generator::Printer* printer,
}
grpc::string GetHeaderPrologue(grpc_generator::File* file,
const Parameters& /*params*/) {
const Parameters& params) {
grpc::string output;
{
// Scope the output stream so it closes and finalizes output to the string.
@ -94,7 +94,9 @@ grpc::string GetHeaderPrologue(grpc_generator::File* file,
vars["filename"] = file->filename();
vars["filename_identifier"] = FilenameIdentifier(file->filename());
vars["filename_base"] = file->filename_without_ext();
vars["message_header_ext"] = kCppGeneratorMessageHeaderExt;
vars["message_header_ext"] = params.message_header_extension.empty()
? kCppGeneratorMessageHeaderExt
: params.message_header_extension;
printer->Print(vars, "// Generated by the gRPC C++ plugin.\n");
printer->Print(vars,
@ -115,6 +117,13 @@ grpc::string GetHeaderPrologue(grpc_generator::File* file,
return output;
}
// Convert from "a/b/c.proto" to "#include \"a/b/c$message_header_ext$\"\n"
grpc::string ImportInludeFromProtoName(const grpc::string& proto_name) {
return grpc::string("#include \"") +
proto_name.substr(0, proto_name.size() - 6) +
grpc::string("$message_header_ext$\"\n");
}
grpc::string GetHeaderIncludes(grpc_generator::File* file,
const Parameters& params) {
grpc::string output;
@ -145,15 +154,27 @@ grpc::string GetHeaderIncludes(grpc_generator::File* file,
PrintIncludes(printer.get(), headers, params.use_system_headers,
params.grpc_search_path);
printer->Print(vars, "\n");
printer->Print(vars, "namespace grpc_impl {\n");
printer->Print(vars, "class Channel;\n");
printer->Print(vars, "namespace grpc {\n");
printer->Print(vars, "class CompletionQueue;\n");
printer->Print(vars, "class Channel;\n");
printer->Print(vars, "class ServerCompletionQueue;\n");
printer->Print(vars, "} // namespace grpc_impl\n\n");
printer->Print(vars, "namespace grpc {\n");
printer->Print(vars, "class ServerContext;\n");
printer->Print(vars, "} // namespace grpc\n\n");
vars["message_header_ext"] = params.message_header_extension.empty()
? kCppGeneratorMessageHeaderExt
: params.message_header_extension;
if (params.include_import_headers) {
const std::vector<grpc::string> import_names = file->GetImportNames();
for (const auto& import_name : import_names) {
const grpc::string include_name =
ImportInludeFromProtoName(import_name);
printer->Print(vars, include_name.c_str());
}
printer->PrintRaw("\n");
}
if (!file->package().empty()) {
std::vector<grpc::string> parts = file->package_parts();
@ -1558,7 +1579,7 @@ grpc::string GetHeaderEpilogue(grpc_generator::File* file,
}
grpc::string GetSourcePrologue(grpc_generator::File* file,
const Parameters& /*params*/) {
const Parameters& params) {
grpc::string output;
{
// Scope the output stream so it closes and finalizes output to the string.
@ -1567,7 +1588,9 @@ grpc::string GetSourcePrologue(grpc_generator::File* file,
vars["filename"] = file->filename();
vars["filename_base"] = file->filename_without_ext();
vars["message_header_ext"] = kCppGeneratorMessageHeaderExt;
vars["message_header_ext"] = params.message_header_extension.empty()
? kCppGeneratorMessageHeaderExt
: params.message_header_extension;
vars["service_header_ext"] = kCppGeneratorServiceHeaderExt;
printer->Print(vars, "// Generated by the gRPC C++ plugin.\n");
@ -1589,7 +1612,6 @@ grpc::string GetSourceIncludes(grpc_generator::File* file,
// Scope the output stream so it closes and finalizes output to the string.
auto printer = file->CreatePrinter(&output);
std::map<grpc::string, grpc::string> vars;
static const char* headers_strs[] = {
"functional",
"grpcpp/impl/codegen/async_stream.h",
@ -2048,7 +2070,7 @@ grpc::string GetSourceEpilogue(grpc_generator::File* file,
// TODO(mmukhi): Make sure we need parameters or not.
grpc::string GetMockPrologue(grpc_generator::File* file,
const Parameters& /*params*/) {
const Parameters& params) {
grpc::string output;
{
// Scope the output stream so it closes and finalizes output to the string.
@ -2057,7 +2079,9 @@ grpc::string GetMockPrologue(grpc_generator::File* file,
vars["filename"] = file->filename();
vars["filename_base"] = file->filename_without_ext();
vars["message_header_ext"] = kCppGeneratorMessageHeaderExt;
vars["message_header_ext"] = params.message_header_extension.empty()
? kCppGeneratorMessageHeaderExt
: params.message_header_extension;
vars["service_header_ext"] = kCppGeneratorServiceHeaderExt;
printer->Print(vars, "// Generated by the gRPC C++ plugin.\n");
@ -2067,6 +2091,15 @@ grpc::string GetMockPrologue(grpc_generator::File* file,
printer->Print(vars, "#include \"$filename_base$$message_header_ext$\"\n");
printer->Print(vars, "#include \"$filename_base$$service_header_ext$\"\n");
if (params.include_import_headers) {
const std::vector<grpc::string> import_names = file->GetImportNames();
for (const auto& import_name : import_names) {
const grpc::string include_name =
ImportInludeFromProtoName(import_name);
printer->Print(vars, include_name.c_str());
}
printer->PrintRaw("\n");
}
printer->Print(vars, file->additional_headers().c_str());
printer->Print(vars, "\n");
}

@ -56,6 +56,10 @@ struct Parameters {
grpc::string gmock_search_path;
// *EXPERIMENTAL* Additional include files in grpc.pb.h
std::vector<grpc::string> additional_header_includes;
// By default, use "pb.h"
grpc::string message_header_extension;
// Whether to include headers corresponding to imports in source file.
bool include_import_headers;
};
// Return the prologue of the generated header file.

@ -48,6 +48,7 @@ class CppGrpcGenerator : public grpc::protobuf::compiler::CodeGenerator {
grpc_cpp_generator::Parameters generator_parameters;
generator_parameters.use_system_headers = true;
generator_parameters.generate_mock_code = false;
generator_parameters.include_import_headers = false;
ProtoBufFile pbfile(file);
@ -83,6 +84,15 @@ class CppGrpcGenerator : public grpc::protobuf::compiler::CodeGenerator {
} else if (param[0] == "additional_header_includes") {
generator_parameters.additional_header_includes =
grpc_generator::tokenize(param[1], ":");
} else if (param[0] == "message_header_extension") {
generator_parameters.message_header_extension = param[1];
} else if (param[0] == "include_import_headers") {
if (param[1] == "true") {
generator_parameters.include_import_headers = true;
} else if (param[1] != "false") {
*error = grpc::string("Invalid parameter: ") + *parameter_string;
return false;
}
} else {
*error = grpc::string("Unknown parameter: ") + *parameter_string;
return false;

@ -50,7 +50,8 @@ void PrintProtoRpcDeclarationAsPragma(
}
template <typename DescriptorType>
static void PrintAllComments(const DescriptorType* desc, Printer* printer) {
static void PrintAllComments(const DescriptorType* desc, Printer* printer,
bool deprecated = false) {
std::vector<grpc::string> comments;
grpc_generator::GetComment(desc, grpc_generator::COMMENTTYPE_LEADING_DETACHED,
&comments);
@ -70,17 +71,20 @@ static void PrintAllComments(const DescriptorType* desc, Printer* printer) {
}
printer->Print("\n");
}
printer->Print(" *\n");
printer->Print(
" * This method belongs to a set of APIs that have been deprecated. Using"
" the v2 API is recommended.\n");
if (deprecated) {
printer->Print(" *\n");
printer->Print(
" * This method belongs to a set of APIs that have been deprecated. "
"Using"
" the v2 API is recommended.\n");
}
printer->Print(" */\n");
}
void PrintMethodSignature(Printer* printer, const MethodDescriptor* method,
const map< ::grpc::string, ::grpc::string>& vars) {
// Print comment
PrintAllComments(method, printer);
PrintAllComments(method, printer, true);
printer->Print(vars, "- ($return_type$)$method_name$With");
if (method->client_streaming()) {

@ -189,6 +189,15 @@ class ProtoBufFile : public grpc_generator::File {
return grpc_python_generator::get_all_comments(file_);
}
vector<grpc::string> GetImportNames() const {
vector<grpc::string> proto_names;
for (int i = 0; i < file_->dependency_count(); ++i) {
const auto& dep = *file_->dependency(i);
proto_names.push_back(dep.name());
}
return proto_names;
}
private:
const grpc::protobuf::FileDescriptor* file_;
};

@ -101,6 +101,7 @@ struct File : public CommentHolder {
virtual grpc::string package() const = 0;
virtual std::vector<grpc::string> package_parts() const = 0;
virtual grpc::string additional_headers() const = 0;
virtual std::vector<grpc::string> GetImportNames() const { return {}; }
virtual int service_count() const = 0;
virtual std::unique_ptr<const Service> service(int i) const = 0;

File diff suppressed because it is too large Load Diff

@ -49,8 +49,8 @@ ClientChannelNode::ClientChannelNode(grpc_channel* channel,
: ChannelNode(channel, channel_tracer_max_nodes, is_top_level_channel) {
client_channel_ =
grpc_channel_stack_last_element(grpc_channel_get_channel_stack(channel));
grpc_client_channel_set_channelz_node(client_channel_, this);
GPR_ASSERT(client_channel_->filter == &grpc_client_channel_filter);
grpc_client_channel_set_channelz_node(client_channel_, this);
}
void ClientChannelNode::PopulateConnectivityState(grpc_json* json) {
@ -127,8 +127,7 @@ void SubchannelNode::PopulateConnectivityState(grpc_json* json) {
if (subchannel_ == nullptr) {
state = GRPC_CHANNEL_SHUTDOWN;
} else {
state = subchannel_->CheckConnectivity(nullptr,
true /* inhibit_health_checking */);
state = subchannel_->CheckConnectivity(true /* inhibit_health_checking */);
}
json = grpc_json_create_child(nullptr, json, "state", nullptr,
GRPC_JSON_OBJECT, false);

@ -188,7 +188,6 @@ class LoadBalancingPolicy : public InternallyRefCounted<LoadBalancingPolicy> {
/// Sets the connectivity state and returns a new picker to be used
/// by the client channel.
virtual void UpdateState(grpc_connectivity_state state,
grpc_error* state_error,
UniquePtr<SubchannelPicker>) GRPC_ABSTRACT;
/// Requests that the resolver re-resolve.

@ -300,7 +300,7 @@ class GrpcLb : public LoadBalancingPolicy {
const HealthCheckParsedObject* health_check) override;
grpc_channel* CreateChannel(const char* target,
const grpc_channel_args& args) override;
void UpdateState(grpc_connectivity_state state, grpc_error* state_error,
void UpdateState(grpc_connectivity_state state,
UniquePtr<SubchannelPicker> picker) override;
void RequestReresolution() override;
@ -643,12 +643,8 @@ grpc_channel* GrpcLb::Helper::CreateChannel(const char* target,
}
void GrpcLb::Helper::UpdateState(grpc_connectivity_state state,
grpc_error* state_error,
UniquePtr<SubchannelPicker> picker) {
if (parent_->shutting_down_) {
GRPC_ERROR_UNREF(state_error);
return;
}
if (parent_->shutting_down_) return;
// If this request is from the pending child policy, ignore it until
// it reports READY, at which point we swap it into place.
if (CalledByPendingChild()) {
@ -658,10 +654,7 @@ void GrpcLb::Helper::UpdateState(grpc_connectivity_state state,
parent_.get(), this, parent_->pending_child_policy_.get(),
grpc_connectivity_state_name(state));
}
if (state != GRPC_CHANNEL_READY) {
GRPC_ERROR_UNREF(state_error);
return;
}
if (state != GRPC_CHANNEL_READY) return;
grpc_pollset_set_del_pollset_set(
parent_->child_policy_->interested_parties(),
parent_->interested_parties());
@ -669,7 +662,6 @@ void GrpcLb::Helper::UpdateState(grpc_connectivity_state state,
parent_->child_policy_ = std::move(parent_->pending_child_policy_);
} else if (!CalledByCurrentChild()) {
// This request is from an outdated child, so ignore it.
GRPC_ERROR_UNREF(state_error);
return;
}
// Record whether child policy reports READY.
@ -704,8 +696,7 @@ void GrpcLb::Helper::UpdateState(grpc_connectivity_state state,
parent_.get(), this, grpc_connectivity_state_name(state),
picker.get());
}
parent_->channel_control_helper()->UpdateState(state, state_error,
std::move(picker));
parent_->channel_control_helper()->UpdateState(state, std::move(picker));
return;
}
// Cases 2 and 3a: wrap picker from the child in our own picker.
@ -720,10 +711,9 @@ void GrpcLb::Helper::UpdateState(grpc_connectivity_state state,
client_stats = parent_->lb_calld_->client_stats()->Ref();
}
parent_->channel_control_helper()->UpdateState(
state, state_error,
UniquePtr<SubchannelPicker>(
New<Picker>(parent_.get(), parent_->serverlist_, std::move(picker),
std::move(client_stats))));
state, UniquePtr<SubchannelPicker>(
New<Picker>(parent_.get(), parent_->serverlist_,
std::move(picker), std::move(client_stats))));
}
void GrpcLb::Helper::RequestReresolution() {

@ -73,7 +73,7 @@ class PickFirst : public LoadBalancingPolicy {
: SubchannelData(subchannel_list, address, subchannel, combiner) {}
void ProcessConnectivityChangeLocked(
grpc_connectivity_state connectivity_state, grpc_error* error) override;
grpc_connectivity_state connectivity_state) override;
// Processes the connectivity change to READY for an unselected subchannel.
void ProcessUnselectedReadyLocked();
@ -190,10 +190,11 @@ void PickFirst::ExitIdleLocked() {
idle_ = false;
if (subchannel_list_ == nullptr ||
subchannel_list_->num_subchannels() == 0) {
grpc_error* error =
GRPC_ERROR_CREATE_FROM_STATIC_STRING("No addresses to connect to");
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, GRPC_ERROR_REF(error),
GRPC_CHANNEL_TRANSIENT_FAILURE,
UniquePtr<SubchannelPicker>(New<TransientFailurePicker>(error)));
} else {
subchannel_list_->subchannel(0)
@ -268,9 +269,11 @@ void PickFirst::UpdateLocked(UpdateArgs args) {
// 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_CREATE_FROM_STATIC_STRING("Empty update");
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, GRPC_ERROR_REF(error),
GRPC_CHANNEL_TRANSIENT_FAILURE,
UniquePtr<SubchannelPicker>(New<TransientFailurePicker>(error)));
}
return;
@ -284,9 +287,7 @@ void PickFirst::UpdateLocked(UpdateArgs args) {
// 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_error* error = GRPC_ERROR_NONE;
grpc_connectivity_state state = sd->CheckConnectivityStateLocked(&error);
GRPC_ERROR_UNREF(error);
grpc_connectivity_state state = sd->CheckConnectivityStateLocked();
if (state == GRPC_CHANNEL_READY) {
subchannel_list_ = std::move(subchannel_list);
sd->StartConnectivityWatchLocked();
@ -340,7 +341,7 @@ void PickFirst::UpdateLocked(UpdateArgs args) {
}
void PickFirst::PickFirstSubchannelData::ProcessConnectivityChangeLocked(
grpc_connectivity_state connectivity_state, grpc_error* error) {
grpc_connectivity_state connectivity_state) {
PickFirst* p = static_cast<PickFirst*>(subchannel_list()->policy());
AutoChildRefsUpdater guard(p);
// The notification must be for a subchannel in either the current or
@ -371,17 +372,16 @@ void PickFirst::PickFirstSubchannelData::ProcessConnectivityChangeLocked(
p->subchannel_list_ = std::move(p->latest_pending_subchannel_list_);
// Set our state to that of the pending subchannel list.
if (p->subchannel_list_->in_transient_failure()) {
grpc_error* new_error =
GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING(
"selected subchannel failed; switching to pending update",
&error, 1);
grpc_error* error = grpc_error_set_int(
GRPC_ERROR_CREATE_FROM_STATIC_STRING(
"selected subchannel failed; switching to pending update"),
GRPC_ERROR_INT_GRPC_STATUS, GRPC_STATUS_UNAVAILABLE);
p->channel_control_helper()->UpdateState(
GRPC_CHANNEL_TRANSIENT_FAILURE, GRPC_ERROR_REF(new_error),
UniquePtr<SubchannelPicker>(
New<TransientFailurePicker>(new_error)));
GRPC_CHANNEL_TRANSIENT_FAILURE,
UniquePtr<SubchannelPicker>(New<TransientFailurePicker>(error)));
} else {
p->channel_control_helper()->UpdateState(
GRPC_CHANNEL_CONNECTING, GRPC_ERROR_NONE,
GRPC_CHANNEL_CONNECTING,
UniquePtr<SubchannelPicker>(New<QueuePicker>(p->Ref())));
}
} else {
@ -395,7 +395,7 @@ void PickFirst::PickFirstSubchannelData::ProcessConnectivityChangeLocked(
p->selected_ = nullptr;
StopConnectivityWatchLocked();
p->channel_control_helper()->UpdateState(
GRPC_CHANNEL_IDLE, GRPC_ERROR_NONE,
GRPC_CHANNEL_IDLE,
UniquePtr<SubchannelPicker>(New<QueuePicker>(p->Ref())));
} else {
// This is unlikely but can happen when a subchannel has been asked
@ -403,19 +403,17 @@ void PickFirst::PickFirstSubchannelData::ProcessConnectivityChangeLocked(
// some connectivity state notifications.
if (connectivity_state == GRPC_CHANNEL_READY) {
p->channel_control_helper()->UpdateState(
GRPC_CHANNEL_READY, GRPC_ERROR_NONE,
UniquePtr<SubchannelPicker>(
New<Picker>(connected_subchannel()->Ref())));
GRPC_CHANNEL_READY, UniquePtr<SubchannelPicker>(New<Picker>(
connected_subchannel()->Ref())));
} else { // CONNECTING
p->channel_control_helper()->UpdateState(
connectivity_state, GRPC_ERROR_REF(error),
connectivity_state,
UniquePtr<SubchannelPicker>(New<QueuePicker>(p->Ref())));
}
// Renew notification.
RenewConnectivityWatchLocked();
}
}
GRPC_ERROR_UNREF(error);
return;
}
// If we get here, there are two possible cases:
@ -452,13 +450,13 @@ void PickFirst::PickFirstSubchannelData::ProcessConnectivityChangeLocked(
subchannel_list()->set_in_transient_failure(true);
// Only report new state in case 1.
if (subchannel_list() == p->subchannel_list_.get()) {
grpc_error* new_error =
GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING(
"failed to connect to all addresses", &error, 1);
grpc_error* error = grpc_error_set_int(
GRPC_ERROR_CREATE_FROM_STATIC_STRING(
"failed to connect to all addresses"),
GRPC_ERROR_INT_GRPC_STATUS, GRPC_STATUS_UNAVAILABLE);
p->channel_control_helper()->UpdateState(
GRPC_CHANNEL_TRANSIENT_FAILURE, GRPC_ERROR_REF(new_error),
UniquePtr<SubchannelPicker>(
New<TransientFailurePicker>(new_error)));
GRPC_CHANNEL_TRANSIENT_FAILURE,
UniquePtr<SubchannelPicker>(New<TransientFailurePicker>(error)));
}
}
sd->CheckConnectivityStateAndStartWatchingLocked();
@ -469,7 +467,7 @@ void PickFirst::PickFirstSubchannelData::ProcessConnectivityChangeLocked(
// Only update connectivity state in case 1.
if (subchannel_list() == p->subchannel_list_.get()) {
p->channel_control_helper()->UpdateState(
GRPC_CHANNEL_CONNECTING, GRPC_ERROR_NONE,
GRPC_CHANNEL_CONNECTING,
UniquePtr<SubchannelPicker>(New<QueuePicker>(p->Ref())));
}
// Renew notification.
@ -479,7 +477,6 @@ void PickFirst::PickFirstSubchannelData::ProcessConnectivityChangeLocked(
case GRPC_CHANNEL_SHUTDOWN:
GPR_UNREACHABLE_CODE(break);
}
GRPC_ERROR_UNREF(error);
}
void PickFirst::PickFirstSubchannelData::ProcessUnselectedReadyLocked() {
@ -509,7 +506,7 @@ void PickFirst::PickFirstSubchannelData::ProcessUnselectedReadyLocked() {
// Cases 1 and 2.
p->selected_ = this;
p->channel_control_helper()->UpdateState(
GRPC_CHANNEL_READY, GRPC_ERROR_NONE,
GRPC_CHANNEL_READY,
UniquePtr<SubchannelPicker>(New<Picker>(connected_subchannel()->Ref())));
if (grpc_lb_pick_first_trace.enabled()) {
gpr_log(GPR_INFO, "Pick First %p selected subchannel %p", p, subchannel());
@ -520,9 +517,7 @@ void PickFirst::PickFirstSubchannelData::
CheckConnectivityStateAndStartWatchingLocked() {
PickFirst* p = static_cast<PickFirst*>(subchannel_list()->policy());
// Check current state.
grpc_error* error = GRPC_ERROR_NONE;
grpc_connectivity_state current_state = CheckConnectivityStateLocked(&error);
GRPC_ERROR_UNREF(error);
grpc_connectivity_state current_state = CheckConnectivityStateLocked();
// Start watch.
StartConnectivityWatchLocked();
// If current state is READY, select the subchannel now, since we started

@ -92,11 +92,11 @@ class RoundRobin : public LoadBalancingPolicy {
}
void UpdateConnectivityStateLocked(
grpc_connectivity_state connectivity_state, grpc_error* error);
grpc_connectivity_state connectivity_state);
private:
void ProcessConnectivityChangeLocked(
grpc_connectivity_state connectivity_state, grpc_error* error) override;
grpc_connectivity_state connectivity_state) override;
grpc_connectivity_state last_connectivity_state_ = GRPC_CHANNEL_IDLE;
};
@ -120,7 +120,6 @@ class RoundRobin : public LoadBalancingPolicy {
}
~RoundRobinSubchannelList() {
GRPC_ERROR_UNREF(last_transient_failure_error_);
RoundRobin* p = static_cast<RoundRobin*>(policy());
p->Unref(DEBUG_LOCATION, "subchannel_list");
}
@ -130,11 +129,8 @@ class RoundRobin : public LoadBalancingPolicy {
// Updates the counters of subchannels in each state when a
// subchannel transitions from old_state to new_state.
// transient_failure_error is the error that is reported when
// new_state is TRANSIENT_FAILURE.
void UpdateStateCountersLocked(grpc_connectivity_state old_state,
grpc_connectivity_state new_state,
grpc_error* transient_failure_error);
grpc_connectivity_state new_state);
// If this subchannel list is the RR policy's current subchannel
// list, updates the RR policy's connectivity state based on the
@ -149,7 +145,6 @@ class RoundRobin : public LoadBalancingPolicy {
size_t num_ready_ = 0;
size_t num_connecting_ = 0;
size_t num_transient_failure_ = 0;
grpc_error* last_transient_failure_error_ = GRPC_ERROR_NONE;
};
class Picker : public SubchannelPicker {
@ -316,11 +311,10 @@ void RoundRobin::RoundRobinSubchannelList::StartWatchingLocked() {
// subchannel already used by some other channel may have a non-IDLE
// state.
for (size_t i = 0; i < num_subchannels(); ++i) {
grpc_error* error = GRPC_ERROR_NONE;
grpc_connectivity_state state =
subchannel(i)->CheckConnectivityStateLocked(&error);
subchannel(i)->CheckConnectivityStateLocked();
if (state != GRPC_CHANNEL_IDLE) {
subchannel(i)->UpdateConnectivityStateLocked(state, error);
subchannel(i)->UpdateConnectivityStateLocked(state);
}
}
// Start connectivity watch for each subchannel.
@ -334,8 +328,7 @@ void RoundRobin::RoundRobinSubchannelList::StartWatchingLocked() {
}
void RoundRobin::RoundRobinSubchannelList::UpdateStateCountersLocked(
grpc_connectivity_state old_state, grpc_connectivity_state new_state,
grpc_error* transient_failure_error) {
grpc_connectivity_state old_state, grpc_connectivity_state new_state) {
GPR_ASSERT(old_state != GRPC_CHANNEL_SHUTDOWN);
GPR_ASSERT(new_state != GRPC_CHANNEL_SHUTDOWN);
if (old_state == GRPC_CHANNEL_READY) {
@ -355,8 +348,6 @@ void RoundRobin::RoundRobinSubchannelList::UpdateStateCountersLocked(
} else if (new_state == GRPC_CHANNEL_TRANSIENT_FAILURE) {
++num_transient_failure_;
}
GRPC_ERROR_UNREF(last_transient_failure_error_);
last_transient_failure_error_ = transient_failure_error;
}
// Sets the RR policy's connectivity state and generates a new picker based
@ -383,20 +374,21 @@ void RoundRobin::RoundRobinSubchannelList::
if (num_ready_ > 0) {
/* 1) READY */
p->channel_control_helper()->UpdateState(
GRPC_CHANNEL_READY, GRPC_ERROR_NONE,
UniquePtr<SubchannelPicker>(New<Picker>(p, this)));
GRPC_CHANNEL_READY, UniquePtr<SubchannelPicker>(New<Picker>(p, this)));
} else if (num_connecting_ > 0) {
/* 2) CONNECTING */
p->channel_control_helper()->UpdateState(
GRPC_CHANNEL_CONNECTING, GRPC_ERROR_NONE,
GRPC_CHANNEL_CONNECTING,
UniquePtr<SubchannelPicker>(New<QueuePicker>(p->Ref())));
} else if (num_transient_failure_ == num_subchannels()) {
/* 3) TRANSIENT_FAILURE */
grpc_error* error =
grpc_error_set_int(GRPC_ERROR_CREATE_FROM_STATIC_STRING(
"connections to all backends failing"),
GRPC_ERROR_INT_GRPC_STATUS, GRPC_STATUS_UNAVAILABLE);
p->channel_control_helper()->UpdateState(
GRPC_CHANNEL_TRANSIENT_FAILURE,
GRPC_ERROR_REF(last_transient_failure_error_),
UniquePtr<SubchannelPicker>(New<TransientFailurePicker>(
GRPC_ERROR_REF(last_transient_failure_error_))));
UniquePtr<SubchannelPicker>(New<TransientFailurePicker>(error)));
}
}
@ -431,7 +423,7 @@ void RoundRobin::RoundRobinSubchannelList::
}
void RoundRobin::RoundRobinSubchannelData::UpdateConnectivityStateLocked(
grpc_connectivity_state connectivity_state, grpc_error* error) {
grpc_connectivity_state connectivity_state) {
RoundRobin* p = static_cast<RoundRobin*>(subchannel_list()->policy());
if (grpc_lb_round_robin_trace.enabled()) {
gpr_log(
@ -444,12 +436,12 @@ void RoundRobin::RoundRobinSubchannelData::UpdateConnectivityStateLocked(
grpc_connectivity_state_name(connectivity_state));
}
subchannel_list()->UpdateStateCountersLocked(last_connectivity_state_,
connectivity_state, error);
connectivity_state);
last_connectivity_state_ = connectivity_state;
}
void RoundRobin::RoundRobinSubchannelData::ProcessConnectivityChangeLocked(
grpc_connectivity_state connectivity_state, grpc_error* error) {
grpc_connectivity_state connectivity_state) {
RoundRobin* p = static_cast<RoundRobin*>(subchannel_list()->policy());
GPR_ASSERT(subchannel() != nullptr);
// If the new state is TRANSIENT_FAILURE, re-resolve.
@ -469,7 +461,7 @@ void RoundRobin::RoundRobinSubchannelData::ProcessConnectivityChangeLocked(
// Renew connectivity watch.
RenewConnectivityWatchLocked();
// Update state counters.
UpdateConnectivityStateLocked(connectivity_state, error);
UpdateConnectivityStateLocked(connectivity_state);
// Update overall state and renew notification.
subchannel_list()->UpdateRoundRobinStateFromSubchannelStateCountsLocked();
}
@ -494,9 +486,11 @@ void RoundRobin::UpdateLocked(UpdateArgs args) {
if (latest_pending_subchannel_list_->num_subchannels() == 0) {
// If the new list is empty, immediately promote the new list to the
// current list and transition to TRANSIENT_FAILURE.
grpc_error* error = GRPC_ERROR_CREATE_FROM_STATIC_STRING("Empty update");
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, GRPC_ERROR_REF(error),
GRPC_CHANNEL_TRANSIENT_FAILURE,
UniquePtr<SubchannelPicker>(New<TransientFailurePicker>(error)));
subchannel_list_ = std::move(latest_pending_subchannel_list_);
} else if (subchannel_list_ == nullptr) {

@ -51,7 +51,7 @@ class MySubchannelData
: public SubchannelData<MySubchannelList, MySubchannelData> {
public:
void ProcessConnectivityChangeLocked(
grpc_connectivity_state connectivity_state, grpc_error* error) override {
grpc_connectivity_state connectivity_state) override {
// ...code to handle connectivity changes...
}
};
@ -101,10 +101,10 @@ class SubchannelData {
// pending (i.e., between calling StartConnectivityWatchLocked() or
// RenewConnectivityWatchLocked() and the resulting invocation of
// ProcessConnectivityChangeLocked()).
grpc_connectivity_state CheckConnectivityStateLocked(grpc_error** error) {
grpc_connectivity_state CheckConnectivityStateLocked() {
GPR_ASSERT(!connectivity_notification_pending_);
pending_connectivity_state_unsafe_ = subchannel()->CheckConnectivity(
error, subchannel_list_->inhibit_health_checking());
subchannel_list_->inhibit_health_checking());
UpdateConnectedSubchannelLocked();
return pending_connectivity_state_unsafe_;
}
@ -153,8 +153,7 @@ class SubchannelData {
// Implementations must invoke either RenewConnectivityWatchLocked() or
// StopConnectivityWatchLocked() before returning.
virtual void ProcessConnectivityChangeLocked(
grpc_connectivity_state connectivity_state,
grpc_error* error) GRPC_ABSTRACT;
grpc_connectivity_state connectivity_state) GRPC_ABSTRACT;
// Unrefs the subchannel.
void UnrefSubchannelLocked(const char* reason);
@ -463,8 +462,7 @@ void SubchannelData<SubchannelListType, SubchannelDataType>::
return;
}
// Call the subclass's ProcessConnectivityChangeLocked() method.
sd->ProcessConnectivityChangeLocked(sd->pending_connectivity_state_unsafe_,
GRPC_ERROR_REF(error));
sd->ProcessConnectivityChangeLocked(sd->pending_connectivity_state_unsafe_);
}
template <typename SubchannelListType, typename SubchannelDataType>

@ -333,7 +333,7 @@ class XdsLb : public LoadBalancingPolicy {
const HealthCheckParsedObject* health_check) override;
grpc_channel* CreateChannel(const char* target,
const grpc_channel_args& args) override;
void UpdateState(grpc_connectivity_state state, grpc_error* state_error,
void UpdateState(grpc_connectivity_state state,
UniquePtr<SubchannelPicker> picker) override;
void RequestReresolution() override;
void set_child(LoadBalancingPolicy* child) { child_ = child; }
@ -1567,6 +1567,7 @@ void XdsLb::LocalityMap::LocalityEntry::Orphan() {
//
// LocalityEntry::Helper implementation
//
bool XdsLb::LocalityMap::LocalityEntry::Helper::CalledByPendingChild() const {
GPR_ASSERT(child_ != nullptr);
return child_ == entry_->pending_child_policy_.get();
@ -1598,12 +1599,8 @@ grpc_channel* XdsLb::LocalityMap::LocalityEntry::Helper::CreateChannel(
}
void XdsLb::LocalityMap::LocalityEntry::Helper::UpdateState(
grpc_connectivity_state state, grpc_error* state_error,
UniquePtr<SubchannelPicker> picker) {
if (entry_->parent_->shutting_down_) {
GRPC_ERROR_UNREF(state_error);
return;
}
grpc_connectivity_state state, UniquePtr<SubchannelPicker> picker) {
if (entry_->parent_->shutting_down_) return;
// If this request is from the pending child policy, ignore it until
// it reports READY, at which point we swap it into place.
if (CalledByPendingChild()) {
@ -1613,10 +1610,7 @@ void XdsLb::LocalityMap::LocalityEntry::Helper::UpdateState(
entry_->parent_.get(), this, entry_->pending_child_policy_.get(),
grpc_connectivity_state_name(state));
}
if (state != GRPC_CHANNEL_READY) {
GRPC_ERROR_UNREF(state_error);
return;
}
if (state != GRPC_CHANNEL_READY) return;
grpc_pollset_set_del_pollset_set(
entry_->child_policy_->interested_parties(),
entry_->parent_->interested_parties());
@ -1624,7 +1618,6 @@ void XdsLb::LocalityMap::LocalityEntry::Helper::UpdateState(
entry_->child_policy_ = std::move(entry_->pending_child_policy_);
} else if (!CalledByCurrentChild()) {
// This request is from an outdated child, so ignore it.
GRPC_ERROR_UNREF(state_error);
return;
}
// TODO(juanlishen): When in fallback mode, pass the child picker
@ -1636,9 +1629,8 @@ void XdsLb::LocalityMap::LocalityEntry::Helper::UpdateState(
? nullptr
: entry_->parent_->lb_chand_->lb_calld()->client_stats();
entry_->parent_->channel_control_helper()->UpdateState(
state, state_error,
UniquePtr<SubchannelPicker>(
New<Picker>(std::move(picker), std::move(client_stats))));
state, UniquePtr<SubchannelPicker>(
New<Picker>(std::move(picker), std::move(client_stats))));
}
void XdsLb::LocalityMap::LocalityEntry::Helper::RequestReresolution() {

@ -43,6 +43,7 @@
#include "src/core/lib/gprpp/manual_constructor.h"
#include "src/core/lib/iomgr/combiner.h"
#include "src/core/lib/iomgr/gethostname.h"
#include "src/core/lib/iomgr/iomgr_custom.h"
#include "src/core/lib/iomgr/resolve_address.h"
#include "src/core/lib/iomgr/timer.h"
#include "src/core/lib/json/json.h"
@ -430,8 +431,11 @@ static grpc_address_resolver_vtable ares_resolver = {
grpc_resolve_address_ares, blocking_resolve_address_ares};
static bool should_use_ares(const char* resolver_env) {
return resolver_env == nullptr || strlen(resolver_env) == 0 ||
gpr_stricmp(resolver_env, "ares") == 0;
// TODO(lidiz): Remove the "g_custom_iomgr_enabled" flag once c-ares support
// custom IO managers (e.g. gevent).
return !g_custom_iomgr_enabled &&
(resolver_env == nullptr || strlen(resolver_env) == 0 ||
gpr_stricmp(resolver_env, "ares") == 0);
}
void grpc_resolver_dns_ares_init() {

@ -122,13 +122,9 @@ class ResolvingLoadBalancingPolicy::ResolvingControlHelper
return parent_->channel_control_helper()->CreateChannel(target, args);
}
void UpdateState(grpc_connectivity_state state, grpc_error* state_error,
void UpdateState(grpc_connectivity_state state,
UniquePtr<SubchannelPicker> picker) override {
if (parent_->resolver_ == nullptr) {
// shutting down.
GRPC_ERROR_UNREF(state_error);
return;
}
if (parent_->resolver_ == nullptr) return; // Shutting down.
// If this request is from the pending child policy, ignore it until
// it reports READY, at which point we swap it into place.
if (CalledByPendingChild()) {
@ -139,10 +135,7 @@ class ResolvingLoadBalancingPolicy::ResolvingControlHelper
parent_.get(), this, child_,
grpc_connectivity_state_name(state));
}
if (state != GRPC_CHANNEL_READY) {
GRPC_ERROR_UNREF(state_error);
return;
}
if (state != GRPC_CHANNEL_READY) return;
grpc_pollset_set_del_pollset_set(
parent_->lb_policy_->interested_parties(),
parent_->interested_parties());
@ -150,11 +143,9 @@ class ResolvingLoadBalancingPolicy::ResolvingControlHelper
parent_->lb_policy_ = std::move(parent_->pending_lb_policy_);
} else if (!CalledByCurrentChild()) {
// This request is from an outdated child, so ignore it.
GRPC_ERROR_UNREF(state_error);
return;
}
parent_->channel_control_helper()->UpdateState(state, state_error,
std::move(picker));
parent_->channel_control_helper()->UpdateState(state, std::move(picker));
}
void RequestReresolution() override {
@ -237,8 +228,7 @@ grpc_error* ResolvingLoadBalancingPolicy::Init(const grpc_channel_args& args) {
}
// Return our picker to the channel.
channel_control_helper()->UpdateState(
GRPC_CHANNEL_IDLE, GRPC_ERROR_NONE,
UniquePtr<SubchannelPicker>(New<QueuePicker>(Ref())));
GRPC_CHANNEL_IDLE, UniquePtr<SubchannelPicker>(New<QueuePicker>(Ref())));
return GRPC_ERROR_NONE;
}
@ -316,7 +306,7 @@ void ResolvingLoadBalancingPolicy::StartResolvingLocked() {
GPR_ASSERT(!started_resolving_);
started_resolving_ = true;
channel_control_helper()->UpdateState(
GRPC_CHANNEL_CONNECTING, GRPC_ERROR_NONE,
GRPC_CHANNEL_CONNECTING,
UniquePtr<SubchannelPicker>(New<QueuePicker>(Ref())));
resolver_->StartLocked();
}
@ -337,7 +327,7 @@ void ResolvingLoadBalancingPolicy::OnResolverError(grpc_error* error) {
grpc_error* state_error = GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING(
"Resolver transient failure", &error, 1);
channel_control_helper()->UpdateState(
GRPC_CHANNEL_TRANSIENT_FAILURE, GRPC_ERROR_REF(state_error),
GRPC_CHANNEL_TRANSIENT_FAILURE,
UniquePtr<SubchannelPicker>(New<TransientFailurePicker>(state_error)));
}
GRPC_ERROR_UNREF(error);

@ -332,10 +332,9 @@ class Subchannel::ConnectedSubchannelStateWatcher
health_state = GRPC_CHANNEL_CONNECTING;
}
// Report initial state.
c->SetConnectivityStateLocked(GRPC_CHANNEL_READY, GRPC_ERROR_NONE,
"subchannel_connected");
c->SetConnectivityStateLocked(GRPC_CHANNEL_READY, "subchannel_connected");
grpc_connectivity_state_set(&c->state_and_health_tracker_, health_state,
GRPC_ERROR_NONE, "subchannel_connected");
"subchannel_connected");
}
~ConnectedSubchannelStateWatcher() {
@ -367,11 +366,10 @@ class Subchannel::ConnectedSubchannelStateWatcher
c->connected_subchannel_watcher_.reset();
self->last_connectivity_state_ = GRPC_CHANNEL_TRANSIENT_FAILURE;
c->SetConnectivityStateLocked(GRPC_CHANNEL_TRANSIENT_FAILURE,
GRPC_ERROR_REF(error),
"reflect_child");
grpc_connectivity_state_set(&c->state_and_health_tracker_,
GRPC_CHANNEL_TRANSIENT_FAILURE,
GRPC_ERROR_REF(error), "reflect_child");
"reflect_child");
c->backoff_begun_ = false;
c->backoff_.Reset();
c->MaybeStartConnectingLocked();
@ -388,11 +386,11 @@ class Subchannel::ConnectedSubchannelStateWatcher
// from READY to CONNECTING or IDLE.
self->last_connectivity_state_ = self->pending_connectivity_state_;
c->SetConnectivityStateLocked(self->pending_connectivity_state_,
GRPC_ERROR_REF(error), "reflect_child");
"reflect_child");
if (self->pending_connectivity_state_ != GRPC_CHANNEL_READY) {
grpc_connectivity_state_set(&c->state_and_health_tracker_,
self->pending_connectivity_state_,
GRPC_ERROR_REF(error), "reflect_child");
"reflect_child");
}
c->connected_subchannel_->NotifyOnStateChange(
nullptr, &self->pending_connectivity_state_,
@ -415,8 +413,7 @@ class Subchannel::ConnectedSubchannelStateWatcher
self->health_check_client_ != nullptr) {
if (self->last_connectivity_state_ == GRPC_CHANNEL_READY) {
grpc_connectivity_state_set(&c->state_and_health_tracker_,
self->health_state_,
GRPC_ERROR_REF(error), "health_changed");
self->health_state_, "health_changed");
}
self->health_check_client_->NotifyOnHealthChange(
&self->health_state_, &self->on_health_changed_);
@ -715,11 +712,10 @@ channelz::SubchannelNode* Subchannel::channelz_node() {
}
grpc_connectivity_state Subchannel::CheckConnectivity(
grpc_error** error, bool inhibit_health_checking) {
MutexLock lock(&mu_);
bool inhibit_health_checking) {
grpc_connectivity_state_tracker* tracker =
inhibit_health_checking ? &state_tracker_ : &state_and_health_tracker_;
grpc_connectivity_state state = grpc_connectivity_state_get(tracker, error);
grpc_connectivity_state state = grpc_connectivity_state_check(tracker);
return state;
}
@ -827,7 +823,6 @@ const char* SubchannelConnectivityStateChangeString(
} // namespace
void Subchannel::SetConnectivityStateLocked(grpc_connectivity_state state,
grpc_error* error,
const char* reason) {
if (channelz_node_ != nullptr) {
channelz_node_->AddTraceEvent(
@ -835,7 +830,7 @@ void Subchannel::SetConnectivityStateLocked(grpc_connectivity_state state,
grpc_slice_from_static_string(
SubchannelConnectivityStateChangeString(state)));
}
grpc_connectivity_state_set(&state_tracker_, state, error, reason);
grpc_connectivity_state_set(&state_tracker_, state, reason);
}
void Subchannel::MaybeStartConnectingLocked() {
@ -912,11 +907,9 @@ void Subchannel::ContinueConnectingLocked() {
next_attempt_deadline_ = backoff_.NextAttemptTime();
args.deadline = std::max(next_attempt_deadline_, min_deadline);
args.channel_args = args_;
SetConnectivityStateLocked(GRPC_CHANNEL_CONNECTING, GRPC_ERROR_NONE,
"connecting");
SetConnectivityStateLocked(GRPC_CHANNEL_CONNECTING, "connecting");
grpc_connectivity_state_set(&state_and_health_tracker_,
GRPC_CHANNEL_CONNECTING, GRPC_ERROR_NONE,
"connecting");
GRPC_CHANNEL_CONNECTING, "connecting");
grpc_connector_connect(connector_, &args, &connecting_result_,
&on_connecting_finished_);
}
@ -934,16 +927,11 @@ void Subchannel::OnConnectingFinished(void* arg, grpc_error* error) {
} else if (c->disconnected_) {
GRPC_SUBCHANNEL_WEAK_UNREF(c, "connecting");
} else {
const char* errmsg = grpc_error_string(error);
gpr_log(GPR_INFO, "Connect failed: %s", errmsg);
error = grpc_error_set_int(
GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING("Connect Failed",
&error, 1),
GRPC_ERROR_INT_GRPC_STATUS, GRPC_STATUS_UNAVAILABLE);
gpr_log(GPR_INFO, "Connect failed: %s", grpc_error_string(error));
c->SetConnectivityStateLocked(GRPC_CHANNEL_TRANSIENT_FAILURE,
GRPC_ERROR_REF(error), "connect_failed");
"connect_failed");
grpc_connectivity_state_set(&c->state_and_health_tracker_,
GRPC_CHANNEL_TRANSIENT_FAILURE, error,
GRPC_CHANNEL_TRANSIENT_FAILURE,
"connect_failed");
c->MaybeStartConnectingLocked();
GRPC_SUBCHANNEL_WEAK_UNREF(c, "connecting");

@ -211,8 +211,7 @@ class Subchannel {
channelz::SubchannelNode* channelz_node();
// Polls the current connectivity state of the subchannel.
grpc_connectivity_state CheckConnectivity(grpc_error** error,
bool inhibit_health_checking);
grpc_connectivity_state CheckConnectivity(bool inhibit_health_checking);
// When the connectivity state of the subchannel changes from \a *state,
// invokes \a notify and updates \a *state with the new state.
@ -245,7 +244,7 @@ class Subchannel {
// Sets the subchannel's connectivity state to \a state.
void SetConnectivityStateLocked(grpc_connectivity_state state,
grpc_error* error, const char* reason);
const char* reason);
// Methods for connection.
void MaybeStartConnectingLocked();

@ -29,6 +29,7 @@
#include "src/core/ext/filters/http/message_compress/message_compress_filter.h"
#include "src/core/lib/channel/channel_args.h"
#include "src/core/lib/compression/algorithm_metadata.h"
#include "src/core/lib/compression/compression_args.h"
#include "src/core/lib/compression/compression_internal.h"
#include "src/core/lib/compression/message_compress.h"
#include "src/core/lib/gpr/string.h"

@ -119,7 +119,7 @@ static void maybe_start_some_streams(grpc_chttp2_transport* t);
static void connectivity_state_set(grpc_chttp2_transport* t,
grpc_connectivity_state state,
grpc_error* error, const char* reason);
const char* reason);
static void benign_reclaimer_locked(void* t, grpc_error* error);
static void destructive_reclaimer_locked(void* t, grpc_error* error);
@ -592,8 +592,7 @@ static void close_transport_locked(grpc_chttp2_transport* t,
}
GPR_ASSERT(error != GRPC_ERROR_NONE);
t->closed_with_error = GRPC_ERROR_REF(error);
connectivity_state_set(t, GRPC_CHANNEL_SHUTDOWN, GRPC_ERROR_REF(error),
"close_transport");
connectivity_state_set(t, GRPC_CHANNEL_SHUTDOWN, "close_transport");
if (t->ping_state.is_delayed_ping_timer_set) {
grpc_timer_cancel(&t->ping_state.delayed_ping_timer);
}
@ -1171,8 +1170,7 @@ void grpc_chttp2_add_incoming_goaway(grpc_chttp2_transport* t,
/* lie: use transient failure from the transport to indicate goaway has been
* received */
connectivity_state_set(t, GRPC_CHANNEL_TRANSIENT_FAILURE,
GRPC_ERROR_REF(t->goaway_error), "got_goaway");
connectivity_state_set(t, GRPC_CHANNEL_TRANSIENT_FAILURE, "got_goaway");
}
static void maybe_start_some_streams(grpc_chttp2_transport* t) {
@ -1194,10 +1192,8 @@ static void maybe_start_some_streams(grpc_chttp2_transport* t) {
t->next_stream_id += 2;
if (t->next_stream_id >= MAX_CLIENT_STREAM_ID) {
connectivity_state_set(
t, GRPC_CHANNEL_TRANSIENT_FAILURE,
GRPC_ERROR_CREATE_FROM_STATIC_STRING("Stream IDs exhausted"),
"no_more_stream_ids");
connectivity_state_set(t, GRPC_CHANNEL_TRANSIENT_FAILURE,
"no_more_stream_ids");
}
grpc_chttp2_stream_map_add(&t->stream_map, s->id, s);
@ -2804,9 +2800,9 @@ static void keepalive_watchdog_fired_locked(void* arg, grpc_error* error) {
static void connectivity_state_set(grpc_chttp2_transport* t,
grpc_connectivity_state state,
grpc_error* error, const char* reason) {
const char* reason) {
GRPC_CHTTP2_IF_TRACING(gpr_log(GPR_INFO, "set connectivity_state=%d", state));
grpc_connectivity_state_set(&t->channel_callback.state_tracker, state, error,
grpc_connectivity_state_set(&t->channel_callback.state_tracker, state,
reason);
}

@ -177,7 +177,7 @@ struct op_and_state {
bool done = false;
struct stream_obj* s; /* Pointer back to the stream object */
/* next op_and_state in the linked list */
struct op_and_state* next;
struct op_and_state* next = nullptr;
};
struct op_storage {
@ -324,7 +324,7 @@ static grpc_error* make_error_with_desc(int error_code, const char* desc) {
inline op_and_state::op_and_state(stream_obj* s,
const grpc_transport_stream_op_batch& op)
: op(op), state(s->arena), s(s), next(s->storage.head) {}
: op(op), state(s->arena), s(s) {}
/*
Add a new stream op to op storage.
@ -335,10 +335,8 @@ static void add_to_storage(struct stream_obj* s,
/* add new op at the beginning of the linked list. The memory is freed
in remove_from_storage */
op_and_state* new_op = grpc_core::New<op_and_state>(s, *op);
// Pontential fix to crash on GPR_ASSERT(!curr->done)
// TODO (mxyan): check if this is indeed necessary.
new_op->done = false;
gpr_mu_lock(&s->mu);
new_op->next = storage->head;
storage->head = new_op;
storage->num_pending_ops++;
if (op->send_message) {

@ -1088,10 +1088,8 @@ void perform_stream_op(grpc_transport* gt, grpc_stream* gs,
void close_transport_locked(inproc_transport* t) {
INPROC_LOG(GPR_INFO, "close_transport %p %d", t, t->is_closed);
grpc_connectivity_state_set(
&t->connectivity, GRPC_CHANNEL_SHUTDOWN,
GRPC_ERROR_CREATE_FROM_STATIC_STRING("Closing transport."),
"close transport");
grpc_connectivity_state_set(&t->connectivity, GRPC_CHANNEL_SHUTDOWN,
"close transport");
if (!t->is_closed) {
t->is_closed = true;
/* Also end all streams on this transport */

@ -0,0 +1,105 @@
/* This file was generated by upbc (the upb compiler) from the input
* file:
*
* envoy/api/v2/endpoint/load_report.proto
*
* Do not edit -- your changes will be discarded when the file is
* regenerated. */
#include <stddef.h>
#include "upb/msg.h"
#include "envoy/api/v2/endpoint/load_report.upb.h"
#include "envoy/api/v2/core/address.upb.h"
#include "envoy/api/v2/core/base.upb.h"
#include "google/protobuf/duration.upb.h"
#include "validate/validate.upb.h"
#include "gogoproto/gogo.upb.h"
#include "upb/port_def.inc"
static const upb_msglayout *const envoy_api_v2_endpoint_UpstreamLocalityStats_submsgs[3] = {
&envoy_api_v2_core_Locality_msginit,
&envoy_api_v2_endpoint_EndpointLoadMetricStats_msginit,
&envoy_api_v2_endpoint_UpstreamEndpointStats_msginit,
};
static const upb_msglayout_field envoy_api_v2_endpoint_UpstreamLocalityStats__fields[7] = {
{1, UPB_SIZE(28, 32), 0, 0, 11, 1},
{2, UPB_SIZE(0, 0), 0, 0, 4, 1},
{3, UPB_SIZE(8, 8), 0, 0, 4, 1},
{4, UPB_SIZE(16, 16), 0, 0, 4, 1},
{5, UPB_SIZE(32, 40), 0, 1, 11, 3},
{6, UPB_SIZE(24, 24), 0, 0, 13, 1},
{7, UPB_SIZE(36, 48), 0, 2, 11, 3},
};
const upb_msglayout envoy_api_v2_endpoint_UpstreamLocalityStats_msginit = {
&envoy_api_v2_endpoint_UpstreamLocalityStats_submsgs[0],
&envoy_api_v2_endpoint_UpstreamLocalityStats__fields[0],
UPB_SIZE(40, 56), 7, false,
};
static const upb_msglayout *const envoy_api_v2_endpoint_UpstreamEndpointStats_submsgs[2] = {
&envoy_api_v2_core_Address_msginit,
&envoy_api_v2_endpoint_EndpointLoadMetricStats_msginit,
};
static const upb_msglayout_field envoy_api_v2_endpoint_UpstreamEndpointStats__fields[5] = {
{1, UPB_SIZE(24, 24), 0, 0, 11, 1},
{2, UPB_SIZE(0, 0), 0, 0, 4, 1},
{3, UPB_SIZE(8, 8), 0, 0, 4, 1},
{4, UPB_SIZE(16, 16), 0, 0, 4, 1},
{5, UPB_SIZE(28, 32), 0, 1, 11, 3},
};
const upb_msglayout envoy_api_v2_endpoint_UpstreamEndpointStats_msginit = {
&envoy_api_v2_endpoint_UpstreamEndpointStats_submsgs[0],
&envoy_api_v2_endpoint_UpstreamEndpointStats__fields[0],
UPB_SIZE(32, 40), 5, false,
};
static const upb_msglayout_field envoy_api_v2_endpoint_EndpointLoadMetricStats__fields[3] = {
{1, UPB_SIZE(16, 16), 0, 0, 9, 1},
{2, UPB_SIZE(0, 0), 0, 0, 4, 1},
{3, UPB_SIZE(8, 8), 0, 0, 1, 1},
};
const upb_msglayout envoy_api_v2_endpoint_EndpointLoadMetricStats_msginit = {
NULL,
&envoy_api_v2_endpoint_EndpointLoadMetricStats__fields[0],
UPB_SIZE(24, 32), 3, false,
};
static const upb_msglayout *const envoy_api_v2_endpoint_ClusterStats_submsgs[3] = {
&envoy_api_v2_endpoint_ClusterStats_DroppedRequests_msginit,
&envoy_api_v2_endpoint_UpstreamLocalityStats_msginit,
&google_protobuf_Duration_msginit,
};
static const upb_msglayout_field envoy_api_v2_endpoint_ClusterStats__fields[5] = {
{1, UPB_SIZE(8, 8), 0, 0, 9, 1},
{2, UPB_SIZE(20, 32), 0, 1, 11, 3},
{3, UPB_SIZE(0, 0), 0, 0, 4, 1},
{4, UPB_SIZE(16, 24), 0, 2, 11, 1},
{5, UPB_SIZE(24, 40), 0, 0, 11, 3},
};
const upb_msglayout envoy_api_v2_endpoint_ClusterStats_msginit = {
&envoy_api_v2_endpoint_ClusterStats_submsgs[0],
&envoy_api_v2_endpoint_ClusterStats__fields[0],
UPB_SIZE(32, 48), 5, false,
};
static const upb_msglayout_field envoy_api_v2_endpoint_ClusterStats_DroppedRequests__fields[2] = {
{1, UPB_SIZE(8, 8), 0, 0, 9, 1},
{2, UPB_SIZE(0, 0), 0, 0, 4, 1},
};
const upb_msglayout envoy_api_v2_endpoint_ClusterStats_DroppedRequests_msginit = {
NULL,
&envoy_api_v2_endpoint_ClusterStats_DroppedRequests__fields[0],
UPB_SIZE(16, 32), 2, false,
};
#include "upb/port_undef.inc"

@ -0,0 +1,299 @@
/* This file was generated by upbc (the upb compiler) from the input
* file:
*
* envoy/api/v2/endpoint/load_report.proto
*
* Do not edit -- your changes will be discarded when the file is
* regenerated. */
#ifndef ENVOY_API_V2_ENDPOINT_LOAD_REPORT_PROTO_UPB_H_
#define ENVOY_API_V2_ENDPOINT_LOAD_REPORT_PROTO_UPB_H_
#include "upb/generated_util.h"
#include "upb/msg.h"
#include "upb/decode.h"
#include "upb/encode.h"
#include "upb/port_def.inc"
#ifdef __cplusplus
extern "C" {
#endif
struct envoy_api_v2_endpoint_UpstreamLocalityStats;
struct envoy_api_v2_endpoint_UpstreamEndpointStats;
struct envoy_api_v2_endpoint_EndpointLoadMetricStats;
struct envoy_api_v2_endpoint_ClusterStats;
struct envoy_api_v2_endpoint_ClusterStats_DroppedRequests;
typedef struct envoy_api_v2_endpoint_UpstreamLocalityStats envoy_api_v2_endpoint_UpstreamLocalityStats;
typedef struct envoy_api_v2_endpoint_UpstreamEndpointStats envoy_api_v2_endpoint_UpstreamEndpointStats;
typedef struct envoy_api_v2_endpoint_EndpointLoadMetricStats envoy_api_v2_endpoint_EndpointLoadMetricStats;
typedef struct envoy_api_v2_endpoint_ClusterStats envoy_api_v2_endpoint_ClusterStats;
typedef struct envoy_api_v2_endpoint_ClusterStats_DroppedRequests envoy_api_v2_endpoint_ClusterStats_DroppedRequests;
extern const upb_msglayout envoy_api_v2_endpoint_UpstreamLocalityStats_msginit;
extern const upb_msglayout envoy_api_v2_endpoint_UpstreamEndpointStats_msginit;
extern const upb_msglayout envoy_api_v2_endpoint_EndpointLoadMetricStats_msginit;
extern const upb_msglayout envoy_api_v2_endpoint_ClusterStats_msginit;
extern const upb_msglayout envoy_api_v2_endpoint_ClusterStats_DroppedRequests_msginit;
struct envoy_api_v2_core_Address;
struct envoy_api_v2_core_Locality;
struct google_protobuf_Duration;
extern const upb_msglayout envoy_api_v2_core_Address_msginit;
extern const upb_msglayout envoy_api_v2_core_Locality_msginit;
extern const upb_msglayout google_protobuf_Duration_msginit;
/* Enums */
/* envoy.api.v2.endpoint.UpstreamLocalityStats */
UPB_INLINE envoy_api_v2_endpoint_UpstreamLocalityStats *envoy_api_v2_endpoint_UpstreamLocalityStats_new(upb_arena *arena) {
return (envoy_api_v2_endpoint_UpstreamLocalityStats *)upb_msg_new(&envoy_api_v2_endpoint_UpstreamLocalityStats_msginit, arena);
}
UPB_INLINE envoy_api_v2_endpoint_UpstreamLocalityStats *envoy_api_v2_endpoint_UpstreamLocalityStats_parsenew(upb_strview buf, upb_arena *arena) {
envoy_api_v2_endpoint_UpstreamLocalityStats *ret = envoy_api_v2_endpoint_UpstreamLocalityStats_new(arena);
return (ret && upb_decode(buf, ret, &envoy_api_v2_endpoint_UpstreamLocalityStats_msginit)) ? ret : NULL;
}
UPB_INLINE char *envoy_api_v2_endpoint_UpstreamLocalityStats_serialize(const envoy_api_v2_endpoint_UpstreamLocalityStats *msg, upb_arena *arena, size_t *len) {
return upb_encode(msg, &envoy_api_v2_endpoint_UpstreamLocalityStats_msginit, arena, len);
}
UPB_INLINE const struct envoy_api_v2_core_Locality* envoy_api_v2_endpoint_UpstreamLocalityStats_locality(const envoy_api_v2_endpoint_UpstreamLocalityStats *msg) { return UPB_FIELD_AT(msg, const struct envoy_api_v2_core_Locality*, UPB_SIZE(28, 32)); }
UPB_INLINE uint64_t envoy_api_v2_endpoint_UpstreamLocalityStats_total_successful_requests(const envoy_api_v2_endpoint_UpstreamLocalityStats *msg) { return UPB_FIELD_AT(msg, uint64_t, UPB_SIZE(0, 0)); }
UPB_INLINE uint64_t envoy_api_v2_endpoint_UpstreamLocalityStats_total_requests_in_progress(const envoy_api_v2_endpoint_UpstreamLocalityStats *msg) { return UPB_FIELD_AT(msg, uint64_t, UPB_SIZE(8, 8)); }
UPB_INLINE uint64_t envoy_api_v2_endpoint_UpstreamLocalityStats_total_error_requests(const envoy_api_v2_endpoint_UpstreamLocalityStats *msg) { return UPB_FIELD_AT(msg, uint64_t, UPB_SIZE(16, 16)); }
UPB_INLINE const envoy_api_v2_endpoint_EndpointLoadMetricStats* const* envoy_api_v2_endpoint_UpstreamLocalityStats_load_metric_stats(const envoy_api_v2_endpoint_UpstreamLocalityStats *msg, size_t *len) { return (const envoy_api_v2_endpoint_EndpointLoadMetricStats* const*)_upb_array_accessor(msg, UPB_SIZE(32, 40), len); }
UPB_INLINE uint32_t envoy_api_v2_endpoint_UpstreamLocalityStats_priority(const envoy_api_v2_endpoint_UpstreamLocalityStats *msg) { return UPB_FIELD_AT(msg, uint32_t, UPB_SIZE(24, 24)); }
UPB_INLINE const envoy_api_v2_endpoint_UpstreamEndpointStats* const* envoy_api_v2_endpoint_UpstreamLocalityStats_upstream_endpoint_stats(const envoy_api_v2_endpoint_UpstreamLocalityStats *msg, size_t *len) { return (const envoy_api_v2_endpoint_UpstreamEndpointStats* const*)_upb_array_accessor(msg, UPB_SIZE(36, 48), len); }
UPB_INLINE void envoy_api_v2_endpoint_UpstreamLocalityStats_set_locality(envoy_api_v2_endpoint_UpstreamLocalityStats *msg, struct envoy_api_v2_core_Locality* value) {
UPB_FIELD_AT(msg, struct envoy_api_v2_core_Locality*, UPB_SIZE(28, 32)) = value;
}
UPB_INLINE struct envoy_api_v2_core_Locality* envoy_api_v2_endpoint_UpstreamLocalityStats_mutable_locality(envoy_api_v2_endpoint_UpstreamLocalityStats *msg, upb_arena *arena) {
struct envoy_api_v2_core_Locality* sub = (struct envoy_api_v2_core_Locality*)envoy_api_v2_endpoint_UpstreamLocalityStats_locality(msg);
if (sub == NULL) {
sub = (struct envoy_api_v2_core_Locality*)upb_msg_new(&envoy_api_v2_core_Locality_msginit, arena);
if (!sub) return NULL;
envoy_api_v2_endpoint_UpstreamLocalityStats_set_locality(msg, sub);
}
return sub;
}
UPB_INLINE void envoy_api_v2_endpoint_UpstreamLocalityStats_set_total_successful_requests(envoy_api_v2_endpoint_UpstreamLocalityStats *msg, uint64_t value) {
UPB_FIELD_AT(msg, uint64_t, UPB_SIZE(0, 0)) = value;
}
UPB_INLINE void envoy_api_v2_endpoint_UpstreamLocalityStats_set_total_requests_in_progress(envoy_api_v2_endpoint_UpstreamLocalityStats *msg, uint64_t value) {
UPB_FIELD_AT(msg, uint64_t, UPB_SIZE(8, 8)) = value;
}
UPB_INLINE void envoy_api_v2_endpoint_UpstreamLocalityStats_set_total_error_requests(envoy_api_v2_endpoint_UpstreamLocalityStats *msg, uint64_t value) {
UPB_FIELD_AT(msg, uint64_t, UPB_SIZE(16, 16)) = value;
}
UPB_INLINE envoy_api_v2_endpoint_EndpointLoadMetricStats** envoy_api_v2_endpoint_UpstreamLocalityStats_mutable_load_metric_stats(envoy_api_v2_endpoint_UpstreamLocalityStats *msg, size_t *len) {
return (envoy_api_v2_endpoint_EndpointLoadMetricStats**)_upb_array_mutable_accessor(msg, UPB_SIZE(32, 40), len);
}
UPB_INLINE envoy_api_v2_endpoint_EndpointLoadMetricStats** envoy_api_v2_endpoint_UpstreamLocalityStats_resize_load_metric_stats(envoy_api_v2_endpoint_UpstreamLocalityStats *msg, size_t len, upb_arena *arena) {
return (envoy_api_v2_endpoint_EndpointLoadMetricStats**)_upb_array_resize_accessor(msg, UPB_SIZE(32, 40), len, UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, arena);
}
UPB_INLINE struct envoy_api_v2_endpoint_EndpointLoadMetricStats* envoy_api_v2_endpoint_UpstreamLocalityStats_add_load_metric_stats(envoy_api_v2_endpoint_UpstreamLocalityStats *msg, upb_arena *arena) {
struct envoy_api_v2_endpoint_EndpointLoadMetricStats* sub = (struct envoy_api_v2_endpoint_EndpointLoadMetricStats*)upb_msg_new(&envoy_api_v2_endpoint_EndpointLoadMetricStats_msginit, arena);
bool ok = _upb_array_append_accessor(
msg, UPB_SIZE(32, 40), UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, &sub, arena);
if (!ok) return NULL;
return sub;
}
UPB_INLINE void envoy_api_v2_endpoint_UpstreamLocalityStats_set_priority(envoy_api_v2_endpoint_UpstreamLocalityStats *msg, uint32_t value) {
UPB_FIELD_AT(msg, uint32_t, UPB_SIZE(24, 24)) = value;
}
UPB_INLINE envoy_api_v2_endpoint_UpstreamEndpointStats** envoy_api_v2_endpoint_UpstreamLocalityStats_mutable_upstream_endpoint_stats(envoy_api_v2_endpoint_UpstreamLocalityStats *msg, size_t *len) {
return (envoy_api_v2_endpoint_UpstreamEndpointStats**)_upb_array_mutable_accessor(msg, UPB_SIZE(36, 48), len);
}
UPB_INLINE envoy_api_v2_endpoint_UpstreamEndpointStats** envoy_api_v2_endpoint_UpstreamLocalityStats_resize_upstream_endpoint_stats(envoy_api_v2_endpoint_UpstreamLocalityStats *msg, size_t len, upb_arena *arena) {
return (envoy_api_v2_endpoint_UpstreamEndpointStats**)_upb_array_resize_accessor(msg, UPB_SIZE(36, 48), len, UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, arena);
}
UPB_INLINE struct envoy_api_v2_endpoint_UpstreamEndpointStats* envoy_api_v2_endpoint_UpstreamLocalityStats_add_upstream_endpoint_stats(envoy_api_v2_endpoint_UpstreamLocalityStats *msg, upb_arena *arena) {
struct envoy_api_v2_endpoint_UpstreamEndpointStats* sub = (struct envoy_api_v2_endpoint_UpstreamEndpointStats*)upb_msg_new(&envoy_api_v2_endpoint_UpstreamEndpointStats_msginit, arena);
bool ok = _upb_array_append_accessor(
msg, UPB_SIZE(36, 48), UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, &sub, arena);
if (!ok) return NULL;
return sub;
}
/* envoy.api.v2.endpoint.UpstreamEndpointStats */
UPB_INLINE envoy_api_v2_endpoint_UpstreamEndpointStats *envoy_api_v2_endpoint_UpstreamEndpointStats_new(upb_arena *arena) {
return (envoy_api_v2_endpoint_UpstreamEndpointStats *)upb_msg_new(&envoy_api_v2_endpoint_UpstreamEndpointStats_msginit, arena);
}
UPB_INLINE envoy_api_v2_endpoint_UpstreamEndpointStats *envoy_api_v2_endpoint_UpstreamEndpointStats_parsenew(upb_strview buf, upb_arena *arena) {
envoy_api_v2_endpoint_UpstreamEndpointStats *ret = envoy_api_v2_endpoint_UpstreamEndpointStats_new(arena);
return (ret && upb_decode(buf, ret, &envoy_api_v2_endpoint_UpstreamEndpointStats_msginit)) ? ret : NULL;
}
UPB_INLINE char *envoy_api_v2_endpoint_UpstreamEndpointStats_serialize(const envoy_api_v2_endpoint_UpstreamEndpointStats *msg, upb_arena *arena, size_t *len) {
return upb_encode(msg, &envoy_api_v2_endpoint_UpstreamEndpointStats_msginit, arena, len);
}
UPB_INLINE const struct envoy_api_v2_core_Address* envoy_api_v2_endpoint_UpstreamEndpointStats_address(const envoy_api_v2_endpoint_UpstreamEndpointStats *msg) { return UPB_FIELD_AT(msg, const struct envoy_api_v2_core_Address*, UPB_SIZE(24, 24)); }
UPB_INLINE uint64_t envoy_api_v2_endpoint_UpstreamEndpointStats_total_successful_requests(const envoy_api_v2_endpoint_UpstreamEndpointStats *msg) { return UPB_FIELD_AT(msg, uint64_t, UPB_SIZE(0, 0)); }
UPB_INLINE uint64_t envoy_api_v2_endpoint_UpstreamEndpointStats_total_requests_in_progress(const envoy_api_v2_endpoint_UpstreamEndpointStats *msg) { return UPB_FIELD_AT(msg, uint64_t, UPB_SIZE(8, 8)); }
UPB_INLINE uint64_t envoy_api_v2_endpoint_UpstreamEndpointStats_total_error_requests(const envoy_api_v2_endpoint_UpstreamEndpointStats *msg) { return UPB_FIELD_AT(msg, uint64_t, UPB_SIZE(16, 16)); }
UPB_INLINE const envoy_api_v2_endpoint_EndpointLoadMetricStats* const* envoy_api_v2_endpoint_UpstreamEndpointStats_load_metric_stats(const envoy_api_v2_endpoint_UpstreamEndpointStats *msg, size_t *len) { return (const envoy_api_v2_endpoint_EndpointLoadMetricStats* const*)_upb_array_accessor(msg, UPB_SIZE(28, 32), len); }
UPB_INLINE void envoy_api_v2_endpoint_UpstreamEndpointStats_set_address(envoy_api_v2_endpoint_UpstreamEndpointStats *msg, struct envoy_api_v2_core_Address* value) {
UPB_FIELD_AT(msg, struct envoy_api_v2_core_Address*, UPB_SIZE(24, 24)) = value;
}
UPB_INLINE struct envoy_api_v2_core_Address* envoy_api_v2_endpoint_UpstreamEndpointStats_mutable_address(envoy_api_v2_endpoint_UpstreamEndpointStats *msg, upb_arena *arena) {
struct envoy_api_v2_core_Address* sub = (struct envoy_api_v2_core_Address*)envoy_api_v2_endpoint_UpstreamEndpointStats_address(msg);
if (sub == NULL) {
sub = (struct envoy_api_v2_core_Address*)upb_msg_new(&envoy_api_v2_core_Address_msginit, arena);
if (!sub) return NULL;
envoy_api_v2_endpoint_UpstreamEndpointStats_set_address(msg, sub);
}
return sub;
}
UPB_INLINE void envoy_api_v2_endpoint_UpstreamEndpointStats_set_total_successful_requests(envoy_api_v2_endpoint_UpstreamEndpointStats *msg, uint64_t value) {
UPB_FIELD_AT(msg, uint64_t, UPB_SIZE(0, 0)) = value;
}
UPB_INLINE void envoy_api_v2_endpoint_UpstreamEndpointStats_set_total_requests_in_progress(envoy_api_v2_endpoint_UpstreamEndpointStats *msg, uint64_t value) {
UPB_FIELD_AT(msg, uint64_t, UPB_SIZE(8, 8)) = value;
}
UPB_INLINE void envoy_api_v2_endpoint_UpstreamEndpointStats_set_total_error_requests(envoy_api_v2_endpoint_UpstreamEndpointStats *msg, uint64_t value) {
UPB_FIELD_AT(msg, uint64_t, UPB_SIZE(16, 16)) = value;
}
UPB_INLINE envoy_api_v2_endpoint_EndpointLoadMetricStats** envoy_api_v2_endpoint_UpstreamEndpointStats_mutable_load_metric_stats(envoy_api_v2_endpoint_UpstreamEndpointStats *msg, size_t *len) {
return (envoy_api_v2_endpoint_EndpointLoadMetricStats**)_upb_array_mutable_accessor(msg, UPB_SIZE(28, 32), len);
}
UPB_INLINE envoy_api_v2_endpoint_EndpointLoadMetricStats** envoy_api_v2_endpoint_UpstreamEndpointStats_resize_load_metric_stats(envoy_api_v2_endpoint_UpstreamEndpointStats *msg, size_t len, upb_arena *arena) {
return (envoy_api_v2_endpoint_EndpointLoadMetricStats**)_upb_array_resize_accessor(msg, UPB_SIZE(28, 32), len, UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, arena);
}
UPB_INLINE struct envoy_api_v2_endpoint_EndpointLoadMetricStats* envoy_api_v2_endpoint_UpstreamEndpointStats_add_load_metric_stats(envoy_api_v2_endpoint_UpstreamEndpointStats *msg, upb_arena *arena) {
struct envoy_api_v2_endpoint_EndpointLoadMetricStats* sub = (struct envoy_api_v2_endpoint_EndpointLoadMetricStats*)upb_msg_new(&envoy_api_v2_endpoint_EndpointLoadMetricStats_msginit, arena);
bool ok = _upb_array_append_accessor(
msg, UPB_SIZE(28, 32), UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, &sub, arena);
if (!ok) return NULL;
return sub;
}
/* envoy.api.v2.endpoint.EndpointLoadMetricStats */
UPB_INLINE envoy_api_v2_endpoint_EndpointLoadMetricStats *envoy_api_v2_endpoint_EndpointLoadMetricStats_new(upb_arena *arena) {
return (envoy_api_v2_endpoint_EndpointLoadMetricStats *)upb_msg_new(&envoy_api_v2_endpoint_EndpointLoadMetricStats_msginit, arena);
}
UPB_INLINE envoy_api_v2_endpoint_EndpointLoadMetricStats *envoy_api_v2_endpoint_EndpointLoadMetricStats_parsenew(upb_strview buf, upb_arena *arena) {
envoy_api_v2_endpoint_EndpointLoadMetricStats *ret = envoy_api_v2_endpoint_EndpointLoadMetricStats_new(arena);
return (ret && upb_decode(buf, ret, &envoy_api_v2_endpoint_EndpointLoadMetricStats_msginit)) ? ret : NULL;
}
UPB_INLINE char *envoy_api_v2_endpoint_EndpointLoadMetricStats_serialize(const envoy_api_v2_endpoint_EndpointLoadMetricStats *msg, upb_arena *arena, size_t *len) {
return upb_encode(msg, &envoy_api_v2_endpoint_EndpointLoadMetricStats_msginit, arena, len);
}
UPB_INLINE upb_strview envoy_api_v2_endpoint_EndpointLoadMetricStats_metric_name(const envoy_api_v2_endpoint_EndpointLoadMetricStats *msg) { return UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(16, 16)); }
UPB_INLINE uint64_t envoy_api_v2_endpoint_EndpointLoadMetricStats_num_requests_finished_with_metric(const envoy_api_v2_endpoint_EndpointLoadMetricStats *msg) { return UPB_FIELD_AT(msg, uint64_t, UPB_SIZE(0, 0)); }
UPB_INLINE double envoy_api_v2_endpoint_EndpointLoadMetricStats_total_metric_value(const envoy_api_v2_endpoint_EndpointLoadMetricStats *msg) { return UPB_FIELD_AT(msg, double, UPB_SIZE(8, 8)); }
UPB_INLINE void envoy_api_v2_endpoint_EndpointLoadMetricStats_set_metric_name(envoy_api_v2_endpoint_EndpointLoadMetricStats *msg, upb_strview value) {
UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(16, 16)) = value;
}
UPB_INLINE void envoy_api_v2_endpoint_EndpointLoadMetricStats_set_num_requests_finished_with_metric(envoy_api_v2_endpoint_EndpointLoadMetricStats *msg, uint64_t value) {
UPB_FIELD_AT(msg, uint64_t, UPB_SIZE(0, 0)) = value;
}
UPB_INLINE void envoy_api_v2_endpoint_EndpointLoadMetricStats_set_total_metric_value(envoy_api_v2_endpoint_EndpointLoadMetricStats *msg, double value) {
UPB_FIELD_AT(msg, double, UPB_SIZE(8, 8)) = value;
}
/* envoy.api.v2.endpoint.ClusterStats */
UPB_INLINE envoy_api_v2_endpoint_ClusterStats *envoy_api_v2_endpoint_ClusterStats_new(upb_arena *arena) {
return (envoy_api_v2_endpoint_ClusterStats *)upb_msg_new(&envoy_api_v2_endpoint_ClusterStats_msginit, arena);
}
UPB_INLINE envoy_api_v2_endpoint_ClusterStats *envoy_api_v2_endpoint_ClusterStats_parsenew(upb_strview buf, upb_arena *arena) {
envoy_api_v2_endpoint_ClusterStats *ret = envoy_api_v2_endpoint_ClusterStats_new(arena);
return (ret && upb_decode(buf, ret, &envoy_api_v2_endpoint_ClusterStats_msginit)) ? ret : NULL;
}
UPB_INLINE char *envoy_api_v2_endpoint_ClusterStats_serialize(const envoy_api_v2_endpoint_ClusterStats *msg, upb_arena *arena, size_t *len) {
return upb_encode(msg, &envoy_api_v2_endpoint_ClusterStats_msginit, arena, len);
}
UPB_INLINE upb_strview envoy_api_v2_endpoint_ClusterStats_cluster_name(const envoy_api_v2_endpoint_ClusterStats *msg) { return UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(8, 8)); }
UPB_INLINE const envoy_api_v2_endpoint_UpstreamLocalityStats* const* envoy_api_v2_endpoint_ClusterStats_upstream_locality_stats(const envoy_api_v2_endpoint_ClusterStats *msg, size_t *len) { return (const envoy_api_v2_endpoint_UpstreamLocalityStats* const*)_upb_array_accessor(msg, UPB_SIZE(20, 32), len); }
UPB_INLINE uint64_t envoy_api_v2_endpoint_ClusterStats_total_dropped_requests(const envoy_api_v2_endpoint_ClusterStats *msg) { return UPB_FIELD_AT(msg, uint64_t, UPB_SIZE(0, 0)); }
UPB_INLINE const struct google_protobuf_Duration* envoy_api_v2_endpoint_ClusterStats_load_report_interval(const envoy_api_v2_endpoint_ClusterStats *msg) { return UPB_FIELD_AT(msg, const struct google_protobuf_Duration*, UPB_SIZE(16, 24)); }
UPB_INLINE const envoy_api_v2_endpoint_ClusterStats_DroppedRequests* const* envoy_api_v2_endpoint_ClusterStats_dropped_requests(const envoy_api_v2_endpoint_ClusterStats *msg, size_t *len) { return (const envoy_api_v2_endpoint_ClusterStats_DroppedRequests* const*)_upb_array_accessor(msg, UPB_SIZE(24, 40), len); }
UPB_INLINE void envoy_api_v2_endpoint_ClusterStats_set_cluster_name(envoy_api_v2_endpoint_ClusterStats *msg, upb_strview value) {
UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(8, 8)) = value;
}
UPB_INLINE envoy_api_v2_endpoint_UpstreamLocalityStats** envoy_api_v2_endpoint_ClusterStats_mutable_upstream_locality_stats(envoy_api_v2_endpoint_ClusterStats *msg, size_t *len) {
return (envoy_api_v2_endpoint_UpstreamLocalityStats**)_upb_array_mutable_accessor(msg, UPB_SIZE(20, 32), len);
}
UPB_INLINE envoy_api_v2_endpoint_UpstreamLocalityStats** envoy_api_v2_endpoint_ClusterStats_resize_upstream_locality_stats(envoy_api_v2_endpoint_ClusterStats *msg, size_t len, upb_arena *arena) {
return (envoy_api_v2_endpoint_UpstreamLocalityStats**)_upb_array_resize_accessor(msg, UPB_SIZE(20, 32), len, UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, arena);
}
UPB_INLINE struct envoy_api_v2_endpoint_UpstreamLocalityStats* envoy_api_v2_endpoint_ClusterStats_add_upstream_locality_stats(envoy_api_v2_endpoint_ClusterStats *msg, upb_arena *arena) {
struct envoy_api_v2_endpoint_UpstreamLocalityStats* sub = (struct envoy_api_v2_endpoint_UpstreamLocalityStats*)upb_msg_new(&envoy_api_v2_endpoint_UpstreamLocalityStats_msginit, arena);
bool ok = _upb_array_append_accessor(
msg, UPB_SIZE(20, 32), UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, &sub, arena);
if (!ok) return NULL;
return sub;
}
UPB_INLINE void envoy_api_v2_endpoint_ClusterStats_set_total_dropped_requests(envoy_api_v2_endpoint_ClusterStats *msg, uint64_t value) {
UPB_FIELD_AT(msg, uint64_t, UPB_SIZE(0, 0)) = value;
}
UPB_INLINE void envoy_api_v2_endpoint_ClusterStats_set_load_report_interval(envoy_api_v2_endpoint_ClusterStats *msg, struct google_protobuf_Duration* value) {
UPB_FIELD_AT(msg, struct google_protobuf_Duration*, UPB_SIZE(16, 24)) = value;
}
UPB_INLINE struct google_protobuf_Duration* envoy_api_v2_endpoint_ClusterStats_mutable_load_report_interval(envoy_api_v2_endpoint_ClusterStats *msg, upb_arena *arena) {
struct google_protobuf_Duration* sub = (struct google_protobuf_Duration*)envoy_api_v2_endpoint_ClusterStats_load_report_interval(msg);
if (sub == NULL) {
sub = (struct google_protobuf_Duration*)upb_msg_new(&google_protobuf_Duration_msginit, arena);
if (!sub) return NULL;
envoy_api_v2_endpoint_ClusterStats_set_load_report_interval(msg, sub);
}
return sub;
}
UPB_INLINE envoy_api_v2_endpoint_ClusterStats_DroppedRequests** envoy_api_v2_endpoint_ClusterStats_mutable_dropped_requests(envoy_api_v2_endpoint_ClusterStats *msg, size_t *len) {
return (envoy_api_v2_endpoint_ClusterStats_DroppedRequests**)_upb_array_mutable_accessor(msg, UPB_SIZE(24, 40), len);
}
UPB_INLINE envoy_api_v2_endpoint_ClusterStats_DroppedRequests** envoy_api_v2_endpoint_ClusterStats_resize_dropped_requests(envoy_api_v2_endpoint_ClusterStats *msg, size_t len, upb_arena *arena) {
return (envoy_api_v2_endpoint_ClusterStats_DroppedRequests**)_upb_array_resize_accessor(msg, UPB_SIZE(24, 40), len, UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, arena);
}
UPB_INLINE struct envoy_api_v2_endpoint_ClusterStats_DroppedRequests* envoy_api_v2_endpoint_ClusterStats_add_dropped_requests(envoy_api_v2_endpoint_ClusterStats *msg, upb_arena *arena) {
struct envoy_api_v2_endpoint_ClusterStats_DroppedRequests* sub = (struct envoy_api_v2_endpoint_ClusterStats_DroppedRequests*)upb_msg_new(&envoy_api_v2_endpoint_ClusterStats_DroppedRequests_msginit, arena);
bool ok = _upb_array_append_accessor(
msg, UPB_SIZE(24, 40), UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, &sub, arena);
if (!ok) return NULL;
return sub;
}
/* envoy.api.v2.endpoint.ClusterStats.DroppedRequests */
UPB_INLINE envoy_api_v2_endpoint_ClusterStats_DroppedRequests *envoy_api_v2_endpoint_ClusterStats_DroppedRequests_new(upb_arena *arena) {
return (envoy_api_v2_endpoint_ClusterStats_DroppedRequests *)upb_msg_new(&envoy_api_v2_endpoint_ClusterStats_DroppedRequests_msginit, arena);
}
UPB_INLINE envoy_api_v2_endpoint_ClusterStats_DroppedRequests *envoy_api_v2_endpoint_ClusterStats_DroppedRequests_parsenew(upb_strview buf, upb_arena *arena) {
envoy_api_v2_endpoint_ClusterStats_DroppedRequests *ret = envoy_api_v2_endpoint_ClusterStats_DroppedRequests_new(arena);
return (ret && upb_decode(buf, ret, &envoy_api_v2_endpoint_ClusterStats_DroppedRequests_msginit)) ? ret : NULL;
}
UPB_INLINE char *envoy_api_v2_endpoint_ClusterStats_DroppedRequests_serialize(const envoy_api_v2_endpoint_ClusterStats_DroppedRequests *msg, upb_arena *arena, size_t *len) {
return upb_encode(msg, &envoy_api_v2_endpoint_ClusterStats_DroppedRequests_msginit, arena, len);
}
UPB_INLINE upb_strview envoy_api_v2_endpoint_ClusterStats_DroppedRequests_category(const envoy_api_v2_endpoint_ClusterStats_DroppedRequests *msg) { return UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(8, 8)); }
UPB_INLINE uint64_t envoy_api_v2_endpoint_ClusterStats_DroppedRequests_dropped_count(const envoy_api_v2_endpoint_ClusterStats_DroppedRequests *msg) { return UPB_FIELD_AT(msg, uint64_t, UPB_SIZE(0, 0)); }
UPB_INLINE void envoy_api_v2_endpoint_ClusterStats_DroppedRequests_set_category(envoy_api_v2_endpoint_ClusterStats_DroppedRequests *msg, upb_strview value) {
UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(8, 8)) = value;
}
UPB_INLINE void envoy_api_v2_endpoint_ClusterStats_DroppedRequests_set_dropped_count(envoy_api_v2_endpoint_ClusterStats_DroppedRequests *msg, uint64_t value) {
UPB_FIELD_AT(msg, uint64_t, UPB_SIZE(0, 0)) = value;
}
#ifdef __cplusplus
} /* extern "C" */
#endif
#include "upb/port_undef.inc"
#endif /* ENVOY_API_V2_ENDPOINT_LOAD_REPORT_PROTO_UPB_H_ */

@ -0,0 +1,52 @@
/* This file was generated by upbc (the upb compiler) from the input
* file:
*
* envoy/service/load_stats/v2/lrs.proto
*
* Do not edit -- your changes will be discarded when the file is
* regenerated. */
#include <stddef.h>
#include "upb/msg.h"
#include "envoy/service/load_stats/v2/lrs.upb.h"
#include "envoy/api/v2/core/base.upb.h"
#include "envoy/api/v2/endpoint/load_report.upb.h"
#include "google/protobuf/duration.upb.h"
#include "validate/validate.upb.h"
#include "upb/port_def.inc"
static const upb_msglayout *const envoy_service_load_stats_v2_LoadStatsRequest_submsgs[2] = {
&envoy_api_v2_core_Node_msginit,
&envoy_api_v2_endpoint_ClusterStats_msginit,
};
static const upb_msglayout_field envoy_service_load_stats_v2_LoadStatsRequest__fields[2] = {
{1, UPB_SIZE(0, 0), 0, 0, 11, 1},
{2, UPB_SIZE(4, 8), 0, 1, 11, 3},
};
const upb_msglayout envoy_service_load_stats_v2_LoadStatsRequest_msginit = {
&envoy_service_load_stats_v2_LoadStatsRequest_submsgs[0],
&envoy_service_load_stats_v2_LoadStatsRequest__fields[0],
UPB_SIZE(8, 16), 2, false,
};
static const upb_msglayout *const envoy_service_load_stats_v2_LoadStatsResponse_submsgs[1] = {
&google_protobuf_Duration_msginit,
};
static const upb_msglayout_field envoy_service_load_stats_v2_LoadStatsResponse__fields[3] = {
{1, UPB_SIZE(8, 16), 0, 0, 9, 3},
{2, UPB_SIZE(4, 8), 0, 0, 11, 1},
{3, UPB_SIZE(0, 0), 0, 0, 8, 1},
};
const upb_msglayout envoy_service_load_stats_v2_LoadStatsResponse_msginit = {
&envoy_service_load_stats_v2_LoadStatsResponse_submsgs[0],
&envoy_service_load_stats_v2_LoadStatsResponse__fields[0],
UPB_SIZE(12, 24), 3, false,
};
#include "upb/port_undef.inc"

@ -0,0 +1,132 @@
/* This file was generated by upbc (the upb compiler) from the input
* file:
*
* envoy/service/load_stats/v2/lrs.proto
*
* Do not edit -- your changes will be discarded when the file is
* regenerated. */
#ifndef ENVOY_SERVICE_LOAD_STATS_V2_LRS_PROTO_UPB_H_
#define ENVOY_SERVICE_LOAD_STATS_V2_LRS_PROTO_UPB_H_
#include "upb/generated_util.h"
#include "upb/msg.h"
#include "upb/decode.h"
#include "upb/encode.h"
#include "upb/port_def.inc"
#ifdef __cplusplus
extern "C" {
#endif
struct envoy_service_load_stats_v2_LoadStatsRequest;
struct envoy_service_load_stats_v2_LoadStatsResponse;
typedef struct envoy_service_load_stats_v2_LoadStatsRequest envoy_service_load_stats_v2_LoadStatsRequest;
typedef struct envoy_service_load_stats_v2_LoadStatsResponse envoy_service_load_stats_v2_LoadStatsResponse;
extern const upb_msglayout envoy_service_load_stats_v2_LoadStatsRequest_msginit;
extern const upb_msglayout envoy_service_load_stats_v2_LoadStatsResponse_msginit;
struct envoy_api_v2_core_Node;
struct envoy_api_v2_endpoint_ClusterStats;
struct google_protobuf_Duration;
extern const upb_msglayout envoy_api_v2_core_Node_msginit;
extern const upb_msglayout envoy_api_v2_endpoint_ClusterStats_msginit;
extern const upb_msglayout google_protobuf_Duration_msginit;
/* Enums */
/* envoy.service.load_stats.v2.LoadStatsRequest */
UPB_INLINE envoy_service_load_stats_v2_LoadStatsRequest *envoy_service_load_stats_v2_LoadStatsRequest_new(upb_arena *arena) {
return (envoy_service_load_stats_v2_LoadStatsRequest *)upb_msg_new(&envoy_service_load_stats_v2_LoadStatsRequest_msginit, arena);
}
UPB_INLINE envoy_service_load_stats_v2_LoadStatsRequest *envoy_service_load_stats_v2_LoadStatsRequest_parsenew(upb_strview buf, upb_arena *arena) {
envoy_service_load_stats_v2_LoadStatsRequest *ret = envoy_service_load_stats_v2_LoadStatsRequest_new(arena);
return (ret && upb_decode(buf, ret, &envoy_service_load_stats_v2_LoadStatsRequest_msginit)) ? ret : NULL;
}
UPB_INLINE char *envoy_service_load_stats_v2_LoadStatsRequest_serialize(const envoy_service_load_stats_v2_LoadStatsRequest *msg, upb_arena *arena, size_t *len) {
return upb_encode(msg, &envoy_service_load_stats_v2_LoadStatsRequest_msginit, arena, len);
}
UPB_INLINE const struct envoy_api_v2_core_Node* envoy_service_load_stats_v2_LoadStatsRequest_node(const envoy_service_load_stats_v2_LoadStatsRequest *msg) { return UPB_FIELD_AT(msg, const struct envoy_api_v2_core_Node*, UPB_SIZE(0, 0)); }
UPB_INLINE const struct envoy_api_v2_endpoint_ClusterStats* const* envoy_service_load_stats_v2_LoadStatsRequest_cluster_stats(const envoy_service_load_stats_v2_LoadStatsRequest *msg, size_t *len) { return (const struct envoy_api_v2_endpoint_ClusterStats* const*)_upb_array_accessor(msg, UPB_SIZE(4, 8), len); }
UPB_INLINE void envoy_service_load_stats_v2_LoadStatsRequest_set_node(envoy_service_load_stats_v2_LoadStatsRequest *msg, struct envoy_api_v2_core_Node* value) {
UPB_FIELD_AT(msg, struct envoy_api_v2_core_Node*, UPB_SIZE(0, 0)) = value;
}
UPB_INLINE struct envoy_api_v2_core_Node* envoy_service_load_stats_v2_LoadStatsRequest_mutable_node(envoy_service_load_stats_v2_LoadStatsRequest *msg, upb_arena *arena) {
struct envoy_api_v2_core_Node* sub = (struct envoy_api_v2_core_Node*)envoy_service_load_stats_v2_LoadStatsRequest_node(msg);
if (sub == NULL) {
sub = (struct envoy_api_v2_core_Node*)upb_msg_new(&envoy_api_v2_core_Node_msginit, arena);
if (!sub) return NULL;
envoy_service_load_stats_v2_LoadStatsRequest_set_node(msg, sub);
}
return sub;
}
UPB_INLINE struct envoy_api_v2_endpoint_ClusterStats** envoy_service_load_stats_v2_LoadStatsRequest_mutable_cluster_stats(envoy_service_load_stats_v2_LoadStatsRequest *msg, size_t *len) {
return (struct envoy_api_v2_endpoint_ClusterStats**)_upb_array_mutable_accessor(msg, UPB_SIZE(4, 8), len);
}
UPB_INLINE struct envoy_api_v2_endpoint_ClusterStats** envoy_service_load_stats_v2_LoadStatsRequest_resize_cluster_stats(envoy_service_load_stats_v2_LoadStatsRequest *msg, size_t len, upb_arena *arena) {
return (struct envoy_api_v2_endpoint_ClusterStats**)_upb_array_resize_accessor(msg, UPB_SIZE(4, 8), len, UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, arena);
}
UPB_INLINE struct envoy_api_v2_endpoint_ClusterStats* envoy_service_load_stats_v2_LoadStatsRequest_add_cluster_stats(envoy_service_load_stats_v2_LoadStatsRequest *msg, upb_arena *arena) {
struct envoy_api_v2_endpoint_ClusterStats* sub = (struct envoy_api_v2_endpoint_ClusterStats*)upb_msg_new(&envoy_api_v2_endpoint_ClusterStats_msginit, arena);
bool ok = _upb_array_append_accessor(
msg, UPB_SIZE(4, 8), UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, &sub, arena);
if (!ok) return NULL;
return sub;
}
/* envoy.service.load_stats.v2.LoadStatsResponse */
UPB_INLINE envoy_service_load_stats_v2_LoadStatsResponse *envoy_service_load_stats_v2_LoadStatsResponse_new(upb_arena *arena) {
return (envoy_service_load_stats_v2_LoadStatsResponse *)upb_msg_new(&envoy_service_load_stats_v2_LoadStatsResponse_msginit, arena);
}
UPB_INLINE envoy_service_load_stats_v2_LoadStatsResponse *envoy_service_load_stats_v2_LoadStatsResponse_parsenew(upb_strview buf, upb_arena *arena) {
envoy_service_load_stats_v2_LoadStatsResponse *ret = envoy_service_load_stats_v2_LoadStatsResponse_new(arena);
return (ret && upb_decode(buf, ret, &envoy_service_load_stats_v2_LoadStatsResponse_msginit)) ? ret : NULL;
}
UPB_INLINE char *envoy_service_load_stats_v2_LoadStatsResponse_serialize(const envoy_service_load_stats_v2_LoadStatsResponse *msg, upb_arena *arena, size_t *len) {
return upb_encode(msg, &envoy_service_load_stats_v2_LoadStatsResponse_msginit, arena, len);
}
UPB_INLINE upb_strview const* envoy_service_load_stats_v2_LoadStatsResponse_clusters(const envoy_service_load_stats_v2_LoadStatsResponse *msg, size_t *len) { return (upb_strview const*)_upb_array_accessor(msg, UPB_SIZE(8, 16), len); }
UPB_INLINE const struct google_protobuf_Duration* envoy_service_load_stats_v2_LoadStatsResponse_load_reporting_interval(const envoy_service_load_stats_v2_LoadStatsResponse *msg) { return UPB_FIELD_AT(msg, const struct google_protobuf_Duration*, UPB_SIZE(4, 8)); }
UPB_INLINE bool envoy_service_load_stats_v2_LoadStatsResponse_report_endpoint_granularity(const envoy_service_load_stats_v2_LoadStatsResponse *msg) { return UPB_FIELD_AT(msg, bool, UPB_SIZE(0, 0)); }
UPB_INLINE upb_strview* envoy_service_load_stats_v2_LoadStatsResponse_mutable_clusters(envoy_service_load_stats_v2_LoadStatsResponse *msg, size_t *len) {
return (upb_strview*)_upb_array_mutable_accessor(msg, UPB_SIZE(8, 16), len);
}
UPB_INLINE upb_strview* envoy_service_load_stats_v2_LoadStatsResponse_resize_clusters(envoy_service_load_stats_v2_LoadStatsResponse *msg, size_t len, upb_arena *arena) {
return (upb_strview*)_upb_array_resize_accessor(msg, UPB_SIZE(8, 16), len, UPB_SIZE(8, 16), UPB_TYPE_STRING, arena);
}
UPB_INLINE bool envoy_service_load_stats_v2_LoadStatsResponse_add_clusters(envoy_service_load_stats_v2_LoadStatsResponse *msg, upb_strview val, upb_arena *arena) {
return _upb_array_append_accessor(
msg, UPB_SIZE(8, 16), UPB_SIZE(8, 16), UPB_TYPE_STRING, &val, arena);
}
UPB_INLINE void envoy_service_load_stats_v2_LoadStatsResponse_set_load_reporting_interval(envoy_service_load_stats_v2_LoadStatsResponse *msg, struct google_protobuf_Duration* value) {
UPB_FIELD_AT(msg, struct google_protobuf_Duration*, UPB_SIZE(4, 8)) = value;
}
UPB_INLINE struct google_protobuf_Duration* envoy_service_load_stats_v2_LoadStatsResponse_mutable_load_reporting_interval(envoy_service_load_stats_v2_LoadStatsResponse *msg, upb_arena *arena) {
struct google_protobuf_Duration* sub = (struct google_protobuf_Duration*)envoy_service_load_stats_v2_LoadStatsResponse_load_reporting_interval(msg);
if (sub == NULL) {
sub = (struct google_protobuf_Duration*)upb_msg_new(&google_protobuf_Duration_msginit, arena);
if (!sub) return NULL;
envoy_service_load_stats_v2_LoadStatsResponse_set_load_reporting_interval(msg, sub);
}
return sub;
}
UPB_INLINE void envoy_service_load_stats_v2_LoadStatsResponse_set_report_endpoint_granularity(envoy_service_load_stats_v2_LoadStatsResponse *msg, bool value) {
UPB_FIELD_AT(msg, bool, UPB_SIZE(0, 0)) = value;
}
#ifdef __cplusplus
} /* extern "C" */
#endif
#include "upb/port_undef.inc"
#endif /* ENVOY_SERVICE_LOAD_STATS_V2_LRS_PROTO_UPB_H_ */

@ -21,7 +21,6 @@
#include <limits.h>
#include <string.h>
#include <grpc/compression.h>
#include <grpc/grpc.h>
#include <grpc/support/alloc.h>
#include <grpc/support/log.h>
@ -213,106 +212,6 @@ void grpc_channel_args_destroy(grpc_channel_args* a) {
gpr_free(a);
}
grpc_compression_algorithm grpc_channel_args_get_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;
}
}
return GRPC_COMPRESS_NONE;
}
grpc_channel_args* grpc_channel_args_set_compression_algorithm(
grpc_channel_args* a, grpc_compression_algorithm algorithm) {
GPR_ASSERT(algorithm < GRPC_COMPRESS_ALGORITHMS_COUNT);
grpc_arg tmp;
tmp.type = GRPC_ARG_INTEGER;
tmp.key = (char*)GRPC_COMPRESSION_CHANNEL_DEFAULT_ALGORITHM;
tmp.value.integer = algorithm;
return grpc_channel_args_copy_and_add(a, &tmp, 1);
}
/** Returns 1 if the argument for compression algorithm's enabled states bitset
* was found in \a a, returning the arg's value in \a states. Otherwise, returns
* 0. */
static int find_compression_algorithm_states_bitset(const grpc_channel_args* a,
int** states_arg) {
if (a != nullptr) {
size_t i;
for (i = 0; i < a->num_args; ++i) {
if (a->args[i].type == GRPC_ARG_INTEGER &&
!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 */
return 1;
}
}
}
return 0; /* GPR_FALSE */
}
grpc_channel_args* grpc_channel_args_compression_algorithm_set_state(
grpc_channel_args** a, grpc_compression_algorithm algorithm, int state) {
int* states_arg = nullptr;
grpc_channel_args* result = *a;
const int states_arg_found =
find_compression_algorithm_states_bitset(*a, &states_arg);
if (grpc_channel_args_get_compression_algorithm(*a) == algorithm &&
state == 0) {
const char* algo_name = nullptr;
GPR_ASSERT(grpc_compression_algorithm_name(algorithm, &algo_name) != 0);
gpr_log(GPR_ERROR,
"Tried to disable default compression algorithm '%s'. The "
"operation has been ignored.",
algo_name);
} else if (states_arg_found) {
if (state != 0) {
GPR_BITSET((unsigned*)states_arg, algorithm);
} else if (algorithm != GRPC_COMPRESS_NONE) {
GPR_BITCLEAR((unsigned*)states_arg, algorithm);
}
} else {
/* create a new arg */
grpc_arg tmp;
tmp.type = GRPC_ARG_INTEGER;
tmp.key = (char*)GRPC_COMPRESSION_CHANNEL_ENABLED_ALGORITHMS_BITSET;
/* all enabled by default */
tmp.value.integer = (1u << GRPC_COMPRESS_ALGORITHMS_COUNT) - 1;
if (state != 0) {
GPR_BITSET((unsigned*)&tmp.value.integer, algorithm);
} else if (algorithm != GRPC_COMPRESS_NONE) {
GPR_BITCLEAR((unsigned*)&tmp.value.integer, algorithm);
}
result = grpc_channel_args_copy_and_add(*a, &tmp, 1);
grpc_channel_args_destroy(*a);
*a = result;
}
return result;
}
uint32_t grpc_channel_args_compression_algorithm_get_states(
const grpc_channel_args* a) {
int* states_arg;
if (find_compression_algorithm_states_bitset(a, &states_arg)) {
return static_cast<uint32_t>(*states_arg);
} else {
return (1u << GRPC_COMPRESS_ALGORITHMS_COUNT) - 1; /* All algs. enabled */
}
}
grpc_channel_args* grpc_channel_args_set_socket_mutator(
grpc_channel_args* a, grpc_socket_mutator* mutator) {
grpc_arg tmp = grpc_socket_mutator_to_arg(mutator);
return grpc_channel_args_copy_and_add(a, &tmp, 1);
}
int grpc_channel_args_compare(const grpc_channel_args* a,
const grpc_channel_args* b) {
int c = GPR_ICMP(a->num_args, b->num_args);

@ -21,9 +21,7 @@
#include <grpc/support/port_platform.h>
#include <grpc/compression.h>
#include <grpc/grpc.h>
#include "src/core/lib/iomgr/socket_mutator.h"
// Channel args are intentionally immutable, to avoid the need for locking.
@ -60,44 +58,9 @@ inline void grpc_channel_args_destroy(const grpc_channel_args* a) {
grpc_channel_args_destroy(const_cast<grpc_channel_args*>(a));
}
/** Returns the compression algorithm set in \a a. */
grpc_compression_algorithm grpc_channel_args_get_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* a, grpc_compression_algorithm algorithm);
/** Sets the support for the given compression algorithm. By default, all
* compression algorithms are enabled. It's an error to disable an algorithm set
* by grpc_channel_args_set_compression_algorithm.
*
* Returns an instance with the updated algorithm states. The \a a pointer is
* modified to point to the returned instance (which may be different from the
* input value of \a a). */
grpc_channel_args* grpc_channel_args_compression_algorithm_set_state(
grpc_channel_args** a, grpc_compression_algorithm algorithm, int enabled);
/** Returns the bitset representing the support state (true for enabled, false
* for disabled) for compression algorithms.
*
* The i-th bit of the returned bitset corresponds to the i-th entry in the
* grpc_compression_algorithm enum. */
uint32_t grpc_channel_args_compression_algorithm_get_states(
const grpc_channel_args* a);
int grpc_channel_args_compare(const grpc_channel_args* a,
const grpc_channel_args* b);
/** Returns a channel arg instance with socket mutator added. The socket mutator
* will perform its mutate_fd method on all file descriptors used by the
* channel.
* If \a a is non-MULL, its args are copied. */
grpc_channel_args* grpc_channel_args_set_socket_mutator(
grpc_channel_args* a, grpc_socket_mutator* mutator);
/** Returns the value of argument \a name from \a args, or NULL if not found. */
const grpc_arg* grpc_channel_args_find(const grpc_channel_args* args,
const char* name);

@ -0,0 +1,127 @@
/*
*
* Copyright 2015 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 <grpc/support/port_platform.h>
#include <limits.h>
#include <string.h>
#include <grpc/compression.h>
#include <grpc/grpc.h>
#include <grpc/support/alloc.h>
#include <grpc/support/log.h>
#include <grpc/support/string_util.h>
#include "src/core/lib/channel/channel_args.h"
#include "src/core/lib/compression/compression_args.h"
#include "src/core/lib/gpr/string.h"
#include "src/core/lib/gpr/useful.h"
grpc_compression_algorithm grpc_channel_args_get_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;
}
}
return GRPC_COMPRESS_NONE;
}
grpc_channel_args* grpc_channel_args_set_compression_algorithm(
grpc_channel_args* a, grpc_compression_algorithm algorithm) {
GPR_ASSERT(algorithm < GRPC_COMPRESS_ALGORITHMS_COUNT);
grpc_arg tmp;
tmp.type = GRPC_ARG_INTEGER;
tmp.key = (char*)GRPC_COMPRESSION_CHANNEL_DEFAULT_ALGORITHM;
tmp.value.integer = algorithm;
return grpc_channel_args_copy_and_add(a, &tmp, 1);
}
/** Returns 1 if the argument for compression algorithm's enabled states bitset
* was found in \a a, returning the arg's value in \a states. Otherwise, returns
* 0. */
static int find_compression_algorithm_states_bitset(const grpc_channel_args* a,
int** states_arg) {
if (a != nullptr) {
size_t i;
for (i = 0; i < a->num_args; ++i) {
if (a->args[i].type == GRPC_ARG_INTEGER &&
!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 */
return 1;
}
}
}
return 0; /* GPR_FALSE */
}
grpc_channel_args* grpc_channel_args_compression_algorithm_set_state(
grpc_channel_args** a, grpc_compression_algorithm algorithm, int state) {
int* states_arg = nullptr;
grpc_channel_args* result = *a;
const int states_arg_found =
find_compression_algorithm_states_bitset(*a, &states_arg);
if (grpc_channel_args_get_compression_algorithm(*a) == algorithm &&
state == 0) {
const char* algo_name = nullptr;
GPR_ASSERT(grpc_compression_algorithm_name(algorithm, &algo_name) != 0);
gpr_log(GPR_ERROR,
"Tried to disable default compression algorithm '%s'. The "
"operation has been ignored.",
algo_name);
} else if (states_arg_found) {
if (state != 0) {
GPR_BITSET((unsigned*)states_arg, algorithm);
} else if (algorithm != GRPC_COMPRESS_NONE) {
GPR_BITCLEAR((unsigned*)states_arg, algorithm);
}
} else {
/* create a new arg */
grpc_arg tmp;
tmp.type = GRPC_ARG_INTEGER;
tmp.key = (char*)GRPC_COMPRESSION_CHANNEL_ENABLED_ALGORITHMS_BITSET;
/* all enabled by default */
tmp.value.integer = (1u << GRPC_COMPRESS_ALGORITHMS_COUNT) - 1;
if (state != 0) {
GPR_BITSET((unsigned*)&tmp.value.integer, algorithm);
} else if (algorithm != GRPC_COMPRESS_NONE) {
GPR_BITCLEAR((unsigned*)&tmp.value.integer, algorithm);
}
result = grpc_channel_args_copy_and_add(*a, &tmp, 1);
grpc_channel_args_destroy(*a);
*a = result;
}
return result;
}
uint32_t grpc_channel_args_compression_algorithm_get_states(
const grpc_channel_args* a) {
int* states_arg;
if (find_compression_algorithm_states_bitset(a, &states_arg)) {
return static_cast<uint32_t>(*states_arg);
} else {
return (1u << GRPC_COMPRESS_ALGORITHMS_COUNT) - 1; /* All algs. enabled */
}
}

@ -0,0 +1,55 @@
/*
*
* Copyright 2015 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.
*
*/
#ifndef GRPC_CORE_LIB_COMPRESSION_COMPRESSION_ARGS_H
#define GRPC_CORE_LIB_COMPRESSION_COMPRESSION_ARGS_H
#include <grpc/support/port_platform.h>
#include <grpc/compression.h>
#include <grpc/impl/codegen/grpc_types.h>
/** Returns the compression algorithm set in \a a. */
grpc_compression_algorithm grpc_channel_args_get_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* a, grpc_compression_algorithm algorithm);
/** Sets the support for the given compression algorithm. By default, all
* compression algorithms are enabled. It's an error to disable an algorithm set
* by grpc_channel_args_set_compression_algorithm.
*
* Returns an instance with the updated algorithm states. The \a a pointer is
* modified to point to the returned instance (which may be different from the
* input value of \a a). */
grpc_channel_args* grpc_channel_args_compression_algorithm_set_state(
grpc_channel_args** a, grpc_compression_algorithm algorithm, int state);
/** Returns the bitset representing the support state (true for enabled, false
* for disabled) for compression algorithms.
*
* The i-th bit of the returned bitset corresponds to the i-th entry in the
* grpc_compression_algorithm enum. */
uint32_t grpc_channel_args_compression_algorithm_get_states(
const grpc_channel_args* a);
#endif /* GRPC_CORE_LIB_COMPRESSION_COMPRESSION_ARGS_H */

@ -29,49 +29,10 @@
#include <grpc/support/sync.h>
#include "src/core/lib/gpr/alloc.h"
#include "src/core/lib/gpr/env.h"
#include "src/core/lib/gprpp/memory.h"
namespace {
enum init_strategy {
NO_INIT, // Do not initialize the arena blocks.
ZERO_INIT, // Initialize arena blocks with 0.
NON_ZERO_INIT, // Initialize arena blocks with a non-zero value.
};
gpr_once g_init_strategy_once = GPR_ONCE_INIT;
init_strategy g_init_strategy = NO_INIT;
} // namespace
static void set_strategy_from_env() {
char* str = gpr_getenv("GRPC_ARENA_INIT_STRATEGY");
if (str == nullptr) {
g_init_strategy = NO_INIT;
} else if (strcmp(str, "zero_init") == 0) {
g_init_strategy = ZERO_INIT;
} else if (strcmp(str, "non_zero_init") == 0) {
g_init_strategy = NON_ZERO_INIT;
} else {
g_init_strategy = NO_INIT;
}
gpr_free(str);
}
static void* gpr_arena_alloc_maybe_init(size_t size) {
void* mem = gpr_malloc_aligned(size, GPR_MAX_ALIGNMENT);
gpr_once_init(&g_init_strategy_once, set_strategy_from_env);
if (GPR_UNLIKELY(g_init_strategy != NO_INIT)) {
if (g_init_strategy == ZERO_INIT) {
memset(mem, 0, size);
} else { // NON_ZERO_INIT.
memset(mem, 0xFE, size);
}
}
return mem;
}
void gpr_arena_init() {
gpr_once_init(&g_init_strategy_once, set_strategy_from_env);
static void* gpr_arena_malloc(size_t size) {
return gpr_malloc_aligned(size, GPR_MAX_ALIGNMENT);
}
// Uncomment this to use a simple arena that simply allocates the
@ -109,8 +70,7 @@ void* gpr_arena_alloc(gpr_arena* arena, size_t size) {
gpr_mu_lock(&arena->mu);
arena->ptrs =
(void**)gpr_realloc(arena->ptrs, sizeof(void*) * (arena->num_ptrs + 1));
void* retval = arena->ptrs[arena->num_ptrs++] =
gpr_arena_alloc_maybe_init(size);
void* retval = arena->ptrs[arena->num_ptrs++] = gpr_arena_malloc(size);
gpr_mu_unlock(&arena->mu);
return retval;
}
@ -154,7 +114,7 @@ struct gpr_arena {
gpr_arena* gpr_arena_create(size_t initial_size) {
initial_size = GPR_ROUND_UP_TO_ALIGNMENT_SIZE(initial_size);
return new (gpr_arena_alloc_maybe_init(
return new (gpr_arena_malloc(
GPR_ROUND_UP_TO_ALIGNMENT_SIZE(sizeof(gpr_arena)) + initial_size))
gpr_arena(initial_size);
}
@ -179,7 +139,7 @@ void* gpr_arena_alloc(gpr_arena* arena, size_t size) {
// sizing historesis (that is, most calls should have a large enough initial
// zone and will not need to grow the arena).
gpr_mu_lock(&arena->arena_growth_mutex);
zone* z = new (gpr_arena_alloc_maybe_init(
zone* z = new (gpr_arena_malloc(
GPR_ROUND_UP_TO_ALIGNMENT_SIZE(sizeof(zone)) + size)) zone();
arena->last_zone->next = z;
arena->last_zone = z;

@ -37,7 +37,5 @@ gpr_arena* gpr_arena_create(size_t initial_size);
void* gpr_arena_alloc(gpr_arena* arena, size_t size);
// Destroy an arena, returning the total number of bytes allocated
size_t gpr_arena_destroy(gpr_arena* arena);
// Initializes the Arena component.
void gpr_arena_init();
#endif /* GRPC_CORE_LIB_GPR_ARENA_H */

@ -213,7 +213,7 @@ struct grpc_pollset {
poll */
bool seen_inactive;
bool shutting_down; /* Is the pollset shutting down ? */
grpc_closure* shutdown_closure; /* Called after after shutdown is complete */
grpc_closure* shutdown_closure; /* Called after shutdown is complete */
/* Number of workers who are *about-to* attach themselves to the pollset
* worker list */

@ -49,6 +49,8 @@ static bool iomgr_platform_add_closure_to_background_poller(
return false;
}
bool g_custom_iomgr_enabled = false;
static grpc_iomgr_platform_vtable vtable = {
iomgr_platform_init,
iomgr_platform_flush,
@ -61,6 +63,7 @@ void grpc_custom_iomgr_init(grpc_socket_vtable* socket,
grpc_custom_resolver_vtable* resolver,
grpc_custom_timer_vtable* timer,
grpc_custom_poller_vtable* poller) {
g_custom_iomgr_enabled = true;
grpc_custom_endpoint_init(socket);
grpc_custom_timer_init(timer);
grpc_custom_pollset_init(poller);

@ -39,6 +39,8 @@ extern gpr_thd_id g_init_thread;
#define GRPC_CUSTOM_IOMGR_ASSERT_SAME_THREAD()
#endif /* GRPC_CUSTOM_IOMGR_THREAD_CHECK */
extern bool g_custom_iomgr_enabled;
void grpc_custom_iomgr_init(grpc_socket_vtable* socket,
grpc_custom_resolver_vtable* resolver,
grpc_custom_timer_vtable* timer,

@ -88,6 +88,15 @@
#ifdef LINUX_VERSION_CODE
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 37)
#define GRPC_HAVE_TCP_USER_TIMEOUT
#ifdef __GLIBC_PREREQ
#if !(__GLIBC_PREREQ(2, 17))
/*
* TCP_USER_TIMEOUT wasn't imported to glibc until 2.17. Use Linux system
* header instead.
*/
#define GRPC_LINUX_TCP_H 1
#endif /* __GLIBC_PREREQ(2, 17) */
#endif /* ifdef __GLIBC_PREREQ */
#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 37) */
#endif /* LINUX_VERSION_CODE */
#ifndef __GLIBC__

@ -30,7 +30,11 @@
#include <fcntl.h>
#include <limits.h>
#include <netinet/in.h>
#ifdef GRPC_LINUX_TCP_H
#include <linux/tcp.h>
#else
#include <netinet/tcp.h>
#endif
#include <stdio.h>
#include <string.h>
#include <sys/socket.h>

@ -88,6 +88,18 @@ static grpc_error* enable_loopback_fast_path(SOCKET sock) {
: GRPC_WSA_ERROR(status, "WSAIoctl(SIO_LOOPBACK_FAST_PATH)");
}
static grpc_error* enable_socket_low_latency(SOCKET sock) {
int status;
BOOL param = TRUE;
status = ::setsockopt(sock, IPPROTO_TCP, TCP_NODELAY,
reinterpret_cast<char*>(&param), sizeof(param));
if (status == SOCKET_ERROR) {
status = WSAGetLastError();
}
return status == 0 ? GRPC_ERROR_NONE
: GRPC_WSA_ERROR(status, "setsockopt(TCP_NODELAY)");
}
grpc_error* grpc_tcp_prepare_socket(SOCKET sock) {
grpc_error* err;
err = grpc_tcp_set_non_block(sock);
@ -96,6 +108,8 @@ grpc_error* grpc_tcp_prepare_socket(SOCKET sock) {
if (err != GRPC_ERROR_NONE) return err;
err = enable_loopback_fast_path(sock);
if (err != GRPC_ERROR_NONE) return err;
err = enable_socket_low_latency(sock);
if (err != GRPC_ERROR_NONE) return err;
return GRPC_ERROR_NONE;
}

@ -314,7 +314,6 @@ class grpc_ssl_server_security_connector
bool try_fetch_ssl_server_credentials() {
grpc_ssl_server_certificate_config* certificate_config = nullptr;
bool status;
if (!has_cert_config_fetcher()) return false;
grpc_ssl_server_credentials* server_creds =
@ -374,7 +373,9 @@ class grpc_ssl_server_security_connector
options.num_alpn_protocols = static_cast<uint16_t>(num_alpn_protocols);
tsi_result result = tsi_create_ssl_server_handshaker_factory_with_options(
&options, &new_handshaker_factory);
gpr_free((void*)options.pem_key_cert_pairs);
grpc_tsi_ssl_pem_key_cert_pairs_destroy(
const_cast<tsi_ssl_pem_key_cert_pair*>(options.pem_key_cert_pairs),
options.num_key_cert_pairs);
gpr_free((void*)alpn_protocol_strings);
if (result != TSI_OK) {

@ -133,7 +133,6 @@ void grpc_init(void) {
}
grpc_core::Fork::GlobalInit();
grpc_fork_handlers_auto_register();
gpr_arena_init();
grpc_stats_init();
grpc_slice_intern_init();
grpc_mdctx_global_init();

@ -48,7 +48,6 @@ void grpc_connectivity_state_init(grpc_connectivity_state_tracker* tracker,
grpc_connectivity_state init_state,
const char* name) {
gpr_atm_no_barrier_store(&tracker->current_state_atm, init_state);
tracker->current_error = GRPC_ERROR_NONE;
tracker->watchers = nullptr;
tracker->name = gpr_strdup(name);
}
@ -69,7 +68,6 @@ void grpc_connectivity_state_destroy(grpc_connectivity_state_tracker* tracker) {
GRPC_CLOSURE_SCHED(w->notify, error);
gpr_free(w);
}
GRPC_ERROR_UNREF(tracker->current_error);
gpr_free(tracker->name);
}
@ -84,20 +82,6 @@ grpc_connectivity_state grpc_connectivity_state_check(
return cur;
}
grpc_connectivity_state grpc_connectivity_state_get(
grpc_connectivity_state_tracker* tracker, grpc_error** error) {
grpc_connectivity_state cur = static_cast<grpc_connectivity_state>(
gpr_atm_no_barrier_load(&tracker->current_state_atm));
if (grpc_connectivity_state_trace.enabled()) {
gpr_log(GPR_INFO, "CONWATCH: %p %s: get %s", tracker, tracker->name,
grpc_connectivity_state_name(cur));
}
if (error != nullptr) {
*error = GRPC_ERROR_REF(tracker->current_error);
}
return cur;
}
bool grpc_connectivity_state_has_watchers(
grpc_connectivity_state_tracker* connectivity_state) {
return connectivity_state->watchers != nullptr;
@ -140,7 +124,7 @@ bool grpc_connectivity_state_notify_on_state_change(
} else {
if (cur != *current) {
*current = cur;
GRPC_CLOSURE_SCHED(notify, GRPC_ERROR_REF(tracker->current_error));
GRPC_CLOSURE_SCHED(notify, GRPC_ERROR_NONE);
} else {
grpc_connectivity_state_watcher* w =
static_cast<grpc_connectivity_state_watcher*>(gpr_malloc(sizeof(*w)));
@ -155,29 +139,15 @@ bool grpc_connectivity_state_notify_on_state_change(
void grpc_connectivity_state_set(grpc_connectivity_state_tracker* tracker,
grpc_connectivity_state state,
grpc_error* error, const char* reason) {
const char* reason) {
grpc_connectivity_state cur = static_cast<grpc_connectivity_state>(
gpr_atm_no_barrier_load(&tracker->current_state_atm));
grpc_connectivity_state_watcher* w;
if (grpc_connectivity_state_trace.enabled()) {
const char* error_string = grpc_error_string(error);
gpr_log(GPR_INFO, "SET: %p %s: %s --> %s [%s] error=%p %s", tracker,
tracker->name, grpc_connectivity_state_name(cur),
grpc_connectivity_state_name(state), reason, error, error_string);
}
switch (state) {
case GRPC_CHANNEL_CONNECTING:
case GRPC_CHANNEL_IDLE:
case GRPC_CHANNEL_READY:
GPR_ASSERT(error == GRPC_ERROR_NONE);
break;
case GRPC_CHANNEL_SHUTDOWN:
case GRPC_CHANNEL_TRANSIENT_FAILURE:
GPR_ASSERT(error != GRPC_ERROR_NONE);
break;
gpr_log(GPR_INFO, "SET: %p %s: %s --> %s [%s]", tracker, tracker->name,
grpc_connectivity_state_name(cur),
grpc_connectivity_state_name(state), reason);
}
GRPC_ERROR_UNREF(tracker->current_error);
tracker->current_error = error;
if (cur == state) {
return;
}
@ -189,7 +159,7 @@ void grpc_connectivity_state_set(grpc_connectivity_state_tracker* tracker,
if (grpc_connectivity_state_trace.enabled()) {
gpr_log(GPR_INFO, "NOTIFY: %p %s: %p", tracker, tracker->name, w->notify);
}
GRPC_CLOSURE_SCHED(w->notify, GRPC_ERROR_REF(tracker->current_error));
GRPC_CLOSURE_SCHED(w->notify, GRPC_ERROR_NONE);
gpr_free(w);
}
}

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

Loading…
Cancel
Save