Merge branch 'master' into callback-rpc-lock

pull/18813/head
Karthik Ravi Shankar 6 years ago
commit 3f05ac9584
  1. 18
      BUILD
  2. 4
      BUILD.gn
  3. 10
      CMakeLists.txt
  4. 10
      Makefile
  5. 11
      build.yaml
  6. 2
      config.m4
  7. 1
      config.w32
  8. 7
      doc/health-checking.md
  9. 7
      gRPC-C++.podspec
  10. 3
      gRPC-Core.podspec
  11. 2
      grpc.gemspec
  12. 2
      grpc.gyp
  13. 85
      include/grpcpp/channel.h
  14. 125
      include/grpcpp/channel_impl.h
  15. 1
      include/grpcpp/create_channel_impl.h
  16. 2
      include/grpcpp/generic/generic_stub_impl.h
  17. 2
      include/grpcpp/impl/codegen/async_stream.h
  18. 1
      include/grpcpp/impl/codegen/async_unary_call.h
  19. 14
      include/grpcpp/impl/codegen/call.h
  20. 1
      include/grpcpp/impl/codegen/call_op_set.h
  21. 16
      include/grpcpp/impl/codegen/channel_interface.h
  22. 6
      include/grpcpp/impl/codegen/client_callback.h
  23. 11
      include/grpcpp/impl/codegen/client_context.h
  24. 6
      include/grpcpp/impl/codegen/client_interceptor.h
  25. 2
      include/grpcpp/impl/codegen/client_unary_call.h
  26. 392
      include/grpcpp/impl/codegen/completion_queue.h
  27. 422
      include/grpcpp/impl/codegen/completion_queue_impl.h
  28. 3
      include/grpcpp/impl/codegen/config_protobuf.h
  29. 13
      include/grpcpp/impl/codegen/intercepted_channel.h
  30. 54
      include/grpcpp/impl/codegen/message_allocator.h
  31. 17
      include/grpcpp/impl/codegen/proto_utils.h
  32. 101
      include/grpcpp/impl/codegen/server_callback.h
  33. 5
      include/grpcpp/impl/codegen/server_context.h
  34. 71
      include/grpcpp/impl/codegen/server_interface.h
  35. 3
      include/grpcpp/impl/codegen/service_type.h
  36. 1
      include/grpcpp/security/credentials_impl.h
  37. 7
      include/grpcpp/server_builder.h
  38. 9
      include/grpcpp/server_builder_impl.h
  39. 5
      include/grpcpp/server_impl.h
  40. 2
      package.xml
  41. 4
      src/android/test/interop/app/src/main/cpp/grpc-interop.cc
  42. 6
      src/compiler/cpp_generator.cc
  43. 11
      src/core/ext/filters/client_channel/backup_poller.cc
  44. 1
      src/core/ext/filters/client_channel/http_connect_handshaker.cc
  45. 13
      src/core/ext/filters/client_channel/lb_policy/xds/xds.cc
  46. 14
      src/core/ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.cc
  47. 28
      src/core/ext/filters/client_channel/resolver/dns/dns_resolver_selection.cc
  48. 29
      src/core/ext/filters/client_channel/resolver/dns/dns_resolver_selection.h
  49. 8
      src/core/ext/filters/client_channel/resolver/dns/native/dns_resolver.cc
  50. 7
      src/core/ext/transport/chttp2/transport/chttp2_plugin.cc
  51. 2
      src/core/ext/transport/chttp2/transport/chttp2_transport.cc
  52. 2
      src/core/ext/transport/chttp2/transport/internal.h
  53. 20
      src/core/lib/debug/trace.cc
  54. 8
      src/core/lib/debug/trace.h
  55. 6
      src/core/lib/gpr/env.h
  56. 2
      src/core/lib/gpr/env_linux.cc
  57. 5
      src/core/lib/gpr/env_windows.cc
  58. 22
      src/core/lib/gpr/log.cc
  59. 41
      src/core/lib/gprpp/fork.cc
  60. 26
      src/core/lib/iomgr/ev_posix.cc
  61. 3
      src/core/lib/iomgr/ev_posix.h
  62. 1
      src/core/lib/iomgr/fork_posix.cc
  63. 3
      src/core/lib/iomgr/iomgr.cc
  64. 14
      src/core/lib/profiling/basic_timers.cc
  65. 12
      src/core/lib/security/security_connector/load_system_roots_linux.cc
  66. 1
      src/core/lib/security/security_connector/security_connector.cc
  67. 44
      src/core/lib/security/security_connector/ssl_utils.cc
  68. 6
      src/core/lib/security/security_connector/ssl_utils.h
  69. 2
      src/core/lib/surface/init.cc
  70. 55
      src/cpp/client/channel_cc.cc
  71. 9
      src/cpp/client/client_context.cc
  72. 2
      src/cpp/client/create_channel.cc
  73. 4
      src/cpp/client/create_channel_internal.cc
  74. 4
      src/cpp/client/create_channel_internal.h
  75. 6
      src/cpp/client/create_channel_posix.cc
  76. 2
      src/cpp/client/secure_credentials.h
  77. 1
      src/cpp/common/channel_filter.cc
  78. 12
      src/cpp/common/completion_queue_cc.cc
  79. 3
      src/objective-c/GRPCClient/private/GRPCSecureChannelFactory.m
  80. 4
      src/objective-c/tests/CoreCronetEnd2EndTests/CoreCronetEnd2EndTests.mm
  81. 7
      src/php/ext/grpc/channel.c
  82. 6
      src/python/grpcio/grpc/_channel.py
  83. 1
      src/python/grpcio/grpc_core_dependencies.py
  84. 4
      templates/gRPC-C++.podspec.template
  85. 1
      test/core/bad_connection/close_fd_test.cc
  86. 4
      test/core/bad_ssl/bad_ssl_test.cc
  87. 8
      test/core/client_channel/resolvers/dns_resolver_test.cc
  88. 4
      test/core/end2end/fixtures/h2_full+trace.cc
  89. 5
      test/core/end2end/fixtures/h2_sockpair+trace.cc
  90. 3
      test/core/end2end/fixtures/h2_spiffe.cc
  91. 4
      test/core/end2end/fixtures/h2_ssl.cc
  92. 4
      test/core/end2end/fixtures/h2_ssl_cred_reload.cc
  93. 4
      test/core/end2end/fixtures/h2_ssl_proxy.cc
  94. 4
      test/core/end2end/h2_ssl_cert_test.cc
  95. 4
      test/core/end2end/h2_ssl_session_reuse_test.cc
  96. 14
      test/core/end2end/tests/keepalive_timeout.cc
  97. 13
      test/core/gpr/log_test.cc
  98. 3
      test/core/http/httpscli_test.cc
  99. 18
      test/core/iomgr/resolve_address_posix_test.cc
  100. 13
      test/core/iomgr/resolve_address_test.cc
  101. Some files were not shown because too many files have changed in this diff Show More

18
BUILD

@ -218,6 +218,7 @@ GRPCXX_PUBLIC_HDRS = [
"include/grpcpp/alarm.h",
"include/grpcpp/alarm_impl.h",
"include/grpcpp/channel.h",
"include/grpcpp/channel_impl.h",
"include/grpcpp/client_context.h",
"include/grpcpp/completion_queue.h",
"include/grpcpp/create_channel.h",
@ -1563,6 +1564,20 @@ grpc_cc_library(
],
)
grpc_cc_library(
name = "grpc_resolver_dns_selection",
srcs = [
"src/core/ext/filters/client_channel/resolver/dns/dns_resolver_selection.cc",
],
hdrs = [
"src/core/ext/filters/client_channel/resolver/dns/dns_resolver_selection.h",
],
language = "c++",
deps = [
"grpc_base",
],
)
grpc_cc_library(
name = "grpc_resolver_dns_native",
srcs = [
@ -1572,6 +1587,7 @@ grpc_cc_library(
deps = [
"grpc_base",
"grpc_client_channel",
"grpc_resolver_dns_selection",
],
)
@ -1601,6 +1617,7 @@ grpc_cc_library(
deps = [
"grpc_base",
"grpc_client_channel",
"grpc_resolver_dns_selection",
],
)
@ -2147,6 +2164,7 @@ grpc_cc_library(
"include/grpcpp/impl/codegen/client_interceptor.h",
"include/grpcpp/impl/codegen/client_unary_call.h",
"include/grpcpp/impl/codegen/completion_queue.h",
"include/grpcpp/impl/codegen/completion_queue_impl.h",
"include/grpcpp/impl/codegen/completion_queue_tag.h",
"include/grpcpp/impl/codegen/config.h",
"include/grpcpp/impl/codegen/core_codegen_interface.h",

@ -324,6 +324,8 @@ config("grpc_config") {
"src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv.cc",
"src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_posix.cc",
"src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_windows.cc",
"src/core/ext/filters/client_channel/resolver/dns/dns_resolver_selection.cc",
"src/core/ext/filters/client_channel/resolver/dns/dns_resolver_selection.h",
"src/core/ext/filters/client_channel/resolver/dns/native/dns_resolver.cc",
"src/core/ext/filters/client_channel/resolver/fake/fake_resolver.cc",
"src/core/ext/filters/client_channel/resolver/fake/fake_resolver.h",
@ -1022,6 +1024,7 @@ config("grpc_config") {
"include/grpcpp/alarm.h",
"include/grpcpp/alarm_impl.h",
"include/grpcpp/channel.h",
"include/grpcpp/channel_impl.h",
"include/grpcpp/client_context.h",
"include/grpcpp/completion_queue.h",
"include/grpcpp/create_channel.h",
@ -1053,6 +1056,7 @@ config("grpc_config") {
"include/grpcpp/impl/codegen/client_interceptor.h",
"include/grpcpp/impl/codegen/client_unary_call.h",
"include/grpcpp/impl/codegen/completion_queue.h",
"include/grpcpp/impl/codegen/completion_queue_impl.h",
"include/grpcpp/impl/codegen/completion_queue_tag.h",
"include/grpcpp/impl/codegen/config.h",
"include/grpcpp/impl/codegen/config_protobuf.h",

@ -1308,6 +1308,7 @@ add_library(grpc
src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv.cc
src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_posix.cc
src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_windows.cc
src/core/ext/filters/client_channel/resolver/dns/dns_resolver_selection.cc
src/core/ext/filters/client_channel/resolver/dns/native/dns_resolver.cc
src/core/ext/filters/client_channel/resolver/sockaddr/sockaddr_resolver.cc
src/core/ext/filters/census/grpc_context.cc
@ -2703,6 +2704,7 @@ add_library(grpc_unsecure
src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv.cc
src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_posix.cc
src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_windows.cc
src/core/ext/filters/client_channel/resolver/dns/dns_resolver_selection.cc
src/core/ext/filters/client_channel/resolver/dns/native/dns_resolver.cc
src/core/ext/filters/client_channel/resolver/sockaddr/sockaddr_resolver.cc
src/core/ext/filters/client_channel/resolver/fake/fake_resolver.cc
@ -3150,6 +3152,7 @@ foreach(_hdr
include/grpcpp/alarm.h
include/grpcpp/alarm_impl.h
include/grpcpp/channel.h
include/grpcpp/channel_impl.h
include/grpcpp/client_context.h
include/grpcpp/completion_queue.h
include/grpcpp/create_channel.h
@ -3311,6 +3314,7 @@ foreach(_hdr
include/grpcpp/impl/codegen/client_interceptor.h
include/grpcpp/impl/codegen/client_unary_call.h
include/grpcpp/impl/codegen/completion_queue.h
include/grpcpp/impl/codegen/completion_queue_impl.h
include/grpcpp/impl/codegen/completion_queue_tag.h
include/grpcpp/impl/codegen/config.h
include/grpcpp/impl/codegen/core_codegen_interface.h
@ -3765,6 +3769,7 @@ foreach(_hdr
include/grpcpp/alarm.h
include/grpcpp/alarm_impl.h
include/grpcpp/channel.h
include/grpcpp/channel_impl.h
include/grpcpp/client_context.h
include/grpcpp/completion_queue.h
include/grpcpp/create_channel.h
@ -3926,6 +3931,7 @@ foreach(_hdr
include/grpcpp/impl/codegen/client_interceptor.h
include/grpcpp/impl/codegen/client_unary_call.h
include/grpcpp/impl/codegen/completion_queue.h
include/grpcpp/impl/codegen/completion_queue_impl.h
include/grpcpp/impl/codegen/completion_queue_tag.h
include/grpcpp/impl/codegen/config.h
include/grpcpp/impl/codegen/core_codegen_interface.h
@ -4360,6 +4366,7 @@ foreach(_hdr
include/grpcpp/impl/codegen/client_interceptor.h
include/grpcpp/impl/codegen/client_unary_call.h
include/grpcpp/impl/codegen/completion_queue.h
include/grpcpp/impl/codegen/completion_queue_impl.h
include/grpcpp/impl/codegen/completion_queue_tag.h
include/grpcpp/impl/codegen/config.h
include/grpcpp/impl/codegen/core_codegen_interface.h
@ -4558,6 +4565,7 @@ foreach(_hdr
include/grpcpp/impl/codegen/client_interceptor.h
include/grpcpp/impl/codegen/client_unary_call.h
include/grpcpp/impl/codegen/completion_queue.h
include/grpcpp/impl/codegen/completion_queue_impl.h
include/grpcpp/impl/codegen/completion_queue_tag.h
include/grpcpp/impl/codegen/config.h
include/grpcpp/impl/codegen/core_codegen_interface.h
@ -4752,6 +4760,7 @@ foreach(_hdr
include/grpcpp/alarm.h
include/grpcpp/alarm_impl.h
include/grpcpp/channel.h
include/grpcpp/channel_impl.h
include/grpcpp/client_context.h
include/grpcpp/completion_queue.h
include/grpcpp/create_channel.h
@ -4913,6 +4922,7 @@ foreach(_hdr
include/grpcpp/impl/codegen/client_interceptor.h
include/grpcpp/impl/codegen/client_unary_call.h
include/grpcpp/impl/codegen/completion_queue.h
include/grpcpp/impl/codegen/completion_queue_impl.h
include/grpcpp/impl/codegen/completion_queue_tag.h
include/grpcpp/impl/codegen/config.h
include/grpcpp/impl/codegen/core_codegen_interface.h

@ -3788,6 +3788,7 @@ LIBGRPC_SRC = \
src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv.cc \
src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_posix.cc \
src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_windows.cc \
src/core/ext/filters/client_channel/resolver/dns/dns_resolver_selection.cc \
src/core/ext/filters/client_channel/resolver/dns/native/dns_resolver.cc \
src/core/ext/filters/client_channel/resolver/sockaddr/sockaddr_resolver.cc \
src/core/ext/filters/census/grpc_context.cc \
@ -5131,6 +5132,7 @@ LIBGRPC_UNSECURE_SRC = \
src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv.cc \
src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_posix.cc \
src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_windows.cc \
src/core/ext/filters/client_channel/resolver/dns/dns_resolver_selection.cc \
src/core/ext/filters/client_channel/resolver/dns/native/dns_resolver.cc \
src/core/ext/filters/client_channel/resolver/sockaddr/sockaddr_resolver.cc \
src/core/ext/filters/client_channel/resolver/fake/fake_resolver.cc \
@ -5507,6 +5509,7 @@ PUBLIC_HEADERS_CXX += \
include/grpcpp/alarm.h \
include/grpcpp/alarm_impl.h \
include/grpcpp/channel.h \
include/grpcpp/channel_impl.h \
include/grpcpp/client_context.h \
include/grpcpp/completion_queue.h \
include/grpcpp/create_channel.h \
@ -5668,6 +5671,7 @@ PUBLIC_HEADERS_CXX += \
include/grpcpp/impl/codegen/client_interceptor.h \
include/grpcpp/impl/codegen/client_unary_call.h \
include/grpcpp/impl/codegen/completion_queue.h \
include/grpcpp/impl/codegen/completion_queue_impl.h \
include/grpcpp/impl/codegen/completion_queue_tag.h \
include/grpcpp/impl/codegen/config.h \
include/grpcpp/impl/codegen/core_codegen_interface.h \
@ -6130,6 +6134,7 @@ PUBLIC_HEADERS_CXX += \
include/grpcpp/alarm.h \
include/grpcpp/alarm_impl.h \
include/grpcpp/channel.h \
include/grpcpp/channel_impl.h \
include/grpcpp/client_context.h \
include/grpcpp/completion_queue.h \
include/grpcpp/create_channel.h \
@ -6291,6 +6296,7 @@ PUBLIC_HEADERS_CXX += \
include/grpcpp/impl/codegen/client_interceptor.h \
include/grpcpp/impl/codegen/client_unary_call.h \
include/grpcpp/impl/codegen/completion_queue.h \
include/grpcpp/impl/codegen/completion_queue_impl.h \
include/grpcpp/impl/codegen/completion_queue_tag.h \
include/grpcpp/impl/codegen/config.h \
include/grpcpp/impl/codegen/core_codegen_interface.h \
@ -6697,6 +6703,7 @@ PUBLIC_HEADERS_CXX += \
include/grpcpp/impl/codegen/client_interceptor.h \
include/grpcpp/impl/codegen/client_unary_call.h \
include/grpcpp/impl/codegen/completion_queue.h \
include/grpcpp/impl/codegen/completion_queue_impl.h \
include/grpcpp/impl/codegen/completion_queue_tag.h \
include/grpcpp/impl/codegen/config.h \
include/grpcpp/impl/codegen/core_codegen_interface.h \
@ -6866,6 +6873,7 @@ PUBLIC_HEADERS_CXX += \
include/grpcpp/impl/codegen/client_interceptor.h \
include/grpcpp/impl/codegen/client_unary_call.h \
include/grpcpp/impl/codegen/completion_queue.h \
include/grpcpp/impl/codegen/completion_queue_impl.h \
include/grpcpp/impl/codegen/completion_queue_tag.h \
include/grpcpp/impl/codegen/config.h \
include/grpcpp/impl/codegen/core_codegen_interface.h \
@ -7066,6 +7074,7 @@ PUBLIC_HEADERS_CXX += \
include/grpcpp/alarm.h \
include/grpcpp/alarm_impl.h \
include/grpcpp/channel.h \
include/grpcpp/channel_impl.h \
include/grpcpp/client_context.h \
include/grpcpp/completion_queue.h \
include/grpcpp/create_channel.h \
@ -7227,6 +7236,7 @@ PUBLIC_HEADERS_CXX += \
include/grpcpp/impl/codegen/client_interceptor.h \
include/grpcpp/impl/codegen/client_unary_call.h \
include/grpcpp/impl/codegen/completion_queue.h \
include/grpcpp/impl/codegen/completion_queue_impl.h \
include/grpcpp/impl/codegen/completion_queue_tag.h \
include/grpcpp/impl/codegen/config.h \
include/grpcpp/impl/codegen/core_codegen_interface.h \

@ -796,6 +796,7 @@ filegroups:
uses:
- grpc_base
- grpc_client_channel
- grpc_resolver_dns_selection
- name: grpc_resolver_dns_native
src:
- src/core/ext/filters/client_channel/resolver/dns/native/dns_resolver.cc
@ -803,6 +804,14 @@ filegroups:
uses:
- grpc_base
- grpc_client_channel
- grpc_resolver_dns_selection
- name: grpc_resolver_dns_selection
headers:
- src/core/ext/filters/client_channel/resolver/dns/dns_resolver_selection.h
src:
- src/core/ext/filters/client_channel/resolver/dns/dns_resolver_selection.cc
uses:
- grpc_base
- name: grpc_resolver_fake
headers:
- src/core/ext/filters/client_channel/resolver/fake/fake_resolver.h
@ -1253,6 +1262,7 @@ filegroups:
- include/grpcpp/impl/codegen/client_interceptor.h
- include/grpcpp/impl/codegen/client_unary_call.h
- include/grpcpp/impl/codegen/completion_queue.h
- include/grpcpp/impl/codegen/completion_queue_impl.h
- include/grpcpp/impl/codegen/completion_queue_tag.h
- include/grpcpp/impl/codegen/config.h
- include/grpcpp/impl/codegen/core_codegen_interface.h
@ -1350,6 +1360,7 @@ filegroups:
- include/grpcpp/alarm.h
- include/grpcpp/alarm_impl.h
- include/grpcpp/channel.h
- include/grpcpp/channel_impl.h
- include/grpcpp/client_context.h
- include/grpcpp/completion_queue.h
- include/grpcpp/create_channel.h

@ -411,6 +411,7 @@ if test "$PHP_GRPC" != "no"; then
src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv.cc \
src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_posix.cc \
src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_windows.cc \
src/core/ext/filters/client_channel/resolver/dns/dns_resolver_selection.cc \
src/core/ext/filters/client_channel/resolver/dns/native/dns_resolver.cc \
src/core/ext/filters/client_channel/resolver/sockaddr/sockaddr_resolver.cc \
src/core/ext/filters/census/grpc_context.cc \
@ -694,6 +695,7 @@ if test "$PHP_GRPC" != "no"; then
PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/filters/client_channel/lb_policy/pick_first)
PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/filters/client_channel/lb_policy/round_robin)
PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/filters/client_channel/lb_policy/xds)
PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/filters/client_channel/resolver/dns)
PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/filters/client_channel/resolver/dns/c_ares)
PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/filters/client_channel/resolver/dns/native)
PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/filters/client_channel/resolver/fake)

@ -386,6 +386,7 @@ if (PHP_GRPC != "no") {
"src\\core\\ext\\filters\\client_channel\\resolver\\dns\\c_ares\\grpc_ares_wrapper_libuv.cc " +
"src\\core\\ext\\filters\\client_channel\\resolver\\dns\\c_ares\\grpc_ares_wrapper_posix.cc " +
"src\\core\\ext\\filters\\client_channel\\resolver\\dns\\c_ares\\grpc_ares_wrapper_windows.cc " +
"src\\core\\ext\\filters\\client_channel\\resolver\\dns\\dns_resolver_selection.cc " +
"src\\core\\ext\\filters\\client_channel\\resolver\\dns\\native\\dns_resolver.cc " +
"src\\core\\ext\\filters\\client_channel\\resolver\\sockaddr\\sockaddr_resolver.cc " +
"src\\core\\ext\\filters\\census\\grpc_context.cc " +

@ -43,6 +43,8 @@ message HealthCheckResponse {
service Health {
rpc Check(HealthCheckRequest) returns (HealthCheckResponse);
rpc Watch(HealthCheckRequest) returns (stream HealthCheckResponse);
}
```
@ -68,3 +70,8 @@ matching semantics that both the client and server agree upon.
A client can declare the server as unhealthy if the rpc is not finished after
some amount of time. The client should be able to handle the case where server
does not have the Health service.
A client can call the `Watch` method to perform a streaming health-check.
The server will immediately send back a message indicating the current
serving status. It will then subsequently send a new message whenever
the service's serving status changes.

@ -24,7 +24,7 @@ Pod::Spec.new do |s|
s.name = 'gRPC-C++'
# TODO (mxyan): use version that match gRPC version when pod is stabilized
# version = '1.22.0-dev'
version = '0.0.8-dev'
version = '0.0.9-dev'
s.version = version
s.summary = 'gRPC C++ library'
s.homepage = 'https://grpc.io'
@ -72,7 +72,7 @@ Pod::Spec.new do |s|
s.default_subspecs = 'Interface', 'Implementation'
# Certificates, to be able to establish TLS connections:
s.resource_bundles = { 'gRPCCertificates' => ['etc/roots.pem'] }
s.resource_bundles = { 'gRPCCertificates-Cpp' => ['etc/roots.pem'] }
s.header_mappings_dir = 'include/grpcpp'
@ -82,6 +82,7 @@ Pod::Spec.new do |s|
ss.source_files = 'include/grpcpp/alarm.h',
'include/grpcpp/alarm_impl.h',
'include/grpcpp/channel.h',
'include/grpcpp/channel_impl.h',
'include/grpcpp/client_context.h',
'include/grpcpp/completion_queue.h',
'include/grpcpp/create_channel.h',
@ -162,6 +163,7 @@ Pod::Spec.new do |s|
'include/grpcpp/impl/codegen/client_interceptor.h',
'include/grpcpp/impl/codegen/client_unary_call.h',
'include/grpcpp/impl/codegen/completion_queue.h',
'include/grpcpp/impl/codegen/completion_queue_impl.h',
'include/grpcpp/impl/codegen/completion_queue_tag.h',
'include/grpcpp/impl/codegen/config.h',
'include/grpcpp/impl/codegen/core_codegen_interface.h',
@ -563,6 +565,7 @@ Pod::Spec.new do |s|
'src/core/ext/filters/client_channel/lb_policy/subchannel_list.h',
'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver.h',
'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.h',
'src/core/ext/filters/client_channel/resolver/dns/dns_resolver_selection.h',
'src/core/ext/filters/max_age/max_age_filter.h',
'src/core/ext/filters/message_size/message_size_filter.h',
'src/core/ext/filters/http/client_authority_filter.h',

@ -539,6 +539,7 @@ Pod::Spec.new do |s|
'src/core/ext/filters/client_channel/lb_policy/subchannel_list.h',
'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver.h',
'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.h',
'src/core/ext/filters/client_channel/resolver/dns/dns_resolver_selection.h',
'src/core/ext/filters/max_age/max_age_filter.h',
'src/core/ext/filters/message_size/message_size_filter.h',
'src/core/ext/filters/http/client_authority_filter.h',
@ -868,6 +869,7 @@ Pod::Spec.new do |s|
'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv.cc',
'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_posix.cc',
'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_windows.cc',
'src/core/ext/filters/client_channel/resolver/dns/dns_resolver_selection.cc',
'src/core/ext/filters/client_channel/resolver/dns/native/dns_resolver.cc',
'src/core/ext/filters/client_channel/resolver/sockaddr/sockaddr_resolver.cc',
'src/core/ext/filters/census/grpc_context.cc',
@ -1189,6 +1191,7 @@ Pod::Spec.new do |s|
'src/core/ext/filters/client_channel/lb_policy/subchannel_list.h',
'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver.h',
'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.h',
'src/core/ext/filters/client_channel/resolver/dns/dns_resolver_selection.h',
'src/core/ext/filters/max_age/max_age_filter.h',
'src/core/ext/filters/message_size/message_size_filter.h',
'src/core/ext/filters/http/client_authority_filter.h',

@ -473,6 +473,7 @@ Gem::Specification.new do |s|
s.files += %w( src/core/ext/filters/client_channel/lb_policy/subchannel_list.h )
s.files += %w( src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver.h )
s.files += %w( src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.h )
s.files += %w( src/core/ext/filters/client_channel/resolver/dns/dns_resolver_selection.h )
s.files += %w( src/core/ext/filters/max_age/max_age_filter.h )
s.files += %w( src/core/ext/filters/message_size/message_size_filter.h )
s.files += %w( src/core/ext/filters/http/client_authority_filter.h )
@ -805,6 +806,7 @@ Gem::Specification.new do |s|
s.files += %w( src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv.cc )
s.files += %w( src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_posix.cc )
s.files += %w( src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_windows.cc )
s.files += %w( src/core/ext/filters/client_channel/resolver/dns/dns_resolver_selection.cc )
s.files += %w( src/core/ext/filters/client_channel/resolver/dns/native/dns_resolver.cc )
s.files += %w( src/core/ext/filters/client_channel/resolver/sockaddr/sockaddr_resolver.cc )
s.files += %w( src/core/ext/filters/census/grpc_context.cc )

@ -593,6 +593,7 @@
'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv.cc',
'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_posix.cc',
'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_windows.cc',
'src/core/ext/filters/client_channel/resolver/dns/dns_resolver_selection.cc',
'src/core/ext/filters/client_channel/resolver/dns/native/dns_resolver.cc',
'src/core/ext/filters/client_channel/resolver/sockaddr/sockaddr_resolver.cc',
'src/core/ext/filters/census/grpc_context.cc',
@ -1352,6 +1353,7 @@
'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv.cc',
'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_posix.cc',
'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_windows.cc',
'src/core/ext/filters/client_channel/resolver/dns/dns_resolver_selection.cc',
'src/core/ext/filters/client_channel/resolver/dns/native/dns_resolver.cc',
'src/core/ext/filters/client_channel/resolver/sockaddr/sockaddr_resolver.cc',
'src/core/ext/filters/client_channel/resolver/fake/fake_resolver.cc',

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

@ -0,0 +1,125 @@
/*
*
* Copyright 2015 gRPC authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
#ifndef GRPCPP_CHANNEL_IMPL_H
#define GRPCPP_CHANNEL_IMPL_H
#include <memory>
#include <mutex>
#include <grpc/grpc.h>
#include <grpcpp/impl/call.h>
#include <grpcpp/impl/codegen/channel_interface.h>
#include <grpcpp/impl/codegen/client_interceptor.h>
#include <grpcpp/impl/codegen/completion_queue.h>
#include <grpcpp/impl/codegen/config.h>
#include <grpcpp/impl/codegen/grpc_library.h>
#include <grpcpp/impl/codegen/sync.h>
struct grpc_channel;
namespace grpc {
std::shared_ptr<::grpc_impl::Channel> CreateChannelInternal(
const grpc::string& host, grpc_channel* c_channel,
std::vector<
std::unique_ptr<experimental::ClientInterceptorFactoryInterface>>
interceptor_creators);
} // namespace grpc
namespace grpc_impl {
namespace experimental {
/// Resets the channel's connection backoff.
/// TODO(roth): Once we see whether this proves useful, either create a gRFC
/// and change this to be a method of the Channel class, or remove it.
void ChannelResetConnectionBackoff(Channel* channel);
} // namespace experimental
/// Channels represent a connection to an endpoint. Created by \a CreateChannel.
class Channel final : public ::grpc::ChannelInterface,
public ::grpc::internal::CallHook,
public std::enable_shared_from_this<Channel>,
private ::grpc::GrpcLibraryCodegen {
public:
~Channel();
/// Get the current channel state. If the channel is in IDLE and
/// \a try_to_connect is set to true, try to connect.
grpc_connectivity_state GetState(bool try_to_connect) override;
/// Returns the LB policy name, or the empty string if not yet available.
grpc::string GetLoadBalancingPolicyName() const;
/// Returns the service config in JSON form, or the empty string if
/// not available.
grpc::string GetServiceConfigJSON() const;
private:
template <class InputMessage, class OutputMessage>
friend class ::grpc::internal::BlockingUnaryCallImpl;
friend void experimental::ChannelResetConnectionBackoff(Channel* channel);
friend std::shared_ptr<Channel> grpc::CreateChannelInternal(
const grpc::string& host, grpc_channel* c_channel,
std::vector<std::unique_ptr<
::grpc::experimental::ClientInterceptorFactoryInterface>>
interceptor_creators);
friend class ::grpc::internal::InterceptedChannel;
Channel(const grpc::string& host, grpc_channel* c_channel,
std::vector<std::unique_ptr<
::grpc::experimental::ClientInterceptorFactoryInterface>>
interceptor_creators);
::grpc::internal::Call CreateCall(const ::grpc::internal::RpcMethod& method,
::grpc::ClientContext* context,
::grpc::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;
bool WaitForStateChangeImpl(grpc_connectivity_state last_observed,
gpr_timespec deadline) override;
::grpc::CompletionQueue* CallbackCQ() override;
::grpc::internal::Call CreateCallInternal(
const ::grpc::internal::RpcMethod& method, ::grpc::ClientContext* context,
::grpc::CompletionQueue* cq, size_t interceptor_pos) override;
const grpc::string host_;
grpc_channel* const c_channel_; // owned
// mu_ protects callback_cq_ (the per-channel callbackable completion queue)
grpc::internal::Mutex mu_;
// callback_cq_ references the callbackable completion queue associated
// with this channel (if any). It is set on the first call to CallbackCQ().
// It is _not owned_ by the channel; ownership belongs with its internal
// shutdown callback tag (invoked when the CQ is fully shutdown).
::grpc::CompletionQueue* callback_cq_ = nullptr;
std::vector<
std::unique_ptr<::grpc::experimental::ClientInterceptorFactoryInterface>>
interceptor_creators_;
};
} // namespace grpc_impl
#endif // GRPCPP_CHANNEL_IMPL_H

@ -28,7 +28,6 @@
#include <grpcpp/support/config.h>
namespace grpc_impl {
/// Create a new \a Channel pointing to \a target.
///
/// \param target The URI of the endpoint to connect to.

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

@ -28,8 +28,6 @@
namespace grpc {
class CompletionQueue;
namespace internal {
/// Common interface for all client side asynchronous streaming.
class ClientAsyncStreamingInterface {

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

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

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

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

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

@ -60,12 +60,12 @@ struct grpc_call;
namespace grpc_impl {
class CallCredentials;
class Channel;
class CompletionQueue;
} // namespace grpc_impl
namespace grpc {
class Channel;
class ChannelInterface;
class CompletionQueue;
class ClientContext;
namespace internal {
@ -397,7 +397,7 @@ class ClientContext {
friend class ::grpc::testing::InteropClientContextInspector;
friend class ::grpc::internal::CallOpClientRecvStatus;
friend class ::grpc::internal::CallOpRecvInitialMetadata;
friend class Channel;
friend class ::grpc_impl::Channel;
template <class R>
friend class ::grpc::ClientReader;
template <class W>
@ -430,7 +430,8 @@ class ClientContext {
}
grpc_call* call() const { return call_; }
void set_call(grpc_call* call, const std::shared_ptr<Channel>& channel);
void set_call(grpc_call* call,
const std::shared_ptr<::grpc_impl::Channel>& channel);
experimental::ClientRpcInfo* set_client_rpc_info(
const char* method, internal::RpcMethod::RpcType type,
@ -463,7 +464,7 @@ class ClientContext {
bool wait_for_ready_explicitly_set_;
bool idempotent_;
bool cacheable_;
std::shared_ptr<Channel> channel_;
std::shared_ptr<::grpc_impl::Channel> channel_;
grpc::internal::Mutex mu_;
grpc_call* call_;
bool call_canceled_;

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

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

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

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

@ -30,9 +30,11 @@
#ifdef GRPC_USE_PROTO_LITE
#include <google/protobuf/message_lite.h>
#define GRPC_CUSTOM_MESSAGE ::google::protobuf::MessageLite
#define GRPC_CUSTOM_MESSAGELITE ::google::protobuf::MessageLite
#else
#include <google/protobuf/message.h>
#define GRPC_CUSTOM_MESSAGE ::google::protobuf::Message
#define GRPC_CUSTOM_MESSAGELITE ::google::protobuf::MessageLite
#endif
#endif
@ -76,6 +78,7 @@ namespace grpc {
namespace protobuf {
typedef GRPC_CUSTOM_MESSAGE Message;
typedef GRPC_CUSTOM_MESSAGELITE MessageLite;
typedef GRPC_CUSTOM_PROTOBUF_INT64 int64;
typedef GRPC_CUSTOM_DESCRIPTOR Descriptor;

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

@ -22,31 +22,49 @@
namespace grpc {
namespace experimental {
// This is per rpc struct for the allocator. We can potentially put the grpc
// call arena in here in the future.
// NOTE: This is an API for advanced users who need custom allocators.
// Per rpc struct for the allocator. This is the interface to return to user.
class RpcAllocatorState {
public:
virtual ~RpcAllocatorState() = default;
// Optionally deallocate request early to reduce the size of working set.
// A custom MessageAllocator needs to be registered to make use of this.
// This is not abstract because implementing it is optional.
virtual void FreeRequest() {}
};
// This is the interface returned by the allocator.
// grpc library will call the methods to get request/response pointers and to
// release the object when it is done.
template <typename RequestT, typename ResponseT>
struct RpcAllocatorInfo {
RequestT* request;
ResponseT* response;
// per rpc allocator internal state. MessageAllocator can set it when
// AllocateMessages is called and use it later.
void* allocator_state;
class MessageHolder : public RpcAllocatorState {
public:
// Release this object. For example, if the custom allocator's
// AllocateMessasge creates an instance of a subclass with new, the Release()
// should do a "delete this;".
virtual void Release() = 0;
RequestT* request() { return request_; }
ResponseT* response() { return response_; }
protected:
void set_request(RequestT* request) { request_ = request; }
void set_response(ResponseT* response) { response_ = response; }
private:
// NOTE: subclasses should set these pointers.
RequestT* request_;
ResponseT* response_;
};
// Implementations need to be thread-safe
// A custom allocator can be set via the generated code to a callback unary
// method, such as SetMessageAllocatorFor_Echo(custom_allocator). The allocator
// needs to be alive for the lifetime of the server.
// Implementations need to be thread-safe.
template <typename RequestT, typename ResponseT>
class MessageAllocator {
public:
virtual ~MessageAllocator() = default;
// Allocate both request and response
virtual void AllocateMessages(
RpcAllocatorInfo<RequestT, ResponseT>* info) = 0;
// Optional: deallocate request early, called by
// ServerCallbackRpcController::ReleaseRequest
virtual void DeallocateRequest(RpcAllocatorInfo<RequestT, ResponseT>* info) {}
// Deallocate response and request (if applicable)
virtual void DeallocateMessages(
RpcAllocatorInfo<RequestT, ResponseT>* info) = 0;
virtual MessageHolder<RequestT, ResponseT>* AllocateMessages() = 0;
};
} // namespace experimental

@ -42,7 +42,7 @@ extern CoreCodegenInterface* g_core_codegen_interface;
// ProtoBufferWriter must be a subclass of ::protobuf::io::ZeroCopyOutputStream.
template <class ProtoBufferWriter, class T>
Status GenericSerialize(const grpc::protobuf::Message& msg, ByteBuffer* bb,
Status GenericSerialize(const grpc::protobuf::MessageLite& msg, ByteBuffer* bb,
bool* own_buffer) {
static_assert(std::is_base_of<protobuf::io::ZeroCopyOutputStream,
ProtoBufferWriter>::value,
@ -68,7 +68,8 @@ Status GenericSerialize(const grpc::protobuf::Message& msg, ByteBuffer* bb,
// BufferReader must be a subclass of ::protobuf::io::ZeroCopyInputStream.
template <class ProtoBufferReader, class T>
Status GenericDeserialize(ByteBuffer* buffer, grpc::protobuf::Message* msg) {
Status GenericDeserialize(ByteBuffer* buffer,
grpc::protobuf::MessageLite* msg) {
static_assert(std::is_base_of<protobuf::io::ZeroCopyInputStream,
ProtoBufferReader>::value,
"ProtoBufferReader must be a subclass of "
@ -102,15 +103,17 @@ Status GenericDeserialize(ByteBuffer* buffer, grpc::protobuf::Message* msg) {
// objects and grpc_byte_buffers. More information about SerializationTraits can
// be found in include/grpcpp/impl/codegen/serialization_traits.h.
template <class T>
class SerializationTraits<T, typename std::enable_if<std::is_base_of<
grpc::protobuf::Message, T>::value>::type> {
class SerializationTraits<
T, typename std::enable_if<
std::is_base_of<grpc::protobuf::MessageLite, T>::value>::type> {
public:
static Status Serialize(const grpc::protobuf::Message& msg, ByteBuffer* bb,
bool* own_buffer) {
static Status Serialize(const grpc::protobuf::MessageLite& msg,
ByteBuffer* bb, bool* own_buffer) {
return GenericSerialize<ProtoBufferWriter, T>(msg, bb, own_buffer);
}
static Status Deserialize(ByteBuffer* buffer, grpc::protobuf::Message* msg) {
static Status Deserialize(ByteBuffer* buffer,
grpc::protobuf::MessageLite* msg) {
return GenericDeserialize<ProtoBufferReader, T>(buffer, msg);
}
};

@ -77,6 +77,24 @@ class ServerReactor {
std::atomic_int on_cancel_conditions_remaining_{2};
};
template <class Request, class Response>
class DefaultMessageHolder
: public experimental::MessageHolder<Request, Response> {
public:
DefaultMessageHolder() {
this->set_request(&request_obj_);
this->set_response(&response_obj_);
}
void Release() override {
// the object is allocated in the call arena.
this->~DefaultMessageHolder<Request, Response>();
}
private:
Request request_obj_;
Response response_obj_;
};
} // namespace internal
namespace experimental {
@ -137,13 +155,9 @@ class ServerCallbackRpcController {
virtual void SetCancelCallback(std::function<void()> callback) = 0;
virtual void ClearCancelCallback() = 0;
// NOTE: This is an API for advanced users who need custom allocators.
// Optionally deallocate request early to reduce the size of working set.
// A custom MessageAllocator needs to be registered to make use of this.
virtual void FreeRequest() = 0;
// NOTE: This is an API for advanced users who need custom allocators.
// Get and maybe mutate the allocator state associated with the current RPC.
virtual void* GetAllocatorState() = 0;
virtual RpcAllocatorState* GetRpcAllocatorState() = 0;
};
// NOTE: The actual streaming object classes are provided
@ -465,13 +479,13 @@ class CallbackUnaryHandler : public MethodHandler {
void RunHandler(const HandlerParameter& param) final {
// Arena allocate a controller structure (that includes request/response)
g_core_codegen_interface->grpc_call_ref(param.call->call());
auto* allocator_info =
static_cast<experimental::RpcAllocatorInfo<RequestType, ResponseType>*>(
auto* allocator_state =
static_cast<experimental::MessageHolder<RequestType, ResponseType>*>(
param.internal_data);
auto* controller = new (g_core_codegen_interface->grpc_call_arena_alloc(
param.call->call(), sizeof(ServerCallbackRpcControllerImpl)))
ServerCallbackRpcControllerImpl(param.server_context, param.call,
allocator_info, allocator_,
allocator_state,
std::move(param.call_requester));
Status status = param.status;
if (status.ok()) {
@ -489,36 +503,24 @@ class CallbackUnaryHandler : public MethodHandler {
ByteBuffer buf;
buf.set_buffer(req);
RequestType* request = nullptr;
experimental::RpcAllocatorInfo<RequestType, ResponseType>* allocator_info =
new (g_core_codegen_interface->grpc_call_arena_alloc(
call, sizeof(*allocator_info)))
experimental::RpcAllocatorInfo<RequestType, ResponseType>();
experimental::MessageHolder<RequestType, ResponseType>* allocator_state =
nullptr;
if (allocator_ != nullptr) {
allocator_->AllocateMessages(allocator_info);
allocator_state = allocator_->AllocateMessages();
} else {
allocator_info->request =
new (g_core_codegen_interface->grpc_call_arena_alloc(
call, sizeof(RequestType))) RequestType();
allocator_info->response =
new (g_core_codegen_interface->grpc_call_arena_alloc(
call, sizeof(ResponseType))) ResponseType();
allocator_state = new (g_core_codegen_interface->grpc_call_arena_alloc(
call, sizeof(DefaultMessageHolder<RequestType, ResponseType>)))
DefaultMessageHolder<RequestType, ResponseType>();
}
*handler_data = allocator_info;
request = allocator_info->request;
*handler_data = allocator_state;
request = allocator_state->request();
*status = SerializationTraits<RequestType>::Deserialize(&buf, request);
buf.Release();
if (status->ok()) {
return request;
}
// Clean up on deserialization failure.
if (allocator_ != nullptr) {
allocator_->DeallocateMessages(allocator_info);
} else {
allocator_info->request->~RequestType();
allocator_info->response->~ResponseType();
allocator_info->request = nullptr;
allocator_info->response = nullptr;
}
allocator_state->Release();
return nullptr;
}
@ -548,9 +550,8 @@ class CallbackUnaryHandler : public MethodHandler {
}
// The response is dropped if the status is not OK.
if (s.ok()) {
finish_ops_.ServerSendStatus(
&ctx_->trailing_metadata_,
finish_ops_.SendMessagePtr(allocator_info_->response));
finish_ops_.ServerSendStatus(&ctx_->trailing_metadata_,
finish_ops_.SendMessagePtr(response()));
} else {
finish_ops_.ServerSendStatus(&ctx_->trailing_metadata_, s);
}
@ -588,14 +589,8 @@ class CallbackUnaryHandler : public MethodHandler {
void ClearCancelCallback() override { ctx_->ClearCancelCallback(); }
void FreeRequest() override {
if (allocator_ != nullptr) {
allocator_->DeallocateRequest(allocator_info_);
}
}
void* GetAllocatorState() override {
return allocator_info_->allocator_state;
experimental::RpcAllocatorState* GetRpcAllocatorState() override {
return allocator_state_;
}
private:
@ -603,35 +598,23 @@ class CallbackUnaryHandler : public MethodHandler {
ServerCallbackRpcControllerImpl(
ServerContext* ctx, Call* call,
experimental::RpcAllocatorInfo<RequestType, ResponseType>*
allocator_info,
experimental::MessageAllocator<RequestType, ResponseType>* allocator,
experimental::MessageHolder<RequestType, ResponseType>* allocator_state,
std::function<void()> call_requester)
: ctx_(ctx),
call_(*call),
allocator_info_(allocator_info),
allocator_(allocator),
allocator_state_(allocator_state),
call_requester_(std::move(call_requester)) {
ctx_->BeginCompletionOp(call, [this](bool) { MaybeDone(); }, nullptr);
}
const RequestType* request() { return allocator_info_->request; }
ResponseType* response() { return allocator_info_->response; }
const RequestType* request() { return allocator_state_->request(); }
ResponseType* response() { return allocator_state_->response(); }
void MaybeDone() {
if (--callbacks_outstanding_ == 0) {
grpc_call* call = call_.call();
auto call_requester = std::move(call_requester_);
if (allocator_ != nullptr) {
allocator_->DeallocateMessages(allocator_info_);
} else {
if (allocator_info_->request != nullptr) {
allocator_info_->request->~RequestType();
}
if (allocator_info_->response != nullptr) {
allocator_info_->response->~ResponseType();
}
}
allocator_state_->Release();
this->~ServerCallbackRpcControllerImpl(); // explicitly call destructor
g_core_codegen_interface->grpc_call_unref(call);
call_requester();
@ -647,8 +630,8 @@ class CallbackUnaryHandler : public MethodHandler {
ServerContext* ctx_;
Call call_;
experimental::RpcAllocatorInfo<RequestType, ResponseType>* allocator_info_;
experimental::MessageAllocator<RequestType, ResponseType>* allocator_;
experimental::MessageHolder<RequestType, ResponseType>* const
allocator_state_;
std::function<void()> call_requester_;
std::atomic_int callbacks_outstanding_{
2}; // reserve for Finish and CompletionOp

@ -43,12 +43,12 @@ struct census_context;
namespace grpc_impl {
class CompletionQueue;
class Server;
} // namespace grpc_impl
namespace grpc {
class ClientContext;
class GenericServerContext;
class CompletionQueue;
class ServerInterface;
template <class W, class R>
class ServerAsyncReader;
@ -90,6 +90,7 @@ class Call;
class ServerReactor;
} // namespace internal
class ServerInterface;
namespace testing {
class InteropServerContextInspector;
class ServerContextTestSpouse;
@ -354,7 +355,7 @@ class ServerContext {
gpr_timespec deadline_;
grpc_call* call_;
CompletionQueue* cq_;
::grpc_impl::CompletionQueue* cq_;
bool sent_initial_metadata_;
mutable std::shared_ptr<const AuthContext> auth_context_;
mutable internal::MetadataMap client_metadata_;

@ -30,14 +30,15 @@
namespace grpc_impl {
class Channel;
class CompletionQueue;
class ServerCompletionQueue;
class ServerCredentials;
} // namespace grpc_impl
namespace grpc {
class AsyncGenericService;
class Channel;
class GenericServerContext;
class ServerCompletionQueue;
class ServerContext;
class Service;
@ -161,7 +162,8 @@ class ServerInterface : public internal::CallHook {
/// caller is required to keep all completion queues live until the server is
/// destroyed.
/// \param num_cqs How many completion queues does \a cqs hold.
virtual void Start(ServerCompletionQueue** cqs, size_t num_cqs) = 0;
virtual void Start(::grpc_impl::ServerCompletionQueue** cqs,
size_t num_cqs) = 0;
virtual void ShutdownInternal(gpr_timespec deadline) = 0;
@ -176,9 +178,9 @@ class ServerInterface : public internal::CallHook {
public:
BaseAsyncRequest(ServerInterface* server, ServerContext* context,
internal::ServerAsyncStreamingInterface* stream,
CompletionQueue* call_cq,
ServerCompletionQueue* notification_cq, void* tag,
bool delete_on_finalize);
::grpc_impl::CompletionQueue* call_cq,
::grpc_impl::ServerCompletionQueue* notification_cq,
void* tag, bool delete_on_finalize);
virtual ~BaseAsyncRequest();
bool FinalizeResult(void** tag, bool* status) override;
@ -190,8 +192,8 @@ class ServerInterface : public internal::CallHook {
ServerInterface* const server_;
ServerContext* const context_;
internal::ServerAsyncStreamingInterface* const stream_;
CompletionQueue* const call_cq_;
ServerCompletionQueue* const notification_cq_;
::grpc_impl::CompletionQueue* const call_cq_;
::grpc_impl::ServerCompletionQueue* const notification_cq_;
void* const tag_;
const bool delete_on_finalize_;
grpc_call* call_;
@ -205,16 +207,17 @@ class ServerInterface : public internal::CallHook {
public:
RegisteredAsyncRequest(ServerInterface* server, ServerContext* context,
internal::ServerAsyncStreamingInterface* stream,
CompletionQueue* call_cq,
ServerCompletionQueue* notification_cq, void* tag,
const char* name, internal::RpcMethod::RpcType type);
::grpc_impl::CompletionQueue* call_cq,
::grpc_impl::ServerCompletionQueue* notification_cq,
void* tag, const char* name,
internal::RpcMethod::RpcType type);
virtual bool FinalizeResult(void** tag, bool* status) override {
/* If we are done intercepting, then there is nothing more for us to do */
if (done_intercepting_) {
return BaseAsyncRequest::FinalizeResult(tag, status);
}
call_wrapper_ = internal::Call(
call_wrapper_ = ::grpc::internal::Call(
call_, server_, call_cq_, server_->max_receive_message_size(),
context_->set_server_rpc_info(name_, type_,
*server_->interceptor_creators()));
@ -223,7 +226,7 @@ class ServerInterface : public internal::CallHook {
protected:
void IssueRequest(void* registered_method, grpc_byte_buffer** payload,
ServerCompletionQueue* notification_cq);
::grpc_impl::ServerCompletionQueue* notification_cq);
const char* name_;
const internal::RpcMethod::RpcType type_;
};
@ -233,8 +236,9 @@ class ServerInterface : public internal::CallHook {
NoPayloadAsyncRequest(internal::RpcServiceMethod* registered_method,
ServerInterface* server, ServerContext* context,
internal::ServerAsyncStreamingInterface* stream,
CompletionQueue* call_cq,
ServerCompletionQueue* notification_cq, void* tag)
::grpc_impl::CompletionQueue* call_cq,
::grpc_impl::ServerCompletionQueue* notification_cq,
void* tag)
: RegisteredAsyncRequest(
server, context, stream, call_cq, notification_cq, tag,
registered_method->name(), registered_method->method_type()) {
@ -250,9 +254,9 @@ class ServerInterface : public internal::CallHook {
PayloadAsyncRequest(internal::RpcServiceMethod* registered_method,
ServerInterface* server, ServerContext* context,
internal::ServerAsyncStreamingInterface* stream,
CompletionQueue* call_cq,
ServerCompletionQueue* notification_cq, void* tag,
Message* request)
::grpc_impl::CompletionQueue* call_cq,
::grpc_impl::ServerCompletionQueue* notification_cq,
void* tag, Message* request)
: RegisteredAsyncRequest(
server, context, stream, call_cq, notification_cq, tag,
registered_method->name(), registered_method->method_type()),
@ -307,9 +311,9 @@ class ServerInterface : public internal::CallHook {
ServerInterface* const server_;
ServerContext* const context_;
internal::ServerAsyncStreamingInterface* const stream_;
CompletionQueue* const call_cq_;
::grpc_impl::CompletionQueue* const call_cq_;
ServerCompletionQueue* const notification_cq_;
::grpc_impl::ServerCompletionQueue* const notification_cq_;
void* const tag_;
Message* const request_;
ByteBuffer payload_;
@ -319,9 +323,9 @@ class ServerInterface : public internal::CallHook {
public:
GenericAsyncRequest(ServerInterface* server, GenericServerContext* context,
internal::ServerAsyncStreamingInterface* stream,
CompletionQueue* call_cq,
ServerCompletionQueue* notification_cq, void* tag,
bool delete_on_finalize);
::grpc_impl::CompletionQueue* call_cq,
::grpc_impl::ServerCompletionQueue* notification_cq,
void* tag, bool delete_on_finalize);
bool FinalizeResult(void** tag, bool* status) override;
@ -333,9 +337,9 @@ class ServerInterface : public internal::CallHook {
void RequestAsyncCall(internal::RpcServiceMethod* method,
ServerContext* context,
internal::ServerAsyncStreamingInterface* stream,
CompletionQueue* call_cq,
ServerCompletionQueue* notification_cq, void* tag,
Message* message) {
::grpc_impl::CompletionQueue* call_cq,
::grpc_impl::ServerCompletionQueue* notification_cq,
void* tag, Message* message) {
GPR_CODEGEN_ASSERT(method);
new PayloadAsyncRequest<Message>(method, this, context, stream, call_cq,
notification_cq, tag, message);
@ -344,18 +348,19 @@ class ServerInterface : public internal::CallHook {
void RequestAsyncCall(internal::RpcServiceMethod* method,
ServerContext* context,
internal::ServerAsyncStreamingInterface* stream,
CompletionQueue* call_cq,
ServerCompletionQueue* notification_cq, void* tag) {
::grpc_impl::CompletionQueue* call_cq,
::grpc_impl::ServerCompletionQueue* notification_cq,
void* tag) {
GPR_CODEGEN_ASSERT(method);
new NoPayloadAsyncRequest(method, this, context, stream, call_cq,
notification_cq, tag);
}
void RequestAsyncGenericCall(GenericServerContext* context,
void RequestAsyncGenericCall(
GenericServerContext* context,
internal::ServerAsyncStreamingInterface* stream,
CompletionQueue* call_cq,
ServerCompletionQueue* notification_cq,
void* tag) {
::grpc_impl::CompletionQueue* call_cq,
::grpc_impl::ServerCompletionQueue* notification_cq, void* tag) {
new GenericAsyncRequest(this, context, stream, call_cq, notification_cq,
tag, true);
}
@ -380,7 +385,7 @@ class ServerInterface : public internal::CallHook {
// Returns nullptr (rather than being pure) since this is a post-1.0 method
// and adding a new pure method to an interface would be a breaking change
// (even though this is private and non-API)
virtual CompletionQueue* CallbackCQ() { return nullptr; }
virtual ::grpc_impl::CompletionQueue* CallbackCQ() { return nullptr; }
};
} // namespace grpc

@ -29,12 +29,11 @@
namespace grpc_impl {
class Server;
class CompletionQueue;
} // namespace grpc_impl
namespace grpc {
class CompletionQueue;
class ServerInterface;
class ServerCompletionQueue;
class ServerContext;
namespace internal {

@ -24,6 +24,7 @@
#include <vector>
#include <grpc/grpc_security_constants.h>
#include <grpcpp/channel.h>
#include <grpcpp/impl/codegen/client_interceptor.h>
#include <grpcpp/impl/codegen/grpc_library.h>
#include <grpcpp/security/auth_context.h>

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

@ -38,15 +38,16 @@ struct grpc_resource_quota;
namespace grpc_impl {
class CompletionQueue;
class ResourceQuota;
class Server;
class ServerCompletionQueue;
class ServerCredentials;
} // namespace grpc_impl
namespace grpc {
class AsyncGenericService;
class CompletionQueue;
class ServerCompletionQueue;
class Service;
namespace testing {
class ServerBuilderPluginTest;
@ -155,7 +156,7 @@ class ServerBuilder {
/// not polling the completion queue frequently) will have a significantly
/// negative performance impact and hence should not be used in production
/// use cases.
std::unique_ptr<grpc::ServerCompletionQueue> AddCompletionQueue(
std::unique_ptr<grpc_impl::ServerCompletionQueue> AddCompletionQueue(
bool is_frequently_polled = true);
//////////////////////////////////////////////////////////////////////////////
@ -361,7 +362,7 @@ class ServerBuilder {
SyncServerSettings sync_server_settings_;
/// List of completion queues added via \a AddCompletionQueue method.
std::vector<grpc::ServerCompletionQueue*> cqs_;
std::vector<grpc_impl::ServerCompletionQueue*> cqs_;
std::shared_ptr<grpc_impl::ServerCredentials> creds_;
std::vector<std::unique_ptr<grpc::ServerBuilderPlugin>> plugins_;

@ -27,6 +27,7 @@
#include <grpc/compression.h>
#include <grpc/support/atm.h>
#include <grpcpp/channel.h>
#include <grpcpp/completion_queue.h>
#include <grpcpp/health_check_service_interface.h>
#include <grpcpp/impl/call.h>
@ -107,7 +108,7 @@ class Server : public grpc::ServerInterface, private grpc::GrpcLibraryCodegen {
}
/// Establish a channel for in-process communication
std::shared_ptr<grpc::Channel> InProcessChannel(
std::shared_ptr<::grpc::Channel> InProcessChannel(
const grpc::ChannelArguments& args);
/// NOTE: class experimental_type is not part of the public API of this class.
@ -119,7 +120,7 @@ class Server : public grpc::ServerInterface, private grpc::GrpcLibraryCodegen {
/// Establish a channel for in-process communication with client
/// interceptors
std::shared_ptr<grpc::Channel> InProcessChannelWithInterceptors(
std::shared_ptr<::grpc::Channel> InProcessChannelWithInterceptors(
const grpc::ChannelArguments& args,
std::vector<std::unique_ptr<
grpc::experimental::ClientInterceptorFactoryInterface>>

@ -478,6 +478,7 @@
<file baseinstalldir="/" name="src/core/ext/filters/client_channel/lb_policy/subchannel_list.h" role="src" />
<file baseinstalldir="/" name="src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver.h" role="src" />
<file baseinstalldir="/" name="src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.h" role="src" />
<file baseinstalldir="/" name="src/core/ext/filters/client_channel/resolver/dns/dns_resolver_selection.h" role="src" />
<file baseinstalldir="/" name="src/core/ext/filters/max_age/max_age_filter.h" role="src" />
<file baseinstalldir="/" name="src/core/ext/filters/message_size/message_size_filter.h" role="src" />
<file baseinstalldir="/" name="src/core/ext/filters/http/client_authority_filter.h" role="src" />
@ -810,6 +811,7 @@
<file baseinstalldir="/" name="src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv.cc" role="src" />
<file baseinstalldir="/" name="src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_posix.cc" role="src" />
<file baseinstalldir="/" name="src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_windows.cc" role="src" />
<file baseinstalldir="/" name="src/core/ext/filters/client_channel/resolver/dns/dns_resolver_selection.cc" role="src" />
<file baseinstalldir="/" name="src/core/ext/filters/client_channel/resolver/dns/native/dns_resolver.cc" role="src" />
<file baseinstalldir="/" name="src/core/ext/filters/client_channel/resolver/sockaddr/sockaddr_resolver.cc" role="src" />
<file baseinstalldir="/" name="src/core/ext/filters/census/grpc_context.cc" role="src" />

@ -18,8 +18,8 @@
#include <grpcpp/grpcpp.h>
#include <jni.h>
#include <src/core/lib/gpr/env.h>
#include "src/core/lib/security/security_connector/ssl_utils.h"
#include "test/cpp/interop/interop_client.h"
extern "C" JNIEXPORT void JNICALL
@ -28,7 +28,7 @@ Java_io_grpc_interop_cpp_InteropActivity_configureSslRoots(JNIEnv* env,
jstring path_raw) {
const char* path = env->GetStringUTFChars(path_raw, (jboolean*)0);
gpr_setenv("GRPC_DEFAULT_SSL_ROOTS_FILE_PATH", path);
GPR_GLOBAL_CONFIG_SET(grpc_default_ssl_roots_file_path, path);
}
std::shared_ptr<grpc::testing::InteropClient> GetClient(const char* host,

@ -154,13 +154,15 @@ grpc::string GetHeaderIncludes(grpc_generator::File* file,
PrintIncludes(printer.get(), headers, params.use_system_headers,
params.grpc_search_path);
printer->Print(vars, "\n");
printer->Print(vars, "namespace grpc_impl {\n");
printer->Print(vars, "class CompletionQueue;\n");
printer->Print(vars, "class ServerCompletionQueue;\n");
printer->Print(vars, "} // namespace grpc_impl\n\n");
printer->Print(vars, "namespace grpc {\n");
printer->Print(vars, "namespace experimental {\n");
printer->Print(vars, "template <typename RequestT, typename ResponseT>\n");
printer->Print(vars, "class MessageAllocator;\n");
printer->Print(vars, "} // namespace experimental\n");
printer->Print(vars, "class CompletionQueue;\n");
printer->Print(vars, "class ServerCompletionQueue;\n");
printer->Print(vars, "class ServerContext;\n");
printer->Print(vars, "} // namespace grpc\n\n");

@ -56,9 +56,14 @@ static backup_poller* g_poller = nullptr; // guarded by g_poller_mu
// treated as const.
static int g_poll_interval_ms = DEFAULT_POLL_INTERVAL_MS;
GPR_GLOBAL_CONFIG_DEFINE_INT32(grpc_client_channel_backup_poll_interval_ms,
DEFAULT_POLL_INTERVAL_MS,
"Client channel backup poll interval (ms)");
GPR_GLOBAL_CONFIG_DEFINE_INT32(
grpc_client_channel_backup_poll_interval_ms, DEFAULT_POLL_INTERVAL_MS,
"Declares the interval in ms between two backup polls on client channels. "
"These polls are run in the timer thread so that gRPC can process "
"connection failures while there is no active polling thread. "
"They help reconnect disconnected client channels (mostly due to "
"idleness), so that the next RPC on this channel won't fail. Set to 0 to "
"turn off the backup polls.");
static void init_globals() {
gpr_mu_init(&g_poller_mu);

@ -31,7 +31,6 @@
#include "src/core/ext/filters/client_channel/resolver_registry.h"
#include "src/core/lib/channel/channel_args.h"
#include "src/core/lib/channel/handshaker_registry.h"
#include "src/core/lib/gpr/env.h"
#include "src/core/lib/gpr/string.h"
#include "src/core/lib/gprpp/sync.h"
#include "src/core/lib/http/format_request.h"

@ -493,9 +493,8 @@ class XdsLb : public LoadBalancingPolicy {
// 1. The fallback timer fires, we enter fallback mode.
// 2. Before the fallback timer fires, the LB channel becomes
// TRANSIENT_FAILURE or the LB call fails, we enter fallback mode.
// 3. Before the fallback timer fires, we receive a response from the
// balancer, we cancel the fallback timer and use the response to update the
// locality map.
// 3. Before the fallback timer fires, if any child policy in the locality map
// becomes READY, we cancel the fallback timer.
bool fallback_at_startup_checks_pending_ = false;
// Timeout in milliseconds for before using fallback backend addresses.
// 0 means not using fallback.
@ -1197,9 +1196,6 @@ void XdsLb::BalancerChannelState::BalancerCallState::
xds_grpclb_destroy_serverlist(
xdslb_policy->locality_serverlist_[0]->serverlist);
} else {
// This is the first serverlist we've received, don't enter fallback
// mode.
xdslb_policy->MaybeCancelFallbackAtStartupChecks();
// Initialize locality serverlist, currently the list only handles
// one child.
xdslb_policy->locality_serverlist_.emplace_back(
@ -2046,7 +2042,10 @@ void XdsLb::LocalityMap::LocalityEntry::Helper::UpdateState(
return;
}
// At this point, child_ must be the current child policy.
if (state == GRPC_CHANNEL_READY) entry_->parent_->MaybeExitFallbackMode();
if (state == GRPC_CHANNEL_READY) {
entry_->parent_->MaybeCancelFallbackAtStartupChecks();
entry_->parent_->MaybeExitFallbackMode();
}
// If we are in fallback mode, ignore update request from the child policy.
if (entry_->parent_->fallback_policy_ != nullptr) return;
GPR_ASSERT(entry_->parent_->lb_chand_ != nullptr);

@ -32,12 +32,12 @@
#include "src/core/ext/filters/client_channel/http_connect_handshaker.h"
#include "src/core/ext/filters/client_channel/lb_policy_registry.h"
#include "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.h"
#include "src/core/ext/filters/client_channel/resolver/dns/dns_resolver_selection.h"
#include "src/core/ext/filters/client_channel/resolver_registry.h"
#include "src/core/ext/filters/client_channel/server_address.h"
#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/env.h"
#include "src/core/lib/gpr/host_port.h"
#include "src/core/lib/gpr/string.h"
#include "src/core/lib/gprpp/manual_constructor.h"
@ -474,8 +474,9 @@ static bool should_use_ares(const char* resolver_env) {
#endif /* GRPC_UV */
void grpc_resolver_dns_ares_init() {
char* resolver_env = gpr_getenv("GRPC_DNS_RESOLVER");
if (should_use_ares(resolver_env)) {
grpc_core::UniquePtr<char> resolver =
GPR_GLOBAL_CONFIG_GET(grpc_dns_resolver);
if (should_use_ares(resolver.get())) {
gpr_log(GPR_DEBUG, "Using ares dns resolver");
address_sorting_init();
grpc_error* error = grpc_ares_init();
@ -491,16 +492,15 @@ void grpc_resolver_dns_ares_init() {
grpc_core::UniquePtr<grpc_core::ResolverFactory>(
grpc_core::New<grpc_core::AresDnsResolverFactory>()));
}
gpr_free(resolver_env);
}
void grpc_resolver_dns_ares_shutdown() {
char* resolver_env = gpr_getenv("GRPC_DNS_RESOLVER");
if (should_use_ares(resolver_env)) {
grpc_core::UniquePtr<char> resolver =
GPR_GLOBAL_CONFIG_GET(grpc_dns_resolver);
if (should_use_ares(resolver.get())) {
address_sorting_shutdown();
grpc_ares_cleanup();
}
gpr_free(resolver_env);
}
#else /* GRPC_ARES == 1 */

@ -0,0 +1,28 @@
//
// 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.
//
// This is similar to the sockaddr resolver, except that it supports a
// bunch of query args that are useful for dependency injection in tests.
#include <grpc/support/port_platform.h>
#include "src/core/ext/filters/client_channel/resolver/dns/dns_resolver_selection.h"
GPR_GLOBAL_CONFIG_DEFINE_STRING(
grpc_dns_resolver, "",
"Declares which DNS resolver to use. The default is ares if gRPC is built "
"with c-ares support. Otherwise, the value of this environment variable is "
"ignored.")

@ -0,0 +1,29 @@
/*
*
* 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 GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_RESOLVER_DNS_DNS_RESOLVER_SELECTION_H
#define GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_RESOLVER_DNS_DNS_RESOLVER_SELECTION_H
#include <grpc/support/port_platform.h>
#include "src/core/lib/gprpp/global_config.h"
GPR_GLOBAL_CONFIG_DECLARE_STRING(grpc_dns_resolver);
#endif /* GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_RESOLVER_DNS_DNS_RESOLVER_SELECTION_H \
*/

@ -26,11 +26,11 @@
#include <grpc/support/string_util.h>
#include <grpc/support/time.h>
#include "src/core/ext/filters/client_channel/resolver/dns/dns_resolver_selection.h"
#include "src/core/ext/filters/client_channel/resolver_registry.h"
#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/env.h"
#include "src/core/lib/gpr/host_port.h"
#include "src/core/lib/gpr/string.h"
#include "src/core/lib/gprpp/manual_constructor.h"
@ -274,8 +274,9 @@ class NativeDnsResolverFactory : public ResolverFactory {
} // namespace grpc_core
void grpc_resolver_dns_native_init() {
char* resolver_env = gpr_getenv("GRPC_DNS_RESOLVER");
if (resolver_env != nullptr && gpr_stricmp(resolver_env, "native") == 0) {
grpc_core::UniquePtr<char> resolver =
GPR_GLOBAL_CONFIG_GET(grpc_dns_resolver);
if (gpr_stricmp(resolver.get(), "native") == 0) {
gpr_log(GPR_DEBUG, "Using native dns resolver");
grpc_core::ResolverRegistry::Builder::RegisterResolverFactory(
grpc_core::UniquePtr<grpc_core::ResolverFactory>(
@ -291,7 +292,6 @@ void grpc_resolver_dns_native_init() {
grpc_core::New<grpc_core::NativeDnsResolverFactory>()));
}
}
gpr_free(resolver_env);
}
void grpc_resolver_dns_native_shutdown() {}

@ -23,8 +23,11 @@
#include "src/core/lib/gprpp/global_config.h"
#include "src/core/lib/transport/metadata.h"
GPR_GLOBAL_CONFIG_DEFINE_BOOL(grpc_experimental_disable_flow_control, false,
"Disable flow control");
GPR_GLOBAL_CONFIG_DEFINE_BOOL(
grpc_experimental_disable_flow_control, false,
"If set, flow control will be effectively disabled. Max out all values and "
"assume the remote peer does the same. Thus we can ignore any flow control "
"bookkeeping, error checking, and decision making");
void grpc_chttp2_plugin_init(void) {
g_flow_control_enabled =

@ -2262,7 +2262,7 @@ void grpc_chttp2_mark_stream_closed(grpc_chttp2_transport* t,
if (closed_read) {
for (int i = 0; i < 2; i++) {
if (s->published_metadata[i] == GRPC_METADATA_NOT_PUBLISHED) {
s->published_metadata[i] = GPRC_METADATA_PUBLISHED_AT_CLOSE;
s->published_metadata[i] = GRPC_METADATA_PUBLISHED_AT_CLOSE;
}
}
grpc_chttp2_maybe_complete_recv_initial_metadata(t, s);

@ -499,7 +499,7 @@ typedef enum {
GRPC_METADATA_NOT_PUBLISHED,
GRPC_METADATA_SYNTHESIZED_FROM_FAKE,
GRPC_METADATA_PUBLISHED_FROM_WIRE,
GPRC_METADATA_PUBLISHED_AT_CLOSE
GRPC_METADATA_PUBLISHED_AT_CLOSE
} grpc_published_metadata_method;
struct grpc_chttp2_stream {

@ -26,7 +26,11 @@
#include <grpc/grpc.h>
#include <grpc/support/alloc.h>
#include <grpc/support/log.h>
#include "src/core/lib/gpr/env.h"
GPR_GLOBAL_CONFIG_DEFINE_STRING(
grpc_trace, "",
"A comma separated list of tracers that provide additional insight into "
"how gRPC C core is processing requests via debug logs.");
int grpc_tracer_set_enabled(const char* name, int enabled);
@ -133,12 +137,14 @@ static void parse(const char* s) {
gpr_free(strings);
}
void grpc_tracer_init(const char* env_var) {
char* e = gpr_getenv(env_var);
if (e != nullptr) {
parse(e);
gpr_free(e);
}
void grpc_tracer_init(const char* env_var_name) {
(void)env_var_name; // suppress unused variable error
grpc_tracer_init();
}
void grpc_tracer_init() {
grpc_core::UniquePtr<char> value = GPR_GLOBAL_CONFIG_GET(grpc_trace);
parse(value.get());
}
void grpc_tracer_shutdown(void) {}

@ -24,7 +24,15 @@
#include <grpc/support/atm.h>
#include <stdbool.h>
#include "src/core/lib/gprpp/global_config.h"
GPR_GLOBAL_CONFIG_DECLARE_STRING(grpc_trace);
// TODO(veblush): Remove this deprecated function once codes depending on this
// function are updated in the internal repo.
void grpc_tracer_init(const char* env_var_name);
void grpc_tracer_init();
void grpc_tracer_shutdown(void);
#if defined(__has_feature)

@ -34,12 +34,6 @@ char* gpr_getenv(const char* name);
/* Sets the environment with the specified name to the specified value. */
void gpr_setenv(const char* name, const char* value);
/* This is a version of gpr_getenv that does not produce any output if it has to
use an insecure version of the function. It is ONLY to be used to solve the
problem in which we need to check an env variable to configure the verbosity
level of logging. So DO NOT USE THIS. */
const char* gpr_getenv_silent(const char* name, char** dst);
/* Deletes the variable name from the environment. */
void gpr_unsetenv(const char* name);

@ -38,7 +38,7 @@
#include "src/core/lib/gpr/string.h"
#include "src/core/lib/gpr/useful.h"
const char* gpr_getenv_silent(const char* name, char** dst) {
static const char* gpr_getenv_silent(const char* name, char** dst) {
const char* insecure_func_used = nullptr;
char* result = nullptr;
#if defined(GPR_BACKWARDS_COMPATIBILITY_MODE)

@ -30,11 +30,6 @@
#include "src/core/lib/gpr/string.h"
#include "src/core/lib/gpr/string_windows.h"
const char* gpr_getenv_silent(const char* name, char** dst) {
*dst = gpr_getenv(name);
return NULL;
}
char* gpr_getenv(const char* name) {
char* result = NULL;
DWORD size;

@ -22,12 +22,15 @@
#include <grpc/support/atm.h>
#include <grpc/support/log.h>
#include "src/core/lib/gpr/env.h"
#include "src/core/lib/gpr/string.h"
#include "src/core/lib/gprpp/global_config.h"
#include <stdio.h>
#include <string.h>
GPR_GLOBAL_CONFIG_DEFINE_STRING(grpc_verbosity, "ERROR",
"Default gRPC logging verbosity")
void gpr_default_log(gpr_log_func_args* args);
static gpr_atm g_log_func = (gpr_atm)gpr_default_log;
static gpr_atm g_min_severity_to_print = GPR_LOG_VERBOSITY_UNSET;
@ -72,29 +75,22 @@ void gpr_set_log_verbosity(gpr_log_severity min_severity_to_print) {
}
void gpr_log_verbosity_init() {
char* verbosity = nullptr;
const char* insecure_getenv = gpr_getenv_silent("GRPC_VERBOSITY", &verbosity);
grpc_core::UniquePtr<char> verbosity = GPR_GLOBAL_CONFIG_GET(grpc_verbosity);
gpr_atm min_severity_to_print = GPR_LOG_SEVERITY_ERROR;
if (verbosity != nullptr) {
if (gpr_stricmp(verbosity, "DEBUG") == 0) {
if (strlen(verbosity.get()) > 0) {
if (gpr_stricmp(verbosity.get(), "DEBUG") == 0) {
min_severity_to_print = static_cast<gpr_atm>(GPR_LOG_SEVERITY_DEBUG);
} else if (gpr_stricmp(verbosity, "INFO") == 0) {
} else if (gpr_stricmp(verbosity.get(), "INFO") == 0) {
min_severity_to_print = static_cast<gpr_atm>(GPR_LOG_SEVERITY_INFO);
} else if (gpr_stricmp(verbosity, "ERROR") == 0) {
} else if (gpr_stricmp(verbosity.get(), "ERROR") == 0) {
min_severity_to_print = static_cast<gpr_atm>(GPR_LOG_SEVERITY_ERROR);
}
gpr_free(verbosity);
}
if ((gpr_atm_no_barrier_load(&g_min_severity_to_print)) ==
GPR_LOG_VERBOSITY_UNSET) {
gpr_atm_no_barrier_store(&g_min_severity_to_print, min_severity_to_print);
}
if (insecure_getenv != nullptr) {
gpr_log(GPR_DEBUG, "Warning: insecure environment read function '%s' used",
insecure_getenv);
}
}
void gpr_set_log_function(gpr_log_func f) {

@ -26,8 +26,8 @@
#include <grpc/support/sync.h>
#include <grpc/support/time.h>
#include "src/core/lib/gpr/env.h"
#include "src/core/lib/gpr/useful.h"
#include "src/core/lib/gprpp/global_config.h"
#include "src/core/lib/gprpp/memory.h"
/*
@ -35,6 +35,16 @@
* AROUND VERY SPECIFIC USE CASES.
*/
#ifdef GRPC_ENABLE_FORK_SUPPORT
#define GRPC_ENABLE_FORK_SUPPORT_DEFAULT true
#else
#define GRPC_ENABLE_FORK_SUPPORT_DEFAULT false
#endif // GRPC_ENABLE_FORK_SUPPORT
GPR_GLOBAL_CONFIG_DEFINE_BOOL(grpc_enable_fork_support,
GRPC_ENABLE_FORK_SUPPORT_DEFAULT,
"Enable folk support");
namespace grpc_core {
namespace internal {
// The exec_ctx_count has 2 modes, blocked and unblocked.
@ -158,34 +168,7 @@ class ThreadState {
void Fork::GlobalInit() {
if (!override_enabled_) {
#ifdef GRPC_ENABLE_FORK_SUPPORT
support_enabled_ = true;
#endif
bool env_var_set = false;
char* env = gpr_getenv("GRPC_ENABLE_FORK_SUPPORT");
if (env != nullptr) {
static const char* truthy[] = {"yes", "Yes", "YES", "true",
"True", "TRUE", "1"};
static const char* falsey[] = {"no", "No", "NO", "false",
"False", "FALSE", "0"};
for (size_t i = 0; i < GPR_ARRAY_SIZE(truthy); i++) {
if (0 == strcmp(env, truthy[i])) {
support_enabled_ = true;
env_var_set = true;
break;
}
}
if (!env_var_set) {
for (size_t i = 0; i < GPR_ARRAY_SIZE(falsey); i++) {
if (0 == strcmp(env, falsey[i])) {
support_enabled_ = false;
env_var_set = true;
break;
}
}
}
gpr_free(env);
}
support_enabled_ = GPR_GLOBAL_CONFIG_GET(grpc_enable_fork_support);
}
if (support_enabled_) {
exec_ctx_state_ = grpc_core::New<internal::ExecCtxState>();

@ -31,13 +31,19 @@
#include <grpc/support/string_util.h>
#include "src/core/lib/debug/trace.h"
#include "src/core/lib/gpr/env.h"
#include "src/core/lib/gpr/useful.h"
#include "src/core/lib/gprpp/global_config.h"
#include "src/core/lib/iomgr/ev_epoll1_linux.h"
#include "src/core/lib/iomgr/ev_epollex_linux.h"
#include "src/core/lib/iomgr/ev_poll_posix.h"
#include "src/core/lib/iomgr/internal_errqueue.h"
GPR_GLOBAL_CONFIG_DEFINE_STRING(
grpc_poll_strategy, "all",
"Declares which polling engines to try when starting gRPC. "
"This is a comma-separated list of engines, which are tried in priority "
"order first -> last.")
grpc_core::TraceFlag grpc_polling_trace(false,
"polling"); /* Disabled by default */
@ -46,16 +52,15 @@ grpc_core::TraceFlag grpc_fd_trace(false, "fd_trace");
grpc_core::DebugOnlyTraceFlag grpc_trace_fd_refcount(false, "fd_refcount");
grpc_core::DebugOnlyTraceFlag grpc_polling_api_trace(false, "polling_api");
#ifndef NDEBUG
// Polling API trace only enabled in debug builds
#ifndef NDEBUG
#define GRPC_POLLING_API_TRACE(format, ...) \
if (GRPC_TRACE_FLAG_ENABLED(grpc_polling_api_trace)) { \
gpr_log(GPR_INFO, "(polling-api) " format, __VA_ARGS__); \
}
#else
#define GRPC_POLLING_API_TRACE(...)
#endif
#endif // NDEBUG
/** Default poll() function - a pointer so that it can be overridden by some
* tests */
@ -66,7 +71,7 @@ int aix_poll(struct pollfd fds[], nfds_t nfds, int timeout) {
return poll(fds, nfds, timeout);
}
grpc_poll_function_type grpc_poll_function = aix_poll;
#endif
#endif // GPR_AIX
grpc_wakeup_fd grpc_global_wakeup_fd;
@ -205,14 +210,11 @@ void grpc_register_event_engine_factory(const char* name,
const char* grpc_get_poll_strategy_name() { return g_poll_strategy_name; }
void grpc_event_engine_init(void) {
char* s = gpr_getenv("GRPC_POLL_STRATEGY");
if (s == nullptr) {
s = gpr_strdup("all");
}
grpc_core::UniquePtr<char> value = GPR_GLOBAL_CONFIG_GET(grpc_poll_strategy);
char** strings = nullptr;
size_t nstrings = 0;
split(s, &strings, &nstrings);
split(value.get(), &strings, &nstrings);
for (size_t i = 0; g_event_engine == nullptr && i < nstrings; i++) {
try_engine(strings[i]);
@ -224,10 +226,10 @@ void grpc_event_engine_init(void) {
gpr_free(strings);
if (g_event_engine == nullptr) {
gpr_log(GPR_ERROR, "No event engine could be initialized from %s", s);
gpr_log(GPR_ERROR, "No event engine could be initialized from %s",
value.get());
abort();
}
gpr_free(s);
}
void grpc_event_engine_shutdown(void) {

@ -24,11 +24,14 @@
#include <poll.h>
#include "src/core/lib/debug/trace.h"
#include "src/core/lib/gprpp/global_config.h"
#include "src/core/lib/iomgr/exec_ctx.h"
#include "src/core/lib/iomgr/pollset.h"
#include "src/core/lib/iomgr/pollset_set.h"
#include "src/core/lib/iomgr/wakeup_fd_posix.h"
GPR_GLOBAL_CONFIG_DECLARE_STRING(grpc_poll_strategy);
extern grpc_core::TraceFlag grpc_fd_trace; /* Disabled by default */
extern grpc_core::TraceFlag grpc_polling_trace; /* Disabled by default */

@ -28,7 +28,6 @@
#include <grpc/grpc.h>
#include <grpc/support/log.h>
#include "src/core/lib/gpr/env.h"
#include "src/core/lib/gprpp/fork.h"
#include "src/core/lib/gprpp/thd.h"
#include "src/core/lib/iomgr/ev_posix.h"

@ -42,7 +42,8 @@
#include "src/core/lib/iomgr/timer_manager.h"
GPR_GLOBAL_CONFIG_DEFINE_BOOL(grpc_abort_on_leaks, false,
"Abort when leak is found");
"A debugging aid to cause a call to abort() when "
"gRPC objects are leaked past grpc_shutdown()");
static gpr_mu g_mu;
static gpr_cv g_rcv;

@ -31,7 +31,8 @@
#include <stdio.h>
#include <string.h>
#include "src/core/lib/gpr/env.h"
#include "src/core/lib/gprpp/global_config.h"
#include "src/core/lib/profiling/timers.h"
typedef enum { BEGIN = '{', END = '}', MARK = '.' } marker_type;
@ -74,11 +75,16 @@ static __thread int g_thread_id;
static int g_next_thread_id;
static int g_writing_enabled = 1;
GPR_GLOBAL_CONFIG_DEFINE_STRING(grpc_latency_trace, "latency_trace.txt",
"Output file name for latency trace")
static const char* output_filename() {
if (output_filename_or_null == NULL) {
output_filename_or_null = gpr_getenv("LATENCY_TRACE");
if (output_filename_or_null == NULL ||
strlen(output_filename_or_null) == 0) {
grpc_core::UniquePtr<char> value =
GPR_GLOBAL_CONFIG_GET(grpc_latency_trace);
if (strlen(value.get()) > 0) {
output_filename_or_null = value.release();
} else {
output_filename_or_null = "latency_trace.txt";
}
}

@ -38,12 +38,15 @@
#include <grpc/support/log.h>
#include <grpc/support/string_util.h>
#include "src/core/lib/gpr/env.h"
#include "src/core/lib/gpr/string.h"
#include "src/core/lib/gpr/useful.h"
#include "src/core/lib/gprpp/global_config.h"
#include "src/core/lib/gprpp/inlined_vector.h"
#include "src/core/lib/iomgr/load_file.h"
GPR_GLOBAL_CONFIG_DEFINE_STRING(grpc_system_ssl_roots_dir, "",
"Custom directory to SSL Roots");
namespace grpc_core {
namespace {
@ -139,10 +142,9 @@ grpc_slice CreateRootCertsBundle(const char* certs_directory) {
grpc_slice LoadSystemRootCerts() {
grpc_slice result = grpc_empty_slice();
// Prioritize user-specified custom directory if flag is set.
char* custom_dir = gpr_getenv("GRPC_SYSTEM_SSL_ROOTS_DIR");
if (custom_dir != nullptr) {
result = CreateRootCertsBundle(custom_dir);
gpr_free(custom_dir);
UniquePtr<char> custom_dir = GPR_GLOBAL_CONFIG_GET(grpc_system_ssl_roots_dir);
if (strlen(custom_dir.get()) > 0) {
result = CreateRootCertsBundle(custom_dir.get());
}
// If the custom directory is empty/invalid/not specified, fallback to
// distribution-specific directory.

@ -28,7 +28,6 @@
#include "src/core/ext/transport/chttp2/alpn/alpn.h"
#include "src/core/lib/channel/channel_args.h"
#include "src/core/lib/channel/handshaker.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/iomgr/load_file.h"

@ -27,7 +27,6 @@
#include "src/core/ext/transport/chttp2/alpn/alpn.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/global_config.h"
@ -46,7 +45,13 @@ static const char* installed_roots_path =
INSTALL_PREFIX "/share/grpc/roots.pem";
#endif
/** Environment variable used as a flag to enable/disable loading system root
/** Config variable that points to the default SSL roots file. This file
must be a PEM encoded file with all the roots such as the one that can be
downloaded from https://pki.google.com/roots.pem. */
GPR_GLOBAL_CONFIG_DEFINE_STRING(grpc_default_ssl_roots_file_path, "",
"Path to the default SSL roots file.");
/** Config variable used as a flag to enable/disable loading system root
certificates from the OS trust store. */
GPR_GLOBAL_CONFIG_DEFINE_BOOL(grpc_not_use_system_ssl_roots, false,
"Disable loading system root certificates.");
@ -65,20 +70,22 @@ void grpc_set_ssl_roots_override_callback(grpc_ssl_roots_override_callback cb) {
/* -- Cipher suites. -- */
/* Defines the cipher suites that we accept by default. All these cipher suites
are compliant with HTTP2. */
#define GRPC_SSL_CIPHER_SUITES \
"ECDHE-ECDSA-AES128-GCM-SHA256:" \
"ECDHE-ECDSA-AES256-GCM-SHA384:" \
"ECDHE-RSA-AES128-GCM-SHA256:" \
"ECDHE-RSA-AES256-GCM-SHA384"
static gpr_once cipher_suites_once = GPR_ONCE_INIT;
static const char* cipher_suites = nullptr;
// All cipher suites for default are compliant with HTTP2.
GPR_GLOBAL_CONFIG_DEFINE_STRING(
grpc_ssl_cipher_suites,
"ECDHE-ECDSA-AES128-GCM-SHA256:"
"ECDHE-ECDSA-AES256-GCM-SHA384:"
"ECDHE-RSA-AES128-GCM-SHA256:"
"ECDHE-RSA-AES256-GCM-SHA384",
"A colon separated list of cipher suites to use with OpenSSL")
static void init_cipher_suites(void) {
char* overridden = gpr_getenv("GRPC_SSL_CIPHER_SUITES");
cipher_suites = overridden != nullptr ? overridden : GRPC_SSL_CIPHER_SUITES;
grpc_core::UniquePtr<char> value =
GPR_GLOBAL_CONFIG_GET(grpc_ssl_cipher_suites);
cipher_suites = value.release();
}
/* --- Util --- */
@ -430,13 +437,12 @@ grpc_slice DefaultSslRootStore::ComputePemRootCerts() {
grpc_slice result = grpc_empty_slice();
const bool not_use_system_roots =
GPR_GLOBAL_CONFIG_GET(grpc_not_use_system_ssl_roots);
// First try to load the roots from the environment.
char* default_root_certs_path =
gpr_getenv(GRPC_DEFAULT_SSL_ROOTS_FILE_PATH_ENV_VAR);
if (default_root_certs_path != nullptr) {
GRPC_LOG_IF_ERROR("load_file",
grpc_load_file(default_root_certs_path, 1, &result));
gpr_free(default_root_certs_path);
// First try to load the roots from the configuration.
UniquePtr<char> default_root_certs_path =
GPR_GLOBAL_CONFIG_GET(grpc_default_ssl_roots_file_path);
if (strlen(default_root_certs_path.get()) > 0) {
GRPC_LOG_IF_ERROR(
"load_file", grpc_load_file(default_root_certs_path.get(), 1, &result));
}
// Try overridden roots if needed.
grpc_ssl_roots_override_result ovrd_res = GRPC_SSL_ROOTS_OVERRIDE_FAIL;

@ -26,6 +26,7 @@
#include <grpc/grpc_security.h>
#include <grpc/slice_buffer.h>
#include "src/core/lib/gprpp/global_config.h"
#include "src/core/lib/gprpp/ref_counted_ptr.h"
#include "src/core/lib/iomgr/error.h"
#include "src/core/lib/security/security_connector/security_connector.h"
@ -33,7 +34,10 @@
#include "src/core/tsi/transport_security.h"
#include "src/core/tsi/transport_security_interface.h"
/* --- Util. --- */
GPR_GLOBAL_CONFIG_DECLARE_STRING(grpc_default_ssl_roots_file_path);
GPR_GLOBAL_CONFIG_DECLARE_BOOL(grpc_not_use_system_ssl_roots);
/* --- Util --- */
/* --- URL schemes. --- */
#define GRPC_SSL_URL_SCHEME "https"

@ -154,7 +154,7 @@ void grpc_init(void) {
* at the appropriate time */
grpc_register_security_filters();
register_builtin_channel_init();
grpc_tracer_init("GRPC_TRACE");
grpc_tracer_init();
/* no more changes to channel init pipelines */
grpc_channel_init_finalize();
grpc_iomgr_start();

@ -42,13 +42,16 @@
#include "src/core/lib/gpr/string.h"
#include "src/core/lib/surface/completion_queue.h"
namespace grpc {
void ::grpc::experimental::ChannelResetConnectionBackoff(Channel* channel) {
grpc_impl::experimental::ChannelResetConnectionBackoff(channel);
}
namespace grpc_impl {
static internal::GrpcLibraryInitializer g_gli_initializer;
Channel::Channel(
const grpc::string& host, grpc_channel* channel,
std::vector<
std::unique_ptr<experimental::ClientInterceptorFactoryInterface>>
static ::grpc::internal::GrpcLibraryInitializer g_gli_initializer;
Channel::Channel(const grpc::string& host, grpc_channel* channel,
std::vector<std::unique_ptr<
::grpc::experimental::ClientInterceptorFactoryInterface>>
interceptor_creators)
: host_(host), c_channel_(channel) {
interceptor_creators_ = std::move(interceptor_creators);
@ -65,7 +68,8 @@ Channel::~Channel() {
namespace {
inline grpc_slice SliceFromArray(const char* arr, size_t len) {
return g_core_codegen_interface->grpc_slice_from_copied_buffer(arr, len);
return ::grpc::g_core_codegen_interface->grpc_slice_from_copied_buffer(arr,
len);
}
grpc::string GetChannelInfoField(grpc_channel* channel,
@ -103,10 +107,9 @@ void ChannelResetConnectionBackoff(Channel* channel) {
} // namespace experimental
internal::Call Channel::CreateCallInternal(const internal::RpcMethod& method,
ClientContext* context,
CompletionQueue* cq,
size_t interceptor_pos) {
::grpc::internal::Call Channel::CreateCallInternal(
const ::grpc::internal::RpcMethod& method, ::grpc::ClientContext* context,
::grpc::CompletionQueue* cq, size_t interceptor_pos) {
const bool kRegistered = method.channel_tag() && context->authority().empty();
grpc_call* c_call = nullptr;
if (kRegistered) {
@ -115,7 +118,7 @@ internal::Call Channel::CreateCallInternal(const internal::RpcMethod& method,
context->propagation_options_.c_bitmask(), cq->cq(),
method.channel_tag(), context->raw_deadline(), nullptr);
} else {
const string* host_str = nullptr;
const ::grpc::string* host_str = nullptr;
if (!context->authority_.empty()) {
host_str = &context->authority_;
} else if (!host_.empty()) {
@ -125,7 +128,7 @@ internal::Call Channel::CreateCallInternal(const internal::RpcMethod& method,
SliceFromArray(method.name(), strlen(method.name()));
grpc_slice host_slice;
if (host_str != nullptr) {
host_slice = SliceFromCopiedString(*host_str);
host_slice = ::grpc::SliceFromCopiedString(*host_str);
}
c_call = grpc_channel_create_call(
c_channel_, context->propagate_from_call_,
@ -147,17 +150,17 @@ internal::Call Channel::CreateCallInternal(const internal::RpcMethod& method,
interceptor_creators_, interceptor_pos);
context->set_call(c_call, shared_from_this());
return internal::Call(c_call, this, cq, info);
return ::grpc::internal::Call(c_call, this, cq, info);
}
::grpc::internal::Call Channel::CreateCall(const internal::RpcMethod& method,
ClientContext* context,
::grpc::internal::Call Channel::CreateCall(
const ::grpc::internal::RpcMethod& method, ::grpc::ClientContext* context,
CompletionQueue* cq) {
return CreateCallInternal(method, context, cq, 0);
}
void Channel::PerformOpsOnCall(internal::CallOpSetInterface* ops,
internal::Call* call) {
void Channel::PerformOpsOnCall(::grpc::internal::CallOpSetInterface* ops,
::grpc::internal::Call* call) {
ops->FillOps(
call); // Make a copy of call. It's fine since Call just has pointers
}
@ -173,7 +176,7 @@ grpc_connectivity_state Channel::GetState(bool try_to_connect) {
namespace {
class TagSaver final : public internal::CompletionQueueTag {
class TagSaver final : public ::grpc::internal::CompletionQueueTag {
public:
explicit TagSaver(void* tag) : tag_(tag) {}
~TagSaver() override {}
@ -191,7 +194,7 @@ class TagSaver final : public internal::CompletionQueueTag {
void Channel::NotifyOnStateChangeImpl(grpc_connectivity_state last_observed,
gpr_timespec deadline,
CompletionQueue* cq, void* tag) {
::grpc::CompletionQueue* cq, void* tag) {
TagSaver* tag_saver = new TagSaver(tag);
grpc_channel_watch_connectivity_state(c_channel_, last_observed, deadline,
cq->cq(), tag_saver);
@ -199,7 +202,7 @@ void Channel::NotifyOnStateChangeImpl(grpc_connectivity_state last_observed,
bool Channel::WaitForStateChangeImpl(grpc_connectivity_state last_observed,
gpr_timespec deadline) {
CompletionQueue cq;
::grpc::CompletionQueue cq;
bool ok = false;
void* tag = nullptr;
NotifyOnStateChangeImpl(last_observed, deadline, &cq, nullptr);
@ -214,7 +217,7 @@ class ShutdownCallback : public grpc_experimental_completion_queue_functor {
ShutdownCallback() { functor_run = &ShutdownCallback::Run; }
// TakeCQ takes ownership of the cq into the shutdown callback
// so that the shutdown callback will be responsible for destroying it
void TakeCQ(CompletionQueue* cq) { cq_ = cq; }
void TakeCQ(::grpc::CompletionQueue* cq) { cq_ = cq; }
// The Run function will get invoked by the completion queue library
// when the shutdown is actually complete
@ -225,17 +228,17 @@ class ShutdownCallback : public grpc_experimental_completion_queue_functor {
}
private:
CompletionQueue* cq_ = nullptr;
::grpc::CompletionQueue* cq_ = nullptr;
};
} // namespace
CompletionQueue* Channel::CallbackCQ() {
::grpc::CompletionQueue* Channel::CallbackCQ() {
// TODO(vjpai): Consider using a single global CQ for the default CQ
// if there is no explicit per-channel CQ registered
grpc::internal::MutexLock l(&mu_);
if (callback_cq_ == nullptr) {
auto* shutdown_callback = new ShutdownCallback;
callback_cq_ = new CompletionQueue(grpc_completion_queue_attributes{
callback_cq_ = new ::grpc::CompletionQueue(grpc_completion_queue_attributes{
GRPC_CQ_CURRENT_VERSION, GRPC_CQ_CALLBACK, GRPC_CQ_DEFAULT_POLLING,
shutdown_callback});
@ -245,4 +248,4 @@ CompletionQueue* Channel::CallbackCQ() {
return callback_cq_;
}
} // namespace grpc
} // namespace grpc_impl

@ -31,6 +31,11 @@
#include <grpcpp/server_context.h>
#include <grpcpp/support/time.h>
namespace grpc_impl {
class Channel;
}
namespace grpc {
class DefaultGlobalClientCallbacks final
@ -83,8 +88,8 @@ void ClientContext::AddMetadata(const grpc::string& meta_key,
send_initial_metadata_.insert(std::make_pair(meta_key, meta_value));
}
void ClientContext::set_call(grpc_call* call,
const std::shared_ptr<Channel>& channel) {
void ClientContext::set_call(
grpc_call* call, const std::shared_ptr<::grpc_impl::Channel>& channel) {
grpc::internal::MutexLock lock(&mu_);
GPR_ASSERT(call_ == nullptr);
call_ = call;

@ -71,7 +71,7 @@ std::shared_ptr<grpc::Channel> CreateCustomChannelWithInterceptors(
interceptor_creators) {
return creds ? creds->CreateChannelWithInterceptors(
target, args, std::move(interceptor_creators))
: ::grpc::CreateChannelInternal(
: grpc::CreateChannelInternal(
"",
grpc_lame_client_channel_create(
nullptr, GRPC_STATUS_INVALID_ARGUMENT,

@ -26,8 +26,8 @@ namespace grpc {
std::shared_ptr<Channel> CreateChannelInternal(
const grpc::string& host, grpc_channel* c_channel,
std::vector<
std::unique_ptr<experimental::ClientInterceptorFactoryInterface>>
std::vector<std::unique_ptr<
::grpc::experimental::ClientInterceptorFactoryInterface>>
interceptor_creators) {
return std::shared_ptr<Channel>(
new Channel(host, c_channel, std::move(interceptor_creators)));

@ -30,8 +30,8 @@ namespace grpc {
std::shared_ptr<Channel> CreateChannelInternal(
const grpc::string& host, grpc_channel* c_channel,
std::vector<
std::unique_ptr<experimental::ClientInterceptorFactoryInterface>>
std::vector<std::unique_ptr<
::grpc::experimental::ClientInterceptorFactoryInterface>>
interceptor_creators);
} // namespace grpc

@ -34,7 +34,7 @@ std::shared_ptr<grpc::Channel> CreateInsecureChannelFromFd(
const grpc::string& target, int fd) {
grpc::internal::GrpcLibrary init_lib;
init_lib.init();
return grpc::CreateChannelInternal(
return ::grpc::CreateChannelInternal(
"", grpc_insecure_channel_create_from_fd(target.c_str(), fd, nullptr),
std::vector<std::unique_ptr<
grpc::experimental::ClientInterceptorFactoryInterface>>());
@ -46,7 +46,7 @@ std::shared_ptr<grpc::Channel> CreateCustomInsecureChannelFromFd(
init_lib.init();
grpc_channel_args channel_args;
args.SetChannelArgs(&channel_args);
return grpc::CreateChannelInternal(
return ::grpc::CreateChannelInternal(
"",
grpc_insecure_channel_create_from_fd(target.c_str(), fd, &channel_args),
std::vector<std::unique_ptr<
@ -65,7 +65,7 @@ CreateCustomInsecureChannelWithInterceptorsFromFd(
init_lib.init();
grpc_channel_args channel_args;
args.SetChannelArgs(&channel_args);
return grpc::CreateChannelInternal(
return ::grpc::CreateChannelInternal(
"",
grpc_insecure_channel_create_from_fd(target.c_str(), fd, &channel_args),
std::move(interceptor_creators));

@ -29,6 +29,8 @@
namespace grpc_impl {
class Channel;
class SecureChannelCredentials final : public ChannelCredentials {
public:
explicit SecureChannelCredentials(grpc_channel_credentials* c_creds);

@ -30,7 +30,6 @@ namespace grpc {
grpc_linked_mdelem* MetadataBatch::AddMetadata(const string& key,
const string& value) {
grpc_linked_mdelem* storage = new grpc_linked_mdelem;
memset(storage, 0, sizeof(grpc_linked_mdelem));
storage->md = grpc_mdelem_from_slices(SliceFromCopiedString(key),
SliceFromCopiedString(value));
GRPC_LOG_IF_ERROR("MetadataBatch::AddMetadata",

@ -24,9 +24,9 @@
#include <grpcpp/impl/grpc_library.h>
#include <grpcpp/support/time.h>
namespace grpc {
namespace grpc_impl {
static internal::GrpcLibraryInitializer g_gli_initializer;
static ::grpc::internal::GrpcLibraryInitializer g_gli_initializer;
// 'CompletionQueue' constructor can safely call GrpcLibraryCodegen(false) here
// i.e not have GrpcLibraryCodegen call grpc_init(). This is because, to create
@ -52,7 +52,8 @@ CompletionQueue::NextStatus CompletionQueue::AsyncNextInternal(
case GRPC_QUEUE_SHUTDOWN:
return SHUTDOWN;
case GRPC_OP_COMPLETE:
auto core_cq_tag = static_cast<internal::CompletionQueueTag*>(ev.tag);
auto core_cq_tag =
static_cast<::grpc::internal::CompletionQueueTag*>(ev.tag);
*ok = ev.success != 0;
*tag = core_cq_tag;
if (core_cq_tag->FinalizeResult(tag, ok)) {
@ -79,7 +80,8 @@ bool CompletionQueue::CompletionQueueTLSCache::Flush(void** tag, bool* ok) {
flushed_ = true;
if (grpc_completion_queue_thread_local_cache_flush(cq_->cq_, &res_tag,
&res)) {
auto core_cq_tag = static_cast<internal::CompletionQueueTag*>(res_tag);
auto core_cq_tag =
static_cast<::grpc::internal::CompletionQueueTag*>(res_tag);
*ok = res == 1;
if (core_cq_tag->FinalizeResult(tag, ok)) {
return true;
@ -88,4 +90,4 @@ bool CompletionQueue::CompletionQueueTLSCache::Flush(void** tag, bool* ok) {
return false;
}
} // namespace grpc
} // namespace grpc_impl

@ -61,8 +61,7 @@
NSBundle *resourceBundle = [NSBundle
bundleWithURL:[[bundle resourceURL] URLByAppendingPathComponent:resourceBundlePath]];
NSString *path = [resourceBundle pathForResource:rootsPEM ofType:@"pem"];
setenv(GRPC_DEFAULT_SSL_ROOTS_FILE_PATH_ENV_VAR,
[path cStringUsingEncoding:NSUTF8StringEncoding], 1);
setenv("GRPC_DEFAULT_SSL_ROOTS_FILE_PATH", [path cStringUsingEncoding:NSUTF8StringEncoding], 1);
});
NSData *rootsASCII = nil;

@ -37,11 +37,11 @@
#include <grpc/support/log.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/gpr/tmpfile.h"
#include "src/core/lib/security/credentials/credentials.h"
#include "src/core/lib/security/security_connector/ssl_utils.h"
#include "test/core/end2end/data/ssl_test_data.h"
#include "test/core/util/port.h"
#include "test/core/util/test_config.h"
@ -172,7 +172,7 @@ static char *roots_filename;
GPR_ASSERT(roots_file != NULL);
GPR_ASSERT(fwrite(test_root_cert, 1, roots_size, roots_file) == roots_size);
fclose(roots_file);
gpr_setenv(GRPC_DEFAULT_SSL_ROOTS_FILE_PATH_ENV_VAR, roots_filename);
GPR_GLOBAL_CONFIG_SET(grpc_default_ssl_roots_file_path, roots_filename);
grpc_init();

@ -30,6 +30,7 @@
#include <grpc/grpc_security.h>
#include <grpc/support/alloc.h>
#include <grpc/support/log.h>
#include "completion_queue.h"
#include "channel_credentials.h"
@ -247,12 +248,12 @@ void create_and_add_channel_to_persistent_list(
// If no channel can be deleted from the persistent map,
// do not persist this one.
create_channel(channel, target, args, creds);
php_printf("[Warning] The number of channel for the"
gpr_log(GPR_INFO, "[Warning] The number of channel for the"
" target %s is maxed out bounded.\n", target);
php_printf("[Warning] Target upper bound: %d. Current size: %d.\n",
gpr_log(GPR_INFO, "[Warning] Target upper bound: %d. Current size: %d.\n",
target_bound_status->upper_bound,
target_bound_status->current_count);
php_printf("[Warning] Target %s will not be persisted.\n", target);
gpr_log(GPR_INFO, "[Warning] Target %s will not be persisted.\n", target);
return;
}
}

@ -1000,6 +1000,11 @@ def _unsubscribe(state, callback):
break
def _unsubscribe_all(state):
with state.lock:
del state.callbacks_and_connectivities[:]
def _augment_options(base_options, compression):
compression_option = _compression.create_channel_option(compression)
return tuple(base_options) + compression_option + ((
@ -1067,6 +1072,7 @@ class Channel(grpc.Channel):
_common.encode(method), request_serializer, response_deserializer)
def _close(self):
_unsubscribe_all(self._connectivity_state)
self._channel.close(cygrpc.StatusCode.cancelled, 'Channel closed!')
cygrpc.fork_unregister_channel(self)
_moot(self._connectivity_state)

@ -385,6 +385,7 @@ CORE_SOURCE_FILES = [
'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv.cc',
'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_posix.cc',
'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_windows.cc',
'src/core/ext/filters/client_channel/resolver/dns/dns_resolver_selection.cc',
'src/core/ext/filters/client_channel/resolver/dns/native/dns_resolver.cc',
'src/core/ext/filters/client_channel/resolver/sockaddr/sockaddr_resolver.cc',
'src/core/ext/filters/census/grpc_context.cc',

@ -140,7 +140,7 @@
s.name = 'gRPC-C++'
# TODO (mxyan): use version that match gRPC version when pod is stabilized
# version = '${settings.version}'
version = '${modify_podspec_version_string('0.0.8', settings.version)}'
version = '${modify_podspec_version_string('0.0.9', settings.version)}'
s.version = version
s.summary = 'gRPC C++ library'
s.homepage = 'https://grpc.io'
@ -188,7 +188,7 @@
s.default_subspecs = 'Interface', 'Implementation'
# Certificates, to be able to establish TLS connections:
s.resource_bundles = { 'gRPCCertificates' => ['etc/roots.pem'] }
s.resource_bundles = { 'gRPCCertificates-Cpp' => ['etc/roots.pem'] }
s.header_mappings_dir = 'include/grpcpp'

@ -39,7 +39,6 @@
#include <grpc/support/log.h>
#include <grpc/support/time.h>
#include "src/core/ext/transport/chttp2/transport/chttp2_transport.h"
#include "src/core/lib/gpr/env.h"
#include "src/core/lib/iomgr/endpoint_pair.h"
#include "src/core/lib/surface/channel.h"
#include "src/core/lib/surface/completion_queue.h"

@ -25,9 +25,9 @@
#include <grpc/support/log.h>
#include <grpc/support/string_util.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/security/security_connector/ssl_utils.h"
#include "test/core/end2end/cq_verifier.h"
#include "test/core/util/port.h"
#include "test/core/util/subprocess.h"
@ -133,7 +133,7 @@ int main(int argc, char** argv) {
strcpy(root, ".");
}
if (argc == 2) {
gpr_setenv("GRPC_DEFAULT_SSL_ROOTS_FILE_PATH", argv[1]);
GPR_GLOBAL_CONFIG_SET(grpc_default_ssl_roots_file_path, argv[1]);
}
/* figure out our test name */
tmp = lunder - 1;

@ -21,8 +21,8 @@
#include <grpc/support/log.h>
#include "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.h"
#include "src/core/ext/filters/client_channel/resolver/dns/dns_resolver_selection.h"
#include "src/core/ext/filters/client_channel/resolver_registry.h"
#include "src/core/lib/gpr/env.h"
#include "src/core/lib/gpr/string.h"
#include "src/core/lib/iomgr/combiner.h"
#include "test/core/util/test_config.h"
@ -78,13 +78,13 @@ int main(int argc, char** argv) {
test_succeeds(dns, "dns:10.2.1.1:1234");
test_succeeds(dns, "dns:www.google.com");
test_succeeds(dns, "dns:///www.google.com");
char* resolver_env = gpr_getenv("GRPC_DNS_RESOLVER");
if (resolver_env != nullptr && gpr_stricmp(resolver_env, "native") == 0) {
grpc_core::UniquePtr<char> resolver =
GPR_GLOBAL_CONFIG_GET(grpc_dns_resolver);
if (gpr_stricmp(resolver.get(), "native") == 0) {
test_fails(dns, "dns://8.8.8.8/8.8.8.8:8888");
} else {
test_succeeds(dns, "dns://8.8.8.8/8.8.8.8:8888");
}
gpr_free(resolver_env);
{
grpc_core::ExecCtx exec_ctx;
GRPC_COMBINER_UNREF(g_combiner, "test");

@ -33,7 +33,7 @@
#include "src/core/ext/filters/http/server/http_server_filter.h"
#include "src/core/ext/transport/chttp2/transport/chttp2_transport.h"
#include "src/core/lib/channel/connected_channel.h"
#include "src/core/lib/gpr/env.h"
#include "src/core/lib/debug/trace.h"
#include "src/core/lib/gpr/host_port.h"
#include "src/core/lib/surface/channel.h"
#include "src/core/lib/surface/server.h"
@ -105,7 +105,7 @@ int main(int argc, char** argv) {
/* force tracing on, with a value to force many
code paths in trace.c to be taken */
gpr_setenv("GRPC_TRACE", "doesnt-exist,http,all");
GPR_GLOBAL_CONFIG_SET(grpc_trace, "doesnt-exist,http,all");
#ifdef GRPC_POSIX_SOCKET
g_fixture_slowdown_factor = isatty(STDOUT_FILENO) ? 10 : 1;

@ -35,7 +35,7 @@
#include "src/core/ext/filters/http/server/http_server_filter.h"
#include "src/core/ext/transport/chttp2/transport/chttp2_transport.h"
#include "src/core/lib/channel/connected_channel.h"
#include "src/core/lib/gpr/env.h"
#include "src/core/lib/debug/trace.h"
#include "src/core/lib/iomgr/endpoint_pair.h"
#include "src/core/lib/iomgr/iomgr.h"
#include "src/core/lib/surface/channel.h"
@ -133,7 +133,8 @@ int main(int argc, char** argv) {
/* force tracing on, with a value to force many
code paths in trace.c to be taken */
gpr_setenv("GRPC_TRACE", "doesnt-exist,http,all");
GPR_GLOBAL_CONFIG_SET(grpc_trace, "doesnt-exist,http,all");
#ifdef GRPC_POSIX_SOCKET
g_fixture_slowdown_factor = isatty(STDOUT_FILENO) ? 10 : 1;
#else

@ -35,6 +35,7 @@
#include "src/core/lib/gprpp/thd.h"
#include "src/core/lib/security/credentials/credentials.h"
#include "src/core/lib/security/credentials/tls/grpc_tls_credentials_options.h"
#include "src/core/lib/security/security_connector/ssl_utils.h"
#include "test/core/end2end/data/ssl_test_data.h"
#include "test/core/util/port.h"
#include "test/core/util/test_config.h"
@ -277,7 +278,7 @@ int main(int argc, char** argv) {
GPR_ASSERT(roots_file != nullptr);
GPR_ASSERT(fwrite(test_root_cert, 1, roots_size, roots_file) == roots_size);
fclose(roots_file);
gpr_setenv(GRPC_DEFAULT_SSL_ROOTS_FILE_PATH_ENV_VAR, roots_filename);
GPR_GLOBAL_CONFIG_SET(grpc_default_ssl_roots_file_path, roots_filename);
grpc_init();
for (size_t ind = 0; ind < sizeof(configs) / sizeof(*configs); ind++) {
grpc_end2end_tests(argc, argv, configs[ind]);

@ -25,11 +25,11 @@
#include <grpc/support/log.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/gpr/tmpfile.h"
#include "src/core/lib/security/credentials/credentials.h"
#include "src/core/lib/security/security_connector/ssl_utils.h"
#include "test/core/end2end/data/ssl_test_data.h"
#include "test/core/util/port.h"
#include "test/core/util/test_config.h"
@ -167,7 +167,7 @@ int main(int argc, char** argv) {
GPR_ASSERT(roots_file != nullptr);
GPR_ASSERT(fwrite(test_root_cert, 1, roots_size, roots_file) == roots_size);
fclose(roots_file);
gpr_setenv(GRPC_DEFAULT_SSL_ROOTS_FILE_PATH_ENV_VAR, roots_filename);
GPR_GLOBAL_CONFIG_SET(grpc_default_ssl_roots_file_path, roots_filename);
grpc_init();

@ -25,11 +25,11 @@
#include <grpc/support/log.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/gpr/tmpfile.h"
#include "src/core/lib/security/credentials/credentials.h"
#include "src/core/lib/security/security_connector/ssl_utils.h"
#include "test/core/end2end/data/ssl_test_data.h"
#include "test/core/util/port.h"
#include "test/core/util/test_config.h"
@ -190,7 +190,7 @@ int main(int argc, char** argv) {
GPR_ASSERT(roots_file != nullptr);
GPR_ASSERT(fwrite(test_root_cert, 1, roots_size, roots_file) == roots_size);
fclose(roots_file);
gpr_setenv(GRPC_DEFAULT_SSL_ROOTS_FILE_PATH_ENV_VAR, roots_filename);
GPR_GLOBAL_CONFIG_SET(grpc_default_ssl_roots_file_path, roots_filename);
grpc_init();

@ -25,11 +25,11 @@
#include <grpc/support/log.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/gpr/tmpfile.h"
#include "src/core/lib/security/credentials/credentials.h"
#include "src/core/lib/security/security_connector/ssl_utils.h"
#include "test/core/end2end/data/ssl_test_data.h"
#include "test/core/end2end/fixtures/proxy.h"
#include "test/core/util/port.h"
@ -208,7 +208,7 @@ int main(int argc, char** argv) {
GPR_ASSERT(roots_file != nullptr);
GPR_ASSERT(fwrite(test_root_cert, 1, roots_size, roots_file) == roots_size);
fclose(roots_file);
gpr_setenv(GRPC_DEFAULT_SSL_ROOTS_FILE_PATH_ENV_VAR, roots_filename);
GPR_GLOBAL_CONFIG_SET(grpc_default_ssl_roots_file_path, roots_filename);
grpc_init();

@ -25,11 +25,11 @@
#include <grpc/support/log.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/gpr/tmpfile.h"
#include "src/core/lib/security/credentials/credentials.h"
#include "src/core/lib/security/security_connector/ssl_utils.h"
#include "test/core/end2end/cq_verifier.h"
#include "test/core/end2end/data/ssl_test_data.h"
#include "test/core/util/port.h"
@ -366,7 +366,7 @@ int main(int argc, char** argv) {
GPR_ASSERT(roots_file != nullptr);
GPR_ASSERT(fwrite(test_root_cert, 1, roots_size, roots_file) == roots_size);
fclose(roots_file);
gpr_setenv(GRPC_DEFAULT_SSL_ROOTS_FILE_PATH_ENV_VAR, roots_filename);
GPR_GLOBAL_CONFIG_SET(grpc_default_ssl_roots_file_path, roots_filename);
grpc_init();
::testing::InitGoogleTest(&argc, argv);

@ -25,11 +25,11 @@
#include <grpc/support/log.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/gpr/tmpfile.h"
#include "src/core/lib/security/credentials/credentials.h"
#include "src/core/lib/security/security_connector/ssl_utils.h"
#include "test/core/end2end/cq_verifier.h"
#include "test/core/end2end/data/ssl_test_data.h"
#include "test/core/util/port.h"
@ -265,7 +265,7 @@ int main(int argc, char** argv) {
GPR_ASSERT(roots_file != nullptr);
GPR_ASSERT(fwrite(test_root_cert, 1, roots_size, roots_file) == roots_size);
fclose(roots_file);
gpr_setenv(GRPC_DEFAULT_SSL_ROOTS_FILE_PATH_ENV_VAR, roots_filename);
GPR_GLOBAL_CONFIG_SET(grpc_default_ssl_roots_file_path, roots_filename);
grpc_init();
::testing::InitGoogleTest(&argc, argv);

@ -28,11 +28,15 @@
#include "src/core/ext/transport/chttp2/transport/frame_ping.h"
#include "src/core/lib/channel/channel_args.h"
#include "src/core/lib/gpr/env.h"
#include "src/core/lib/gpr/useful.h"
#include "src/core/lib/iomgr/exec_ctx.h"
#include "src/core/lib/iomgr/iomgr.h"
#include "test/core/end2end/cq_verifier.h"
#ifdef GRPC_POSIX_SOCKET
#include "src/core/lib/iomgr/ev_posix.h"
#endif // GRPC_POSIX_SOCKET
static void* tag(intptr_t t) { return (void*)t; }
static grpc_end2end_test_fixture begin_test(grpc_end2end_test_config config,
@ -225,13 +229,13 @@ static void test_keepalive_timeout(grpc_end2end_test_config config) {
* 200ms. In the success case, each ping ack should reset the keepalive timer so
* that the keepalive ping is never sent. */
static void test_read_delays_keepalive(grpc_end2end_test_config config) {
char* poller = gpr_getenv("GRPC_POLL_STRATEGY");
#ifdef GRPC_POSIX_SOCKET
grpc_core::UniquePtr<char> poller = GPR_GLOBAL_CONFIG_GET(grpc_poll_strategy);
/* It is hard to get the timing right for the polling engine poll. */
if (poller != nullptr && (0 == strcmp(poller, "poll"))) {
gpr_free(poller);
if ((0 == strcmp(poller.get(), "poll"))) {
return;
}
gpr_free(poller);
#endif // GRPC_POSIX_SOCKET
const int kPingIntervalMS = 100;
grpc_arg keepalive_arg_elems[3];
keepalive_arg_elems[0].type = GRPC_ARG_INTEGER;

@ -21,9 +21,14 @@
#include <stdbool.h>
#include <string.h>
#include "src/core/lib/gpr/env.h"
#include "src/core/lib/gprpp/global_config.h"
#include "test/core/util/test_config.h"
// Config declaration is supposed to be located at log.h but
// log.h doesn't include global_config headers because it has to
// be a strict C so declaration statement gets to be here.
GPR_GLOBAL_CONFIG_DECLARE_STRING(grpc_verbosity);
static bool log_func_reached = false;
static void test_callback(gpr_log_func_args* args) {
@ -67,7 +72,7 @@ int main(int argc, char** argv) {
/* gpr_log_verbosity_init() will be effective only once, and only before
* gpr_set_log_verbosity() is called */
gpr_setenv("GRPC_VERBOSITY", "ERROR");
GPR_GLOBAL_CONFIG_SET(grpc_verbosity, "ERROR");
gpr_log_verbosity_init();
test_log_function_reached(GPR_ERROR);
@ -75,7 +80,7 @@ int main(int argc, char** argv) {
test_log_function_unreached(GPR_DEBUG);
/* gpr_log_verbosity_init() should not be effective */
gpr_setenv("GRPC_VERBOSITY", "DEBUG");
GPR_GLOBAL_CONFIG_SET(grpc_verbosity, "DEBUG");
gpr_log_verbosity_init();
test_log_function_reached(GPR_ERROR);
test_log_function_unreached(GPR_INFO);
@ -97,7 +102,7 @@ int main(int argc, char** argv) {
test_log_function_unreached(GPR_DEBUG);
/* gpr_log_verbosity_init() should not be effective */
gpr_setenv("GRPC_VERBOSITY", "DEBUG");
GPR_GLOBAL_CONFIG_SET(grpc_verbosity, "DEBUG");
gpr_log_verbosity_init();
test_log_function_reached(GPR_ERROR);
test_log_function_unreached(GPR_INFO);

@ -29,6 +29,7 @@
#include "src/core/lib/gpr/env.h"
#include "src/core/lib/iomgr/iomgr.h"
#include "src/core/lib/security/security_connector/ssl_utils.h"
#include "test/core/util/port.h"
#include "test/core/util/subprocess.h"
#include "test/core/util/test_config.h"
@ -184,7 +185,7 @@ int main(int argc, char** argv) {
/* Set the environment variable for the SSL certificate file */
char* pem_file;
gpr_asprintf(&pem_file, "%s/src/core/tsi/test_creds/ca.pem", root);
gpr_setenv(GRPC_DEFAULT_SSL_ROOTS_FILE_PATH_ENV_VAR, pem_file);
GPR_GLOBAL_CONFIG_SET(grpc_default_ssl_roots_file_path, pem_file);
gpr_free(pem_file);
/* start the server */

@ -29,6 +29,7 @@
#include <grpc/support/sync.h>
#include <grpc/support/time.h>
#include "src/core/ext/filters/client_channel/resolver/dns/dns_resolver_selection.h"
#include "src/core/lib/gpr/env.h"
#include "src/core/lib/gpr/string.h"
#include "src/core/lib/gpr/useful.h"
@ -224,15 +225,16 @@ int main(int argc, char** argv) {
// --resolver will always be the first one, so only parse the first argument
// (other arguments may be unknown to cl)
gpr_cmdline_parse(cl, argc > 2 ? 2 : argc, argv);
const char* cur_resolver = gpr_getenv("GRPC_DNS_RESOLVER");
if (cur_resolver != nullptr && strlen(cur_resolver) != 0) {
grpc_core::UniquePtr<char> resolver =
GPR_GLOBAL_CONFIG_GET(grpc_dns_resolver);
if (strlen(resolver.get()) != 0) {
gpr_log(GPR_INFO, "Warning: overriding resolver setting of %s",
cur_resolver);
resolver.get());
}
if (gpr_stricmp(resolver_type, "native") == 0) {
gpr_setenv("GRPC_DNS_RESOLVER", "native");
GPR_GLOBAL_CONFIG_SET(grpc_dns_resolver, "native");
} else if (gpr_stricmp(resolver_type, "ares") == 0) {
gpr_setenv("GRPC_DNS_RESOLVER", "ares");
GPR_GLOBAL_CONFIG_SET(grpc_dns_resolver, "ares");
} else {
gpr_log(GPR_ERROR, "--resolver_type was not set to ares or native");
abort();
@ -246,12 +248,12 @@ int main(int argc, char** argv) {
// c-ares resolver doesn't support UDS (ability for native DNS resolver
// to handle this is only expected to be used by servers, which
// unconditionally use the native DNS resolver).
char* resolver_env = gpr_getenv("GRPC_DNS_RESOLVER");
if (resolver_env == nullptr || gpr_stricmp(resolver_env, "native") == 0) {
grpc_core::UniquePtr<char> resolver =
GPR_GLOBAL_CONFIG_GET(grpc_dns_resolver);
if (gpr_stricmp(resolver.get(), "native") == 0) {
test_unix_socket();
test_unix_socket_path_name_too_long();
}
gpr_free(resolver_env);
}
gpr_cmdline_destroy(cl);

@ -27,7 +27,7 @@
#include <string.h>
#include "src/core/lib/gpr/env.h"
#include "src/core/ext/filters/client_channel/resolver/dns/dns_resolver_selection.h"
#include "src/core/lib/gpr/string.h"
#include "src/core/lib/iomgr/executor.h"
#include "src/core/lib/iomgr/iomgr.h"
@ -347,16 +347,17 @@ int main(int argc, char** argv) {
// --resolver will always be the first one, so only parse the first argument
// (other arguments may be unknown to cl)
gpr_cmdline_parse(cl, argc > 2 ? 2 : argc, argv);
const char* cur_resolver = gpr_getenv("GRPC_DNS_RESOLVER");
if (cur_resolver != nullptr && strlen(cur_resolver) != 0) {
grpc_core::UniquePtr<char> resolver =
GPR_GLOBAL_CONFIG_GET(grpc_dns_resolver);
if (strlen(resolver.get()) != 0) {
gpr_log(GPR_INFO, "Warning: overriding resolver setting of %s",
cur_resolver);
resolver.get());
}
if (gpr_stricmp(resolver_type, "native") == 0) {
gpr_setenv("GRPC_DNS_RESOLVER", "native");
GPR_GLOBAL_CONFIG_SET(grpc_dns_resolver, "native");
} else if (gpr_stricmp(resolver_type, "ares") == 0) {
#ifndef GRPC_UV
gpr_setenv("GRPC_DNS_RESOLVER", "ares");
GPR_GLOBAL_CONFIG_SET(grpc_dns_resolver, "ares");
#endif
} else {
gpr_log(GPR_ERROR, "--resolver_type was not set to ares or native");

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

Loading…
Cancel
Save