Merge branch 'master' into callback-offload-only-not-bg-poller

pull/19406/head
Karthik Ravi Shankar 6 years ago
commit 7461407ad0
  1. 3
      .gitignore
  2. 108
      BUILD
  3. 23
      BUILD.gn
  4. 471
      CMakeLists.txt
  5. 408
      Makefile
  6. 4
      Rakefile
  7. 2
      WORKSPACE
  8. 2
      bazel/cc_grpc_library.bzl
  9. 6
      bazel/generate_cc.bzl
  10. 34
      bazel/grpc_deps.bzl
  11. 8
      bazel/python_rules.bzl
  12. 97
      build.yaml
  13. 4
      config.m4
  14. 4
      config.w32
  15. 6
      doc/core/moving-to-c++.md
  16. 2
      doc/statuscodes.md
  17. 41
      doc/versioning.md
  18. 2
      examples/cpp/helloworld/CMakeLists.txt
  19. 2
      examples/cpp/helloworld/cmake_externalproject/CMakeLists.txt
  20. 65
      examples/python/auth/BUILD.bazel
  21. 112
      examples/python/auth/README.md
  22. 31
      examples/python/auth/_credentials.py
  23. 19
      examples/python/auth/credentials/localhost.crt
  24. 27
      examples/python/auth/credentials/localhost.key
  25. 20
      examples/python/auth/credentials/root.crt
  26. 105
      examples/python/auth/customized_auth_client.py
  27. 110
      examples/python/auth/customized_auth_server.py
  28. 56
      examples/python/auth/test/_auth_example_test.py
  29. 44
      examples/python/compression/BUILD.bazel
  30. 58
      examples/python/compression/README.md
  31. 76
      examples/python/compression/client.py
  32. 109
      examples/python/compression/server.py
  33. 62
      examples/python/compression/test/compression_example_test.py
  34. 4
      examples/python/multiprocessing/BUILD
  35. 2
      examples/python/multiprocessing/server.py
  36. 19
      gRPC-C++.podspec
  37. 16
      gRPC-Core.podspec
  38. 1
      grpc.def
  39. 9
      grpc.gemspec
  40. 6
      grpc.gyp
  41. 25
      include/grpc/grpc_security.h
  42. 13
      include/grpcpp/channel_impl.h
  43. 24
      include/grpcpp/completion_queue_impl.h
  44. 42
      include/grpcpp/generic/generic_stub_impl.h
  45. 32
      include/grpcpp/impl/codegen/async_generic_service.h
  46. 1099
      include/grpcpp/impl/codegen/async_stream.h
  47. 1134
      include/grpcpp/impl/codegen/async_stream_impl.h
  48. 290
      include/grpcpp/impl/codegen/async_unary_call.h
  49. 315
      include/grpcpp/impl/codegen/async_unary_call_impl.h
  50. 19
      include/grpcpp/impl/codegen/byte_buffer.h
  51. 10
      include/grpcpp/impl/codegen/call_op_set.h
  52. 47
      include/grpcpp/impl/codegen/channel_interface.h
  53. 1005
      include/grpcpp/impl/codegen/client_callback.h
  54. 1067
      include/grpcpp/impl/codegen/client_callback_impl.h
  55. 52
      include/grpcpp/impl/codegen/client_context_impl.h
  56. 4
      include/grpcpp/impl/codegen/client_unary_call.h
  57. 17
      include/grpcpp/impl/codegen/completion_queue_impl.h
  58. 2
      include/grpcpp/impl/codegen/intercepted_channel.h
  59. 39
      include/grpcpp/impl/codegen/method_handler_impl.h
  60. 1127
      include/grpcpp/impl/codegen/server_callback.h
  61. 1186
      include/grpcpp/impl/codegen/server_callback_impl.h
  62. 54
      include/grpcpp/impl/codegen/server_context_impl.h
  63. 3
      include/grpcpp/impl/codegen/server_interface.h
  64. 20
      include/grpcpp/impl/codegen/service_type.h
  65. 898
      include/grpcpp/impl/codegen/sync_stream.h
  66. 944
      include/grpcpp/impl/codegen/sync_stream_impl.h
  67. 4
      include/grpcpp/impl/server_builder_plugin.h
  68. 19
      include/grpcpp/security/credentials.h
  69. 92
      include/grpcpp/security/credentials_impl.h
  70. 49
      include/grpcpp/server_impl.h
  71. 24
      include/grpcpp/support/async_stream_impl.h
  72. 24
      include/grpcpp/support/async_unary_call_impl.h
  73. 24
      include/grpcpp/support/client_callback_impl.h
  74. 24
      include/grpcpp/support/server_callback_impl.h
  75. 24
      include/grpcpp/support/sync_stream_impl.h
  76. 7
      package.xml
  77. 120
      src/compiler/BUILD
  78. 30
      src/compiler/config.h
  79. 52
      src/compiler/config_protobuf.h
  80. 126
      src/compiler/cpp_generator.cc
  81. 6
      src/core/ext/filters/client_channel/backup_poller.cc
  82. 110
      src/core/ext/filters/client_channel/client_channel.cc
  83. 25
      src/core/ext/filters/client_channel/client_channel_channelz.cc
  84. 17
      src/core/ext/filters/client_channel/client_channel_channelz.h
  85. 6
      src/core/ext/filters/client_channel/health/health_check_client.cc
  86. 19
      src/core/ext/filters/client_channel/http_proxy.cc
  87. 1
      src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc
  88. 119
      src/core/ext/filters/client_channel/lb_policy/pick_first/pick_first.cc
  89. 1
      src/core/ext/filters/client_channel/lb_policy/xds/xds.cc
  90. 55
      src/core/ext/filters/client_channel/parse_address.cc
  91. 8
      src/core/ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.cc
  92. 487
      src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_windows.cc
  93. 95
      src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.cc
  94. 1
      src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv.cc
  95. 1
      src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_windows.cc
  96. 17
      src/core/ext/filters/client_channel/resolver/dns/native/dns_resolver.cc
  97. 12
      src/core/ext/filters/client_channel/resolver/fake/fake_resolver.cc
  98. 45
      src/core/ext/filters/client_channel/resolver/sockaddr/sockaddr_resolver.cc
  99. 4
      src/core/ext/filters/client_channel/resolver_factory.h
  100. 11
      src/core/ext/filters/client_channel/resolver_registry.cc
  101. Some files were not shown because too many files have changed in this diff Show More

3
.gitignore vendored

@ -146,3 +146,6 @@ bm_*.json
# Clion artifacts
cmake-build-debug/
# Benchmark outputs
BenchmarkDotNet.Artifacts/

108
BUILD

@ -30,7 +30,6 @@ load(
"//bazel:grpc_build_system.bzl",
"grpc_cc_library",
"grpc_generate_one_off_targets",
"grpc_proto_plugin",
)
config_setting(
@ -222,6 +221,7 @@ GRPCXX_PUBLIC_HDRS = [
"include/grpcpp/channel_impl.h",
"include/grpcpp/client_context.h",
"include/grpcpp/completion_queue.h",
"include/grpcpp/completion_queue_impl.h",
"include/grpcpp/create_channel.h",
"include/grpcpp/create_channel_impl.h",
"include/grpcpp/create_channel_posix.h",
@ -267,11 +267,14 @@ GRPCXX_PUBLIC_HDRS = [
"include/grpcpp/server_posix.h",
"include/grpcpp/server_posix_impl.h",
"include/grpcpp/support/async_stream.h",
"include/grpcpp/support/async_stream_impl.h",
"include/grpcpp/support/async_unary_call.h",
"include/grpcpp/support/async_unary_call_impl.h",
"include/grpcpp/support/byte_buffer.h",
"include/grpcpp/support/channel_arguments.h",
"include/grpcpp/support/channel_arguments_impl.h",
"include/grpcpp/support/client_callback.h",
"include/grpcpp/support/client_callback_impl.h",
"include/grpcpp/support/client_interceptor.h",
"include/grpcpp/support/config.h",
"include/grpcpp/support/interceptor.h",
@ -279,6 +282,7 @@ GRPCXX_PUBLIC_HDRS = [
"include/grpcpp/support/proto_buffer_reader.h",
"include/grpcpp/support/proto_buffer_writer.h",
"include/grpcpp/support/server_callback.h",
"include/grpcpp/support/server_callback_impl.h",
"include/grpcpp/support/server_interceptor.h",
"include/grpcpp/support/slice.h",
"include/grpcpp/support/status.h",
@ -286,6 +290,7 @@ GRPCXX_PUBLIC_HDRS = [
"include/grpcpp/support/string_ref.h",
"include/grpcpp/support/stub_options.h",
"include/grpcpp/support/sync_stream.h",
"include/grpcpp/support/sync_stream_impl.h",
"include/grpcpp/support/time.h",
"include/grpcpp/support/validate_service_config.h",
]
@ -423,92 +428,6 @@ grpc_cc_library(
],
)
grpc_cc_library(
name = "grpc_plugin_support",
srcs = [
"src/compiler/cpp_generator.cc",
"src/compiler/csharp_generator.cc",
"src/compiler/node_generator.cc",
"src/compiler/objective_c_generator.cc",
"src/compiler/php_generator.cc",
"src/compiler/python_generator.cc",
"src/compiler/ruby_generator.cc",
],
hdrs = [
"src/compiler/config.h",
"src/compiler/cpp_generator.h",
"src/compiler/cpp_generator_helpers.h",
"src/compiler/cpp_plugin.h",
"src/compiler/csharp_generator.h",
"src/compiler/csharp_generator_helpers.h",
"src/compiler/generator_helpers.h",
"src/compiler/node_generator.h",
"src/compiler/node_generator_helpers.h",
"src/compiler/objective_c_generator.h",
"src/compiler/objective_c_generator_helpers.h",
"src/compiler/php_generator.h",
"src/compiler/php_generator_helpers.h",
"src/compiler/protobuf_plugin.h",
"src/compiler/python_generator.h",
"src/compiler/python_generator_helpers.h",
"src/compiler/python_private_generator.h",
"src/compiler/ruby_generator.h",
"src/compiler/ruby_generator_helpers-inl.h",
"src/compiler/ruby_generator_map-inl.h",
"src/compiler/ruby_generator_string-inl.h",
"src/compiler/schema_interface.h",
],
external_deps = [
"protobuf_clib",
],
language = "c++",
deps = [
"grpc++_config_proto",
],
)
grpc_proto_plugin(
name = "grpc_cpp_plugin",
srcs = ["src/compiler/cpp_plugin.cc"],
deps = [":grpc_plugin_support"],
)
grpc_proto_plugin(
name = "grpc_csharp_plugin",
srcs = ["src/compiler/csharp_plugin.cc"],
deps = [":grpc_plugin_support"],
)
grpc_proto_plugin(
name = "grpc_node_plugin",
srcs = ["src/compiler/node_plugin.cc"],
deps = [":grpc_plugin_support"],
)
grpc_proto_plugin(
name = "grpc_objective_c_plugin",
srcs = ["src/compiler/objective_c_plugin.cc"],
deps = [":grpc_plugin_support"],
)
grpc_proto_plugin(
name = "grpc_php_plugin",
srcs = ["src/compiler/php_plugin.cc"],
deps = [":grpc_plugin_support"],
)
grpc_proto_plugin(
name = "grpc_python_plugin",
srcs = ["src/compiler/python_plugin.cc"],
deps = [":grpc_plugin_support"],
)
grpc_proto_plugin(
name = "grpc_ruby_plugin",
srcs = ["src/compiler/ruby_plugin.cc"],
deps = [":grpc_plugin_support"],
)
grpc_cc_library(
name = "grpc_csharp_ext",
srcs = [
@ -558,7 +477,6 @@ grpc_cc_library(
"src/core/lib/gpr/env_linux.cc",
"src/core/lib/gpr/env_posix.cc",
"src/core/lib/gpr/env_windows.cc",
"src/core/lib/gpr/host_port.cc",
"src/core/lib/gpr/log.cc",
"src/core/lib/gpr/log_android.cc",
"src/core/lib/gpr/log_linux.cc",
@ -585,6 +503,7 @@ grpc_cc_library(
"src/core/lib/gprpp/arena.cc",
"src/core/lib/gprpp/fork.cc",
"src/core/lib/gprpp/global_config_env.cc",
"src/core/lib/gprpp/host_port.cc",
"src/core/lib/gprpp/thd_posix.cc",
"src/core/lib/gprpp/thd_windows.cc",
"src/core/lib/profiling/basic_timers.cc",
@ -594,7 +513,6 @@ grpc_cc_library(
"src/core/lib/gpr/alloc.h",
"src/core/lib/gpr/arena.h",
"src/core/lib/gpr/env.h",
"src/core/lib/gpr/host_port.h",
"src/core/lib/gpr/mpscq.h",
"src/core/lib/gpr/murmur_hash.h",
"src/core/lib/gpr/spinlock.h",
@ -611,14 +529,16 @@ grpc_cc_library(
"src/core/lib/gprpp/arena.h",
"src/core/lib/gprpp/atomic.h",
"src/core/lib/gprpp/fork.h",
"src/core/lib/gprpp/global_config.h",
"src/core/lib/gprpp/global_config_custom.h",
"src/core/lib/gprpp/global_config_env.h",
"src/core/lib/gprpp/global_config_generic.h",
"src/core/lib/gprpp/global_config.h",
"src/core/lib/gprpp/host_port.h",
"src/core/lib/gprpp/manual_constructor.h",
"src/core/lib/gprpp/map.h",
"src/core/lib/gprpp/memory.h",
"src/core/lib/gprpp/pair.h",
"src/core/lib/gprpp/string_view.h",
"src/core/lib/gprpp/sync.h",
"src/core/lib/gprpp/thd.h",
"src/core/lib/profiling/timers.h",
@ -627,6 +547,7 @@ grpc_cc_library(
public_hdrs = GPR_PUBLIC_HDRS,
deps = [
"gpr_codegen",
"grpc_codegen",
],
)
@ -782,6 +703,7 @@ grpc_cc_library(
"src/core/lib/iomgr/ev_windows.cc",
"src/core/lib/iomgr/exec_ctx.cc",
"src/core/lib/iomgr/executor.cc",
"src/core/lib/iomgr/executor/mpmcqueue.cc",
"src/core/lib/iomgr/fork_posix.cc",
"src/core/lib/iomgr/fork_windows.cc",
"src/core/lib/iomgr/gethostname_fallback.cc",
@ -939,6 +861,7 @@ grpc_cc_library(
"src/core/lib/iomgr/ev_posix.h",
"src/core/lib/iomgr/exec_ctx.h",
"src/core/lib/iomgr/executor.h",
"src/core/lib/iomgr/executor/mpmcqueue.h",
"src/core/lib/iomgr/gethostname.h",
"src/core/lib/iomgr/gevent_util.h",
"src/core/lib/iomgr/grpc_if_nametoindex.h",
@ -2154,7 +2077,9 @@ grpc_cc_library(
"include/grpc++/impl/codegen/time.h",
"include/grpcpp/impl/codegen/async_generic_service.h",
"include/grpcpp/impl/codegen/async_stream.h",
"include/grpcpp/impl/codegen/async_stream_impl.h",
"include/grpcpp/impl/codegen/async_unary_call.h",
"include/grpcpp/impl/codegen/async_unary_call_impl.h",
"include/grpcpp/impl/codegen/byte_buffer.h",
"include/grpcpp/impl/codegen/call.h",
"include/grpcpp/impl/codegen/call_hook.h",
@ -2163,6 +2088,7 @@ grpc_cc_library(
"include/grpcpp/impl/codegen/callback_common.h",
"include/grpcpp/impl/codegen/channel_interface.h",
"include/grpcpp/impl/codegen/client_callback.h",
"include/grpcpp/impl/codegen/client_callback_impl.h",
"include/grpcpp/impl/codegen/client_context.h",
"include/grpcpp/impl/codegen/client_context_impl.h",
"include/grpcpp/impl/codegen/client_interceptor.h",
@ -2185,6 +2111,7 @@ grpc_cc_library(
"include/grpcpp/impl/codegen/security/auth_context.h",
"include/grpcpp/impl/codegen/serialization_traits.h",
"include/grpcpp/impl/codegen/server_callback.h",
"include/grpcpp/impl/codegen/server_callback_impl.h",
"include/grpcpp/impl/codegen/server_context.h",
"include/grpcpp/impl/codegen/server_context_impl.h",
"include/grpcpp/impl/codegen/server_interceptor.h",
@ -2196,6 +2123,7 @@ grpc_cc_library(
"include/grpcpp/impl/codegen/string_ref.h",
"include/grpcpp/impl/codegen/stub_options.h",
"include/grpcpp/impl/codegen/sync_stream.h",
"include/grpcpp/impl/codegen/sync_stream_impl.h",
"include/grpcpp/impl/codegen/time.h",
],
deps = [

@ -141,8 +141,6 @@ config("grpc_config") {
"src/core/lib/gpr/env_linux.cc",
"src/core/lib/gpr/env_posix.cc",
"src/core/lib/gpr/env_windows.cc",
"src/core/lib/gpr/host_port.cc",
"src/core/lib/gpr/host_port.h",
"src/core/lib/gpr/log.cc",
"src/core/lib/gpr/log_android.cc",
"src/core/lib/gpr/log_linux.cc",
@ -189,6 +187,8 @@ config("grpc_config") {
"src/core/lib/gprpp/global_config_env.cc",
"src/core/lib/gprpp/global_config_env.h",
"src/core/lib/gprpp/global_config_generic.h",
"src/core/lib/gprpp/host_port.cc",
"src/core/lib/gprpp/host_port.h",
"src/core/lib/gprpp/manual_constructor.h",
"src/core/lib/gprpp/map.h",
"src/core/lib/gprpp/memory.h",
@ -480,6 +480,7 @@ config("grpc_config") {
"src/core/lib/gprpp/orphanable.h",
"src/core/lib/gprpp/ref_counted.h",
"src/core/lib/gprpp/ref_counted_ptr.h",
"src/core/lib/gprpp/string_view.h",
"src/core/lib/http/format_request.cc",
"src/core/lib/http/format_request.h",
"src/core/lib/http/httpcli.cc",
@ -524,6 +525,8 @@ config("grpc_config") {
"src/core/lib/iomgr/exec_ctx.h",
"src/core/lib/iomgr/executor.cc",
"src/core/lib/iomgr/executor.h",
"src/core/lib/iomgr/executor/mpmcqueue.cc",
"src/core/lib/iomgr/executor/mpmcqueue.h",
"src/core/lib/iomgr/fork_posix.cc",
"src/core/lib/iomgr/fork_windows.cc",
"src/core/lib/iomgr/gethostname.h",
@ -1028,6 +1031,7 @@ config("grpc_config") {
"include/grpcpp/channel_impl.h",
"include/grpcpp/client_context.h",
"include/grpcpp/completion_queue.h",
"include/grpcpp/completion_queue_impl.h",
"include/grpcpp/create_channel.h",
"include/grpcpp/create_channel_impl.h",
"include/grpcpp/create_channel_posix.h",
@ -1044,7 +1048,9 @@ config("grpc_config") {
"include/grpcpp/impl/client_unary_call.h",
"include/grpcpp/impl/codegen/async_generic_service.h",
"include/grpcpp/impl/codegen/async_stream.h",
"include/grpcpp/impl/codegen/async_stream_impl.h",
"include/grpcpp/impl/codegen/async_unary_call.h",
"include/grpcpp/impl/codegen/async_unary_call_impl.h",
"include/grpcpp/impl/codegen/byte_buffer.h",
"include/grpcpp/impl/codegen/call.h",
"include/grpcpp/impl/codegen/call_hook.h",
@ -1053,6 +1059,7 @@ config("grpc_config") {
"include/grpcpp/impl/codegen/callback_common.h",
"include/grpcpp/impl/codegen/channel_interface.h",
"include/grpcpp/impl/codegen/client_callback.h",
"include/grpcpp/impl/codegen/client_callback_impl.h",
"include/grpcpp/impl/codegen/client_context.h",
"include/grpcpp/impl/codegen/client_context_impl.h",
"include/grpcpp/impl/codegen/client_interceptor.h",
@ -1081,6 +1088,7 @@ config("grpc_config") {
"include/grpcpp/impl/codegen/security/auth_context.h",
"include/grpcpp/impl/codegen/serialization_traits.h",
"include/grpcpp/impl/codegen/server_callback.h",
"include/grpcpp/impl/codegen/server_callback_impl.h",
"include/grpcpp/impl/codegen/server_context.h",
"include/grpcpp/impl/codegen/server_context_impl.h",
"include/grpcpp/impl/codegen/server_interceptor.h",
@ -1093,6 +1101,7 @@ config("grpc_config") {
"include/grpcpp/impl/codegen/stub_options.h",
"include/grpcpp/impl/codegen/sync.h",
"include/grpcpp/impl/codegen/sync_stream.h",
"include/grpcpp/impl/codegen/sync_stream_impl.h",
"include/grpcpp/impl/codegen/time.h",
"include/grpcpp/impl/grpc_library.h",
"include/grpcpp/impl/method_handler_impl.h",
@ -1122,11 +1131,14 @@ config("grpc_config") {
"include/grpcpp/server_posix.h",
"include/grpcpp/server_posix_impl.h",
"include/grpcpp/support/async_stream.h",
"include/grpcpp/support/async_stream_impl.h",
"include/grpcpp/support/async_unary_call.h",
"include/grpcpp/support/async_unary_call_impl.h",
"include/grpcpp/support/byte_buffer.h",
"include/grpcpp/support/channel_arguments.h",
"include/grpcpp/support/channel_arguments_impl.h",
"include/grpcpp/support/client_callback.h",
"include/grpcpp/support/client_callback_impl.h",
"include/grpcpp/support/client_interceptor.h",
"include/grpcpp/support/config.h",
"include/grpcpp/support/interceptor.h",
@ -1134,6 +1146,7 @@ config("grpc_config") {
"include/grpcpp/support/proto_buffer_reader.h",
"include/grpcpp/support/proto_buffer_writer.h",
"include/grpcpp/support/server_callback.h",
"include/grpcpp/support/server_callback_impl.h",
"include/grpcpp/support/server_interceptor.h",
"include/grpcpp/support/slice.h",
"include/grpcpp/support/status.h",
@ -1141,6 +1154,7 @@ config("grpc_config") {
"include/grpcpp/support/string_ref.h",
"include/grpcpp/support/stub_options.h",
"include/grpcpp/support/sync_stream.h",
"include/grpcpp/support/sync_stream_impl.h",
"include/grpcpp/support/time.h",
"include/grpcpp/support/validate_service_config.h",
"src/core/ext/transport/inproc/inproc_transport.h",
@ -1171,7 +1185,6 @@ config("grpc_config") {
"src/core/lib/gpr/alloc.h",
"src/core/lib/gpr/arena.h",
"src/core/lib/gpr/env.h",
"src/core/lib/gpr/host_port.h",
"src/core/lib/gpr/mpscq.h",
"src/core/lib/gpr/murmur_hash.h",
"src/core/lib/gpr/spinlock.h",
@ -1193,6 +1206,7 @@ config("grpc_config") {
"src/core/lib/gprpp/global_config_custom.h",
"src/core/lib/gprpp/global_config_env.h",
"src/core/lib/gprpp/global_config_generic.h",
"src/core/lib/gprpp/host_port.h",
"src/core/lib/gprpp/inlined_vector.h",
"src/core/lib/gprpp/manual_constructor.h",
"src/core/lib/gprpp/map.h",
@ -1202,6 +1216,7 @@ config("grpc_config") {
"src/core/lib/gprpp/pair.h",
"src/core/lib/gprpp/ref_counted.h",
"src/core/lib/gprpp/ref_counted_ptr.h",
"src/core/lib/gprpp/string_view.h",
"src/core/lib/gprpp/sync.h",
"src/core/lib/gprpp/thd.h",
"src/core/lib/http/format_request.h",
@ -1226,6 +1241,7 @@ config("grpc_config") {
"src/core/lib/iomgr/ev_posix.h",
"src/core/lib/iomgr/exec_ctx.h",
"src/core/lib/iomgr/executor.h",
"src/core/lib/iomgr/executor/mpmcqueue.h",
"src/core/lib/iomgr/gethostname.h",
"src/core/lib/iomgr/grpc_if_nametoindex.h",
"src/core/lib/iomgr/internal_errqueue.h",
@ -1397,6 +1413,7 @@ config("grpc_config") {
"include/grpc++/impl/codegen/config_protobuf.h",
"include/grpcpp/impl/codegen/config_protobuf.h",
"src/compiler/config.h",
"src/compiler/config_protobuf.h",
"src/compiler/cpp_generator.cc",
"src/compiler/cpp_generator.h",
"src/compiler/cpp_generator_helpers.h",

@ -21,7 +21,7 @@
cmake_minimum_required(VERSION 2.8)
cmake_minimum_required(VERSION 3.5.1)
set(PACKAGE_NAME "grpc")
set(PACKAGE_VERSION "1.23.0-dev")
@ -275,7 +275,8 @@ add_dependencies(buildtests_c compression_test)
add_dependencies(buildtests_c concurrent_connectivity_test)
add_dependencies(buildtests_c connection_refused_test)
add_dependencies(buildtests_c dns_resolver_connectivity_test)
add_dependencies(buildtests_c dns_resolver_cooldown_test)
add_dependencies(buildtests_c dns_resolver_cooldown_using_ares_resolver_test)
add_dependencies(buildtests_c dns_resolver_cooldown_using_native_resolver_test)
add_dependencies(buildtests_c dns_resolver_test)
if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX)
add_dependencies(buildtests_c dualstack_socket_test)
@ -331,7 +332,6 @@ add_dependencies(buildtests_c grpc_channel_stack_test)
add_dependencies(buildtests_c grpc_completion_queue_test)
add_dependencies(buildtests_c grpc_completion_queue_threading_test)
add_dependencies(buildtests_c grpc_credentials_test)
add_dependencies(buildtests_c grpc_fetch_oauth2)
add_dependencies(buildtests_c grpc_ipv6_loopback_available_test)
if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX)
add_dependencies(buildtests_c grpc_json_token_test)
@ -378,6 +378,7 @@ add_dependencies(buildtests_c memory_usage_test)
endif()
add_dependencies(buildtests_c message_compress_test)
add_dependencies(buildtests_c minimal_stack_is_minimal_test)
add_dependencies(buildtests_c mpmcqueue_test)
add_dependencies(buildtests_c multiple_server_queues_test)
add_dependencies(buildtests_c murmur_hash_test)
add_dependencies(buildtests_c no_server_test)
@ -632,10 +633,14 @@ add_dependencies(buildtests_cxx golden_file_test)
add_dependencies(buildtests_cxx grpc_alts_credentials_options_test)
add_dependencies(buildtests_cxx grpc_cli)
add_dependencies(buildtests_cxx grpc_core_map_test)
add_dependencies(buildtests_cxx grpc_fetch_oauth2)
add_dependencies(buildtests_cxx grpc_linux_system_roots_test)
add_dependencies(buildtests_cxx grpc_tool_test)
add_dependencies(buildtests_cxx grpclb_api_test)
add_dependencies(buildtests_cxx grpclb_end2end_test)
if(_gRPC_PLATFORM_LINUX)
add_dependencies(buildtests_cxx grpclb_fallback_test)
endif()
add_dependencies(buildtests_cxx h2_ssl_cert_test)
add_dependencies(buildtests_cxx h2_ssl_session_reuse_test)
add_dependencies(buildtests_cxx health_service_end2end_test)
@ -713,6 +718,7 @@ if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX)
add_dependencies(buildtests_cxx streaming_throughput_test)
endif()
add_dependencies(buildtests_cxx stress_test)
add_dependencies(buildtests_cxx string_view_test)
add_dependencies(buildtests_cxx thread_manager_test)
add_dependencies(buildtests_cxx thread_stress_test)
if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX)
@ -724,6 +730,7 @@ if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX)
add_dependencies(buildtests_cxx writes_per_rpc_test)
endif()
add_dependencies(buildtests_cxx xds_end2end_test)
add_dependencies(buildtests_cxx bad_streaming_id_bad_client_test)
add_dependencies(buildtests_cxx badreq_bad_client_test)
add_dependencies(buildtests_cxx connection_prefix_bad_client_test)
add_dependencies(buildtests_cxx duplicate_header_bad_client_test)
@ -731,6 +738,7 @@ add_dependencies(buildtests_cxx head_of_line_blocking_bad_client_test)
add_dependencies(buildtests_cxx headers_bad_client_test)
add_dependencies(buildtests_cxx initial_settings_frame_bad_client_test)
add_dependencies(buildtests_cxx large_metadata_bad_client_test)
add_dependencies(buildtests_cxx out_of_bounds_bad_client_test)
add_dependencies(buildtests_cxx server_registered_method_bad_client_test)
add_dependencies(buildtests_cxx simple_request_bad_client_test)
add_dependencies(buildtests_cxx unknown_frame_bad_client_test)
@ -859,7 +867,6 @@ add_library(gpr
src/core/lib/gpr/env_linux.cc
src/core/lib/gpr/env_posix.cc
src/core/lib/gpr/env_windows.cc
src/core/lib/gpr/host_port.cc
src/core/lib/gpr/log.cc
src/core/lib/gpr/log_android.cc
src/core/lib/gpr/log_linux.cc
@ -886,6 +893,7 @@ add_library(gpr
src/core/lib/gprpp/arena.cc
src/core/lib/gprpp/fork.cc
src/core/lib/gprpp/global_config_env.cc
src/core/lib/gprpp/host_port.cc
src/core/lib/gprpp/thd_posix.cc
src/core/lib/gprpp/thd_windows.cc
src/core/lib/profiling/basic_timers.cc
@ -1026,6 +1034,7 @@ add_library(grpc
src/core/lib/iomgr/ev_windows.cc
src/core/lib/iomgr/exec_ctx.cc
src/core/lib/iomgr/executor.cc
src/core/lib/iomgr/executor/mpmcqueue.cc
src/core/lib/iomgr/fork_posix.cc
src/core/lib/iomgr/fork_windows.cc
src/core/lib/iomgr/gethostname_fallback.cc
@ -1361,6 +1370,9 @@ target_link_libraries(grpc
${_gRPC_ALLTARGETS_LIBRARIES}
gpr
)
if (_gRPC_PLATFORM_IOS OR _gRPC_PLATFORM_MAC)
target_link_libraries(grpc "-framework CoreFoundation")
endif()
foreach(_hdr
include/grpc/impl/codegen/byte_buffer.h
@ -1461,6 +1473,7 @@ add_library(grpc_cronet
src/core/lib/iomgr/ev_windows.cc
src/core/lib/iomgr/exec_ctx.cc
src/core/lib/iomgr/executor.cc
src/core/lib/iomgr/executor/mpmcqueue.cc
src/core/lib/iomgr/fork_posix.cc
src/core/lib/iomgr/fork_windows.cc
src/core/lib/iomgr/gethostname_fallback.cc
@ -1759,6 +1772,9 @@ target_link_libraries(grpc_cronet
${_gRPC_ALLTARGETS_LIBRARIES}
gpr
)
if (_gRPC_PLATFORM_IOS OR _gRPC_PLATFORM_MAC)
target_link_libraries(grpc_cronet "-framework CoreFoundation")
endif()
foreach(_hdr
include/grpc/impl/codegen/byte_buffer.h
@ -1878,6 +1894,7 @@ add_library(grpc_test_util
src/core/lib/iomgr/ev_windows.cc
src/core/lib/iomgr/exec_ctx.cc
src/core/lib/iomgr/executor.cc
src/core/lib/iomgr/executor/mpmcqueue.cc
src/core/lib/iomgr/fork_posix.cc
src/core/lib/iomgr/fork_windows.cc
src/core/lib/iomgr/gethostname_fallback.cc
@ -2088,6 +2105,9 @@ target_link_libraries(grpc_test_util
gpr
grpc
)
if (_gRPC_PLATFORM_IOS OR _gRPC_PLATFORM_MAC)
target_link_libraries(grpc_test_util "-framework CoreFoundation")
endif()
foreach(_hdr
include/grpc/support/alloc.h
@ -2208,6 +2228,7 @@ add_library(grpc_test_util_unsecure
src/core/lib/iomgr/ev_windows.cc
src/core/lib/iomgr/exec_ctx.cc
src/core/lib/iomgr/executor.cc
src/core/lib/iomgr/executor/mpmcqueue.cc
src/core/lib/iomgr/fork_posix.cc
src/core/lib/iomgr/fork_windows.cc
src/core/lib/iomgr/gethostname_fallback.cc
@ -2418,6 +2439,9 @@ target_link_libraries(grpc_test_util_unsecure
gpr
grpc_unsecure
)
if (_gRPC_PLATFORM_IOS OR _gRPC_PLATFORM_MAC)
target_link_libraries(grpc_test_util_unsecure "-framework CoreFoundation")
endif()
foreach(_hdr
include/grpc/support/alloc.h
@ -2514,6 +2538,7 @@ add_library(grpc_unsecure
src/core/lib/iomgr/ev_windows.cc
src/core/lib/iomgr/exec_ctx.cc
src/core/lib/iomgr/executor.cc
src/core/lib/iomgr/executor/mpmcqueue.cc
src/core/lib/iomgr/fork_posix.cc
src/core/lib/iomgr/fork_windows.cc
src/core/lib/iomgr/gethostname_fallback.cc
@ -2771,6 +2796,9 @@ target_link_libraries(grpc_unsecure
${_gRPC_ALLTARGETS_LIBRARIES}
gpr
)
if (_gRPC_PLATFORM_IOS OR _gRPC_PLATFORM_MAC)
target_link_libraries(grpc_unsecure "-framework CoreFoundation")
endif()
foreach(_hdr
include/grpc/impl/codegen/byte_buffer.h
@ -3158,6 +3186,7 @@ foreach(_hdr
include/grpcpp/channel_impl.h
include/grpcpp/client_context.h
include/grpcpp/completion_queue.h
include/grpcpp/completion_queue_impl.h
include/grpcpp/create_channel.h
include/grpcpp/create_channel_impl.h
include/grpcpp/create_channel_posix.h
@ -3201,11 +3230,14 @@ foreach(_hdr
include/grpcpp/server_posix.h
include/grpcpp/server_posix_impl.h
include/grpcpp/support/async_stream.h
include/grpcpp/support/async_stream_impl.h
include/grpcpp/support/async_unary_call.h
include/grpcpp/support/async_unary_call_impl.h
include/grpcpp/support/byte_buffer.h
include/grpcpp/support/channel_arguments.h
include/grpcpp/support/channel_arguments_impl.h
include/grpcpp/support/client_callback.h
include/grpcpp/support/client_callback_impl.h
include/grpcpp/support/client_interceptor.h
include/grpcpp/support/config.h
include/grpcpp/support/interceptor.h
@ -3213,6 +3245,7 @@ foreach(_hdr
include/grpcpp/support/proto_buffer_reader.h
include/grpcpp/support/proto_buffer_writer.h
include/grpcpp/support/server_callback.h
include/grpcpp/support/server_callback_impl.h
include/grpcpp/support/server_interceptor.h
include/grpcpp/support/slice.h
include/grpcpp/support/status.h
@ -3220,6 +3253,7 @@ foreach(_hdr
include/grpcpp/support/string_ref.h
include/grpcpp/support/stub_options.h
include/grpcpp/support/sync_stream.h
include/grpcpp/support/sync_stream_impl.h
include/grpcpp/support/time.h
include/grpcpp/support/validate_service_config.h
include/grpc/support/alloc.h
@ -3305,7 +3339,9 @@ foreach(_hdr
include/grpc++/impl/codegen/time.h
include/grpcpp/impl/codegen/async_generic_service.h
include/grpcpp/impl/codegen/async_stream.h
include/grpcpp/impl/codegen/async_stream_impl.h
include/grpcpp/impl/codegen/async_unary_call.h
include/grpcpp/impl/codegen/async_unary_call_impl.h
include/grpcpp/impl/codegen/byte_buffer.h
include/grpcpp/impl/codegen/call.h
include/grpcpp/impl/codegen/call_hook.h
@ -3314,6 +3350,7 @@ foreach(_hdr
include/grpcpp/impl/codegen/callback_common.h
include/grpcpp/impl/codegen/channel_interface.h
include/grpcpp/impl/codegen/client_callback.h
include/grpcpp/impl/codegen/client_callback_impl.h
include/grpcpp/impl/codegen/client_context.h
include/grpcpp/impl/codegen/client_context_impl.h
include/grpcpp/impl/codegen/client_interceptor.h
@ -3336,6 +3373,7 @@ foreach(_hdr
include/grpcpp/impl/codegen/security/auth_context.h
include/grpcpp/impl/codegen/serialization_traits.h
include/grpcpp/impl/codegen/server_callback.h
include/grpcpp/impl/codegen/server_callback_impl.h
include/grpcpp/impl/codegen/server_context.h
include/grpcpp/impl/codegen/server_context_impl.h
include/grpcpp/impl/codegen/server_interceptor.h
@ -3347,6 +3385,7 @@ foreach(_hdr
include/grpcpp/impl/codegen/string_ref.h
include/grpcpp/impl/codegen/stub_options.h
include/grpcpp/impl/codegen/sync_stream.h
include/grpcpp/impl/codegen/sync_stream_impl.h
include/grpcpp/impl/codegen/time.h
include/grpcpp/impl/codegen/sync.h
include/grpc++/impl/codegen/proto_utils.h
@ -3540,6 +3579,7 @@ add_library(grpc++_cronet
src/core/lib/iomgr/ev_windows.cc
src/core/lib/iomgr/exec_ctx.cc
src/core/lib/iomgr/executor.cc
src/core/lib/iomgr/executor/mpmcqueue.cc
src/core/lib/iomgr/fork_posix.cc
src/core/lib/iomgr/fork_windows.cc
src/core/lib/iomgr/gethostname_fallback.cc
@ -3726,6 +3766,9 @@ target_link_libraries(grpc++_cronet
grpc_cronet
grpc
)
if (_gRPC_PLATFORM_IOS OR _gRPC_PLATFORM_MAC)
target_link_libraries(grpc++_cronet "-framework CoreFoundation")
endif()
foreach(_hdr
include/grpc++/alarm.h
@ -3779,6 +3822,7 @@ foreach(_hdr
include/grpcpp/channel_impl.h
include/grpcpp/client_context.h
include/grpcpp/completion_queue.h
include/grpcpp/completion_queue_impl.h
include/grpcpp/create_channel.h
include/grpcpp/create_channel_impl.h
include/grpcpp/create_channel_posix.h
@ -3822,11 +3866,14 @@ foreach(_hdr
include/grpcpp/server_posix.h
include/grpcpp/server_posix_impl.h
include/grpcpp/support/async_stream.h
include/grpcpp/support/async_stream_impl.h
include/grpcpp/support/async_unary_call.h
include/grpcpp/support/async_unary_call_impl.h
include/grpcpp/support/byte_buffer.h
include/grpcpp/support/channel_arguments.h
include/grpcpp/support/channel_arguments_impl.h
include/grpcpp/support/client_callback.h
include/grpcpp/support/client_callback_impl.h
include/grpcpp/support/client_interceptor.h
include/grpcpp/support/config.h
include/grpcpp/support/interceptor.h
@ -3834,6 +3881,7 @@ foreach(_hdr
include/grpcpp/support/proto_buffer_reader.h
include/grpcpp/support/proto_buffer_writer.h
include/grpcpp/support/server_callback.h
include/grpcpp/support/server_callback_impl.h
include/grpcpp/support/server_interceptor.h
include/grpcpp/support/slice.h
include/grpcpp/support/status.h
@ -3841,6 +3889,7 @@ foreach(_hdr
include/grpcpp/support/string_ref.h
include/grpcpp/support/stub_options.h
include/grpcpp/support/sync_stream.h
include/grpcpp/support/sync_stream_impl.h
include/grpcpp/support/time.h
include/grpcpp/support/validate_service_config.h
include/grpc/support/alloc.h
@ -3926,7 +3975,9 @@ foreach(_hdr
include/grpc++/impl/codegen/time.h
include/grpcpp/impl/codegen/async_generic_service.h
include/grpcpp/impl/codegen/async_stream.h
include/grpcpp/impl/codegen/async_stream_impl.h
include/grpcpp/impl/codegen/async_unary_call.h
include/grpcpp/impl/codegen/async_unary_call_impl.h
include/grpcpp/impl/codegen/byte_buffer.h
include/grpcpp/impl/codegen/call.h
include/grpcpp/impl/codegen/call_hook.h
@ -3935,6 +3986,7 @@ foreach(_hdr
include/grpcpp/impl/codegen/callback_common.h
include/grpcpp/impl/codegen/channel_interface.h
include/grpcpp/impl/codegen/client_callback.h
include/grpcpp/impl/codegen/client_callback_impl.h
include/grpcpp/impl/codegen/client_context.h
include/grpcpp/impl/codegen/client_context_impl.h
include/grpcpp/impl/codegen/client_interceptor.h
@ -3957,6 +4009,7 @@ foreach(_hdr
include/grpcpp/impl/codegen/security/auth_context.h
include/grpcpp/impl/codegen/serialization_traits.h
include/grpcpp/impl/codegen/server_callback.h
include/grpcpp/impl/codegen/server_callback_impl.h
include/grpcpp/impl/codegen/server_context.h
include/grpcpp/impl/codegen/server_context_impl.h
include/grpcpp/impl/codegen/server_interceptor.h
@ -3968,6 +4021,7 @@ foreach(_hdr
include/grpcpp/impl/codegen/string_ref.h
include/grpcpp/impl/codegen/stub_options.h
include/grpcpp/impl/codegen/sync_stream.h
include/grpcpp/impl/codegen/sync_stream_impl.h
include/grpcpp/impl/codegen/time.h
include/grpcpp/impl/codegen/sync.h
include/grpc/census.h
@ -4363,7 +4417,9 @@ foreach(_hdr
include/grpc++/impl/codegen/time.h
include/grpcpp/impl/codegen/async_generic_service.h
include/grpcpp/impl/codegen/async_stream.h
include/grpcpp/impl/codegen/async_stream_impl.h
include/grpcpp/impl/codegen/async_unary_call.h
include/grpcpp/impl/codegen/async_unary_call_impl.h
include/grpcpp/impl/codegen/byte_buffer.h
include/grpcpp/impl/codegen/call.h
include/grpcpp/impl/codegen/call_hook.h
@ -4372,6 +4428,7 @@ foreach(_hdr
include/grpcpp/impl/codegen/callback_common.h
include/grpcpp/impl/codegen/channel_interface.h
include/grpcpp/impl/codegen/client_callback.h
include/grpcpp/impl/codegen/client_callback_impl.h
include/grpcpp/impl/codegen/client_context.h
include/grpcpp/impl/codegen/client_context_impl.h
include/grpcpp/impl/codegen/client_interceptor.h
@ -4394,6 +4451,7 @@ foreach(_hdr
include/grpcpp/impl/codegen/security/auth_context.h
include/grpcpp/impl/codegen/serialization_traits.h
include/grpcpp/impl/codegen/server_callback.h
include/grpcpp/impl/codegen/server_callback_impl.h
include/grpcpp/impl/codegen/server_context.h
include/grpcpp/impl/codegen/server_context_impl.h
include/grpcpp/impl/codegen/server_interceptor.h
@ -4405,6 +4463,7 @@ foreach(_hdr
include/grpcpp/impl/codegen/string_ref.h
include/grpcpp/impl/codegen/stub_options.h
include/grpcpp/impl/codegen/sync_stream.h
include/grpcpp/impl/codegen/sync_stream_impl.h
include/grpcpp/impl/codegen/time.h
include/grpc/impl/codegen/byte_buffer.h
include/grpc/impl/codegen/byte_buffer_reader.h
@ -4564,7 +4623,9 @@ foreach(_hdr
include/grpc++/impl/codegen/time.h
include/grpcpp/impl/codegen/async_generic_service.h
include/grpcpp/impl/codegen/async_stream.h
include/grpcpp/impl/codegen/async_stream_impl.h
include/grpcpp/impl/codegen/async_unary_call.h
include/grpcpp/impl/codegen/async_unary_call_impl.h
include/grpcpp/impl/codegen/byte_buffer.h
include/grpcpp/impl/codegen/call.h
include/grpcpp/impl/codegen/call_hook.h
@ -4573,6 +4634,7 @@ foreach(_hdr
include/grpcpp/impl/codegen/callback_common.h
include/grpcpp/impl/codegen/channel_interface.h
include/grpcpp/impl/codegen/client_callback.h
include/grpcpp/impl/codegen/client_callback_impl.h
include/grpcpp/impl/codegen/client_context.h
include/grpcpp/impl/codegen/client_context_impl.h
include/grpcpp/impl/codegen/client_interceptor.h
@ -4595,6 +4657,7 @@ foreach(_hdr
include/grpcpp/impl/codegen/security/auth_context.h
include/grpcpp/impl/codegen/serialization_traits.h
include/grpcpp/impl/codegen/server_callback.h
include/grpcpp/impl/codegen/server_callback_impl.h
include/grpcpp/impl/codegen/server_context.h
include/grpcpp/impl/codegen/server_context_impl.h
include/grpcpp/impl/codegen/server_interceptor.h
@ -4606,6 +4669,7 @@ foreach(_hdr
include/grpcpp/impl/codegen/string_ref.h
include/grpcpp/impl/codegen/stub_options.h
include/grpcpp/impl/codegen/sync_stream.h
include/grpcpp/impl/codegen/sync_stream_impl.h
include/grpcpp/impl/codegen/time.h
include/grpc/impl/codegen/byte_buffer.h
include/grpc/impl/codegen/byte_buffer_reader.h
@ -4778,6 +4842,7 @@ foreach(_hdr
include/grpcpp/channel_impl.h
include/grpcpp/client_context.h
include/grpcpp/completion_queue.h
include/grpcpp/completion_queue_impl.h
include/grpcpp/create_channel.h
include/grpcpp/create_channel_impl.h
include/grpcpp/create_channel_posix.h
@ -4821,11 +4886,14 @@ foreach(_hdr
include/grpcpp/server_posix.h
include/grpcpp/server_posix_impl.h
include/grpcpp/support/async_stream.h
include/grpcpp/support/async_stream_impl.h
include/grpcpp/support/async_unary_call.h
include/grpcpp/support/async_unary_call_impl.h
include/grpcpp/support/byte_buffer.h
include/grpcpp/support/channel_arguments.h
include/grpcpp/support/channel_arguments_impl.h
include/grpcpp/support/client_callback.h
include/grpcpp/support/client_callback_impl.h
include/grpcpp/support/client_interceptor.h
include/grpcpp/support/config.h
include/grpcpp/support/interceptor.h
@ -4833,6 +4901,7 @@ foreach(_hdr
include/grpcpp/support/proto_buffer_reader.h
include/grpcpp/support/proto_buffer_writer.h
include/grpcpp/support/server_callback.h
include/grpcpp/support/server_callback_impl.h
include/grpcpp/support/server_interceptor.h
include/grpcpp/support/slice.h
include/grpcpp/support/status.h
@ -4840,6 +4909,7 @@ foreach(_hdr
include/grpcpp/support/string_ref.h
include/grpcpp/support/stub_options.h
include/grpcpp/support/sync_stream.h
include/grpcpp/support/sync_stream_impl.h
include/grpcpp/support/time.h
include/grpcpp/support/validate_service_config.h
include/grpc/support/alloc.h
@ -4925,7 +4995,9 @@ foreach(_hdr
include/grpc++/impl/codegen/time.h
include/grpcpp/impl/codegen/async_generic_service.h
include/grpcpp/impl/codegen/async_stream.h
include/grpcpp/impl/codegen/async_stream_impl.h
include/grpcpp/impl/codegen/async_unary_call.h
include/grpcpp/impl/codegen/async_unary_call_impl.h
include/grpcpp/impl/codegen/byte_buffer.h
include/grpcpp/impl/codegen/call.h
include/grpcpp/impl/codegen/call_hook.h
@ -4934,6 +5006,7 @@ foreach(_hdr
include/grpcpp/impl/codegen/callback_common.h
include/grpcpp/impl/codegen/channel_interface.h
include/grpcpp/impl/codegen/client_callback.h
include/grpcpp/impl/codegen/client_callback_impl.h
include/grpcpp/impl/codegen/client_context.h
include/grpcpp/impl/codegen/client_context_impl.h
include/grpcpp/impl/codegen/client_interceptor.h
@ -4956,6 +5029,7 @@ foreach(_hdr
include/grpcpp/impl/codegen/security/auth_context.h
include/grpcpp/impl/codegen/serialization_traits.h
include/grpcpp/impl/codegen/server_callback.h
include/grpcpp/impl/codegen/server_callback_impl.h
include/grpcpp/impl/codegen/server_context.h
include/grpcpp/impl/codegen/server_context_impl.h
include/grpcpp/impl/codegen/server_interceptor.h
@ -4967,6 +5041,7 @@ foreach(_hdr
include/grpcpp/impl/codegen/string_ref.h
include/grpcpp/impl/codegen/stub_options.h
include/grpcpp/impl/codegen/sync_stream.h
include/grpcpp/impl/codegen/sync_stream_impl.h
include/grpcpp/impl/codegen/time.h
include/grpcpp/impl/codegen/sync.h
)
@ -5766,58 +5841,6 @@ endif()
endif (gRPC_BUILD_CSHARP_EXT)
if (gRPC_BUILD_TESTS)
add_library(upb
third_party/upb/google/protobuf/descriptor.upb.c
third_party/upb/upb/decode.c
third_party/upb/upb/def.c
third_party/upb/upb/encode.c
third_party/upb/upb/handlers.c
third_party/upb/upb/msg.c
third_party/upb/upb/msgfactory.c
third_party/upb/upb/sink.c
third_party/upb/upb/table.c
third_party/upb/upb/upb.c
)
if(WIN32 AND MSVC)
set_target_properties(upb PROPERTIES COMPILE_PDB_NAME "upb"
COMPILE_PDB_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}"
)
if (gRPC_INSTALL)
install(FILES ${CMAKE_CURRENT_BINARY_DIR}/upb.pdb
DESTINATION ${gRPC_INSTALL_LIBDIR} OPTIONAL
)
endif()
endif()
target_include_directories(upb
PUBLIC $<INSTALL_INTERFACE:${gRPC_INSTALL_INCLUDEDIR}> $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
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}
)
# avoid dependency on libstdc++
if (_gRPC_CORE_NOSTDCXX_FLAGS)
set_target_properties(upb PROPERTIES LINKER_LANGUAGE C)
# only use the flags for C++ source files
target_compile_options(upb PRIVATE $<$<COMPILE_LANGUAGE:CXX>:${_gRPC_CORE_NOSTDCXX_FLAGS}>)
endif()
target_link_libraries(upb
${_gRPC_SSL_LIBRARIES}
${_gRPC_ALLTARGETS_LIBRARIES}
)
endif (gRPC_BUILD_TESTS)
if (gRPC_BUILD_TESTS)
add_library(bad_client_test
test/core/bad_client/bad_client.cc
)
@ -6872,12 +6895,12 @@ target_link_libraries(dns_resolver_connectivity_test
endif (gRPC_BUILD_TESTS)
if (gRPC_BUILD_TESTS)
add_executable(dns_resolver_cooldown_test
add_executable(dns_resolver_cooldown_using_ares_resolver_test
test/core/client_channel/resolvers/dns_resolver_cooldown_test.cc
)
target_include_directories(dns_resolver_cooldown_test
target_include_directories(dns_resolver_cooldown_using_ares_resolver_test
PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
PRIVATE ${_gRPC_SSL_INCLUDE_DIR}
@ -6890,7 +6913,7 @@ target_include_directories(dns_resolver_cooldown_test
PRIVATE ${_gRPC_NANOPB_INCLUDE_DIR}
)
target_link_libraries(dns_resolver_cooldown_test
target_link_libraries(dns_resolver_cooldown_using_ares_resolver_test
${_gRPC_ALLTARGETS_LIBRARIES}
grpc_test_util
grpc
@ -6899,8 +6922,42 @@ target_link_libraries(dns_resolver_cooldown_test
# avoid dependency on libstdc++
if (_gRPC_CORE_NOSTDCXX_FLAGS)
set_target_properties(dns_resolver_cooldown_test PROPERTIES LINKER_LANGUAGE C)
target_compile_options(dns_resolver_cooldown_test PRIVATE $<$<COMPILE_LANGUAGE:CXX>:${_gRPC_CORE_NOSTDCXX_FLAGS}>)
set_target_properties(dns_resolver_cooldown_using_ares_resolver_test PROPERTIES LINKER_LANGUAGE C)
target_compile_options(dns_resolver_cooldown_using_ares_resolver_test PRIVATE $<$<COMPILE_LANGUAGE:CXX>:${_gRPC_CORE_NOSTDCXX_FLAGS}>)
endif()
endif (gRPC_BUILD_TESTS)
if (gRPC_BUILD_TESTS)
add_executable(dns_resolver_cooldown_using_native_resolver_test
test/core/client_channel/resolvers/dns_resolver_cooldown_test.cc
)
target_include_directories(dns_resolver_cooldown_using_native_resolver_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(dns_resolver_cooldown_using_native_resolver_test
${_gRPC_ALLTARGETS_LIBRARIES}
grpc_test_util
grpc
gpr
)
# avoid dependency on libstdc++
if (_gRPC_CORE_NOSTDCXX_FLAGS)
set_target_properties(dns_resolver_cooldown_using_native_resolver_test PROPERTIES LINKER_LANGUAGE C)
target_compile_options(dns_resolver_cooldown_using_native_resolver_test PRIVATE $<$<COMPILE_LANGUAGE:CXX>:${_gRPC_CORE_NOSTDCXX_FLAGS}>)
endif()
endif (gRPC_BUILD_TESTS)
@ -7504,7 +7561,7 @@ endif (gRPC_BUILD_TESTS)
if (gRPC_BUILD_TESTS)
add_executable(gpr_host_port_test
test/core/gpr/host_port_test.cc
test/core/gprpp/host_port_test.cc
)
@ -8216,40 +8273,6 @@ target_link_libraries(grpc_credentials_test
endif (gRPC_BUILD_TESTS)
if (gRPC_BUILD_TESTS)
add_executable(grpc_fetch_oauth2
test/core/security/fetch_oauth2.cc
)
target_include_directories(grpc_fetch_oauth2
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(grpc_fetch_oauth2
${_gRPC_ALLTARGETS_LIBRARIES}
grpc_test_util
grpc
gpr
)
# avoid dependency on libstdc++
if (_gRPC_CORE_NOSTDCXX_FLAGS)
set_target_properties(grpc_fetch_oauth2 PROPERTIES LINKER_LANGUAGE C)
target_compile_options(grpc_fetch_oauth2 PRIVATE $<$<COMPILE_LANGUAGE:CXX>:${_gRPC_CORE_NOSTDCXX_FLAGS}>)
endif()
endif (gRPC_BUILD_TESTS)
if (gRPC_BUILD_TESTS)
add_executable(grpc_ipv6_loopback_available_test
test/core/iomgr/grpc_ipv6_loopback_available_test.cc
)
@ -9355,6 +9378,40 @@ target_link_libraries(minimal_stack_is_minimal_test
endif (gRPC_BUILD_TESTS)
if (gRPC_BUILD_TESTS)
add_executable(mpmcqueue_test
test/core/iomgr/mpmcqueue_test.cc
)
target_include_directories(mpmcqueue_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(mpmcqueue_test
${_gRPC_ALLTARGETS_LIBRARIES}
grpc_test_util
grpc
gpr
)
# avoid dependency on libstdc++
if (_gRPC_CORE_NOSTDCXX_FLAGS)
set_target_properties(mpmcqueue_test PROPERTIES LINKER_LANGUAGE C)
target_compile_options(mpmcqueue_test PRIVATE $<$<COMPILE_LANGUAGE:CXX>:${_gRPC_CORE_NOSTDCXX_FLAGS}>)
endif()
endif (gRPC_BUILD_TESTS)
if (gRPC_BUILD_TESTS)
add_executable(multiple_server_queues_test
test/core/end2end/multiple_server_queues_test.cc
)
@ -13992,6 +14049,45 @@ endif()
endif (gRPC_BUILD_CODEGEN)
if (gRPC_BUILD_TESTS)
add_executable(grpc_fetch_oauth2
test/core/security/fetch_oauth2.cc
third_party/googletest/googletest/src/gtest-all.cc
third_party/googletest/googlemock/src/gmock-all.cc
)
target_include_directories(grpc_fetch_oauth2
PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
PRIVATE ${_gRPC_SSL_INCLUDE_DIR}
PRIVATE ${_gRPC_PROTOBUF_INCLUDE_DIR}
PRIVATE ${_gRPC_ZLIB_INCLUDE_DIR}
PRIVATE ${_gRPC_BENCHMARK_INCLUDE_DIR}
PRIVATE ${_gRPC_CARES_INCLUDE_DIR}
PRIVATE ${_gRPC_GFLAGS_INCLUDE_DIR}
PRIVATE ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR}
PRIVATE ${_gRPC_NANOPB_INCLUDE_DIR}
PRIVATE third_party/googletest/googletest/include
PRIVATE third_party/googletest/googletest
PRIVATE third_party/googletest/googlemock/include
PRIVATE third_party/googletest/googlemock
PRIVATE ${_gRPC_PROTO_GENS_DIR}
)
target_link_libraries(grpc_fetch_oauth2
${_gRPC_PROTOBUF_LIBRARIES}
${_gRPC_ALLTARGETS_LIBRARIES}
grpc_test_util
grpc++
grpc
gpr
${_gRPC_GFLAGS_LIBRARIES}
)
endif (gRPC_BUILD_TESTS)
if (gRPC_BUILD_TESTS)
add_executable(grpc_linux_system_roots_test
test/core/security/linux_system_roots_test.cc
third_party/googletest/googletest/src/gtest-all.cc
@ -14372,6 +14468,70 @@ target_link_libraries(grpclb_end2end_test
)
endif (gRPC_BUILD_TESTS)
if (gRPC_BUILD_TESTS)
if(_gRPC_PLATFORM_LINUX)
add_executable(grpclb_fallback_test
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/empty.pb.cc
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/empty.grpc.pb.cc
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/empty.pb.h
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/empty.grpc.pb.h
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/messages.pb.cc
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/messages.grpc.pb.cc
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/messages.pb.h
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/messages.grpc.pb.h
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/test.pb.cc
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/test.grpc.pb.cc
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/test.pb.h
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/test.grpc.pb.h
test/cpp/interop/grpclb_fallback_test.cc
third_party/googletest/googletest/src/gtest-all.cc
third_party/googletest/googlemock/src/gmock-all.cc
)
protobuf_generate_grpc_cpp(
src/proto/grpc/testing/empty.proto
)
protobuf_generate_grpc_cpp(
src/proto/grpc/testing/messages.proto
)
protobuf_generate_grpc_cpp(
src/proto/grpc/testing/test.proto
)
target_include_directories(grpclb_fallback_test
PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
PRIVATE ${_gRPC_SSL_INCLUDE_DIR}
PRIVATE ${_gRPC_PROTOBUF_INCLUDE_DIR}
PRIVATE ${_gRPC_ZLIB_INCLUDE_DIR}
PRIVATE ${_gRPC_BENCHMARK_INCLUDE_DIR}
PRIVATE ${_gRPC_CARES_INCLUDE_DIR}
PRIVATE ${_gRPC_GFLAGS_INCLUDE_DIR}
PRIVATE ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR}
PRIVATE ${_gRPC_NANOPB_INCLUDE_DIR}
PRIVATE third_party/googletest/googletest/include
PRIVATE third_party/googletest/googletest
PRIVATE third_party/googletest/googlemock/include
PRIVATE third_party/googletest/googlemock
PRIVATE ${_gRPC_PROTO_GENS_DIR}
)
target_link_libraries(grpclb_fallback_test
${_gRPC_PROTOBUF_LIBRARIES}
${_gRPC_ALLTARGETS_LIBRARIES}
grpc++_test_util
grpc_test_util
grpc++
grpc
gpr
grpc++_test_config
${_gRPC_GFLAGS_LIBRARIES}
)
endif()
endif (gRPC_BUILD_TESTS)
if (gRPC_BUILD_TESTS)
@ -16637,6 +16797,45 @@ target_link_libraries(stress_test
)
endif (gRPC_BUILD_TESTS)
if (gRPC_BUILD_TESTS)
add_executable(string_view_test
test/core/gprpp/string_view_test.cc
third_party/googletest/googletest/src/gtest-all.cc
third_party/googletest/googlemock/src/gmock-all.cc
)
target_include_directories(string_view_test
PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
PRIVATE ${_gRPC_SSL_INCLUDE_DIR}
PRIVATE ${_gRPC_PROTOBUF_INCLUDE_DIR}
PRIVATE ${_gRPC_ZLIB_INCLUDE_DIR}
PRIVATE ${_gRPC_BENCHMARK_INCLUDE_DIR}
PRIVATE ${_gRPC_CARES_INCLUDE_DIR}
PRIVATE ${_gRPC_GFLAGS_INCLUDE_DIR}
PRIVATE ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR}
PRIVATE ${_gRPC_NANOPB_INCLUDE_DIR}
PRIVATE third_party/googletest/googletest/include
PRIVATE third_party/googletest/googletest
PRIVATE third_party/googletest/googlemock/include
PRIVATE third_party/googletest/googlemock
PRIVATE ${_gRPC_PROTO_GENS_DIR}
)
target_link_libraries(string_view_test
${_gRPC_PROTOBUF_LIBRARIES}
${_gRPC_ALLTARGETS_LIBRARIES}
grpc_test_util
grpc++
grpc
gpr
${_gRPC_GFLAGS_LIBRARIES}
)
endif (gRPC_BUILD_TESTS)
if (gRPC_BUILD_TESTS)
@ -17030,6 +17229,46 @@ target_link_libraries(gen_percent_encoding_tables
if (gRPC_BUILD_TESTS)
add_executable(bad_streaming_id_bad_client_test
test/core/bad_client/tests/bad_streaming_id.cc
third_party/googletest/googletest/src/gtest-all.cc
third_party/googletest/googlemock/src/gmock-all.cc
)
target_include_directories(bad_streaming_id_bad_client_test
PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
PRIVATE ${_gRPC_SSL_INCLUDE_DIR}
PRIVATE ${_gRPC_PROTOBUF_INCLUDE_DIR}
PRIVATE ${_gRPC_ZLIB_INCLUDE_DIR}
PRIVATE ${_gRPC_BENCHMARK_INCLUDE_DIR}
PRIVATE ${_gRPC_CARES_INCLUDE_DIR}
PRIVATE ${_gRPC_GFLAGS_INCLUDE_DIR}
PRIVATE ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR}
PRIVATE ${_gRPC_NANOPB_INCLUDE_DIR}
PRIVATE third_party/googletest/googletest/include
PRIVATE third_party/googletest/googletest
PRIVATE third_party/googletest/googlemock/include
PRIVATE third_party/googletest/googlemock
PRIVATE ${_gRPC_PROTO_GENS_DIR}
)
target_link_libraries(bad_streaming_id_bad_client_test
${_gRPC_SSL_LIBRARIES}
${_gRPC_PROTOBUF_LIBRARIES}
${_gRPC_ALLTARGETS_LIBRARIES}
bad_client_test
grpc_test_util_unsecure
grpc_unsecure
gpr
${_gRPC_GFLAGS_LIBRARIES}
)
endif (gRPC_BUILD_TESTS)
if (gRPC_BUILD_TESTS)
add_executable(badreq_bad_client_test
test/core/bad_client/tests/badreq.cc
third_party/googletest/googletest/src/gtest-all.cc
@ -17307,6 +17546,46 @@ target_link_libraries(large_metadata_bad_client_test
)
endif (gRPC_BUILD_TESTS)
if (gRPC_BUILD_TESTS)
add_executable(out_of_bounds_bad_client_test
test/core/bad_client/tests/out_of_bounds.cc
third_party/googletest/googletest/src/gtest-all.cc
third_party/googletest/googlemock/src/gmock-all.cc
)
target_include_directories(out_of_bounds_bad_client_test
PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
PRIVATE ${_gRPC_SSL_INCLUDE_DIR}
PRIVATE ${_gRPC_PROTOBUF_INCLUDE_DIR}
PRIVATE ${_gRPC_ZLIB_INCLUDE_DIR}
PRIVATE ${_gRPC_BENCHMARK_INCLUDE_DIR}
PRIVATE ${_gRPC_CARES_INCLUDE_DIR}
PRIVATE ${_gRPC_GFLAGS_INCLUDE_DIR}
PRIVATE ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR}
PRIVATE ${_gRPC_NANOPB_INCLUDE_DIR}
PRIVATE third_party/googletest/googletest/include
PRIVATE third_party/googletest/googletest
PRIVATE third_party/googletest/googlemock/include
PRIVATE third_party/googletest/googlemock
PRIVATE ${_gRPC_PROTO_GENS_DIR}
)
target_link_libraries(out_of_bounds_bad_client_test
${_gRPC_SSL_LIBRARIES}
${_gRPC_PROTOBUF_LIBRARIES}
${_gRPC_ALLTARGETS_LIBRARIES}
bad_client_test
grpc_test_util_unsecure
grpc_unsecure
gpr
${_gRPC_GFLAGS_LIBRARIES}
)
endif (gRPC_BUILD_TESTS)
if (gRPC_BUILD_TESTS)

@ -351,6 +351,7 @@ CFLAGS += -std=c99 -Wsign-conversion -Wconversion $(W_SHADOW) $(W_EXTRA_SEMI)
CXXFLAGS += -std=c++11
ifeq ($(SYSTEM),Darwin)
CXXFLAGS += -stdlib=libc++
LDFLAGS += -framework CoreFoundation
endif
CXXFLAGS += -Wnon-virtual-dtor
CPPFLAGS += -g -Wall -Wextra -Werror -Wno-long-long -Wno-unused-parameter -DOSATOMIC_USE_INLINED=1 -Wno-deprecated-declarations -Ithird_party/nanopb -DPB_FIELD_32BIT
@ -1015,7 +1016,8 @@ compression_test: $(BINDIR)/$(CONFIG)/compression_test
concurrent_connectivity_test: $(BINDIR)/$(CONFIG)/concurrent_connectivity_test
connection_refused_test: $(BINDIR)/$(CONFIG)/connection_refused_test
dns_resolver_connectivity_test: $(BINDIR)/$(CONFIG)/dns_resolver_connectivity_test
dns_resolver_cooldown_test: $(BINDIR)/$(CONFIG)/dns_resolver_cooldown_test
dns_resolver_cooldown_using_ares_resolver_test: $(BINDIR)/$(CONFIG)/dns_resolver_cooldown_using_ares_resolver_test
dns_resolver_cooldown_using_native_resolver_test: $(BINDIR)/$(CONFIG)/dns_resolver_cooldown_using_native_resolver_test
dns_resolver_test: $(BINDIR)/$(CONFIG)/dns_resolver_test
dualstack_socket_test: $(BINDIR)/$(CONFIG)/dualstack_socket_test
endpoint_pair_test: $(BINDIR)/$(CONFIG)/endpoint_pair_test
@ -1054,7 +1056,6 @@ grpc_completion_queue_test: $(BINDIR)/$(CONFIG)/grpc_completion_queue_test
grpc_completion_queue_threading_test: $(BINDIR)/$(CONFIG)/grpc_completion_queue_threading_test
grpc_create_jwt: $(BINDIR)/$(CONFIG)/grpc_create_jwt
grpc_credentials_test: $(BINDIR)/$(CONFIG)/grpc_credentials_test
grpc_fetch_oauth2: $(BINDIR)/$(CONFIG)/grpc_fetch_oauth2
grpc_ipv6_loopback_available_test: $(BINDIR)/$(CONFIG)/grpc_ipv6_loopback_available_test
grpc_json_token_test: $(BINDIR)/$(CONFIG)/grpc_json_token_test
grpc_jwt_verifier_test: $(BINDIR)/$(CONFIG)/grpc_jwt_verifier_test
@ -1092,6 +1093,7 @@ memory_usage_server: $(BINDIR)/$(CONFIG)/memory_usage_server
memory_usage_test: $(BINDIR)/$(CONFIG)/memory_usage_test
message_compress_test: $(BINDIR)/$(CONFIG)/message_compress_test
minimal_stack_is_minimal_test: $(BINDIR)/$(CONFIG)/minimal_stack_is_minimal_test
mpmcqueue_test: $(BINDIR)/$(CONFIG)/mpmcqueue_test
multiple_server_queues_test: $(BINDIR)/$(CONFIG)/multiple_server_queues_test
murmur_hash_test: $(BINDIR)/$(CONFIG)/murmur_hash_test
nanopb_fuzzer_response_test: $(BINDIR)/$(CONFIG)/nanopb_fuzzer_response_test
@ -1216,6 +1218,7 @@ grpc_cli: $(BINDIR)/$(CONFIG)/grpc_cli
grpc_core_map_test: $(BINDIR)/$(CONFIG)/grpc_core_map_test
grpc_cpp_plugin: $(BINDIR)/$(CONFIG)/grpc_cpp_plugin
grpc_csharp_plugin: $(BINDIR)/$(CONFIG)/grpc_csharp_plugin
grpc_fetch_oauth2: $(BINDIR)/$(CONFIG)/grpc_fetch_oauth2
grpc_linux_system_roots_test: $(BINDIR)/$(CONFIG)/grpc_linux_system_roots_test
grpc_node_plugin: $(BINDIR)/$(CONFIG)/grpc_node_plugin
grpc_objective_c_plugin: $(BINDIR)/$(CONFIG)/grpc_objective_c_plugin
@ -1225,6 +1228,7 @@ grpc_ruby_plugin: $(BINDIR)/$(CONFIG)/grpc_ruby_plugin
grpc_tool_test: $(BINDIR)/$(CONFIG)/grpc_tool_test
grpclb_api_test: $(BINDIR)/$(CONFIG)/grpclb_api_test
grpclb_end2end_test: $(BINDIR)/$(CONFIG)/grpclb_end2end_test
grpclb_fallback_test: $(BINDIR)/$(CONFIG)/grpclb_fallback_test
h2_ssl_cert_test: $(BINDIR)/$(CONFIG)/h2_ssl_cert_test
h2_ssl_session_reuse_test: $(BINDIR)/$(CONFIG)/h2_ssl_session_reuse_test
health_service_end2end_test: $(BINDIR)/$(CONFIG)/health_service_end2end_test
@ -1278,6 +1282,7 @@ status_metadata_test: $(BINDIR)/$(CONFIG)/status_metadata_test
status_util_test: $(BINDIR)/$(CONFIG)/status_util_test
streaming_throughput_test: $(BINDIR)/$(CONFIG)/streaming_throughput_test
stress_test: $(BINDIR)/$(CONFIG)/stress_test
string_view_test: $(BINDIR)/$(CONFIG)/string_view_test
thread_manager_test: $(BINDIR)/$(CONFIG)/thread_manager_test
thread_stress_test: $(BINDIR)/$(CONFIG)/thread_stress_test
time_change_test: $(BINDIR)/$(CONFIG)/time_change_test
@ -1291,6 +1296,7 @@ gen_legal_metadata_characters: $(BINDIR)/$(CONFIG)/gen_legal_metadata_characters
gen_percent_encoding_tables: $(BINDIR)/$(CONFIG)/gen_percent_encoding_tables
boringssl_ssl_test: $(BINDIR)/$(CONFIG)/boringssl_ssl_test
boringssl_crypto_test: $(BINDIR)/$(CONFIG)/boringssl_crypto_test
bad_streaming_id_bad_client_test: $(BINDIR)/$(CONFIG)/bad_streaming_id_bad_client_test
badreq_bad_client_test: $(BINDIR)/$(CONFIG)/badreq_bad_client_test
connection_prefix_bad_client_test: $(BINDIR)/$(CONFIG)/connection_prefix_bad_client_test
duplicate_header_bad_client_test: $(BINDIR)/$(CONFIG)/duplicate_header_bad_client_test
@ -1298,6 +1304,7 @@ head_of_line_blocking_bad_client_test: $(BINDIR)/$(CONFIG)/head_of_line_blocking
headers_bad_client_test: $(BINDIR)/$(CONFIG)/headers_bad_client_test
initial_settings_frame_bad_client_test: $(BINDIR)/$(CONFIG)/initial_settings_frame_bad_client_test
large_metadata_bad_client_test: $(BINDIR)/$(CONFIG)/large_metadata_bad_client_test
out_of_bounds_bad_client_test: $(BINDIR)/$(CONFIG)/out_of_bounds_bad_client_test
server_registered_method_bad_client_test: $(BINDIR)/$(CONFIG)/server_registered_method_bad_client_test
simple_request_bad_client_test: $(BINDIR)/$(CONFIG)/simple_request_bad_client_test
unknown_frame_bad_client_test: $(BINDIR)/$(CONFIG)/unknown_frame_bad_client_test
@ -1444,7 +1451,8 @@ buildtests_c: privatelibs_c \
$(BINDIR)/$(CONFIG)/concurrent_connectivity_test \
$(BINDIR)/$(CONFIG)/connection_refused_test \
$(BINDIR)/$(CONFIG)/dns_resolver_connectivity_test \
$(BINDIR)/$(CONFIG)/dns_resolver_cooldown_test \
$(BINDIR)/$(CONFIG)/dns_resolver_cooldown_using_ares_resolver_test \
$(BINDIR)/$(CONFIG)/dns_resolver_cooldown_using_native_resolver_test \
$(BINDIR)/$(CONFIG)/dns_resolver_test \
$(BINDIR)/$(CONFIG)/dualstack_socket_test \
$(BINDIR)/$(CONFIG)/endpoint_pair_test \
@ -1482,7 +1490,6 @@ buildtests_c: privatelibs_c \
$(BINDIR)/$(CONFIG)/grpc_completion_queue_test \
$(BINDIR)/$(CONFIG)/grpc_completion_queue_threading_test \
$(BINDIR)/$(CONFIG)/grpc_credentials_test \
$(BINDIR)/$(CONFIG)/grpc_fetch_oauth2 \
$(BINDIR)/$(CONFIG)/grpc_ipv6_loopback_available_test \
$(BINDIR)/$(CONFIG)/grpc_json_token_test \
$(BINDIR)/$(CONFIG)/grpc_jwt_verifier_test \
@ -1513,6 +1520,7 @@ buildtests_c: privatelibs_c \
$(BINDIR)/$(CONFIG)/memory_usage_test \
$(BINDIR)/$(CONFIG)/message_compress_test \
$(BINDIR)/$(CONFIG)/minimal_stack_is_minimal_test \
$(BINDIR)/$(CONFIG)/mpmcqueue_test \
$(BINDIR)/$(CONFIG)/multiple_server_queues_test \
$(BINDIR)/$(CONFIG)/murmur_hash_test \
$(BINDIR)/$(CONFIG)/no_server_test \
@ -1685,10 +1693,12 @@ buildtests_cxx: privatelibs_cxx \
$(BINDIR)/$(CONFIG)/grpc_alts_credentials_options_test \
$(BINDIR)/$(CONFIG)/grpc_cli \
$(BINDIR)/$(CONFIG)/grpc_core_map_test \
$(BINDIR)/$(CONFIG)/grpc_fetch_oauth2 \
$(BINDIR)/$(CONFIG)/grpc_linux_system_roots_test \
$(BINDIR)/$(CONFIG)/grpc_tool_test \
$(BINDIR)/$(CONFIG)/grpclb_api_test \
$(BINDIR)/$(CONFIG)/grpclb_end2end_test \
$(BINDIR)/$(CONFIG)/grpclb_fallback_test \
$(BINDIR)/$(CONFIG)/h2_ssl_cert_test \
$(BINDIR)/$(CONFIG)/h2_ssl_session_reuse_test \
$(BINDIR)/$(CONFIG)/health_service_end2end_test \
@ -1742,6 +1752,7 @@ buildtests_cxx: privatelibs_cxx \
$(BINDIR)/$(CONFIG)/status_util_test \
$(BINDIR)/$(CONFIG)/streaming_throughput_test \
$(BINDIR)/$(CONFIG)/stress_test \
$(BINDIR)/$(CONFIG)/string_view_test \
$(BINDIR)/$(CONFIG)/thread_manager_test \
$(BINDIR)/$(CONFIG)/thread_stress_test \
$(BINDIR)/$(CONFIG)/time_change_test \
@ -1751,6 +1762,7 @@ buildtests_cxx: privatelibs_cxx \
$(BINDIR)/$(CONFIG)/xds_end2end_test \
$(BINDIR)/$(CONFIG)/boringssl_ssl_test \
$(BINDIR)/$(CONFIG)/boringssl_crypto_test \
$(BINDIR)/$(CONFIG)/bad_streaming_id_bad_client_test \
$(BINDIR)/$(CONFIG)/badreq_bad_client_test \
$(BINDIR)/$(CONFIG)/connection_prefix_bad_client_test \
$(BINDIR)/$(CONFIG)/duplicate_header_bad_client_test \
@ -1758,6 +1770,7 @@ buildtests_cxx: privatelibs_cxx \
$(BINDIR)/$(CONFIG)/headers_bad_client_test \
$(BINDIR)/$(CONFIG)/initial_settings_frame_bad_client_test \
$(BINDIR)/$(CONFIG)/large_metadata_bad_client_test \
$(BINDIR)/$(CONFIG)/out_of_bounds_bad_client_test \
$(BINDIR)/$(CONFIG)/server_registered_method_bad_client_test \
$(BINDIR)/$(CONFIG)/simple_request_bad_client_test \
$(BINDIR)/$(CONFIG)/unknown_frame_bad_client_test \
@ -1846,10 +1859,12 @@ buildtests_cxx: privatelibs_cxx \
$(BINDIR)/$(CONFIG)/grpc_alts_credentials_options_test \
$(BINDIR)/$(CONFIG)/grpc_cli \
$(BINDIR)/$(CONFIG)/grpc_core_map_test \
$(BINDIR)/$(CONFIG)/grpc_fetch_oauth2 \
$(BINDIR)/$(CONFIG)/grpc_linux_system_roots_test \
$(BINDIR)/$(CONFIG)/grpc_tool_test \
$(BINDIR)/$(CONFIG)/grpclb_api_test \
$(BINDIR)/$(CONFIG)/grpclb_end2end_test \
$(BINDIR)/$(CONFIG)/grpclb_fallback_test \
$(BINDIR)/$(CONFIG)/h2_ssl_cert_test \
$(BINDIR)/$(CONFIG)/h2_ssl_session_reuse_test \
$(BINDIR)/$(CONFIG)/health_service_end2end_test \
@ -1903,6 +1918,7 @@ buildtests_cxx: privatelibs_cxx \
$(BINDIR)/$(CONFIG)/status_util_test \
$(BINDIR)/$(CONFIG)/streaming_throughput_test \
$(BINDIR)/$(CONFIG)/stress_test \
$(BINDIR)/$(CONFIG)/string_view_test \
$(BINDIR)/$(CONFIG)/thread_manager_test \
$(BINDIR)/$(CONFIG)/thread_stress_test \
$(BINDIR)/$(CONFIG)/time_change_test \
@ -1910,6 +1926,7 @@ buildtests_cxx: privatelibs_cxx \
$(BINDIR)/$(CONFIG)/transport_security_common_api_test \
$(BINDIR)/$(CONFIG)/writes_per_rpc_test \
$(BINDIR)/$(CONFIG)/xds_end2end_test \
$(BINDIR)/$(CONFIG)/bad_streaming_id_bad_client_test \
$(BINDIR)/$(CONFIG)/badreq_bad_client_test \
$(BINDIR)/$(CONFIG)/connection_prefix_bad_client_test \
$(BINDIR)/$(CONFIG)/duplicate_header_bad_client_test \
@ -1917,6 +1934,7 @@ buildtests_cxx: privatelibs_cxx \
$(BINDIR)/$(CONFIG)/headers_bad_client_test \
$(BINDIR)/$(CONFIG)/initial_settings_frame_bad_client_test \
$(BINDIR)/$(CONFIG)/large_metadata_bad_client_test \
$(BINDIR)/$(CONFIG)/out_of_bounds_bad_client_test \
$(BINDIR)/$(CONFIG)/server_registered_method_bad_client_test \
$(BINDIR)/$(CONFIG)/simple_request_bad_client_test \
$(BINDIR)/$(CONFIG)/unknown_frame_bad_client_test \
@ -1977,8 +1995,10 @@ test_c: buildtests_c
$(Q) $(BINDIR)/$(CONFIG)/connection_refused_test || ( echo test connection_refused_test failed ; exit 1 )
$(E) "[RUN] Testing dns_resolver_connectivity_test"
$(Q) $(BINDIR)/$(CONFIG)/dns_resolver_connectivity_test || ( echo test dns_resolver_connectivity_test failed ; exit 1 )
$(E) "[RUN] Testing dns_resolver_cooldown_test"
$(Q) $(BINDIR)/$(CONFIG)/dns_resolver_cooldown_test || ( echo test dns_resolver_cooldown_test failed ; exit 1 )
$(E) "[RUN] Testing dns_resolver_cooldown_using_ares_resolver_test"
$(Q) $(BINDIR)/$(CONFIG)/dns_resolver_cooldown_using_ares_resolver_test || ( echo test dns_resolver_cooldown_using_ares_resolver_test failed ; exit 1 )
$(E) "[RUN] Testing dns_resolver_cooldown_using_native_resolver_test"
$(Q) $(BINDIR)/$(CONFIG)/dns_resolver_cooldown_using_native_resolver_test || ( echo test dns_resolver_cooldown_using_native_resolver_test failed ; exit 1 )
$(E) "[RUN] Testing dns_resolver_test"
$(Q) $(BINDIR)/$(CONFIG)/dns_resolver_test || ( echo test dns_resolver_test failed ; exit 1 )
$(E) "[RUN] Testing dualstack_socket_test"
@ -2103,6 +2123,8 @@ test_c: buildtests_c
$(Q) $(BINDIR)/$(CONFIG)/message_compress_test || ( echo test message_compress_test failed ; exit 1 )
$(E) "[RUN] Testing minimal_stack_is_minimal_test"
$(Q) $(BINDIR)/$(CONFIG)/minimal_stack_is_minimal_test || ( echo test minimal_stack_is_minimal_test failed ; exit 1 )
$(E) "[RUN] Testing mpmcqueue_test"
$(Q) $(BINDIR)/$(CONFIG)/mpmcqueue_test || ( echo test mpmcqueue_test failed ; exit 1 )
$(E) "[RUN] Testing multiple_server_queues_test"
$(Q) $(BINDIR)/$(CONFIG)/multiple_server_queues_test || ( echo test multiple_server_queues_test failed ; exit 1 )
$(E) "[RUN] Testing murmur_hash_test"
@ -2347,6 +2369,8 @@ test_cxx: buildtests_cxx
$(Q) $(BINDIR)/$(CONFIG)/grpclb_api_test || ( echo test grpclb_api_test failed ; exit 1 )
$(E) "[RUN] Testing grpclb_end2end_test"
$(Q) $(BINDIR)/$(CONFIG)/grpclb_end2end_test || ( echo test grpclb_end2end_test failed ; exit 1 )
$(E) "[RUN] Testing grpclb_fallback_test"
$(Q) $(BINDIR)/$(CONFIG)/grpclb_fallback_test || ( echo test grpclb_fallback_test failed ; exit 1 )
$(E) "[RUN] Testing h2_ssl_cert_test"
$(Q) $(BINDIR)/$(CONFIG)/h2_ssl_cert_test || ( echo test h2_ssl_cert_test failed ; exit 1 )
$(E) "[RUN] Testing h2_ssl_session_reuse_test"
@ -2427,6 +2451,8 @@ test_cxx: buildtests_cxx
$(Q) $(BINDIR)/$(CONFIG)/status_util_test || ( echo test status_util_test failed ; exit 1 )
$(E) "[RUN] Testing streaming_throughput_test"
$(Q) $(BINDIR)/$(CONFIG)/streaming_throughput_test || ( echo test streaming_throughput_test failed ; exit 1 )
$(E) "[RUN] Testing string_view_test"
$(Q) $(BINDIR)/$(CONFIG)/string_view_test || ( echo test string_view_test failed ; exit 1 )
$(E) "[RUN] Testing thread_manager_test"
$(Q) $(BINDIR)/$(CONFIG)/thread_manager_test || ( echo test thread_manager_test failed ; exit 1 )
$(E) "[RUN] Testing thread_stress_test"
@ -2441,6 +2467,8 @@ test_cxx: buildtests_cxx
$(Q) $(BINDIR)/$(CONFIG)/writes_per_rpc_test || ( echo test writes_per_rpc_test failed ; exit 1 )
$(E) "[RUN] Testing xds_end2end_test"
$(Q) $(BINDIR)/$(CONFIG)/xds_end2end_test || ( echo test xds_end2end_test failed ; exit 1 )
$(E) "[RUN] Testing bad_streaming_id_bad_client_test"
$(Q) $(BINDIR)/$(CONFIG)/bad_streaming_id_bad_client_test || ( echo test bad_streaming_id_bad_client_test failed ; exit 1 )
$(E) "[RUN] Testing badreq_bad_client_test"
$(Q) $(BINDIR)/$(CONFIG)/badreq_bad_client_test || ( echo test badreq_bad_client_test failed ; exit 1 )
$(E) "[RUN] Testing connection_prefix_bad_client_test"
@ -2455,6 +2483,8 @@ test_cxx: buildtests_cxx
$(Q) $(BINDIR)/$(CONFIG)/initial_settings_frame_bad_client_test || ( echo test initial_settings_frame_bad_client_test failed ; exit 1 )
$(E) "[RUN] Testing large_metadata_bad_client_test"
$(Q) $(BINDIR)/$(CONFIG)/large_metadata_bad_client_test || ( echo test large_metadata_bad_client_test failed ; exit 1 )
$(E) "[RUN] Testing out_of_bounds_bad_client_test"
$(Q) $(BINDIR)/$(CONFIG)/out_of_bounds_bad_client_test || ( echo test out_of_bounds_bad_client_test failed ; exit 1 )
$(E) "[RUN] Testing server_registered_method_bad_client_test"
$(Q) $(BINDIR)/$(CONFIG)/server_registered_method_bad_client_test || ( echo test server_registered_method_bad_client_test failed ; exit 1 )
$(E) "[RUN] Testing simple_request_bad_client_test"
@ -3369,7 +3399,6 @@ LIBGPR_SRC = \
src/core/lib/gpr/env_linux.cc \
src/core/lib/gpr/env_posix.cc \
src/core/lib/gpr/env_windows.cc \
src/core/lib/gpr/host_port.cc \
src/core/lib/gpr/log.cc \
src/core/lib/gpr/log_android.cc \
src/core/lib/gpr/log_linux.cc \
@ -3396,6 +3425,7 @@ LIBGPR_SRC = \
src/core/lib/gprpp/arena.cc \
src/core/lib/gprpp/fork.cc \
src/core/lib/gprpp/global_config_env.cc \
src/core/lib/gprpp/host_port.cc \
src/core/lib/gprpp/thd_posix.cc \
src/core/lib/gprpp/thd_windows.cc \
src/core/lib/profiling/basic_timers.cc \
@ -3515,6 +3545,7 @@ LIBGRPC_SRC = \
src/core/lib/iomgr/ev_windows.cc \
src/core/lib/iomgr/exec_ctx.cc \
src/core/lib/iomgr/executor.cc \
src/core/lib/iomgr/executor/mpmcqueue.cc \
src/core/lib/iomgr/fork_posix.cc \
src/core/lib/iomgr/fork_windows.cc \
src/core/lib/iomgr/gethostname_fallback.cc \
@ -3944,6 +3975,7 @@ LIBGRPC_CRONET_SRC = \
src/core/lib/iomgr/ev_windows.cc \
src/core/lib/iomgr/exec_ctx.cc \
src/core/lib/iomgr/executor.cc \
src/core/lib/iomgr/executor/mpmcqueue.cc \
src/core/lib/iomgr/fork_posix.cc \
src/core/lib/iomgr/fork_windows.cc \
src/core/lib/iomgr/gethostname_fallback.cc \
@ -4354,6 +4386,7 @@ LIBGRPC_TEST_UTIL_SRC = \
src/core/lib/iomgr/ev_windows.cc \
src/core/lib/iomgr/exec_ctx.cc \
src/core/lib/iomgr/executor.cc \
src/core/lib/iomgr/executor/mpmcqueue.cc \
src/core/lib/iomgr/fork_posix.cc \
src/core/lib/iomgr/fork_windows.cc \
src/core/lib/iomgr/gethostname_fallback.cc \
@ -4671,6 +4704,7 @@ LIBGRPC_TEST_UTIL_UNSECURE_SRC = \
src/core/lib/iomgr/ev_windows.cc \
src/core/lib/iomgr/exec_ctx.cc \
src/core/lib/iomgr/executor.cc \
src/core/lib/iomgr/executor/mpmcqueue.cc \
src/core/lib/iomgr/fork_posix.cc \
src/core/lib/iomgr/fork_windows.cc \
src/core/lib/iomgr/gethostname_fallback.cc \
@ -4951,6 +4985,7 @@ LIBGRPC_UNSECURE_SRC = \
src/core/lib/iomgr/ev_windows.cc \
src/core/lib/iomgr/exec_ctx.cc \
src/core/lib/iomgr/executor.cc \
src/core/lib/iomgr/executor/mpmcqueue.cc \
src/core/lib/iomgr/fork_posix.cc \
src/core/lib/iomgr/fork_windows.cc \
src/core/lib/iomgr/gethostname_fallback.cc \
@ -5524,6 +5559,7 @@ PUBLIC_HEADERS_CXX += \
include/grpcpp/channel_impl.h \
include/grpcpp/client_context.h \
include/grpcpp/completion_queue.h \
include/grpcpp/completion_queue_impl.h \
include/grpcpp/create_channel.h \
include/grpcpp/create_channel_impl.h \
include/grpcpp/create_channel_posix.h \
@ -5567,11 +5603,14 @@ PUBLIC_HEADERS_CXX += \
include/grpcpp/server_posix.h \
include/grpcpp/server_posix_impl.h \
include/grpcpp/support/async_stream.h \
include/grpcpp/support/async_stream_impl.h \
include/grpcpp/support/async_unary_call.h \
include/grpcpp/support/async_unary_call_impl.h \
include/grpcpp/support/byte_buffer.h \
include/grpcpp/support/channel_arguments.h \
include/grpcpp/support/channel_arguments_impl.h \
include/grpcpp/support/client_callback.h \
include/grpcpp/support/client_callback_impl.h \
include/grpcpp/support/client_interceptor.h \
include/grpcpp/support/config.h \
include/grpcpp/support/interceptor.h \
@ -5579,6 +5618,7 @@ PUBLIC_HEADERS_CXX += \
include/grpcpp/support/proto_buffer_reader.h \
include/grpcpp/support/proto_buffer_writer.h \
include/grpcpp/support/server_callback.h \
include/grpcpp/support/server_callback_impl.h \
include/grpcpp/support/server_interceptor.h \
include/grpcpp/support/slice.h \
include/grpcpp/support/status.h \
@ -5586,6 +5626,7 @@ PUBLIC_HEADERS_CXX += \
include/grpcpp/support/string_ref.h \
include/grpcpp/support/stub_options.h \
include/grpcpp/support/sync_stream.h \
include/grpcpp/support/sync_stream_impl.h \
include/grpcpp/support/time.h \
include/grpcpp/support/validate_service_config.h \
include/grpc/support/alloc.h \
@ -5671,7 +5712,9 @@ PUBLIC_HEADERS_CXX += \
include/grpc++/impl/codegen/time.h \
include/grpcpp/impl/codegen/async_generic_service.h \
include/grpcpp/impl/codegen/async_stream.h \
include/grpcpp/impl/codegen/async_stream_impl.h \
include/grpcpp/impl/codegen/async_unary_call.h \
include/grpcpp/impl/codegen/async_unary_call_impl.h \
include/grpcpp/impl/codegen/byte_buffer.h \
include/grpcpp/impl/codegen/call.h \
include/grpcpp/impl/codegen/call_hook.h \
@ -5680,6 +5723,7 @@ PUBLIC_HEADERS_CXX += \
include/grpcpp/impl/codegen/callback_common.h \
include/grpcpp/impl/codegen/channel_interface.h \
include/grpcpp/impl/codegen/client_callback.h \
include/grpcpp/impl/codegen/client_callback_impl.h \
include/grpcpp/impl/codegen/client_context.h \
include/grpcpp/impl/codegen/client_context_impl.h \
include/grpcpp/impl/codegen/client_interceptor.h \
@ -5702,6 +5746,7 @@ PUBLIC_HEADERS_CXX += \
include/grpcpp/impl/codegen/security/auth_context.h \
include/grpcpp/impl/codegen/serialization_traits.h \
include/grpcpp/impl/codegen/server_callback.h \
include/grpcpp/impl/codegen/server_callback_impl.h \
include/grpcpp/impl/codegen/server_context.h \
include/grpcpp/impl/codegen/server_context_impl.h \
include/grpcpp/impl/codegen/server_interceptor.h \
@ -5713,6 +5758,7 @@ PUBLIC_HEADERS_CXX += \
include/grpcpp/impl/codegen/string_ref.h \
include/grpcpp/impl/codegen/stub_options.h \
include/grpcpp/impl/codegen/sync_stream.h \
include/grpcpp/impl/codegen/sync_stream_impl.h \
include/grpcpp/impl/codegen/time.h \
include/grpcpp/impl/codegen/sync.h \
include/grpc++/impl/codegen/proto_utils.h \
@ -5950,6 +5996,7 @@ LIBGRPC++_CRONET_SRC = \
src/core/lib/iomgr/ev_windows.cc \
src/core/lib/iomgr/exec_ctx.cc \
src/core/lib/iomgr/executor.cc \
src/core/lib/iomgr/executor/mpmcqueue.cc \
src/core/lib/iomgr/fork_posix.cc \
src/core/lib/iomgr/fork_windows.cc \
src/core/lib/iomgr/gethostname_fallback.cc \
@ -6153,6 +6200,7 @@ PUBLIC_HEADERS_CXX += \
include/grpcpp/channel_impl.h \
include/grpcpp/client_context.h \
include/grpcpp/completion_queue.h \
include/grpcpp/completion_queue_impl.h \
include/grpcpp/create_channel.h \
include/grpcpp/create_channel_impl.h \
include/grpcpp/create_channel_posix.h \
@ -6196,11 +6244,14 @@ PUBLIC_HEADERS_CXX += \
include/grpcpp/server_posix.h \
include/grpcpp/server_posix_impl.h \
include/grpcpp/support/async_stream.h \
include/grpcpp/support/async_stream_impl.h \
include/grpcpp/support/async_unary_call.h \
include/grpcpp/support/async_unary_call_impl.h \
include/grpcpp/support/byte_buffer.h \
include/grpcpp/support/channel_arguments.h \
include/grpcpp/support/channel_arguments_impl.h \
include/grpcpp/support/client_callback.h \
include/grpcpp/support/client_callback_impl.h \
include/grpcpp/support/client_interceptor.h \
include/grpcpp/support/config.h \
include/grpcpp/support/interceptor.h \
@ -6208,6 +6259,7 @@ PUBLIC_HEADERS_CXX += \
include/grpcpp/support/proto_buffer_reader.h \
include/grpcpp/support/proto_buffer_writer.h \
include/grpcpp/support/server_callback.h \
include/grpcpp/support/server_callback_impl.h \
include/grpcpp/support/server_interceptor.h \
include/grpcpp/support/slice.h \
include/grpcpp/support/status.h \
@ -6215,6 +6267,7 @@ PUBLIC_HEADERS_CXX += \
include/grpcpp/support/string_ref.h \
include/grpcpp/support/stub_options.h \
include/grpcpp/support/sync_stream.h \
include/grpcpp/support/sync_stream_impl.h \
include/grpcpp/support/time.h \
include/grpcpp/support/validate_service_config.h \
include/grpc/support/alloc.h \
@ -6300,7 +6353,9 @@ PUBLIC_HEADERS_CXX += \
include/grpc++/impl/codegen/time.h \
include/grpcpp/impl/codegen/async_generic_service.h \
include/grpcpp/impl/codegen/async_stream.h \
include/grpcpp/impl/codegen/async_stream_impl.h \
include/grpcpp/impl/codegen/async_unary_call.h \
include/grpcpp/impl/codegen/async_unary_call_impl.h \
include/grpcpp/impl/codegen/byte_buffer.h \
include/grpcpp/impl/codegen/call.h \
include/grpcpp/impl/codegen/call_hook.h \
@ -6309,6 +6364,7 @@ PUBLIC_HEADERS_CXX += \
include/grpcpp/impl/codegen/callback_common.h \
include/grpcpp/impl/codegen/channel_interface.h \
include/grpcpp/impl/codegen/client_callback.h \
include/grpcpp/impl/codegen/client_callback_impl.h \
include/grpcpp/impl/codegen/client_context.h \
include/grpcpp/impl/codegen/client_context_impl.h \
include/grpcpp/impl/codegen/client_interceptor.h \
@ -6331,6 +6387,7 @@ PUBLIC_HEADERS_CXX += \
include/grpcpp/impl/codegen/security/auth_context.h \
include/grpcpp/impl/codegen/serialization_traits.h \
include/grpcpp/impl/codegen/server_callback.h \
include/grpcpp/impl/codegen/server_callback_impl.h \
include/grpcpp/impl/codegen/server_context.h \
include/grpcpp/impl/codegen/server_context_impl.h \
include/grpcpp/impl/codegen/server_interceptor.h \
@ -6342,6 +6399,7 @@ PUBLIC_HEADERS_CXX += \
include/grpcpp/impl/codegen/string_ref.h \
include/grpcpp/impl/codegen/stub_options.h \
include/grpcpp/impl/codegen/sync_stream.h \
include/grpcpp/impl/codegen/sync_stream_impl.h \
include/grpcpp/impl/codegen/time.h \
include/grpcpp/impl/codegen/sync.h \
include/grpc/census.h \
@ -6709,7 +6767,9 @@ PUBLIC_HEADERS_CXX += \
include/grpc++/impl/codegen/time.h \
include/grpcpp/impl/codegen/async_generic_service.h \
include/grpcpp/impl/codegen/async_stream.h \
include/grpcpp/impl/codegen/async_stream_impl.h \
include/grpcpp/impl/codegen/async_unary_call.h \
include/grpcpp/impl/codegen/async_unary_call_impl.h \
include/grpcpp/impl/codegen/byte_buffer.h \
include/grpcpp/impl/codegen/call.h \
include/grpcpp/impl/codegen/call_hook.h \
@ -6718,6 +6778,7 @@ PUBLIC_HEADERS_CXX += \
include/grpcpp/impl/codegen/callback_common.h \
include/grpcpp/impl/codegen/channel_interface.h \
include/grpcpp/impl/codegen/client_callback.h \
include/grpcpp/impl/codegen/client_callback_impl.h \
include/grpcpp/impl/codegen/client_context.h \
include/grpcpp/impl/codegen/client_context_impl.h \
include/grpcpp/impl/codegen/client_interceptor.h \
@ -6740,6 +6801,7 @@ PUBLIC_HEADERS_CXX += \
include/grpcpp/impl/codegen/security/auth_context.h \
include/grpcpp/impl/codegen/serialization_traits.h \
include/grpcpp/impl/codegen/server_callback.h \
include/grpcpp/impl/codegen/server_callback_impl.h \
include/grpcpp/impl/codegen/server_context.h \
include/grpcpp/impl/codegen/server_context_impl.h \
include/grpcpp/impl/codegen/server_interceptor.h \
@ -6751,6 +6813,7 @@ PUBLIC_HEADERS_CXX += \
include/grpcpp/impl/codegen/string_ref.h \
include/grpcpp/impl/codegen/stub_options.h \
include/grpcpp/impl/codegen/sync_stream.h \
include/grpcpp/impl/codegen/sync_stream_impl.h \
include/grpcpp/impl/codegen/time.h \
include/grpc/impl/codegen/byte_buffer.h \
include/grpc/impl/codegen/byte_buffer_reader.h \
@ -6881,7 +6944,9 @@ PUBLIC_HEADERS_CXX += \
include/grpc++/impl/codegen/time.h \
include/grpcpp/impl/codegen/async_generic_service.h \
include/grpcpp/impl/codegen/async_stream.h \
include/grpcpp/impl/codegen/async_stream_impl.h \
include/grpcpp/impl/codegen/async_unary_call.h \
include/grpcpp/impl/codegen/async_unary_call_impl.h \
include/grpcpp/impl/codegen/byte_buffer.h \
include/grpcpp/impl/codegen/call.h \
include/grpcpp/impl/codegen/call_hook.h \
@ -6890,6 +6955,7 @@ PUBLIC_HEADERS_CXX += \
include/grpcpp/impl/codegen/callback_common.h \
include/grpcpp/impl/codegen/channel_interface.h \
include/grpcpp/impl/codegen/client_callback.h \
include/grpcpp/impl/codegen/client_callback_impl.h \
include/grpcpp/impl/codegen/client_context.h \
include/grpcpp/impl/codegen/client_context_impl.h \
include/grpcpp/impl/codegen/client_interceptor.h \
@ -6912,6 +6978,7 @@ PUBLIC_HEADERS_CXX += \
include/grpcpp/impl/codegen/security/auth_context.h \
include/grpcpp/impl/codegen/serialization_traits.h \
include/grpcpp/impl/codegen/server_callback.h \
include/grpcpp/impl/codegen/server_callback_impl.h \
include/grpcpp/impl/codegen/server_context.h \
include/grpcpp/impl/codegen/server_context_impl.h \
include/grpcpp/impl/codegen/server_interceptor.h \
@ -6923,6 +6990,7 @@ PUBLIC_HEADERS_CXX += \
include/grpcpp/impl/codegen/string_ref.h \
include/grpcpp/impl/codegen/stub_options.h \
include/grpcpp/impl/codegen/sync_stream.h \
include/grpcpp/impl/codegen/sync_stream_impl.h \
include/grpcpp/impl/codegen/time.h \
include/grpc/impl/codegen/byte_buffer.h \
include/grpc/impl/codegen/byte_buffer_reader.h \
@ -7101,6 +7169,7 @@ PUBLIC_HEADERS_CXX += \
include/grpcpp/channel_impl.h \
include/grpcpp/client_context.h \
include/grpcpp/completion_queue.h \
include/grpcpp/completion_queue_impl.h \
include/grpcpp/create_channel.h \
include/grpcpp/create_channel_impl.h \
include/grpcpp/create_channel_posix.h \
@ -7144,11 +7213,14 @@ PUBLIC_HEADERS_CXX += \
include/grpcpp/server_posix.h \
include/grpcpp/server_posix_impl.h \
include/grpcpp/support/async_stream.h \
include/grpcpp/support/async_stream_impl.h \
include/grpcpp/support/async_unary_call.h \
include/grpcpp/support/async_unary_call_impl.h \
include/grpcpp/support/byte_buffer.h \
include/grpcpp/support/channel_arguments.h \
include/grpcpp/support/channel_arguments_impl.h \
include/grpcpp/support/client_callback.h \
include/grpcpp/support/client_callback_impl.h \
include/grpcpp/support/client_interceptor.h \
include/grpcpp/support/config.h \
include/grpcpp/support/interceptor.h \
@ -7156,6 +7228,7 @@ PUBLIC_HEADERS_CXX += \
include/grpcpp/support/proto_buffer_reader.h \
include/grpcpp/support/proto_buffer_writer.h \
include/grpcpp/support/server_callback.h \
include/grpcpp/support/server_callback_impl.h \
include/grpcpp/support/server_interceptor.h \
include/grpcpp/support/slice.h \
include/grpcpp/support/status.h \
@ -7163,6 +7236,7 @@ PUBLIC_HEADERS_CXX += \
include/grpcpp/support/string_ref.h \
include/grpcpp/support/stub_options.h \
include/grpcpp/support/sync_stream.h \
include/grpcpp/support/sync_stream_impl.h \
include/grpcpp/support/time.h \
include/grpcpp/support/validate_service_config.h \
include/grpc/support/alloc.h \
@ -7248,7 +7322,9 @@ PUBLIC_HEADERS_CXX += \
include/grpc++/impl/codegen/time.h \
include/grpcpp/impl/codegen/async_generic_service.h \
include/grpcpp/impl/codegen/async_stream.h \
include/grpcpp/impl/codegen/async_stream_impl.h \
include/grpcpp/impl/codegen/async_unary_call.h \
include/grpcpp/impl/codegen/async_unary_call_impl.h \
include/grpcpp/impl/codegen/byte_buffer.h \
include/grpcpp/impl/codegen/call.h \
include/grpcpp/impl/codegen/call_hook.h \
@ -7257,6 +7333,7 @@ PUBLIC_HEADERS_CXX += \
include/grpcpp/impl/codegen/callback_common.h \
include/grpcpp/impl/codegen/channel_interface.h \
include/grpcpp/impl/codegen/client_callback.h \
include/grpcpp/impl/codegen/client_callback_impl.h \
include/grpcpp/impl/codegen/client_context.h \
include/grpcpp/impl/codegen/client_context_impl.h \
include/grpcpp/impl/codegen/client_interceptor.h \
@ -7279,6 +7356,7 @@ PUBLIC_HEADERS_CXX += \
include/grpcpp/impl/codegen/security/auth_context.h \
include/grpcpp/impl/codegen/serialization_traits.h \
include/grpcpp/impl/codegen/server_callback.h \
include/grpcpp/impl/codegen/server_callback_impl.h \
include/grpcpp/impl/codegen/server_context.h \
include/grpcpp/impl/codegen/server_context_impl.h \
include/grpcpp/impl/codegen/server_interceptor.h \
@ -7290,6 +7368,7 @@ PUBLIC_HEADERS_CXX += \
include/grpcpp/impl/codegen/string_ref.h \
include/grpcpp/impl/codegen/stub_options.h \
include/grpcpp/impl/codegen/sync_stream.h \
include/grpcpp/impl/codegen/sync_stream_impl.h \
include/grpcpp/impl/codegen/time.h \
include/grpcpp/impl/codegen/sync.h \
@ -9628,34 +9707,66 @@ endif
endif
DNS_RESOLVER_COOLDOWN_TEST_SRC = \
DNS_RESOLVER_COOLDOWN_USING_ARES_RESOLVER_TEST_SRC = \
test/core/client_channel/resolvers/dns_resolver_cooldown_test.cc \
DNS_RESOLVER_COOLDOWN_USING_ARES_RESOLVER_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(DNS_RESOLVER_COOLDOWN_USING_ARES_RESOLVER_TEST_SRC))))
ifeq ($(NO_SECURE),true)
# You can't build secure targets if you don't have OpenSSL.
$(BINDIR)/$(CONFIG)/dns_resolver_cooldown_using_ares_resolver_test: openssl_dep_error
else
$(BINDIR)/$(CONFIG)/dns_resolver_cooldown_using_ares_resolver_test: $(DNS_RESOLVER_COOLDOWN_USING_ARES_RESOLVER_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a
$(E) "[LD] Linking $@"
$(Q) mkdir -p `dirname $@`
$(Q) $(LD) $(LDFLAGS) $(DNS_RESOLVER_COOLDOWN_USING_ARES_RESOLVER_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/dns_resolver_cooldown_using_ares_resolver_test
endif
$(OBJDIR)/$(CONFIG)/test/core/client_channel/resolvers/dns_resolver_cooldown_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a
deps_dns_resolver_cooldown_using_ares_resolver_test: $(DNS_RESOLVER_COOLDOWN_USING_ARES_RESOLVER_TEST_OBJS:.o=.dep)
ifneq ($(NO_SECURE),true)
ifneq ($(NO_DEPS),true)
-include $(DNS_RESOLVER_COOLDOWN_USING_ARES_RESOLVER_TEST_OBJS:.o=.dep)
endif
endif
DNS_RESOLVER_COOLDOWN_USING_NATIVE_RESOLVER_TEST_SRC = \
test/core/client_channel/resolvers/dns_resolver_cooldown_test.cc \
DNS_RESOLVER_COOLDOWN_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(DNS_RESOLVER_COOLDOWN_TEST_SRC))))
DNS_RESOLVER_COOLDOWN_USING_NATIVE_RESOLVER_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(DNS_RESOLVER_COOLDOWN_USING_NATIVE_RESOLVER_TEST_SRC))))
ifeq ($(NO_SECURE),true)
# You can't build secure targets if you don't have OpenSSL.
$(BINDIR)/$(CONFIG)/dns_resolver_cooldown_test: openssl_dep_error
$(BINDIR)/$(CONFIG)/dns_resolver_cooldown_using_native_resolver_test: openssl_dep_error
else
$(BINDIR)/$(CONFIG)/dns_resolver_cooldown_test: $(DNS_RESOLVER_COOLDOWN_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a
$(BINDIR)/$(CONFIG)/dns_resolver_cooldown_using_native_resolver_test: $(DNS_RESOLVER_COOLDOWN_USING_NATIVE_RESOLVER_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a
$(E) "[LD] Linking $@"
$(Q) mkdir -p `dirname $@`
$(Q) $(LD) $(LDFLAGS) $(DNS_RESOLVER_COOLDOWN_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/dns_resolver_cooldown_test
$(Q) $(LD) $(LDFLAGS) $(DNS_RESOLVER_COOLDOWN_USING_NATIVE_RESOLVER_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/dns_resolver_cooldown_using_native_resolver_test
endif
$(OBJDIR)/$(CONFIG)/test/core/client_channel/resolvers/dns_resolver_cooldown_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a
deps_dns_resolver_cooldown_test: $(DNS_RESOLVER_COOLDOWN_TEST_OBJS:.o=.dep)
deps_dns_resolver_cooldown_using_native_resolver_test: $(DNS_RESOLVER_COOLDOWN_USING_NATIVE_RESOLVER_TEST_OBJS:.o=.dep)
ifneq ($(NO_SECURE),true)
ifneq ($(NO_DEPS),true)
-include $(DNS_RESOLVER_COOLDOWN_TEST_OBJS:.o=.dep)
-include $(DNS_RESOLVER_COOLDOWN_USING_NATIVE_RESOLVER_TEST_OBJS:.o=.dep)
endif
endif
@ -10208,7 +10319,7 @@ endif
GPR_HOST_PORT_TEST_SRC = \
test/core/gpr/host_port_test.cc \
test/core/gprpp/host_port_test.cc \
GPR_HOST_PORT_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(GPR_HOST_PORT_TEST_SRC))))
ifeq ($(NO_SECURE),true)
@ -10228,7 +10339,7 @@ $(BINDIR)/$(CONFIG)/gpr_host_port_test: $(GPR_HOST_PORT_TEST_OBJS) $(LIBDIR)/$(C
endif
$(OBJDIR)/$(CONFIG)/test/core/gpr/host_port_test.o: $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a
$(OBJDIR)/$(CONFIG)/test/core/gprpp/host_port_test.o: $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a
deps_gpr_host_port_test: $(GPR_HOST_PORT_TEST_OBJS:.o=.dep)
@ -10882,38 +10993,6 @@ endif
endif
GRPC_FETCH_OAUTH2_SRC = \
test/core/security/fetch_oauth2.cc \
GRPC_FETCH_OAUTH2_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(GRPC_FETCH_OAUTH2_SRC))))
ifeq ($(NO_SECURE),true)
# You can't build secure targets if you don't have OpenSSL.
$(BINDIR)/$(CONFIG)/grpc_fetch_oauth2: openssl_dep_error
else
$(BINDIR)/$(CONFIG)/grpc_fetch_oauth2: $(GRPC_FETCH_OAUTH2_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a
$(E) "[LD] Linking $@"
$(Q) mkdir -p `dirname $@`
$(Q) $(LD) $(LDFLAGS) $(GRPC_FETCH_OAUTH2_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/grpc_fetch_oauth2
endif
$(OBJDIR)/$(CONFIG)/test/core/security/fetch_oauth2.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a
deps_grpc_fetch_oauth2: $(GRPC_FETCH_OAUTH2_OBJS:.o=.dep)
ifneq ($(NO_SECURE),true)
ifneq ($(NO_DEPS),true)
-include $(GRPC_FETCH_OAUTH2_OBJS:.o=.dep)
endif
endif
GRPC_IPV6_LOOPBACK_AVAILABLE_TEST_SRC = \
test/core/iomgr/grpc_ipv6_loopback_available_test.cc \
@ -12110,6 +12189,38 @@ endif
endif
MPMCQUEUE_TEST_SRC = \
test/core/iomgr/mpmcqueue_test.cc \
MPMCQUEUE_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(MPMCQUEUE_TEST_SRC))))
ifeq ($(NO_SECURE),true)
# You can't build secure targets if you don't have OpenSSL.
$(BINDIR)/$(CONFIG)/mpmcqueue_test: openssl_dep_error
else
$(BINDIR)/$(CONFIG)/mpmcqueue_test: $(MPMCQUEUE_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a
$(E) "[LD] Linking $@"
$(Q) mkdir -p `dirname $@`
$(Q) $(LD) $(LDFLAGS) $(MPMCQUEUE_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/mpmcqueue_test
endif
$(OBJDIR)/$(CONFIG)/test/core/iomgr/mpmcqueue_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a
deps_mpmcqueue_test: $(MPMCQUEUE_TEST_OBJS:.o=.dep)
ifneq ($(NO_SECURE),true)
ifneq ($(NO_DEPS),true)
-include $(MPMCQUEUE_TEST_OBJS:.o=.dep)
endif
endif
MULTIPLE_SERVER_QUEUES_TEST_SRC = \
test/core/end2end/multiple_server_queues_test.cc \
@ -16997,6 +17108,49 @@ ifneq ($(NO_DEPS),true)
endif
GRPC_FETCH_OAUTH2_SRC = \
test/core/security/fetch_oauth2.cc \
GRPC_FETCH_OAUTH2_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(GRPC_FETCH_OAUTH2_SRC))))
ifeq ($(NO_SECURE),true)
# You can't build secure targets if you don't have OpenSSL.
$(BINDIR)/$(CONFIG)/grpc_fetch_oauth2: openssl_dep_error
else
ifeq ($(NO_PROTOBUF),true)
# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.5.0+.
$(BINDIR)/$(CONFIG)/grpc_fetch_oauth2: protobuf_dep_error
else
$(BINDIR)/$(CONFIG)/grpc_fetch_oauth2: $(PROTOBUF_DEP) $(GRPC_FETCH_OAUTH2_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a
$(E) "[LD] Linking $@"
$(Q) mkdir -p `dirname $@`
$(Q) $(LDXX) $(LDFLAGS) $(GRPC_FETCH_OAUTH2_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/grpc_fetch_oauth2
endif
endif
$(OBJDIR)/$(CONFIG)/test/core/security/fetch_oauth2.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a
deps_grpc_fetch_oauth2: $(GRPC_FETCH_OAUTH2_OBJS:.o=.dep)
ifneq ($(NO_SECURE),true)
ifneq ($(NO_DEPS),true)
-include $(GRPC_FETCH_OAUTH2_OBJS:.o=.dep)
endif
endif
GRPC_LINUX_SYSTEM_ROOTS_TEST_SRC = \
test/core/security/linux_system_roots_test.cc \
@ -17339,6 +17493,59 @@ endif
$(OBJDIR)/$(CONFIG)/test/cpp/end2end/grpclb_end2end_test.o: $(GENDIR)/src/proto/grpc/lb/v1/load_balancer.pb.cc $(GENDIR)/src/proto/grpc/lb/v1/load_balancer.grpc.pb.cc
GRPCLB_FALLBACK_TEST_SRC = \
$(GENDIR)/src/proto/grpc/testing/empty.pb.cc $(GENDIR)/src/proto/grpc/testing/empty.grpc.pb.cc \
$(GENDIR)/src/proto/grpc/testing/messages.pb.cc $(GENDIR)/src/proto/grpc/testing/messages.grpc.pb.cc \
$(GENDIR)/src/proto/grpc/testing/test.pb.cc $(GENDIR)/src/proto/grpc/testing/test.grpc.pb.cc \
test/cpp/interop/grpclb_fallback_test.cc \
GRPCLB_FALLBACK_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(GRPCLB_FALLBACK_TEST_SRC))))
ifeq ($(NO_SECURE),true)
# You can't build secure targets if you don't have OpenSSL.
$(BINDIR)/$(CONFIG)/grpclb_fallback_test: openssl_dep_error
else
ifeq ($(NO_PROTOBUF),true)
# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.5.0+.
$(BINDIR)/$(CONFIG)/grpclb_fallback_test: protobuf_dep_error
else
$(BINDIR)/$(CONFIG)/grpclb_fallback_test: $(PROTOBUF_DEP) $(GRPCLB_FALLBACK_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a
$(E) "[LD] Linking $@"
$(Q) mkdir -p `dirname $@`
$(Q) $(LDXX) $(LDFLAGS) $(GRPCLB_FALLBACK_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/grpclb_fallback_test
endif
endif
$(OBJDIR)/$(CONFIG)/src/proto/grpc/testing/empty.o: $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a
$(OBJDIR)/$(CONFIG)/src/proto/grpc/testing/messages.o: $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a
$(OBJDIR)/$(CONFIG)/src/proto/grpc/testing/test.o: $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a
$(OBJDIR)/$(CONFIG)/test/cpp/interop/grpclb_fallback_test.o: $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a
deps_grpclb_fallback_test: $(GRPCLB_FALLBACK_TEST_OBJS:.o=.dep)
ifneq ($(NO_SECURE),true)
ifneq ($(NO_DEPS),true)
-include $(GRPCLB_FALLBACK_TEST_OBJS:.o=.dep)
endif
endif
$(OBJDIR)/$(CONFIG)/test/cpp/interop/grpclb_fallback_test.o: $(GENDIR)/src/proto/grpc/testing/empty.pb.cc $(GENDIR)/src/proto/grpc/testing/empty.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/messages.pb.cc $(GENDIR)/src/proto/grpc/testing/messages.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/test.pb.cc $(GENDIR)/src/proto/grpc/testing/test.grpc.pb.cc
H2_SSL_CERT_TEST_SRC = \
test/core/end2end/h2_ssl_cert_test.cc \
@ -19656,6 +19863,49 @@ $(OBJDIR)/$(CONFIG)/test/cpp/interop/stress_test.o: $(GENDIR)/src/proto/grpc/tes
$(OBJDIR)/$(CONFIG)/test/cpp/util/metrics_server.o: $(GENDIR)/src/proto/grpc/testing/empty.pb.cc $(GENDIR)/src/proto/grpc/testing/empty.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/messages.pb.cc $(GENDIR)/src/proto/grpc/testing/messages.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/metrics.pb.cc $(GENDIR)/src/proto/grpc/testing/metrics.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/test.pb.cc $(GENDIR)/src/proto/grpc/testing/test.grpc.pb.cc
STRING_VIEW_TEST_SRC = \
test/core/gprpp/string_view_test.cc \
STRING_VIEW_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(STRING_VIEW_TEST_SRC))))
ifeq ($(NO_SECURE),true)
# You can't build secure targets if you don't have OpenSSL.
$(BINDIR)/$(CONFIG)/string_view_test: openssl_dep_error
else
ifeq ($(NO_PROTOBUF),true)
# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.5.0+.
$(BINDIR)/$(CONFIG)/string_view_test: protobuf_dep_error
else
$(BINDIR)/$(CONFIG)/string_view_test: $(PROTOBUF_DEP) $(STRING_VIEW_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a
$(E) "[LD] Linking $@"
$(Q) mkdir -p `dirname $@`
$(Q) $(LDXX) $(LDFLAGS) $(STRING_VIEW_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/string_view_test
endif
endif
$(OBJDIR)/$(CONFIG)/test/core/gprpp/string_view_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a
deps_string_view_test: $(STRING_VIEW_TEST_OBJS:.o=.dep)
ifneq ($(NO_SECURE),true)
ifneq ($(NO_DEPS),true)
-include $(STRING_VIEW_TEST_OBJS:.o=.dep)
endif
endif
THREAD_MANAGER_TEST_SRC = \
test/cpp/thread_manager/thread_manager_test.cc \
@ -20323,6 +20573,37 @@ ifneq ($(NO_DEPS),true)
endif
BAD_STREAMING_ID_BAD_CLIENT_TEST_SRC = \
test/core/bad_client/tests/bad_streaming_id.cc \
BAD_STREAMING_ID_BAD_CLIENT_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(BAD_STREAMING_ID_BAD_CLIENT_TEST_SRC))))
ifeq ($(NO_PROTOBUF),true)
# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.5.0+.
$(BINDIR)/$(CONFIG)/bad_streaming_id_bad_client_test: protobuf_dep_error
else
$(BINDIR)/$(CONFIG)/bad_streaming_id_bad_client_test: $(PROTOBUF_DEP) $(BAD_STREAMING_ID_BAD_CLIENT_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libbad_client_test.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr.a
$(E) "[LD] Linking $@"
$(Q) mkdir -p `dirname $@`
$(Q) $(LDXX) $(LDFLAGS) $(BAD_STREAMING_ID_BAD_CLIENT_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libbad_client_test.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/bad_streaming_id_bad_client_test
endif
$(OBJDIR)/$(CONFIG)/test/core/bad_client/tests/bad_streaming_id.o: $(LIBDIR)/$(CONFIG)/libbad_client_test.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr.a
deps_bad_streaming_id_bad_client_test: $(BAD_STREAMING_ID_BAD_CLIENT_TEST_OBJS:.o=.dep)
ifneq ($(NO_DEPS),true)
-include $(BAD_STREAMING_ID_BAD_CLIENT_TEST_OBJS:.o=.dep)
endif
BADREQ_BAD_CLIENT_TEST_SRC = \
test/core/bad_client/tests/badreq.cc \
@ -20540,6 +20821,37 @@ ifneq ($(NO_DEPS),true)
endif
OUT_OF_BOUNDS_BAD_CLIENT_TEST_SRC = \
test/core/bad_client/tests/out_of_bounds.cc \
OUT_OF_BOUNDS_BAD_CLIENT_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(OUT_OF_BOUNDS_BAD_CLIENT_TEST_SRC))))
ifeq ($(NO_PROTOBUF),true)
# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.5.0+.
$(BINDIR)/$(CONFIG)/out_of_bounds_bad_client_test: protobuf_dep_error
else
$(BINDIR)/$(CONFIG)/out_of_bounds_bad_client_test: $(PROTOBUF_DEP) $(OUT_OF_BOUNDS_BAD_CLIENT_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libbad_client_test.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr.a
$(E) "[LD] Linking $@"
$(Q) mkdir -p `dirname $@`
$(Q) $(LDXX) $(LDFLAGS) $(OUT_OF_BOUNDS_BAD_CLIENT_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libbad_client_test.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/out_of_bounds_bad_client_test
endif
$(OBJDIR)/$(CONFIG)/test/core/bad_client/tests/out_of_bounds.o: $(LIBDIR)/$(CONFIG)/libbad_client_test.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr.a
deps_out_of_bounds_bad_client_test: $(OUT_OF_BOUNDS_BAD_CLIENT_TEST_OBJS:.o=.dep)
ifneq ($(NO_DEPS),true)
-include $(OUT_OF_BOUNDS_BAD_CLIENT_TEST_OBJS:.o=.dep)
endif
SERVER_REGISTERED_METHOD_BAD_CLIENT_TEST_SRC = \
test/core/bad_client/tests/server_registered_method.cc \

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

@ -20,7 +20,7 @@ register_toolchains(
git_repository(
name = "io_bazel_rules_python",
commit = "8b5d0683a7d878b28fffe464779c8a53659fc645",
commit = "fdbb17a4118a1728d19e638a5291b4c4266ea5b8",
remote = "https://github.com/bazelbuild/rules_python.git",
)

@ -88,7 +88,7 @@ def cc_grpc_library(
generate_cc(
name = codegen_grpc_target,
srcs = proto_targets,
plugin = "@com_github_grpc_grpc//:grpc_cpp_plugin",
plugin = "@com_github_grpc_grpc//src/compiler:grpc_cpp_plugin",
well_known_protos = well_known_protos,
generate_mocks = generate_mocks,
**kwargs

@ -41,11 +41,11 @@ def _join_directories(directories):
def generate_cc_impl(ctx):
"""Implementation of the generate_cc rule."""
protos = [f for src in ctx.attr.srcs for f in src.proto.check_deps_sources.to_list()]
protos = [f for src in ctx.attr.srcs for f in src[ProtoInfo].check_deps_sources.to_list()]
includes = [
f
for src in ctx.attr.srcs
for f in src.proto.transitive_imports.to_list()
for f in src[ProtoInfo].transitive_imports.to_list()
]
outs = []
proto_root = get_proto_root(
@ -146,7 +146,7 @@ _generate_cc = rule(
"srcs": attr.label_list(
mandatory = True,
allow_empty = False,
providers = ["proto"],
providers = [ProtoInfo],
),
"plugin": attr.label(
executable = True,

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

@ -28,12 +28,12 @@ def _get_staged_proto_file(context, source_file):
def _generate_py_impl(context):
protos = []
for src in context.attr.deps:
for file in src.proto.direct_sources:
for file in src[ProtoInfo].direct_sources:
protos.append(_get_staged_proto_file(context, file))
includes = [
file
for src in context.attr.deps
for file in src.proto.transitive_imports.to_list()
for file in src[ProtoInfo].transitive_imports.to_list()
]
proto_root = get_proto_root(context.label.workspace_root)
format_str = (_GENERATED_GRPC_PROTO_FORMAT if context.executable.plugin else _GENERATED_PROTO_FORMAT)
@ -99,7 +99,7 @@ __generate_py = rule(
"deps": attr.label_list(
mandatory = True,
allow_empty = False,
providers = ["proto"],
providers = [ProtoInfo],
),
"plugin": attr.label(
executable = True,
@ -163,7 +163,7 @@ def py_proto_library(
_generate_py(
name = codegen_grpc_target,
deps = deps,
plugin = "//:grpc_python_plugin",
plugin = "//src/compiler:grpc_python_plugin",
well_known_protos = well_known_protos,
**kwargs
)

@ -122,7 +122,6 @@ filegroups:
- src/core/lib/gpr/env_linux.cc
- src/core/lib/gpr/env_posix.cc
- src/core/lib/gpr/env_windows.cc
- src/core/lib/gpr/host_port.cc
- src/core/lib/gpr/log.cc
- src/core/lib/gpr/log_android.cc
- src/core/lib/gpr/log_linux.cc
@ -149,6 +148,7 @@ filegroups:
- src/core/lib/gprpp/arena.cc
- src/core/lib/gprpp/fork.cc
- src/core/lib/gprpp/global_config_env.cc
- src/core/lib/gprpp/host_port.cc
- src/core/lib/gprpp/thd_posix.cc
- src/core/lib/gprpp/thd_windows.cc
- src/core/lib/profiling/basic_timers.cc
@ -178,7 +178,6 @@ filegroups:
- src/core/lib/gpr/alloc.h
- src/core/lib/gpr/arena.h
- src/core/lib/gpr/env.h
- src/core/lib/gpr/host_port.h
- src/core/lib/gpr/mpscq.h
- src/core/lib/gpr/murmur_hash.h
- src/core/lib/gpr/spinlock.h
@ -199,6 +198,7 @@ filegroups:
- src/core/lib/gprpp/global_config_custom.h
- src/core/lib/gprpp/global_config_env.h
- src/core/lib/gprpp/global_config_generic.h
- src/core/lib/gprpp/host_port.h
- src/core/lib/gprpp/manual_constructor.h
- src/core/lib/gprpp/map.h
- src/core/lib/gprpp/memory.h
@ -280,6 +280,7 @@ filegroups:
- src/core/lib/iomgr/ev_windows.cc
- src/core/lib/iomgr/exec_ctx.cc
- src/core/lib/iomgr/executor.cc
- src/core/lib/iomgr/executor/mpmcqueue.cc
- src/core/lib/iomgr/fork_posix.cc
- src/core/lib/iomgr/fork_windows.cc
- src/core/lib/iomgr/gethostname_fallback.cc
@ -444,6 +445,7 @@ filegroups:
- src/core/lib/gprpp/orphanable.h
- src/core/lib/gprpp/ref_counted.h
- src/core/lib/gprpp/ref_counted_ptr.h
- src/core/lib/gprpp/string_view.h
- src/core/lib/http/format_request.h
- src/core/lib/http/httpcli.h
- src/core/lib/http/parser.h
@ -466,6 +468,7 @@ filegroups:
- src/core/lib/iomgr/ev_posix.h
- src/core/lib/iomgr/exec_ctx.h
- src/core/lib/iomgr/executor.h
- src/core/lib/iomgr/executor/mpmcqueue.h
- src/core/lib/iomgr/gethostname.h
- src/core/lib/iomgr/grpc_if_nametoindex.h
- src/core/lib/iomgr/internal_errqueue.h
@ -1250,7 +1253,9 @@ filegroups:
- include/grpc++/impl/codegen/time.h
- include/grpcpp/impl/codegen/async_generic_service.h
- include/grpcpp/impl/codegen/async_stream.h
- include/grpcpp/impl/codegen/async_stream_impl.h
- include/grpcpp/impl/codegen/async_unary_call.h
- include/grpcpp/impl/codegen/async_unary_call_impl.h
- include/grpcpp/impl/codegen/byte_buffer.h
- include/grpcpp/impl/codegen/call.h
- include/grpcpp/impl/codegen/call_hook.h
@ -1259,6 +1264,7 @@ filegroups:
- include/grpcpp/impl/codegen/callback_common.h
- include/grpcpp/impl/codegen/channel_interface.h
- include/grpcpp/impl/codegen/client_callback.h
- include/grpcpp/impl/codegen/client_callback_impl.h
- include/grpcpp/impl/codegen/client_context.h
- include/grpcpp/impl/codegen/client_context_impl.h
- include/grpcpp/impl/codegen/client_interceptor.h
@ -1281,6 +1287,7 @@ filegroups:
- include/grpcpp/impl/codegen/security/auth_context.h
- include/grpcpp/impl/codegen/serialization_traits.h
- include/grpcpp/impl/codegen/server_callback.h
- include/grpcpp/impl/codegen/server_callback_impl.h
- include/grpcpp/impl/codegen/server_context.h
- include/grpcpp/impl/codegen/server_context_impl.h
- include/grpcpp/impl/codegen/server_interceptor.h
@ -1292,6 +1299,7 @@ filegroups:
- include/grpcpp/impl/codegen/string_ref.h
- include/grpcpp/impl/codegen/stub_options.h
- include/grpcpp/impl/codegen/sync_stream.h
- include/grpcpp/impl/codegen/sync_stream_impl.h
- include/grpcpp/impl/codegen/time.h
uses:
- grpc_codegen
@ -1366,6 +1374,7 @@ filegroups:
- include/grpcpp/channel_impl.h
- include/grpcpp/client_context.h
- include/grpcpp/completion_queue.h
- include/grpcpp/completion_queue_impl.h
- include/grpcpp/create_channel.h
- include/grpcpp/create_channel_impl.h
- include/grpcpp/create_channel_posix.h
@ -1409,11 +1418,14 @@ filegroups:
- include/grpcpp/server_posix.h
- include/grpcpp/server_posix_impl.h
- include/grpcpp/support/async_stream.h
- include/grpcpp/support/async_stream_impl.h
- include/grpcpp/support/async_unary_call.h
- include/grpcpp/support/async_unary_call_impl.h
- include/grpcpp/support/byte_buffer.h
- include/grpcpp/support/channel_arguments.h
- include/grpcpp/support/channel_arguments_impl.h
- include/grpcpp/support/client_callback.h
- include/grpcpp/support/client_callback_impl.h
- include/grpcpp/support/client_interceptor.h
- include/grpcpp/support/config.h
- include/grpcpp/support/interceptor.h
@ -1421,6 +1433,7 @@ filegroups:
- include/grpcpp/support/proto_buffer_reader.h
- include/grpcpp/support/proto_buffer_writer.h
- include/grpcpp/support/server_callback.h
- include/grpcpp/support/server_callback_impl.h
- include/grpcpp/support/server_interceptor.h
- include/grpcpp/support/slice.h
- include/grpcpp/support/status.h
@ -1428,6 +1441,7 @@ filegroups:
- include/grpcpp/support/string_ref.h
- include/grpcpp/support/stub_options.h
- include/grpcpp/support/sync_stream.h
- include/grpcpp/support/sync_stream_impl.h
- include/grpcpp/support/time.h
- include/grpcpp/support/validate_service_config.h
headers:
@ -1955,6 +1969,7 @@ libs:
language: c++
headers:
- src/compiler/config.h
- src/compiler/config_protobuf.h
- src/compiler/cpp_generator.h
- src/compiler/cpp_generator_helpers.h
- src/compiler/csharp_generator.h
@ -2399,7 +2414,7 @@ targets:
- gpr
exclude_iomgrs:
- uv
- name: dns_resolver_cooldown_test
- name: dns_resolver_cooldown_using_ares_resolver_test
build: test
language: c
src:
@ -2408,6 +2423,19 @@ targets:
- grpc_test_util
- grpc
- gpr
args:
- --resolver=ares
- name: dns_resolver_cooldown_using_native_resolver_test
build: test
language: c
src:
- test/core/client_channel/resolvers/dns_resolver_cooldown_test.cc
deps:
- grpc_test_util
- grpc
- gpr
args:
- --resolver=native
- name: dns_resolver_test
build: test
language: c
@ -2625,7 +2653,7 @@ targets:
build: test
language: c
src:
- test/core/gpr/host_port_test.cc
- test/core/gprpp/host_port_test.cc
deps:
- gpr
- grpc_test_util_unsecure
@ -2836,16 +2864,6 @@ targets:
- grpc_test_util
- grpc
- gpr
- name: grpc_fetch_oauth2
build: test
run: false
language: c
src:
- test/core/security/fetch_oauth2.cc
deps:
- grpc_test_util
- grpc
- gpr
- name: grpc_ipv6_loopback_available_test
build: test
language: c
@ -3266,6 +3284,16 @@ targets:
- grpc
- gpr
uses_polling: false
- name: mpmcqueue_test
build: test
language: c
src:
- test/core/iomgr/mpmcqueue_test.cc
deps:
- grpc_test_util
- grpc
- gpr
uses_polling: false
- name: multiple_server_queues_test
build: test
language: c
@ -4908,6 +4936,17 @@ targets:
deps:
- grpc_plugin_support
secure: false
- name: grpc_fetch_oauth2
build: test
run: false
language: c++
src:
- test/core/security/fetch_oauth2.cc
deps:
- grpc_test_util
- grpc++
- grpc
- gpr
- name: grpc_linux_system_roots_test
gtest: true
build: test
@ -5002,6 +5041,23 @@ targets:
- grpc++
- grpc
- gpr
- name: grpclb_fallback_test
build: test
language: c++
src:
- src/proto/grpc/testing/empty.proto
- src/proto/grpc/testing/messages.proto
- src/proto/grpc/testing/test.proto
- test/cpp/interop/grpclb_fallback_test.cc
deps:
- grpc++_test_util
- grpc_test_util
- grpc++
- grpc
- gpr
- grpc++_test_config
platforms:
- linux
- name: h2_ssl_cert_test
gtest: true
build: test
@ -5760,6 +5816,19 @@ targets:
- grpc
- gpr
- grpc++_test_config
- name: string_view_test
gtest: true
build: test
language: c++
src:
- test/core/gprpp/string_view_test.cc
deps:
- grpc_test_util
- grpc++
- grpc
- gpr
uses:
- grpc++_test
- name: thread_manager_test
build: test
language: c++

@ -53,7 +53,6 @@ if test "$PHP_GRPC" != "no"; then
src/core/lib/gpr/env_linux.cc \
src/core/lib/gpr/env_posix.cc \
src/core/lib/gpr/env_windows.cc \
src/core/lib/gpr/host_port.cc \
src/core/lib/gpr/log.cc \
src/core/lib/gpr/log_android.cc \
src/core/lib/gpr/log_linux.cc \
@ -80,6 +79,7 @@ if test "$PHP_GRPC" != "no"; then
src/core/lib/gprpp/arena.cc \
src/core/lib/gprpp/fork.cc \
src/core/lib/gprpp/global_config_env.cc \
src/core/lib/gprpp/host_port.cc \
src/core/lib/gprpp/thd_posix.cc \
src/core/lib/gprpp/thd_windows.cc \
src/core/lib/profiling/basic_timers.cc \
@ -127,6 +127,7 @@ if test "$PHP_GRPC" != "no"; then
src/core/lib/iomgr/ev_windows.cc \
src/core/lib/iomgr/exec_ctx.cc \
src/core/lib/iomgr/executor.cc \
src/core/lib/iomgr/executor/mpmcqueue.cc \
src/core/lib/iomgr/fork_posix.cc \
src/core/lib/iomgr/fork_windows.cc \
src/core/lib/iomgr/gethostname_fallback.cc \
@ -726,6 +727,7 @@ if test "$PHP_GRPC" != "no"; then
PHP_ADD_BUILD_DIR($ext_builddir/src/core/lib/gprpp)
PHP_ADD_BUILD_DIR($ext_builddir/src/core/lib/http)
PHP_ADD_BUILD_DIR($ext_builddir/src/core/lib/iomgr)
PHP_ADD_BUILD_DIR($ext_builddir/src/core/lib/iomgr/executor)
PHP_ADD_BUILD_DIR($ext_builddir/src/core/lib/json)
PHP_ADD_BUILD_DIR($ext_builddir/src/core/lib/profiling)
PHP_ADD_BUILD_DIR($ext_builddir/src/core/lib/security/context)

@ -28,7 +28,6 @@ if (PHP_GRPC != "no") {
"src\\core\\lib\\gpr\\env_linux.cc " +
"src\\core\\lib\\gpr\\env_posix.cc " +
"src\\core\\lib\\gpr\\env_windows.cc " +
"src\\core\\lib\\gpr\\host_port.cc " +
"src\\core\\lib\\gpr\\log.cc " +
"src\\core\\lib\\gpr\\log_android.cc " +
"src\\core\\lib\\gpr\\log_linux.cc " +
@ -55,6 +54,7 @@ if (PHP_GRPC != "no") {
"src\\core\\lib\\gprpp\\arena.cc " +
"src\\core\\lib\\gprpp\\fork.cc " +
"src\\core\\lib\\gprpp\\global_config_env.cc " +
"src\\core\\lib\\gprpp\\host_port.cc " +
"src\\core\\lib\\gprpp\\thd_posix.cc " +
"src\\core\\lib\\gprpp\\thd_windows.cc " +
"src\\core\\lib\\profiling\\basic_timers.cc " +
@ -102,6 +102,7 @@ if (PHP_GRPC != "no") {
"src\\core\\lib\\iomgr\\ev_windows.cc " +
"src\\core\\lib\\iomgr\\exec_ctx.cc " +
"src\\core\\lib\\iomgr\\executor.cc " +
"src\\core\\lib\\iomgr\\executor\\mpmcqueue.cc " +
"src\\core\\lib\\iomgr\\fork_posix.cc " +
"src\\core\\lib\\iomgr\\fork_windows.cc " +
"src\\core\\lib\\iomgr\\gethostname_fallback.cc " +
@ -739,6 +740,7 @@ if (PHP_GRPC != "no") {
FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\lib\\gprpp");
FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\lib\\http");
FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\lib\\iomgr");
FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\lib\\iomgr\\executor");
FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\lib\\json");
FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\lib\\profiling");
FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\lib\\security");

@ -21,9 +21,13 @@ C++ compatible with
## Constraints
- No use of standard library
- No use of standard library if it requires link-time dependency
- Standard library makes wrapping difficult/impossible and also reduces platform portability
- This takes precedence over using C++ style guide
- Limited use of standard library if it does not require link-time dependency
- We can use things from `std::` as long as they are header-only implementations.
- Since the standard library API does not specify whether any given part of the API is implemented header-only, the only way to know is to try using something and see if our tests fail.
- Since there is no guarantee that some header-only implementation in the standard library will remain header-only in the future, we should define our own API in lib/gprpp that is an alias for the thing we want to use in `std::` and use the gprpp API in core. That way, if we later need to stop using the thing from `std::`, we can replace the alias with our own implementation.
- But lambdas are ok
- As are third-party libraries that meet our build requirements (such as many parts of abseil)
- There will be some C++ features that don't work

@ -71,4 +71,4 @@ The following status codes are never generated by the library:
- OUT_OF_RANGE
- DATA_LOSS
Applications that may wish to [retry](https:github.com/grpc/proposal/blob/master/A6-client-retries.md) failed RPCs must decide which status codes on which to retry. As shown in the table above, the gRPC library can generate the same status code for different cases. Server applications can also return those same status codes. Therefore, there is no fixed list of status codes on which it is appropriate to retry in all applications. As a result, individual applications must make their own determination as to which status codes should cause an RPC to be retried.
Applications that may wish to [retry](https://github.com/grpc/proposal/blob/master/A6-client-retries.md) failed RPCs must decide which status codes on which to retry. As shown in the table above, the gRPC library can generate the same status code for different cases. Server applications can also return those same status codes. Therefore, there is no fixed list of status codes on which it is appropriate to retry in all applications. As a result, individual applications must make their own determination as to which status codes should cause an RPC to be retried.

@ -0,0 +1,41 @@
# gRPC Versioning Guide
## Versioning Overview
All gRPC implementations use a three-part version number (`vX.Y.Z`) and strictly follow [semantic versioning](https://semver.org/), which defines the semantics of major, minor and patch components of the version number. In addition to that, gRPC versions evolve according to these rules:
- **Major version bumps** only happen on rare occasions. In order to qualify for a major version bump, certain criteria described later in this document need to be met. Most importantly, a major version increase must not break wire compatibility with other gRPC implementations so that existing gRPC libraries remain fully interoperable.
- **Minor version bumps** happen approx. every 6 weeks as part of the normal release cycle as defined by the gRPC release process. A new release branch named vMAJOR.MINOR.PATCH) is cut every 6 weeks based on the [release schedule](https://github.com/grpc/grpc/blob/master/doc/grpc_release_schedule.md).
- **Patch version bump** corresponds to bugfixes done on release branch.
There are also a few extra rules regarding adding new gRPC implementations (e.g. adding support for a new language)
- New implementations start at v0.x.y version and until they reach 1.0, they are considered not ready for production workloads. Breaking API changes are allowed in the 0.x releases as the library is not considered stable yet.
- The "1.0" release has semantics of GA (generally available) and being production ready. Requirements to reach this milestone are at least these
- basic RPC features are feature complete and tested
- implementation is tested for interoperability with other languages
- Public API is declared stable
- Once a gRPC library reaches 1.0 (or higher version), the normal rules for versioning apply.
## Policy for updating the major version number
To avoid user confusion and simplify reasoning, the gRPC releases in different languages try to stay synchronized in terms of major and minor version (all languages follow the same release schedule). Nevertheless, because we also strictly follow semantic versioning, there are circumstances in which a gRPC implementation needs to break the version synchronicity and do a major version bump independently of other languages.
### Situations when it's ok to do a major version bump
- **change forced by the language ecosystem:** when the language itself or its standard libraries that we depend on make a breaking change (something which is out of our control), reacting with updating gRPC APIs may be the only adequate response.
- **voluntary change:** Even in non-forced situations, there might be circumstances in which a breaking API change makes sense and represents a net win, but as a rule of thumb breaking changes are very disruptive for users, cause user fragmentation and incur high maintenance costs. Therefore, breaking API changes should be very rare events that need to be considered with extreme care and the bar for accepting such changes is intentionally set very high.
Example scenarios where a breaking API change might be adequate:
- fixing a security problem which requires changes to API (need to consider the non-breaking alternatives first)
- the change leads to very significant gains to security, usability or development velocity. These gains need to be clearly documented and claims need to be supported by evidence (ideally by numbers). Costs to the ecosystem (impact on users, dev team etc.) need to be taken into account and the change still needs to be a net positive after subtracting the costs.
All proposals to make a breaking change need to be documented as a gRFC document (in the grpc/proposal repository) that covers at least these areas:
- Description of the proposal including an explanation why the proposed change is one of the very rare events where a breaking change is introduced.
- Migration costs (= what does it mean for the users to migrate to the new API, what are the costs and risks associated with it)
- Pros of the change (what is gained and how)
- Cons of the change (e.g. user confusion, lost users and user trust, work needed, added maintenance costs)
- Plan for supporting users still using the old major version (in case migration to the new major version is not trivial or not everyone can migrate easily)
Note that while major version bump allows changing APIs used by the users, it must not impact the interoperability of the implementation with other gRPC implementations and the previous major version released. That means that **no backward incompatible protocol changes are allowed**: old clients must continue interoperating correctly with new servers and new servers with old clients.
### Situations that DON'T warrant a major version bump
- Because other languages do so. This is not a good enough reason because
doing a major version bump has high potential for disturbing and confusing the users of that language and fragmenting the user base and that is a bigger threat than having language implementations at different major version (provided the state is well documented). Having some languages at different major version seems to be unavoidable anyway (due to forced version bumps), unless we bump some languages artificially.
- "I don't like this API": In retrospect, some API decisions made in the past necessarily turn out more lucky than others, but without strong reasons that would be in favor of changing the API and without enough supporting evidence (see previous section), other strategy than making a breaking API change needs to be used. Possible options: Expand the API to make it useful again; mark API as deprecated while keeping its functionality and providing a new better API.

@ -17,7 +17,7 @@
# See cmake_externalproject/CMakeLists.txt for all-in-one cmake build
# that automatically builds all the dependencies before building helloworld.
cmake_minimum_required(VERSION 2.8)
cmake_minimum_required(VERSION 3.5.1)
project(HelloWorld C CXX)

@ -20,7 +20,7 @@
# including the "helloworld" project itself.
# See https://blog.kitware.com/cmake-superbuilds-git-submodules/
cmake_minimum_required(VERSION 2.8)
cmake_minimum_required(VERSION 3.5.1)
# Project
project(HelloWorld-SuperBuild C CXX)

@ -0,0 +1,65 @@
# 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.
filegroup(
name = "_credentials_files",
testonly = 1,
srcs = [
"credentials/localhost.key",
"credentials/localhost.crt",
"credentials/root.crt",
],
)
py_library(
name = "_credentials",
testonly = 1,
srcs = ["_credentials.py"],
data = [":_credentials_files"],
)
py_binary(
name = "customized_auth_client",
testonly = 1,
srcs = ["customized_auth_client.py"],
deps = [
":_credentials",
"//src/python/grpcio/grpc:grpcio",
"//examples:py_helloworld",
],
)
py_binary(
name = "customized_auth_server",
testonly = 1,
srcs = ["customized_auth_server.py"],
deps = [
":_credentials",
"//src/python/grpcio/grpc:grpcio",
"//examples:py_helloworld",
],
)
py_test(
name = "_auth_example_test",
srcs = ["test/_auth_example_test.py"],
deps = [
"//src/python/grpcio/grpc:grpcio",
"//examples:py_helloworld",
":customized_auth_client",
":customized_auth_server",
":_credentials",
],
)

@ -0,0 +1,112 @@
# Authentication Extension Example in gRPC Python
## Check Our Guide First
For most common usage of authentication in gRPC Python, please see our
[Authentication](https://grpc.io/docs/guides/auth/) guide's Python section. The
Guide includes following scenarios:
1. Server SSL credential setup
2. Client SSL credential setup
3. Authenticate with Google using a JWT
4. Authenticate with Google using an Oauth2 token
Also, the guide talks about gRPC specific credential types.
### Channel credentials
Channel credentials are attached to a `Channel` object, the most common use case
are SSL credentials.
### Call credentials
Call credentials are attached to a `Call` object (corresponding to an RPC).
Under the hood, the call credentials is a function that takes in information of
the RPC and modify metadata through callback.
## About This Example
This example focuses on extending gRPC authentication mechanism:
1) Customize authentication plugin;
2) Composite client side credentials;
3) Validation through interceptor on server side.
## AuthMetadataPlugin: Manipulate metadata for each call
Unlike TLS/SSL based authentication, the authentication extension in gRPC Python
lives at a much higher level of networking. It relies on the transmission of
metadata (HTTP Header) between client and server, instead of alternating the
transport protocol.
gRPC Python provides a way to intercept an RPC and append authentication related
metadata through
[`AuthMetadataPlugin`](https://grpc.github.io/grpc/python/grpc.html#grpc.AuthMetadataPlugin).
Those in need of a custom authentication method may simply provide a concrete
implementation of the following interface:
```Python
class AuthMetadataPlugin:
"""A specification for custom authentication."""
def __call__(self, context, callback):
"""Implements authentication by passing metadata to a callback.
Implementations of this method must not block.
Args:
context: An AuthMetadataContext providing information on the RPC that
the plugin is being called to authenticate.
callback: An AuthMetadataPluginCallback to be invoked either
synchronously or asynchronously.
"""
```
Then pass the instance of the concrete implementation to
`grpc.metadata_call_credentials` function to be converted into a
`CallCredentials` object. Please NOTE that it is possible to pass a Python
function object directly, but we recommend to inherit from the base class to
ensure implementation correctness.
```Python
def metadata_call_credentials(metadata_plugin, name=None):
"""Construct CallCredentials from an AuthMetadataPlugin.
Args:
metadata_plugin: An AuthMetadataPlugin to use for authentication.
name: An optional name for the plugin.
Returns:
A CallCredentials.
"""
```
The `CallCredentials` object can be passed directly into an RPC like:
```Python
call_credentials = grpc.metadata_call_credentials(my_foo_plugin)
stub.FooRpc(request, credentials=call_credentials)
```
Or you can use `ChannelCredentials` and `CallCredentials` at the same time by
combining them:
```Python
channel_credentials = ...
call_credentials = ...
composite_credentials = grpc.composite_channel_credentials(
channel_credential,
call_credentials)
channel = grpc.secure_channel(server_address, composite_credentials)
```
It is also possible to apply multiple `CallCredentials` to a single RPC:
```Python
call_credentials_foo = ...
call_credentials_bar = ...
call_credentials = grpc.composite_call_credentials(
call_credentials_foo,
call_credentials_bar)
stub.FooRpc(request, credentials=call_credentials)
```

@ -0,0 +1,31 @@
# 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.
"""Loading SSL credentials for gRPC Python authentication example."""
from __future__ import absolute_import
from __future__ import division
from __future__ import print_function
import os
def _load_credential_from_file(filepath):
real_path = os.path.join(os.path.dirname(__file__), filepath)
with open(real_path, 'rb') as f:
return f.read()
SERVER_CERTIFICATE = _load_credential_from_file('credentials/localhost.crt')
SERVER_CERTIFICATE_KEY = _load_credential_from_file('credentials/localhost.key')
ROOT_CERTIFICATE = _load_credential_from_file('credentials/root.crt')

@ -0,0 +1,19 @@
-----BEGIN CERTIFICATE-----
MIIDFjCCAf4CCQCzrLIhrWa55zANBgkqhkiG9w0BAQsFADBCMQswCQYDVQQGEwJV
UzETMBEGA1UECAwKQ2FsaWZvcm5pYTEPMA0GA1UECgwGR29vZ2xlMQ0wCwYDVQQL
DARnUlBDMCAXDTE5MDYyNDIyMjIzM1oYDzIxMTkwNTMxMjIyMjMzWjBWMQswCQYD
VQQGEwJVUzETMBEGA1UECAwKQ2FsaWZvcm5pYTEPMA0GA1UECgwGR29vZ2xlMQ0w
CwYDVQQLDARnUlBDMRIwEAYDVQQDDAlsb2NhbGhvc3QwggEiMA0GCSqGSIb3DQEB
AQUAA4IBDwAwggEKAoIBAQCtCW0TjugnIUu8BEVIYvdMP+/2GENQDjZhZ8eKR5C6
toDGbgjsDtt/GxISAg4cg70fIvy0XolnGPZodvfHDM4lJ7yHBOdZD8TXQoE6okR7
HZuLUJ20M0pXgWqtRewKRUjuYsSDXBnzLiZw1dcv9nGpo+Bqa8NonpiGRRpEkshF
D6T9KU9Ts/x+wMQBIra2Gj0UMh79jPhUuxcYAQA0JQGivnOtdwuPiumpnUT8j8h6
tWg5l01EsCZWJecCF85KnGpJEVYPyPqBqGsy0nGS9plGotOWF87+jyUQt+KD63xA
aBmTro86mKDDKEK4JvzjVeMGz2UbVcLPiiZnErTFaiXJAgMBAAEwDQYJKoZIhvcN
AQELBQADggEBAKsDgOPCWp5WCy17vJbRlgfgk05sVNIHZtzrmdswjBmvSg8MUpep
XqcPNUpsljAXsf9UM5IFEMRdilUsFGWvHjBEtNAW8WUK9UV18WRuU//0w1Mp5HAN
xUEKb4BoyZr65vlCnTR+AR5c9FfPvLibhr5qHs2RA8Y3GyLOcGqBWed87jhdQLCc
P1bxB+96le5JeXq0tw215lxonI2/3ZYVK4/ok9gwXrQoWm8YieJqitk/ZQ4S17/4
pynHtDfdxLn23EXeGx+UTxJGfpRmhEZdJ+MN7QGYoomzx5qS5XoYKxRNrDlirJpr
OqXIn8E1it+6d5gOZfuHawcNGhRLplE/pfA=
-----END CERTIFICATE-----

@ -0,0 +1,27 @@
-----BEGIN RSA PRIVATE KEY-----
MIIEogIBAAKCAQEArQltE47oJyFLvARFSGL3TD/v9hhDUA42YWfHikeQuraAxm4I
7A7bfxsSEgIOHIO9HyL8tF6JZxj2aHb3xwzOJSe8hwTnWQ/E10KBOqJEex2bi1Cd
tDNKV4FqrUXsCkVI7mLEg1wZ8y4mcNXXL/ZxqaPgamvDaJ6YhkUaRJLIRQ+k/SlP
U7P8fsDEASK2tho9FDIe/Yz4VLsXGAEANCUBor5zrXcLj4rpqZ1E/I/IerVoOZdN
RLAmViXnAhfOSpxqSRFWD8j6gahrMtJxkvaZRqLTlhfO/o8lELfig+t8QGgZk66P
OpigwyhCuCb841XjBs9lG1XCz4omZxK0xWolyQIDAQABAoIBADeq/Kh6JT3RfGf0
h8WN8TlaqHxnueAbcmtL0+oss+cdp7gu1jf7X6o4r0uT1a5ew40s2Fe+wj2kzkE1
ZOlouTlC22gkr7j7Vbxa7PBMG/Pvxoa/XL0IczZLsGImSJXVTG1E4SvRiZeulTdf
1GbdxhtpWV1jZe5Wd4Na3+SHxF5S7m3PrHiZlYdz1ND+8XZs1NlL9+ej72qSFul9
t/QjMWJ9pky/Wad5abnRLRyOsg+BsgnXbkUy2rD89ZxFMLda9pzXo3TPyAlBHonr
mkEsE4eRMWMpjBM79JbeyDdHn/cs/LjAZrzeDf7ugXr2CHQpKaM5O0PsNHezJII9
L5kCfzECgYEA4M/rz1UP1/BJoSqigUlSs0tPAg8a5UlkVsh6Osuq72IPNo8qg/Fw
oV/IiIS+q+obRcFj1Od3PGdTpCJwW5dzd2fXBQGmGdj0HucnCrs13RtBh91JiF5i
y/YYI9KfgOG2ZT9gG68T0gTs6jRrS3Qd83npqjrkJqMOd7s00MK9tUcCgYEAxQq7
T541oCYHSBRIIb0IrR25krZy9caxzCqPDwOcuuhaCqCiaq+ATvOWlSfgecm4eH0K
PCH0xlWxG0auPEwm4pA8+/WR/XJwscPZMuoht1EoKy1his4eKx/s7hHNeO6KOF0V
Y/zqIiuZnEwUoKbn7EqqNFSTT65PJKyGsICJFG8CgYAfaw9yl1myfQNdQb8aQGwN
YJ33FLNWje427qeeZe5KrDKiFloDvI9YDjHRWnPnRL1w/zj7fSm9yFb5HlMDieP6
MQnsyjEzdY2QcA+VwVoiv3dmDHgFVeOKy6bOAtaFxYWfGr9MvygO9t9BT/gawGyb
JVORlc9i0vDnrMMR1dV7awKBgBpTWLtGc/u1mPt0Wj7HtsUKV6TWY32a0l5owTxM
S0BdksogtBJ06DukJ9Y9wawD23WdnyRxlPZ6tHLkeprrwbY7dypioOKvy4a0l+xJ
g7+uRCOgqIuXBkjUtx8HmeAyXp0xMo5tWArAsIFFWOwt4IadYygitJvMuh44PraO
NcJZAoGADEiV0dheXUCVr8DrtSom8DQMj92/G/FIYjXL8OUhh0+F+YlYP0+F8PEU
yYIWEqL/S5tVKYshimUXQa537JcRKsTVJBG/ZKD2kuqgOc72zQy3oplimXeJDCXY
h2eAQ0u8GN6tN9C4t8Kp4a3y6FGsxgu+UTxdnL3YQ+yHAVhtCzo=
-----END RSA PRIVATE KEY-----

@ -0,0 +1,20 @@
-----BEGIN CERTIFICATE-----
MIIDWTCCAkGgAwIBAgIJAPOConZMwykwMA0GCSqGSIb3DQEBCwUAMEIxCzAJBgNV
BAYTAlVTMRMwEQYDVQQIDApDYWxpZm9ybmlhMQ8wDQYDVQQKDAZHb29nbGUxDTAL
BgNVBAsMBGdSUEMwIBcNMTkwNjI0MjIyMDA3WhgPMjExOTA1MzEyMjIwMDdaMEIx
CzAJBgNVBAYTAlVTMRMwEQYDVQQIDApDYWxpZm9ybmlhMQ8wDQYDVQQKDAZHb29n
bGUxDTALBgNVBAsMBGdSUEMwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB
AQCwqei3TfyLidnQNDJ2lierMYo229K92DuORni7nSjJQ59Jc3dNMsmqGQJjCD8o
6mTlKM/oCbs27Wpx+OxcOLvT95j2kiDGca1fCvaMdguIod09SWiyMpv/hp0trLv7
NJIKHznath6rHYX2Ii3fZ1yCPzyQbEPSAA+GNpoNm1v1ZWmWKke9v7vLlS3inNlW
Mt9jepK7DrtbNZnVDjeItnppBSbVYRMxIyNHkepFbqXx5TpkCvl4M4XQZw9bfSxQ
i3WZ3q+T1Tw//OUdPNc+OfMhu0MA0QoMwikskP0NaIC3dbJZ5Ogx0RcnaB4E+9C6
O/znUEh3WuKVl5HXBF+UwWoFAgMBAAGjUDBOMB0GA1UdDgQWBBRm3JIgzgK4G97J
fbMGatWMZc7V3jAfBgNVHSMEGDAWgBRm3JIgzgK4G97JfbMGatWMZc7V3jAMBgNV
HRMEBTADAQH/MA0GCSqGSIb3DQEBCwUAA4IBAQCNiV8x41if094ry2srS0YucpiN
3rTPk08FOLsENTMYai524TGXJti1P6ofGr5KXCL0uxTByHE3fEiMMud2TIY5iHQo
Y4mzDTTcb+Q7yKHwYZMlcp6nO8W+NeY5t+S0JPHhb8deKWepcN2UpXBUYQLw7AiE
l96T9Gi+vC9h/XE5IVwHFQXTxf5UYzXtW1nfapvrOONg/ms41dgmrRKIi+knWfiJ
FdHpHX2sfDAoJtnpEISX+nxRGNVTLY64utXWm4yxaZJshvy2s8zWJgRg7rtwAhTT
Np9E9MnihXLEmDI4Co9XlLPJyZFmqImsbmVuKFeQOCiLAoPJaMI2lbi7fiTo
-----END CERTIFICATE-----

@ -0,0 +1,105 @@
# 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.
"""Client of the Python example of customizing authentication mechanism."""
from __future__ import absolute_import
from __future__ import division
from __future__ import print_function
import argparse
import contextlib
import logging
import grpc
from examples import helloworld_pb2
from examples import helloworld_pb2_grpc
from examples.python.auth import _credentials
_LOGGER = logging.getLogger(__name__)
_LOGGER.setLevel(logging.INFO)
_ONE_DAY_IN_SECONDS = 60 * 60 * 24
_SERVER_ADDR_TEMPLATE = 'localhost:%d'
_SIGNATURE_HEADER_KEY = 'x-signature'
class AuthGateway(grpc.AuthMetadataPlugin):
def __call__(self, context, callback):
"""Implements authentication by passing metadata to a callback.
Implementations of this method must not block.
Args:
context: An AuthMetadataContext providing information on the RPC that
the plugin is being called to authenticate.
callback: An AuthMetadataPluginCallback to be invoked either
synchronously or asynchronously.
"""
# Example AuthMetadataContext object:
# AuthMetadataContext(
# service_url=u'https://localhost:50051/helloworld.Greeter',
# method_name=u'SayHello')
signature = context.method_name[::-1]
callback(((_SIGNATURE_HEADER_KEY, signature),), None)
@contextlib.contextmanager
def create_client_channel(addr):
# Call credential object will be invoked for every single RPC
call_credentials = grpc.metadata_call_credentials(
AuthGateway(), name='auth gateway')
# Channel credential will be valid for the entire channel
channel_credential = grpc.ssl_channel_credentials(
_credentials.ROOT_CERTIFICATE)
# Combining channel credentials and call credentials together
composite_credentials = grpc.composite_channel_credentials(
channel_credential,
call_credentials,
)
channel = grpc.secure_channel(addr, composite_credentials)
yield channel
def send_rpc(channel):
stub = helloworld_pb2_grpc.GreeterStub(channel)
request = helloworld_pb2.HelloRequest(name='you')
try:
response = stub.SayHello(request)
except grpc.RpcError as rpc_error:
_LOGGER.error('Received error: %s', rpc_error)
return rpc_error
else:
_LOGGER.info('Received message: %s', response)
return response
def main():
parser = argparse.ArgumentParser()
parser.add_argument(
'--port',
nargs='?',
type=int,
default=50051,
help='the address of server')
args = parser.parse_args()
with create_client_channel(_SERVER_ADDR_TEMPLATE % args.port) as channel:
send_rpc(channel)
if __name__ == '__main__':
logging.basicConfig(level=logging.INFO)
main()

@ -0,0 +1,110 @@
# 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.
"""Server of the Python example of customizing authentication mechanism."""
from __future__ import absolute_import
from __future__ import division
from __future__ import print_function
import argparse
import contextlib
import logging
import time
from concurrent import futures
import grpc
from examples import helloworld_pb2
from examples import helloworld_pb2_grpc
from examples.python.auth import _credentials
_LOGGER = logging.getLogger(__name__)
_LOGGER.setLevel(logging.INFO)
_ONE_DAY_IN_SECONDS = 60 * 60 * 24
_LISTEN_ADDRESS_TEMPLATE = 'localhost:%d'
_SIGNATURE_HEADER_KEY = 'x-signature'
class SignatureValidationInterceptor(grpc.ServerInterceptor):
def __init__(self):
def abort(ignored_request, context):
context.abort(grpc.StatusCode.UNAUTHENTICATED, 'Invalid signature')
self._abortion = grpc.unary_unary_rpc_method_handler(abort)
def intercept_service(self, continuation, handler_call_details):
# Example HandlerCallDetails object:
# _HandlerCallDetails(
# method=u'/helloworld.Greeter/SayHello',
# invocation_metadata=...)
method_name = handler_call_details.method.split('/')[-1]
expected_metadata = (_SIGNATURE_HEADER_KEY, method_name[::-1])
if expected_metadata in handler_call_details.invocation_metadata:
return continuation(handler_call_details)
else:
return self._abortion
class SimpleGreeter(helloworld_pb2_grpc.GreeterServicer):
def SayHello(self, request, unused_context):
return helloworld_pb2.HelloReply(message='Hello, %s!' % request.name)
@contextlib.contextmanager
def run_server(port):
# Bind interceptor to server
server = grpc.server(
futures.ThreadPoolExecutor(),
interceptors=(SignatureValidationInterceptor(),))
helloworld_pb2_grpc.add_GreeterServicer_to_server(SimpleGreeter(), server)
# Loading credentials
server_credentials = grpc.ssl_server_credentials(((
_credentials.SERVER_CERTIFICATE_KEY,
_credentials.SERVER_CERTIFICATE,
),))
# Pass down credentials
port = server.add_secure_port(_LISTEN_ADDRESS_TEMPLATE % port,
server_credentials)
server.start()
try:
yield port
finally:
server.stop(0)
def main():
parser = argparse.ArgumentParser()
parser.add_argument(
'--port', nargs='?', type=int, default=50051, help='the listening port')
args = parser.parse_args()
with run_server(args.port) as port:
logging.info('Server is listening at port :%d', port)
try:
while True:
time.sleep(_ONE_DAY_IN_SECONDS)
except KeyboardInterrupt:
pass
if __name__ == '__main__':
logging.basicConfig(level=logging.INFO)
main()

@ -0,0 +1,56 @@
# Copyright 2019 The gRPC Authors
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""Test for gRPC Python authentication example."""
from __future__ import absolute_import
from __future__ import division
from __future__ import print_function
import unittest
import grpc
from examples.python.auth import _credentials
from examples.python.auth import customized_auth_client
from examples.python.auth import customized_auth_server
_SERVER_ADDR_TEMPLATE = 'localhost:%d'
class AuthExampleTest(unittest.TestCase):
def test_successful_call(self):
with customized_auth_server.run_server(0) as port:
with customized_auth_client.create_client_channel(
_SERVER_ADDR_TEMPLATE % port) as channel:
customized_auth_client.send_rpc(channel)
# No unhandled exception raised, test passed!
def test_no_channel_credential(self):
with customized_auth_server.run_server(0) as port:
with grpc.insecure_channel(_SERVER_ADDR_TEMPLATE % port) as channel:
resp = customized_auth_client.send_rpc(channel)
self.assertEqual(resp.code(), grpc.StatusCode.UNAVAILABLE)
def test_no_call_credential(self):
with customized_auth_server.run_server(0) as port:
channel_credential = grpc.ssl_channel_credentials(
_credentials.ROOT_CERTIFICATE)
with grpc.secure_channel(_SERVER_ADDR_TEMPLATE % port,
channel_credential) as channel:
resp = customized_auth_client.send_rpc(channel)
self.assertEqual(resp.code(), grpc.StatusCode.UNAUTHENTICATED)
if __name__ == '__main__':
unittest.main(verbosity=2)

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

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

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

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

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

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

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

@ -85,6 +85,7 @@ Pod::Spec.new do |s|
'include/grpcpp/channel_impl.h',
'include/grpcpp/client_context.h',
'include/grpcpp/completion_queue.h',
'include/grpcpp/completion_queue_impl.h',
'include/grpcpp/create_channel.h',
'include/grpcpp/create_channel_impl.h',
'include/grpcpp/create_channel_posix.h',
@ -128,11 +129,14 @@ Pod::Spec.new do |s|
'include/grpcpp/server_posix.h',
'include/grpcpp/server_posix_impl.h',
'include/grpcpp/support/async_stream.h',
'include/grpcpp/support/async_stream_impl.h',
'include/grpcpp/support/async_unary_call.h',
'include/grpcpp/support/async_unary_call_impl.h',
'include/grpcpp/support/byte_buffer.h',
'include/grpcpp/support/channel_arguments.h',
'include/grpcpp/support/channel_arguments_impl.h',
'include/grpcpp/support/client_callback.h',
'include/grpcpp/support/client_callback_impl.h',
'include/grpcpp/support/client_interceptor.h',
'include/grpcpp/support/config.h',
'include/grpcpp/support/interceptor.h',
@ -140,6 +144,7 @@ Pod::Spec.new do |s|
'include/grpcpp/support/proto_buffer_reader.h',
'include/grpcpp/support/proto_buffer_writer.h',
'include/grpcpp/support/server_callback.h',
'include/grpcpp/support/server_callback_impl.h',
'include/grpcpp/support/server_interceptor.h',
'include/grpcpp/support/slice.h',
'include/grpcpp/support/status.h',
@ -147,11 +152,14 @@ Pod::Spec.new do |s|
'include/grpcpp/support/string_ref.h',
'include/grpcpp/support/stub_options.h',
'include/grpcpp/support/sync_stream.h',
'include/grpcpp/support/sync_stream_impl.h',
'include/grpcpp/support/time.h',
'include/grpcpp/support/validate_service_config.h',
'include/grpcpp/impl/codegen/async_generic_service.h',
'include/grpcpp/impl/codegen/async_stream.h',
'include/grpcpp/impl/codegen/async_stream_impl.h',
'include/grpcpp/impl/codegen/async_unary_call.h',
'include/grpcpp/impl/codegen/async_unary_call_impl.h',
'include/grpcpp/impl/codegen/byte_buffer.h',
'include/grpcpp/impl/codegen/call.h',
'include/grpcpp/impl/codegen/call_hook.h',
@ -160,6 +168,7 @@ Pod::Spec.new do |s|
'include/grpcpp/impl/codegen/callback_common.h',
'include/grpcpp/impl/codegen/channel_interface.h',
'include/grpcpp/impl/codegen/client_callback.h',
'include/grpcpp/impl/codegen/client_callback_impl.h',
'include/grpcpp/impl/codegen/client_context.h',
'include/grpcpp/impl/codegen/client_context_impl.h',
'include/grpcpp/impl/codegen/client_interceptor.h',
@ -182,6 +191,7 @@ Pod::Spec.new do |s|
'include/grpcpp/impl/codegen/security/auth_context.h',
'include/grpcpp/impl/codegen/serialization_traits.h',
'include/grpcpp/impl/codegen/server_callback.h',
'include/grpcpp/impl/codegen/server_callback_impl.h',
'include/grpcpp/impl/codegen/server_context.h',
'include/grpcpp/impl/codegen/server_context_impl.h',
'include/grpcpp/impl/codegen/server_interceptor.h',
@ -193,6 +203,7 @@ Pod::Spec.new do |s|
'include/grpcpp/impl/codegen/string_ref.h',
'include/grpcpp/impl/codegen/stub_options.h',
'include/grpcpp/impl/codegen/sync_stream.h',
'include/grpcpp/impl/codegen/sync_stream_impl.h',
'include/grpcpp/impl/codegen/time.h',
'include/grpcpp/impl/codegen/sync.h'
end
@ -261,7 +272,6 @@ Pod::Spec.new do |s|
'src/core/lib/gpr/alloc.h',
'src/core/lib/gpr/arena.h',
'src/core/lib/gpr/env.h',
'src/core/lib/gpr/host_port.h',
'src/core/lib/gpr/mpscq.h',
'src/core/lib/gpr/murmur_hash.h',
'src/core/lib/gpr/spinlock.h',
@ -282,6 +292,7 @@ Pod::Spec.new do |s|
'src/core/lib/gprpp/global_config_custom.h',
'src/core/lib/gprpp/global_config_env.h',
'src/core/lib/gprpp/global_config_generic.h',
'src/core/lib/gprpp/host_port.h',
'src/core/lib/gprpp/manual_constructor.h',
'src/core/lib/gprpp/map.h',
'src/core/lib/gprpp/memory.h',
@ -444,6 +455,7 @@ Pod::Spec.new do |s|
'src/core/lib/gprpp/orphanable.h',
'src/core/lib/gprpp/ref_counted.h',
'src/core/lib/gprpp/ref_counted_ptr.h',
'src/core/lib/gprpp/string_view.h',
'src/core/lib/http/format_request.h',
'src/core/lib/http/httpcli.h',
'src/core/lib/http/parser.h',
@ -466,6 +478,7 @@ Pod::Spec.new do |s|
'src/core/lib/iomgr/ev_posix.h',
'src/core/lib/iomgr/exec_ctx.h',
'src/core/lib/iomgr/executor.h',
'src/core/lib/iomgr/executor/mpmcqueue.h',
'src/core/lib/iomgr/gethostname.h',
'src/core/lib/iomgr/grpc_if_nametoindex.h',
'src/core/lib/iomgr/internal_errqueue.h',
@ -591,7 +604,6 @@ Pod::Spec.new do |s|
'src/core/lib/gpr/alloc.h',
'src/core/lib/gpr/arena.h',
'src/core/lib/gpr/env.h',
'src/core/lib/gpr/host_port.h',
'src/core/lib/gpr/mpscq.h',
'src/core/lib/gpr/murmur_hash.h',
'src/core/lib/gpr/spinlock.h',
@ -612,6 +624,7 @@ Pod::Spec.new do |s|
'src/core/lib/gprpp/global_config_custom.h',
'src/core/lib/gprpp/global_config_env.h',
'src/core/lib/gprpp/global_config_generic.h',
'src/core/lib/gprpp/host_port.h',
'src/core/lib/gprpp/manual_constructor.h',
'src/core/lib/gprpp/map.h',
'src/core/lib/gprpp/memory.h',
@ -648,6 +661,7 @@ Pod::Spec.new do |s|
'src/core/lib/gprpp/orphanable.h',
'src/core/lib/gprpp/ref_counted.h',
'src/core/lib/gprpp/ref_counted_ptr.h',
'src/core/lib/gprpp/string_view.h',
'src/core/lib/http/format_request.h',
'src/core/lib/http/httpcli.h',
'src/core/lib/http/parser.h',
@ -670,6 +684,7 @@ Pod::Spec.new do |s|
'src/core/lib/iomgr/ev_posix.h',
'src/core/lib/iomgr/exec_ctx.h',
'src/core/lib/iomgr/executor.h',
'src/core/lib/iomgr/executor/mpmcqueue.h',
'src/core/lib/iomgr/gethostname.h',
'src/core/lib/iomgr/grpc_if_nametoindex.h',
'src/core/lib/iomgr/internal_errqueue.h',

@ -191,7 +191,6 @@ Pod::Spec.new do |s|
ss.source_files = 'src/core/lib/gpr/alloc.h',
'src/core/lib/gpr/arena.h',
'src/core/lib/gpr/env.h',
'src/core/lib/gpr/host_port.h',
'src/core/lib/gpr/mpscq.h',
'src/core/lib/gpr/murmur_hash.h',
'src/core/lib/gpr/spinlock.h',
@ -212,6 +211,7 @@ Pod::Spec.new do |s|
'src/core/lib/gprpp/global_config_custom.h',
'src/core/lib/gprpp/global_config_env.h',
'src/core/lib/gprpp/global_config_generic.h',
'src/core/lib/gprpp/host_port.h',
'src/core/lib/gprpp/manual_constructor.h',
'src/core/lib/gprpp/map.h',
'src/core/lib/gprpp/memory.h',
@ -228,7 +228,6 @@ Pod::Spec.new do |s|
'src/core/lib/gpr/env_linux.cc',
'src/core/lib/gpr/env_posix.cc',
'src/core/lib/gpr/env_windows.cc',
'src/core/lib/gpr/host_port.cc',
'src/core/lib/gpr/log.cc',
'src/core/lib/gpr/log_android.cc',
'src/core/lib/gpr/log_linux.cc',
@ -255,6 +254,7 @@ Pod::Spec.new do |s|
'src/core/lib/gprpp/arena.cc',
'src/core/lib/gprpp/fork.cc',
'src/core/lib/gprpp/global_config_env.cc',
'src/core/lib/gprpp/host_port.cc',
'src/core/lib/gprpp/thd_posix.cc',
'src/core/lib/gprpp/thd_windows.cc',
'src/core/lib/profiling/basic_timers.cc',
@ -414,6 +414,7 @@ Pod::Spec.new do |s|
'src/core/lib/gprpp/orphanable.h',
'src/core/lib/gprpp/ref_counted.h',
'src/core/lib/gprpp/ref_counted_ptr.h',
'src/core/lib/gprpp/string_view.h',
'src/core/lib/http/format_request.h',
'src/core/lib/http/httpcli.h',
'src/core/lib/http/parser.h',
@ -436,6 +437,7 @@ Pod::Spec.new do |s|
'src/core/lib/iomgr/ev_posix.h',
'src/core/lib/iomgr/exec_ctx.h',
'src/core/lib/iomgr/executor.h',
'src/core/lib/iomgr/executor/mpmcqueue.h',
'src/core/lib/iomgr/gethostname.h',
'src/core/lib/iomgr/grpc_if_nametoindex.h',
'src/core/lib/iomgr/internal_errqueue.h',
@ -589,6 +591,7 @@ Pod::Spec.new do |s|
'src/core/lib/iomgr/ev_windows.cc',
'src/core/lib/iomgr/exec_ctx.cc',
'src/core/lib/iomgr/executor.cc',
'src/core/lib/iomgr/executor/mpmcqueue.cc',
'src/core/lib/iomgr/fork_posix.cc',
'src/core/lib/iomgr/fork_windows.cc',
'src/core/lib/iomgr/gethostname_fallback.cc',
@ -884,7 +887,6 @@ Pod::Spec.new do |s|
ss.private_header_files = 'src/core/lib/gpr/alloc.h',
'src/core/lib/gpr/arena.h',
'src/core/lib/gpr/env.h',
'src/core/lib/gpr/host_port.h',
'src/core/lib/gpr/mpscq.h',
'src/core/lib/gpr/murmur_hash.h',
'src/core/lib/gpr/spinlock.h',
@ -905,6 +907,7 @@ Pod::Spec.new do |s|
'src/core/lib/gprpp/global_config_custom.h',
'src/core/lib/gprpp/global_config_env.h',
'src/core/lib/gprpp/global_config_generic.h',
'src/core/lib/gprpp/host_port.h',
'src/core/lib/gprpp/manual_constructor.h',
'src/core/lib/gprpp/map.h',
'src/core/lib/gprpp/memory.h',
@ -1067,6 +1070,7 @@ Pod::Spec.new do |s|
'src/core/lib/gprpp/orphanable.h',
'src/core/lib/gprpp/ref_counted.h',
'src/core/lib/gprpp/ref_counted_ptr.h',
'src/core/lib/gprpp/string_view.h',
'src/core/lib/http/format_request.h',
'src/core/lib/http/httpcli.h',
'src/core/lib/http/parser.h',
@ -1089,6 +1093,7 @@ Pod::Spec.new do |s|
'src/core/lib/iomgr/ev_posix.h',
'src/core/lib/iomgr/exec_ctx.h',
'src/core/lib/iomgr/executor.h',
'src/core/lib/iomgr/executor/mpmcqueue.h',
'src/core/lib/iomgr/gethostname.h',
'src/core/lib/iomgr/grpc_if_nametoindex.h',
'src/core/lib/iomgr/internal_errqueue.h',
@ -1382,8 +1387,7 @@ Pod::Spec.new do |s|
# TODO (mxyan): Instead of this hack, add include path "third_party" to C core's include path?
s.prepare_command = <<-END_OF_COMMAND
find src/core/ -type f ! -path '*.grpc_back' -print0 | xargs -0 -L1 sed -E -i'.grpc_back' 's;#include "(pb(_.*)?\\.h)";#include <nanopb/\\1>;g'
find src/core/ -type f -path '*.grpc_back' -print0 | xargs -0 rm
find src/core/ -type f \\( -path '*.h' -or -path '*.cc' \\) -print0 | xargs -0 -L1 sed -E -i'.grpc_back' 's;#include <openssl/;#include <openssl_grpc/;g'
sed -E -i '' 's;#include "(pb(_.*)?\\.h)";#if COCOAPODS==1\\\n #include <nanopb/\\1>\\\n#else\\\n #include "\\1"\\\n#endif;g' $(find src/core -type f -print | xargs grep -H -c '#include <nanopb/' | grep 0$ | cut -d':' -f1)
sed -E -i '' 's;#include <openssl/(.*)>;#if COCOAPODS==1\\\n #include <openssl_grpc/\\1>\\\n#else\\\n #include <openssl/\\1>\\\n#endif;g' $(find src/core -type f \\( -path '*.h' -or -path '*.cc' \\) -print | xargs grep -H -c '#include <openssl_grpc/' | grep 0$ | cut -d':' -f1)
END_OF_COMMAND
end

@ -111,6 +111,7 @@ EXPORTS
grpc_google_refresh_token_credentials_create
grpc_access_token_credentials_create
grpc_google_iam_credentials_create
grpc_sts_credentials_create
grpc_metadata_credentials_create_from_plugin
grpc_secure_channel_create
grpc_server_credentials_release

@ -13,7 +13,7 @@ Gem::Specification.new do |s|
s.description = 'Send RPCs from Ruby using GRPC'
s.license = 'Apache-2.0'
s.required_ruby_version = '>= 2.0.0'
s.required_ruby_version = '>= 2.3.0'
s.files = %w( Makefile .yardopts )
s.files += %w( etc/roots.pem )
@ -85,7 +85,6 @@ Gem::Specification.new do |s|
s.files += %w( src/core/lib/gpr/alloc.h )
s.files += %w( src/core/lib/gpr/arena.h )
s.files += %w( src/core/lib/gpr/env.h )
s.files += %w( src/core/lib/gpr/host_port.h )
s.files += %w( src/core/lib/gpr/mpscq.h )
s.files += %w( src/core/lib/gpr/murmur_hash.h )
s.files += %w( src/core/lib/gpr/spinlock.h )
@ -106,6 +105,7 @@ Gem::Specification.new do |s|
s.files += %w( src/core/lib/gprpp/global_config_custom.h )
s.files += %w( src/core/lib/gprpp/global_config_env.h )
s.files += %w( src/core/lib/gprpp/global_config_generic.h )
s.files += %w( src/core/lib/gprpp/host_port.h )
s.files += %w( src/core/lib/gprpp/manual_constructor.h )
s.files += %w( src/core/lib/gprpp/map.h )
s.files += %w( src/core/lib/gprpp/memory.h )
@ -122,7 +122,6 @@ Gem::Specification.new do |s|
s.files += %w( src/core/lib/gpr/env_linux.cc )
s.files += %w( src/core/lib/gpr/env_posix.cc )
s.files += %w( src/core/lib/gpr/env_windows.cc )
s.files += %w( src/core/lib/gpr/host_port.cc )
s.files += %w( src/core/lib/gpr/log.cc )
s.files += %w( src/core/lib/gpr/log_android.cc )
s.files += %w( src/core/lib/gpr/log_linux.cc )
@ -149,6 +148,7 @@ Gem::Specification.new do |s|
s.files += %w( src/core/lib/gprpp/arena.cc )
s.files += %w( src/core/lib/gprpp/fork.cc )
s.files += %w( src/core/lib/gprpp/global_config_env.cc )
s.files += %w( src/core/lib/gprpp/host_port.cc )
s.files += %w( src/core/lib/gprpp/thd_posix.cc )
s.files += %w( src/core/lib/gprpp/thd_windows.cc )
s.files += %w( src/core/lib/profiling/basic_timers.cc )
@ -348,6 +348,7 @@ Gem::Specification.new do |s|
s.files += %w( src/core/lib/gprpp/orphanable.h )
s.files += %w( src/core/lib/gprpp/ref_counted.h )
s.files += %w( src/core/lib/gprpp/ref_counted_ptr.h )
s.files += %w( src/core/lib/gprpp/string_view.h )
s.files += %w( src/core/lib/http/format_request.h )
s.files += %w( src/core/lib/http/httpcli.h )
s.files += %w( src/core/lib/http/parser.h )
@ -370,6 +371,7 @@ Gem::Specification.new do |s|
s.files += %w( src/core/lib/iomgr/ev_posix.h )
s.files += %w( src/core/lib/iomgr/exec_ctx.h )
s.files += %w( src/core/lib/iomgr/executor.h )
s.files += %w( src/core/lib/iomgr/executor/mpmcqueue.h )
s.files += %w( src/core/lib/iomgr/gethostname.h )
s.files += %w( src/core/lib/iomgr/grpc_if_nametoindex.h )
s.files += %w( src/core/lib/iomgr/internal_errqueue.h )
@ -523,6 +525,7 @@ Gem::Specification.new do |s|
s.files += %w( src/core/lib/iomgr/ev_windows.cc )
s.files += %w( src/core/lib/iomgr/exec_ctx.cc )
s.files += %w( src/core/lib/iomgr/executor.cc )
s.files += %w( src/core/lib/iomgr/executor/mpmcqueue.cc )
s.files += %w( src/core/lib/iomgr/fork_posix.cc )
s.files += %w( src/core/lib/iomgr/fork_windows.cc )
s.files += %w( src/core/lib/iomgr/gethostname_fallback.cc )

@ -226,7 +226,6 @@
'src/core/lib/gpr/env_linux.cc',
'src/core/lib/gpr/env_posix.cc',
'src/core/lib/gpr/env_windows.cc',
'src/core/lib/gpr/host_port.cc',
'src/core/lib/gpr/log.cc',
'src/core/lib/gpr/log_android.cc',
'src/core/lib/gpr/log_linux.cc',
@ -253,6 +252,7 @@
'src/core/lib/gprpp/arena.cc',
'src/core/lib/gprpp/fork.cc',
'src/core/lib/gprpp/global_config_env.cc',
'src/core/lib/gprpp/host_port.cc',
'src/core/lib/gprpp/thd_posix.cc',
'src/core/lib/gprpp/thd_windows.cc',
'src/core/lib/profiling/basic_timers.cc',
@ -309,6 +309,7 @@
'src/core/lib/iomgr/ev_windows.cc',
'src/core/lib/iomgr/exec_ctx.cc',
'src/core/lib/iomgr/executor.cc',
'src/core/lib/iomgr/executor/mpmcqueue.cc',
'src/core/lib/iomgr/fork_posix.cc',
'src/core/lib/iomgr/fork_windows.cc',
'src/core/lib/iomgr/gethostname_fallback.cc',
@ -685,6 +686,7 @@
'src/core/lib/iomgr/ev_windows.cc',
'src/core/lib/iomgr/exec_ctx.cc',
'src/core/lib/iomgr/executor.cc',
'src/core/lib/iomgr/executor/mpmcqueue.cc',
'src/core/lib/iomgr/fork_posix.cc',
'src/core/lib/iomgr/fork_windows.cc',
'src/core/lib/iomgr/gethostname_fallback.cc',
@ -935,6 +937,7 @@
'src/core/lib/iomgr/ev_windows.cc',
'src/core/lib/iomgr/exec_ctx.cc',
'src/core/lib/iomgr/executor.cc',
'src/core/lib/iomgr/executor/mpmcqueue.cc',
'src/core/lib/iomgr/fork_posix.cc',
'src/core/lib/iomgr/fork_windows.cc',
'src/core/lib/iomgr/gethostname_fallback.cc',
@ -1161,6 +1164,7 @@
'src/core/lib/iomgr/ev_windows.cc',
'src/core/lib/iomgr/exec_ctx.cc',
'src/core/lib/iomgr/executor.cc',
'src/core/lib/iomgr/executor/mpmcqueue.cc',
'src/core/lib/iomgr/fork_posix.cc',
'src/core/lib/iomgr/fork_windows.cc',
'src/core/lib/iomgr/gethostname_fallback.cc',

@ -328,6 +328,31 @@ GRPCAPI grpc_call_credentials* grpc_google_iam_credentials_create(
const char* authorization_token, const char* authority_selector,
void* reserved);
/** Options for creating STS Oauth Token Exchange credentials following the IETF
draft https://tools.ietf.org/html/draft-ietf-oauth-token-exchange-16.
Optional fields may be set to NULL or empty string. It is the responsibility
of the caller to ensure that the subject and actor tokens are refreshed on
disk at the specified paths. This API is used for experimental purposes for
now and may change in the future. */
typedef struct {
const char* token_exchange_service_uri; /* Required. */
const char* resource; /* Optional. */
const char* audience; /* Optional. */
const char* scope; /* Optional. */
const char* requested_token_type; /* Optional. */
const char* subject_token_path; /* Required. */
const char* subject_token_type; /* Required. */
const char* actor_token_path; /* Optional. */
const char* actor_token_type; /* Optional. */
} grpc_sts_credentials_options;
/** Creates an STS credentials following the STS Token Exchanged specifed in the
IETF draft https://tools.ietf.org/html/draft-ietf-oauth-token-exchange-16.
This API is used for experimental purposes for now and may change in the
future. */
GRPCAPI grpc_call_credentials* grpc_sts_credentials_create(
const grpc_sts_credentials_options* options, void* reserved);
/** Callback function to be called by the metadata credentials plugin
implementation when the metadata is ready.
- user_data is the opaque pointer that was passed in the get_metadata method

@ -26,7 +26,7 @@
#include <grpcpp/impl/call.h>
#include <grpcpp/impl/codegen/channel_interface.h>
#include <grpcpp/impl/codegen/client_interceptor.h>
#include <grpcpp/impl/codegen/completion_queue.h>
#include <grpcpp/impl/codegen/completion_queue_impl.h>
#include <grpcpp/impl/codegen/config.h>
#include <grpcpp/impl/codegen/grpc_library.h>
#include <grpcpp/impl/codegen/sync.h>
@ -86,22 +86,23 @@ class Channel final : public ::grpc::ChannelInterface,
::grpc::internal::Call CreateCall(const ::grpc::internal::RpcMethod& method,
::grpc_impl::ClientContext* context,
::grpc::CompletionQueue* cq) override;
::grpc_impl::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,
::grpc::CompletionQueue* cq, void* tag) override;
::grpc_impl::CompletionQueue* cq,
void* tag) override;
bool WaitForStateChangeImpl(grpc_connectivity_state last_observed,
gpr_timespec deadline) override;
::grpc::CompletionQueue* CallbackCQ() override;
::grpc_impl::CompletionQueue* CallbackCQ() override;
::grpc::internal::Call CreateCallInternal(
const ::grpc::internal::RpcMethod& method,
::grpc_impl::ClientContext* context, ::grpc::CompletionQueue* cq,
::grpc_impl::ClientContext* context, ::grpc_impl::CompletionQueue* cq,
size_t interceptor_pos) override;
const grpc::string host_;
@ -114,7 +115,7 @@ class Channel final : public ::grpc::ChannelInterface,
// 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).
::grpc::CompletionQueue* callback_cq_ = nullptr;
::grpc_impl::CompletionQueue* callback_cq_ = nullptr;
std::vector<
std::unique_ptr<::grpc::experimental::ClientInterceptorFactoryInterface>>

@ -0,0 +1,24 @@
/*
*
* Copyright 2019 gRPC authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
#ifndef GRPCPP_COMPLETION_QUEUE_IMPL_H
#define GRPCPP_COMPLETION_QUEUE_IMPL_H
#include <grpcpp/impl/codegen/completion_queue_impl.h>
#endif // GRPCPP_COMPLETION_QUEUE_IMPL_H

@ -21,17 +21,21 @@
#include <functional>
#include <grpcpp/support/async_stream.h>
#include <grpcpp/support/async_unary_call.h>
#include <grpcpp/client_context.h>
#include <grpcpp/support/async_stream_impl.h>
#include <grpcpp/support/async_unary_call_impl.h>
#include <grpcpp/support/byte_buffer.h>
#include <grpcpp/support/client_callback.h>
#include <grpcpp/support/client_callback_impl.h>
#include <grpcpp/support/status.h>
#include <functional>
namespace grpc {
typedef ClientAsyncReaderWriter<ByteBuffer, ByteBuffer>
typedef ::grpc_impl::ClientAsyncReaderWriter<ByteBuffer, ByteBuffer>
GenericClientAsyncReaderWriter;
typedef ClientAsyncResponseReader<ByteBuffer> GenericClientAsyncResponseReader;
typedef ::grpc_impl::ClientAsyncResponseReader<ByteBuffer>
GenericClientAsyncResponseReader;
} // namespace grpc
namespace grpc_impl {
class CompletionQueue;
@ -49,15 +53,15 @@ class GenericStub final {
/// succeeded (i.e. the call won't proceed if the return value is nullptr).
std::unique_ptr<grpc::GenericClientAsyncReaderWriter> PrepareCall(
grpc::ClientContext* context, const grpc::string& method,
grpc::CompletionQueue* cq);
CompletionQueue* cq);
/// Setup a unary call to a named method \a method using \a context, and don't
/// start it. Let it be started explicitly with StartCall.
/// The return value only indicates whether or not registration of the call
/// succeeded (i.e. the call won't proceed if the return value is nullptr).
std::unique_ptr<grpc::GenericClientAsyncResponseReader> PrepareUnaryCall(
grpc::ClientContext* context, const grpc::string& method,
const grpc::ByteBuffer& request, grpc::CompletionQueue* cq);
grpc_impl::ClientContext* context, const grpc::string& method,
const grpc::ByteBuffer& request, CompletionQueue* cq);
/// DEPRECATED for multi-threaded use
/// Begin a call to a named method \a method using \a context.
@ -66,8 +70,8 @@ class GenericStub final {
/// The return value only indicates whether or not registration of the call
/// succeeded (i.e. the call won't proceed if the return value is nullptr).
std::unique_ptr<grpc::GenericClientAsyncReaderWriter> Call(
grpc::ClientContext* context, const grpc::string& method,
grpc::CompletionQueue* cq, void* tag);
grpc_impl::ClientContext* context, const grpc::string& method,
CompletionQueue* cq, void* tag);
/// NOTE: class experimental_type is not part of the public API of this class
/// TODO(vjpai): Move these contents to the public API of GenericStub when
@ -78,23 +82,25 @@ class GenericStub final {
/// Setup and start a unary call to a named method \a method using
/// \a context and specifying the \a request and \a response buffers.
void UnaryCall(grpc::ClientContext* context, const grpc::string& method,
const grpc::ByteBuffer* request, grpc::ByteBuffer* response,
void UnaryCall(grpc_impl::ClientContext* context,
const grpc::string& method, const grpc::ByteBuffer* request,
grpc::ByteBuffer* response,
std::function<void(grpc::Status)> on_completion);
/// Setup and start a unary call to a named method \a method using
/// \a context and specifying the \a request and \a response buffers.
void UnaryCall(grpc::ClientContext* context, const grpc::string& method,
const grpc::ByteBuffer* request, grpc::ByteBuffer* response,
grpc::experimental::ClientUnaryReactor* reactor);
void UnaryCall(grpc_impl::ClientContext* context,
const grpc::string& method, const grpc::ByteBuffer* request,
grpc::ByteBuffer* response,
grpc_impl::experimental::ClientUnaryReactor* reactor);
/// Setup a call to a named method \a method using \a context and tied to
/// \a reactor . Like any other bidi streaming RPC, it will not be activated
/// until StartCall is invoked on its reactor.
void PrepareBidiStreamingCall(
grpc::ClientContext* context, const grpc::string& method,
grpc::experimental::ClientBidiReactor<grpc::ByteBuffer,
grpc::ByteBuffer>* reactor);
grpc_impl::ClientContext* context, const grpc::string& method,
grpc_impl::experimental::ClientBidiReactor<grpc::ByteBuffer,
grpc::ByteBuffer>* reactor);
private:
GenericStub* stub_;

@ -19,21 +19,23 @@
#ifndef GRPCPP_IMPL_CODEGEN_ASYNC_GENERIC_SERVICE_H
#define GRPCPP_IMPL_CODEGEN_ASYNC_GENERIC_SERVICE_H
#include <grpcpp/impl/codegen/async_stream.h>
#include <grpcpp/impl/codegen/async_stream_impl.h>
#include <grpcpp/impl/codegen/byte_buffer.h>
#include <grpcpp/impl/codegen/server_callback.h>
#include <grpcpp/impl/codegen/server_callback_impl.h>
struct grpc_server;
namespace grpc {
typedef ServerAsyncReaderWriter<ByteBuffer, ByteBuffer>
typedef ::grpc_impl::ServerAsyncReaderWriter<ByteBuffer, ByteBuffer>
GenericServerAsyncReaderWriter;
typedef ServerAsyncResponseWriter<ByteBuffer> GenericServerAsyncResponseWriter;
typedef ServerAsyncReader<ByteBuffer, ByteBuffer> GenericServerAsyncReader;
typedef ServerAsyncWriter<ByteBuffer> GenericServerAsyncWriter;
typedef ::grpc_impl::ServerAsyncResponseWriter<ByteBuffer>
GenericServerAsyncResponseWriter;
typedef ::grpc_impl::ServerAsyncReader<ByteBuffer, ByteBuffer>
GenericServerAsyncReader;
typedef ::grpc_impl::ServerAsyncWriter<ByteBuffer> GenericServerAsyncWriter;
class GenericServerContext final : public ServerContext {
class GenericServerContext final : public ::grpc_impl::ServerContext {
public:
const grpc::string& method() const { return method_; }
const grpc::string& host() const { return host_; }
@ -75,8 +77,9 @@ class AsyncGenericService final {
void RequestCall(GenericServerContext* ctx,
GenericServerAsyncReaderWriter* reader_writer,
CompletionQueue* call_cq,
ServerCompletionQueue* notification_cq, void* tag);
::grpc_impl::CompletionQueue* call_cq,
::grpc_impl::ServerCompletionQueue* notification_cq,
void* tag);
private:
friend class grpc_impl::Server;
@ -91,7 +94,8 @@ namespace experimental {
/// GenericServerContext rather than a ServerContext. All other reaction and
/// operation initiation APIs are the same as ServerBidiReactor.
class ServerGenericBidiReactor
: public ServerBidiReactor<ByteBuffer, ByteBuffer> {
: public ::grpc_impl::experimental::ServerBidiReactor<ByteBuffer,
ByteBuffer> {
public:
/// Similar to ServerBidiReactor::OnStarted except for argument type.
///
@ -99,7 +103,7 @@ class ServerGenericBidiReactor
virtual void OnStarted(GenericServerContext* context) {}
private:
void OnStarted(ServerContext* ctx) final {
void OnStarted(::grpc_impl::ServerContext* ctx) final {
OnStarted(static_cast<GenericServerContext*>(ctx));
}
};
@ -137,8 +141,10 @@ class CallbackGenericService {
private:
friend class ::grpc_impl::Server;
internal::CallbackBidiHandler<ByteBuffer, ByteBuffer>* Handler() {
return new internal::CallbackBidiHandler<ByteBuffer, ByteBuffer>(
::grpc_impl::internal::CallbackBidiHandler<ByteBuffer, ByteBuffer>*
Handler() {
return new ::grpc_impl::internal::CallbackBidiHandler<ByteBuffer,
ByteBuffer>(
[this] { return CreateReactor(); });
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

@ -19,298 +19,28 @@
#ifndef GRPCPP_IMPL_CODEGEN_ASYNC_UNARY_CALL_H
#define GRPCPP_IMPL_CODEGEN_ASYNC_UNARY_CALL_H
#include <assert.h>
#include <grpcpp/impl/codegen/call.h>
#include <grpcpp/impl/codegen/channel_interface.h>
#include <grpcpp/impl/codegen/client_context.h>
#include <grpcpp/impl/codegen/server_context.h>
#include <grpcpp/impl/codegen/service_type.h>
#include <grpcpp/impl/codegen/status.h>
#include <grpcpp/impl/codegen/async_unary_call_impl.h>
namespace grpc {
extern CoreCodegenInterface* g_core_codegen_interface;
/// An interface relevant for async client side unary RPCs (which send
/// one request message to a server and receive one response message).
template <class R>
class ClientAsyncResponseReaderInterface {
public:
virtual ~ClientAsyncResponseReaderInterface() {}
/// Start the call that was set up by the constructor, but only if the
/// constructor was invoked through the "Prepare" API which doesn't actually
/// start the call
virtual void StartCall() = 0;
/// Request notification of the reading of initial metadata. Completion
/// will be notified by \a tag on the associated completion queue.
/// This call is optional, but if it is used, it cannot be used concurrently
/// with or after the \a Finish method.
///
/// \param[in] tag Tag identifying this request.
virtual void ReadInitialMetadata(void* tag) = 0;
/// Request to receive the server's response \a msg and final \a status for
/// the call, and to notify \a tag on this call's completion queue when
/// finished.
///
/// This function will return when either:
/// - when the server's response message and status have been received.
/// - when the server has returned a non-OK status (no message expected in
/// this case).
/// - when the call failed for some reason and the library generated a
/// non-OK status.
///
/// \param[in] tag Tag identifying this request.
/// \param[out] status To be updated with the operation status.
/// \param[out] msg To be filled in with the server's response message.
virtual void Finish(R* msg, Status* status, void* tag) = 0;
};
namespace internal {
template <class R>
class ClientAsyncResponseReaderFactory {
public:
/// Start a call and write the request out if \a start is set.
/// \a tag will be notified on \a cq when the call has been started (i.e.
/// intitial metadata sent) and \a request has been written out.
/// If \a start is not set, the actual call must be initiated by StartCall
/// Note that \a context will be used to fill in custom initial metadata
/// used to send to the server when starting the call.
template <class W>
static ClientAsyncResponseReader<R>* Create(
ChannelInterface* channel, CompletionQueue* cq,
const ::grpc::internal::RpcMethod& method, ClientContext* context,
const W& request, bool start) {
::grpc::internal::Call call = channel->CreateCall(method, context, cq);
return new (g_core_codegen_interface->grpc_call_arena_alloc(
call.call(), sizeof(ClientAsyncResponseReader<R>)))
ClientAsyncResponseReader<R>(call, context, request, start);
}
};
} // namespace internal
using ClientAsyncResponseReaderInterface =
grpc_impl::ClientAsyncResponseReaderInterface<R>;
/// Async API for client-side unary RPCs, where the message response
/// received from the server is of type \a R.
template <class R>
class ClientAsyncResponseReader final
: public ClientAsyncResponseReaderInterface<R> {
public:
// always allocated against a call arena, no memory free required
static void operator delete(void* ptr, std::size_t size) {
assert(size == sizeof(ClientAsyncResponseReader));
}
// This operator should never be called as the memory should be freed as part
// of the arena destruction. It only exists to provide a matching operator
// delete to the operator new so that some compilers will not complain (see
// https://github.com/grpc/grpc/issues/11301) Note at the time of adding this
// there are no tests catching the compiler warning.
static void operator delete(void*, void*) { assert(0); }
void StartCall() override {
assert(!started_);
started_ = true;
StartCallInternal();
}
/// See \a ClientAsyncResponseReaderInterface::ReadInitialMetadata for
/// semantics.
///
/// Side effect:
/// - the \a ClientContext associated with this call is updated with
/// possible initial and trailing metadata sent from the server.
void ReadInitialMetadata(void* tag) override {
assert(started_);
GPR_CODEGEN_ASSERT(!context_->initial_metadata_received_);
single_buf.set_output_tag(tag);
single_buf.RecvInitialMetadata(context_);
call_.PerformOps(&single_buf);
initial_metadata_read_ = true;
}
/// See \a ClientAysncResponseReaderInterface::Finish for semantics.
///
/// Side effect:
/// - the \a ClientContext associated with this call is updated with
/// possible initial and trailing metadata sent from the server.
void Finish(R* msg, Status* status, void* tag) override {
assert(started_);
if (initial_metadata_read_) {
finish_buf.set_output_tag(tag);
finish_buf.RecvMessage(msg);
finish_buf.AllowNoMessage();
finish_buf.ClientRecvStatus(context_, status);
call_.PerformOps(&finish_buf);
} else {
single_buf.set_output_tag(tag);
single_buf.RecvInitialMetadata(context_);
single_buf.RecvMessage(msg);
single_buf.AllowNoMessage();
single_buf.ClientRecvStatus(context_, status);
call_.PerformOps(&single_buf);
}
}
private:
friend class internal::ClientAsyncResponseReaderFactory<R>;
ClientContext* const context_;
::grpc::internal::Call call_;
bool started_;
bool initial_metadata_read_ = false;
using ClientAsyncResponseReader = grpc_impl::ClientAsyncResponseReader<R>;
template <class W>
ClientAsyncResponseReader(::grpc::internal::Call call, ClientContext* context,
const W& request, bool start)
: context_(context), call_(call), started_(start) {
// Bind the metadata at time of StartCallInternal but set up the rest here
// TODO(ctiller): don't assert
GPR_CODEGEN_ASSERT(single_buf.SendMessage(request).ok());
single_buf.ClientSendClose();
if (start) StartCallInternal();
}
void StartCallInternal() {
single_buf.SendInitialMetadata(&context_->send_initial_metadata_,
context_->initial_metadata_flags());
}
// disable operator new
static void* operator new(std::size_t size);
static void* operator new(std::size_t size, void* p) { return p; }
::grpc::internal::CallOpSet<::grpc::internal::CallOpSendInitialMetadata,
::grpc::internal::CallOpSendMessage,
::grpc::internal::CallOpClientSendClose,
::grpc::internal::CallOpRecvInitialMetadata,
::grpc::internal::CallOpRecvMessage<R>,
::grpc::internal::CallOpClientRecvStatus>
single_buf;
::grpc::internal::CallOpSet<::grpc::internal::CallOpRecvMessage<R>,
::grpc::internal::CallOpClientRecvStatus>
finish_buf;
};
/// Async server-side API for handling unary calls, where the single
/// response message sent to the client is of type \a W.
template <class W>
class ServerAsyncResponseWriter final
: public internal::ServerAsyncStreamingInterface {
public:
explicit ServerAsyncResponseWriter(ServerContext* ctx)
: call_(nullptr, nullptr, nullptr), ctx_(ctx) {}
/// See \a ServerAsyncStreamingInterface::SendInitialMetadata for semantics.
///
/// Side effect:
/// The initial metadata that will be sent to the client from this op will
/// be taken from the \a ServerContext associated with the call.
///
/// \param[in] tag Tag identifying this request.
void SendInitialMetadata(void* tag) override {
GPR_CODEGEN_ASSERT(!ctx_->sent_initial_metadata_);
meta_buf_.set_output_tag(tag);
meta_buf_.SendInitialMetadata(&ctx_->initial_metadata_,
ctx_->initial_metadata_flags());
if (ctx_->compression_level_set()) {
meta_buf_.set_compression_level(ctx_->compression_level());
}
ctx_->sent_initial_metadata_ = true;
call_.PerformOps(&meta_buf_);
}
/// Indicate that the stream is to be finished and request notification
/// when the server has sent the appropriate signals to the client to
/// end the call. Should not be used concurrently with other operations.
///
/// \param[in] tag Tag identifying this request.
/// \param[in] status To be sent to the client as the result of the call.
/// \param[in] msg Message to be sent to the client.
///
/// Side effect:
/// - also sends initial metadata if not already sent (using the
/// \a ServerContext associated with this call).
///
/// Note: if \a status has a non-OK code, then \a msg will not be sent,
/// and the client will receive only the status with possible trailing
/// metadata.
void Finish(const W& msg, const Status& status, void* tag) {
finish_buf_.set_output_tag(tag);
finish_buf_.set_core_cq_tag(&finish_buf_);
if (!ctx_->sent_initial_metadata_) {
finish_buf_.SendInitialMetadata(&ctx_->initial_metadata_,
ctx_->initial_metadata_flags());
if (ctx_->compression_level_set()) {
finish_buf_.set_compression_level(ctx_->compression_level());
}
ctx_->sent_initial_metadata_ = true;
}
// The response is dropped if the status is not OK.
if (status.ok()) {
finish_buf_.ServerSendStatus(&ctx_->trailing_metadata_,
finish_buf_.SendMessage(msg));
} else {
finish_buf_.ServerSendStatus(&ctx_->trailing_metadata_, status);
}
call_.PerformOps(&finish_buf_);
}
using ServerAsyncResponseWriter = ::grpc_impl::ServerAsyncResponseWriter<W>;
/// Indicate that the stream is to be finished with a non-OK status,
/// and request notification for when the server has finished sending the
/// appropriate signals to the client to end the call.
/// Should not be used concurrently with other operations.
///
/// \param[in] tag Tag identifying this request.
/// \param[in] status To be sent to the client as the result of the call.
/// - Note: \a status must have a non-OK code.
///
/// Side effect:
/// - also sends initial metadata if not already sent (using the
/// \a ServerContext associated with this call).
void FinishWithError(const Status& status, void* tag) {
GPR_CODEGEN_ASSERT(!status.ok());
finish_buf_.set_output_tag(tag);
if (!ctx_->sent_initial_metadata_) {
finish_buf_.SendInitialMetadata(&ctx_->initial_metadata_,
ctx_->initial_metadata_flags());
if (ctx_->compression_level_set()) {
finish_buf_.set_compression_level(ctx_->compression_level());
}
ctx_->sent_initial_metadata_ = true;
}
finish_buf_.ServerSendStatus(&ctx_->trailing_metadata_, status);
call_.PerformOps(&finish_buf_);
}
namespace internal {
private:
void BindCall(::grpc::internal::Call* call) override { call_ = *call; }
template <class R>
using ClientAsyncResponseReaderFactory =
::grpc_impl::internal::ClientAsyncResponseReaderFactory<R>;
::grpc::internal::Call call_;
ServerContext* ctx_;
::grpc::internal::CallOpSet<::grpc::internal::CallOpSendInitialMetadata>
meta_buf_;
::grpc::internal::CallOpSet<::grpc::internal::CallOpSendInitialMetadata,
::grpc::internal::CallOpSendMessage,
::grpc::internal::CallOpServerSendStatus>
finish_buf_;
};
} // namespace internal
} // namespace grpc
namespace std {
template <class R>
class default_delete<grpc::ClientAsyncResponseReader<R>> {
public:
void operator()(void* p) {}
};
template <class R>
class default_delete<grpc::ClientAsyncResponseReaderInterface<R>> {
public:
void operator()(void* p) {}
};
} // namespace std
#endif // GRPCPP_IMPL_CODEGEN_ASYNC_UNARY_CALL_H

@ -0,0 +1,315 @@
/*
*
* 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_IMPL_CODEGEN_ASYNC_UNARY_CALL_IMPL_H
#define GRPCPP_IMPL_CODEGEN_ASYNC_UNARY_CALL_IMPL_H
#include <assert.h>
#include <grpcpp/impl/codegen/call.h>
#include <grpcpp/impl/codegen/channel_interface.h>
#include <grpcpp/impl/codegen/client_context_impl.h>
#include <grpcpp/impl/codegen/server_context_impl.h>
#include <grpcpp/impl/codegen/service_type.h>
#include <grpcpp/impl/codegen/status.h>
namespace grpc_impl {
/// An interface relevant for async client side unary RPCs (which send
/// one request message to a server and receive one response message).
template <class R>
class ClientAsyncResponseReaderInterface {
public:
virtual ~ClientAsyncResponseReaderInterface() {}
/// Start the call that was set up by the constructor, but only if the
/// constructor was invoked through the "Prepare" API which doesn't actually
/// start the call
virtual void StartCall() = 0;
/// Request notification of the reading of initial metadata. Completion
/// will be notified by \a tag on the associated completion queue.
/// This call is optional, but if it is used, it cannot be used concurrently
/// with or after the \a Finish method.
///
/// \param[in] tag Tag identifying this request.
virtual void ReadInitialMetadata(void* tag) = 0;
/// Request to receive the server's response \a msg and final \a status for
/// the call, and to notify \a tag on this call's completion queue when
/// finished.
///
/// This function will return when either:
/// - when the server's response message and status have been received.
/// - when the server has returned a non-OK status (no message expected in
/// this case).
/// - when the call failed for some reason and the library generated a
/// non-OK status.
///
/// \param[in] tag Tag identifying this request.
/// \param[out] status To be updated with the operation status.
/// \param[out] msg To be filled in with the server's response message.
virtual void Finish(R* msg, ::grpc::Status* status, void* tag) = 0;
};
namespace internal {
template <class R>
class ClientAsyncResponseReaderFactory {
public:
/// Start a call and write the request out if \a start is set.
/// \a tag will be notified on \a cq when the call has been started (i.e.
/// intitial metadata sent) and \a request has been written out.
/// If \a start is not set, the actual call must be initiated by StartCall
/// Note that \a context will be used to fill in custom initial metadata
/// used to send to the server when starting the call.
template <class W>
static ClientAsyncResponseReader<R>* Create(
::grpc::ChannelInterface* channel, ::grpc_impl::CompletionQueue* cq,
const ::grpc::internal::RpcMethod& method,
::grpc_impl::ClientContext* context, const W& request, bool start) {
::grpc::internal::Call call = channel->CreateCall(method, context, cq);
return new (::grpc::g_core_codegen_interface->grpc_call_arena_alloc(
call.call(), sizeof(ClientAsyncResponseReader<R>)))
ClientAsyncResponseReader<R>(call, context, request, start);
}
};
} // namespace internal
/// Async API for client-side unary RPCs, where the message response
/// received from the server is of type \a R.
template <class R>
class ClientAsyncResponseReader final
: public ClientAsyncResponseReaderInterface<R> {
public:
// always allocated against a call arena, no memory free required
static void operator delete(void* ptr, std::size_t size) {
assert(size == sizeof(ClientAsyncResponseReader));
}
// This operator should never be called as the memory should be freed as part
// of the arena destruction. It only exists to provide a matching operator
// delete to the operator new so that some compilers will not complain (see
// https://github.com/grpc/grpc/issues/11301) Note at the time of adding this
// there are no tests catching the compiler warning.
static void operator delete(void*, void*) { assert(0); }
void StartCall() override {
assert(!started_);
started_ = true;
StartCallInternal();
}
/// See \a ClientAsyncResponseReaderInterface::ReadInitialMetadata for
/// semantics.
///
/// Side effect:
/// - the \a ClientContext associated with this call is updated with
/// possible initial and trailing metadata sent from the server.
void ReadInitialMetadata(void* tag) override {
assert(started_);
GPR_CODEGEN_ASSERT(!context_->initial_metadata_received_);
single_buf.set_output_tag(tag);
single_buf.RecvInitialMetadata(context_);
call_.PerformOps(&single_buf);
initial_metadata_read_ = true;
}
/// See \a ClientAysncResponseReaderInterface::Finish for semantics.
///
/// Side effect:
/// - the \a ClientContext associated with this call is updated with
/// possible initial and trailing metadata sent from the server.
void Finish(R* msg, ::grpc::Status* status, void* tag) override {
assert(started_);
if (initial_metadata_read_) {
finish_buf.set_output_tag(tag);
finish_buf.RecvMessage(msg);
finish_buf.AllowNoMessage();
finish_buf.ClientRecvStatus(context_, status);
call_.PerformOps(&finish_buf);
} else {
single_buf.set_output_tag(tag);
single_buf.RecvInitialMetadata(context_);
single_buf.RecvMessage(msg);
single_buf.AllowNoMessage();
single_buf.ClientRecvStatus(context_, status);
call_.PerformOps(&single_buf);
}
}
private:
friend class internal::ClientAsyncResponseReaderFactory<R>;
::grpc_impl::ClientContext* const context_;
::grpc::internal::Call call_;
bool started_;
bool initial_metadata_read_ = false;
template <class W>
ClientAsyncResponseReader(::grpc::internal::Call call,
::grpc_impl::ClientContext* context,
const W& request, bool start)
: context_(context), call_(call), started_(start) {
// Bind the metadata at time of StartCallInternal but set up the rest here
// TODO(ctiller): don't assert
GPR_CODEGEN_ASSERT(single_buf.SendMessage(request).ok());
single_buf.ClientSendClose();
if (start) StartCallInternal();
}
void StartCallInternal() {
single_buf.SendInitialMetadata(&context_->send_initial_metadata_,
context_->initial_metadata_flags());
}
// disable operator new
static void* operator new(std::size_t size);
static void* operator new(std::size_t size, void* p) { return p; }
::grpc::internal::CallOpSet<::grpc::internal::CallOpSendInitialMetadata,
::grpc::internal::CallOpSendMessage,
::grpc::internal::CallOpClientSendClose,
::grpc::internal::CallOpRecvInitialMetadata,
::grpc::internal::CallOpRecvMessage<R>,
::grpc::internal::CallOpClientRecvStatus>
single_buf;
::grpc::internal::CallOpSet<::grpc::internal::CallOpRecvMessage<R>,
::grpc::internal::CallOpClientRecvStatus>
finish_buf;
};
/// Async server-side API for handling unary calls, where the single
/// response message sent to the client is of type \a W.
template <class W>
class ServerAsyncResponseWriter final
: public ::grpc::internal::ServerAsyncStreamingInterface {
public:
explicit ServerAsyncResponseWriter(::grpc_impl::ServerContext* ctx)
: call_(nullptr, nullptr, nullptr), ctx_(ctx) {}
/// See \a ServerAsyncStreamingInterface::SendInitialMetadata for semantics.
///
/// Side effect:
/// The initial metadata that will be sent to the client from this op will
/// be taken from the \a ServerContext associated with the call.
///
/// \param[in] tag Tag identifying this request.
void SendInitialMetadata(void* tag) override {
GPR_CODEGEN_ASSERT(!ctx_->sent_initial_metadata_);
meta_buf_.set_output_tag(tag);
meta_buf_.SendInitialMetadata(&ctx_->initial_metadata_,
ctx_->initial_metadata_flags());
if (ctx_->compression_level_set()) {
meta_buf_.set_compression_level(ctx_->compression_level());
}
ctx_->sent_initial_metadata_ = true;
call_.PerformOps(&meta_buf_);
}
/// Indicate that the stream is to be finished and request notification
/// when the server has sent the appropriate signals to the client to
/// end the call. Should not be used concurrently with other operations.
///
/// \param[in] tag Tag identifying this request.
/// \param[in] status To be sent to the client as the result of the call.
/// \param[in] msg Message to be sent to the client.
///
/// Side effect:
/// - also sends initial metadata if not already sent (using the
/// \a ServerContext associated with this call).
///
/// Note: if \a status has a non-OK code, then \a msg will not be sent,
/// and the client will receive only the status with possible trailing
/// metadata.
void Finish(const W& msg, const ::grpc::Status& status, void* tag) {
finish_buf_.set_output_tag(tag);
finish_buf_.set_core_cq_tag(&finish_buf_);
if (!ctx_->sent_initial_metadata_) {
finish_buf_.SendInitialMetadata(&ctx_->initial_metadata_,
ctx_->initial_metadata_flags());
if (ctx_->compression_level_set()) {
finish_buf_.set_compression_level(ctx_->compression_level());
}
ctx_->sent_initial_metadata_ = true;
}
// The response is dropped if the status is not OK.
if (status.ok()) {
finish_buf_.ServerSendStatus(&ctx_->trailing_metadata_,
finish_buf_.SendMessage(msg));
} else {
finish_buf_.ServerSendStatus(&ctx_->trailing_metadata_, status);
}
call_.PerformOps(&finish_buf_);
}
/// Indicate that the stream is to be finished with a non-OK status,
/// and request notification for when the server has finished sending the
/// appropriate signals to the client to end the call.
/// Should not be used concurrently with other operations.
///
/// \param[in] tag Tag identifying this request.
/// \param[in] status To be sent to the client as the result of the call.
/// - Note: \a status must have a non-OK code.
///
/// Side effect:
/// - also sends initial metadata if not already sent (using the
/// \a ServerContext associated with this call).
void FinishWithError(const ::grpc::Status& status, void* tag) {
GPR_CODEGEN_ASSERT(!status.ok());
finish_buf_.set_output_tag(tag);
if (!ctx_->sent_initial_metadata_) {
finish_buf_.SendInitialMetadata(&ctx_->initial_metadata_,
ctx_->initial_metadata_flags());
if (ctx_->compression_level_set()) {
finish_buf_.set_compression_level(ctx_->compression_level());
}
ctx_->sent_initial_metadata_ = true;
}
finish_buf_.ServerSendStatus(&ctx_->trailing_metadata_, status);
call_.PerformOps(&finish_buf_);
}
private:
void BindCall(::grpc::internal::Call* call) override { call_ = *call; }
::grpc::internal::Call call_;
::grpc_impl::ServerContext* ctx_;
::grpc::internal::CallOpSet<::grpc::internal::CallOpSendInitialMetadata>
meta_buf_;
::grpc::internal::CallOpSet<::grpc::internal::CallOpSendInitialMetadata,
::grpc::internal::CallOpSendMessage,
::grpc::internal::CallOpServerSendStatus>
finish_buf_;
};
} // namespace grpc_impl
namespace std {
template <class R>
class default_delete<::grpc_impl::ClientAsyncResponseReader<R>> {
public:
void operator()(void* p) {}
};
template <class R>
class default_delete<::grpc_impl::ClientAsyncResponseReaderInterface<R>> {
public:
void operator()(void* p) {}
};
} // namespace std
#endif // GRPCPP_IMPL_CODEGEN_ASYNC_UNARY_CALL_IMPL_H

@ -29,6 +29,17 @@
#include <vector>
namespace grpc_impl {
namespace internal {
template <class RequestType, class ResponseType>
class CallbackUnaryHandler;
template <class RequestType, class ResponseType>
class CallbackServerStreamingHandler;
} // namespace internal
} // namespace grpc_impl
namespace grpc {
class ServerInterface;
@ -45,10 +56,6 @@ template <class ServiceType, class RequestType, class ResponseType>
class RpcMethodHandler;
template <class ServiceType, class RequestType, class ResponseType>
class ServerStreamingHandler;
template <class RequestType, class ResponseType>
class CallbackUnaryHandler;
template <class RequestType, class ResponseType>
class CallbackServerStreamingHandler;
template <StatusCode code>
class ErrorMethodHandler;
class ExternalConnectionAcceptorImpl;
@ -176,9 +183,9 @@ class ByteBuffer final {
template <class ServiceType, class RequestType, class ResponseType>
friend class internal::ServerStreamingHandler;
template <class RequestType, class ResponseType>
friend class internal::CallbackUnaryHandler;
friend class ::grpc_impl::internal::CallbackUnaryHandler;
template <class RequestType, class ResponseType>
friend class ::grpc::internal::CallbackServerStreamingHandler;
friend class ::grpc_impl::internal::CallbackServerStreamingHandler;
template <StatusCode code>
friend class internal::ErrorMethodHandler;
template <class R>

@ -31,8 +31,8 @@
#include <grpcpp/impl/codegen/call.h>
#include <grpcpp/impl/codegen/call_hook.h>
#include <grpcpp/impl/codegen/call_op_set_interface.h>
#include <grpcpp/impl/codegen/client_context.h>
#include <grpcpp/impl/codegen/completion_queue.h>
#include <grpcpp/impl/codegen/client_context_impl.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>
@ -697,7 +697,7 @@ class CallOpRecvInitialMetadata {
public:
CallOpRecvInitialMetadata() : metadata_map_(nullptr) {}
void RecvInitialMetadata(ClientContext* context) {
void RecvInitialMetadata(::grpc_impl::ClientContext* context) {
context->initial_metadata_received_ = true;
metadata_map_ = &context->recv_initial_metadata_;
}
@ -746,7 +746,7 @@ class CallOpClientRecvStatus {
CallOpClientRecvStatus()
: recv_status_(nullptr), debug_error_string_(nullptr) {}
void ClientRecvStatus(ClientContext* context, Status* status) {
void ClientRecvStatus(::grpc_impl::ClientContext* context, Status* status) {
client_context_ = context;
metadata_map_ = &client_context_->trailing_metadata_;
recv_status_ = status;
@ -807,7 +807,7 @@ class CallOpClientRecvStatus {
private:
bool hijacked_ = false;
ClientContext* client_context_;
::grpc_impl::ClientContext* client_context_;
MetadataMap* metadata_map_;
Status* recv_status_;
const char* debug_error_string_;

@ -27,24 +27,13 @@
namespace grpc_impl {
class ClientContext;
class CompletionQueue;
} // namespace grpc_impl
namespace grpc {
class ChannelInterface;
template <class R>
class ClientReader;
template <class W>
class ClientWriter;
template <class W, class R>
class ClientReaderWriter;
namespace internal {
class Call;
class CallOpSetInterface;
class RpcMethod;
template <class InputMessage, class OutputMessage>
class BlockingUnaryCallImpl;
template <class InputMessage, class OutputMessage>
class CallbackUnaryCallImpl;
template <class R>
@ -62,7 +51,19 @@ class ClientCallbackReaderFactory;
template <class W>
class ClientCallbackWriterFactory;
class ClientCallbackUnaryFactory;
} // namespace internal
} // namespace grpc_impl
namespace grpc {
class ChannelInterface;
namespace internal {
class Call;
class CallOpSetInterface;
class RpcMethod;
class InterceptedChannel;
template <class InputMessage, class OutputMessage>
class BlockingUnaryCallImpl;
} // namespace internal
/// Codegen interface for \a grpc::Channel.
@ -102,30 +103,30 @@ class ChannelInterface {
private:
template <class R>
friend class ::grpc::ClientReader;
friend class ::grpc_impl::ClientReader;
template <class W>
friend class ::grpc::ClientWriter;
friend class ::grpc_impl::ClientWriter;
template <class W, class R>
friend class ::grpc::ClientReaderWriter;
friend class ::grpc_impl::ClientReaderWriter;
template <class R>
friend class ::grpc::internal::ClientAsyncReaderFactory;
friend class ::grpc_impl::internal::ClientAsyncReaderFactory;
template <class W>
friend class ::grpc::internal::ClientAsyncWriterFactory;
friend class ::grpc_impl::internal::ClientAsyncWriterFactory;
template <class W, class R>
friend class ::grpc::internal::ClientAsyncReaderWriterFactory;
friend class ::grpc_impl::internal::ClientAsyncReaderWriterFactory;
template <class R>
friend class ::grpc::internal::ClientAsyncResponseReaderFactory;
friend class ::grpc_impl::internal::ClientAsyncResponseReaderFactory;
template <class W, class R>
friend class ::grpc::internal::ClientCallbackReaderWriterFactory;
friend class ::grpc_impl::internal::ClientCallbackReaderWriterFactory;
template <class R>
friend class ::grpc::internal::ClientCallbackReaderFactory;
friend class ::grpc_impl::internal::ClientCallbackReaderFactory;
template <class W>
friend class ::grpc::internal::ClientCallbackWriterFactory;
friend class ::grpc::internal::ClientCallbackUnaryFactory;
friend class ::grpc_impl::internal::ClientCallbackWriterFactory;
friend class ::grpc_impl::internal::ClientCallbackUnaryFactory;
template <class InputMessage, class OutputMessage>
friend class ::grpc::internal::BlockingUnaryCallImpl;
template <class InputMessage, class OutputMessage>
friend class ::grpc::internal::CallbackUnaryCallImpl;
friend class ::grpc_impl::internal::CallbackUnaryCallImpl;
friend class ::grpc::internal::RpcMethod;
friend class ::grpc::internal::InterceptedChannel;
virtual internal::Call CreateCall(const internal::RpcMethod& method,

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

@ -63,10 +63,19 @@ class ChannelInterface;
namespace internal {
class RpcMethod;
class CallOpClientRecvStatus;
class CallOpRecvInitialMetadata;
template <class InputMessage, class OutputMessage>
class BlockingUnaryCallImpl;
class CallOpClientRecvStatus;
class CallOpRecvInitialMetadata;
} // namespace internal
namespace testing {
class InteropClientContextInspector;
} // namespace testing
} // namespace grpc
namespace grpc_impl {
namespace internal {
template <class InputMessage, class OutputMessage>
class CallbackUnaryCallImpl;
template <class Request, class Response>
@ -78,6 +87,10 @@ class ClientCallbackWriterImpl;
class ClientCallbackUnaryImpl;
} // namespace internal
class CallCredentials;
class Channel;
class CompletionQueue;
class ServerContext;
template <class R>
class ClientReader;
template <class W>
@ -93,17 +106,6 @@ class ClientAsyncReaderWriter;
template <class R>
class ClientAsyncResponseReader;
namespace testing {
class InteropClientContextInspector;
} // namespace testing
} // namespace grpc
namespace grpc_impl {
class CallCredentials;
class Channel;
class CompletionQueue;
class ServerContext;
/// Options for \a ClientContext::FromServerContext specifying which traits from
/// the \a ServerContext to propagate (copy) from it into a new \a
/// ClientContext.
@ -398,30 +400,30 @@ class ClientContext {
friend class ::grpc::internal::CallOpRecvInitialMetadata;
friend class ::grpc_impl::Channel;
template <class R>
friend class ::grpc::ClientReader;
friend class ::grpc_impl::ClientReader;
template <class W>
friend class ::grpc::ClientWriter;
friend class ::grpc_impl::ClientWriter;
template <class W, class R>
friend class ::grpc::ClientReaderWriter;
friend class ::grpc_impl::ClientReaderWriter;
template <class R>
friend class ::grpc::ClientAsyncReader;
friend class ::grpc_impl::ClientAsyncReader;
template <class W>
friend class ::grpc::ClientAsyncWriter;
friend class ::grpc_impl::ClientAsyncWriter;
template <class W, class R>
friend class ::grpc::ClientAsyncReaderWriter;
friend class ::grpc_impl::ClientAsyncReaderWriter;
template <class R>
friend class ::grpc::ClientAsyncResponseReader;
friend class ::grpc_impl::ClientAsyncResponseReader;
template <class InputMessage, class OutputMessage>
friend class ::grpc::internal::BlockingUnaryCallImpl;
template <class InputMessage, class OutputMessage>
friend class ::grpc::internal::CallbackUnaryCallImpl;
friend class ::grpc_impl::internal::CallbackUnaryCallImpl;
template <class Request, class Response>
friend class ::grpc::internal::ClientCallbackReaderWriterImpl;
friend class ::grpc_impl::internal::ClientCallbackReaderWriterImpl;
template <class Response>
friend class ::grpc::internal::ClientCallbackReaderImpl;
friend class ::grpc_impl::internal::ClientCallbackReaderImpl;
template <class Request>
friend class ::grpc::internal::ClientCallbackWriterImpl;
friend class ::grpc::internal::ClientCallbackUnaryImpl;
friend class ::grpc_impl::internal::ClientCallbackWriterImpl;
friend class ::grpc_impl::internal::ClientCallbackUnaryImpl;
// Used by friend class CallOpClientRecvStatus
void set_debug_error_string(const grpc::string& debug_error_string) {

@ -49,10 +49,10 @@ class BlockingUnaryCallImpl {
BlockingUnaryCallImpl(ChannelInterface* channel, const RpcMethod& method,
grpc_impl::ClientContext* context,
const InputMessage& request, OutputMessage* result) {
CompletionQueue cq(grpc_completion_queue_attributes{
::grpc_impl::CompletionQueue cq(grpc_completion_queue_attributes{
GRPC_CQ_CURRENT_VERSION, GRPC_CQ_PLUCK, GRPC_CQ_DEFAULT_POLLING,
nullptr}); // Pluckable completion queue
Call call(channel->CreateCall(method, context, &cq));
::grpc::internal::Call call(channel->CreateCall(method, context, &cq));
CallOpSet<CallOpSendInitialMetadata, CallOpSendMessage,
CallOpRecvInitialMetadata, CallOpRecvMessage<OutputMessage>,
CallOpClientSendClose, CallOpClientRecvStatus>

@ -47,9 +47,6 @@ class Channel;
class Server;
class ServerBuilder;
class ServerContext;
} // namespace grpc_impl
namespace grpc {
template <class R>
class ClientReader;
template <class W>
@ -64,6 +61,8 @@ namespace internal {
template <class W, class R>
class ServerReaderWriterBody;
} // namespace internal
} // namespace grpc_impl
namespace grpc {
class ChannelInterface;
class ServerInterface;
@ -255,17 +254,17 @@ class CompletionQueue : private ::grpc::GrpcLibraryCodegen {
// 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;
friend class ::grpc_impl::ClientReader;
template <class W>
friend class ::grpc::ClientWriter;
friend class ::grpc_impl::ClientWriter;
template <class W, class R>
friend class ::grpc::ClientReaderWriter;
friend class ::grpc_impl::ClientReaderWriter;
template <class R>
friend class ::grpc::ServerReader;
friend class ::grpc_impl::ServerReader;
template <class W>
friend class ::grpc::ServerWriter;
friend class ::grpc_impl::ServerWriter;
template <class W, class R>
friend class ::grpc::internal::ServerReaderWriterBody;
friend class ::grpc_impl::internal::ServerReaderWriterBody;
template <class ServiceType, class RequestType, class ResponseType>
friend class ::grpc::internal::RpcMethodHandler;
template <class ServiceType, class RequestType, class ResponseType>

@ -49,7 +49,7 @@ class InterceptedChannel : public ChannelInterface {
InterceptedChannel(ChannelInterface* channel, size_t pos)
: channel_(channel), interceptor_pos_(pos) {}
Call CreateCall(const RpcMethod& method, ClientContext* context,
Call CreateCall(const RpcMethod& method, ::grpc_impl::ClientContext* context,
::grpc_impl::CompletionQueue* cq) override {
return channel_->CreateCallInternal(method, context, cq, interceptor_pos_);
}

@ -52,10 +52,11 @@ Status CatchingFunctionHandler(Callable&& handler) {
template <class ServiceType, class RequestType, class ResponseType>
class RpcMethodHandler : public MethodHandler {
public:
RpcMethodHandler(std::function<Status(ServiceType*, ServerContext*,
const RequestType*, ResponseType*)>
func,
ServiceType* service)
RpcMethodHandler(
std::function<Status(ServiceType*, ::grpc_impl::ServerContext*,
const RequestType*, ResponseType*)>
func,
ServiceType* service)
: func_(func), service_(service) {}
void RunHandler(const HandlerParameter& param) final {
@ -103,8 +104,8 @@ class RpcMethodHandler : public MethodHandler {
private:
/// Application provided rpc handler function.
std::function<Status(ServiceType*, ServerContext*, const RequestType*,
ResponseType*)>
std::function<Status(ServiceType*, ::grpc_impl::ServerContext*,
const RequestType*, ResponseType*)>
func_;
// The class the above handler function lives in.
ServiceType* service_;
@ -115,7 +116,7 @@ template <class ServiceType, class RequestType, class ResponseType>
class ClientStreamingHandler : public MethodHandler {
public:
ClientStreamingHandler(
std::function<Status(ServiceType*, ServerContext*,
std::function<Status(ServiceType*, ::grpc_impl::ServerContext*,
ServerReader<RequestType>*, ResponseType*)>
func,
ServiceType* service)
@ -147,8 +148,8 @@ class ClientStreamingHandler : public MethodHandler {
}
private:
std::function<Status(ServiceType*, ServerContext*, ServerReader<RequestType>*,
ResponseType*)>
std::function<Status(ServiceType*, ::grpc_impl::ServerContext*,
ServerReader<RequestType>*, ResponseType*)>
func_;
ServiceType* service_;
};
@ -158,8 +159,8 @@ template <class ServiceType, class RequestType, class ResponseType>
class ServerStreamingHandler : public MethodHandler {
public:
ServerStreamingHandler(
std::function<Status(ServiceType*, ServerContext*, const RequestType*,
ServerWriter<ResponseType>*)>
std::function<Status(ServiceType*, ::grpc_impl::ServerContext*,
const RequestType*, ServerWriter<ResponseType>*)>
func,
ServiceType* service)
: func_(func), service_(service) {}
@ -207,8 +208,8 @@ class ServerStreamingHandler : public MethodHandler {
}
private:
std::function<Status(ServiceType*, ServerContext*, const RequestType*,
ServerWriter<ResponseType>*)>
std::function<Status(ServiceType*, ::grpc_impl::ServerContext*,
const RequestType*, ServerWriter<ResponseType>*)>
func_;
ServiceType* service_;
};
@ -224,7 +225,7 @@ template <class Streamer, bool WriteNeeded>
class TemplatedBidiStreamingHandler : public MethodHandler {
public:
TemplatedBidiStreamingHandler(
std::function<Status(ServerContext*, Streamer*)> func)
std::function<Status(::grpc_impl::ServerContext*, Streamer*)> func)
: func_(func), write_needed_(WriteNeeded) {}
void RunHandler(const HandlerParameter& param) final {
@ -256,7 +257,7 @@ class TemplatedBidiStreamingHandler : public MethodHandler {
}
private:
std::function<Status(ServerContext*, Streamer*)> func_;
std::function<Status(::grpc_impl::ServerContext*, Streamer*)> func_;
const bool write_needed_;
};
@ -266,7 +267,7 @@ class BidiStreamingHandler
ServerReaderWriter<ResponseType, RequestType>, false> {
public:
BidiStreamingHandler(
std::function<Status(ServiceType*, ServerContext*,
std::function<Status(ServiceType*, ::grpc_impl::ServerContext*,
ServerReaderWriter<ResponseType, RequestType>*)>
func,
ServiceType* service)
@ -281,7 +282,7 @@ class StreamedUnaryHandler
ServerUnaryStreamer<RequestType, ResponseType>, true> {
public:
explicit StreamedUnaryHandler(
std::function<Status(ServerContext*,
std::function<Status(::grpc_impl::ServerContext*,
ServerUnaryStreamer<RequestType, ResponseType>*)>
func)
: TemplatedBidiStreamingHandler<
@ -294,7 +295,7 @@ class SplitServerStreamingHandler
ServerSplitStreamer<RequestType, ResponseType>, false> {
public:
explicit SplitServerStreamingHandler(
std::function<Status(ServerContext*,
std::function<Status(::grpc_impl::ServerContext*,
ServerSplitStreamer<RequestType, ResponseType>*)>
func)
: TemplatedBidiStreamingHandler<
@ -307,7 +308,7 @@ template <StatusCode code>
class ErrorMethodHandler : public MethodHandler {
public:
template <class T>
static void FillOps(ServerContext* context, T* ops) {
static void FillOps(::grpc_impl::ServerContext* context, T* ops) {
Status status(code, "");
if (!context->sent_initial_metadata_) {
ops->SendInitialMetadata(&context->initial_metadata_,

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

@ -44,10 +44,6 @@ namespace grpc_impl {
class ClientContext;
class CompletionQueue;
class Server;
} // namespace grpc_impl
namespace grpc {
class GenericServerContext;
class ServerInterface;
template <class W, class R>
class ServerAsyncReader;
template <class W>
@ -62,14 +58,6 @@ template <class W>
class ServerWriter;
namespace internal {
template <class W, class R>
class ServerReaderWriterBody;
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 RequestType, class ResponseType>
@ -80,12 +68,28 @@ template <class RequestType, class ResponseType>
class CallbackServerStreamingHandler;
template <class RequestType, class ResponseType>
class CallbackBidiHandler;
template <class W, class R>
class ServerReaderWriterBody;
class ServerReactor;
} // namespace internal
} // namespace grpc_impl
namespace grpc {
class GenericServerContext;
class ServerInterface;
namespace internal {
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 RpcMethodHandler;
template <class Streamer, bool WriteNeeded>
class TemplatedBidiStreamingHandler;
template <StatusCode code>
class ErrorMethodHandler;
class Call;
class ServerReactor;
} // namespace internal
class ServerInterface;
@ -275,19 +279,19 @@ class ServerContext {
friend class ::grpc::ServerInterface;
friend class ::grpc_impl::Server;
template <class W, class R>
friend class ::grpc::ServerAsyncReader;
friend class ::grpc_impl::ServerAsyncReader;
template <class W>
friend class ::grpc::ServerAsyncWriter;
friend class ::grpc_impl::ServerAsyncWriter;
template <class W>
friend class ::grpc::ServerAsyncResponseWriter;
friend class ::grpc_impl::ServerAsyncResponseWriter;
template <class W, class R>
friend class ::grpc::ServerAsyncReaderWriter;
friend class ::grpc_impl::ServerAsyncReaderWriter;
template <class R>
friend class ::grpc::ServerReader;
friend class ::grpc_impl::ServerReader;
template <class W>
friend class ::grpc::ServerWriter;
friend class ::grpc_impl::ServerWriter;
template <class W, class R>
friend class ::grpc::internal::ServerReaderWriterBody;
friend class ::grpc_impl::internal::ServerReaderWriterBody;
template <class ServiceType, class RequestType, class ResponseType>
friend class ::grpc::internal::RpcMethodHandler;
template <class ServiceType, class RequestType, class ResponseType>
@ -297,13 +301,13 @@ class ServerContext {
template <class Streamer, bool WriteNeeded>
friend class ::grpc::internal::TemplatedBidiStreamingHandler;
template <class RequestType, class ResponseType>
friend class ::grpc::internal::CallbackUnaryHandler;
friend class ::grpc_impl::internal::CallbackUnaryHandler;
template <class RequestType, class ResponseType>
friend class ::grpc::internal::CallbackClientStreamingHandler;
friend class ::grpc_impl::internal::CallbackClientStreamingHandler;
template <class RequestType, class ResponseType>
friend class ::grpc::internal::CallbackServerStreamingHandler;
friend class ::grpc_impl::internal::CallbackServerStreamingHandler;
template <class RequestType, class ResponseType>
friend class ::grpc::internal::CallbackBidiHandler;
friend class ::grpc_impl::internal::CallbackBidiHandler;
template <::grpc::StatusCode code>
friend class ::grpc::internal::ErrorMethodHandler;
friend class ::grpc_impl::ClientContext;
@ -317,7 +321,7 @@ class ServerContext {
void BeginCompletionOp(::grpc::internal::Call* call,
std::function<void(bool)> callback,
::grpc::internal::ServerReactor* reactor);
::grpc_impl::internal::ServerReactor* reactor);
/// Return the tag queued by BeginCompletionOp()
::grpc::internal::CompletionQueueTag* GetCompletionOpTag();

@ -26,7 +26,7 @@
#include <grpcpp/impl/codegen/completion_queue_tag.h>
#include <grpcpp/impl/codegen/core_codegen_interface.h>
#include <grpcpp/impl/codegen/rpc_service_method.h>
#include <grpcpp/impl/codegen/server_context.h>
#include <grpcpp/impl/codegen/server_context_impl.h>
namespace grpc_impl {
@ -34,7 +34,6 @@ class Channel;
class CompletionQueue;
class ServerCompletionQueue;
class ServerCredentials;
class ServerContext;
} // namespace grpc_impl
namespace grpc {

@ -149,8 +149,9 @@ class Service {
void RequestAsyncUnary(int index, ::grpc_impl::ServerContext* context,
Message* request,
internal::ServerAsyncStreamingInterface* stream,
CompletionQueue* call_cq,
ServerCompletionQueue* notification_cq, void* tag) {
::grpc_impl::CompletionQueue* call_cq,
::grpc_impl::ServerCompletionQueue* notification_cq,
void* tag) {
// Typecast the index to size_t for indexing into a vector
// while preserving the API that existed before a compiler
// warning was first seen (grpc/grpc#11664)
@ -160,8 +161,9 @@ class Service {
}
void RequestAsyncClientStreaming(
int index, ::grpc_impl::ServerContext* context,
internal::ServerAsyncStreamingInterface* stream, CompletionQueue* call_cq,
ServerCompletionQueue* notification_cq, void* tag) {
internal::ServerAsyncStreamingInterface* stream,
::grpc_impl::CompletionQueue* call_cq,
::grpc_impl::ServerCompletionQueue* notification_cq, void* tag) {
size_t idx = static_cast<size_t>(index);
server_->RequestAsyncCall(methods_[idx].get(), context, stream, call_cq,
notification_cq, tag);
@ -169,16 +171,18 @@ class Service {
template <class Message>
void RequestAsyncServerStreaming(
int index, ::grpc_impl::ServerContext* context, Message* request,
internal::ServerAsyncStreamingInterface* stream, CompletionQueue* call_cq,
ServerCompletionQueue* notification_cq, void* tag) {
internal::ServerAsyncStreamingInterface* stream,
::grpc_impl::CompletionQueue* call_cq,
::grpc_impl::ServerCompletionQueue* notification_cq, void* tag) {
size_t idx = static_cast<size_t>(index);
server_->RequestAsyncCall(methods_[idx].get(), context, stream, call_cq,
notification_cq, tag, request);
}
void RequestAsyncBidiStreaming(
int index, ::grpc_impl::ServerContext* context,
internal::ServerAsyncStreamingInterface* stream, CompletionQueue* call_cq,
ServerCompletionQueue* notification_cq, void* tag) {
internal::ServerAsyncStreamingInterface* stream,
::grpc_impl::CompletionQueue* call_cq,
::grpc_impl::ServerCompletionQueue* notification_cq, void* tag) {
size_t idx = static_cast<size_t>(index);
server_->RequestAsyncCall(methods_[idx].get(), context, stream, call_cq,
notification_cq, tag);

@ -19,915 +19,81 @@
#ifndef GRPCPP_IMPL_CODEGEN_SYNC_STREAM_H
#define GRPCPP_IMPL_CODEGEN_SYNC_STREAM_H
#include <grpcpp/impl/codegen/call.h>
#include <grpcpp/impl/codegen/channel_interface.h>
#include <grpcpp/impl/codegen/client_context.h>
#include <grpcpp/impl/codegen/completion_queue.h>
#include <grpcpp/impl/codegen/core_codegen_interface.h>
#include <grpcpp/impl/codegen/server_context.h>
#include <grpcpp/impl/codegen/service_type.h>
#include <grpcpp/impl/codegen/status.h>
#include <grpcpp/impl/codegen/sync_stream_impl.h>
namespace grpc {
namespace internal {
/// Common interface for all synchronous client side streaming.
class ClientStreamingInterface {
public:
virtual ~ClientStreamingInterface() {}
/// Block waiting until the stream finishes and a final status of the call is
/// available.
///
/// It is appropriate to call this method when both:
/// * the calling code (client-side) has no more message to send
/// (this can be declared implicitly by calling this method, or
/// explicitly through an earlier call to <i>WritesDone</i> method of the
/// class in use, e.g. \a ClientWriterInterface::WritesDone or
/// \a ClientReaderWriterInterface::WritesDone).
/// * there are no more messages to be received from the server (which can
/// be known implicitly, or explicitly from an earlier call to \a
/// ReaderInterface::Read that returned "false").
///
/// This function will return either:
/// - when all incoming messages have been read and the server has
/// returned status.
/// - when the server has returned a non-OK status.
/// - OR when the call failed for some reason and the library generated a
/// status.
///
/// Return values:
/// - \a Status contains the status code, message and details for the call
/// - the \a ClientContext associated with this call is updated with
/// possible trailing metadata sent from the server.
virtual Status Finish() = 0;
};
typedef ::grpc_impl::internal::ClientStreamingInterface
ClientStreamingInterface;
/// Common interface for all synchronous server side streaming.
class ServerStreamingInterface {
public:
virtual ~ServerStreamingInterface() {}
typedef ::grpc_impl::internal::ServerStreamingInterface
ServerStreamingInterface;
/// Block to send initial metadata to client.
/// This call is optional, but if it is used, it cannot be used concurrently
/// with or after the \a Finish method.
///
/// The initial metadata that will be sent to the client will be
/// taken from the \a ServerContext associated with the call.
virtual void SendInitialMetadata() = 0;
};
/// An interface that yields a sequence of messages of type \a R.
template <class R>
class ReaderInterface {
public:
virtual ~ReaderInterface() {}
/// Get an upper bound on the next message size available for reading on this
/// stream.
virtual bool NextMessageSize(uint32_t* sz) = 0;
/// Block to read a message and parse to \a msg. Returns \a true on success.
/// This is thread-safe with respect to \a Write or \WritesDone methods on
/// the same stream. It should not be called concurrently with another \a
/// Read on the same stream as the order of delivery will not be defined.
///
/// \param[out] msg The read message.
///
/// \return \a false when there will be no more incoming messages, either
/// because the other side has called \a WritesDone() or the stream has failed
/// (or been cancelled).
virtual bool Read(R* msg) = 0;
};
using ReaderInterface = ::grpc_impl::internal::ReaderInterface<R>;
/// An interface that can be fed a sequence of messages of type \a W.
template <class W>
class WriterInterface {
public:
virtual ~WriterInterface() {}
using WriterInterface = ::grpc_impl::internal::WriterInterface<W>;
/// Block to write \a msg to the stream with WriteOptions \a options.
/// This is thread-safe with respect to \a ReaderInterface::Read
///
/// \param msg The message to be written to the stream.
/// \param options The WriteOptions affecting the write operation.
///
/// \return \a true on success, \a false when the stream has been closed.
virtual bool Write(const W& msg, WriteOptions options) = 0;
template <class R>
using ClientReaderFactory = ::grpc_impl::internal::ClientReaderFactory<R>;
/// Block to write \a msg to the stream with default write options.
/// This is thread-safe with respect to \a ReaderInterface::Read
///
/// \param msg The message to be written to the stream.
///
/// \return \a true on success, \a false when the stream has been closed.
inline bool Write(const W& msg) { return Write(msg, WriteOptions()); }
template <class W>
using ClientWriterFactory = ::grpc_impl::internal::ClientWriterFactory<W>;
/// Write \a msg and coalesce it with the writing of trailing metadata, using
/// WriteOptions \a options.
///
/// For client, WriteLast is equivalent of performing Write and WritesDone in
/// a single step. \a msg and trailing metadata are coalesced and sent on wire
/// by calling this function. For server, WriteLast buffers the \a msg.
/// The writing of \a msg is held until the service handler returns,
/// where \a msg and trailing metadata are coalesced and sent on wire.
/// Note that WriteLast can only buffer \a msg up to the flow control window
/// size. If \a msg size is larger than the window size, it will be sent on
/// wire without buffering.
///
/// \param[in] msg The message to be written to the stream.
/// \param[in] options The WriteOptions to be used to write this message.
void WriteLast(const W& msg, WriteOptions options) {
Write(msg, options.set_last_message());
}
};
template <class W, class R>
using ClientReaderWriterFactory =
::grpc_impl::internal::ClientReaderWriterFactory<W, R>;
} // namespace internal
/// Client-side interface for streaming reads of message of type \a R.
template <class R>
class ClientReaderInterface : public internal::ClientStreamingInterface,
public internal::ReaderInterface<R> {
public:
/// Block to wait for initial metadata from server. The received metadata
/// can only be accessed after this call returns. Should only be called before
/// the first read. Calling this method is optional, and if it is not called
/// the metadata will be available in ClientContext after the first read.
virtual void WaitForInitialMetadata() = 0;
};
using ClientReaderInterface = ::grpc_impl::ClientReaderInterface<R>;
namespace internal {
template <class R>
class ClientReaderFactory {
public:
template <class W>
static ClientReader<R>* Create(ChannelInterface* channel,
const ::grpc::internal::RpcMethod& method,
ClientContext* context, const W& request) {
return new ClientReader<R>(channel, method, context, request);
}
};
} // namespace internal
/// Synchronous (blocking) client-side API for doing server-streaming RPCs,
/// where the stream of messages coming from the server has messages
/// of type \a R.
template <class R>
class ClientReader final : public ClientReaderInterface<R> {
public:
/// See the \a ClientStreamingInterface.WaitForInitialMetadata method for
/// semantics.
///
// Side effect:
/// Once complete, the initial metadata read from
/// the server will be accessible through the \a ClientContext used to
/// construct this object.
void WaitForInitialMetadata() override {
GPR_CODEGEN_ASSERT(!context_->initial_metadata_received_);
::grpc::internal::CallOpSet<::grpc::internal::CallOpRecvInitialMetadata>
ops;
ops.RecvInitialMetadata(context_);
call_.PerformOps(&ops);
cq_.Pluck(&ops); /// status ignored
}
using ClientReader = ::grpc_impl::ClientReader<R>;
bool NextMessageSize(uint32_t* sz) override {
*sz = call_.max_receive_message_size();
return true;
}
/// See the \a ReaderInterface.Read method for semantics.
/// Side effect:
/// This also receives initial metadata from the server, if not
/// already received (if initial metadata is received, it can be then
/// accessed through the \a ClientContext associated with this call).
bool Read(R* msg) override {
::grpc::internal::CallOpSet<::grpc::internal::CallOpRecvInitialMetadata,
::grpc::internal::CallOpRecvMessage<R>>
ops;
if (!context_->initial_metadata_received_) {
ops.RecvInitialMetadata(context_);
}
ops.RecvMessage(msg);
call_.PerformOps(&ops);
return cq_.Pluck(&ops) && ops.got_message;
}
/// See the \a ClientStreamingInterface.Finish method for semantics.
///
/// Side effect:
/// The \a ClientContext associated with this call is updated with
/// possible metadata received from the server.
Status Finish() override {
::grpc::internal::CallOpSet<::grpc::internal::CallOpClientRecvStatus> ops;
Status status;
ops.ClientRecvStatus(context_, &status);
call_.PerformOps(&ops);
GPR_CODEGEN_ASSERT(cq_.Pluck(&ops));
return status;
}
private:
friend class internal::ClientReaderFactory<R>;
ClientContext* context_;
CompletionQueue cq_;
::grpc::internal::Call call_;
/// Block to create a stream and write the initial metadata and \a request
/// out. Note that \a context will be used to fill in custom initial
/// metadata used to send to the server when starting the call.
template <class W>
ClientReader(::grpc::ChannelInterface* channel,
const ::grpc::internal::RpcMethod& method,
ClientContext* context, const W& request)
: context_(context),
cq_(grpc_completion_queue_attributes{
GRPC_CQ_CURRENT_VERSION, GRPC_CQ_PLUCK, GRPC_CQ_DEFAULT_POLLING,
nullptr}), // Pluckable cq
call_(channel->CreateCall(method, context, &cq_)) {
::grpc::internal::CallOpSet<::grpc::internal::CallOpSendInitialMetadata,
::grpc::internal::CallOpSendMessage,
::grpc::internal::CallOpClientSendClose>
ops;
ops.SendInitialMetadata(&context->send_initial_metadata_,
context->initial_metadata_flags());
// TODO(ctiller): don't assert
GPR_CODEGEN_ASSERT(ops.SendMessagePtr(&request).ok());
ops.ClientSendClose();
call_.PerformOps(&ops);
cq_.Pluck(&ops);
}
};
/// Client-side interface for streaming writes of message type \a W.
template <class W>
class ClientWriterInterface : public internal::ClientStreamingInterface,
public internal::WriterInterface<W> {
public:
/// Half close writing from the client. (signal that the stream of messages
/// coming from the client is complete).
/// Blocks until currently-pending writes are completed.
/// Thread safe with respect to \a ReaderInterface::Read operations only
///
/// \return Whether the writes were successful.
virtual bool WritesDone() = 0;
};
using ClientWriterInterface = ::grpc_impl::ClientWriterInterface<W>;
namespace internal {
template <class W>
class ClientWriterFactory {
public:
template <class R>
static ClientWriter<W>* Create(::grpc::ChannelInterface* channel,
const ::grpc::internal::RpcMethod& method,
ClientContext* context, R* response) {
return new ClientWriter<W>(channel, method, context, response);
}
};
} // namespace internal
/// Synchronous (blocking) client-side API for doing client-streaming RPCs,
/// where the outgoing message stream coming from the client has messages of
/// type \a W.
template <class W>
class ClientWriter : public ClientWriterInterface<W> {
public:
/// See the \a ClientStreamingInterface.WaitForInitialMetadata method for
/// semantics.
///
// Side effect:
/// Once complete, the initial metadata read from the server will be
/// accessible through the \a ClientContext used to construct this object.
void WaitForInitialMetadata() {
GPR_CODEGEN_ASSERT(!context_->initial_metadata_received_);
::grpc::internal::CallOpSet<::grpc::internal::CallOpRecvInitialMetadata>
ops;
ops.RecvInitialMetadata(context_);
call_.PerformOps(&ops);
cq_.Pluck(&ops); // status ignored
}
using ClientWriter = ::grpc_impl::ClientWriter<W>;
/// See the WriterInterface.Write(const W& msg, WriteOptions options) method
/// for semantics.
///
/// Side effect:
/// Also sends initial metadata if not already sent (using the
/// \a ClientContext associated with this call).
using ::grpc::internal::WriterInterface<W>::Write;
bool Write(const W& msg, WriteOptions options) override {
::grpc::internal::CallOpSet<::grpc::internal::CallOpSendInitialMetadata,
::grpc::internal::CallOpSendMessage,
::grpc::internal::CallOpClientSendClose>
ops;
if (options.is_last_message()) {
options.set_buffer_hint();
ops.ClientSendClose();
}
if (context_->initial_metadata_corked_) {
ops.SendInitialMetadata(&context_->send_initial_metadata_,
context_->initial_metadata_flags());
context_->set_initial_metadata_corked(false);
}
if (!ops.SendMessagePtr(&msg, options).ok()) {
return false;
}
call_.PerformOps(&ops);
return cq_.Pluck(&ops);
}
bool WritesDone() override {
::grpc::internal::CallOpSet<::grpc::internal::CallOpClientSendClose> ops;
ops.ClientSendClose();
call_.PerformOps(&ops);
return cq_.Pluck(&ops);
}
/// See the ClientStreamingInterface.Finish method for semantics.
/// Side effects:
/// - Also receives initial metadata if not already received.
/// - Attempts to fill in the \a response parameter passed
/// to the constructor of this instance with the response
/// message from the server.
Status Finish() override {
Status status;
if (!context_->initial_metadata_received_) {
finish_ops_.RecvInitialMetadata(context_);
}
finish_ops_.ClientRecvStatus(context_, &status);
call_.PerformOps(&finish_ops_);
GPR_CODEGEN_ASSERT(cq_.Pluck(&finish_ops_));
return status;
}
private:
friend class internal::ClientWriterFactory<W>;
/// Block to create a stream (i.e. send request headers and other initial
/// metadata to the server). Note that \a context will be used to fill
/// in custom initial metadata. \a response will be filled in with the
/// single expected response message from the server upon a successful
/// call to the \a Finish method of this instance.
template <class R>
ClientWriter(ChannelInterface* channel,
const ::grpc::internal::RpcMethod& method,
ClientContext* context, R* response)
: context_(context),
cq_(grpc_completion_queue_attributes{
GRPC_CQ_CURRENT_VERSION, GRPC_CQ_PLUCK, GRPC_CQ_DEFAULT_POLLING,
nullptr}), // Pluckable cq
call_(channel->CreateCall(method, context, &cq_)) {
finish_ops_.RecvMessage(response);
finish_ops_.AllowNoMessage();
if (!context_->initial_metadata_corked_) {
::grpc::internal::CallOpSet<::grpc::internal::CallOpSendInitialMetadata>
ops;
ops.SendInitialMetadata(&context->send_initial_metadata_,
context->initial_metadata_flags());
call_.PerformOps(&ops);
cq_.Pluck(&ops);
}
}
ClientContext* context_;
::grpc::internal::CallOpSet<::grpc::internal::CallOpRecvInitialMetadata,
::grpc::internal::CallOpGenericRecvMessage,
::grpc::internal::CallOpClientRecvStatus>
finish_ops_;
CompletionQueue cq_;
::grpc::internal::Call call_;
};
/// Client-side interface for bi-directional streaming with
/// client-to-server stream messages of type \a W and
/// server-to-client stream messages of type \a R.
template <class W, class R>
class ClientReaderWriterInterface : public internal::ClientStreamingInterface,
public internal::WriterInterface<W>,
public internal::ReaderInterface<R> {
public:
/// Block to wait for initial metadata from server. The received metadata
/// can only be accessed after this call returns. Should only be called before
/// the first read. Calling this method is optional, and if it is not called
/// the metadata will be available in ClientContext after the first read.
virtual void WaitForInitialMetadata() = 0;
using ClientReaderWriterInterface =
::grpc_impl::ClientReaderWriterInterface<W, R>;
/// Half close writing from the client. (signal that the stream of messages
/// coming from the clinet is complete).
/// Blocks until currently-pending writes are completed.
/// Thread-safe with respect to \a ReaderInterface::Read
///
/// \return Whether the writes were successful.
virtual bool WritesDone() = 0;
};
namespace internal {
template <class W, class R>
class ClientReaderWriterFactory {
public:
static ClientReaderWriter<W, R>* Create(
::grpc::ChannelInterface* channel,
const ::grpc::internal::RpcMethod& method, ClientContext* context) {
return new ClientReaderWriter<W, R>(channel, method, context);
}
};
} // namespace internal
/// Synchronous (blocking) client-side API for bi-directional streaming RPCs,
/// where the outgoing message stream coming from the client has messages of
/// type \a W, and the incoming messages stream coming from the server has
/// messages of type \a R.
template <class W, class R>
class ClientReaderWriter final : public ClientReaderWriterInterface<W, R> {
public:
/// Block waiting to read initial metadata from the server.
/// This call is optional, but if it is used, it cannot be used concurrently
/// with or after the \a Finish method.
///
/// Once complete, the initial metadata read from the server will be
/// accessible through the \a ClientContext used to construct this object.
void WaitForInitialMetadata() override {
GPR_CODEGEN_ASSERT(!context_->initial_metadata_received_);
::grpc::internal::CallOpSet<::grpc::internal::CallOpRecvInitialMetadata>
ops;
ops.RecvInitialMetadata(context_);
call_.PerformOps(&ops);
cq_.Pluck(&ops); // status ignored
}
bool NextMessageSize(uint32_t* sz) override {
*sz = call_.max_receive_message_size();
return true;
}
/// See the \a ReaderInterface.Read method for semantics.
/// Side effect:
/// Also receives initial metadata if not already received (updates the \a
/// ClientContext associated with this call in that case).
bool Read(R* msg) override {
::grpc::internal::CallOpSet<::grpc::internal::CallOpRecvInitialMetadata,
::grpc::internal::CallOpRecvMessage<R>>
ops;
if (!context_->initial_metadata_received_) {
ops.RecvInitialMetadata(context_);
}
ops.RecvMessage(msg);
call_.PerformOps(&ops);
return cq_.Pluck(&ops) && ops.got_message;
}
/// See the \a WriterInterface.Write method for semantics.
///
/// Side effect:
/// Also sends initial metadata if not already sent (using the
/// \a ClientContext associated with this call to fill in values).
using ::grpc::internal::WriterInterface<W>::Write;
bool Write(const W& msg, WriteOptions options) override {
::grpc::internal::CallOpSet<::grpc::internal::CallOpSendInitialMetadata,
::grpc::internal::CallOpSendMessage,
::grpc::internal::CallOpClientSendClose>
ops;
if (options.is_last_message()) {
options.set_buffer_hint();
ops.ClientSendClose();
}
if (context_->initial_metadata_corked_) {
ops.SendInitialMetadata(&context_->send_initial_metadata_,
context_->initial_metadata_flags());
context_->set_initial_metadata_corked(false);
}
if (!ops.SendMessagePtr(&msg, options).ok()) {
return false;
}
call_.PerformOps(&ops);
return cq_.Pluck(&ops);
}
bool WritesDone() override {
::grpc::internal::CallOpSet<::grpc::internal::CallOpClientSendClose> ops;
ops.ClientSendClose();
call_.PerformOps(&ops);
return cq_.Pluck(&ops);
}
using ClientReaderWriter = ::grpc_impl::ClientReaderWriter<W, R>;
/// See the ClientStreamingInterface.Finish method for semantics.
///
/// Side effect:
/// - the \a ClientContext associated with this call is updated with
/// possible trailing metadata sent from the server.
Status Finish() override {
::grpc::internal::CallOpSet<::grpc::internal::CallOpRecvInitialMetadata,
::grpc::internal::CallOpClientRecvStatus>
ops;
if (!context_->initial_metadata_received_) {
ops.RecvInitialMetadata(context_);
}
Status status;
ops.ClientRecvStatus(context_, &status);
call_.PerformOps(&ops);
GPR_CODEGEN_ASSERT(cq_.Pluck(&ops));
return status;
}
private:
friend class internal::ClientReaderWriterFactory<W, R>;
ClientContext* context_;
CompletionQueue cq_;
::grpc::internal::Call call_;
/// Block to create a stream and write the initial metadata and \a request
/// out. Note that \a context will be used to fill in custom initial metadata
/// used to send to the server when starting the call.
ClientReaderWriter(::grpc::ChannelInterface* channel,
const ::grpc::internal::RpcMethod& method,
ClientContext* context)
: context_(context),
cq_(grpc_completion_queue_attributes{
GRPC_CQ_CURRENT_VERSION, GRPC_CQ_PLUCK, GRPC_CQ_DEFAULT_POLLING,
nullptr}), // Pluckable cq
call_(channel->CreateCall(method, context, &cq_)) {
if (!context_->initial_metadata_corked_) {
::grpc::internal::CallOpSet<::grpc::internal::CallOpSendInitialMetadata>
ops;
ops.SendInitialMetadata(&context->send_initial_metadata_,
context->initial_metadata_flags());
call_.PerformOps(&ops);
cq_.Pluck(&ops);
}
}
};
/// Server-side interface for streaming reads of message of type \a R.
template <class R>
class ServerReaderInterface : public internal::ServerStreamingInterface,
public internal::ReaderInterface<R> {};
using ServerReaderInterface = ::grpc_impl::ServerReaderInterface<R>;
/// Synchronous (blocking) server-side API for doing client-streaming RPCs,
/// where the incoming message stream coming from the client has messages of
/// type \a R.
template <class R>
class ServerReader final : public ServerReaderInterface<R> {
public:
/// See the \a ServerStreamingInterface.SendInitialMetadata method
/// for semantics. Note that initial metadata will be affected by the
/// \a ServerContext associated with this call.
void SendInitialMetadata() override {
GPR_CODEGEN_ASSERT(!ctx_->sent_initial_metadata_);
internal::CallOpSet<internal::CallOpSendInitialMetadata> ops;
ops.SendInitialMetadata(&ctx_->initial_metadata_,
ctx_->initial_metadata_flags());
if (ctx_->compression_level_set()) {
ops.set_compression_level(ctx_->compression_level());
}
ctx_->sent_initial_metadata_ = true;
call_->PerformOps(&ops);
call_->cq()->Pluck(&ops);
}
bool NextMessageSize(uint32_t* sz) override {
*sz = call_->max_receive_message_size();
return true;
}
using ServerReader = ::grpc_impl::ServerReader<R>;
bool Read(R* msg) override {
internal::CallOpSet<internal::CallOpRecvMessage<R>> ops;
ops.RecvMessage(msg);
call_->PerformOps(&ops);
return call_->cq()->Pluck(&ops) && ops.got_message;
}
private:
internal::Call* const call_;
ServerContext* const ctx_;
template <class ServiceType, class RequestType, class ResponseType>
friend class internal::ClientStreamingHandler;
ServerReader(internal::Call* call, ServerContext* ctx)
: call_(call), ctx_(ctx) {}
};
/// Server-side interface for streaming writes of message of type \a W.
template <class W>
class ServerWriterInterface : public internal::ServerStreamingInterface,
public internal::WriterInterface<W> {};
using ServerWriterInterface = ::grpc_impl::ServerWriterInterface<W>;
/// Synchronous (blocking) server-side API for doing for doing a
/// server-streaming RPCs, where the outgoing message stream coming from the
/// server has messages of type \a W.
template <class W>
class ServerWriter final : public ServerWriterInterface<W> {
public:
/// See the \a ServerStreamingInterface.SendInitialMetadata method
/// for semantics.
/// Note that initial metadata will be affected by the
/// \a ServerContext associated with this call.
void SendInitialMetadata() override {
GPR_CODEGEN_ASSERT(!ctx_->sent_initial_metadata_);
internal::CallOpSet<internal::CallOpSendInitialMetadata> ops;
ops.SendInitialMetadata(&ctx_->initial_metadata_,
ctx_->initial_metadata_flags());
if (ctx_->compression_level_set()) {
ops.set_compression_level(ctx_->compression_level());
}
ctx_->sent_initial_metadata_ = true;
call_->PerformOps(&ops);
call_->cq()->Pluck(&ops);
}
using ServerWriter = ::grpc_impl::ServerWriter<W>;
/// See the \a WriterInterface.Write method for semantics.
///
/// Side effect:
/// Also sends initial metadata if not already sent (using the
/// \a ClientContext associated with this call to fill in values).
using internal::WriterInterface<W>::Write;
bool Write(const W& msg, WriteOptions options) override {
if (options.is_last_message()) {
options.set_buffer_hint();
}
if (!ctx_->pending_ops_.SendMessagePtr(&msg, options).ok()) {
return false;
}
if (!ctx_->sent_initial_metadata_) {
ctx_->pending_ops_.SendInitialMetadata(&ctx_->initial_metadata_,
ctx_->initial_metadata_flags());
if (ctx_->compression_level_set()) {
ctx_->pending_ops_.set_compression_level(ctx_->compression_level());
}
ctx_->sent_initial_metadata_ = true;
}
call_->PerformOps(&ctx_->pending_ops_);
// if this is the last message we defer the pluck until AFTER we start
// the trailing md op. This prevents hangs. See
// https://github.com/grpc/grpc/issues/11546
if (options.is_last_message()) {
ctx_->has_pending_ops_ = true;
return true;
}
ctx_->has_pending_ops_ = false;
return call_->cq()->Pluck(&ctx_->pending_ops_);
}
private:
internal::Call* const call_;
ServerContext* const ctx_;
template <class ServiceType, class RequestType, class ResponseType>
friend class internal::ServerStreamingHandler;
ServerWriter(internal::Call* call, ServerContext* ctx)
: call_(call), ctx_(ctx) {}
};
/// Server-side interface for bi-directional streaming.
template <class W, class R>
class ServerReaderWriterInterface : public internal::ServerStreamingInterface,
public internal::WriterInterface<W>,
public internal::ReaderInterface<R> {};
/// Actual implementation of bi-directional streaming
namespace internal {
template <class W, class R>
class ServerReaderWriterBody final {
public:
ServerReaderWriterBody(Call* call, ServerContext* ctx)
: call_(call), ctx_(ctx) {}
void SendInitialMetadata() {
GPR_CODEGEN_ASSERT(!ctx_->sent_initial_metadata_);
CallOpSet<CallOpSendInitialMetadata> ops;
ops.SendInitialMetadata(&ctx_->initial_metadata_,
ctx_->initial_metadata_flags());
if (ctx_->compression_level_set()) {
ops.set_compression_level(ctx_->compression_level());
}
ctx_->sent_initial_metadata_ = true;
call_->PerformOps(&ops);
call_->cq()->Pluck(&ops);
}
using ServerReaderWriterInterface =
::grpc_impl::ServerReaderWriterInterface<W, R>;
bool NextMessageSize(uint32_t* sz) {
*sz = call_->max_receive_message_size();
return true;
}
bool Read(R* msg) {
CallOpSet<CallOpRecvMessage<R>> ops;
ops.RecvMessage(msg);
call_->PerformOps(&ops);
return call_->cq()->Pluck(&ops) && ops.got_message;
}
bool Write(const W& msg, WriteOptions options) {
if (options.is_last_message()) {
options.set_buffer_hint();
}
if (!ctx_->pending_ops_.SendMessagePtr(&msg, options).ok()) {
return false;
}
if (!ctx_->sent_initial_metadata_) {
ctx_->pending_ops_.SendInitialMetadata(&ctx_->initial_metadata_,
ctx_->initial_metadata_flags());
if (ctx_->compression_level_set()) {
ctx_->pending_ops_.set_compression_level(ctx_->compression_level());
}
ctx_->sent_initial_metadata_ = true;
}
call_->PerformOps(&ctx_->pending_ops_);
// if this is the last message we defer the pluck until AFTER we start
// the trailing md op. This prevents hangs. See
// https://github.com/grpc/grpc/issues/11546
if (options.is_last_message()) {
ctx_->has_pending_ops_ = true;
return true;
}
ctx_->has_pending_ops_ = false;
return call_->cq()->Pluck(&ctx_->pending_ops_);
}
private:
Call* const call_;
ServerContext* const ctx_;
};
} // namespace internal
/// Synchronous (blocking) server-side API for a bidirectional
/// streaming call, where the incoming message stream coming from the client has
/// messages of type \a R, and the outgoing message streaming coming from
/// the server has messages of type \a W.
template <class W, class R>
class ServerReaderWriter final : public ServerReaderWriterInterface<W, R> {
public:
/// See the \a ServerStreamingInterface.SendInitialMetadata method
/// for semantics. Note that initial metadata will be affected by the
/// \a ServerContext associated with this call.
void SendInitialMetadata() override { body_.SendInitialMetadata(); }
bool NextMessageSize(uint32_t* sz) override {
return body_.NextMessageSize(sz);
}
bool Read(R* msg) override { return body_.Read(msg); }
/// See the \a WriterInterface.Write(const W& msg, WriteOptions options)
/// method for semantics.
/// Side effect:
/// Also sends initial metadata if not already sent (using the \a
/// ServerContext associated with this call).
using internal::WriterInterface<W>::Write;
bool Write(const W& msg, WriteOptions options) override {
return body_.Write(msg, options);
}
private:
internal::ServerReaderWriterBody<W, R> body_;
friend class internal::TemplatedBidiStreamingHandler<ServerReaderWriter<W, R>,
false>;
ServerReaderWriter(internal::Call* call, ServerContext* ctx)
: body_(call, ctx) {}
};
using ServerReaderWriter = ::grpc_impl::ServerReaderWriter<W, R>;
/// A class to represent a flow-controlled unary call. This is something
/// of a hybrid between conventional unary and streaming. This is invoked
/// through a unary call on the client side, but the server responds to it
/// as though it were a single-ping-pong streaming call. The server can use
/// the \a NextMessageSize method to determine an upper-bound on the size of
/// the message. A key difference relative to streaming: ServerUnaryStreamer
/// must have exactly 1 Read and exactly 1 Write, in that order, to function
/// correctly. Otherwise, the RPC is in error.
template <class RequestType, class ResponseType>
class ServerUnaryStreamer final
: public ServerReaderWriterInterface<ResponseType, RequestType> {
public:
/// Block to send initial metadata to client.
/// Implicit input parameter:
/// - the \a ServerContext associated with this call will be used for
/// sending initial metadata.
void SendInitialMetadata() override { body_.SendInitialMetadata(); }
using ServerUnaryStreamer =
::grpc_impl::ServerUnaryStreamer<RequestType, ResponseType>;
/// Get an upper bound on the request message size from the client.
bool NextMessageSize(uint32_t* sz) override {
return body_.NextMessageSize(sz);
}
/// Read a message of type \a R into \a msg. Completion will be notified by \a
/// tag on the associated completion queue.
/// This is thread-safe with respect to \a Write or \a WritesDone methods. It
/// should not be called concurrently with other streaming APIs
/// on the same stream. It is not meaningful to call it concurrently
/// with another \a ReaderInterface::Read on the same stream since reads on
/// the same stream are delivered in order.
///
/// \param[out] msg Where to eventually store the read message.
/// \param[in] tag The tag identifying the operation.
bool Read(RequestType* request) override {
if (read_done_) {
return false;
}
read_done_ = true;
return body_.Read(request);
}
/// Block to write \a msg to the stream with WriteOptions \a options.
/// This is thread-safe with respect to \a ReaderInterface::Read
///
/// \param msg The message to be written to the stream.
/// \param options The WriteOptions affecting the write operation.
///
/// \return \a true on success, \a false when the stream has been closed.
using internal::WriterInterface<ResponseType>::Write;
bool Write(const ResponseType& response, WriteOptions options) override {
if (write_done_ || !read_done_) {
return false;
}
write_done_ = true;
return body_.Write(response, options);
}
private:
internal::ServerReaderWriterBody<ResponseType, RequestType> body_;
bool read_done_;
bool write_done_;
friend class internal::TemplatedBidiStreamingHandler<
ServerUnaryStreamer<RequestType, ResponseType>, true>;
ServerUnaryStreamer(internal::Call* call, ServerContext* ctx)
: body_(call, ctx), read_done_(false), write_done_(false) {}
};
/// A class to represent a flow-controlled server-side streaming call.
/// This is something of a hybrid between server-side and bidi streaming.
/// This is invoked through a server-side streaming call on the client side,
/// but the server responds to it as though it were a bidi streaming call that
/// must first have exactly 1 Read and then any number of Writes.
template <class RequestType, class ResponseType>
class ServerSplitStreamer final
: public ServerReaderWriterInterface<ResponseType, RequestType> {
public:
/// Block to send initial metadata to client.
/// Implicit input parameter:
/// - the \a ServerContext associated with this call will be used for
/// sending initial metadata.
void SendInitialMetadata() override { body_.SendInitialMetadata(); }
/// Get an upper bound on the request message size from the client.
bool NextMessageSize(uint32_t* sz) override {
return body_.NextMessageSize(sz);
}
/// Read a message of type \a R into \a msg. Completion will be notified by \a
/// tag on the associated completion queue.
/// This is thread-safe with respect to \a Write or \a WritesDone methods. It
/// should not be called concurrently with other streaming APIs
/// on the same stream. It is not meaningful to call it concurrently
/// with another \a ReaderInterface::Read on the same stream since reads on
/// the same stream are delivered in order.
///
/// \param[out] msg Where to eventually store the read message.
/// \param[in] tag The tag identifying the operation.
bool Read(RequestType* request) override {
if (read_done_) {
return false;
}
read_done_ = true;
return body_.Read(request);
}
/// Block to write \a msg to the stream with WriteOptions \a options.
/// This is thread-safe with respect to \a ReaderInterface::Read
///
/// \param msg The message to be written to the stream.
/// \param options The WriteOptions affecting the write operation.
///
/// \return \a true on success, \a false when the stream has been closed.
using internal::WriterInterface<ResponseType>::Write;
bool Write(const ResponseType& response, WriteOptions options) override {
return read_done_ && body_.Write(response, options);
}
private:
internal::ServerReaderWriterBody<ResponseType, RequestType> body_;
bool read_done_;
friend class internal::TemplatedBidiStreamingHandler<
ServerSplitStreamer<RequestType, ResponseType>, false>;
ServerSplitStreamer(internal::Call* call, ServerContext* ctx)
: body_(call, ctx), read_done_(false) {}
};
using ServerSplitStreamer =
::grpc_impl::ServerSplitStreamer<RequestType, ResponseType>;
} // namespace grpc

@ -0,0 +1,944 @@
/*
*
* Copyright 2019 gRPC authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef GRPCPP_IMPL_CODEGEN_SYNC_STREAM_IMPL_H
#define GRPCPP_IMPL_CODEGEN_SYNC_STREAM_IMPL_H
#include <grpcpp/impl/codegen/call.h>
#include <grpcpp/impl/codegen/channel_interface.h>
#include <grpcpp/impl/codegen/client_context_impl.h>
#include <grpcpp/impl/codegen/completion_queue_impl.h>
#include <grpcpp/impl/codegen/core_codegen_interface.h>
#include <grpcpp/impl/codegen/server_context_impl.h>
#include <grpcpp/impl/codegen/service_type.h>
#include <grpcpp/impl/codegen/status.h>
namespace grpc_impl {
namespace internal {
/// Common interface for all synchronous client side streaming.
class ClientStreamingInterface {
public:
virtual ~ClientStreamingInterface() {}
/// Block waiting until the stream finishes and a final status of the call is
/// available.
///
/// It is appropriate to call this method when both:
/// * the calling code (client-side) has no more message to send
/// (this can be declared implicitly by calling this method, or
/// explicitly through an earlier call to <i>WritesDone</i> method of the
/// class in use, e.g. \a ClientWriterInterface::WritesDone or
/// \a ClientReaderWriterInterface::WritesDone).
/// * there are no more messages to be received from the server (which can
/// be known implicitly, or explicitly from an earlier call to \a
/// ReaderInterface::Read that returned "false").
///
/// This function will return either:
/// - when all incoming messages have been read and the server has
/// returned status.
/// - when the server has returned a non-OK status.
/// - OR when the call failed for some reason and the library generated a
/// status.
///
/// Return values:
/// - \a Status contains the status code, message and details for the call
/// - the \a ClientContext associated with this call is updated with
/// possible trailing metadata sent from the server.
virtual ::grpc::Status Finish() = 0;
};
/// Common interface for all synchronous server side streaming.
class ServerStreamingInterface {
public:
virtual ~ServerStreamingInterface() {}
/// Block to send initial metadata to client.
/// This call is optional, but if it is used, it cannot be used concurrently
/// with or after the \a Finish method.
///
/// The initial metadata that will be sent to the client will be
/// taken from the \a ServerContext associated with the call.
virtual void SendInitialMetadata() = 0;
};
/// An interface that yields a sequence of messages of type \a R.
template <class R>
class ReaderInterface {
public:
virtual ~ReaderInterface() {}
/// Get an upper bound on the next message size available for reading on this
/// stream.
virtual bool NextMessageSize(uint32_t* sz) = 0;
/// Block to read a message and parse to \a msg. Returns \a true on success.
/// This is thread-safe with respect to \a Write or \WritesDone methods on
/// the same stream. It should not be called concurrently with another \a
/// Read on the same stream as the order of delivery will not be defined.
///
/// \param[out] msg The read message.
///
/// \return \a false when there will be no more incoming messages, either
/// because the other side has called \a WritesDone() or the stream has failed
/// (or been cancelled).
virtual bool Read(R* msg) = 0;
};
/// An interface that can be fed a sequence of messages of type \a W.
template <class W>
class WriterInterface {
public:
virtual ~WriterInterface() {}
/// Block to write \a msg to the stream with WriteOptions \a options.
/// This is thread-safe with respect to \a ReaderInterface::Read
///
/// \param msg The message to be written to the stream.
/// \param options The WriteOptions affecting the write operation.
///
/// \return \a true on success, \a false when the stream has been closed.
virtual bool Write(const W& msg, ::grpc::WriteOptions options) = 0;
/// Block to write \a msg to the stream with default write options.
/// This is thread-safe with respect to \a ReaderInterface::Read
///
/// \param msg The message to be written to the stream.
///
/// \return \a true on success, \a false when the stream has been closed.
inline bool Write(const W& msg) { return Write(msg, ::grpc::WriteOptions()); }
/// Write \a msg and coalesce it with the writing of trailing metadata, using
/// WriteOptions \a options.
///
/// For client, WriteLast is equivalent of performing Write and WritesDone in
/// a single step. \a msg and trailing metadata are coalesced and sent on wire
/// by calling this function. For server, WriteLast buffers the \a msg.
/// The writing of \a msg is held until the service handler returns,
/// where \a msg and trailing metadata are coalesced and sent on wire.
/// Note that WriteLast can only buffer \a msg up to the flow control window
/// size. If \a msg size is larger than the window size, it will be sent on
/// wire without buffering.
///
/// \param[in] msg The message to be written to the stream.
/// \param[in] options The WriteOptions to be used to write this message.
void WriteLast(const W& msg, ::grpc::WriteOptions options) {
Write(msg, options.set_last_message());
}
};
} // namespace internal
/// Client-side interface for streaming reads of message of type \a R.
template <class R>
class ClientReaderInterface : public internal::ClientStreamingInterface,
public internal::ReaderInterface<R> {
public:
/// Block to wait for initial metadata from server. The received metadata
/// can only be accessed after this call returns. Should only be called before
/// the first read. Calling this method is optional, and if it is not called
/// the metadata will be available in ClientContext after the first read.
virtual void WaitForInitialMetadata() = 0;
};
namespace internal {
template <class R>
class ClientReaderFactory {
public:
template <class W>
static ClientReader<R>* Create(::grpc::ChannelInterface* channel,
const ::grpc::internal::RpcMethod& method,
::grpc_impl::ClientContext* context,
const W& request) {
return new ClientReader<R>(channel, method, context, request);
}
};
} // namespace internal
/// Synchronous (blocking) client-side API for doing server-streaming RPCs,
/// where the stream of messages coming from the server has messages
/// of type \a R.
template <class R>
class ClientReader final : public ClientReaderInterface<R> {
public:
/// See the \a ClientStreamingInterface.WaitForInitialMetadata method for
/// semantics.
///
// Side effect:
/// Once complete, the initial metadata read from
/// the server will be accessible through the \a ClientContext used to
/// construct this object.
void WaitForInitialMetadata() override {
GPR_CODEGEN_ASSERT(!context_->initial_metadata_received_);
::grpc::internal::CallOpSet<::grpc::internal::CallOpRecvInitialMetadata>
ops;
ops.RecvInitialMetadata(context_);
call_.PerformOps(&ops);
cq_.Pluck(&ops); /// status ignored
}
bool NextMessageSize(uint32_t* sz) override {
*sz = call_.max_receive_message_size();
return true;
}
/// See the \a ReaderInterface.Read method for semantics.
/// Side effect:
/// This also receives initial metadata from the server, if not
/// already received (if initial metadata is received, it can be then
/// accessed through the \a ClientContext associated with this call).
bool Read(R* msg) override {
::grpc::internal::CallOpSet<::grpc::internal::CallOpRecvInitialMetadata,
::grpc::internal::CallOpRecvMessage<R>>
ops;
if (!context_->initial_metadata_received_) {
ops.RecvInitialMetadata(context_);
}
ops.RecvMessage(msg);
call_.PerformOps(&ops);
return cq_.Pluck(&ops) && ops.got_message;
}
/// See the \a ClientStreamingInterface.Finish method for semantics.
///
/// Side effect:
/// The \a ClientContext associated with this call is updated with
/// possible metadata received from the server.
::grpc::Status Finish() override {
::grpc::internal::CallOpSet<::grpc::internal::CallOpClientRecvStatus> ops;
::grpc::Status status;
ops.ClientRecvStatus(context_, &status);
call_.PerformOps(&ops);
GPR_CODEGEN_ASSERT(cq_.Pluck(&ops));
return status;
}
private:
friend class internal::ClientReaderFactory<R>;
::grpc_impl::ClientContext* context_;
::grpc_impl::CompletionQueue cq_;
::grpc::internal::Call call_;
/// Block to create a stream and write the initial metadata and \a request
/// out. Note that \a context will be used to fill in custom initial
/// metadata used to send to the server when starting the call.
template <class W>
ClientReader(::grpc::ChannelInterface* channel,
const ::grpc::internal::RpcMethod& method,
::grpc_impl::ClientContext* context, const W& request)
: context_(context),
cq_(grpc_completion_queue_attributes{
GRPC_CQ_CURRENT_VERSION, GRPC_CQ_PLUCK, GRPC_CQ_DEFAULT_POLLING,
nullptr}), // Pluckable cq
call_(channel->CreateCall(method, context, &cq_)) {
::grpc::internal::CallOpSet<::grpc::internal::CallOpSendInitialMetadata,
::grpc::internal::CallOpSendMessage,
::grpc::internal::CallOpClientSendClose>
ops;
ops.SendInitialMetadata(&context->send_initial_metadata_,
context->initial_metadata_flags());
// TODO(ctiller): don't assert
GPR_CODEGEN_ASSERT(ops.SendMessagePtr(&request).ok());
ops.ClientSendClose();
call_.PerformOps(&ops);
cq_.Pluck(&ops);
}
};
/// Client-side interface for streaming writes of message type \a W.
template <class W>
class ClientWriterInterface : public internal::ClientStreamingInterface,
public internal::WriterInterface<W> {
public:
/// Half close writing from the client. (signal that the stream of messages
/// coming from the client is complete).
/// Blocks until currently-pending writes are completed.
/// Thread safe with respect to \a ReaderInterface::Read operations only
///
/// \return Whether the writes were successful.
virtual bool WritesDone() = 0;
};
namespace internal {
template <class W>
class ClientWriterFactory {
public:
template <class R>
static ClientWriter<W>* Create(::grpc::ChannelInterface* channel,
const ::grpc::internal::RpcMethod& method,
::grpc_impl::ClientContext* context,
R* response) {
return new ClientWriter<W>(channel, method, context, response);
}
};
} // namespace internal
/// Synchronous (blocking) client-side API for doing client-streaming RPCs,
/// where the outgoing message stream coming from the client has messages of
/// type \a W.
template <class W>
class ClientWriter : public ClientWriterInterface<W> {
public:
/// See the \a ClientStreamingInterface.WaitForInitialMetadata method for
/// semantics.
///
// Side effect:
/// Once complete, the initial metadata read from the server will be
/// accessible through the \a ClientContext used to construct this object.
void WaitForInitialMetadata() {
GPR_CODEGEN_ASSERT(!context_->initial_metadata_received_);
::grpc::internal::CallOpSet<::grpc::internal::CallOpRecvInitialMetadata>
ops;
ops.RecvInitialMetadata(context_);
call_.PerformOps(&ops);
cq_.Pluck(&ops); // status ignored
}
/// See the WriterInterface.Write(const W& msg, WriteOptions options) method
/// for semantics.
///
/// Side effect:
/// Also sends initial metadata if not already sent (using the
/// \a ClientContext associated with this call).
using internal::WriterInterface<W>::Write;
bool Write(const W& msg, ::grpc::WriteOptions options) override {
::grpc::internal::CallOpSet<::grpc::internal::CallOpSendInitialMetadata,
::grpc::internal::CallOpSendMessage,
::grpc::internal::CallOpClientSendClose>
ops;
if (options.is_last_message()) {
options.set_buffer_hint();
ops.ClientSendClose();
}
if (context_->initial_metadata_corked_) {
ops.SendInitialMetadata(&context_->send_initial_metadata_,
context_->initial_metadata_flags());
context_->set_initial_metadata_corked(false);
}
if (!ops.SendMessagePtr(&msg, options).ok()) {
return false;
}
call_.PerformOps(&ops);
return cq_.Pluck(&ops);
}
bool WritesDone() override {
::grpc::internal::CallOpSet<::grpc::internal::CallOpClientSendClose> ops;
ops.ClientSendClose();
call_.PerformOps(&ops);
return cq_.Pluck(&ops);
}
/// See the ClientStreamingInterface.Finish method for semantics.
/// Side effects:
/// - Also receives initial metadata if not already received.
/// - Attempts to fill in the \a response parameter passed
/// to the constructor of this instance with the response
/// message from the server.
::grpc::Status Finish() override {
::grpc::Status status;
if (!context_->initial_metadata_received_) {
finish_ops_.RecvInitialMetadata(context_);
}
finish_ops_.ClientRecvStatus(context_, &status);
call_.PerformOps(&finish_ops_);
GPR_CODEGEN_ASSERT(cq_.Pluck(&finish_ops_));
return status;
}
private:
friend class internal::ClientWriterFactory<W>;
/// Block to create a stream (i.e. send request headers and other initial
/// metadata to the server). Note that \a context will be used to fill
/// in custom initial metadata. \a response will be filled in with the
/// single expected response message from the server upon a successful
/// call to the \a Finish method of this instance.
template <class R>
ClientWriter(::grpc::ChannelInterface* channel,
const ::grpc::internal::RpcMethod& method,
::grpc_impl::ClientContext* context, R* response)
: context_(context),
cq_(grpc_completion_queue_attributes{
GRPC_CQ_CURRENT_VERSION, GRPC_CQ_PLUCK, GRPC_CQ_DEFAULT_POLLING,
nullptr}), // Pluckable cq
call_(channel->CreateCall(method, context, &cq_)) {
finish_ops_.RecvMessage(response);
finish_ops_.AllowNoMessage();
if (!context_->initial_metadata_corked_) {
::grpc::internal::CallOpSet<::grpc::internal::CallOpSendInitialMetadata>
ops;
ops.SendInitialMetadata(&context->send_initial_metadata_,
context->initial_metadata_flags());
call_.PerformOps(&ops);
cq_.Pluck(&ops);
}
}
::grpc_impl::ClientContext* context_;
::grpc::internal::CallOpSet<::grpc::internal::CallOpRecvInitialMetadata,
::grpc::internal::CallOpGenericRecvMessage,
::grpc::internal::CallOpClientRecvStatus>
finish_ops_;
::grpc_impl::CompletionQueue cq_;
::grpc::internal::Call call_;
};
/// Client-side interface for bi-directional streaming with
/// client-to-server stream messages of type \a W and
/// server-to-client stream messages of type \a R.
template <class W, class R>
class ClientReaderWriterInterface : public internal::ClientStreamingInterface,
public internal::WriterInterface<W>,
public internal::ReaderInterface<R> {
public:
/// Block to wait for initial metadata from server. The received metadata
/// can only be accessed after this call returns. Should only be called before
/// the first read. Calling this method is optional, and if it is not called
/// the metadata will be available in ClientContext after the first read.
virtual void WaitForInitialMetadata() = 0;
/// Half close writing from the client. (signal that the stream of messages
/// coming from the clinet is complete).
/// Blocks until currently-pending writes are completed.
/// Thread-safe with respect to \a ReaderInterface::Read
///
/// \return Whether the writes were successful.
virtual bool WritesDone() = 0;
};
namespace internal {
template <class W, class R>
class ClientReaderWriterFactory {
public:
static ClientReaderWriter<W, R>* Create(
::grpc::ChannelInterface* channel,
const ::grpc::internal::RpcMethod& method,
::grpc_impl::ClientContext* context) {
return new ClientReaderWriter<W, R>(channel, method, context);
}
};
} // namespace internal
/// Synchronous (blocking) client-side API for bi-directional streaming RPCs,
/// where the outgoing message stream coming from the client has messages of
/// type \a W, and the incoming messages stream coming from the server has
/// messages of type \a R.
template <class W, class R>
class ClientReaderWriter final : public ClientReaderWriterInterface<W, R> {
public:
/// Block waiting to read initial metadata from the server.
/// This call is optional, but if it is used, it cannot be used concurrently
/// with or after the \a Finish method.
///
/// Once complete, the initial metadata read from the server will be
/// accessible through the \a ClientContext used to construct this object.
void WaitForInitialMetadata() override {
GPR_CODEGEN_ASSERT(!context_->initial_metadata_received_);
::grpc::internal::CallOpSet<::grpc::internal::CallOpRecvInitialMetadata>
ops;
ops.RecvInitialMetadata(context_);
call_.PerformOps(&ops);
cq_.Pluck(&ops); // status ignored
}
bool NextMessageSize(uint32_t* sz) override {
*sz = call_.max_receive_message_size();
return true;
}
/// See the \a ReaderInterface.Read method for semantics.
/// Side effect:
/// Also receives initial metadata if not already received (updates the \a
/// ClientContext associated with this call in that case).
bool Read(R* msg) override {
::grpc::internal::CallOpSet<::grpc::internal::CallOpRecvInitialMetadata,
::grpc::internal::CallOpRecvMessage<R>>
ops;
if (!context_->initial_metadata_received_) {
ops.RecvInitialMetadata(context_);
}
ops.RecvMessage(msg);
call_.PerformOps(&ops);
return cq_.Pluck(&ops) && ops.got_message;
}
/// See the \a WriterInterface.Write method for semantics.
///
/// Side effect:
/// Also sends initial metadata if not already sent (using the
/// \a ClientContext associated with this call to fill in values).
using internal::WriterInterface<W>::Write;
bool Write(const W& msg, ::grpc::WriteOptions options) override {
::grpc::internal::CallOpSet<::grpc::internal::CallOpSendInitialMetadata,
::grpc::internal::CallOpSendMessage,
::grpc::internal::CallOpClientSendClose>
ops;
if (options.is_last_message()) {
options.set_buffer_hint();
ops.ClientSendClose();
}
if (context_->initial_metadata_corked_) {
ops.SendInitialMetadata(&context_->send_initial_metadata_,
context_->initial_metadata_flags());
context_->set_initial_metadata_corked(false);
}
if (!ops.SendMessagePtr(&msg, options).ok()) {
return false;
}
call_.PerformOps(&ops);
return cq_.Pluck(&ops);
}
bool WritesDone() override {
::grpc::internal::CallOpSet<::grpc::internal::CallOpClientSendClose> ops;
ops.ClientSendClose();
call_.PerformOps(&ops);
return cq_.Pluck(&ops);
}
/// See the ClientStreamingInterface.Finish method for semantics.
///
/// Side effect:
/// - the \a ClientContext associated with this call is updated with
/// possible trailing metadata sent from the server.
::grpc::Status Finish() override {
::grpc::internal::CallOpSet<::grpc::internal::CallOpRecvInitialMetadata,
::grpc::internal::CallOpClientRecvStatus>
ops;
if (!context_->initial_metadata_received_) {
ops.RecvInitialMetadata(context_);
}
::grpc::Status status;
ops.ClientRecvStatus(context_, &status);
call_.PerformOps(&ops);
GPR_CODEGEN_ASSERT(cq_.Pluck(&ops));
return status;
}
private:
friend class internal::ClientReaderWriterFactory<W, R>;
::grpc_impl::ClientContext* context_;
::grpc_impl::CompletionQueue cq_;
::grpc::internal::Call call_;
/// Block to create a stream and write the initial metadata and \a request
/// out. Note that \a context will be used to fill in custom initial metadata
/// used to send to the server when starting the call.
ClientReaderWriter(::grpc::ChannelInterface* channel,
const ::grpc::internal::RpcMethod& method,
::grpc_impl::ClientContext* context)
: context_(context),
cq_(grpc_completion_queue_attributes{
GRPC_CQ_CURRENT_VERSION, GRPC_CQ_PLUCK, GRPC_CQ_DEFAULT_POLLING,
nullptr}), // Pluckable cq
call_(channel->CreateCall(method, context, &cq_)) {
if (!context_->initial_metadata_corked_) {
::grpc::internal::CallOpSet<::grpc::internal::CallOpSendInitialMetadata>
ops;
ops.SendInitialMetadata(&context->send_initial_metadata_,
context->initial_metadata_flags());
call_.PerformOps(&ops);
cq_.Pluck(&ops);
}
}
};
/// Server-side interface for streaming reads of message of type \a R.
template <class R>
class ServerReaderInterface : public internal::ServerStreamingInterface,
public internal::ReaderInterface<R> {};
/// Synchronous (blocking) server-side API for doing client-streaming RPCs,
/// where the incoming message stream coming from the client has messages of
/// type \a R.
template <class R>
class ServerReader final : public ServerReaderInterface<R> {
public:
/// See the \a ServerStreamingInterface.SendInitialMetadata method
/// for semantics. Note that initial metadata will be affected by the
/// \a ServerContext associated with this call.
void SendInitialMetadata() override {
GPR_CODEGEN_ASSERT(!ctx_->sent_initial_metadata_);
::grpc::internal::CallOpSet<::grpc::internal::CallOpSendInitialMetadata>
ops;
ops.SendInitialMetadata(&ctx_->initial_metadata_,
ctx_->initial_metadata_flags());
if (ctx_->compression_level_set()) {
ops.set_compression_level(ctx_->compression_level());
}
ctx_->sent_initial_metadata_ = true;
call_->PerformOps(&ops);
call_->cq()->Pluck(&ops);
}
bool NextMessageSize(uint32_t* sz) override {
*sz = call_->max_receive_message_size();
return true;
}
bool Read(R* msg) override {
::grpc::internal::CallOpSet<::grpc::internal::CallOpRecvMessage<R>> ops;
ops.RecvMessage(msg);
call_->PerformOps(&ops);
return call_->cq()->Pluck(&ops) && ops.got_message;
}
private:
::grpc::internal::Call* const call_;
ServerContext* const ctx_;
template <class ServiceType, class RequestType, class ResponseType>
friend class ::grpc::internal::ClientStreamingHandler;
ServerReader(::grpc::internal::Call* call, ::grpc_impl::ServerContext* ctx)
: call_(call), ctx_(ctx) {}
};
/// Server-side interface for streaming writes of message of type \a W.
template <class W>
class ServerWriterInterface : public internal::ServerStreamingInterface,
public internal::WriterInterface<W> {};
/// Synchronous (blocking) server-side API for doing for doing a
/// server-streaming RPCs, where the outgoing message stream coming from the
/// server has messages of type \a W.
template <class W>
class ServerWriter final : public ServerWriterInterface<W> {
public:
/// See the \a ServerStreamingInterface.SendInitialMetadata method
/// for semantics.
/// Note that initial metadata will be affected by the
/// \a ServerContext associated with this call.
void SendInitialMetadata() override {
GPR_CODEGEN_ASSERT(!ctx_->sent_initial_metadata_);
::grpc::internal::CallOpSet<::grpc::internal::CallOpSendInitialMetadata>
ops;
ops.SendInitialMetadata(&ctx_->initial_metadata_,
ctx_->initial_metadata_flags());
if (ctx_->compression_level_set()) {
ops.set_compression_level(ctx_->compression_level());
}
ctx_->sent_initial_metadata_ = true;
call_->PerformOps(&ops);
call_->cq()->Pluck(&ops);
}
/// See the \a WriterInterface.Write method for semantics.
///
/// Side effect:
/// Also sends initial metadata if not already sent (using the
/// \a ClientContext associated with this call to fill in values).
using internal::WriterInterface<W>::Write;
bool Write(const W& msg, ::grpc::WriteOptions options) override {
if (options.is_last_message()) {
options.set_buffer_hint();
}
if (!ctx_->pending_ops_.SendMessagePtr(&msg, options).ok()) {
return false;
}
if (!ctx_->sent_initial_metadata_) {
ctx_->pending_ops_.SendInitialMetadata(&ctx_->initial_metadata_,
ctx_->initial_metadata_flags());
if (ctx_->compression_level_set()) {
ctx_->pending_ops_.set_compression_level(ctx_->compression_level());
}
ctx_->sent_initial_metadata_ = true;
}
call_->PerformOps(&ctx_->pending_ops_);
// if this is the last message we defer the pluck until AFTER we start
// the trailing md op. This prevents hangs. See
// https://github.com/grpc/grpc/issues/11546
if (options.is_last_message()) {
ctx_->has_pending_ops_ = true;
return true;
}
ctx_->has_pending_ops_ = false;
return call_->cq()->Pluck(&ctx_->pending_ops_);
}
private:
::grpc::internal::Call* const call_;
::grpc_impl::ServerContext* const ctx_;
template <class ServiceType, class RequestType, class ResponseType>
friend class ::grpc::internal::ServerStreamingHandler;
ServerWriter(::grpc::internal::Call* call, ::grpc_impl::ServerContext* ctx)
: call_(call), ctx_(ctx) {}
};
/// Server-side interface for bi-directional streaming.
template <class W, class R>
class ServerReaderWriterInterface : public internal::ServerStreamingInterface,
public internal::WriterInterface<W>,
public internal::ReaderInterface<R> {};
/// Actual implementation of bi-directional streaming
namespace internal {
template <class W, class R>
class ServerReaderWriterBody final {
public:
ServerReaderWriterBody(grpc::internal::Call* call,
::grpc_impl::ServerContext* ctx)
: call_(call), ctx_(ctx) {}
void SendInitialMetadata() {
GPR_CODEGEN_ASSERT(!ctx_->sent_initial_metadata_);
grpc::internal::CallOpSet<grpc::internal::CallOpSendInitialMetadata> ops;
ops.SendInitialMetadata(&ctx_->initial_metadata_,
ctx_->initial_metadata_flags());
if (ctx_->compression_level_set()) {
ops.set_compression_level(ctx_->compression_level());
}
ctx_->sent_initial_metadata_ = true;
call_->PerformOps(&ops);
call_->cq()->Pluck(&ops);
}
bool NextMessageSize(uint32_t* sz) {
*sz = call_->max_receive_message_size();
return true;
}
bool Read(R* msg) {
::grpc::internal::CallOpSet<::grpc::internal::CallOpRecvMessage<R>> ops;
ops.RecvMessage(msg);
call_->PerformOps(&ops);
return call_->cq()->Pluck(&ops) && ops.got_message;
}
bool Write(const W& msg, ::grpc::WriteOptions options) {
if (options.is_last_message()) {
options.set_buffer_hint();
}
if (!ctx_->pending_ops_.SendMessagePtr(&msg, options).ok()) {
return false;
}
if (!ctx_->sent_initial_metadata_) {
ctx_->pending_ops_.SendInitialMetadata(&ctx_->initial_metadata_,
ctx_->initial_metadata_flags());
if (ctx_->compression_level_set()) {
ctx_->pending_ops_.set_compression_level(ctx_->compression_level());
}
ctx_->sent_initial_metadata_ = true;
}
call_->PerformOps(&ctx_->pending_ops_);
// if this is the last message we defer the pluck until AFTER we start
// the trailing md op. This prevents hangs. See
// https://github.com/grpc/grpc/issues/11546
if (options.is_last_message()) {
ctx_->has_pending_ops_ = true;
return true;
}
ctx_->has_pending_ops_ = false;
return call_->cq()->Pluck(&ctx_->pending_ops_);
}
private:
grpc::internal::Call* const call_;
::grpc_impl::ServerContext* const ctx_;
};
} // namespace internal
/// Synchronous (blocking) server-side API for a bidirectional
/// streaming call, where the incoming message stream coming from the client has
/// messages of type \a R, and the outgoing message streaming coming from
/// the server has messages of type \a W.
template <class W, class R>
class ServerReaderWriter final : public ServerReaderWriterInterface<W, R> {
public:
/// See the \a ServerStreamingInterface.SendInitialMetadata method
/// for semantics. Note that initial metadata will be affected by the
/// \a ServerContext associated with this call.
void SendInitialMetadata() override { body_.SendInitialMetadata(); }
bool NextMessageSize(uint32_t* sz) override {
return body_.NextMessageSize(sz);
}
bool Read(R* msg) override { return body_.Read(msg); }
/// See the \a WriterInterface.Write(const W& msg, WriteOptions options)
/// method for semantics.
/// Side effect:
/// Also sends initial metadata if not already sent (using the \a
/// ServerContext associated with this call).
using internal::WriterInterface<W>::Write;
bool Write(const W& msg, ::grpc::WriteOptions options) override {
return body_.Write(msg, options);
}
private:
internal::ServerReaderWriterBody<W, R> body_;
friend class ::grpc::internal::TemplatedBidiStreamingHandler<
ServerReaderWriter<W, R>, false>;
ServerReaderWriter(::grpc::internal::Call* call,
::grpc_impl::ServerContext* ctx)
: body_(call, ctx) {}
};
/// A class to represent a flow-controlled unary call. This is something
/// of a hybrid between conventional unary and streaming. This is invoked
/// through a unary call on the client side, but the server responds to it
/// as though it were a single-ping-pong streaming call. The server can use
/// the \a NextMessageSize method to determine an upper-bound on the size of
/// the message. A key difference relative to streaming: ServerUnaryStreamer
/// must have exactly 1 Read and exactly 1 Write, in that order, to function
/// correctly. Otherwise, the RPC is in error.
template <class RequestType, class ResponseType>
class ServerUnaryStreamer final
: public ServerReaderWriterInterface<ResponseType, RequestType> {
public:
/// Block to send initial metadata to client.
/// Implicit input parameter:
/// - the \a ServerContext associated with this call will be used for
/// sending initial metadata.
void SendInitialMetadata() override { body_.SendInitialMetadata(); }
/// Get an upper bound on the request message size from the client.
bool NextMessageSize(uint32_t* sz) override {
return body_.NextMessageSize(sz);
}
/// Read a message of type \a R into \a msg. Completion will be notified by \a
/// tag on the associated completion queue.
/// This is thread-safe with respect to \a Write or \a WritesDone methods. It
/// should not be called concurrently with other streaming APIs
/// on the same stream. It is not meaningful to call it concurrently
/// with another \a ReaderInterface::Read on the same stream since reads on
/// the same stream are delivered in order.
///
/// \param[out] msg Where to eventually store the read message.
/// \param[in] tag The tag identifying the operation.
bool Read(RequestType* request) override {
if (read_done_) {
return false;
}
read_done_ = true;
return body_.Read(request);
}
/// Block to write \a msg to the stream with WriteOptions \a options.
/// This is thread-safe with respect to \a ReaderInterface::Read
///
/// \param msg The message to be written to the stream.
/// \param options The WriteOptions affecting the write operation.
///
/// \return \a true on success, \a false when the stream has been closed.
using internal::WriterInterface<ResponseType>::Write;
bool Write(const ResponseType& response,
::grpc::WriteOptions options) override {
if (write_done_ || !read_done_) {
return false;
}
write_done_ = true;
return body_.Write(response, options);
}
private:
internal::ServerReaderWriterBody<ResponseType, RequestType> body_;
bool read_done_;
bool write_done_;
friend class ::grpc::internal::TemplatedBidiStreamingHandler<
ServerUnaryStreamer<RequestType, ResponseType>, true>;
ServerUnaryStreamer(::grpc::internal::Call* call,
::grpc_impl::ServerContext* ctx)
: body_(call, ctx), read_done_(false), write_done_(false) {}
};
/// A class to represent a flow-controlled server-side streaming call.
/// This is something of a hybrid between server-side and bidi streaming.
/// This is invoked through a server-side streaming call on the client side,
/// but the server responds to it as though it were a bidi streaming call that
/// must first have exactly 1 Read and then any number of Writes.
template <class RequestType, class ResponseType>
class ServerSplitStreamer final
: public ServerReaderWriterInterface<ResponseType, RequestType> {
public:
/// Block to send initial metadata to client.
/// Implicit input parameter:
/// - the \a ServerContext associated with this call will be used for
/// sending initial metadata.
void SendInitialMetadata() override { body_.SendInitialMetadata(); }
/// Get an upper bound on the request message size from the client.
bool NextMessageSize(uint32_t* sz) override {
return body_.NextMessageSize(sz);
}
/// Read a message of type \a R into \a msg. Completion will be notified by \a
/// tag on the associated completion queue.
/// This is thread-safe with respect to \a Write or \a WritesDone methods. It
/// should not be called concurrently with other streaming APIs
/// on the same stream. It is not meaningful to call it concurrently
/// with another \a ReaderInterface::Read on the same stream since reads on
/// the same stream are delivered in order.
///
/// \param[out] msg Where to eventually store the read message.
/// \param[in] tag The tag identifying the operation.
bool Read(RequestType* request) override {
if (read_done_) {
return false;
}
read_done_ = true;
return body_.Read(request);
}
/// Block to write \a msg to the stream with WriteOptions \a options.
/// This is thread-safe with respect to \a ReaderInterface::Read
///
/// \param msg The message to be written to the stream.
/// \param options The WriteOptions affecting the write operation.
///
/// \return \a true on success, \a false when the stream has been closed.
using internal::WriterInterface<ResponseType>::Write;
bool Write(const ResponseType& response,
::grpc::WriteOptions options) override {
return read_done_ && body_.Write(response, options);
}
private:
internal::ServerReaderWriterBody<ResponseType, RequestType> body_;
bool read_done_;
friend class ::grpc::internal::TemplatedBidiStreamingHandler<
ServerSplitStreamer<RequestType, ResponseType>, false>;
ServerSplitStreamer(::grpc::internal::Call* call,
::grpc_impl::ServerContext* ctx)
: body_(call, ctx), read_done_(false) {}
};
} // namespace grpc_impl
#endif // GRPCPP_IMPL_CODEGEN_SYNC_STREAM_IMPL_H

@ -21,11 +21,11 @@
#include <memory>
#include <grpcpp/support/channel_arguments.h>
#include <grpcpp/support/config.h>
namespace grpc_impl {
class ChannelArguments;
class ServerBuilder;
class ServerInitializer;
} // namespace grpc_impl
@ -57,7 +57,7 @@ class ServerBuilderPlugin {
/// UpdateChannelArguments will be called in ServerBuilder::BuildAndStart(),
/// before the Server instance is created.
virtual void UpdateChannelArguments(grpc_impl::ChannelArguments* args) {}
virtual void UpdateChannelArguments(ChannelArguments* args) {}
virtual bool has_sync_methods() const { return false; }
virtual bool has_async_methods() const { return false; }

@ -28,6 +28,7 @@ typedef ::grpc_impl::CallCredentials CallCredentials;
typedef ::grpc_impl::SslCredentialsOptions SslCredentialsOptions;
typedef ::grpc_impl::SecureCallCredentials SecureCallCredentials;
typedef ::grpc_impl::SecureChannelCredentials SecureChannelCredentials;
typedef ::grpc_impl::MetadataCredentialsPlugin MetadataCredentialsPlugin;
static inline std::shared_ptr<grpc_impl::ChannelCredentials>
GoogleDefaultCredentials() {
@ -105,6 +106,24 @@ MetadataCredentialsFromPlugin(
namespace experimental {
typedef ::grpc_impl::experimental::StsCredentialsOptions StsCredentialsOptions;
static inline grpc::Status StsCredentialsOptionsFromJson(
const grpc::string& json_string, StsCredentialsOptions* options) {
return ::grpc_impl::experimental::StsCredentialsOptionsFromJson(json_string,
options);
}
static inline grpc::Status StsCredentialsOptionsFromEnv(
StsCredentialsOptions* options) {
return grpc_impl::experimental::StsCredentialsOptionsFromEnv(options);
}
static inline std::shared_ptr<grpc_impl::CallCredentials> StsCredentials(
const StsCredentialsOptions& options) {
return grpc_impl::experimental::StsCredentials(options);
}
typedef ::grpc_impl::experimental::AltsCredentialsOptions
AltsCredentialsOptions;

@ -24,11 +24,11 @@
#include <vector>
#include <grpc/grpc_security_constants.h>
#include <grpcpp/channel.h>
#include <grpcpp/channel_impl.h>
#include <grpcpp/impl/codegen/client_interceptor.h>
#include <grpcpp/impl/codegen/grpc_library.h>
#include <grpcpp/security/auth_context.h>
#include <grpcpp/support/channel_arguments.h>
#include <grpcpp/support/channel_arguments_impl.h>
#include <grpcpp/support/status.h>
#include <grpcpp/support/string_ref.h>
@ -41,16 +41,16 @@ class CallCredentials;
class SecureCallCredentials;
class SecureChannelCredentials;
std::shared_ptr<::grpc::Channel> CreateCustomChannelImpl(
std::shared_ptr<Channel> CreateCustomChannelImpl(
const grpc::string& target,
const std::shared_ptr<ChannelCredentials>& creds,
const grpc::ChannelArguments& args);
const ChannelArguments& args);
namespace experimental {
std::shared_ptr<::grpc::Channel> CreateCustomChannelWithInterceptors(
std::shared_ptr<Channel> CreateCustomChannelWithInterceptors(
const grpc::string& target,
const std::shared_ptr<ChannelCredentials>& creds,
const grpc::ChannelArguments& args,
const ChannelArguments& args,
std::vector<
std::unique_ptr<grpc::experimental::ClientInterceptorFactoryInterface>>
interceptor_creators);
@ -75,27 +75,27 @@ class ChannelCredentials : private grpc::GrpcLibraryCodegen {
virtual SecureChannelCredentials* AsSecureCredentials() = 0;
private:
friend std::shared_ptr<::grpc::Channel> CreateCustomChannelImpl(
friend std::shared_ptr<Channel> CreateCustomChannelImpl(
const grpc::string& target,
const std::shared_ptr<ChannelCredentials>& creds,
const grpc::ChannelArguments& args);
const ChannelArguments& args);
friend std::shared_ptr<::grpc::Channel>
friend std::shared_ptr<Channel>
grpc_impl::experimental::CreateCustomChannelWithInterceptors(
const grpc::string& target,
const std::shared_ptr<ChannelCredentials>& creds,
const grpc::ChannelArguments& args,
const ChannelArguments& args,
std::vector<std::unique_ptr<
grpc::experimental::ClientInterceptorFactoryInterface>>
interceptor_creators);
virtual std::shared_ptr<::grpc::Channel> CreateChannelImpl(
const grpc::string& target, const grpc::ChannelArguments& args) = 0;
virtual std::shared_ptr<Channel> CreateChannelImpl(
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::Channel> CreateChannelWithInterceptors(
const grpc::string& target, const grpc::ChannelArguments& args,
virtual std::shared_ptr<Channel> CreateChannelWithInterceptors(
const grpc::string& target, const ChannelArguments& args,
std::vector<std::unique_ptr<
grpc::experimental::ClientInterceptorFactoryInterface>>
interceptor_creators) {
@ -259,6 +259,70 @@ std::shared_ptr<CallCredentials> MetadataCredentialsFromPlugin(
namespace experimental {
/// Options for creating STS Oauth Token Exchange credentials following the IETF
/// draft https://tools.ietf.org/html/draft-ietf-oauth-token-exchange-16.
/// Optional fields may be set to empty string. It is the responsibility of the
/// caller to ensure that the subject and actor tokens are refreshed on disk at
/// the specified paths.
struct StsCredentialsOptions {
grpc::string token_exchange_service_uri; // Required.
grpc::string resource; // Optional.
grpc::string audience; // Optional.
grpc::string scope; // Optional.
grpc::string requested_token_type; // Optional.
grpc::string subject_token_path; // Required.
grpc::string subject_token_type; // Required.
grpc::string actor_token_path; // Optional.
grpc::string actor_token_type; // Optional.
};
/// Creates STS Options from a JSON string. The JSON schema is as follows:
/// {
/// "title": "STS Credentials Config",
/// "type": "object",
/// "required": ["token_exchange_service_uri", "subject_token_path",
/// "subject_token_type"],
/// "properties": {
/// "token_exchange_service_uri": {
/// "type": "string"
/// },
/// "resource": {
/// "type": "string"
/// },
/// "audience": {
/// "type": "string"
/// },
/// "scope": {
/// "type": "string"
/// },
/// "requested_token_type": {
/// "type": "string"
/// },
/// "subject_token_path": {
/// "type": "string"
/// },
/// "subject_token_type": {
/// "type": "string"
/// },
/// "actor_token_path" : {
/// "type": "string"
/// },
/// "actor_token_type": {
/// "type": "string"
/// }
/// }
/// }
grpc::Status StsCredentialsOptionsFromJson(const grpc::string& json_string,
StsCredentialsOptions* options);
/// Creates STS credentials options from the $STS_CREDENTIALS environment
/// variable. This environment variable points to the path of a JSON file
/// comforming to the schema described above.
grpc::Status StsCredentialsOptionsFromEnv(StsCredentialsOptions* options);
std::shared_ptr<CallCredentials> StsCredentials(
const StsCredentialsOptions& options);
/// Options used to build AltsCredentials.
struct AltsCredentialsOptions {
/// service accounts of target endpoint that will be acceptable

@ -27,16 +27,17 @@
#include <grpc/compression.h>
#include <grpc/support/atm.h>
#include <grpcpp/channel.h>
#include <grpcpp/completion_queue.h>
#include <grpcpp/channel_impl.h>
#include <grpcpp/completion_queue_impl.h>
#include <grpcpp/health_check_service_interface.h>
#include <grpcpp/impl/call.h>
#include <grpcpp/impl/codegen/client_interceptor.h>
#include <grpcpp/impl/codegen/completion_queue_impl.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/channel_arguments_impl.h>
#include <grpcpp/support/config.h>
#include <grpcpp/support/status.h>
@ -80,7 +81,7 @@ class Server : public grpc::ServerInterface, private grpc::GrpcLibraryCodegen {
public:
virtual ~GlobalCallbacks() {}
/// Called before server is created.
virtual void UpdateArguments(grpc::ChannelArguments* args) {}
virtual void UpdateArguments(ChannelArguments* args) {}
/// Called before application callback for each synchronous server request
virtual void PreSynchronousRequest(grpc_impl::ServerContext* context) = 0;
/// Called after application callback for each synchronous server request
@ -108,8 +109,7 @@ class Server : public grpc::ServerInterface, private grpc::GrpcLibraryCodegen {
}
/// Establish a channel for in-process communication
std::shared_ptr<::grpc::Channel> InProcessChannel(
const grpc::ChannelArguments& args);
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
@ -120,8 +120,8 @@ class Server : public grpc::ServerInterface, private grpc::GrpcLibraryCodegen {
/// Establish a channel for in-process communication with client
/// interceptors
std::shared_ptr<::grpc::Channel> InProcessChannelWithInterceptors(
const grpc::ChannelArguments& args,
std::shared_ptr<Channel> InProcessChannelWithInterceptors(
const ChannelArguments& args,
std::vector<std::unique_ptr<
grpc::experimental::ClientInterceptorFactoryInterface>>
interceptor_creators);
@ -182,19 +182,18 @@ class Server : public grpc::ServerInterface, private grpc::GrpcLibraryCodegen {
///
/// \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, grpc::ChannelArguments* args,
std::shared_ptr<std::vector<std::unique_ptr<grpc::ServerCompletionQueue>>>
sync_server_cqs,
int min_pollers, int max_pollers, int sync_cq_timeout_msec,
std::vector<
std::shared_ptr<grpc::internal::ExternalConnectionAcceptorImpl>>
acceptors,
grpc_resource_quota* server_rq = nullptr,
std::vector<std::unique_ptr<
grpc::experimental::ServerInterceptorFactoryInterface>>
interceptor_creators = std::vector<std::unique_ptr<
grpc::experimental::ServerInterceptorFactoryInterface>>());
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,
std::vector<
std::shared_ptr<grpc::internal::ExternalConnectionAcceptorImpl>>
acceptors,
grpc_resource_quota* server_rq = nullptr,
std::vector<std::unique_ptr<
grpc::experimental::ServerInterceptorFactoryInterface>>
interceptor_creators = std::vector<std::unique_ptr<
grpc::experimental::ServerInterceptorFactoryInterface>>());
/// Start the server.
///
@ -202,7 +201,7 @@ class Server : public grpc::ServerInterface, private grpc::GrpcLibraryCodegen {
/// 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(grpc::ServerCompletionQueue** cqs, size_t num_cqs) override;
void Start(ServerCompletionQueue** cqs, size_t num_cqs) override;
grpc_server* server() override { return server_; }
@ -283,7 +282,7 @@ class Server : public grpc::ServerInterface, private grpc::GrpcLibraryCodegen {
return max_receive_message_size_;
}
grpc::CompletionQueue* CallbackCQ() override;
CompletionQueue* CallbackCQ() override;
grpc_impl::ServerInitializer* initializer();
@ -304,7 +303,7 @@ class Server : public grpc::ServerInterface, private grpc::GrpcLibraryCodegen {
/// 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<grpc::ServerCompletionQueue>>>
std::shared_ptr<std::vector<std::unique_ptr<ServerCompletionQueue>>>
sync_server_cqs_;
/// List of \a ThreadManager instances (one for each cq in
@ -374,7 +373,7 @@ class Server : public grpc::ServerInterface, private grpc::GrpcLibraryCodegen {
// 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_
grpc::CompletionQueue* callback_cq_ = nullptr;
CompletionQueue* callback_cq_ = nullptr;
};
} // namespace grpc_impl

@ -0,0 +1,24 @@
/*
*
* Copyright 2019 gRPC authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
#ifndef GRPCPP_SUPPORT_ASYNC_STREAM_IMPL_H
#define GRPCPP_SUPPORT_ASYNC_STREAM_IMPL_H
#include <grpcpp/impl/codegen/async_stream_impl.h>
#endif // GRPCPP_SUPPORT_ASYNC_STREAM_IMPL_H

@ -0,0 +1,24 @@
/*
*
* Copyright 2019 gRPC authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
#ifndef GRPCPP_SUPPORT_ASYNC_UNARY_CALL_IMPL_H
#define GRPCPP_SUPPORT_ASYNC_UNARY_CALL_IMPL_H
#include <grpcpp/impl/codegen/async_unary_call_impl.h>
#endif // GRPCPP_SUPPORT_ASYNC_UNARY_CALL_IMPL_H

@ -0,0 +1,24 @@
/*
*
* Copyright 2019 gRPC authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
#ifndef GRPCPP_SUPPORT_CLIENT_CALLBACK_IMPL_H
#define GRPCPP_SUPPORT_CLIENT_CALLBACK_IMPL_H
#include <grpcpp/impl/codegen/client_callback_impl.h>
#endif // GRPCPP_SUPPORT_CLIENT_CALLBACK_IMPL_H

@ -0,0 +1,24 @@
/*
*
* Copyright 2019 gRPC authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
#ifndef GRPCPP_SUPPORT_SERVER_CALLBACK_IMPL_H
#define GRPCPP_SUPPORT_SERVER_CALLBACK_IMPL_H
#include <grpcpp/impl/codegen/server_callback_impl.h>
#endif // GRPCPP_SUPPORT_SERVER_CALLBACK_IMPL_H

@ -0,0 +1,24 @@
/*
*
* Copyright 2019 gRPC authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
#ifndef GRPCPP_SUPPORT_SYNC_STREAM_IMPL_H
#define GRPCPP_SUPPORT_SYNC_STREAM_IMPL_H
#include <grpcpp/impl/codegen/sync_stream_impl.h>
#endif // GRPCPP_SUPPORT_SYNC_STREAM_IMPL_H

@ -90,7 +90,6 @@
<file baseinstalldir="/" name="src/core/lib/gpr/alloc.h" role="src" />
<file baseinstalldir="/" name="src/core/lib/gpr/arena.h" role="src" />
<file baseinstalldir="/" name="src/core/lib/gpr/env.h" role="src" />
<file baseinstalldir="/" name="src/core/lib/gpr/host_port.h" role="src" />
<file baseinstalldir="/" name="src/core/lib/gpr/mpscq.h" role="src" />
<file baseinstalldir="/" name="src/core/lib/gpr/murmur_hash.h" role="src" />
<file baseinstalldir="/" name="src/core/lib/gpr/spinlock.h" role="src" />
@ -111,6 +110,7 @@
<file baseinstalldir="/" name="src/core/lib/gprpp/global_config_custom.h" role="src" />
<file baseinstalldir="/" name="src/core/lib/gprpp/global_config_env.h" role="src" />
<file baseinstalldir="/" name="src/core/lib/gprpp/global_config_generic.h" role="src" />
<file baseinstalldir="/" name="src/core/lib/gprpp/host_port.h" role="src" />
<file baseinstalldir="/" name="src/core/lib/gprpp/manual_constructor.h" role="src" />
<file baseinstalldir="/" name="src/core/lib/gprpp/map.h" role="src" />
<file baseinstalldir="/" name="src/core/lib/gprpp/memory.h" role="src" />
@ -127,7 +127,6 @@
<file baseinstalldir="/" name="src/core/lib/gpr/env_linux.cc" role="src" />
<file baseinstalldir="/" name="src/core/lib/gpr/env_posix.cc" role="src" />
<file baseinstalldir="/" name="src/core/lib/gpr/env_windows.cc" role="src" />
<file baseinstalldir="/" name="src/core/lib/gpr/host_port.cc" role="src" />
<file baseinstalldir="/" name="src/core/lib/gpr/log.cc" role="src" />
<file baseinstalldir="/" name="src/core/lib/gpr/log_android.cc" role="src" />
<file baseinstalldir="/" name="src/core/lib/gpr/log_linux.cc" role="src" />
@ -154,6 +153,7 @@
<file baseinstalldir="/" name="src/core/lib/gprpp/arena.cc" role="src" />
<file baseinstalldir="/" name="src/core/lib/gprpp/fork.cc" role="src" />
<file baseinstalldir="/" name="src/core/lib/gprpp/global_config_env.cc" role="src" />
<file baseinstalldir="/" name="src/core/lib/gprpp/host_port.cc" role="src" />
<file baseinstalldir="/" name="src/core/lib/gprpp/thd_posix.cc" role="src" />
<file baseinstalldir="/" name="src/core/lib/gprpp/thd_windows.cc" role="src" />
<file baseinstalldir="/" name="src/core/lib/profiling/basic_timers.cc" role="src" />
@ -353,6 +353,7 @@
<file baseinstalldir="/" name="src/core/lib/gprpp/orphanable.h" role="src" />
<file baseinstalldir="/" name="src/core/lib/gprpp/ref_counted.h" role="src" />
<file baseinstalldir="/" name="src/core/lib/gprpp/ref_counted_ptr.h" role="src" />
<file baseinstalldir="/" name="src/core/lib/gprpp/string_view.h" role="src" />
<file baseinstalldir="/" name="src/core/lib/http/format_request.h" role="src" />
<file baseinstalldir="/" name="src/core/lib/http/httpcli.h" role="src" />
<file baseinstalldir="/" name="src/core/lib/http/parser.h" role="src" />
@ -375,6 +376,7 @@
<file baseinstalldir="/" name="src/core/lib/iomgr/ev_posix.h" role="src" />
<file baseinstalldir="/" name="src/core/lib/iomgr/exec_ctx.h" role="src" />
<file baseinstalldir="/" name="src/core/lib/iomgr/executor.h" role="src" />
<file baseinstalldir="/" name="src/core/lib/iomgr/executor/mpmcqueue.h" role="src" />
<file baseinstalldir="/" name="src/core/lib/iomgr/gethostname.h" role="src" />
<file baseinstalldir="/" name="src/core/lib/iomgr/grpc_if_nametoindex.h" role="src" />
<file baseinstalldir="/" name="src/core/lib/iomgr/internal_errqueue.h" role="src" />
@ -528,6 +530,7 @@
<file baseinstalldir="/" name="src/core/lib/iomgr/ev_windows.cc" role="src" />
<file baseinstalldir="/" name="src/core/lib/iomgr/exec_ctx.cc" role="src" />
<file baseinstalldir="/" name="src/core/lib/iomgr/executor.cc" role="src" />
<file baseinstalldir="/" name="src/core/lib/iomgr/executor/mpmcqueue.cc" role="src" />
<file baseinstalldir="/" name="src/core/lib/iomgr/fork_posix.cc" role="src" />
<file baseinstalldir="/" name="src/core/lib/iomgr/fork_windows.cc" role="src" />
<file baseinstalldir="/" name="src/core/lib/iomgr/gethostname_fallback.cc" role="src" />

@ -0,0 +1,120 @@
# gRPC Bazel BUILD file.
#
# Copyright 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.
licenses(["notice"]) # Apache v2
exports_files(["LICENSE"])
package(
default_visibility = ["//visibility:public"],
features = [
"-layering_check",
"-parse_headers",
],
)
load(
"//bazel:grpc_build_system.bzl",
"grpc_cc_library",
"grpc_proto_plugin",
)
grpc_cc_library(
name = "grpc_plugin_support",
srcs = [
"cpp_generator.cc",
"csharp_generator.cc",
"node_generator.cc",
"objective_c_generator.cc",
"php_generator.cc",
"python_generator.cc",
"ruby_generator.cc",
],
hdrs = [
"config_protobuf.h",
"config.h",
"cpp_generator.h",
"cpp_generator_helpers.h",
"cpp_plugin.h",
"csharp_generator.h",
"csharp_generator_helpers.h",
"generator_helpers.h",
"node_generator.h",
"node_generator_helpers.h",
"objective_c_generator.h",
"objective_c_generator_helpers.h",
"php_generator.h",
"php_generator_helpers.h",
"protobuf_plugin.h",
"python_generator.h",
"python_generator_helpers.h",
"python_private_generator.h",
"ruby_generator.h",
"ruby_generator_helpers-inl.h",
"ruby_generator_map-inl.h",
"ruby_generator_string-inl.h",
"schema_interface.h",
],
external_deps = [
"protobuf_clib",
],
language = "c++",
deps = [
"//:grpc++_config_proto",
],
)
grpc_proto_plugin(
name = "grpc_cpp_plugin",
srcs = ["cpp_plugin.cc"],
deps = [":grpc_plugin_support"],
)
grpc_proto_plugin(
name = "grpc_csharp_plugin",
srcs = ["csharp_plugin.cc"],
deps = [":grpc_plugin_support"],
)
grpc_proto_plugin(
name = "grpc_node_plugin",
srcs = ["node_plugin.cc"],
deps = [":grpc_plugin_support"],
)
grpc_proto_plugin(
name = "grpc_objective_c_plugin",
srcs = ["objective_c_plugin.cc"],
deps = [":grpc_plugin_support"],
)
grpc_proto_plugin(
name = "grpc_php_plugin",
srcs = ["php_plugin.cc"],
deps = [":grpc_plugin_support"],
)
grpc_proto_plugin(
name = "grpc_python_plugin",
srcs = ["python_plugin.cc"],
deps = [":grpc_plugin_support"],
)
grpc_proto_plugin(
name = "grpc_ruby_plugin",
srcs = ["ruby_plugin.cc"],
deps = [":grpc_plugin_support"],
)

@ -19,35 +19,7 @@
#ifndef SRC_COMPILER_CONFIG_H
#define SRC_COMPILER_CONFIG_H
#include <grpcpp/impl/codegen/config_protobuf.h>
#ifndef GRPC_CUSTOM_CODEGENERATOR
#include <google/protobuf/compiler/code_generator.h>
#define GRPC_CUSTOM_CODEGENERATOR ::google::protobuf::compiler::CodeGenerator
#define GRPC_CUSTOM_GENERATORCONTEXT \
::google::protobuf::compiler::GeneratorContext
#endif
#ifndef GRPC_CUSTOM_PRINTER
#include <google/protobuf/io/coded_stream.h>
#include <google/protobuf/io/printer.h>
#include <google/protobuf/io/zero_copy_stream_impl_lite.h>
#define GRPC_CUSTOM_PRINTER ::google::protobuf::io::Printer
#define GRPC_CUSTOM_CODEDOUTPUTSTREAM ::google::protobuf::io::CodedOutputStream
#define GRPC_CUSTOM_STRINGOUTPUTSTREAM \
::google::protobuf::io::StringOutputStream
#endif
#ifndef GRPC_CUSTOM_PLUGINMAIN
#include <google/protobuf/compiler/plugin.h>
#define GRPC_CUSTOM_PLUGINMAIN ::google::protobuf::compiler::PluginMain
#endif
#ifndef GRPC_CUSTOM_PARSEGENERATORPARAMETER
#include <google/protobuf/compiler/code_generator.h>
#define GRPC_CUSTOM_PARSEGENERATORPARAMETER \
::google::protobuf::compiler::ParseGeneratorParameter
#endif
#include "src/compiler/config_protobuf.h"
#ifndef GRPC_CUSTOM_STRING
#include <string>

@ -0,0 +1,52 @@
/*
*
* Copyright 2019 gRPC authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
#ifndef SRC_COMPILER_CONFIG_PROTOBUF_H
#define SRC_COMPILER_CONFIG_PROTOBUF_H
#include <grpcpp/impl/codegen/config_protobuf.h>
#ifndef GRPC_CUSTOM_CODEGENERATOR
#include <google/protobuf/compiler/code_generator.h>
#define GRPC_CUSTOM_CODEGENERATOR ::google::protobuf::compiler::CodeGenerator
#define GRPC_CUSTOM_GENERATORCONTEXT \
::google::protobuf::compiler::GeneratorContext
#endif
#ifndef GRPC_CUSTOM_PRINTER
#include <google/protobuf/io/coded_stream.h>
#include <google/protobuf/io/printer.h>
#include <google/protobuf/io/zero_copy_stream_impl_lite.h>
#define GRPC_CUSTOM_PRINTER ::google::protobuf::io::Printer
#define GRPC_CUSTOM_CODEDOUTPUTSTREAM ::google::protobuf::io::CodedOutputStream
#define GRPC_CUSTOM_STRINGOUTPUTSTREAM \
::google::protobuf::io::StringOutputStream
#endif
#ifndef GRPC_CUSTOM_PLUGINMAIN
#include <google/protobuf/compiler/plugin.h>
#define GRPC_CUSTOM_PLUGINMAIN ::google::protobuf::compiler::PluginMain
#endif
#ifndef GRPC_CUSTOM_PARSEGENERATORPARAMETER
#include <google/protobuf/compiler/code_generator.h>
#define GRPC_CUSTOM_PARSEGENERATORPARAMETER \
::google::protobuf::compiler::ParseGeneratorParameter
#endif
#endif // SRC_COMPILER_CONFIG_PROTOBUF_H

@ -142,14 +142,18 @@ grpc::string GetHeaderIncludes(grpc_generator::File* file,
"grpcpp/impl/codegen/async_stream.h",
"grpcpp/impl/codegen/async_unary_call.h",
"grpcpp/impl/codegen/client_callback.h",
"grpcpp/impl/codegen/client_context.h",
"grpcpp/impl/codegen/completion_queue.h",
"grpcpp/impl/codegen/method_handler_impl.h",
"grpcpp/impl/codegen/proto_utils.h",
"grpcpp/impl/codegen/rpc_method.h",
"grpcpp/impl/codegen/server_callback.h",
"grpcpp/impl/codegen/server_context.h",
"grpcpp/impl/codegen/service_type.h",
"grpcpp/impl/codegen/status.h",
"grpcpp/impl/codegen/stub_options.h",
"grpcpp/impl/codegen/sync_stream.h"};
"grpcpp/impl/codegen/sync_stream.h",
};
std::vector<grpc::string> headers(headers_strs, array_end(headers_strs));
PrintIncludes(printer.get(), headers, params.use_system_headers,
params.grpc_search_path);
@ -943,11 +947,12 @@ void PrintHeaderServerCallbackMethodsHelper(
" abort();\n"
" return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, \"\");\n"
"}\n");
printer->Print(*vars,
"virtual ::grpc::experimental::ServerReadReactor< "
"$RealRequest$, $RealResponse$>* $Method$() {\n"
" return new ::grpc::internal::UnimplementedReadReactor<\n"
" $RealRequest$, $RealResponse$>;}\n");
printer->Print(
*vars,
"virtual ::grpc::experimental::ServerReadReactor< "
"$RealRequest$, $RealResponse$>* $Method$() {\n"
" return new ::grpc_impl::internal::UnimplementedReadReactor<\n"
" $RealRequest$, $RealResponse$>;}\n");
} else if (ServerOnlyStreaming(method)) {
printer->Print(
*vars,
@ -959,11 +964,12 @@ void PrintHeaderServerCallbackMethodsHelper(
" abort();\n"
" return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, \"\");\n"
"}\n");
printer->Print(*vars,
"virtual ::grpc::experimental::ServerWriteReactor< "
"$RealRequest$, $RealResponse$>* $Method$() {\n"
" return new ::grpc::internal::UnimplementedWriteReactor<\n"
" $RealRequest$, $RealResponse$>;}\n");
printer->Print(
*vars,
"virtual ::grpc::experimental::ServerWriteReactor< "
"$RealRequest$, $RealResponse$>* $Method$() {\n"
" return new ::grpc_impl::internal::UnimplementedWriteReactor<\n"
" $RealRequest$, $RealResponse$>;}\n");
} else if (method->BidiStreaming()) {
printer->Print(
*vars,
@ -975,11 +981,12 @@ void PrintHeaderServerCallbackMethodsHelper(
" abort();\n"
" return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, \"\");\n"
"}\n");
printer->Print(*vars,
"virtual ::grpc::experimental::ServerBidiReactor< "
"$RealRequest$, $RealResponse$>* $Method$() {\n"
" return new ::grpc::internal::UnimplementedBidiReactor<\n"
" $RealRequest$, $RealResponse$>;}\n");
printer->Print(
*vars,
"virtual ::grpc::experimental::ServerBidiReactor< "
"$RealRequest$, $RealResponse$>* $Method$() {\n"
" return new ::grpc_impl::internal::UnimplementedBidiReactor<\n"
" $RealRequest$, $RealResponse$>;}\n");
}
}
@ -1007,7 +1014,7 @@ void PrintHeaderServerMethodCallback(
printer->Print(
*vars,
" ::grpc::Service::experimental().MarkMethodCallback($Idx$,\n"
" new ::grpc::internal::CallbackUnaryHandler< "
" new ::grpc_impl::internal::CallbackUnaryHandler< "
"$RealRequest$, $RealResponse$>(\n"
" [this](::grpc::ServerContext* context,\n"
" const $RealRequest$* request,\n"
@ -1021,7 +1028,7 @@ void PrintHeaderServerMethodCallback(
"void SetMessageAllocatorFor_$Method$(\n"
" ::grpc::experimental::MessageAllocator< "
"$RealRequest$, $RealResponse$>* allocator) {\n"
" static_cast<::grpc::internal::CallbackUnaryHandler< "
" static_cast<::grpc_impl::internal::CallbackUnaryHandler< "
"$RealRequest$, $RealResponse$>*>(\n"
" ::grpc::Service::experimental().GetHandler($Idx$))\n"
" ->SetMessageAllocator(allocator);\n");
@ -1029,21 +1036,21 @@ void PrintHeaderServerMethodCallback(
printer->Print(
*vars,
" ::grpc::Service::experimental().MarkMethodCallback($Idx$,\n"
" new ::grpc::internal::CallbackClientStreamingHandler< "
" new ::grpc_impl::internal::CallbackClientStreamingHandler< "
"$RealRequest$, $RealResponse$>(\n"
" [this] { return this->$Method$(); }));\n");
} else if (ServerOnlyStreaming(method)) {
printer->Print(
*vars,
" ::grpc::Service::experimental().MarkMethodCallback($Idx$,\n"
" new ::grpc::internal::CallbackServerStreamingHandler< "
" new ::grpc_impl::internal::CallbackServerStreamingHandler< "
"$RealRequest$, $RealResponse$>(\n"
" [this] { return this->$Method$(); }));\n");
} else if (method->BidiStreaming()) {
printer->Print(
*vars,
" ::grpc::Service::experimental().MarkMethodCallback($Idx$,\n"
" new ::grpc::internal::CallbackBidiHandler< "
" new ::grpc_impl::internal::CallbackBidiHandler< "
"$RealRequest$, $RealResponse$>(\n"
" [this] { return this->$Method$(); }));\n");
}
@ -1081,7 +1088,7 @@ void PrintHeaderServerMethodRawCallback(
printer->Print(
*vars,
" ::grpc::Service::experimental().MarkMethodRawCallback($Idx$,\n"
" new ::grpc::internal::CallbackUnaryHandler< "
" new ::grpc_impl::internal::CallbackUnaryHandler< "
"$RealRequest$, $RealResponse$>(\n"
" [this](::grpc::ServerContext* context,\n"
" const $RealRequest$* request,\n"
@ -1095,21 +1102,21 @@ void PrintHeaderServerMethodRawCallback(
printer->Print(
*vars,
" ::grpc::Service::experimental().MarkMethodRawCallback($Idx$,\n"
" new ::grpc::internal::CallbackClientStreamingHandler< "
" new ::grpc_impl::internal::CallbackClientStreamingHandler< "
"$RealRequest$, $RealResponse$>(\n"
" [this] { return this->$Method$(); }));\n");
} else if (ServerOnlyStreaming(method)) {
printer->Print(
*vars,
" ::grpc::Service::experimental().MarkMethodRawCallback($Idx$,\n"
" new ::grpc::internal::CallbackServerStreamingHandler< "
" new ::grpc_impl::internal::CallbackServerStreamingHandler< "
"$RealRequest$, $RealResponse$>(\n"
" [this] { return this->$Method$(); }));\n");
} else if (method->BidiStreaming()) {
printer->Print(
*vars,
" ::grpc::Service::experimental().MarkMethodRawCallback($Idx$,\n"
" new ::grpc::internal::CallbackBidiHandler< "
" new ::grpc_impl::internal::CallbackBidiHandler< "
"$RealRequest$, $RealResponse$>(\n"
" [this] { return this->$Method$(); }));\n");
}
@ -1702,7 +1709,7 @@ void PrintSourceClientMethod(grpc_generator::Printer* printer,
"const $Request$* request, $Response$* response, "
"std::function<void(::grpc::Status)> f) {\n");
printer->Print(*vars,
" ::grpc::internal::CallbackUnaryCall"
" ::grpc_impl::internal::CallbackUnaryCall"
"(stub_->channel_.get(), stub_->rpcmethod_$Method$_, "
"context, request, response, std::move(f));\n}\n\n");
@ -1712,7 +1719,7 @@ void PrintSourceClientMethod(grpc_generator::Printer* printer,
"const ::grpc::ByteBuffer* request, $Response$* response, "
"std::function<void(::grpc::Status)> f) {\n");
printer->Print(*vars,
" ::grpc::internal::CallbackUnaryCall"
" ::grpc_impl::internal::CallbackUnaryCall"
"(stub_->channel_.get(), stub_->rpcmethod_$Method$_, "
"context, request, response, std::move(f));\n}\n\n");
@ -1722,7 +1729,7 @@ void PrintSourceClientMethod(grpc_generator::Printer* printer,
"const $Request$* request, $Response$* response, "
"::grpc::experimental::ClientUnaryReactor* reactor) {\n");
printer->Print(*vars,
" ::grpc::internal::ClientCallbackUnaryFactory::Create"
" ::grpc_impl::internal::ClientCallbackUnaryFactory::Create"
"(stub_->channel_.get(), stub_->rpcmethod_$Method$_, "
"context, request, response, reactor);\n}\n\n");
@ -1732,7 +1739,7 @@ void PrintSourceClientMethod(grpc_generator::Printer* printer,
"const ::grpc::ByteBuffer* request, $Response$* response, "
"::grpc::experimental::ClientUnaryReactor* reactor) {\n");
printer->Print(*vars,
" ::grpc::internal::ClientCallbackUnaryFactory::Create"
" ::grpc_impl::internal::ClientCallbackUnaryFactory::Create"
"(stub_->channel_.get(), stub_->rpcmethod_$Method$_, "
"context, request, response, reactor);\n}\n\n");
@ -1748,7 +1755,7 @@ void PrintSourceClientMethod(grpc_generator::Printer* printer,
printer->Print(
*vars,
" return "
"::grpc::internal::ClientAsyncResponseReaderFactory< $Response$>"
"::grpc_impl::internal::ClientAsyncResponseReaderFactory< $Response$>"
"::Create(channel_.get(), cq, "
"rpcmethod_$Method$_, "
"context, request, $AsyncStart$);\n"
@ -1759,13 +1766,13 @@ void PrintSourceClientMethod(grpc_generator::Printer* printer,
"::grpc::ClientWriter< $Request$>* "
"$ns$$Service$::Stub::$Method$Raw("
"::grpc::ClientContext* context, $Response$* response) {\n");
printer->Print(
*vars,
" return ::grpc::internal::ClientWriterFactory< $Request$>::Create("
"channel_.get(), "
"rpcmethod_$Method$_, "
"context, response);\n"
"}\n\n");
printer->Print(*vars,
" return ::grpc_impl::internal::ClientWriterFactory< "
"$Request$>::Create("
"channel_.get(), "
"rpcmethod_$Method$_, "
"context, response);\n"
"}\n\n");
printer->Print(
*vars,
@ -1774,7 +1781,7 @@ void PrintSourceClientMethod(grpc_generator::Printer* printer,
"$Response$* response, "
"::grpc::experimental::ClientWriteReactor< $Request$>* reactor) {\n");
printer->Print(*vars,
" ::grpc::internal::ClientCallbackWriterFactory< "
" ::grpc_impl::internal::ClientCallbackWriterFactory< "
"$Request$>::Create("
"stub_->channel_.get(), "
"stub_->rpcmethod_$Method$_, "
@ -1793,7 +1800,7 @@ void PrintSourceClientMethod(grpc_generator::Printer* printer,
"::grpc::CompletionQueue* cq$AsyncMethodParams$) {\n");
printer->Print(
*vars,
" return ::grpc::internal::ClientAsyncWriterFactory< $Request$>"
" return ::grpc_impl::internal::ClientAsyncWriterFactory< $Request$>"
"::Create(channel_.get(), cq, "
"rpcmethod_$Method$_, "
"context, response, $AsyncStart$$AsyncCreateArgs$);\n"
@ -1805,13 +1812,13 @@ void PrintSourceClientMethod(grpc_generator::Printer* printer,
"::grpc::ClientReader< $Response$>* "
"$ns$$Service$::Stub::$Method$Raw("
"::grpc::ClientContext* context, const $Request$& request) {\n");
printer->Print(
*vars,
" return ::grpc::internal::ClientReaderFactory< $Response$>::Create("
"channel_.get(), "
"rpcmethod_$Method$_, "
"context, request);\n"
"}\n\n");
printer->Print(*vars,
" return ::grpc_impl::internal::ClientReaderFactory< "
"$Response$>::Create("
"channel_.get(), "
"rpcmethod_$Method$_, "
"context, request);\n"
"}\n\n");
printer->Print(
*vars,
@ -1820,7 +1827,7 @@ void PrintSourceClientMethod(grpc_generator::Printer* printer,
"$Request$* request, "
"::grpc::experimental::ClientReadReactor< $Response$>* reactor) {\n");
printer->Print(*vars,
" ::grpc::internal::ClientCallbackReaderFactory< "
" ::grpc_impl::internal::ClientCallbackReaderFactory< "
"$Response$>::Create("
"stub_->channel_.get(), "
"stub_->rpcmethod_$Method$_, "
@ -1840,7 +1847,8 @@ void PrintSourceClientMethod(grpc_generator::Printer* printer,
"::grpc::CompletionQueue* cq$AsyncMethodParams$) {\n");
printer->Print(
*vars,
" return ::grpc::internal::ClientAsyncReaderFactory< $Response$>"
" return ::grpc_impl::internal::ClientAsyncReaderFactory< "
"$Response$>"
"::Create(channel_.get(), cq, "
"rpcmethod_$Method$_, "
"context, request, $AsyncStart$$AsyncCreateArgs$);\n"
@ -1852,7 +1860,7 @@ void PrintSourceClientMethod(grpc_generator::Printer* printer,
"::grpc::ClientReaderWriter< $Request$, $Response$>* "
"$ns$$Service$::Stub::$Method$Raw(::grpc::ClientContext* context) {\n");
printer->Print(*vars,
" return ::grpc::internal::ClientReaderWriterFactory< "
" return ::grpc_impl::internal::ClientReaderWriterFactory< "
"$Request$, $Response$>::Create("
"channel_.get(), "
"rpcmethod_$Method$_, "
@ -1865,13 +1873,14 @@ void PrintSourceClientMethod(grpc_generator::Printer* printer,
"ClientContext* context, "
"::grpc::experimental::ClientBidiReactor< $Request$,$Response$>* "
"reactor) {\n");
printer->Print(*vars,
" ::grpc::internal::ClientCallbackReaderWriterFactory< "
"$Request$,$Response$>::Create("
"stub_->channel_.get(), "
"stub_->rpcmethod_$Method$_, "
"context, reactor);\n"
"}\n\n");
printer->Print(
*vars,
" ::grpc_impl::internal::ClientCallbackReaderWriterFactory< "
"$Request$,$Response$>::Create("
"stub_->channel_.get(), "
"stub_->rpcmethod_$Method$_, "
"context, reactor);\n"
"}\n\n");
for (auto async_prefix : async_prefixes) {
(*vars)["AsyncPrefix"] = async_prefix.prefix;
@ -1885,7 +1894,7 @@ void PrintSourceClientMethod(grpc_generator::Printer* printer,
"::grpc::CompletionQueue* cq$AsyncMethodParams$) {\n");
printer->Print(*vars,
" return "
"::grpc::internal::ClientAsyncReaderWriterFactory< "
"::grpc_impl::internal::ClientAsyncReaderWriterFactory< "
"$Request$, $Response$>::Create("
"channel_.get(), cq, "
"rpcmethod_$Method$_, "
@ -2276,7 +2285,8 @@ void PrintMockClientMethods(grpc_generator::Printer* printer,
printer->Print(
*vars,
"MOCK_METHOD$MockArgs$($AsyncPrefix$$Method$Raw, "
"::grpc::ClientAsyncReaderWriterInterface<$Request$, $Response$>*"
"::grpc::ClientAsyncReaderWriterInterface<$Request$, "
"$Response$>*"
"(::grpc::ClientContext* context, ::grpc::CompletionQueue* cq"
"$AsyncMethodParams$));\n");
}

@ -24,10 +24,12 @@
#include <grpc/support/alloc.h>
#include <grpc/support/log.h>
#include <grpc/support/sync.h>
#include "src/core/ext/filters/client_channel/client_channel.h"
#include "src/core/lib/gpr/string.h"
#include "src/core/lib/gprpp/global_config.h"
#include "src/core/lib/iomgr/error.h"
#include "src/core/lib/iomgr/iomgr.h"
#include "src/core/lib/iomgr/pollset.h"
#include "src/core/lib/iomgr/timer.h"
#include "src/core/lib/surface/channel.h"
@ -153,7 +155,7 @@ static void g_poller_init_locked() {
void grpc_client_channel_start_backup_polling(
grpc_pollset_set* interested_parties) {
if (g_poll_interval_ms == 0) {
if (g_poll_interval_ms == 0 || grpc_iomgr_run_in_background()) {
return;
}
gpr_mu_lock(&g_poller_mu);
@ -171,7 +173,7 @@ void grpc_client_channel_start_backup_polling(
void grpc_client_channel_stop_backup_polling(
grpc_pollset_set* interested_parties) {
if (g_poll_interval_ms == 0) {
if (g_poll_interval_ms == 0 || grpc_iomgr_run_in_background()) {
return;
}
grpc_pollset_set_del_pollset(interested_parties, g_poller->pollset);

@ -210,6 +210,10 @@ class ChannelData {
ChannelData(grpc_channel_element_args* args, grpc_error** error);
~ChannelData();
void CreateResolvingLoadBalancingPolicyLocked();
void DestroyResolvingLoadBalancingPolicyLocked();
static bool ProcessResolverResultLocked(
void* arg, const Resolver::Result& result, const char** lb_policy_name,
RefCountedPtr<LoadBalancingPolicy::Config>* lb_policy_config,
@ -235,8 +239,10 @@ class ChannelData {
const size_t per_rpc_retry_buffer_size_;
grpc_channel_stack* owning_stack_;
ClientChannelFactory* client_channel_factory_;
UniquePtr<char> server_name_;
const grpc_channel_args* channel_args_;
RefCountedPtr<ServiceConfig> default_service_config_;
UniquePtr<char> server_name_;
UniquePtr<char> target_uri_;
channelz::ChannelNode* channelz_node_;
//
@ -1226,59 +1232,61 @@ ChannelData::ChannelData(grpc_channel_element_args* args, grpc_error** error)
grpc_channel_args* new_args = nullptr;
grpc_proxy_mappers_map_name(server_uri, args->channel_args, &proxy_name,
&new_args);
UniquePtr<char> target_uri(proxy_name != nullptr ? proxy_name
: gpr_strdup(server_uri));
target_uri_.reset(proxy_name != nullptr ? proxy_name
: gpr_strdup(server_uri));
channel_args_ = new_args != nullptr
? new_args
: grpc_channel_args_copy(args->channel_args);
if (!ResolverRegistry::IsValidTarget(target_uri_.get())) {
*error =
GRPC_ERROR_CREATE_FROM_STATIC_STRING("the target uri is not valid.");
return;
}
*error = GRPC_ERROR_NONE;
}
ChannelData::~ChannelData() {
if (GRPC_TRACE_FLAG_ENABLED(grpc_client_channel_routing_trace)) {
gpr_log(GPR_INFO, "chand=%p: destroying channel", this);
}
DestroyResolvingLoadBalancingPolicyLocked();
grpc_channel_args_destroy(channel_args_);
// Stop backup polling.
grpc_client_channel_stop_backup_polling(interested_parties_);
grpc_pollset_set_destroy(interested_parties_);
GRPC_COMBINER_UNREF(data_plane_combiner_, "client_channel");
GRPC_COMBINER_UNREF(combiner_, "client_channel");
GRPC_ERROR_UNREF(disconnect_error_.Load(MemoryOrder::RELAXED));
grpc_connectivity_state_destroy(&state_tracker_);
gpr_mu_destroy(&info_mu_);
}
void ChannelData::CreateResolvingLoadBalancingPolicyLocked() {
// Instantiate resolving LB policy.
LoadBalancingPolicy::Args lb_args;
lb_args.combiner = combiner_;
lb_args.channel_control_helper =
UniquePtr<LoadBalancingPolicy::ChannelControlHelper>(
New<ClientChannelControlHelper>(this));
lb_args.args = new_args != nullptr ? new_args : args->channel_args;
lb_args.args = channel_args_;
UniquePtr<char> target_uri(strdup(target_uri_.get()));
resolving_lb_policy_.reset(New<ResolvingLoadBalancingPolicy>(
std::move(lb_args), &grpc_client_channel_routing_trace,
std::move(target_uri), ProcessResolverResultLocked, this, error));
grpc_channel_args_destroy(new_args);
if (*error != GRPC_ERROR_NONE) {
// Orphan the resolving LB policy and flush the exec_ctx to ensure
// that it finishes shutting down. This ensures that if we are
// failing, we destroy the ClientChannelControlHelper (and thus
// unref the channel stack) before we return.
// TODO(roth): This is not a complete solution, because it only
// catches the case where channel stack initialization fails in this
// particular filter. If there is a failure in a different filter, we
// will leave a dangling ref here, which can cause a crash. Fortunately,
// in practice, there are no other filters that can cause failures in
// channel stack initialization, so this works for now.
resolving_lb_policy_.reset();
ExecCtx::Get()->Flush();
} else {
grpc_pollset_set_add_pollset_set(resolving_lb_policy_->interested_parties(),
interested_parties_);
if (GRPC_TRACE_FLAG_ENABLED(grpc_client_channel_routing_trace)) {
gpr_log(GPR_INFO, "chand=%p: created resolving_lb_policy=%p", this,
resolving_lb_policy_.get());
}
std::move(target_uri), ProcessResolverResultLocked, this));
grpc_pollset_set_add_pollset_set(resolving_lb_policy_->interested_parties(),
interested_parties_);
if (GRPC_TRACE_FLAG_ENABLED(grpc_client_channel_routing_trace)) {
gpr_log(GPR_INFO, "chand=%p: created resolving_lb_policy=%p", this,
resolving_lb_policy_.get());
}
}
ChannelData::~ChannelData() {
if (GRPC_TRACE_FLAG_ENABLED(grpc_client_channel_routing_trace)) {
gpr_log(GPR_INFO, "chand=%p: destroying channel", this);
}
void ChannelData::DestroyResolvingLoadBalancingPolicyLocked() {
if (resolving_lb_policy_ != nullptr) {
grpc_pollset_set_del_pollset_set(resolving_lb_policy_->interested_parties(),
interested_parties_);
resolving_lb_policy_.reset();
}
// Stop backup polling.
grpc_client_channel_stop_backup_polling(interested_parties_);
grpc_pollset_set_destroy(interested_parties_);
GRPC_COMBINER_UNREF(data_plane_combiner_, "client_channel");
GRPC_COMBINER_UNREF(combiner_, "client_channel");
GRPC_ERROR_UNREF(disconnect_error_.Load(MemoryOrder::RELAXED));
grpc_connectivity_state_destroy(&state_tracker_);
gpr_mu_destroy(&info_mu_);
}
void ChannelData::ProcessLbPolicy(
@ -1500,10 +1508,7 @@ void ChannelData::StartTransportOpLocked(void* arg, grpc_error* ignored) {
GPR_ASSERT(chand->disconnect_error_.CompareExchangeStrong(
&error, op->disconnect_with_error, MemoryOrder::ACQ_REL,
MemoryOrder::ACQUIRE));
grpc_pollset_set_del_pollset_set(
chand->resolving_lb_policy_->interested_parties(),
chand->interested_parties_);
chand->resolving_lb_policy_.reset();
chand->DestroyResolvingLoadBalancingPolicyLocked();
// Will delete itself.
New<ConnectivityStateAndPickerSetter>(
chand, GRPC_CHANNEL_SHUTDOWN, "shutdown from API",
@ -1574,6 +1579,8 @@ void ChannelData::TryToConnectLocked(void* arg, grpc_error* error_ignored) {
auto* chand = static_cast<ChannelData*>(arg);
if (chand->resolving_lb_policy_ != nullptr) {
chand->resolving_lb_policy_->ExitIdleLocked();
} else {
chand->CreateResolvingLoadBalancingPolicyLocked();
}
GRPC_CHANNEL_STACK_UNREF(chand->owning_stack_, "TryToConnect");
}
@ -2157,9 +2164,8 @@ void CallData::DoRetry(grpc_call_element* elem,
GPR_ASSERT(method_params_ != nullptr);
const auto* retry_policy = method_params_->retry_policy();
GPR_ASSERT(retry_policy != nullptr);
// Reset subchannel call and connected subchannel.
// Reset subchannel call.
subchannel_call_.reset();
connected_subchannel_.reset();
// Compute backoff delay.
grpc_millis next_attempt_time;
if (server_pushback_ms >= 0) {
@ -3277,13 +3283,14 @@ void CallData::CreateSubchannelCall(grpc_call_element* elem) {
ChannelData* chand = static_cast<ChannelData*>(elem->channel_data);
const size_t parent_data_size =
enable_retries_ ? sizeof(SubchannelCallRetryState) : 0;
const ConnectedSubchannel::CallArgs call_args = {
pollent_, path_, call_start_time_, deadline_, arena_,
SubchannelCall::Args call_args = {
std::move(connected_subchannel_), pollent_, path_, call_start_time_,
deadline_, arena_,
// TODO(roth): When we implement hedging support, we will probably
// need to use a separate call context for each subchannel call.
call_context_, call_combiner_, parent_data_size};
grpc_error* error = GRPC_ERROR_NONE;
subchannel_call_ = connected_subchannel_->CreateCall(call_args, &error);
subchannel_call_ = SubchannelCall::Create(std::move(call_args), &error);
if (GRPC_TRACE_FLAG_ENABLED(grpc_client_channel_routing_trace)) {
gpr_log(GPR_INFO, "chand=%p calld=%p: create subchannel_call=%p: error=%s",
chand, this, subchannel_call_.get(), grpc_error_string(error));
@ -3463,6 +3470,15 @@ void CallData::StartPickLocked(void* arg, grpc_error* error) {
ChannelData* chand = static_cast<ChannelData*>(elem->channel_data);
GPR_ASSERT(calld->connected_subchannel_ == nullptr);
GPR_ASSERT(calld->subchannel_call_ == nullptr);
// picker's being null means the channel is currently in IDLE state. The
// incoming call will make the channel exit IDLE and queue itself.
if (chand->picker() == nullptr) {
// We are currently in the data plane.
// Bounce into the control plane to exit IDLE.
chand->CheckConnectivityState(true);
calld->AddCallToQueuedPicksLocked(elem);
return;
}
// Apply service config to call if needed.
calld->MaybeApplyServiceConfigToCallLocked(elem);
// If this is a retry, use the send_initial_metadata payload that

@ -30,24 +30,25 @@
namespace grpc_core {
namespace channelz {
SubchannelNode::SubchannelNode(Subchannel* subchannel,
SubchannelNode::SubchannelNode(const char* target_address,
size_t channel_tracer_max_nodes)
: BaseNode(EntityType::kSubchannel),
subchannel_(subchannel),
target_(UniquePtr<char>(gpr_strdup(subchannel_->GetTargetAddress()))),
target_(UniquePtr<char>(gpr_strdup(target_address))),
trace_(channel_tracer_max_nodes) {}
SubchannelNode::~SubchannelNode() {}
void SubchannelNode::UpdateConnectivityState(grpc_connectivity_state state) {
connectivity_state_.Store(state, MemoryOrder::RELAXED);
}
void SubchannelNode::SetChildSocketUuid(intptr_t uuid) {
child_socket_uuid_.Store(uuid, MemoryOrder::RELAXED);
}
void SubchannelNode::PopulateConnectivityState(grpc_json* json) {
grpc_connectivity_state state;
if (subchannel_ == nullptr) {
state = GRPC_CHANNEL_SHUTDOWN;
} else {
state = subchannel_->CheckConnectivityState(
nullptr /* health_check_service_name */,
nullptr /* connected_subchannel */);
}
grpc_connectivity_state state =
connectivity_state_.Load(MemoryOrder::RELAXED);
json = grpc_json_create_child(nullptr, json, "state", nullptr,
GRPC_JSON_OBJECT, false);
grpc_json_create_child(nullptr, json, "state",
@ -87,7 +88,7 @@ grpc_json* SubchannelNode::RenderJson() {
call_counter_.PopulateCallCounts(json);
json = top_level_json;
// populate the child socket.
intptr_t socket_uuid = subchannel_->GetChildSocketUuid();
intptr_t socket_uuid = child_socket_uuid_.Load(MemoryOrder::RELAXED);
if (socket_uuid != 0) {
grpc_json* array_parent = grpc_json_create_child(
nullptr, json, "socketRef", nullptr, GRPC_JSON_ARRAY, false);

@ -34,13 +34,17 @@ namespace channelz {
class SubchannelNode : public BaseNode {
public:
SubchannelNode(Subchannel* subchannel, size_t channel_tracer_max_nodes);
SubchannelNode(const char* target_address, size_t channel_tracer_max_nodes);
~SubchannelNode() override;
void MarkSubchannelDestroyed() {
GPR_ASSERT(subchannel_ != nullptr);
subchannel_ = nullptr;
}
// Sets the subchannel's connectivity state without health checking.
void UpdateConnectivityState(grpc_connectivity_state state);
// Used when the subchannel's child socket uuid changes. This should be set
// when the subchannel's transport is created and set to 0 when the subchannel
// unrefs the transport. A uuid of 0 indicates that the child socket is no
// longer associated with this subchannel.
void SetChildSocketUuid(intptr_t uuid);
grpc_json* RenderJson() override;
@ -61,7 +65,8 @@ class SubchannelNode : public BaseNode {
private:
void PopulateConnectivityState(grpc_json* json);
Subchannel* subchannel_;
Atomic<grpc_connectivity_state> connectivity_state_{GRPC_CHANNEL_IDLE};
Atomic<intptr_t> child_socket_uuid_{0};
UniquePtr<char> target_;
CallCountingHelper call_counter_;
ChannelTrace trace_;

@ -310,7 +310,8 @@ void HealthCheckClient::CallState::Orphan() {
}
void HealthCheckClient::CallState::StartCall() {
ConnectedSubchannel::CallArgs args = {
SubchannelCall::Args args = {
health_check_client_->connected_subchannel_,
&pollent_,
GRPC_MDSTR_SLASH_GRPC_DOT_HEALTH_DOT_V1_DOT_HEALTH_SLASH_WATCH,
gpr_now(GPR_CLOCK_MONOTONIC), // start_time
@ -321,8 +322,7 @@ void HealthCheckClient::CallState::StartCall() {
0, // parent_data_size
};
grpc_error* error = GRPC_ERROR_NONE;
call_ = health_check_client_->connected_subchannel_->CreateCall(args, &error)
.release();
call_ = SubchannelCall::Create(std::move(args), &error).release();
// Register after-destruction callback.
GRPC_CLOSURE_INIT(&after_call_stack_destruction_, AfterCallStackDestruction,
this, grpc_schedule_on_exec_ctx);

@ -31,8 +31,8 @@
#include "src/core/ext/filters/client_channel/proxy_mapper_registry.h"
#include "src/core/lib/channel/channel_args.h"
#include "src/core/lib/gpr/env.h"
#include "src/core/lib/gpr/host_port.h"
#include "src/core/lib/gpr/string.h"
#include "src/core/lib/gprpp/host_port.h"
#include "src/core/lib/slice/b64.h"
#include "src/core/lib/uri/uri_parser.h"
@ -126,17 +126,18 @@ static bool proxy_mapper_map_name(grpc_proxy_mapper* mapper,
if (no_proxy_str != nullptr) {
static const char* NO_PROXY_SEPARATOR = ",";
bool use_proxy = true;
char* server_host;
char* server_port;
if (!gpr_split_host_port(uri->path[0] == '/' ? uri->path + 1 : uri->path,
&server_host, &server_port)) {
grpc_core::UniquePtr<char> server_host;
grpc_core::UniquePtr<char> server_port;
if (!grpc_core::SplitHostPort(
uri->path[0] == '/' ? uri->path + 1 : uri->path, &server_host,
&server_port)) {
gpr_log(GPR_INFO,
"unable to split host and port, not checking no_proxy list for "
"host '%s'",
server_uri);
gpr_free(no_proxy_str);
} else {
size_t uri_len = strlen(server_host);
size_t uri_len = strlen(server_host.get());
char** no_proxy_hosts;
size_t num_no_proxy_hosts;
gpr_string_split(no_proxy_str, NO_PROXY_SEPARATOR, &no_proxy_hosts,
@ -145,8 +146,8 @@ static bool proxy_mapper_map_name(grpc_proxy_mapper* mapper,
char* no_proxy_entry = no_proxy_hosts[i];
size_t no_proxy_len = strlen(no_proxy_entry);
if (no_proxy_len <= uri_len &&
gpr_stricmp(no_proxy_entry, &server_host[uri_len - no_proxy_len]) ==
0) {
gpr_stricmp(no_proxy_entry,
&(server_host.get()[uri_len - no_proxy_len])) == 0) {
gpr_log(GPR_INFO, "not using proxy for host in no_proxy list '%s'",
server_uri);
use_proxy = false;
@ -157,8 +158,6 @@ static bool proxy_mapper_map_name(grpc_proxy_mapper* mapper,
gpr_free(no_proxy_hosts[i]);
}
gpr_free(no_proxy_hosts);
gpr_free(server_host);
gpr_free(server_port);
gpr_free(no_proxy_str);
if (!use_proxy) goto no_use_proxy;
}

@ -84,7 +84,6 @@
#include "src/core/lib/backoff/backoff.h"
#include "src/core/lib/channel/channel_args.h"
#include "src/core/lib/channel/channel_stack.h"
#include "src/core/lib/gpr/host_port.h"
#include "src/core/lib/gpr/string.h"
#include "src/core/lib/gprpp/manual_constructor.h"
#include "src/core/lib/gprpp/memory.h"

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

@ -84,7 +84,6 @@
#include "src/core/lib/backoff/backoff.h"
#include "src/core/lib/channel/channel_args.h"
#include "src/core/lib/channel/channel_stack.h"
#include "src/core/lib/gpr/host_port.h"
#include "src/core/lib/gpr/string.h"
#include "src/core/lib/gprpp/manual_constructor.h"
#include "src/core/lib/gprpp/map.h"

@ -33,8 +33,8 @@
#include <grpc/support/log.h>
#include <grpc/support/string_util.h>
#include "src/core/lib/gpr/host_port.h"
#include "src/core/lib/gpr/string.h"
#include "src/core/lib/gprpp/host_port.h"
#ifdef GRPC_POSIX_SOCKET
#include <errno.h>
@ -73,9 +73,9 @@ bool grpc_parse_ipv4_hostport(const char* hostport, grpc_resolved_address* addr,
bool log_errors) {
bool success = false;
// Split host and port.
char* host;
char* port;
if (!gpr_split_host_port(hostport, &host, &port)) {
grpc_core::UniquePtr<char> host;
grpc_core::UniquePtr<char> port;
if (!grpc_core::SplitHostPort(hostport, &host, &port)) {
if (log_errors) {
gpr_log(GPR_ERROR, "Failed gpr_split_host_port(%s, ...)", hostport);
}
@ -86,8 +86,10 @@ bool grpc_parse_ipv4_hostport(const char* hostport, grpc_resolved_address* addr,
addr->len = static_cast<socklen_t>(sizeof(grpc_sockaddr_in));
grpc_sockaddr_in* in = reinterpret_cast<grpc_sockaddr_in*>(addr->addr);
in->sin_family = GRPC_AF_INET;
if (grpc_inet_pton(GRPC_AF_INET, host, &in->sin_addr) == 0) {
if (log_errors) gpr_log(GPR_ERROR, "invalid ipv4 address: '%s'", host);
if (grpc_inet_pton(GRPC_AF_INET, host.get(), &in->sin_addr) == 0) {
if (log_errors) {
gpr_log(GPR_ERROR, "invalid ipv4 address: '%s'", host.get());
}
goto done;
}
// Parse port.
@ -96,15 +98,14 @@ bool grpc_parse_ipv4_hostport(const char* hostport, grpc_resolved_address* addr,
goto done;
}
int port_num;
if (sscanf(port, "%d", &port_num) != 1 || port_num < 0 || port_num > 65535) {
if (log_errors) gpr_log(GPR_ERROR, "invalid ipv4 port: '%s'", port);
if (sscanf(port.get(), "%d", &port_num) != 1 || port_num < 0 ||
port_num > 65535) {
if (log_errors) gpr_log(GPR_ERROR, "invalid ipv4 port: '%s'", port.get());
goto done;
}
in->sin_port = grpc_htons(static_cast<uint16_t>(port_num));
success = true;
done:
gpr_free(host);
gpr_free(port);
return success;
}
@ -124,9 +125,9 @@ bool grpc_parse_ipv6_hostport(const char* hostport, grpc_resolved_address* addr,
bool log_errors) {
bool success = false;
// Split host and port.
char* host;
char* port;
if (!gpr_split_host_port(hostport, &host, &port)) {
grpc_core::UniquePtr<char> host;
grpc_core::UniquePtr<char> port;
if (!grpc_core::SplitHostPort(hostport, &host, &port)) {
if (log_errors) {
gpr_log(GPR_ERROR, "Failed gpr_split_host_port(%s, ...)", hostport);
}
@ -138,11 +139,12 @@ bool grpc_parse_ipv6_hostport(const char* hostport, grpc_resolved_address* addr,
grpc_sockaddr_in6* in6 = reinterpret_cast<grpc_sockaddr_in6*>(addr->addr);
in6->sin6_family = GRPC_AF_INET6;
// Handle the RFC6874 syntax for IPv6 zone identifiers.
char* host_end = static_cast<char*>(gpr_memrchr(host, '%', strlen(host)));
char* host_end =
static_cast<char*>(gpr_memrchr(host.get(), '%', strlen(host.get())));
if (host_end != nullptr) {
GPR_ASSERT(host_end >= host);
GPR_ASSERT(host_end >= host.get());
char host_without_scope[GRPC_INET6_ADDRSTRLEN + 1];
size_t host_without_scope_len = static_cast<size_t>(host_end - host);
size_t host_without_scope_len = static_cast<size_t>(host_end - host.get());
uint32_t sin6_scope_id = 0;
if (host_without_scope_len > GRPC_INET6_ADDRSTRLEN) {
if (log_errors) {
@ -154,7 +156,7 @@ bool grpc_parse_ipv6_hostport(const char* hostport, grpc_resolved_address* addr,
}
goto done;
}
strncpy(host_without_scope, host, host_without_scope_len);
strncpy(host_without_scope, host.get(), host_without_scope_len);
host_without_scope[host_without_scope_len] = '\0';
if (grpc_inet_pton(GRPC_AF_INET6, host_without_scope, &in6->sin6_addr) ==
0) {
@ -163,9 +165,9 @@ bool grpc_parse_ipv6_hostport(const char* hostport, grpc_resolved_address* addr,
}
goto done;
}
if (gpr_parse_bytes_to_uint32(host_end + 1,
strlen(host) - host_without_scope_len - 1,
&sin6_scope_id) == 0) {
if (gpr_parse_bytes_to_uint32(
host_end + 1, strlen(host.get()) - host_without_scope_len - 1,
&sin6_scope_id) == 0) {
if ((sin6_scope_id = grpc_if_nametoindex(host_end + 1)) == 0) {
gpr_log(GPR_ERROR,
"Invalid interface name: '%s'. "
@ -177,8 +179,10 @@ bool grpc_parse_ipv6_hostport(const char* hostport, grpc_resolved_address* addr,
// Handle "sin6_scope_id" being type "u_long". See grpc issue #10027.
in6->sin6_scope_id = sin6_scope_id;
} else {
if (grpc_inet_pton(GRPC_AF_INET6, host, &in6->sin6_addr) == 0) {
if (log_errors) gpr_log(GPR_ERROR, "invalid ipv6 address: '%s'", host);
if (grpc_inet_pton(GRPC_AF_INET6, host.get(), &in6->sin6_addr) == 0) {
if (log_errors) {
gpr_log(GPR_ERROR, "invalid ipv6 address: '%s'", host.get());
}
goto done;
}
}
@ -188,15 +192,14 @@ bool grpc_parse_ipv6_hostport(const char* hostport, grpc_resolved_address* addr,
goto done;
}
int port_num;
if (sscanf(port, "%d", &port_num) != 1 || port_num < 0 || port_num > 65535) {
if (log_errors) gpr_log(GPR_ERROR, "invalid ipv6 port: '%s'", port);
if (sscanf(port.get(), "%d", &port_num) != 1 || port_num < 0 ||
port_num > 65535) {
if (log_errors) gpr_log(GPR_ERROR, "invalid ipv6 port: '%s'", port.get());
goto done;
}
in6->sin6_port = grpc_htons(static_cast<uint16_t>(port_num));
success = true;
done:
gpr_free(host);
gpr_free(port);
return success;
}

@ -38,7 +38,6 @@
#include "src/core/ext/filters/client_channel/service_config.h"
#include "src/core/lib/backoff/backoff.h"
#include "src/core/lib/channel/channel_args.h"
#include "src/core/lib/gpr/host_port.h"
#include "src/core/lib/gpr/string.h"
#include "src/core/lib/gprpp/manual_constructor.h"
#include "src/core/lib/iomgr/combiner.h"
@ -145,7 +144,7 @@ AresDnsResolver::AresDnsResolver(ResolverArgs args)
arg = grpc_channel_args_find(channel_args_,
GRPC_ARG_DNS_MIN_TIME_BETWEEN_RESOLUTIONS_MS);
min_time_between_resolutions_ =
grpc_channel_arg_get_integer(arg, {1000, 0, INT_MAX});
grpc_channel_arg_get_integer(arg, {1000 * 30, 0, INT_MAX});
// Enable SRV queries option
arg = grpc_channel_args_find(channel_args_, GRPC_ARG_DNS_ENABLE_SRV_QUERIES);
enable_srv_queries_ = grpc_channel_arg_get_bool(arg, false);
@ -401,7 +400,8 @@ void AresDnsResolver::MaybeStartResolvingLocked() {
// new closure API is done, find a way to track this ref with the timer
// callback as part of the type system.
Ref(DEBUG_LOCATION, "next_resolution_timer_cooldown").release();
grpc_timer_init(&next_resolution_timer_, ms_until_next_resolution,
grpc_timer_init(&next_resolution_timer_,
ExecCtx::Get()->Now() + ms_until_next_resolution,
&on_next_resolution_);
return;
}
@ -433,6 +433,8 @@ void AresDnsResolver::StartResolvingLocked() {
class AresDnsResolverFactory : public ResolverFactory {
public:
bool IsValidUri(const grpc_uri* uri) const override { return true; }
OrphanablePtr<Resolver> CreateResolver(ResolverArgs args) const override {
return OrphanablePtr<Resolver>(New<AresDnsResolver>(std::move(args)));
}

@ -31,6 +31,9 @@
#include "src/core/lib/gpr/string.h"
#include "src/core/lib/gprpp/memory.h"
#include "src/core/lib/iomgr/combiner.h"
#include "src/core/lib/iomgr/iocp_windows.h"
#include "src/core/lib/iomgr/sockaddr_utils.h"
#include "src/core/lib/iomgr/sockaddr_windows.h"
#include "src/core/lib/iomgr/socket_windows.h"
#include "src/core/lib/iomgr/tcp_windows.h"
#include "src/core/lib/slice/slice_internal.h"
@ -50,6 +53,32 @@ struct iovec {
namespace grpc_core {
/* c-ares reads and takes action on the error codes of the
* "virtual socket operations" in this file, via the WSAGetLastError
* APIs. If code in this file wants to set a specific WSA error that
* c-ares should read, it must do so by calling SetWSAError() on the
* WSAErrorContext instance passed to it. A WSAErrorContext must only be
* instantiated at the top of the virtual socket function callstack. */
class WSAErrorContext {
public:
explicit WSAErrorContext(){};
~WSAErrorContext() {
if (error_ != 0) {
WSASetLastError(error_);
}
}
/* Disallow copy and assignment operators */
WSAErrorContext(const WSAErrorContext&) = delete;
WSAErrorContext& operator=(const WSAErrorContext&) = delete;
void SetWSAError(int error) { error_ = error; }
private:
int error_ = 0;
};
/* c-ares creates its own sockets and is meant to read them when readable and
* write them when writeable. To fit this socket usage model into the grpc
* windows poller (which gives notifications when attempted reads and writes are
@ -68,11 +97,14 @@ class GrpcPolledFdWindows : public GrpcPolledFd {
WRITE_WAITING_FOR_VERIFICATION_UPON_RETRY,
};
GrpcPolledFdWindows(ares_socket_t as, grpc_combiner* combiner)
GrpcPolledFdWindows(ares_socket_t as, grpc_combiner* combiner,
int address_family, int socket_type)
: read_buf_(grpc_empty_slice()),
write_buf_(grpc_empty_slice()),
write_state_(WRITE_IDLE),
gotten_into_driver_list_(false) {
tcp_write_state_(WRITE_IDLE),
gotten_into_driver_list_(false),
address_family_(address_family),
socket_type_(socket_type) {
gpr_asprintf(&name_, "c-ares socket: %" PRIdPTR, as);
winsocket_ = grpc_winsocket_create(as, name_);
combiner_ = GRPC_COMBINER_REF(combiner, name_);
@ -82,6 +114,16 @@ class GrpcPolledFdWindows : public GrpcPolledFd {
GRPC_CLOSURE_INIT(&outer_write_closure_,
&GrpcPolledFdWindows::OnIocpWriteable, this,
grpc_combiner_scheduler(combiner_));
GRPC_CLOSURE_INIT(&on_tcp_connect_locked_,
&GrpcPolledFdWindows::OnTcpConnectLocked, this,
grpc_combiner_scheduler(combiner_));
GRPC_CLOSURE_INIT(&continue_register_for_on_readable_locked_,
&GrpcPolledFdWindows::ContinueRegisterForOnReadableLocked,
this, grpc_combiner_scheduler(combiner_));
GRPC_CLOSURE_INIT(
&continue_register_for_on_writeable_locked_,
&GrpcPolledFdWindows::ContinueRegisterForOnWriteableLocked, this,
grpc_combiner_scheduler(combiner_));
}
~GrpcPolledFdWindows() {
@ -111,6 +153,33 @@ class GrpcPolledFdWindows : public GrpcPolledFd {
grpc_slice_unref_internal(read_buf_);
GPR_ASSERT(!read_buf_has_data_);
read_buf_ = GRPC_SLICE_MALLOC(4192);
if (connect_done_) {
GRPC_CLOSURE_SCHED(&continue_register_for_on_readable_locked_,
GRPC_ERROR_NONE);
} else {
GPR_ASSERT(pending_continue_register_for_on_readable_locked_ == nullptr);
pending_continue_register_for_on_readable_locked_ =
&continue_register_for_on_readable_locked_;
}
}
static void ContinueRegisterForOnReadableLocked(void* arg,
grpc_error* unused_error) {
GrpcPolledFdWindows* grpc_polled_fd =
static_cast<GrpcPolledFdWindows*>(arg);
grpc_polled_fd->InnerContinueRegisterForOnReadableLocked(GRPC_ERROR_NONE);
}
void InnerContinueRegisterForOnReadableLocked(grpc_error* unused_error) {
GRPC_CARES_TRACE_LOG(
"fd:|%s| InnerContinueRegisterForOnReadableLocked "
"wsa_connect_error_:%d",
GetName(), wsa_connect_error_);
GPR_ASSERT(connect_done_);
if (wsa_connect_error_ != 0) {
ScheduleAndNullReadClosure(GRPC_WSA_ERROR(wsa_connect_error_, "connect"));
return;
}
WSABUF buffer;
buffer.buf = (char*)GRPC_SLICE_START_PTR(read_buf_);
buffer.len = GRPC_SLICE_LENGTH(read_buf_);
@ -123,13 +192,14 @@ class GrpcPolledFdWindows : public GrpcPolledFd {
&winsocket_->read_info.overlapped, nullptr)) {
int wsa_last_error = WSAGetLastError();
char* msg = gpr_format_message(wsa_last_error);
grpc_error* error = GRPC_ERROR_CREATE_FROM_COPIED_STRING(msg);
GRPC_CARES_TRACE_LOG(
"RegisterForOnReadableLocked: WSARecvFrom error:|%s|. fd:|%s|", msg,
GetName());
"fd:|%s| RegisterForOnReadableLocked WSARecvFrom error code:|%d| "
"msg:|%s|",
GetName(), wsa_last_error, msg);
gpr_free(msg);
if (wsa_last_error != WSA_IO_PENDING) {
ScheduleAndNullReadClosure(error);
ScheduleAndNullReadClosure(
GRPC_WSA_ERROR(wsa_last_error, "WSARecvFrom"));
return;
}
}
@ -137,23 +207,68 @@ class GrpcPolledFdWindows : public GrpcPolledFd {
}
void RegisterForOnWriteableLocked(grpc_closure* write_closure) override {
GRPC_CARES_TRACE_LOG(
"RegisterForOnWriteableLocked. fd:|%s|. Current write state: %d",
GetName(), write_state_);
if (socket_type_ == SOCK_DGRAM) {
GRPC_CARES_TRACE_LOG("fd:|%s| RegisterForOnWriteableLocked called",
GetName());
} else {
GPR_ASSERT(socket_type_ == SOCK_STREAM);
GRPC_CARES_TRACE_LOG(
"fd:|%s| RegisterForOnWriteableLocked called tcp_write_state_: %d",
GetName(), tcp_write_state_);
}
GPR_ASSERT(write_closure_ == nullptr);
write_closure_ = write_closure;
switch (write_state_) {
case WRITE_IDLE:
ScheduleAndNullWriteClosure(GRPC_ERROR_NONE);
break;
case WRITE_REQUESTED:
write_state_ = WRITE_PENDING;
SendWriteBuf(nullptr, &winsocket_->write_info.overlapped);
grpc_socket_notify_on_write(winsocket_, &outer_write_closure_);
break;
case WRITE_PENDING:
case WRITE_WAITING_FOR_VERIFICATION_UPON_RETRY:
abort();
if (connect_done_) {
GRPC_CLOSURE_SCHED(&continue_register_for_on_writeable_locked_,
GRPC_ERROR_NONE);
} else {
GPR_ASSERT(pending_continue_register_for_on_writeable_locked_ == nullptr);
pending_continue_register_for_on_writeable_locked_ =
&continue_register_for_on_writeable_locked_;
}
}
static void ContinueRegisterForOnWriteableLocked(void* arg,
grpc_error* unused_error) {
GrpcPolledFdWindows* grpc_polled_fd =
static_cast<GrpcPolledFdWindows*>(arg);
grpc_polled_fd->InnerContinueRegisterForOnWriteableLocked(GRPC_ERROR_NONE);
}
void InnerContinueRegisterForOnWriteableLocked(grpc_error* unused_error) {
GRPC_CARES_TRACE_LOG(
"fd:|%s| InnerContinueRegisterForOnWriteableLocked "
"wsa_connect_error_:%d",
GetName(), wsa_connect_error_);
GPR_ASSERT(connect_done_);
if (wsa_connect_error_ != 0) {
ScheduleAndNullWriteClosure(
GRPC_WSA_ERROR(wsa_connect_error_, "connect"));
return;
}
if (socket_type_ == SOCK_DGRAM) {
ScheduleAndNullWriteClosure(GRPC_ERROR_NONE);
} else {
GPR_ASSERT(socket_type_ == SOCK_STREAM);
int wsa_error_code = 0;
switch (tcp_write_state_) {
case WRITE_IDLE:
ScheduleAndNullWriteClosure(GRPC_ERROR_NONE);
break;
case WRITE_REQUESTED:
tcp_write_state_ = WRITE_PENDING;
if (SendWriteBuf(nullptr, &winsocket_->write_info.overlapped,
&wsa_error_code) != 0) {
ScheduleAndNullWriteClosure(
GRPC_WSA_ERROR(wsa_error_code, "WSASend (overlapped)"));
} else {
grpc_socket_notify_on_write(winsocket_, &outer_write_closure_);
}
break;
case WRITE_PENDING:
case WRITE_WAITING_FOR_VERIFICATION_UPON_RETRY:
abort();
}
}
}
@ -171,13 +286,15 @@ class GrpcPolledFdWindows : public GrpcPolledFd {
const char* GetName() override { return name_; }
ares_ssize_t RecvFrom(void* data, ares_socket_t data_len, int flags,
ares_ssize_t RecvFrom(WSAErrorContext* wsa_error_ctx, void* data,
ares_socket_t data_len, int flags,
struct sockaddr* from, ares_socklen_t* from_len) {
GRPC_CARES_TRACE_LOG(
"RecvFrom called on fd:|%s|. Current read buf length:|%d|", GetName(),
GRPC_SLICE_LENGTH(read_buf_));
"fd:|%s| RecvFrom called read_buf_has_data:%d Current read buf "
"length:|%d|",
GetName(), read_buf_has_data_, GRPC_SLICE_LENGTH(read_buf_));
if (!read_buf_has_data_) {
WSASetLastError(WSAEWOULDBLOCK);
wsa_error_ctx->SetWSAError(WSAEWOULDBLOCK);
return -1;
}
ares_ssize_t bytes_read = 0;
@ -215,54 +332,99 @@ class GrpcPolledFdWindows : public GrpcPolledFd {
return out;
}
int SendWriteBuf(LPDWORD bytes_sent_ptr, LPWSAOVERLAPPED overlapped) {
int SendWriteBuf(LPDWORD bytes_sent_ptr, LPWSAOVERLAPPED overlapped,
int* wsa_error_code) {
WSABUF buf;
buf.len = GRPC_SLICE_LENGTH(write_buf_);
buf.buf = (char*)GRPC_SLICE_START_PTR(write_buf_);
DWORD flags = 0;
int out = WSASend(grpc_winsocket_wrapped_socket(winsocket_), &buf, 1,
bytes_sent_ptr, flags, overlapped, nullptr);
*wsa_error_code = WSAGetLastError();
GRPC_CARES_TRACE_LOG(
"WSASend: name:%s. buf len:%d. bytes sent: %d. overlapped %p. return "
"val: %d",
GetName(), buf.len, *bytes_sent_ptr, overlapped, out);
"fd:|%s| SendWriteBuf WSASend buf.len:%d *bytes_sent_ptr:%d "
"overlapped:%p "
"return:%d *wsa_error_code:%d",
GetName(), buf.len, bytes_sent_ptr != nullptr ? *bytes_sent_ptr : 0,
overlapped, out, *wsa_error_code);
return out;
}
ares_ssize_t TrySendWriteBufSyncNonBlocking() {
GPR_ASSERT(write_state_ == WRITE_IDLE);
ares_ssize_t SendV(WSAErrorContext* wsa_error_ctx, const struct iovec* iov,
int iov_count) {
GRPC_CARES_TRACE_LOG(
"fd:|%s| SendV called connect_done_:%d wsa_connect_error_:%d",
GetName(), connect_done_, wsa_connect_error_);
if (!connect_done_) {
wsa_error_ctx->SetWSAError(WSAEWOULDBLOCK);
return -1;
}
if (wsa_connect_error_ != 0) {
wsa_error_ctx->SetWSAError(wsa_connect_error_);
return -1;
}
switch (socket_type_) {
case SOCK_DGRAM:
return SendVUDP(wsa_error_ctx, iov, iov_count);
case SOCK_STREAM:
return SendVTCP(wsa_error_ctx, iov, iov_count);
default:
abort();
}
}
ares_ssize_t SendVUDP(WSAErrorContext* wsa_error_ctx, const struct iovec* iov,
int iov_count) {
// c-ares doesn't handle retryable errors on writes of UDP sockets.
// Therefore, the sendv handler for UDP sockets must only attempt
// to write everything inline.
GRPC_CARES_TRACE_LOG("fd:|%s| SendVUDP called", GetName());
GPR_ASSERT(GRPC_SLICE_LENGTH(write_buf_) == 0);
grpc_slice_unref_internal(write_buf_);
write_buf_ = FlattenIovec(iov, iov_count);
DWORD bytes_sent = 0;
if (SendWriteBuf(&bytes_sent, nullptr) != 0) {
int wsa_last_error = WSAGetLastError();
char* msg = gpr_format_message(wsa_last_error);
int wsa_error_code = 0;
if (SendWriteBuf(&bytes_sent, nullptr, &wsa_error_code) != 0) {
wsa_error_ctx->SetWSAError(wsa_error_code);
char* msg = gpr_format_message(wsa_error_code);
GRPC_CARES_TRACE_LOG(
"TrySendWriteBufSyncNonBlocking: SendWriteBuf error:|%s|. fd:|%s|",
msg, GetName());
"fd:|%s| SendVUDP SendWriteBuf error code:%d msg:|%s|", GetName(),
wsa_error_code, msg);
gpr_free(msg);
if (wsa_last_error == WSA_IO_PENDING) {
WSASetLastError(WSAEWOULDBLOCK);
write_state_ = WRITE_REQUESTED;
}
return -1;
}
write_buf_ = grpc_slice_sub_no_ref(write_buf_, bytes_sent,
GRPC_SLICE_LENGTH(write_buf_));
return bytes_sent;
}
ares_ssize_t SendV(const struct iovec* iov, int iov_count) {
GRPC_CARES_TRACE_LOG("SendV called on fd:|%s|. Current write state: %d",
GetName(), write_state_);
switch (write_state_) {
ares_ssize_t SendVTCP(WSAErrorContext* wsa_error_ctx, const struct iovec* iov,
int iov_count) {
// The "sendv" handler on TCP sockets buffers up write
// requests and returns an artifical WSAEWOULDBLOCK. Writing that buffer out
// in the background, and making further send progress in general, will
// happen as long as c-ares continues to show interest in writeability on
// this fd.
GRPC_CARES_TRACE_LOG("fd:|%s| SendVTCP called tcp_write_state_:%d",
GetName(), tcp_write_state_);
switch (tcp_write_state_) {
case WRITE_IDLE:
tcp_write_state_ = WRITE_REQUESTED;
GPR_ASSERT(GRPC_SLICE_LENGTH(write_buf_) == 0);
grpc_slice_unref_internal(write_buf_);
write_buf_ = FlattenIovec(iov, iov_count);
return TrySendWriteBufSyncNonBlocking();
wsa_error_ctx->SetWSAError(WSAEWOULDBLOCK);
return -1;
case WRITE_REQUESTED:
case WRITE_PENDING:
WSASetLastError(WSAEWOULDBLOCK);
wsa_error_ctx->SetWSAError(WSAEWOULDBLOCK);
return -1;
case WRITE_WAITING_FOR_VERIFICATION_UPON_RETRY:
// c-ares is retrying a send on data that we previously returned
// WSAEWOULDBLOCK for, but then subsequently wrote out in the
// background. Right now, we assume that c-ares is retrying the same
// send again. If c-ares still needs to send even more data, we'll get
// to it eventually.
grpc_slice currently_attempted = FlattenIovec(iov, iov_count);
GPR_ASSERT(GRPC_SLICE_LENGTH(currently_attempted) >=
GRPC_SLICE_LENGTH(write_buf_));
@ -272,31 +434,160 @@ class GrpcPolledFdWindows : public GrpcPolledFd {
GRPC_SLICE_START_PTR(write_buf_)[i]);
total_sent++;
}
grpc_slice_unref_internal(write_buf_);
write_buf_ =
grpc_slice_sub_no_ref(currently_attempted, total_sent,
GRPC_SLICE_LENGTH(currently_attempted));
write_state_ = WRITE_IDLE;
total_sent += TrySendWriteBufSyncNonBlocking();
grpc_slice_unref_internal(currently_attempted);
tcp_write_state_ = WRITE_IDLE;
return total_sent;
}
abort();
}
int Connect(const struct sockaddr* target, ares_socklen_t target_len) {
static void OnTcpConnectLocked(void* arg, grpc_error* error) {
GrpcPolledFdWindows* grpc_polled_fd =
static_cast<GrpcPolledFdWindows*>(arg);
grpc_polled_fd->InnerOnTcpConnectLocked(error);
}
void InnerOnTcpConnectLocked(grpc_error* error) {
GRPC_CARES_TRACE_LOG(
"fd:%s InnerOnTcpConnectLocked error:|%s| "
"pending_register_for_readable:%" PRIdPTR
" pending_register_for_writeable:%" PRIdPTR,
GetName(), grpc_error_string(error),
pending_continue_register_for_on_readable_locked_,
pending_continue_register_for_on_writeable_locked_);
GPR_ASSERT(!connect_done_);
connect_done_ = true;
GPR_ASSERT(wsa_connect_error_ == 0);
if (error == GRPC_ERROR_NONE) {
DWORD transferred_bytes = 0;
DWORD flags;
BOOL wsa_success =
WSAGetOverlappedResult(grpc_winsocket_wrapped_socket(winsocket_),
&winsocket_->write_info.overlapped,
&transferred_bytes, FALSE, &flags);
GPR_ASSERT(transferred_bytes == 0);
if (!wsa_success) {
wsa_connect_error_ = WSAGetLastError();
char* msg = gpr_format_message(wsa_connect_error_);
GRPC_CARES_TRACE_LOG(
"fd:%s InnerOnTcpConnectLocked WSA overlapped result code:%d "
"msg:|%s|",
GetName(), wsa_connect_error_, msg);
gpr_free(msg);
}
} else {
// Spoof up an error code that will cause any future c-ares operations on
// this fd to abort.
wsa_connect_error_ = WSA_OPERATION_ABORTED;
}
if (pending_continue_register_for_on_readable_locked_ != nullptr) {
GRPC_CLOSURE_SCHED(pending_continue_register_for_on_readable_locked_,
GRPC_ERROR_NONE);
}
if (pending_continue_register_for_on_writeable_locked_ != nullptr) {
GRPC_CLOSURE_SCHED(pending_continue_register_for_on_writeable_locked_,
GRPC_ERROR_NONE);
}
}
int Connect(WSAErrorContext* wsa_error_ctx, const struct sockaddr* target,
ares_socklen_t target_len) {
switch (socket_type_) {
case SOCK_DGRAM:
return ConnectUDP(wsa_error_ctx, target, target_len);
case SOCK_STREAM:
return ConnectTCP(wsa_error_ctx, target, target_len);
default:
abort();
}
}
int ConnectUDP(WSAErrorContext* wsa_error_ctx, const struct sockaddr* target,
ares_socklen_t target_len) {
GRPC_CARES_TRACE_LOG("fd:%s ConnectUDP", GetName());
GPR_ASSERT(!connect_done_);
GPR_ASSERT(wsa_connect_error_ == 0);
SOCKET s = grpc_winsocket_wrapped_socket(winsocket_);
GRPC_CARES_TRACE_LOG("Connect: fd:|%s|", GetName());
int out =
WSAConnect(s, target, target_len, nullptr, nullptr, nullptr, nullptr);
if (out != 0) {
wsa_connect_error_ = WSAGetLastError();
wsa_error_ctx->SetWSAError(wsa_connect_error_);
connect_done_ = true;
char* msg = gpr_format_message(wsa_connect_error_);
GRPC_CARES_TRACE_LOG("fd:%s WSAConnect error code:|%d| msg:|%s|", GetName(),
wsa_connect_error_, msg);
gpr_free(msg);
// c-ares expects a posix-style connect API
return out == 0 ? 0 : -1;
}
int ConnectTCP(WSAErrorContext* wsa_error_ctx, const struct sockaddr* target,
ares_socklen_t target_len) {
GRPC_CARES_TRACE_LOG("fd:%s ConnectTCP", GetName());
LPFN_CONNECTEX ConnectEx;
GUID guid = WSAID_CONNECTEX;
DWORD ioctl_num_bytes;
SOCKET s = grpc_winsocket_wrapped_socket(winsocket_);
if (WSAIoctl(s, SIO_GET_EXTENSION_FUNCTION_POINTER, &guid, sizeof(guid),
&ConnectEx, sizeof(ConnectEx), &ioctl_num_bytes, nullptr,
nullptr) != 0) {
int wsa_last_error = WSAGetLastError();
wsa_error_ctx->SetWSAError(wsa_last_error);
char* msg = gpr_format_message(wsa_last_error);
GRPC_CARES_TRACE_LOG(
"fd:%s WSAIoctl(SIO_GET_EXTENSION_FUNCTION_POINTER) error code:%d "
"msg:|%s|",
GetName(), wsa_last_error, msg);
gpr_free(msg);
connect_done_ = true;
wsa_connect_error_ = wsa_last_error;
return -1;
}
grpc_resolved_address wildcard4_addr;
grpc_resolved_address wildcard6_addr;
grpc_sockaddr_make_wildcards(0, &wildcard4_addr, &wildcard6_addr);
grpc_resolved_address* local_address = nullptr;
if (address_family_ == AF_INET) {
local_address = &wildcard4_addr;
} else {
local_address = &wildcard6_addr;
}
if (bind(s, (struct sockaddr*)local_address->addr,
(int)local_address->len) != 0) {
int wsa_last_error = WSAGetLastError();
wsa_error_ctx->SetWSAError(wsa_last_error);
char* msg = gpr_format_message(wsa_last_error);
GRPC_CARES_TRACE_LOG("Connect error code:|%d|, msg:|%s|. fd:|%s|",
wsa_last_error, msg, GetName());
GRPC_CARES_TRACE_LOG("fd:%s bind error code:%d msg:|%s|", GetName(),
wsa_last_error, msg);
gpr_free(msg);
// c-ares expects a posix-style connect API
connect_done_ = true;
wsa_connect_error_ = wsa_last_error;
return -1;
}
int out = 0;
if (ConnectEx(s, target, target_len, nullptr, 0, nullptr,
&winsocket_->write_info.overlapped) == 0) {
out = -1;
int wsa_last_error = WSAGetLastError();
wsa_error_ctx->SetWSAError(wsa_last_error);
char* msg = gpr_format_message(wsa_last_error);
GRPC_CARES_TRACE_LOG("fd:%s ConnectEx error code:%d msg:|%s|", GetName(),
wsa_last_error, msg);
gpr_free(msg);
if (wsa_last_error == WSA_IO_PENDING) {
// c-ares only understands WSAEINPROGRESS and EWOULDBLOCK error codes on
// connect, but an async connect on IOCP socket will give
// WSA_IO_PENDING, so we need to convert.
wsa_error_ctx->SetWSAError(WSAEWOULDBLOCK);
} else {
// By returning a non-retryable error to c-ares at this point,
// we're aborting the possibility of any future operations on this fd.
connect_done_ = true;
wsa_connect_error_ = wsa_last_error;
return -1;
}
}
grpc_socket_notify_on_write(winsocket_, &on_tcp_connect_locked_);
return out;
}
@ -319,26 +610,27 @@ class GrpcPolledFdWindows : public GrpcPolledFd {
* in subsequent c-ares reads. */
if (winsocket_->read_info.wsa_error != WSAEMSGSIZE) {
GRPC_ERROR_UNREF(error);
char* msg = gpr_format_message(winsocket_->read_info.wsa_error);
error = GRPC_WSA_ERROR(winsocket_->read_info.wsa_error,
"OnIocpReadableInner");
GRPC_CARES_TRACE_LOG(
"OnIocpReadableInner. winsocket error:|%s|. fd:|%s|", msg,
GetName());
error = GRPC_ERROR_CREATE_FROM_COPIED_STRING(msg);
gpr_free(msg);
"fd:|%s| OnIocpReadableInner winsocket_->read_info.wsa_error "
"code:|%d| msg:|%s|",
GetName(), winsocket_->read_info.wsa_error,
grpc_error_string(error));
}
}
}
if (error == GRPC_ERROR_NONE) {
read_buf_ = grpc_slice_sub_no_ref(read_buf_, 0,
winsocket_->read_info.bytes_transfered);
read_buf_ = grpc_slice_sub_no_ref(
read_buf_, 0, winsocket_->read_info.bytes_transferred);
read_buf_has_data_ = true;
} else {
grpc_slice_unref_internal(read_buf_);
read_buf_ = grpc_empty_slice();
}
GRPC_CARES_TRACE_LOG(
"OnIocpReadable finishing. read buf length now:|%d|. :fd:|%s|",
GRPC_SLICE_LENGTH(read_buf_), GetName());
"fd:|%s| OnIocpReadable finishing. read buf length now:|%d|", GetName(),
GRPC_SLICE_LENGTH(read_buf_));
ScheduleAndNullReadClosure(error);
}
@ -349,22 +641,26 @@ class GrpcPolledFdWindows : public GrpcPolledFd {
void OnIocpWriteableInner(grpc_error* error) {
GRPC_CARES_TRACE_LOG("OnIocpWriteableInner. fd:|%s|", GetName());
GPR_ASSERT(socket_type_ == SOCK_STREAM);
if (error == GRPC_ERROR_NONE) {
if (winsocket_->write_info.wsa_error != 0) {
char* msg = gpr_format_message(winsocket_->write_info.wsa_error);
GRPC_CARES_TRACE_LOG(
"OnIocpWriteableInner. winsocket error:|%s|. fd:|%s|", msg,
GetName());
GRPC_ERROR_UNREF(error);
error = GRPC_ERROR_CREATE_FROM_COPIED_STRING(msg);
gpr_free(msg);
error = GRPC_WSA_ERROR(winsocket_->write_info.wsa_error,
"OnIocpWriteableInner");
GRPC_CARES_TRACE_LOG(
"fd:|%s| OnIocpWriteableInner. winsocket_->write_info.wsa_error "
"code:|%d| msg:|%s|",
GetName(), winsocket_->write_info.wsa_error,
grpc_error_string(error));
}
}
GPR_ASSERT(write_state_ == WRITE_PENDING);
GPR_ASSERT(tcp_write_state_ == WRITE_PENDING);
if (error == GRPC_ERROR_NONE) {
write_state_ = WRITE_WAITING_FOR_VERIFICATION_UPON_RETRY;
tcp_write_state_ = WRITE_WAITING_FOR_VERIFICATION_UPON_RETRY;
write_buf_ = grpc_slice_sub_no_ref(
write_buf_, 0, winsocket_->write_info.bytes_transfered);
write_buf_, 0, winsocket_->write_info.bytes_transferred);
GRPC_CARES_TRACE_LOG("fd:|%s| OnIocpWriteableInner. bytes transferred:%d",
GetName(), winsocket_->write_info.bytes_transferred);
} else {
grpc_slice_unref_internal(write_buf_);
write_buf_ = grpc_empty_slice();
@ -386,9 +682,22 @@ class GrpcPolledFdWindows : public GrpcPolledFd {
grpc_closure outer_read_closure_;
grpc_closure outer_write_closure_;
grpc_winsocket* winsocket_;
WriteState write_state_;
// tcp_write_state_ is only used on TCP GrpcPolledFds
WriteState tcp_write_state_;
char* name_ = nullptr;
bool gotten_into_driver_list_;
int address_family_;
int socket_type_;
grpc_closure on_tcp_connect_locked_;
bool connect_done_ = false;
int wsa_connect_error_ = 0;
// We don't run register_for_{readable,writeable} logic until
// a socket is connected. In the interim, we queue readable/writeable
// registrations with the following state.
grpc_closure continue_register_for_on_readable_locked_;
grpc_closure continue_register_for_on_writeable_locked_;
grpc_closure* pending_continue_register_for_on_readable_locked_ = nullptr;
grpc_closure* pending_continue_register_for_on_writeable_locked_ = nullptr;
};
struct SockToPolledFdEntry {
@ -454,39 +763,53 @@ class SockToPolledFdMap {
* objects.
*/
static ares_socket_t Socket(int af, int type, int protocol, void* user_data) {
if (type != SOCK_DGRAM && type != SOCK_STREAM) {
GRPC_CARES_TRACE_LOG("Socket called with invalid socket type:%d", type);
return INVALID_SOCKET;
}
SockToPolledFdMap* map = static_cast<SockToPolledFdMap*>(user_data);
SOCKET s = WSASocket(af, type, protocol, nullptr, 0,
grpc_get_default_wsa_socket_flags());
if (s == INVALID_SOCKET) {
GRPC_CARES_TRACE_LOG(
"WSASocket failed with params af:%d type:%d protocol:%d", af, type,
protocol);
return s;
}
grpc_tcp_set_non_block(s);
GrpcPolledFdWindows* polled_fd =
New<GrpcPolledFdWindows>(s, map->combiner_);
New<GrpcPolledFdWindows>(s, map->combiner_, af, type);
GRPC_CARES_TRACE_LOG(
"fd:|%s| created with params af:%d type:%d protocol:%d",
polled_fd->GetName(), af, type, protocol);
map->AddNewSocket(s, polled_fd);
return s;
}
static int Connect(ares_socket_t as, const struct sockaddr* target,
ares_socklen_t target_len, void* user_data) {
WSAErrorContext wsa_error_ctx;
SockToPolledFdMap* map = static_cast<SockToPolledFdMap*>(user_data);
GrpcPolledFdWindows* polled_fd = map->LookupPolledFd(as);
return polled_fd->Connect(target, target_len);
return polled_fd->Connect(&wsa_error_ctx, target, target_len);
}
static ares_ssize_t SendV(ares_socket_t as, const struct iovec* iov,
int iovec_count, void* user_data) {
WSAErrorContext wsa_error_ctx;
SockToPolledFdMap* map = static_cast<SockToPolledFdMap*>(user_data);
GrpcPolledFdWindows* polled_fd = map->LookupPolledFd(as);
return polled_fd->SendV(iov, iovec_count);
return polled_fd->SendV(&wsa_error_ctx, iov, iovec_count);
}
static ares_ssize_t RecvFrom(ares_socket_t as, void* data, size_t data_len,
int flags, struct sockaddr* from,
ares_socklen_t* from_len, void* user_data) {
WSAErrorContext wsa_error_ctx;
SockToPolledFdMap* map = static_cast<SockToPolledFdMap*>(user_data);
GrpcPolledFdWindows* polled_fd = map->LookupPolledFd(as);
return polled_fd->RecvFrom(data, data_len, flags, from, from_len);
return polled_fd->RecvFrom(&wsa_error_ctx, data, data_len, flags, from,
from_len);
}
static int CloseSocket(SOCKET s, void* user_data) {

@ -35,8 +35,8 @@
#include <address_sorting/address_sorting.h>
#include "src/core/ext/filters/client_channel/parse_address.h"
#include "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver.h"
#include "src/core/lib/gpr/host_port.h"
#include "src/core/lib/gpr/string.h"
#include "src/core/lib/gprpp/host_port.h"
#include "src/core/lib/iomgr/combiner.h"
#include "src/core/lib/iomgr/error.h"
#include "src/core/lib/iomgr/executor.h"
@ -355,9 +355,9 @@ void grpc_dns_lookup_ares_continue_after_check_localhost_and_ip_literals_locked(
grpc_ares_hostbyname_request* hr = nullptr;
ares_channel* channel = nullptr;
/* parse name, splitting it into host and port parts */
char* host;
char* port;
gpr_split_host_port(name, &host, &port);
grpc_core::UniquePtr<char> host;
grpc_core::UniquePtr<char> port;
grpc_core::SplitHostPort(name, &host, &port);
if (host == nullptr) {
error = grpc_error_set_str(
GRPC_ERROR_CREATE_FROM_STATIC_STRING("unparseable host:port"),
@ -370,7 +370,7 @@ void grpc_dns_lookup_ares_continue_after_check_localhost_and_ip_literals_locked(
GRPC_ERROR_STR_TARGET_ADDRESS, grpc_slice_from_copied_string(name));
goto error_cleanup;
}
port = gpr_strdup(default_port);
port.reset(gpr_strdup(default_port));
}
error = grpc_ares_ev_driver_create_locked(&r->ev_driver, interested_parties,
query_timeout_ms, combiner, r);
@ -414,20 +414,22 @@ void grpc_dns_lookup_ares_continue_after_check_localhost_and_ip_literals_locked(
}
r->pending_queries = 1;
if (grpc_ares_query_ipv6()) {
hr = create_hostbyname_request_locked(r, host, grpc_strhtons(port),
false /* is_balancer */);
hr = create_hostbyname_request_locked(r, host.get(),
grpc_strhtons(port.get()),
/*is_balancer=*/false);
ares_gethostbyname(*channel, hr->host, AF_INET6, on_hostbyname_done_locked,
hr);
}
hr = create_hostbyname_request_locked(r, host, grpc_strhtons(port),
false /* is_balancer */);
hr =
create_hostbyname_request_locked(r, host.get(), grpc_strhtons(port.get()),
/*is_balancer=*/false);
ares_gethostbyname(*channel, hr->host, AF_INET, on_hostbyname_done_locked,
hr);
if (check_grpclb) {
/* Query the SRV record */
grpc_ares_request_ref_locked(r);
char* service_name;
gpr_asprintf(&service_name, "_grpclb._tcp.%s", host);
gpr_asprintf(&service_name, "_grpclb._tcp.%s", host.get());
ares_query(*channel, service_name, ns_c_in, ns_t_srv,
on_srv_query_done_locked, r);
gpr_free(service_name);
@ -435,28 +437,25 @@ void grpc_dns_lookup_ares_continue_after_check_localhost_and_ip_literals_locked(
if (r->service_config_json_out != nullptr) {
grpc_ares_request_ref_locked(r);
char* config_name;
gpr_asprintf(&config_name, "_grpc_config.%s", host);
gpr_asprintf(&config_name, "_grpc_config.%s", host.get());
ares_search(*channel, config_name, ns_c_in, ns_t_txt, on_txt_done_locked,
r);
gpr_free(config_name);
}
grpc_ares_ev_driver_start_locked(r->ev_driver);
grpc_ares_request_unref_locked(r);
gpr_free(host);
gpr_free(port);
return;
error_cleanup:
GRPC_CLOSURE_SCHED(r->on_done, error);
gpr_free(host);
gpr_free(port);
}
static bool inner_resolve_as_ip_literal_locked(
const char* name, const char* default_port,
grpc_core::UniquePtr<grpc_core::ServerAddressList>* addrs, char** host,
char** port, char** hostport) {
gpr_split_host_port(name, host, port);
grpc_core::UniquePtr<grpc_core::ServerAddressList>* addrs,
grpc_core::UniquePtr<char>* host, grpc_core::UniquePtr<char>* port,
grpc_core::UniquePtr<char>* hostport) {
grpc_core::SplitHostPort(name, host, port);
if (*host == nullptr) {
gpr_log(GPR_ERROR,
"Failed to parse %s to host:port while attempting to resolve as ip "
@ -472,12 +471,14 @@ static bool inner_resolve_as_ip_literal_locked(
name);
return false;
}
*port = gpr_strdup(default_port);
port->reset(gpr_strdup(default_port));
}
grpc_resolved_address addr;
GPR_ASSERT(gpr_join_host_port(hostport, *host, atoi(*port)));
if (grpc_parse_ipv4_hostport(*hostport, &addr, false /* log errors */) ||
grpc_parse_ipv6_hostport(*hostport, &addr, false /* log errors */)) {
GPR_ASSERT(grpc_core::JoinHostPort(hostport, host->get(), atoi(port->get())));
if (grpc_parse_ipv4_hostport(hostport->get(), &addr,
false /* log errors */) ||
grpc_parse_ipv6_hostport(hostport->get(), &addr,
false /* log errors */)) {
GPR_ASSERT(*addrs == nullptr);
*addrs = grpc_core::MakeUnique<ServerAddressList>();
(*addrs)->emplace_back(addr.addr, addr.len, nullptr /* args */);
@ -489,24 +490,22 @@ static bool inner_resolve_as_ip_literal_locked(
static bool resolve_as_ip_literal_locked(
const char* name, const char* default_port,
grpc_core::UniquePtr<grpc_core::ServerAddressList>* addrs) {
char* host = nullptr;
char* port = nullptr;
char* hostport = nullptr;
grpc_core::UniquePtr<char> host;
grpc_core::UniquePtr<char> port;
grpc_core::UniquePtr<char> hostport;
bool out = inner_resolve_as_ip_literal_locked(name, default_port, addrs,
&host, &port, &hostport);
gpr_free(host);
gpr_free(port);
gpr_free(hostport);
return out;
}
static bool target_matches_localhost_inner(const char* name, char** host,
char** port) {
if (!gpr_split_host_port(name, host, port)) {
static bool target_matches_localhost_inner(const char* name,
grpc_core::UniquePtr<char>* host,
grpc_core::UniquePtr<char>* port) {
if (!grpc_core::SplitHostPort(name, host, port)) {
gpr_log(GPR_ERROR, "Unable to split host and port for name: %s", name);
return false;
}
if (gpr_stricmp(*host, "localhost") == 0) {
if (gpr_stricmp(host->get(), "localhost") == 0) {
return true;
} else {
return false;
@ -514,20 +513,17 @@ static bool target_matches_localhost_inner(const char* name, char** host,
}
static bool target_matches_localhost(const char* name) {
char* host = nullptr;
char* port = nullptr;
bool out = target_matches_localhost_inner(name, &host, &port);
gpr_free(host);
gpr_free(port);
return out;
grpc_core::UniquePtr<char> host;
grpc_core::UniquePtr<char> port;
return target_matches_localhost_inner(name, &host, &port);
}
#ifdef GRPC_ARES_RESOLVE_LOCALHOST_MANUALLY
static bool inner_maybe_resolve_localhost_manually_locked(
const char* name, const char* default_port,
grpc_core::UniquePtr<grpc_core::ServerAddressList>* addrs, char** host,
char** port) {
gpr_split_host_port(name, host, port);
grpc_core::UniquePtr<grpc_core::ServerAddressList>* addrs,
grpc_core::UniquePtr<char>* host, grpc_core::UniquePtr<char>* port) {
grpc_core::SplitHostPort(name, host, port);
if (*host == nullptr) {
gpr_log(GPR_ERROR,
"Failed to parse %s into host:port during manual localhost "
@ -543,12 +539,12 @@ static bool inner_maybe_resolve_localhost_manually_locked(
name);
return false;
}
*port = gpr_strdup(default_port);
port->reset(gpr_strdup(default_port));
}
if (gpr_stricmp(*host, "localhost") == 0) {
if (gpr_stricmp(host->get(), "localhost") == 0) {
GPR_ASSERT(*addrs == nullptr);
*addrs = grpc_core::MakeUnique<grpc_core::ServerAddressList>();
uint16_t numeric_port = grpc_strhtons(*port);
uint16_t numeric_port = grpc_strhtons(port->get());
// Append the ipv6 loopback address.
struct sockaddr_in6 ipv6_loopback_addr;
memset(&ipv6_loopback_addr, 0, sizeof(ipv6_loopback_addr));
@ -576,13 +572,10 @@ static bool inner_maybe_resolve_localhost_manually_locked(
static bool grpc_ares_maybe_resolve_localhost_manually_locked(
const char* name, const char* default_port,
grpc_core::UniquePtr<grpc_core::ServerAddressList>* addrs) {
char* host = nullptr;
char* port = nullptr;
bool out = inner_maybe_resolve_localhost_manually_locked(name, default_port,
addrs, &host, &port);
gpr_free(host);
gpr_free(port);
return out;
grpc_core::UniquePtr<char> host;
grpc_core::UniquePtr<char> port;
return inner_maybe_resolve_localhost_manually_locked(name, default_port,
addrs, &host, &port);
}
#else /* GRPC_ARES_RESOLVE_LOCALHOST_MANUALLY */
static bool grpc_ares_maybe_resolve_localhost_manually_locked(

@ -26,7 +26,6 @@
#include "src/core/ext/filters/client_channel/parse_address.h"
#include "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.h"
#include "src/core/ext/filters/client_channel/server_address.h"
#include "src/core/lib/gpr/host_port.h"
#include "src/core/lib/gpr/string.h"
bool grpc_ares_query_ipv6() {

@ -26,7 +26,6 @@
#include "src/core/ext/filters/client_channel/parse_address.h"
#include "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.h"
#include "src/core/ext/filters/client_channel/server_address.h"
#include "src/core/lib/gpr/host_port.h"
#include "src/core/lib/gpr/string.h"
#include "src/core/lib/iomgr/socket_windows.h"

@ -31,7 +31,6 @@
#include "src/core/ext/filters/client_channel/server_address.h"
#include "src/core/lib/backoff/backoff.h"
#include "src/core/lib/channel/channel_args.h"
#include "src/core/lib/gpr/host_port.h"
#include "src/core/lib/gpr/string.h"
#include "src/core/lib/gprpp/manual_constructor.h"
#include "src/core/lib/iomgr/combiner.h"
@ -111,7 +110,7 @@ NativeDnsResolver::NativeDnsResolver(ResolverArgs args)
const grpc_arg* arg = grpc_channel_args_find(
args.args, GRPC_ARG_DNS_MIN_TIME_BETWEEN_RESOLUTIONS_MS);
min_time_between_resolutions_ =
grpc_channel_arg_get_integer(arg, {1000, 0, INT_MAX});
grpc_channel_arg_get_integer(arg, {1000 * 30, 0, INT_MAX});
interested_parties_ = grpc_pollset_set_create();
if (args.pollset_set != nullptr) {
grpc_pollset_set_add_pollset_set(interested_parties_, args.pollset_set);
@ -230,7 +229,8 @@ void NativeDnsResolver::MaybeStartResolvingLocked() {
// new closure API is done, find a way to track this ref with the timer
// callback as part of the type system.
Ref(DEBUG_LOCATION, "next_resolution_timer_cooldown").release();
grpc_timer_init(&next_resolution_timer_, ms_until_next_resolution,
grpc_timer_init(&next_resolution_timer_,
ExecCtx::Get()->Now() + ms_until_next_resolution,
&on_next_resolution_);
return;
}
@ -258,11 +258,16 @@ void NativeDnsResolver::StartResolvingLocked() {
class NativeDnsResolverFactory : public ResolverFactory {
public:
OrphanablePtr<Resolver> CreateResolver(ResolverArgs args) const override {
if (GPR_UNLIKELY(0 != strcmp(args.uri->authority, ""))) {
bool IsValidUri(const grpc_uri* uri) const override {
if (GPR_UNLIKELY(0 != strcmp(uri->authority, ""))) {
gpr_log(GPR_ERROR, "authority based dns uri's not supported");
return OrphanablePtr<Resolver>(nullptr);
return false;
}
return true;
}
OrphanablePtr<Resolver> CreateResolver(ResolverArgs args) const override {
if (!IsValidUri(args.uri)) return nullptr;
return OrphanablePtr<Resolver>(New<NativeDnsResolver>(std::move(args)));
}

@ -32,7 +32,6 @@
#include "src/core/ext/filters/client_channel/resolver_registry.h"
#include "src/core/ext/filters/client_channel/server_address.h"
#include "src/core/lib/channel/channel_args.h"
#include "src/core/lib/gpr/host_port.h"
#include "src/core/lib/gpr/string.h"
#include "src/core/lib/gpr/useful.h"
#include "src/core/lib/iomgr/closure.h"
@ -90,9 +89,15 @@ FakeResolver::FakeResolver(ResolverArgs args)
: Resolver(args.combiner, std::move(args.result_handler)) {
GRPC_CLOSURE_INIT(&reresolution_closure_, ReturnReresolutionResult, this,
grpc_combiner_scheduler(combiner()));
channel_args_ = grpc_channel_args_copy(args.args);
FakeResolverResponseGenerator* response_generator =
FakeResolverResponseGenerator::GetFromArgs(args.args);
// Channels sharing the same subchannels may have different resolver response
// generators. If we don't remove this arg, subchannel pool will create new
// subchannels for the same address instead of reusing existing ones because
// of different values of this channel arg.
const char* args_to_remove[] = {GRPC_ARG_FAKE_RESOLVER_RESPONSE_GENERATOR};
channel_args_ = grpc_channel_args_copy_and_remove(
args.args, args_to_remove, GPR_ARRAY_SIZE(args_to_remove));
if (response_generator != nullptr) {
response_generator->resolver_ = this;
if (response_generator->has_result_) {
@ -191,7 +196,6 @@ void FakeResolverResponseGenerator::SetResponse(Resolver::Result result) {
grpc_combiner_scheduler(resolver_->combiner())),
GRPC_ERROR_NONE);
} else {
GPR_ASSERT(!has_result_);
has_result_ = true;
result_ = std::move(result);
}
@ -316,6 +320,8 @@ namespace {
class FakeResolverFactory : public ResolverFactory {
public:
bool IsValidUri(const grpc_uri* uri) const override { return true; }
OrphanablePtr<Resolver> CreateResolver(ResolverArgs args) const override {
return OrphanablePtr<Resolver>(New<FakeResolver>(std::move(args)));
}

@ -30,7 +30,6 @@
#include "src/core/ext/filters/client_channel/resolver_registry.h"
#include "src/core/ext/filters/client_channel/server_address.h"
#include "src/core/lib/channel/channel_args.h"
#include "src/core/lib/gpr/host_port.h"
#include "src/core/lib/gpr/string.h"
#include "src/core/lib/iomgr/combiner.h"
#include "src/core/lib/iomgr/resolve_address.h"
@ -81,24 +80,23 @@ void SockaddrResolver::StartLocked() {
void DoNothing(void* ignored) {}
OrphanablePtr<Resolver> CreateSockaddrResolver(
ResolverArgs args,
bool parse(const grpc_uri* uri, grpc_resolved_address* dst)) {
if (0 != strcmp(args.uri->authority, "")) {
bool ParseUri(const grpc_uri* uri,
bool parse(const grpc_uri* uri, grpc_resolved_address* dst),
ServerAddressList* addresses) {
if (0 != strcmp(uri->authority, "")) {
gpr_log(GPR_ERROR, "authority-based URIs not supported by the %s scheme",
args.uri->scheme);
return nullptr;
uri->scheme);
return false;
}
// Construct addresses.
grpc_slice path_slice =
grpc_slice_new(args.uri->path, strlen(args.uri->path), DoNothing);
grpc_slice_new(uri->path, strlen(uri->path), DoNothing);
grpc_slice_buffer path_parts;
grpc_slice_buffer_init(&path_parts);
grpc_slice_split(path_slice, ",", &path_parts);
ServerAddressList addresses;
bool errors_found = false;
for (size_t i = 0; i < path_parts.count; i++) {
grpc_uri ith_uri = *args.uri;
grpc_uri ith_uri = *uri;
UniquePtr<char> part_str(grpc_slice_to_c_string(path_parts.slices[i]));
ith_uri.path = part_str.get();
grpc_resolved_address addr;
@ -106,13 +104,20 @@ OrphanablePtr<Resolver> CreateSockaddrResolver(
errors_found = true;
break;
}
addresses.emplace_back(addr, nullptr /* args */);
if (addresses != nullptr) {
addresses->emplace_back(addr, nullptr /* args */);
}
}
grpc_slice_buffer_destroy_internal(&path_parts);
grpc_slice_unref_internal(path_slice);
if (errors_found) {
return OrphanablePtr<Resolver>(nullptr);
}
return !errors_found;
}
OrphanablePtr<Resolver> CreateSockaddrResolver(
ResolverArgs args,
bool parse(const grpc_uri* uri, grpc_resolved_address* dst)) {
ServerAddressList addresses;
if (!ParseUri(args.uri, parse, &addresses)) return nullptr;
// Instantiate resolver.
return OrphanablePtr<Resolver>(
New<SockaddrResolver>(std::move(addresses), std::move(args)));
@ -120,6 +125,10 @@ OrphanablePtr<Resolver> CreateSockaddrResolver(
class IPv4ResolverFactory : public ResolverFactory {
public:
bool IsValidUri(const grpc_uri* uri) const override {
return ParseUri(uri, grpc_parse_ipv4, nullptr);
}
OrphanablePtr<Resolver> CreateResolver(ResolverArgs args) const override {
return CreateSockaddrResolver(std::move(args), grpc_parse_ipv4);
}
@ -129,6 +138,10 @@ class IPv4ResolverFactory : public ResolverFactory {
class IPv6ResolverFactory : public ResolverFactory {
public:
bool IsValidUri(const grpc_uri* uri) const override {
return ParseUri(uri, grpc_parse_ipv6, nullptr);
}
OrphanablePtr<Resolver> CreateResolver(ResolverArgs args) const override {
return CreateSockaddrResolver(std::move(args), grpc_parse_ipv6);
}
@ -139,6 +152,10 @@ class IPv6ResolverFactory : public ResolverFactory {
#ifdef GRPC_HAVE_UNIX_SOCKET
class UnixResolverFactory : public ResolverFactory {
public:
bool IsValidUri(const grpc_uri* uri) const override {
return ParseUri(uri, grpc_parse_unix, nullptr);
}
OrphanablePtr<Resolver> CreateResolver(ResolverArgs args) const override {
return CreateSockaddrResolver(std::move(args), grpc_parse_unix);
}

@ -47,6 +47,10 @@ struct ResolverArgs {
class ResolverFactory {
public:
/// Returns a bool indicating whether the input uri is valid to create a
/// resolver.
virtual bool IsValidUri(const grpc_uri* uri) const GRPC_ABSTRACT;
/// Returns a new resolver instance.
virtual OrphanablePtr<Resolver> CreateResolver(ResolverArgs args) const
GRPC_ABSTRACT;

@ -132,6 +132,17 @@ ResolverFactory* ResolverRegistry::LookupResolverFactory(const char* scheme) {
return g_state->LookupResolverFactory(scheme);
}
bool ResolverRegistry::IsValidTarget(const char* target) {
grpc_uri* uri = nullptr;
char* canonical_target = nullptr;
ResolverFactory* factory =
g_state->FindResolverFactory(target, &uri, &canonical_target);
bool result = factory == nullptr ? false : factory->IsValidUri(uri);
grpc_uri_destroy(uri);
gpr_free(canonical_target);
return result;
}
OrphanablePtr<Resolver> ResolverRegistry::CreateResolver(
const char* target, const grpc_channel_args* args,
grpc_pollset_set* pollset_set, grpc_combiner* combiner,

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

Loading…
Cancel
Save