Merge remote-tracking branch 'upstream/master' into config-isolation

pull/16190/head
Muxi Yan 6 years ago
commit 62693ec1bd
  1. 8
      .github/CODEOWNERS
  2. 71
      BUILD
  3. 63
      CMakeLists.txt
  4. 157
      Makefile
  5. 5
      WORKSPACE
  6. 2
      bazel/OWNERS
  7. 68
      build.yaml
  8. 2
      build_config.rb
  9. 2
      cmake/OWNERS
  10. 3
      doc/g_stands_for.md
  11. 2
      doc/ssl-performance.md
  12. 4
      gRPC-C++.podspec
  13. 2
      gRPC-Core.podspec
  14. 2
      gRPC-ProtoRPC.podspec
  15. 2
      gRPC-RxLibrary.podspec
  16. 2
      gRPC.podspec
  17. 2
      grpc.def
  18. 1
      grpc.gyp
  19. 4
      include/grpc/grpc.h
  20. 8
      include/grpc/grpc_posix.h
  21. 4
      include/grpcpp/opencensus.h
  22. 4
      package.xml
  23. 2
      src/core/ext/filters/client_channel/OWNERS
  24. 121
      src/core/ext/filters/client_channel/client_channel.cc
  25. 8
      src/core/ext/filters/client_channel/client_channel.h
  26. 1
      src/core/ext/filters/client_channel/client_channel_channelz.cc
  27. 7
      src/core/ext/filters/client_channel/client_channel_channelz.h
  28. 1
      src/core/ext/filters/client_channel/http_connect_handshaker.cc
  29. 10
      src/core/ext/filters/client_channel/lb_policy.h
  30. 12
      src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc
  31. 13
      src/core/ext/filters/client_channel/lb_policy/pick_first/pick_first.cc
  32. 13
      src/core/ext/filters/client_channel/lb_policy/round_robin/round_robin.cc
  33. 2
      src/core/ext/filters/client_channel/lb_policy/subchannel_list.h
  34. 140
      src/core/ext/filters/client_channel/lb_policy/xds/client_load_reporting_filter.cc
  35. 29
      src/core/ext/filters/client_channel/lb_policy/xds/client_load_reporting_filter.h
  36. 307
      src/core/ext/filters/client_channel/lb_policy/xds/load_balancer_api.cc
  37. 89
      src/core/ext/filters/client_channel/lb_policy/xds/load_balancer_api.h
  38. 1894
      src/core/ext/filters/client_channel/lb_policy/xds/xds.cc
  39. 36
      src/core/ext/filters/client_channel/lb_policy/xds/xds.h
  40. 26
      src/core/ext/filters/client_channel/lb_policy/xds/xds_channel.cc
  41. 36
      src/core/ext/filters/client_channel/lb_policy/xds/xds_channel.h
  42. 107
      src/core/ext/filters/client_channel/lb_policy/xds/xds_channel_secure.cc
  43. 85
      src/core/ext/filters/client_channel/lb_policy/xds/xds_client_stats.cc
  44. 72
      src/core/ext/filters/client_channel/lb_policy/xds/xds_client_stats.h
  45. 125
      src/core/ext/filters/client_channel/subchannel.cc
  46. 13
      src/core/ext/filters/client_channel/subchannel.h
  47. 5
      src/core/ext/filters/http/client_authority_filter.cc
  48. 2
      src/core/ext/transport/chttp2/client/chttp2_connector.cc
  49. 25
      src/core/ext/transport/chttp2/server/chttp2_server.cc
  50. 2
      src/core/ext/transport/chttp2/server/insecure/server_chttp2_posix.cc
  51. 3
      src/core/ext/transport/chttp2/transport/chttp2_transport.cc
  52. 4
      src/core/ext/transport/inproc/inproc_transport.cc
  53. 76
      src/core/lib/channel/channelz.cc
  54. 29
      src/core/lib/channel/channelz.h
  55. 115
      src/core/lib/channel/channelz_registry.cc
  56. 20
      src/core/lib/channel/channelz_registry.h
  57. 5
      src/core/lib/channel/handshaker_factory.cc
  58. 2
      src/core/lib/channel/handshaker_factory.h
  59. 8
      src/core/lib/channel/handshaker_registry.cc
  60. 1
      src/core/lib/channel/handshaker_registry.h
  61. 8
      src/core/lib/gprpp/inlined_vector.h
  62. 5
      src/core/lib/http/httpcli_security_connector.cc
  63. 2
      src/core/lib/iomgr/ev_posix.cc
  64. 3
      src/core/lib/iomgr/socket_utils_common_posix.cc
  65. 6
      src/core/lib/iomgr/tcp_posix.cc
  66. 2
      src/core/lib/iomgr/timer_manager.cc
  67. 7
      src/core/lib/iomgr/wakeup_fd_eventfd.cc
  68. 3
      src/core/lib/security/credentials/plugin/plugin_credentials.cc
  69. 16
      src/core/lib/security/security_connector/alts_security_connector.cc
  70. 5
      src/core/lib/security/security_connector/local_security_connector.cc
  71. 11
      src/core/lib/security/security_connector/security_connector.cc
  72. 7
      src/core/lib/security/security_connector/security_connector.h
  73. 10
      src/core/lib/security/transport/security_handshaker.cc
  74. 14
      src/core/lib/surface/channel.cc
  75. 4
      src/core/lib/surface/channel.h
  76. 7
      src/core/lib/surface/completion_queue.cc
  77. 35
      src/core/lib/surface/server.cc
  78. 15
      src/core/lib/surface/server.h
  79. 4
      src/core/lib/surface/version.cc
  80. 5
      src/core/lib/transport/metadata.cc
  81. 5
      src/core/lib/transport/metadata.h
  82. 1
      src/core/lib/transport/metadata_batch.cc
  83. 3
      src/core/tsi/alts/handshaker/alts_tsi_handshaker.cc
  84. 5
      src/core/tsi/alts/handshaker/alts_tsi_handshaker.h
  85. 2
      src/cpp/common/version_cc.cc
  86. 18
      src/cpp/server/channelz/channelz_service.cc
  87. 5
      src/cpp/server/channelz/channelz_service.h
  88. 23
      src/csharp/.editorconfig
  89. 1
      src/csharp/Grpc.Core.Tests/SanityTest.cs
  90. 40
      src/csharp/Grpc.Core/Internal/UnmanagedLibrary.cs
  91. 2
      src/csharp/Grpc.Core/Version.csproj.include
  92. 4
      src/csharp/Grpc.Core/VersionInfo.cs
  93. 85
      src/csharp/Grpc.Tools.Tests/CSharpGeneratorTest.cs
  94. 88
      src/csharp/Grpc.Tools.Tests/CppGeneratorTest.cs
  95. 146
      src/csharp/Grpc.Tools.Tests/DepFileUtilTest.cs
  96. 55
      src/csharp/Grpc.Tools.Tests/GeneratorTest.cs
  97. 78
      src/csharp/Grpc.Tools.Tests/Grpc.Tools.Tests.csproj
  98. 33
      src/csharp/Grpc.Tools.Tests/NUnitMain.cs
  99. 76
      src/csharp/Grpc.Tools.Tests/ProtoCompileBasicTest.cs
  100. 179
      src/csharp/Grpc.Tools.Tests/ProtoCompileCommandLineGeneratorTest.cs
  101. Some files were not shown because too many files have changed in this diff Show More

@ -2,8 +2,8 @@
# Uses OWNERS files in different modules throughout the
# repository as the source of truth for module ownership.
/**/OWNERS @markdroth @nicolasnoble @a11r
/bazel/** @nicolasnoble @dgquintas @a11r @vjpai
/cmake/** @jtattermusch @nicolasnoble @mehrdada
/src/core/ext/filters/client_channel/** @markdroth @dgquintas @AspirinSJL
/tools/dockerfile/** @jtattermusch @mehrdada @nicolasnoble
/bazel/** @nicolasnoble @jtattermusch @a11r @vjpai
/cmake/** @jtattermusch @nicolasnoble @apolcyn
/src/core/ext/filters/client_channel/** @markdroth @apolcyn @AspirinSJL
/tools/dockerfile/** @jtattermusch @apolcyn @nicolasnoble
/tools/run_tests/performance/** @ncteisen @apolcyn @jtattermusch

71
BUILD

@ -64,11 +64,11 @@ config_setting(
)
# This should be updated along with build.yaml
g_stands_for = "gao"
g_stands_for = "gizmo"
core_version = "6.0.0-dev"
version = "1.16.0-dev"
version = "1.17.0-dev"
GPR_PUBLIC_HDRS = [
"include/grpc/support/alloc.h",
@ -1265,6 +1265,73 @@ grpc_cc_library(
],
)
grpc_cc_library(
name = "grpc_lb_policy_xds",
srcs = [
"src/core/ext/filters/client_channel/lb_policy/xds/client_load_reporting_filter.cc",
"src/core/ext/filters/client_channel/lb_policy/xds/xds.cc",
"src/core/ext/filters/client_channel/lb_policy/xds/xds_channel.cc",
"src/core/ext/filters/client_channel/lb_policy/xds/xds_client_stats.cc",
"src/core/ext/filters/client_channel/lb_policy/xds/load_balancer_api.cc",
"src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/google/protobuf/duration.pb.c",
"src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/google/protobuf/timestamp.pb.c",
"src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.c",
],
hdrs = [
"src/core/ext/filters/client_channel/lb_policy/xds/client_load_reporting_filter.h",
"src/core/ext/filters/client_channel/lb_policy/xds/xds.h",
"src/core/ext/filters/client_channel/lb_policy/xds/xds_channel.h",
"src/core/ext/filters/client_channel/lb_policy/xds/xds_client_stats.h",
"src/core/ext/filters/client_channel/lb_policy/xds/load_balancer_api.h",
"src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/google/protobuf/duration.pb.h",
"src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/google/protobuf/timestamp.pb.h",
"src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.h",
],
external_deps = [
"nanopb",
],
language = "c++",
deps = [
"grpc_base",
"grpc_client_channel",
"grpc_resolver_fake",
],
)
grpc_cc_library(
name = "grpc_lb_policy_xds_secure",
srcs = [
"src/core/ext/filters/client_channel/lb_policy/xds/client_load_reporting_filter.cc",
"src/core/ext/filters/client_channel/lb_policy/xds/xds.cc",
"src/core/ext/filters/client_channel/lb_policy/xds/xds_channel_secure.cc",
"src/core/ext/filters/client_channel/lb_policy/xds/xds_client_stats.cc",
"src/core/ext/filters/client_channel/lb_policy/xds/load_balancer_api.cc",
"src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/google/protobuf/duration.pb.c",
"src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/google/protobuf/timestamp.pb.c",
"src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.c",
],
hdrs = [
"src/core/ext/filters/client_channel/lb_policy/xds/client_load_reporting_filter.h",
"src/core/ext/filters/client_channel/lb_policy/xds/xds.h",
"src/core/ext/filters/client_channel/lb_policy/xds/xds_channel.h",
"src/core/ext/filters/client_channel/lb_policy/xds/xds_client_stats.h",
"src/core/ext/filters/client_channel/lb_policy/xds/load_balancer_api.h",
"src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/google/protobuf/duration.pb.h",
"src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/google/protobuf/timestamp.pb.h",
"src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.h",
],
external_deps = [
"nanopb",
],
language = "c++",
deps = [
"grpc_base",
"grpc_client_channel",
"grpc_resolver_fake",
"grpc_secure",
],
)
grpc_cc_library(
name = "grpc_lb_subchannel_list",
hdrs = [

@ -24,7 +24,7 @@
cmake_minimum_required(VERSION 2.8)
set(PACKAGE_NAME "grpc")
set(PACKAGE_VERSION "1.16.0-dev")
set(PACKAGE_VERSION "1.17.0-dev")
set(PACKAGE_STRING "${PACKAGE_NAME} ${PACKAGE_VERSION}")
set(PACKAGE_TARNAME "${PACKAGE_NAME}-${PACKAGE_VERSION}")
set(PACKAGE_BUGREPORT "https://github.com/grpc/grpc/issues/")
@ -328,10 +328,10 @@ add_dependencies(buildtests_c grpc_jwt_verifier_test)
add_dependencies(buildtests_c grpc_security_connector_test)
add_dependencies(buildtests_c grpc_ssl_credentials_test)
if(_gRPC_PLATFORM_LINUX)
add_dependencies(buildtests_c handshake_client)
add_dependencies(buildtests_c handshake_client_ssl)
endif()
if(_gRPC_PLATFORM_LINUX)
add_dependencies(buildtests_c handshake_server)
add_dependencies(buildtests_c handshake_server_ssl)
endif()
if(_gRPC_PLATFORM_LINUX)
add_dependencies(buildtests_c handshake_server_with_readahead_handshaker)
@ -359,10 +359,10 @@ add_dependencies(buildtests_c json_stream_error_test)
add_dependencies(buildtests_c json_test)
add_dependencies(buildtests_c lame_client_test)
add_dependencies(buildtests_c load_file_test)
add_dependencies(buildtests_c memory_profile_client)
add_dependencies(buildtests_c memory_profile_server)
add_dependencies(buildtests_c memory_usage_client)
add_dependencies(buildtests_c memory_usage_server)
if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX)
add_dependencies(buildtests_c memory_profile_test)
add_dependencies(buildtests_c memory_usage_test)
endif()
add_dependencies(buildtests_c message_compress_test)
add_dependencies(buildtests_c minimal_stack_is_minimal_test)
@ -5249,6 +5249,7 @@ add_library(qps
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/worker_service.grpc.pb.h
test/cpp/qps/benchmark_config.cc
test/cpp/qps/client_async.cc
test/cpp/qps/client_callback.cc
test/cpp/qps/client_sync.cc
test/cpp/qps/driver.cc
test/cpp/qps/parse_json.cc
@ -8040,12 +8041,12 @@ target_link_libraries(grpc_verify_jwt
if (gRPC_BUILD_TESTS)
if(_gRPC_PLATFORM_LINUX)
add_executable(handshake_client
add_executable(handshake_client_ssl
test/core/handshake/client_ssl.cc
)
target_include_directories(handshake_client
target_include_directories(handshake_client_ssl
PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
PRIVATE ${_gRPC_SSL_INCLUDE_DIR}
@ -8058,7 +8059,7 @@ target_include_directories(handshake_client
PRIVATE ${_gRPC_NANOPB_INCLUDE_DIR}
)
target_link_libraries(handshake_client
target_link_libraries(handshake_client_ssl
${_gRPC_SSL_LIBRARIES}
${_gRPC_ALLTARGETS_LIBRARIES}
grpc_test_util
@ -8069,8 +8070,8 @@ target_link_libraries(handshake_client
# avoid dependency on libstdc++
if (_gRPC_CORE_NOSTDCXX_FLAGS)
set_target_properties(handshake_client PROPERTIES LINKER_LANGUAGE C)
target_compile_options(handshake_client PRIVATE $<$<COMPILE_LANGUAGE:CXX>:${_gRPC_CORE_NOSTDCXX_FLAGS}>)
set_target_properties(handshake_client_ssl PROPERTIES LINKER_LANGUAGE C)
target_compile_options(handshake_client_ssl PRIVATE $<$<COMPILE_LANGUAGE:CXX>:${_gRPC_CORE_NOSTDCXX_FLAGS}>)
endif()
endif()
@ -8078,13 +8079,13 @@ endif (gRPC_BUILD_TESTS)
if (gRPC_BUILD_TESTS)
if(_gRPC_PLATFORM_LINUX)
add_executable(handshake_server
add_executable(handshake_server_ssl
test/core/handshake/server_ssl.cc
test/core/handshake/server_ssl_common.cc
)
target_include_directories(handshake_server
target_include_directories(handshake_server_ssl
PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
PRIVATE ${_gRPC_SSL_INCLUDE_DIR}
@ -8097,7 +8098,7 @@ target_include_directories(handshake_server
PRIVATE ${_gRPC_NANOPB_INCLUDE_DIR}
)
target_link_libraries(handshake_server
target_link_libraries(handshake_server_ssl
${_gRPC_SSL_LIBRARIES}
${_gRPC_ALLTARGETS_LIBRARIES}
grpc_test_util
@ -8108,8 +8109,8 @@ target_link_libraries(handshake_server
# avoid dependency on libstdc++
if (_gRPC_CORE_NOSTDCXX_FLAGS)
set_target_properties(handshake_server PROPERTIES LINKER_LANGUAGE C)
target_compile_options(handshake_server PRIVATE $<$<COMPILE_LANGUAGE:CXX>:${_gRPC_CORE_NOSTDCXX_FLAGS}>)
set_target_properties(handshake_server_ssl PROPERTIES LINKER_LANGUAGE C)
target_compile_options(handshake_server_ssl PRIVATE $<$<COMPILE_LANGUAGE:CXX>:${_gRPC_CORE_NOSTDCXX_FLAGS}>)
endif()
endif()
@ -8755,12 +8756,12 @@ target_link_libraries(load_file_test
endif (gRPC_BUILD_TESTS)
if (gRPC_BUILD_TESTS)
add_executable(memory_profile_client
add_executable(memory_usage_client
test/core/memory_usage/client.cc
)
target_include_directories(memory_profile_client
target_include_directories(memory_usage_client
PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
PRIVATE ${_gRPC_SSL_INCLUDE_DIR}
@ -8773,7 +8774,7 @@ target_include_directories(memory_profile_client
PRIVATE ${_gRPC_NANOPB_INCLUDE_DIR}
)
target_link_libraries(memory_profile_client
target_link_libraries(memory_usage_client
${_gRPC_ALLTARGETS_LIBRARIES}
grpc_test_util
grpc
@ -8783,19 +8784,19 @@ target_link_libraries(memory_profile_client
# avoid dependency on libstdc++
if (_gRPC_CORE_NOSTDCXX_FLAGS)
set_target_properties(memory_profile_client PROPERTIES LINKER_LANGUAGE C)
target_compile_options(memory_profile_client PRIVATE $<$<COMPILE_LANGUAGE:CXX>:${_gRPC_CORE_NOSTDCXX_FLAGS}>)
set_target_properties(memory_usage_client PROPERTIES LINKER_LANGUAGE C)
target_compile_options(memory_usage_client PRIVATE $<$<COMPILE_LANGUAGE:CXX>:${_gRPC_CORE_NOSTDCXX_FLAGS}>)
endif()
endif (gRPC_BUILD_TESTS)
if (gRPC_BUILD_TESTS)
add_executable(memory_profile_server
add_executable(memory_usage_server
test/core/memory_usage/server.cc
)
target_include_directories(memory_profile_server
target_include_directories(memory_usage_server
PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
PRIVATE ${_gRPC_SSL_INCLUDE_DIR}
@ -8808,7 +8809,7 @@ target_include_directories(memory_profile_server
PRIVATE ${_gRPC_NANOPB_INCLUDE_DIR}
)
target_link_libraries(memory_profile_server
target_link_libraries(memory_usage_server
${_gRPC_ALLTARGETS_LIBRARIES}
grpc_test_util
grpc
@ -8818,20 +8819,20 @@ target_link_libraries(memory_profile_server
# avoid dependency on libstdc++
if (_gRPC_CORE_NOSTDCXX_FLAGS)
set_target_properties(memory_profile_server PROPERTIES LINKER_LANGUAGE C)
target_compile_options(memory_profile_server PRIVATE $<$<COMPILE_LANGUAGE:CXX>:${_gRPC_CORE_NOSTDCXX_FLAGS}>)
set_target_properties(memory_usage_server PROPERTIES LINKER_LANGUAGE C)
target_compile_options(memory_usage_server PRIVATE $<$<COMPILE_LANGUAGE:CXX>:${_gRPC_CORE_NOSTDCXX_FLAGS}>)
endif()
endif (gRPC_BUILD_TESTS)
if (gRPC_BUILD_TESTS)
if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX)
add_executable(memory_profile_test
add_executable(memory_usage_test
test/core/memory_usage/memory_usage_test.cc
)
target_include_directories(memory_profile_test
target_include_directories(memory_usage_test
PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
PRIVATE ${_gRPC_SSL_INCLUDE_DIR}
@ -8844,7 +8845,7 @@ target_include_directories(memory_profile_test
PRIVATE ${_gRPC_NANOPB_INCLUDE_DIR}
)
target_link_libraries(memory_profile_test
target_link_libraries(memory_usage_test
${_gRPC_ALLTARGETS_LIBRARIES}
grpc_test_util
grpc
@ -8854,8 +8855,8 @@ target_link_libraries(memory_profile_test
# avoid dependency on libstdc++
if (_gRPC_CORE_NOSTDCXX_FLAGS)
set_target_properties(memory_profile_test PROPERTIES LINKER_LANGUAGE C)
target_compile_options(memory_profile_test PRIVATE $<$<COMPILE_LANGUAGE:CXX>:${_gRPC_CORE_NOSTDCXX_FLAGS}>)
set_target_properties(memory_usage_test PROPERTIES LINKER_LANGUAGE C)
target_compile_options(memory_usage_test PRIVATE $<$<COMPILE_LANGUAGE:CXX>:${_gRPC_CORE_NOSTDCXX_FLAGS}>)
endif()
endif()

@ -437,9 +437,9 @@ E = @echo
Q = @
endif
CORE_VERSION = 6.0.0-dev
CPP_VERSION = 1.16.0-dev
CSHARP_VERSION = 1.16.0-dev
CORE_VERSION = 7.0.0-dev
CPP_VERSION = 1.17.0-dev
CSHARP_VERSION = 1.17.0-dev
CPPFLAGS_NO_ARCH += $(addprefix -I, $(INCLUDES)) $(addprefix -D, $(DEFINES))
CPPFLAGS += $(CPPFLAGS_NO_ARCH) $(ARCH_FLAGS)
@ -487,7 +487,7 @@ SHARED_EXT_CORE = dll
SHARED_EXT_CPP = dll
SHARED_EXT_CSHARP = dll
SHARED_PREFIX =
SHARED_VERSION_CORE = -6
SHARED_VERSION_CORE = -7
SHARED_VERSION_CPP = -1
SHARED_VERSION_CSHARP = -1
else ifeq ($(SYSTEM),Darwin)
@ -1039,8 +1039,8 @@ grpc_print_google_default_creds_token: $(BINDIR)/$(CONFIG)/grpc_print_google_def
grpc_security_connector_test: $(BINDIR)/$(CONFIG)/grpc_security_connector_test
grpc_ssl_credentials_test: $(BINDIR)/$(CONFIG)/grpc_ssl_credentials_test
grpc_verify_jwt: $(BINDIR)/$(CONFIG)/grpc_verify_jwt
handshake_client: $(BINDIR)/$(CONFIG)/handshake_client
handshake_server: $(BINDIR)/$(CONFIG)/handshake_server
handshake_client_ssl: $(BINDIR)/$(CONFIG)/handshake_client_ssl
handshake_server_ssl: $(BINDIR)/$(CONFIG)/handshake_server_ssl
handshake_server_with_readahead_handshaker: $(BINDIR)/$(CONFIG)/handshake_server_with_readahead_handshaker
handshake_verify_peer_options: $(BINDIR)/$(CONFIG)/handshake_verify_peer_options
histogram_test: $(BINDIR)/$(CONFIG)/histogram_test
@ -1064,9 +1064,9 @@ json_test: $(BINDIR)/$(CONFIG)/json_test
lame_client_test: $(BINDIR)/$(CONFIG)/lame_client_test
load_file_test: $(BINDIR)/$(CONFIG)/load_file_test
low_level_ping_pong_benchmark: $(BINDIR)/$(CONFIG)/low_level_ping_pong_benchmark
memory_profile_client: $(BINDIR)/$(CONFIG)/memory_profile_client
memory_profile_server: $(BINDIR)/$(CONFIG)/memory_profile_server
memory_profile_test: $(BINDIR)/$(CONFIG)/memory_profile_test
memory_usage_client: $(BINDIR)/$(CONFIG)/memory_usage_client
memory_usage_server: $(BINDIR)/$(CONFIG)/memory_usage_server
memory_usage_test: $(BINDIR)/$(CONFIG)/memory_usage_test
message_compress_test: $(BINDIR)/$(CONFIG)/message_compress_test
minimal_stack_is_minimal_test: $(BINDIR)/$(CONFIG)/minimal_stack_is_minimal_test
multiple_server_queues_test: $(BINDIR)/$(CONFIG)/multiple_server_queues_test
@ -1491,8 +1491,8 @@ buildtests_c: privatelibs_c \
$(BINDIR)/$(CONFIG)/grpc_jwt_verifier_test \
$(BINDIR)/$(CONFIG)/grpc_security_connector_test \
$(BINDIR)/$(CONFIG)/grpc_ssl_credentials_test \
$(BINDIR)/$(CONFIG)/handshake_client \
$(BINDIR)/$(CONFIG)/handshake_server \
$(BINDIR)/$(CONFIG)/handshake_client_ssl \
$(BINDIR)/$(CONFIG)/handshake_server_ssl \
$(BINDIR)/$(CONFIG)/handshake_server_with_readahead_handshaker \
$(BINDIR)/$(CONFIG)/handshake_verify_peer_options \
$(BINDIR)/$(CONFIG)/histogram_test \
@ -1511,9 +1511,9 @@ buildtests_c: privatelibs_c \
$(BINDIR)/$(CONFIG)/json_test \
$(BINDIR)/$(CONFIG)/lame_client_test \
$(BINDIR)/$(CONFIG)/load_file_test \
$(BINDIR)/$(CONFIG)/memory_profile_client \
$(BINDIR)/$(CONFIG)/memory_profile_server \
$(BINDIR)/$(CONFIG)/memory_profile_test \
$(BINDIR)/$(CONFIG)/memory_usage_client \
$(BINDIR)/$(CONFIG)/memory_usage_server \
$(BINDIR)/$(CONFIG)/memory_usage_test \
$(BINDIR)/$(CONFIG)/message_compress_test \
$(BINDIR)/$(CONFIG)/minimal_stack_is_minimal_test \
$(BINDIR)/$(CONFIG)/multiple_server_queues_test \
@ -2058,10 +2058,10 @@ test_c: buildtests_c
$(Q) $(BINDIR)/$(CONFIG)/grpc_security_connector_test || ( echo test grpc_security_connector_test failed ; exit 1 )
$(E) "[RUN] Testing grpc_ssl_credentials_test"
$(Q) $(BINDIR)/$(CONFIG)/grpc_ssl_credentials_test || ( echo test grpc_ssl_credentials_test failed ; exit 1 )
$(E) "[RUN] Testing handshake_client"
$(Q) $(BINDIR)/$(CONFIG)/handshake_client || ( echo test handshake_client failed ; exit 1 )
$(E) "[RUN] Testing handshake_server"
$(Q) $(BINDIR)/$(CONFIG)/handshake_server || ( echo test handshake_server failed ; exit 1 )
$(E) "[RUN] Testing handshake_client_ssl"
$(Q) $(BINDIR)/$(CONFIG)/handshake_client_ssl || ( echo test handshake_client_ssl failed ; exit 1 )
$(E) "[RUN] Testing handshake_server_ssl"
$(Q) $(BINDIR)/$(CONFIG)/handshake_server_ssl || ( echo test handshake_server_ssl failed ; exit 1 )
$(E) "[RUN] Testing handshake_server_with_readahead_handshaker"
$(Q) $(BINDIR)/$(CONFIG)/handshake_server_with_readahead_handshaker || ( echo test handshake_server_with_readahead_handshaker failed ; exit 1 )
$(E) "[RUN] Testing handshake_verify_peer_options"
@ -2096,8 +2096,8 @@ test_c: buildtests_c
$(Q) $(BINDIR)/$(CONFIG)/lame_client_test || ( echo test lame_client_test failed ; exit 1 )
$(E) "[RUN] Testing load_file_test"
$(Q) $(BINDIR)/$(CONFIG)/load_file_test || ( echo test load_file_test failed ; exit 1 )
$(E) "[RUN] Testing memory_profile_test"
$(Q) $(BINDIR)/$(CONFIG)/memory_profile_test || ( echo test memory_profile_test failed ; exit 1 )
$(E) "[RUN] Testing memory_usage_test"
$(Q) $(BINDIR)/$(CONFIG)/memory_usage_test || ( echo test memory_usage_test failed ; exit 1 )
$(E) "[RUN] Testing message_compress_test"
$(Q) $(BINDIR)/$(CONFIG)/message_compress_test || ( echo test message_compress_test failed ; exit 1 )
$(E) "[RUN] Testing minimal_stack_is_minimal_test"
@ -3003,7 +3003,7 @@ install-shared_c: shared_c strip-shared_c install-pkg-config_c
ifeq ($(SYSTEM),MINGW32)
$(Q) $(INSTALL) $(LIBDIR)/$(CONFIG)/libaddress_sorting$(SHARED_VERSION_CORE)-dll.a $(prefix)/lib/libaddress_sorting.a
else ifneq ($(SYSTEM),Darwin)
$(Q) ln -sf $(SHARED_PREFIX)address_sorting$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(prefix)/lib/libaddress_sorting.so.6
$(Q) ln -sf $(SHARED_PREFIX)address_sorting$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(prefix)/lib/libaddress_sorting.so.7
$(Q) ln -sf $(SHARED_PREFIX)address_sorting$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(prefix)/lib/libaddress_sorting.so
endif
$(E) "[INSTALL] Installing $(SHARED_PREFIX)gpr$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE)"
@ -3012,7 +3012,7 @@ endif
ifeq ($(SYSTEM),MINGW32)
$(Q) $(INSTALL) $(LIBDIR)/$(CONFIG)/libgpr$(SHARED_VERSION_CORE)-dll.a $(prefix)/lib/libgpr.a
else ifneq ($(SYSTEM),Darwin)
$(Q) ln -sf $(SHARED_PREFIX)gpr$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(prefix)/lib/libgpr.so.6
$(Q) ln -sf $(SHARED_PREFIX)gpr$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(prefix)/lib/libgpr.so.7
$(Q) ln -sf $(SHARED_PREFIX)gpr$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(prefix)/lib/libgpr.so
endif
$(E) "[INSTALL] Installing $(SHARED_PREFIX)grpc$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE)"
@ -3021,7 +3021,7 @@ endif
ifeq ($(SYSTEM),MINGW32)
$(Q) $(INSTALL) $(LIBDIR)/$(CONFIG)/libgrpc$(SHARED_VERSION_CORE)-dll.a $(prefix)/lib/libgrpc.a
else ifneq ($(SYSTEM),Darwin)
$(Q) ln -sf $(SHARED_PREFIX)grpc$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(prefix)/lib/libgrpc.so.6
$(Q) ln -sf $(SHARED_PREFIX)grpc$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(prefix)/lib/libgrpc.so.7
$(Q) ln -sf $(SHARED_PREFIX)grpc$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(prefix)/lib/libgrpc.so
endif
$(E) "[INSTALL] Installing $(SHARED_PREFIX)grpc_cronet$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE)"
@ -3030,7 +3030,7 @@ endif
ifeq ($(SYSTEM),MINGW32)
$(Q) $(INSTALL) $(LIBDIR)/$(CONFIG)/libgrpc_cronet$(SHARED_VERSION_CORE)-dll.a $(prefix)/lib/libgrpc_cronet.a
else ifneq ($(SYSTEM),Darwin)
$(Q) ln -sf $(SHARED_PREFIX)grpc_cronet$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(prefix)/lib/libgrpc_cronet.so.6
$(Q) ln -sf $(SHARED_PREFIX)grpc_cronet$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(prefix)/lib/libgrpc_cronet.so.7
$(Q) ln -sf $(SHARED_PREFIX)grpc_cronet$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(prefix)/lib/libgrpc_cronet.so
endif
$(E) "[INSTALL] Installing $(SHARED_PREFIX)grpc_unsecure$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE)"
@ -3039,7 +3039,7 @@ endif
ifeq ($(SYSTEM),MINGW32)
$(Q) $(INSTALL) $(LIBDIR)/$(CONFIG)/libgrpc_unsecure$(SHARED_VERSION_CORE)-dll.a $(prefix)/lib/libgrpc_unsecure.a
else ifneq ($(SYSTEM),Darwin)
$(Q) ln -sf $(SHARED_PREFIX)grpc_unsecure$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(prefix)/lib/libgrpc_unsecure.so.6
$(Q) ln -sf $(SHARED_PREFIX)grpc_unsecure$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(prefix)/lib/libgrpc_unsecure.so.7
$(Q) ln -sf $(SHARED_PREFIX)grpc_unsecure$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(prefix)/lib/libgrpc_unsecure.so
endif
ifneq ($(SYSTEM),MINGW32)
@ -3056,7 +3056,7 @@ install-shared_cxx: shared_cxx strip-shared_cxx install-shared_c install-pkg-con
ifeq ($(SYSTEM),MINGW32)
$(Q) $(INSTALL) $(LIBDIR)/$(CONFIG)/libgrpc++$(SHARED_VERSION_CPP)-dll.a $(prefix)/lib/libgrpc++.a
else ifneq ($(SYSTEM),Darwin)
$(Q) ln -sf $(SHARED_PREFIX)grpc++$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(prefix)/lib/libgrpc++.so.6
$(Q) ln -sf $(SHARED_PREFIX)grpc++$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(prefix)/lib/libgrpc++.so.7
$(Q) ln -sf $(SHARED_PREFIX)grpc++$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(prefix)/lib/libgrpc++.so
endif
$(E) "[INSTALL] Installing $(SHARED_PREFIX)grpc++_cronet$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP)"
@ -3065,7 +3065,7 @@ endif
ifeq ($(SYSTEM),MINGW32)
$(Q) $(INSTALL) $(LIBDIR)/$(CONFIG)/libgrpc++_cronet$(SHARED_VERSION_CPP)-dll.a $(prefix)/lib/libgrpc++_cronet.a
else ifneq ($(SYSTEM),Darwin)
$(Q) ln -sf $(SHARED_PREFIX)grpc++_cronet$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(prefix)/lib/libgrpc++_cronet.so.6
$(Q) ln -sf $(SHARED_PREFIX)grpc++_cronet$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(prefix)/lib/libgrpc++_cronet.so.7
$(Q) ln -sf $(SHARED_PREFIX)grpc++_cronet$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(prefix)/lib/libgrpc++_cronet.so
endif
$(E) "[INSTALL] Installing $(SHARED_PREFIX)grpc++_error_details$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP)"
@ -3074,7 +3074,7 @@ endif
ifeq ($(SYSTEM),MINGW32)
$(Q) $(INSTALL) $(LIBDIR)/$(CONFIG)/libgrpc++_error_details$(SHARED_VERSION_CPP)-dll.a $(prefix)/lib/libgrpc++_error_details.a
else ifneq ($(SYSTEM),Darwin)
$(Q) ln -sf $(SHARED_PREFIX)grpc++_error_details$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(prefix)/lib/libgrpc++_error_details.so.6
$(Q) ln -sf $(SHARED_PREFIX)grpc++_error_details$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(prefix)/lib/libgrpc++_error_details.so.7
$(Q) ln -sf $(SHARED_PREFIX)grpc++_error_details$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(prefix)/lib/libgrpc++_error_details.so
endif
$(E) "[INSTALL] Installing $(SHARED_PREFIX)grpc++_reflection$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP)"
@ -3083,7 +3083,7 @@ endif
ifeq ($(SYSTEM),MINGW32)
$(Q) $(INSTALL) $(LIBDIR)/$(CONFIG)/libgrpc++_reflection$(SHARED_VERSION_CPP)-dll.a $(prefix)/lib/libgrpc++_reflection.a
else ifneq ($(SYSTEM),Darwin)
$(Q) ln -sf $(SHARED_PREFIX)grpc++_reflection$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(prefix)/lib/libgrpc++_reflection.so.6
$(Q) ln -sf $(SHARED_PREFIX)grpc++_reflection$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(prefix)/lib/libgrpc++_reflection.so.7
$(Q) ln -sf $(SHARED_PREFIX)grpc++_reflection$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(prefix)/lib/libgrpc++_reflection.so
endif
$(E) "[INSTALL] Installing $(SHARED_PREFIX)grpc++_unsecure$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP)"
@ -3092,7 +3092,7 @@ endif
ifeq ($(SYSTEM),MINGW32)
$(Q) $(INSTALL) $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure$(SHARED_VERSION_CPP)-dll.a $(prefix)/lib/libgrpc++_unsecure.a
else ifneq ($(SYSTEM),Darwin)
$(Q) ln -sf $(SHARED_PREFIX)grpc++_unsecure$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(prefix)/lib/libgrpc++_unsecure.so.6
$(Q) ln -sf $(SHARED_PREFIX)grpc++_unsecure$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(prefix)/lib/libgrpc++_unsecure.so.7
$(Q) ln -sf $(SHARED_PREFIX)grpc++_unsecure$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(prefix)/lib/libgrpc++_unsecure.so
endif
$(E) "[INSTALL] Installing $(SHARED_PREFIX)grpcpp_channelz$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP)"
@ -3101,7 +3101,7 @@ endif
ifeq ($(SYSTEM),MINGW32)
$(Q) $(INSTALL) $(LIBDIR)/$(CONFIG)/libgrpcpp_channelz$(SHARED_VERSION_CPP)-dll.a $(prefix)/lib/libgrpcpp_channelz.a
else ifneq ($(SYSTEM),Darwin)
$(Q) ln -sf $(SHARED_PREFIX)grpcpp_channelz$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(prefix)/lib/libgrpcpp_channelz.so.6
$(Q) ln -sf $(SHARED_PREFIX)grpcpp_channelz$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(prefix)/lib/libgrpcpp_channelz.so.7
$(Q) ln -sf $(SHARED_PREFIX)grpcpp_channelz$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(prefix)/lib/libgrpcpp_channelz.so
endif
ifneq ($(SYSTEM),MINGW32)
@ -3118,7 +3118,7 @@ install-shared_csharp: shared_csharp strip-shared_csharp
ifeq ($(SYSTEM),MINGW32)
$(Q) $(INSTALL) $(LIBDIR)/$(CONFIG)/libgrpc_csharp_ext$(SHARED_VERSION_CSHARP)-dll.a $(prefix)/lib/libgrpc_csharp_ext.a
else ifneq ($(SYSTEM),Darwin)
$(Q) ln -sf $(SHARED_PREFIX)grpc_csharp_ext$(SHARED_VERSION_CSHARP).$(SHARED_EXT_CSHARP) $(prefix)/lib/libgrpc_csharp_ext.so.6
$(Q) ln -sf $(SHARED_PREFIX)grpc_csharp_ext$(SHARED_VERSION_CSHARP).$(SHARED_EXT_CSHARP) $(prefix)/lib/libgrpc_csharp_ext.so.7
$(Q) ln -sf $(SHARED_PREFIX)grpc_csharp_ext$(SHARED_VERSION_CSHARP).$(SHARED_EXT_CSHARP) $(prefix)/lib/libgrpc_csharp_ext.so
endif
ifneq ($(SYSTEM),MINGW32)
@ -3209,8 +3209,8 @@ $(LIBDIR)/$(CONFIG)/libaddress_sorting$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE):
ifeq ($(SYSTEM),Darwin)
$(Q) $(LD) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -install_name $(SHARED_PREFIX)address_sorting$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) -dynamiclib -o $(LIBDIR)/$(CONFIG)/libaddress_sorting$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(LIBADDRESS_SORTING_OBJS) $(ZLIB_MERGE_LIBS) $(CARES_MERGE_LIBS) $(ADDRESS_SORTING_MERGE_LIBS) $(LDLIBS)
else
$(Q) $(LD) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -shared -Wl,-soname,libaddress_sorting.so.6 -o $(LIBDIR)/$(CONFIG)/libaddress_sorting$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(LIBADDRESS_SORTING_OBJS) $(ZLIB_MERGE_LIBS) $(CARES_MERGE_LIBS) $(ADDRESS_SORTING_MERGE_LIBS) $(LDLIBS)
$(Q) ln -sf $(SHARED_PREFIX)address_sorting$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(LIBDIR)/$(CONFIG)/libaddress_sorting$(SHARED_VERSION_CORE).so.6
$(Q) $(LD) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -shared -Wl,-soname,libaddress_sorting.so.7 -o $(LIBDIR)/$(CONFIG)/libaddress_sorting$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(LIBADDRESS_SORTING_OBJS) $(ZLIB_MERGE_LIBS) $(CARES_MERGE_LIBS) $(ADDRESS_SORTING_MERGE_LIBS) $(LDLIBS)
$(Q) ln -sf $(SHARED_PREFIX)address_sorting$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(LIBDIR)/$(CONFIG)/libaddress_sorting$(SHARED_VERSION_CORE).so.7
$(Q) ln -sf $(SHARED_PREFIX)address_sorting$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(LIBDIR)/$(CONFIG)/libaddress_sorting$(SHARED_VERSION_CORE).so
endif
endif
@ -3404,8 +3404,8 @@ $(LIBDIR)/$(CONFIG)/libgpr$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE): $(LIBGPR_OB
ifeq ($(SYSTEM),Darwin)
$(Q) $(LD) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -install_name $(SHARED_PREFIX)gpr$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) -dynamiclib -o $(LIBDIR)/$(CONFIG)/libgpr$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(LIBGPR_OBJS) $(ZLIB_MERGE_LIBS) $(CARES_MERGE_LIBS) $(ADDRESS_SORTING_MERGE_LIBS) $(LDLIBS)
else
$(Q) $(LD) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -shared -Wl,-soname,libgpr.so.6 -o $(LIBDIR)/$(CONFIG)/libgpr$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(LIBGPR_OBJS) $(ZLIB_MERGE_LIBS) $(CARES_MERGE_LIBS) $(ADDRESS_SORTING_MERGE_LIBS) $(LDLIBS)
$(Q) ln -sf $(SHARED_PREFIX)gpr$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(LIBDIR)/$(CONFIG)/libgpr$(SHARED_VERSION_CORE).so.6
$(Q) $(LD) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -shared -Wl,-soname,libgpr.so.7 -o $(LIBDIR)/$(CONFIG)/libgpr$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(LIBGPR_OBJS) $(ZLIB_MERGE_LIBS) $(CARES_MERGE_LIBS) $(ADDRESS_SORTING_MERGE_LIBS) $(LDLIBS)
$(Q) ln -sf $(SHARED_PREFIX)gpr$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(LIBDIR)/$(CONFIG)/libgpr$(SHARED_VERSION_CORE).so.7
$(Q) ln -sf $(SHARED_PREFIX)gpr$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(LIBDIR)/$(CONFIG)/libgpr$(SHARED_VERSION_CORE).so
endif
endif
@ -3831,8 +3831,8 @@ $(LIBDIR)/$(CONFIG)/libgrpc$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE): $(LIBGRPC_
ifeq ($(SYSTEM),Darwin)
$(Q) $(LD) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -install_name $(SHARED_PREFIX)grpc$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) -dynamiclib -o $(LIBDIR)/$(CONFIG)/libgrpc$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(LIBGRPC_OBJS) $(LIBDIR)/$(CONFIG)/libgpr.a $(OPENSSL_MERGE_LIBS) $(LDLIBS_SECURE) $(ZLIB_MERGE_LIBS) $(CARES_MERGE_LIBS) $(ADDRESS_SORTING_MERGE_LIBS) $(LDLIBS)
else
$(Q) $(LD) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -shared -Wl,-soname,libgrpc.so.6 -o $(LIBDIR)/$(CONFIG)/libgrpc$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(LIBGRPC_OBJS) $(LIBDIR)/$(CONFIG)/libgpr.a $(OPENSSL_MERGE_LIBS) $(LDLIBS_SECURE) $(ZLIB_MERGE_LIBS) $(CARES_MERGE_LIBS) $(ADDRESS_SORTING_MERGE_LIBS) $(LDLIBS)
$(Q) ln -sf $(SHARED_PREFIX)grpc$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(LIBDIR)/$(CONFIG)/libgrpc$(SHARED_VERSION_CORE).so.6
$(Q) $(LD) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -shared -Wl,-soname,libgrpc.so.7 -o $(LIBDIR)/$(CONFIG)/libgrpc$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(LIBGRPC_OBJS) $(LIBDIR)/$(CONFIG)/libgpr.a $(OPENSSL_MERGE_LIBS) $(LDLIBS_SECURE) $(ZLIB_MERGE_LIBS) $(CARES_MERGE_LIBS) $(ADDRESS_SORTING_MERGE_LIBS) $(LDLIBS)
$(Q) ln -sf $(SHARED_PREFIX)grpc$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(LIBDIR)/$(CONFIG)/libgrpc$(SHARED_VERSION_CORE).so.7
$(Q) ln -sf $(SHARED_PREFIX)grpc$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(LIBDIR)/$(CONFIG)/libgrpc$(SHARED_VERSION_CORE).so
endif
endif
@ -4196,8 +4196,8 @@ $(LIBDIR)/$(CONFIG)/libgrpc_cronet$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE): $(L
ifeq ($(SYSTEM),Darwin)
$(Q) $(LD) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -install_name $(SHARED_PREFIX)grpc_cronet$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) -dynamiclib -o $(LIBDIR)/$(CONFIG)/libgrpc_cronet$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(LIBGRPC_CRONET_OBJS) $(LIBDIR)/$(CONFIG)/libgpr.a $(OPENSSL_MERGE_LIBS) $(LDLIBS_SECURE) $(ZLIB_MERGE_LIBS) $(CARES_MERGE_LIBS) $(ADDRESS_SORTING_MERGE_LIBS) $(LDLIBS)
else
$(Q) $(LD) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -shared -Wl,-soname,libgrpc_cronet.so.6 -o $(LIBDIR)/$(CONFIG)/libgrpc_cronet$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(LIBGRPC_CRONET_OBJS) $(LIBDIR)/$(CONFIG)/libgpr.a $(OPENSSL_MERGE_LIBS) $(LDLIBS_SECURE) $(ZLIB_MERGE_LIBS) $(CARES_MERGE_LIBS) $(ADDRESS_SORTING_MERGE_LIBS) $(LDLIBS)
$(Q) ln -sf $(SHARED_PREFIX)grpc_cronet$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(LIBDIR)/$(CONFIG)/libgrpc_cronet$(SHARED_VERSION_CORE).so.6
$(Q) $(LD) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -shared -Wl,-soname,libgrpc_cronet.so.7 -o $(LIBDIR)/$(CONFIG)/libgrpc_cronet$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(LIBGRPC_CRONET_OBJS) $(LIBDIR)/$(CONFIG)/libgpr.a $(OPENSSL_MERGE_LIBS) $(LDLIBS_SECURE) $(ZLIB_MERGE_LIBS) $(CARES_MERGE_LIBS) $(ADDRESS_SORTING_MERGE_LIBS) $(LDLIBS)
$(Q) ln -sf $(SHARED_PREFIX)grpc_cronet$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(LIBDIR)/$(CONFIG)/libgrpc_cronet$(SHARED_VERSION_CORE).so.7
$(Q) ln -sf $(SHARED_PREFIX)grpc_cronet$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(LIBDIR)/$(CONFIG)/libgrpc_cronet$(SHARED_VERSION_CORE).so
endif
endif
@ -5110,8 +5110,8 @@ $(LIBDIR)/$(CONFIG)/libgrpc_unsecure$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE): $
ifeq ($(SYSTEM),Darwin)
$(Q) $(LD) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -install_name $(SHARED_PREFIX)grpc_unsecure$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) -dynamiclib -o $(LIBDIR)/$(CONFIG)/libgrpc_unsecure$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(LIBGRPC_UNSECURE_OBJS) $(LIBDIR)/$(CONFIG)/libgpr.a $(ZLIB_MERGE_LIBS) $(CARES_MERGE_LIBS) $(ADDRESS_SORTING_MERGE_LIBS) $(LDLIBS)
else
$(Q) $(LD) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -shared -Wl,-soname,libgrpc_unsecure.so.6 -o $(LIBDIR)/$(CONFIG)/libgrpc_unsecure$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(LIBGRPC_UNSECURE_OBJS) $(LIBDIR)/$(CONFIG)/libgpr.a $(ZLIB_MERGE_LIBS) $(CARES_MERGE_LIBS) $(ADDRESS_SORTING_MERGE_LIBS) $(LDLIBS)
$(Q) ln -sf $(SHARED_PREFIX)grpc_unsecure$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(LIBDIR)/$(CONFIG)/libgrpc_unsecure$(SHARED_VERSION_CORE).so.6
$(Q) $(LD) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -shared -Wl,-soname,libgrpc_unsecure.so.7 -o $(LIBDIR)/$(CONFIG)/libgrpc_unsecure$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(LIBGRPC_UNSECURE_OBJS) $(LIBDIR)/$(CONFIG)/libgpr.a $(ZLIB_MERGE_LIBS) $(CARES_MERGE_LIBS) $(ADDRESS_SORTING_MERGE_LIBS) $(LDLIBS)
$(Q) ln -sf $(SHARED_PREFIX)grpc_unsecure$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(LIBDIR)/$(CONFIG)/libgrpc_unsecure$(SHARED_VERSION_CORE).so.7
$(Q) ln -sf $(SHARED_PREFIX)grpc_unsecure$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(LIBDIR)/$(CONFIG)/libgrpc_unsecure$(SHARED_VERSION_CORE).so
endif
endif
@ -7510,6 +7510,7 @@ LIBQPS_SRC = \
$(GENDIR)/src/proto/grpc/testing/worker_service.pb.cc $(GENDIR)/src/proto/grpc/testing/worker_service.grpc.pb.cc \
test/cpp/qps/benchmark_config.cc \
test/cpp/qps/client_async.cc \
test/cpp/qps/client_callback.cc \
test/cpp/qps/client_sync.cc \
test/cpp/qps/driver.cc \
test/cpp/qps/parse_json.cc \
@ -7566,6 +7567,7 @@ endif
endif
$(OBJDIR)/$(CONFIG)/test/cpp/qps/benchmark_config.o: $(GENDIR)/src/proto/grpc/testing/messages.pb.cc $(GENDIR)/src/proto/grpc/testing/messages.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/payloads.pb.cc $(GENDIR)/src/proto/grpc/testing/payloads.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/stats.pb.cc $(GENDIR)/src/proto/grpc/testing/stats.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/control.pb.cc $(GENDIR)/src/proto/grpc/testing/control.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/benchmark_service.pb.cc $(GENDIR)/src/proto/grpc/testing/benchmark_service.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/report_qps_scenario_service.pb.cc $(GENDIR)/src/proto/grpc/testing/report_qps_scenario_service.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/worker_service.pb.cc $(GENDIR)/src/proto/grpc/testing/worker_service.grpc.pb.cc
$(OBJDIR)/$(CONFIG)/test/cpp/qps/client_async.o: $(GENDIR)/src/proto/grpc/testing/messages.pb.cc $(GENDIR)/src/proto/grpc/testing/messages.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/payloads.pb.cc $(GENDIR)/src/proto/grpc/testing/payloads.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/stats.pb.cc $(GENDIR)/src/proto/grpc/testing/stats.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/control.pb.cc $(GENDIR)/src/proto/grpc/testing/control.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/benchmark_service.pb.cc $(GENDIR)/src/proto/grpc/testing/benchmark_service.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/report_qps_scenario_service.pb.cc $(GENDIR)/src/proto/grpc/testing/report_qps_scenario_service.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/worker_service.pb.cc $(GENDIR)/src/proto/grpc/testing/worker_service.grpc.pb.cc
$(OBJDIR)/$(CONFIG)/test/cpp/qps/client_callback.o: $(GENDIR)/src/proto/grpc/testing/messages.pb.cc $(GENDIR)/src/proto/grpc/testing/messages.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/payloads.pb.cc $(GENDIR)/src/proto/grpc/testing/payloads.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/stats.pb.cc $(GENDIR)/src/proto/grpc/testing/stats.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/control.pb.cc $(GENDIR)/src/proto/grpc/testing/control.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/benchmark_service.pb.cc $(GENDIR)/src/proto/grpc/testing/benchmark_service.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/report_qps_scenario_service.pb.cc $(GENDIR)/src/proto/grpc/testing/report_qps_scenario_service.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/worker_service.pb.cc $(GENDIR)/src/proto/grpc/testing/worker_service.grpc.pb.cc
$(OBJDIR)/$(CONFIG)/test/cpp/qps/client_sync.o: $(GENDIR)/src/proto/grpc/testing/messages.pb.cc $(GENDIR)/src/proto/grpc/testing/messages.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/payloads.pb.cc $(GENDIR)/src/proto/grpc/testing/payloads.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/stats.pb.cc $(GENDIR)/src/proto/grpc/testing/stats.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/control.pb.cc $(GENDIR)/src/proto/grpc/testing/control.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/benchmark_service.pb.cc $(GENDIR)/src/proto/grpc/testing/benchmark_service.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/report_qps_scenario_service.pb.cc $(GENDIR)/src/proto/grpc/testing/report_qps_scenario_service.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/worker_service.pb.cc $(GENDIR)/src/proto/grpc/testing/worker_service.grpc.pb.cc
$(OBJDIR)/$(CONFIG)/test/cpp/qps/driver.o: $(GENDIR)/src/proto/grpc/testing/messages.pb.cc $(GENDIR)/src/proto/grpc/testing/messages.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/payloads.pb.cc $(GENDIR)/src/proto/grpc/testing/payloads.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/stats.pb.cc $(GENDIR)/src/proto/grpc/testing/stats.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/control.pb.cc $(GENDIR)/src/proto/grpc/testing/control.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/benchmark_service.pb.cc $(GENDIR)/src/proto/grpc/testing/benchmark_service.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/report_qps_scenario_service.pb.cc $(GENDIR)/src/proto/grpc/testing/report_qps_scenario_service.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/worker_service.pb.cc $(GENDIR)/src/proto/grpc/testing/worker_service.grpc.pb.cc
$(OBJDIR)/$(CONFIG)/test/cpp/qps/parse_json.o: $(GENDIR)/src/proto/grpc/testing/messages.pb.cc $(GENDIR)/src/proto/grpc/testing/messages.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/payloads.pb.cc $(GENDIR)/src/proto/grpc/testing/payloads.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/stats.pb.cc $(GENDIR)/src/proto/grpc/testing/stats.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/control.pb.cc $(GENDIR)/src/proto/grpc/testing/control.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/benchmark_service.pb.cc $(GENDIR)/src/proto/grpc/testing/benchmark_service.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/report_qps_scenario_service.pb.cc $(GENDIR)/src/proto/grpc/testing/report_qps_scenario_service.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/worker_service.pb.cc $(GENDIR)/src/proto/grpc/testing/worker_service.grpc.pb.cc
@ -12668,57 +12670,57 @@ endif
endif
HANDSHAKE_CLIENT_SRC = \
HANDSHAKE_CLIENT_SSL_SRC = \
test/core/handshake/client_ssl.cc \
HANDSHAKE_CLIENT_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(HANDSHAKE_CLIENT_SRC))))
HANDSHAKE_CLIENT_SSL_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(HANDSHAKE_CLIENT_SSL_SRC))))
ifeq ($(NO_SECURE),true)
# You can't build secure targets if you don't have OpenSSL.
$(BINDIR)/$(CONFIG)/handshake_client: openssl_dep_error
$(BINDIR)/$(CONFIG)/handshake_client_ssl: openssl_dep_error
else
$(BINDIR)/$(CONFIG)/handshake_client: $(HANDSHAKE_CLIENT_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
$(BINDIR)/$(CONFIG)/handshake_client_ssl: $(HANDSHAKE_CLIENT_SSL_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
$(E) "[LD] Linking $@"
$(Q) mkdir -p `dirname $@`
$(Q) $(LD) $(LDFLAGS) $(HANDSHAKE_CLIENT_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/handshake_client
$(Q) $(LD) $(LDFLAGS) $(HANDSHAKE_CLIENT_SSL_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/handshake_client_ssl
endif
$(OBJDIR)/$(CONFIG)/test/core/handshake/client_ssl.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
deps_handshake_client: $(HANDSHAKE_CLIENT_OBJS:.o=.dep)
deps_handshake_client_ssl: $(HANDSHAKE_CLIENT_SSL_OBJS:.o=.dep)
ifneq ($(NO_SECURE),true)
ifneq ($(NO_DEPS),true)
-include $(HANDSHAKE_CLIENT_OBJS:.o=.dep)
-include $(HANDSHAKE_CLIENT_SSL_OBJS:.o=.dep)
endif
endif
HANDSHAKE_SERVER_SRC = \
HANDSHAKE_SERVER_SSL_SRC = \
test/core/handshake/server_ssl.cc \
test/core/handshake/server_ssl_common.cc \
HANDSHAKE_SERVER_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(HANDSHAKE_SERVER_SRC))))
HANDSHAKE_SERVER_SSL_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(HANDSHAKE_SERVER_SSL_SRC))))
ifeq ($(NO_SECURE),true)
# You can't build secure targets if you don't have OpenSSL.
$(BINDIR)/$(CONFIG)/handshake_server: openssl_dep_error
$(BINDIR)/$(CONFIG)/handshake_server_ssl: openssl_dep_error
else
$(BINDIR)/$(CONFIG)/handshake_server: $(HANDSHAKE_SERVER_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
$(BINDIR)/$(CONFIG)/handshake_server_ssl: $(HANDSHAKE_SERVER_SSL_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
$(E) "[LD] Linking $@"
$(Q) mkdir -p `dirname $@`
$(Q) $(LD) $(LDFLAGS) $(HANDSHAKE_SERVER_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/handshake_server
$(Q) $(LD) $(LDFLAGS) $(HANDSHAKE_SERVER_SSL_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/handshake_server_ssl
endif
@ -12726,11 +12728,11 @@ $(OBJDIR)/$(CONFIG)/test/core/handshake/server_ssl.o: $(LIBDIR)/$(CONFIG)/libgr
$(OBJDIR)/$(CONFIG)/test/core/handshake/server_ssl_common.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
deps_handshake_server: $(HANDSHAKE_SERVER_OBJS:.o=.dep)
deps_handshake_server_ssl: $(HANDSHAKE_SERVER_SSL_OBJS:.o=.dep)
ifneq ($(NO_SECURE),true)
ifneq ($(NO_DEPS),true)
-include $(HANDSHAKE_SERVER_OBJS:.o=.dep)
-include $(HANDSHAKE_SERVER_SSL_OBJS:.o=.dep)
endif
endif
@ -13474,98 +13476,98 @@ endif
endif
MEMORY_PROFILE_CLIENT_SRC = \
MEMORY_USAGE_CLIENT_SRC = \
test/core/memory_usage/client.cc \
MEMORY_PROFILE_CLIENT_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(MEMORY_PROFILE_CLIENT_SRC))))
MEMORY_USAGE_CLIENT_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(MEMORY_USAGE_CLIENT_SRC))))
ifeq ($(NO_SECURE),true)
# You can't build secure targets if you don't have OpenSSL.
$(BINDIR)/$(CONFIG)/memory_profile_client: openssl_dep_error
$(BINDIR)/$(CONFIG)/memory_usage_client: openssl_dep_error
else
$(BINDIR)/$(CONFIG)/memory_profile_client: $(MEMORY_PROFILE_CLIENT_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
$(BINDIR)/$(CONFIG)/memory_usage_client: $(MEMORY_USAGE_CLIENT_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
$(E) "[LD] Linking $@"
$(Q) mkdir -p `dirname $@`
$(Q) $(LD) $(LDFLAGS) $(MEMORY_PROFILE_CLIENT_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/memory_profile_client
$(Q) $(LD) $(LDFLAGS) $(MEMORY_USAGE_CLIENT_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/memory_usage_client
endif
$(OBJDIR)/$(CONFIG)/test/core/memory_usage/client.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
deps_memory_profile_client: $(MEMORY_PROFILE_CLIENT_OBJS:.o=.dep)
deps_memory_usage_client: $(MEMORY_USAGE_CLIENT_OBJS:.o=.dep)
ifneq ($(NO_SECURE),true)
ifneq ($(NO_DEPS),true)
-include $(MEMORY_PROFILE_CLIENT_OBJS:.o=.dep)
-include $(MEMORY_USAGE_CLIENT_OBJS:.o=.dep)
endif
endif
MEMORY_PROFILE_SERVER_SRC = \
MEMORY_USAGE_SERVER_SRC = \
test/core/memory_usage/server.cc \
MEMORY_PROFILE_SERVER_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(MEMORY_PROFILE_SERVER_SRC))))
MEMORY_USAGE_SERVER_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(MEMORY_USAGE_SERVER_SRC))))
ifeq ($(NO_SECURE),true)
# You can't build secure targets if you don't have OpenSSL.
$(BINDIR)/$(CONFIG)/memory_profile_server: openssl_dep_error
$(BINDIR)/$(CONFIG)/memory_usage_server: openssl_dep_error
else
$(BINDIR)/$(CONFIG)/memory_profile_server: $(MEMORY_PROFILE_SERVER_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
$(BINDIR)/$(CONFIG)/memory_usage_server: $(MEMORY_USAGE_SERVER_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
$(E) "[LD] Linking $@"
$(Q) mkdir -p `dirname $@`
$(Q) $(LD) $(LDFLAGS) $(MEMORY_PROFILE_SERVER_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/memory_profile_server
$(Q) $(LD) $(LDFLAGS) $(MEMORY_USAGE_SERVER_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/memory_usage_server
endif
$(OBJDIR)/$(CONFIG)/test/core/memory_usage/server.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
deps_memory_profile_server: $(MEMORY_PROFILE_SERVER_OBJS:.o=.dep)
deps_memory_usage_server: $(MEMORY_USAGE_SERVER_OBJS:.o=.dep)
ifneq ($(NO_SECURE),true)
ifneq ($(NO_DEPS),true)
-include $(MEMORY_PROFILE_SERVER_OBJS:.o=.dep)
-include $(MEMORY_USAGE_SERVER_OBJS:.o=.dep)
endif
endif
MEMORY_PROFILE_TEST_SRC = \
MEMORY_USAGE_TEST_SRC = \
test/core/memory_usage/memory_usage_test.cc \
MEMORY_PROFILE_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(MEMORY_PROFILE_TEST_SRC))))
MEMORY_USAGE_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(MEMORY_USAGE_TEST_SRC))))
ifeq ($(NO_SECURE),true)
# You can't build secure targets if you don't have OpenSSL.
$(BINDIR)/$(CONFIG)/memory_profile_test: openssl_dep_error
$(BINDIR)/$(CONFIG)/memory_usage_test: openssl_dep_error
else
$(BINDIR)/$(CONFIG)/memory_profile_test: $(MEMORY_PROFILE_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
$(BINDIR)/$(CONFIG)/memory_usage_test: $(MEMORY_USAGE_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
$(E) "[LD] Linking $@"
$(Q) mkdir -p `dirname $@`
$(Q) $(LD) $(LDFLAGS) $(MEMORY_PROFILE_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/memory_profile_test
$(Q) $(LD) $(LDFLAGS) $(MEMORY_USAGE_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/memory_usage_test
endif
$(OBJDIR)/$(CONFIG)/test/core/memory_usage/memory_usage_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
deps_memory_profile_test: $(MEMORY_PROFILE_TEST_OBJS:.o=.dep)
deps_memory_usage_test: $(MEMORY_USAGE_TEST_OBJS:.o=.dep)
ifneq ($(NO_SECURE),true)
ifneq ($(NO_DEPS),true)
-include $(MEMORY_PROFILE_TEST_OBJS:.o=.dep)
-include $(MEMORY_USAGE_TEST_OBJS:.o=.dep)
endif
endif
@ -24917,6 +24919,7 @@ test/cpp/interop/server_helper.cc: $(OPENSSL_DEP)
test/cpp/microbenchmarks/helpers.cc: $(OPENSSL_DEP)
test/cpp/qps/benchmark_config.cc: $(OPENSSL_DEP)
test/cpp/qps/client_async.cc: $(OPENSSL_DEP)
test/cpp/qps/client_callback.cc: $(OPENSSL_DEP)
test/cpp/qps/client_sync.cc: $(OPENSSL_DEP)
test/cpp/qps/driver.cc: $(OPENSSL_DEP)
test/cpp/qps/parse_json.cc: $(OPENSSL_DEP)

@ -34,10 +34,11 @@ pip_import(
load("@grpc_python_dependencies//:requirements.bzl", "pip_install")
pip_install()
# NOTE(https://github.com/pubref/rules_protobuf/pull/196): Switch to upstream repo after this gets merged.
git_repository(
name="org_pubref_rules_protobuf",
remote="https://github.com/pubref/rules_protobuf",
tag="v0.8.2",
remote="https://github.com/ghostwriternr/rules_protobuf",
tag="v0.8.2.1-alpha",
)
load("@org_pubref_rules_protobuf//python:rules.bzl", "py_proto_repositories")

@ -1,6 +1,6 @@
set noparent
@nicolasnoble
@dgquintas
@jtattermusch
@a11r
@vjpai

@ -12,9 +12,9 @@ settings:
'#08': Use "-preN" suffixes to identify pre-release versions
'#09': Per-language overrides are possible with (eg) ruby_version tag here
'#10': See the expand_version.py for all the quirks here
core_version: 6.0.0-dev
g_stands_for: gao
version: 1.16.0-dev
core_version: 7.0.0-dev
g_stands_for: gizmo
version: 1.17.0-dev
filegroups:
- name: alts_proto
headers:
@ -715,6 +715,57 @@ filegroups:
- grpc_base
- grpc_client_channel
- grpc_lb_subchannel_list
- name: grpc_lb_policy_xds
headers:
- src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/google/protobuf/duration.pb.h
- src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/google/protobuf/timestamp.pb.h
- src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.h
- src/core/ext/filters/client_channel/lb_policy/xds/client_load_reporting_filter.h
- src/core/ext/filters/client_channel/lb_policy/xds/load_balancer_api.h
- src/core/ext/filters/client_channel/lb_policy/xds/xds.h
- src/core/ext/filters/client_channel/lb_policy/xds/xds_channel.h
- src/core/ext/filters/client_channel/lb_policy/xds/xds_client_stats.h
src:
- src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/google/protobuf/duration.pb.c
- src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/google/protobuf/timestamp.pb.c
- src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.c
- src/core/ext/filters/client_channel/lb_policy/xds/client_load_reporting_filter.cc
- src/core/ext/filters/client_channel/lb_policy/xds/load_balancer_api.cc
- src/core/ext/filters/client_channel/lb_policy/xds/xds.cc
- src/core/ext/filters/client_channel/lb_policy/xds/xds_channel.cc
- src/core/ext/filters/client_channel/lb_policy/xds/xds_client_stats.cc
plugin: grpc_lb_policy_xds
uses:
- grpc_base
- grpc_client_channel
- nanopb
- grpc_resolver_fake
- name: grpc_lb_policy_xds_secure
headers:
- src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/google/protobuf/duration.pb.h
- src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/google/protobuf/timestamp.pb.h
- src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.h
- src/core/ext/filters/client_channel/lb_policy/xds/client_load_reporting_filter.h
- src/core/ext/filters/client_channel/lb_policy/xds/load_balancer_api.h
- src/core/ext/filters/client_channel/lb_policy/xds/xds.h
- src/core/ext/filters/client_channel/lb_policy/xds/xds_channel.h
- src/core/ext/filters/client_channel/lb_policy/xds/xds_client_stats.h
src:
- src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/google/protobuf/duration.pb.c
- src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/google/protobuf/timestamp.pb.c
- src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.c
- src/core/ext/filters/client_channel/lb_policy/xds/client_load_reporting_filter.cc
- src/core/ext/filters/client_channel/lb_policy/xds/load_balancer_api.cc
- src/core/ext/filters/client_channel/lb_policy/xds/xds.cc
- src/core/ext/filters/client_channel/lb_policy/xds/xds_channel_secure.cc
- src/core/ext/filters/client_channel/lb_policy/xds/xds_client_stats.cc
plugin: grpc_lb_policy_xds
uses:
- grpc_base
- grpc_secure
- grpc_client_channel
- nanopb
- grpc_resolver_fake
- name: grpc_lb_subchannel_list
headers:
- src/core/ext/filters/client_channel/lb_policy/subchannel_list.h
@ -1965,6 +2016,7 @@ libs:
- src/proto/grpc/testing/worker_service.proto
- test/cpp/qps/benchmark_config.cc
- test/cpp/qps/client_async.cc
- test/cpp/qps/client_callback.cc
- test/cpp/qps/client_sync.cc
- test/cpp/qps/driver.cc
- test/cpp/qps/parse_json.cc
@ -2785,7 +2837,7 @@ targets:
filegroups:
- cmdline
uses_polling: false
- name: handshake_client
- name: handshake_client_ssl
build: test
language: c
src:
@ -2800,7 +2852,7 @@ targets:
platforms:
- linux
secure: true
- name: handshake_server
- name: handshake_server_ssl
build: test
language: c
headers:
@ -3099,7 +3151,7 @@ targets:
- mac
- linux
- posix
- name: memory_profile_client
- name: memory_usage_client
build: test
run: false
language: c
@ -3111,7 +3163,7 @@ targets:
- gpr_test_util
- gpr
uses_polling: false
- name: memory_profile_server
- name: memory_usage_server
build: test
run: false
language: c
@ -3122,7 +3174,7 @@ targets:
- grpc
- gpr_test_util
- gpr
- name: memory_profile_test
- name: memory_usage_test
cpu_cost: 1.5
build: test
language: c

@ -13,5 +13,5 @@
# limitations under the License.
module GrpcBuildConfig
CORE_WINDOWS_DLL = '/tmp/libs/opt/grpc-6.dll'
CORE_WINDOWS_DLL = '/tmp/libs/opt/grpc-7.dll'
end

@ -1,4 +1,4 @@
set noparent
@jtattermusch
@nicolasnoble
@mehrdada
@apolcyn

@ -15,4 +15,5 @@
- 1.13 'g' stands for ['gloriosa'](https://github.com/grpc/grpc/tree/v1.13.x)
- 1.14 'g' stands for ['gladiolus'](https://github.com/grpc/grpc/tree/v1.14.x)
- 1.15 'g' stands for ['glider'](https://github.com/grpc/grpc/tree/v1.15.x)
- 1.16 'g' stands for ['gao'](https://github.com/grpc/grpc/tree/master)
- 1.16 'g' stands for ['gao'](https://github.com/grpc/grpc/tree/v1.16.x)
- 1.17 'g' stands for ['gizmo'](https://github.com/grpc/grpc/tree/master)

@ -28,7 +28,7 @@ Language | From source | Platform | Uses assembly optimizations
C# | n/a | Linux, 64bit | :heavy_check_mark:
C# | n/a | Linux, 32bit | :x:
C# | n/a | MacOS | :heavy_check_mark:
C# | n/a | Windows | :x:
C# | n/a | Windows | :heavy_check_mark:
Node.JS | n/a | Linux | :heavy_check_mark:
Node.JS | n/a | MacOS | :heavy_check_mark:
Node.JS | n/a | Windows | :x:

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

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

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

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

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

@ -75,12 +75,12 @@ EXPORTS
grpc_resource_quota_arg_vtable
grpc_channelz_get_top_channels
grpc_channelz_get_servers
grpc_channelz_get_server_sockets
grpc_channelz_get_channel
grpc_channelz_get_subchannel
grpc_channelz_get_socket
grpc_insecure_channel_create_from_fd
grpc_server_add_insecure_channel_from_fd
grpc_use_signal
grpc_auth_property_iterator_next
grpc_auth_context_property_iterator
grpc_auth_context_peer_identity

@ -1717,6 +1717,7 @@
'src/proto/grpc/testing/worker_service.proto',
'test/cpp/qps/benchmark_config.cc',
'test/cpp/qps/client_async.cc',
'test/cpp/qps/client_callback.cc',
'test/cpp/qps/client_sync.cc',
'test/cpp/qps/driver.cc',
'test/cpp/qps/parse_json.cc',

@ -503,6 +503,10 @@ GRPCAPI char* grpc_channelz_get_top_channels(intptr_t start_channel_id);
/* Gets all servers that exist in the process. */
GRPCAPI char* grpc_channelz_get_servers(intptr_t start_server_id);
/* Gets all server sockets that exist in the server. */
GRPCAPI char* grpc_channelz_get_server_sockets(intptr_t server_id,
intptr_t start_socket_id);
/* Returns a single Channel, or else a NOT_FOUND code. The returned string
is allocated and must be freed by the application. */
GRPCAPI char* grpc_channelz_get_channel(intptr_t channel_id);

@ -52,14 +52,6 @@ GRPCAPI grpc_channel* grpc_insecure_channel_create_from_fd(
GRPCAPI void grpc_server_add_insecure_channel_from_fd(grpc_server* server,
void* reserved, int fd);
/** GRPC Core POSIX library may internally use signals to optimize some work.
The library uses (SIGRTMIN + 6) signal by default. Use this API to instruct
the library to use a different signal i.e 'signum' instead.
Note:
- To prevent GRPC library from using any signals, pass a 'signum' of -1
- This API is optional but if called, it MUST be called before grpc_init() */
GRPCAPI void grpc_use_signal(int signum);
#ifdef __cplusplus
}
#endif

@ -19,10 +19,6 @@
#ifndef GRPCPP_OPENCENSUS_H
#define GRPCPP_OPENCENSUS_H
#ifndef GRPC_BAZEL_BUILD
#error OpenCensus for gRPC is only supported when building with bazel.
#endif
#include "opencensus/trace/span.h"
namespace grpc {

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

@ -1,4 +1,4 @@
set noparent
@markdroth
@dgquintas
@apolcyn
@AspirinSJL

@ -129,6 +129,8 @@ typedef struct client_channel_channel_data {
grpc_core::UniquePtr<char> info_lb_policy_name;
/** service config in JSON form */
grpc_core::UniquePtr<char> info_service_config_json;
/* backpointer to grpc_channel's channelz node */
grpc_core::channelz::ClientChannelNode* channelz_channel;
} channel_data;
typedef struct {
@ -153,6 +155,23 @@ static void watch_lb_policy_locked(channel_data* chand,
grpc_core::LoadBalancingPolicy* lb_policy,
grpc_connectivity_state current_state);
static const char* channel_connectivity_state_change_string(
grpc_connectivity_state state) {
switch (state) {
case GRPC_CHANNEL_IDLE:
return "Channel state change to IDLE";
case GRPC_CHANNEL_CONNECTING:
return "Channel state change to CONNECTING";
case GRPC_CHANNEL_READY:
return "Channel state change to READY";
case GRPC_CHANNEL_TRANSIENT_FAILURE:
return "Channel state change to TRANSIENT_FAILURE";
case GRPC_CHANNEL_SHUTDOWN:
return "Channel state change to SHUTDOWN";
}
GPR_UNREACHABLE_CODE(return "UNKNOWN");
}
static void set_channel_connectivity_state_locked(channel_data* chand,
grpc_connectivity_state state,
grpc_error* error,
@ -177,6 +196,12 @@ static void set_channel_connectivity_state_locked(channel_data* chand,
gpr_log(GPR_INFO, "chand=%p: setting connectivity state to %s", chand,
grpc_connectivity_state_name(state));
}
if (chand->channelz_channel != nullptr) {
chand->channelz_channel->AddTraceEvent(
grpc_core::channelz::ChannelTrace::Severity::Info,
grpc_slice_from_static_string(
channel_connectivity_state_change_string(state)));
}
grpc_connectivity_state_set(&chand->state_tracker, state, error, reason);
}
@ -699,6 +724,7 @@ static grpc_error* cc_init_channel_elem(grpc_channel_element* elem,
// Record enable_retries.
arg = grpc_channel_args_find(args->channel_args, GRPC_ARG_ENABLE_RETRIES);
chand->enable_retries = grpc_channel_arg_get_bool(arg, true);
chand->channelz_channel = nullptr;
// Record client channel factory.
arg = grpc_channel_args_find(args->channel_args,
GRPC_ARG_CLIENT_CHANNEL_FACTORY);
@ -933,11 +959,6 @@ typedef struct client_channel_call_data {
grpc_closure pick_closure;
grpc_closure pick_cancel_closure;
// state needed to support channelz interception of recv trailing metadata.
grpc_closure recv_trailing_metadata_ready_channelz;
grpc_closure* original_recv_trailing_metadata;
grpc_metadata_batch* recv_trailing_metadata;
grpc_polling_entity* pollent;
bool pollent_added_to_interested_parties;
@ -999,8 +1020,6 @@ static void start_internal_recv_trailing_metadata(grpc_call_element* elem);
static void on_complete(void* arg, grpc_error* error);
static void start_retriable_subchannel_batches(void* arg, grpc_error* ignored);
static void start_pick_locked(void* arg, grpc_error* ignored);
static void maybe_intercept_recv_trailing_metadata_for_channelz(
grpc_call_element* elem, grpc_transport_stream_op_batch* batch);
//
// send op data caching
@ -1299,7 +1318,6 @@ static void pending_batches_resume(grpc_call_element* elem) {
pending_batch* pending = &calld->pending_batches[i];
grpc_transport_stream_op_batch* batch = pending->batch;
if (batch != nullptr) {
maybe_intercept_recv_trailing_metadata_for_channelz(elem, batch);
batch->handler_private.extra_arg = calld->subchannel_call;
GRPC_CLOSURE_INIT(&batch->handler_private.closure,
resume_pending_batch_in_call_combiner, batch,
@ -1977,15 +1995,6 @@ static void recv_trailing_metadata_ready(void* arg, grpc_error* error) {
batch_data->batch.payload->recv_trailing_metadata.recv_trailing_metadata;
get_call_status(elem, md_batch, GRPC_ERROR_REF(error), &status,
&server_pushback_md);
grpc_core::channelz::SubchannelNode* channelz_subchannel =
calld->pick.connected_subchannel->channelz_subchannel();
if (channelz_subchannel != nullptr) {
if (status == GRPC_STATUS_OK) {
channelz_subchannel->RecordCallSucceeded();
} else {
channelz_subchannel->RecordCallFailed();
}
}
if (grpc_client_channel_trace.enabled()) {
gpr_log(GPR_INFO, "chand=%p calld=%p: call finished, status=%s", chand,
calld, grpc_status_code_to_string(status));
@ -2211,9 +2220,9 @@ static void add_retriable_send_initial_metadata_op(
.grpc_previous_rpc_attempts);
}
if (GPR_UNLIKELY(calld->num_attempts_completed > 0)) {
grpc_mdelem retry_md = grpc_mdelem_from_slices(
grpc_mdelem retry_md = grpc_mdelem_create(
GRPC_MDSTR_GRPC_PREVIOUS_RPC_ATTEMPTS,
*retry_count_strings[calld->num_attempts_completed - 1]);
*retry_count_strings[calld->num_attempts_completed - 1], nullptr);
grpc_error* error = grpc_metadata_batch_add_tail(
&retry_state->send_initial_metadata,
&retry_state->send_initial_metadata_storage[calld->send_initial_metadata
@ -2589,69 +2598,6 @@ static void start_retriable_subchannel_batches(void* arg, grpc_error* ignored) {
closures.RunClosures(calld->call_combiner);
}
//
// Channelz
//
static void recv_trailing_metadata_ready_channelz(void* arg,
grpc_error* error) {
grpc_call_element* elem = static_cast<grpc_call_element*>(arg);
channel_data* chand = static_cast<channel_data*>(elem->channel_data);
call_data* calld = static_cast<call_data*>(elem->call_data);
if (grpc_client_channel_trace.enabled()) {
gpr_log(GPR_INFO,
"chand=%p calld=%p: got recv_trailing_metadata_ready_channelz, "
"error=%s",
chand, calld, grpc_error_string(error));
}
GPR_ASSERT(calld->recv_trailing_metadata != nullptr);
grpc_status_code status = GRPC_STATUS_OK;
grpc_metadata_batch* md_batch = calld->recv_trailing_metadata;
get_call_status(elem, md_batch, GRPC_ERROR_REF(error), &status, nullptr);
grpc_core::channelz::SubchannelNode* channelz_subchannel =
calld->pick.connected_subchannel->channelz_subchannel();
GPR_ASSERT(channelz_subchannel != nullptr);
if (status == GRPC_STATUS_OK) {
channelz_subchannel->RecordCallSucceeded();
} else {
channelz_subchannel->RecordCallFailed();
}
calld->recv_trailing_metadata = nullptr;
GRPC_CLOSURE_RUN(calld->original_recv_trailing_metadata, error);
}
// If channelz is enabled, intercept recv_trailing so that we may check the
// status and associate it to a subchannel.
// Returns true if callback was intercepted, false otherwise.
static void maybe_intercept_recv_trailing_metadata_for_channelz(
grpc_call_element* elem, grpc_transport_stream_op_batch* batch) {
call_data* calld = static_cast<call_data*>(elem->call_data);
// only intercept payloads with recv trailing.
if (!batch->recv_trailing_metadata) {
return;
}
// only add interceptor is channelz is enabled.
if (calld->pick.connected_subchannel->channelz_subchannel() == nullptr) {
return;
}
if (grpc_client_channel_trace.enabled()) {
gpr_log(GPR_INFO,
"calld=%p batch=%p: intercepting recv trailing for channelz", calld,
batch);
}
GRPC_CLOSURE_INIT(&calld->recv_trailing_metadata_ready_channelz,
recv_trailing_metadata_ready_channelz, elem,
grpc_schedule_on_exec_ctx);
// save some state needed for the interception callback.
GPR_ASSERT(calld->recv_trailing_metadata == nullptr);
calld->recv_trailing_metadata =
batch->payload->recv_trailing_metadata.recv_trailing_metadata;
calld->original_recv_trailing_metadata =
batch->payload->recv_trailing_metadata.recv_trailing_metadata_ready;
batch->payload->recv_trailing_metadata.recv_trailing_metadata_ready =
&calld->recv_trailing_metadata_ready_channelz;
}
//
// LB pick
//
@ -3288,9 +3234,16 @@ static void try_to_connect_locked(void* arg, grpc_error* error_ignored) {
GRPC_CHANNEL_STACK_UNREF(chand->owning_stack, "try_to_connect");
}
void grpc_client_channel_set_channelz_node(
grpc_channel_element* elem, grpc_core::channelz::ClientChannelNode* node) {
channel_data* chand = static_cast<channel_data*>(elem->channel_data);
chand->channelz_channel = node;
}
void grpc_client_channel_populate_child_refs(
grpc_channel_element* elem, grpc_core::ChildRefsList* child_subchannels,
grpc_core::ChildRefsList* child_channels) {
grpc_channel_element* elem,
grpc_core::channelz::ChildRefsList* child_subchannels,
grpc_core::channelz::ChildRefsList* child_channels) {
channel_data* chand = static_cast<channel_data*>(elem->channel_data);
if (chand->lb_policy != nullptr) {
chand->lb_policy->FillChildRefsForChannelz(child_subchannels,

@ -40,9 +40,13 @@ extern grpc_core::TraceFlag grpc_client_channel_trace;
extern const grpc_channel_filter grpc_client_channel_filter;
void grpc_client_channel_set_channelz_node(
grpc_channel_element* elem, grpc_core::channelz::ClientChannelNode* node);
void grpc_client_channel_populate_child_refs(
grpc_channel_element* elem, grpc_core::ChildRefsList* child_subchannels,
grpc_core::ChildRefsList* child_channels);
grpc_channel_element* elem,
grpc_core::channelz::ChildRefsList* child_subchannels,
grpc_core::channelz::ChildRefsList* child_channels);
grpc_connectivity_state grpc_client_channel_check_connectivity_state(
grpc_channel_element* elem, int try_to_connect);

@ -49,6 +49,7 @@ ClientChannelNode::ClientChannelNode(grpc_channel* channel,
: ChannelNode(channel, channel_tracer_max_nodes, is_top_level_channel) {
client_channel_ =
grpc_channel_stack_last_element(grpc_channel_get_channel_stack(channel));
grpc_client_channel_set_channelz_node(client_channel_, this);
GPR_ASSERT(client_channel_->filter == &grpc_client_channel_filter);
}

@ -25,17 +25,10 @@
#include "src/core/lib/channel/channel_stack.h"
#include "src/core/lib/channel/channel_trace.h"
#include "src/core/lib/channel/channelz.h"
#include "src/core/lib/gprpp/inlined_vector.h"
typedef struct grpc_subchannel grpc_subchannel;
namespace grpc_core {
// TODO(ncteisen), this only contains the uuids of the children for now,
// since that is all that is strictly needed. In a future enhancement we will
// add human readable names as in the channelz.proto
typedef InlinedVector<intptr_t, 10> ChildRefsList;
namespace channelz {
// Subtype of ChannelNode that overrides and provides client_channel specific

@ -351,6 +351,7 @@ static grpc_handshaker* grpc_http_connect_handshaker_create() {
static void handshaker_factory_add_handshakers(
grpc_handshaker_factory* factory, const grpc_channel_args* args,
grpc_pollset_set* interested_parties,
grpc_handshake_manager* handshake_mgr) {
grpc_handshake_manager_add(handshake_mgr,
grpc_http_connect_handshaker_create());

@ -151,9 +151,9 @@ class LoadBalancingPolicy
/// LB policy's referenced children. This is not invoked from the
/// client_channel's combiner. The implementation is responsible for
/// providing its own synchronization.
virtual void FillChildRefsForChannelz(ChildRefsList* child_subchannels,
ChildRefsList* child_channels)
GRPC_ABSTRACT;
virtual void FillChildRefsForChannelz(
channelz::ChildRefsList* child_subchannels,
channelz::ChildRefsList* child_channels) GRPC_ABSTRACT;
void Orphan() override {
// Invoke ShutdownAndUnrefLocked() inside of the combiner.
@ -212,8 +212,8 @@ class LoadBalancingPolicy
// Dummy classes needed for alignment issues.
// See https://github.com/grpc/grpc/issues/16032 for context.
// TODO(ncteisen): remove this as soon as the issue is resolved.
ChildRefsList dummy_list_foo;
ChildRefsList dummy_list_bar;
channelz::ChildRefsList dummy_list_foo;
channelz::ChildRefsList dummy_list_bar;
};
} // namespace grpc_core

@ -136,8 +136,9 @@ class GrpcLb : public LoadBalancingPolicy {
void HandOffPendingPicksLocked(LoadBalancingPolicy* new_policy) override;
void ExitIdleLocked() override;
void ResetBackoffLocked() override;
void FillChildRefsForChannelz(ChildRefsList* child_subchannels,
ChildRefsList* child_channels) override;
void FillChildRefsForChannelz(
channelz::ChildRefsList* child_subchannels,
channelz::ChildRefsList* child_channels) override;
private:
/// Linked list of pending pick requests. It stores all information needed to
@ -1258,8 +1259,9 @@ bool GrpcLb::PickLocked(PickState* pick, grpc_error** error) {
return pick_done;
}
void GrpcLb::FillChildRefsForChannelz(ChildRefsList* child_subchannels,
ChildRefsList* child_channels) {
void GrpcLb::FillChildRefsForChannelz(
channelz::ChildRefsList* child_subchannels,
channelz::ChildRefsList* child_channels) {
// delegate to the RoundRobin to fill the children subchannels.
rr_policy_->FillChildRefsForChannelz(child_subchannels, child_channels);
MutexLock lock(&lb_channel_mu_);
@ -1489,7 +1491,7 @@ void GrpcLb::OnBalancerChannelConnectivityChangedLocked(void* arg,
grpclb_policy->lb_call_backoff_.Reset();
grpclb_policy->StartBalancerCallLocked();
}
// Fall through.
// fallthrough
case GRPC_CHANNEL_SHUTDOWN:
done:
grpclb_policy->watching_lb_channel_ = false;

@ -59,8 +59,8 @@ class PickFirst : public LoadBalancingPolicy {
void HandOffPendingPicksLocked(LoadBalancingPolicy* new_policy) override;
void ExitIdleLocked() override;
void ResetBackoffLocked() override;
void FillChildRefsForChannelz(ChildRefsList* child_subchannels,
ChildRefsList* ignored) override;
void FillChildRefsForChannelz(channelz::ChildRefsList* child_subchannels,
channelz::ChildRefsList* ignored) override;
private:
~PickFirst();
@ -147,8 +147,8 @@ class PickFirst : public LoadBalancingPolicy {
/// Lock and data used to capture snapshots of this channels child
/// channels and subchannels. This data is consumed by channelz.
gpr_mu child_refs_mu_;
ChildRefsList child_subchannels_;
ChildRefsList child_channels_;
channelz::ChildRefsList child_subchannels_;
channelz::ChildRefsList child_channels_;
};
PickFirst::PickFirst(const Args& args) : LoadBalancingPolicy(args) {
@ -300,7 +300,8 @@ void PickFirst::NotifyOnStateChangeLocked(grpc_connectivity_state* current,
}
void PickFirst::FillChildRefsForChannelz(
ChildRefsList* child_subchannels_to_fill, ChildRefsList* ignored) {
channelz::ChildRefsList* child_subchannels_to_fill,
channelz::ChildRefsList* ignored) {
MutexLock lock(&child_refs_mu_);
for (size_t i = 0; i < child_subchannels_.size(); ++i) {
// TODO(ncteisen): implement a de dup loop that is not O(n^2). Might
@ -320,7 +321,7 @@ void PickFirst::FillChildRefsForChannelz(
}
void PickFirst::UpdateChildRefsLocked() {
ChildRefsList cs;
channelz::ChildRefsList cs;
if (subchannel_list_ != nullptr) {
subchannel_list_->PopulateChildRefsList(&cs);
}

@ -70,8 +70,8 @@ class RoundRobin : public LoadBalancingPolicy {
void HandOffPendingPicksLocked(LoadBalancingPolicy* new_policy) override;
void ExitIdleLocked() override;
void ResetBackoffLocked() override;
void FillChildRefsForChannelz(ChildRefsList* child_subchannels,
ChildRefsList* ignored) override;
void FillChildRefsForChannelz(channelz::ChildRefsList* child_subchannels,
channelz::ChildRefsList* ignored) override;
private:
~RoundRobin();
@ -223,8 +223,8 @@ class RoundRobin : public LoadBalancingPolicy {
/// Lock and data used to capture snapshots of this channel's child
/// channels and subchannels. This data is consumed by channelz.
gpr_mu child_refs_mu_;
ChildRefsList child_subchannels_;
ChildRefsList child_channels_;
channelz::ChildRefsList child_subchannels_;
channelz::ChildRefsList child_channels_;
};
RoundRobin::RoundRobin(const Args& args) : LoadBalancingPolicy(args) {
@ -402,7 +402,8 @@ bool RoundRobin::PickLocked(PickState* pick, grpc_error** error) {
}
void RoundRobin::FillChildRefsForChannelz(
ChildRefsList* child_subchannels_to_fill, ChildRefsList* ignored) {
channelz::ChildRefsList* child_subchannels_to_fill,
channelz::ChildRefsList* ignored) {
MutexLock lock(&child_refs_mu_);
for (size_t i = 0; i < child_subchannels_.size(); ++i) {
// TODO(ncteisen): implement a de dup loop that is not O(n^2). Might
@ -422,7 +423,7 @@ void RoundRobin::FillChildRefsForChannelz(
}
void RoundRobin::UpdateChildRefsLocked() {
ChildRefsList cs;
channelz::ChildRefsList cs;
if (subchannel_list_ != nullptr) {
subchannel_list_->PopulateChildRefsList(&cs);
}

@ -201,7 +201,7 @@ class SubchannelList
bool shutting_down() const { return shutting_down_; }
// Populates refs_list with the uuids of this SubchannelLists's subchannels.
void PopulateChildRefsList(ChildRefsList* refs_list) {
void PopulateChildRefsList(channelz::ChildRefsList* refs_list) {
for (size_t i = 0; i < subchannels_.size(); ++i) {
if (subchannels_[i].subchannel() != nullptr) {
grpc_core::channelz::SubchannelNode* subchannel_node =

@ -0,0 +1,140 @@
/*
*
* Copyright 2018 gRPC authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
#include <grpc/support/port_platform.h>
#include "src/core/ext/filters/client_channel/lb_policy/xds/client_load_reporting_filter.h"
#include <grpc/support/atm.h>
#include <grpc/support/log.h>
#include "src/core/ext/filters/client_channel/lb_policy/xds/xds_client_stats.h"
#include "src/core/lib/iomgr/error.h"
#include "src/core/lib/profiling/timers.h"
static grpc_error* init_channel_elem(grpc_channel_element* elem,
grpc_channel_element_args* args) {
return GRPC_ERROR_NONE;
}
static void destroy_channel_elem(grpc_channel_element* elem) {}
namespace {
struct call_data {
// Stats object to update.
grpc_core::RefCountedPtr<grpc_core::XdsLbClientStats> client_stats;
// State for intercepting send_initial_metadata.
grpc_closure on_complete_for_send;
grpc_closure* original_on_complete_for_send;
bool send_initial_metadata_succeeded;
// State for intercepting recv_initial_metadata.
grpc_closure recv_initial_metadata_ready;
grpc_closure* original_recv_initial_metadata_ready;
bool recv_initial_metadata_succeeded;
};
} // namespace
static void on_complete_for_send(void* arg, grpc_error* error) {
call_data* calld = static_cast<call_data*>(arg);
if (error == GRPC_ERROR_NONE) {
calld->send_initial_metadata_succeeded = true;
}
GRPC_CLOSURE_RUN(calld->original_on_complete_for_send, GRPC_ERROR_REF(error));
}
static void recv_initial_metadata_ready(void* arg, grpc_error* error) {
call_data* calld = static_cast<call_data*>(arg);
if (error == GRPC_ERROR_NONE) {
calld->recv_initial_metadata_succeeded = true;
}
GRPC_CLOSURE_RUN(calld->original_recv_initial_metadata_ready,
GRPC_ERROR_REF(error));
}
static grpc_error* init_call_elem(grpc_call_element* elem,
const grpc_call_element_args* args) {
call_data* calld = static_cast<call_data*>(elem->call_data);
// Get stats object from context and take a ref.
GPR_ASSERT(args->context != nullptr);
if (args->context[GRPC_GRPCLB_CLIENT_STATS].value != nullptr) {
calld->client_stats = static_cast<grpc_core::XdsLbClientStats*>(
args->context[GRPC_GRPCLB_CLIENT_STATS].value)
->Ref();
// Record call started.
calld->client_stats->AddCallStarted();
}
return GRPC_ERROR_NONE;
}
static void destroy_call_elem(grpc_call_element* elem,
const grpc_call_final_info* final_info,
grpc_closure* ignored) {
call_data* calld = static_cast<call_data*>(elem->call_data);
if (calld->client_stats != nullptr) {
// Record call finished, optionally setting client_failed_to_send and
// received.
calld->client_stats->AddCallFinished(
!calld->send_initial_metadata_succeeded /* client_failed_to_send */,
calld->recv_initial_metadata_succeeded /* known_received */);
// All done, so unref the stats object.
// TODO(roth): Eliminate this once filter stack is converted to C++.
calld->client_stats.reset();
}
}
static void start_transport_stream_op_batch(
grpc_call_element* elem, grpc_transport_stream_op_batch* batch) {
call_data* calld = static_cast<call_data*>(elem->call_data);
GPR_TIMER_SCOPE("clr_start_transport_stream_op_batch", 0);
if (calld->client_stats != nullptr) {
// Intercept send_initial_metadata.
if (batch->send_initial_metadata) {
calld->original_on_complete_for_send = batch->on_complete;
GRPC_CLOSURE_INIT(&calld->on_complete_for_send, on_complete_for_send,
calld, grpc_schedule_on_exec_ctx);
batch->on_complete = &calld->on_complete_for_send;
}
// Intercept recv_initial_metadata.
if (batch->recv_initial_metadata) {
calld->original_recv_initial_metadata_ready =
batch->payload->recv_initial_metadata.recv_initial_metadata_ready;
GRPC_CLOSURE_INIT(&calld->recv_initial_metadata_ready,
recv_initial_metadata_ready, calld,
grpc_schedule_on_exec_ctx);
batch->payload->recv_initial_metadata.recv_initial_metadata_ready =
&calld->recv_initial_metadata_ready;
}
}
// Chain to next filter.
grpc_call_next_op(elem, batch);
}
const grpc_channel_filter xds_client_load_reporting_filter = {
start_transport_stream_op_batch,
grpc_channel_next_op,
sizeof(call_data),
init_call_elem,
grpc_call_stack_ignore_set_pollset_or_pollset_set,
destroy_call_elem,
0, // sizeof(channel_data)
init_channel_elem,
destroy_channel_elem,
grpc_channel_next_get_info,
"client_load_reporting"};

@ -0,0 +1,29 @@
/*
*
* Copyright 2018 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_LB_POLICY_XDS_CLIENT_LOAD_REPORTING_FILTER_H
#define GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_LB_POLICY_XDS_CLIENT_LOAD_REPORTING_FILTER_H
#include <grpc/support/port_platform.h>
#include "src/core/lib/channel/channel_stack.h"
extern const grpc_channel_filter xds_client_load_reporting_filter;
#endif /* GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_LB_POLICY_XDS_CLIENT_LOAD_REPORTING_FILTER_H \
*/

@ -0,0 +1,307 @@
/*
*
* Copyright 2018 gRPC authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
#include <grpc/support/port_platform.h>
#include "pb_decode.h"
#include "pb_encode.h"
#include "src/core/ext/filters/client_channel/lb_policy/xds/load_balancer_api.h"
#include <grpc/support/alloc.h>
/* invoked once for every Server in ServerList */
static bool count_serverlist(pb_istream_t* stream, const pb_field_t* field,
void** arg) {
xds_grpclb_serverlist* sl = static_cast<xds_grpclb_serverlist*>(*arg);
xds_grpclb_server server;
if (GPR_UNLIKELY(!pb_decode(stream, grpc_lb_v1_Server_fields, &server))) {
gpr_log(GPR_ERROR, "nanopb error: %s", PB_GET_ERROR(stream));
return false;
}
++sl->num_servers;
return true;
}
typedef struct decode_serverlist_arg {
/* The decoding callback is invoked once per server in serverlist. Remember
* which index of the serverlist are we currently decoding */
size_t decoding_idx;
/* The decoded serverlist */
xds_grpclb_serverlist* serverlist;
} decode_serverlist_arg;
/* invoked once for every Server in ServerList */
static bool decode_serverlist(pb_istream_t* stream, const pb_field_t* field,
void** arg) {
decode_serverlist_arg* dec_arg = static_cast<decode_serverlist_arg*>(*arg);
GPR_ASSERT(dec_arg->serverlist->num_servers >= dec_arg->decoding_idx);
xds_grpclb_server* server =
static_cast<xds_grpclb_server*>(gpr_zalloc(sizeof(xds_grpclb_server)));
if (GPR_UNLIKELY(!pb_decode(stream, grpc_lb_v1_Server_fields, server))) {
gpr_free(server);
gpr_log(GPR_ERROR, "nanopb error: %s", PB_GET_ERROR(stream));
return false;
}
dec_arg->serverlist->servers[dec_arg->decoding_idx++] = server;
return true;
}
xds_grpclb_request* xds_grpclb_request_create(const char* lb_service_name) {
xds_grpclb_request* req =
static_cast<xds_grpclb_request*>(gpr_malloc(sizeof(xds_grpclb_request)));
req->has_client_stats = false;
req->has_initial_request = true;
req->initial_request.has_name = true;
strncpy(req->initial_request.name, lb_service_name,
XDS_SERVICE_NAME_MAX_LENGTH);
return req;
}
static void populate_timestamp(gpr_timespec timestamp,
xds_grpclb_timestamp* timestamp_pb) {
timestamp_pb->has_seconds = true;
timestamp_pb->seconds = timestamp.tv_sec;
timestamp_pb->has_nanos = true;
timestamp_pb->nanos = timestamp.tv_nsec;
}
static bool encode_string(pb_ostream_t* stream, const pb_field_t* field,
void* const* arg) {
char* str = static_cast<char*>(*arg);
if (!pb_encode_tag_for_field(stream, field)) return false;
return pb_encode_string(stream, reinterpret_cast<uint8_t*>(str), strlen(str));
}
static bool encode_drops(pb_ostream_t* stream, const pb_field_t* field,
void* const* arg) {
grpc_core::XdsLbClientStats::DroppedCallCounts* drop_entries =
static_cast<grpc_core::XdsLbClientStats::DroppedCallCounts*>(*arg);
if (drop_entries == nullptr) return true;
for (size_t i = 0; i < drop_entries->size(); ++i) {
if (!pb_encode_tag_for_field(stream, field)) return false;
grpc_lb_v1_ClientStatsPerToken drop_message;
drop_message.load_balance_token.funcs.encode = encode_string;
drop_message.load_balance_token.arg = (*drop_entries)[i].token.get();
drop_message.has_num_calls = true;
drop_message.num_calls = (*drop_entries)[i].count;
if (!pb_encode_submessage(stream, grpc_lb_v1_ClientStatsPerToken_fields,
&drop_message)) {
return false;
}
}
return true;
}
xds_grpclb_request* xds_grpclb_load_report_request_create_locked(
grpc_core::XdsLbClientStats* client_stats) {
xds_grpclb_request* req =
static_cast<xds_grpclb_request*>(gpr_zalloc(sizeof(xds_grpclb_request)));
req->has_client_stats = true;
req->client_stats.has_timestamp = true;
populate_timestamp(gpr_now(GPR_CLOCK_REALTIME), &req->client_stats.timestamp);
req->client_stats.has_num_calls_started = true;
req->client_stats.has_num_calls_finished = true;
req->client_stats.has_num_calls_finished_with_client_failed_to_send = true;
req->client_stats.has_num_calls_finished_with_client_failed_to_send = true;
req->client_stats.has_num_calls_finished_known_received = true;
req->client_stats.calls_finished_with_drop.funcs.encode = encode_drops;
grpc_core::UniquePtr<grpc_core::XdsLbClientStats::DroppedCallCounts>
drop_counts;
client_stats->GetLocked(
&req->client_stats.num_calls_started,
&req->client_stats.num_calls_finished,
&req->client_stats.num_calls_finished_with_client_failed_to_send,
&req->client_stats.num_calls_finished_known_received, &drop_counts);
// Will be deleted in xds_grpclb_request_destroy().
req->client_stats.calls_finished_with_drop.arg = drop_counts.release();
return req;
}
grpc_slice xds_grpclb_request_encode(const xds_grpclb_request* request) {
size_t encoded_length;
pb_ostream_t sizestream;
pb_ostream_t outputstream;
grpc_slice slice;
memset(&sizestream, 0, sizeof(pb_ostream_t));
pb_encode(&sizestream, grpc_lb_v1_LoadBalanceRequest_fields, request);
encoded_length = sizestream.bytes_written;
slice = GRPC_SLICE_MALLOC(encoded_length);
outputstream =
pb_ostream_from_buffer(GRPC_SLICE_START_PTR(slice), encoded_length);
GPR_ASSERT(pb_encode(&outputstream, grpc_lb_v1_LoadBalanceRequest_fields,
request) != 0);
return slice;
}
void xds_grpclb_request_destroy(xds_grpclb_request* request) {
if (request->has_client_stats) {
grpc_core::XdsLbClientStats::DroppedCallCounts* drop_entries =
static_cast<grpc_core::XdsLbClientStats::DroppedCallCounts*>(
request->client_stats.calls_finished_with_drop.arg);
grpc_core::Delete(drop_entries);
}
gpr_free(request);
}
typedef grpc_lb_v1_LoadBalanceResponse xds_grpclb_response;
xds_grpclb_initial_response* xds_grpclb_initial_response_parse(
grpc_slice encoded_xds_grpclb_response) {
pb_istream_t stream =
pb_istream_from_buffer(GRPC_SLICE_START_PTR(encoded_xds_grpclb_response),
GRPC_SLICE_LENGTH(encoded_xds_grpclb_response));
xds_grpclb_response res;
memset(&res, 0, sizeof(xds_grpclb_response));
if (GPR_UNLIKELY(
!pb_decode(&stream, grpc_lb_v1_LoadBalanceResponse_fields, &res))) {
gpr_log(GPR_ERROR, "nanopb error: %s", PB_GET_ERROR(&stream));
return nullptr;
}
if (!res.has_initial_response) return nullptr;
xds_grpclb_initial_response* initial_res =
static_cast<xds_grpclb_initial_response*>(
gpr_malloc(sizeof(xds_grpclb_initial_response)));
memcpy(initial_res, &res.initial_response,
sizeof(xds_grpclb_initial_response));
return initial_res;
}
xds_grpclb_serverlist* xds_grpclb_response_parse_serverlist(
grpc_slice encoded_xds_grpclb_response) {
pb_istream_t stream =
pb_istream_from_buffer(GRPC_SLICE_START_PTR(encoded_xds_grpclb_response),
GRPC_SLICE_LENGTH(encoded_xds_grpclb_response));
pb_istream_t stream_at_start = stream;
xds_grpclb_serverlist* sl = static_cast<xds_grpclb_serverlist*>(
gpr_zalloc(sizeof(xds_grpclb_serverlist)));
xds_grpclb_response res;
memset(&res, 0, sizeof(xds_grpclb_response));
// First pass: count number of servers.
res.server_list.servers.funcs.decode = count_serverlist;
res.server_list.servers.arg = sl;
bool status = pb_decode(&stream, grpc_lb_v1_LoadBalanceResponse_fields, &res);
if (GPR_UNLIKELY(!status)) {
gpr_free(sl);
gpr_log(GPR_ERROR, "nanopb error: %s", PB_GET_ERROR(&stream));
return nullptr;
}
// Second pass: populate servers.
if (sl->num_servers > 0) {
sl->servers = static_cast<xds_grpclb_server**>(
gpr_zalloc(sizeof(xds_grpclb_server*) * sl->num_servers));
decode_serverlist_arg decode_arg;
memset(&decode_arg, 0, sizeof(decode_arg));
decode_arg.serverlist = sl;
res.server_list.servers.funcs.decode = decode_serverlist;
res.server_list.servers.arg = &decode_arg;
status = pb_decode(&stream_at_start, grpc_lb_v1_LoadBalanceResponse_fields,
&res);
if (GPR_UNLIKELY(!status)) {
xds_grpclb_destroy_serverlist(sl);
gpr_log(GPR_ERROR, "nanopb error: %s", PB_GET_ERROR(&stream));
return nullptr;
}
}
return sl;
}
void xds_grpclb_destroy_serverlist(xds_grpclb_serverlist* serverlist) {
if (serverlist == nullptr) {
return;
}
for (size_t i = 0; i < serverlist->num_servers; i++) {
gpr_free(serverlist->servers[i]);
}
gpr_free(serverlist->servers);
gpr_free(serverlist);
}
xds_grpclb_serverlist* xds_grpclb_serverlist_copy(
const xds_grpclb_serverlist* sl) {
xds_grpclb_serverlist* copy = static_cast<xds_grpclb_serverlist*>(
gpr_zalloc(sizeof(xds_grpclb_serverlist)));
copy->num_servers = sl->num_servers;
copy->servers = static_cast<xds_grpclb_server**>(
gpr_malloc(sizeof(xds_grpclb_server*) * sl->num_servers));
for (size_t i = 0; i < sl->num_servers; i++) {
copy->servers[i] =
static_cast<xds_grpclb_server*>(gpr_malloc(sizeof(xds_grpclb_server)));
memcpy(copy->servers[i], sl->servers[i], sizeof(xds_grpclb_server));
}
return copy;
}
bool xds_grpclb_serverlist_equals(const xds_grpclb_serverlist* lhs,
const xds_grpclb_serverlist* rhs) {
if (lhs == nullptr || rhs == nullptr) {
return false;
}
if (lhs->num_servers != rhs->num_servers) {
return false;
}
for (size_t i = 0; i < lhs->num_servers; i++) {
if (!xds_grpclb_server_equals(lhs->servers[i], rhs->servers[i])) {
return false;
}
}
return true;
}
bool xds_grpclb_server_equals(const xds_grpclb_server* lhs,
const xds_grpclb_server* rhs) {
return memcmp(lhs, rhs, sizeof(xds_grpclb_server)) == 0;
}
int xds_grpclb_duration_compare(const xds_grpclb_duration* lhs,
const xds_grpclb_duration* rhs) {
GPR_ASSERT(lhs && rhs);
if (lhs->has_seconds && rhs->has_seconds) {
if (lhs->seconds < rhs->seconds) return -1;
if (lhs->seconds > rhs->seconds) return 1;
} else if (lhs->has_seconds) {
return 1;
} else if (rhs->has_seconds) {
return -1;
}
GPR_ASSERT(lhs->seconds == rhs->seconds);
if (lhs->has_nanos && rhs->has_nanos) {
if (lhs->nanos < rhs->nanos) return -1;
if (lhs->nanos > rhs->nanos) return 1;
} else if (lhs->has_nanos) {
return 1;
} else if (rhs->has_nanos) {
return -1;
}
return 0;
}
grpc_millis xds_grpclb_duration_to_millis(xds_grpclb_duration* duration_pb) {
return static_cast<grpc_millis>(
(duration_pb->has_seconds ? duration_pb->seconds : 0) * GPR_MS_PER_SEC +
(duration_pb->has_nanos ? duration_pb->nanos : 0) / GPR_NS_PER_MS);
}
void xds_grpclb_initial_response_destroy(
xds_grpclb_initial_response* response) {
gpr_free(response);
}

@ -0,0 +1,89 @@
/*
*
* Copyright 2018 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_LB_POLICY_XDS_LOAD_BALANCER_API_H
#define GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_LB_POLICY_XDS_LOAD_BALANCER_API_H
#include <grpc/support/port_platform.h>
#include <grpc/slice_buffer.h>
#include "src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.h"
#include "src/core/ext/filters/client_channel/lb_policy/xds/xds_client_stats.h"
#include "src/core/ext/filters/client_channel/lb_policy_factory.h"
#define XDS_SERVICE_NAME_MAX_LENGTH 128
typedef grpc_lb_v1_Server_ip_address_t xds_grpclb_ip_address;
typedef grpc_lb_v1_LoadBalanceRequest xds_grpclb_request;
typedef grpc_lb_v1_InitialLoadBalanceResponse xds_grpclb_initial_response;
typedef grpc_lb_v1_Server xds_grpclb_server;
typedef google_protobuf_Duration xds_grpclb_duration;
typedef google_protobuf_Timestamp xds_grpclb_timestamp;
typedef struct {
xds_grpclb_server** servers;
size_t num_servers;
} xds_grpclb_serverlist;
/** Create a request for a gRPC LB service under \a lb_service_name */
xds_grpclb_request* xds_grpclb_request_create(const char* lb_service_name);
xds_grpclb_request* xds_grpclb_load_report_request_create_locked(
grpc_core::XdsLbClientStats* client_stats);
/** Protocol Buffers v3-encode \a request */
grpc_slice xds_grpclb_request_encode(const xds_grpclb_request* request);
/** Destroy \a request */
void xds_grpclb_request_destroy(xds_grpclb_request* request);
/** Parse (ie, decode) the bytes in \a encoded_xds_grpclb_response as a \a
* xds_grpclb_initial_response */
xds_grpclb_initial_response* xds_grpclb_initial_response_parse(
grpc_slice encoded_xds_grpclb_response);
/** Parse the list of servers from an encoded \a xds_grpclb_response */
xds_grpclb_serverlist* xds_grpclb_response_parse_serverlist(
grpc_slice encoded_xds_grpclb_response);
/** Return a copy of \a sl. The caller is responsible for calling \a
* xds_grpclb_destroy_serverlist on the returned copy. */
xds_grpclb_serverlist* xds_grpclb_serverlist_copy(
const xds_grpclb_serverlist* sl);
bool xds_grpclb_serverlist_equals(const xds_grpclb_serverlist* lhs,
const xds_grpclb_serverlist* rhs);
bool xds_grpclb_server_equals(const xds_grpclb_server* lhs,
const xds_grpclb_server* rhs);
/** Destroy \a serverlist */
void xds_grpclb_destroy_serverlist(xds_grpclb_serverlist* serverlist);
/** Compare \a lhs against \a rhs and return 0 if \a lhs and \a rhs are equal,
* < 0 if \a lhs represents a duration shorter than \a rhs and > 0 otherwise */
int xds_grpclb_duration_compare(const xds_grpclb_duration* lhs,
const xds_grpclb_duration* rhs);
grpc_millis xds_grpclb_duration_to_millis(xds_grpclb_duration* duration_pb);
/** Destroy \a initial_response */
void xds_grpclb_initial_response_destroy(xds_grpclb_initial_response* response);
#endif /* GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_LB_POLICY_XDS_LOAD_BALANCER_API_H \
*/

File diff suppressed because it is too large Load Diff

@ -0,0 +1,36 @@
/*
*
* Copyright 2018 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_LB_POLICY_XDS_XDS_H
#define GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_LB_POLICY_XDS_XDS_H
#include <grpc/support/port_platform.h>
/** Channel arg indicating if a target corresponding to the address is grpclb
* loadbalancer. The type of this arg is an integer and the value is treated as
* a bool. */
#define GRPC_ARG_ADDRESS_IS_XDS_LOAD_BALANCER \
"grpc.address_is_xds_load_balancer"
/** Channel arg indicating if a target corresponding to the address is a backend
* received from a balancer. The type of this arg is an integer and the value is
* treated as a bool. */
#define GRPC_ARG_ADDRESS_IS_BACKEND_FROM_XDS_LOAD_BALANCER \
"grpc.address_is_backend_from_xds_load_balancer"
#endif /* GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_LB_POLICY_XDS_XDS_H \
*/

@ -0,0 +1,26 @@
/*
*
* Copyright 2018 gRPC authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
#include <grpc/support/port_platform.h>
#include "src/core/ext/filters/client_channel/lb_policy/xds/xds_channel.h"
grpc_channel_args* grpc_lb_policy_xds_modify_lb_channel_args(
grpc_channel_args* args) {
return args;
}

@ -0,0 +1,36 @@
/*
*
* Copyright 2018 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_LB_POLICY_XDS_XDS_CHANNEL_H
#define GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_LB_POLICY_XDS_XDS_CHANNEL_H
#include <grpc/support/port_platform.h>
#include "src/core/ext/filters/client_channel/lb_policy_factory.h"
/// Makes any necessary modifications to \a args for use in the xds
/// balancer channel.
///
/// Takes ownership of \a args.
///
/// Caller takes ownership of the returned args.
grpc_channel_args* grpc_lb_policy_xds_modify_lb_channel_args(
grpc_channel_args* args);
#endif /* GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_LB_POLICY_XDS_XDS_CHANNEL_H \
*/

@ -0,0 +1,107 @@
/*
*
* Copyright 2018 gRPC authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
#include <grpc/support/port_platform.h>
#include "src/core/ext/filters/client_channel/lb_policy/xds/xds_channel.h"
#include <grpc/support/alloc.h>
#include <grpc/support/string_util.h>
#include <string.h>
#include "src/core/ext/filters/client_channel/client_channel.h"
#include "src/core/lib/channel/channel_args.h"
#include "src/core/lib/gpr/string.h"
#include "src/core/lib/iomgr/sockaddr_utils.h"
#include "src/core/lib/security/credentials/credentials.h"
#include "src/core/lib/security/transport/target_authority_table.h"
#include "src/core/lib/slice/slice_internal.h"
namespace grpc_core {
namespace {
int BalancerNameCmp(const grpc_core::UniquePtr<char>& a,
const grpc_core::UniquePtr<char>& b) {
return strcmp(a.get(), b.get());
}
RefCountedPtr<TargetAuthorityTable> CreateTargetAuthorityTable(
grpc_lb_addresses* addresses) {
TargetAuthorityTable::Entry* target_authority_entries =
static_cast<TargetAuthorityTable::Entry*>(gpr_zalloc(
sizeof(*target_authority_entries) * addresses->num_addresses));
for (size_t i = 0; i < addresses->num_addresses; ++i) {
char* addr_str;
GPR_ASSERT(grpc_sockaddr_to_string(
&addr_str, &addresses->addresses[i].address, true) > 0);
target_authority_entries[i].key = grpc_slice_from_copied_string(addr_str);
target_authority_entries[i].value.reset(
gpr_strdup(addresses->addresses[i].balancer_name));
gpr_free(addr_str);
}
RefCountedPtr<TargetAuthorityTable> target_authority_table =
TargetAuthorityTable::Create(addresses->num_addresses,
target_authority_entries, BalancerNameCmp);
gpr_free(target_authority_entries);
return target_authority_table;
}
} // namespace
} // namespace grpc_core
grpc_channel_args* grpc_lb_policy_xds_modify_lb_channel_args(
grpc_channel_args* args) {
const char* args_to_remove[1];
size_t num_args_to_remove = 0;
grpc_arg args_to_add[2];
size_t num_args_to_add = 0;
// Add arg for targets info table.
const grpc_arg* arg = grpc_channel_args_find(args, GRPC_ARG_LB_ADDRESSES);
GPR_ASSERT(arg != nullptr);
GPR_ASSERT(arg->type == GRPC_ARG_POINTER);
grpc_lb_addresses* addresses =
static_cast<grpc_lb_addresses*>(arg->value.pointer.p);
grpc_core::RefCountedPtr<grpc_core::TargetAuthorityTable>
target_authority_table = grpc_core::CreateTargetAuthorityTable(addresses);
args_to_add[num_args_to_add++] =
grpc_core::CreateTargetAuthorityTableChannelArg(
target_authority_table.get());
// Substitute the channel credentials with a version without call
// credentials: the load balancer is not necessarily trusted to handle
// bearer token credentials.
grpc_channel_credentials* channel_credentials =
grpc_channel_credentials_find_in_args(args);
grpc_channel_credentials* creds_sans_call_creds = nullptr;
if (channel_credentials != nullptr) {
creds_sans_call_creds =
grpc_channel_credentials_duplicate_without_call_credentials(
channel_credentials);
GPR_ASSERT(creds_sans_call_creds != nullptr);
args_to_remove[num_args_to_remove++] = GRPC_ARG_CHANNEL_CREDENTIALS;
args_to_add[num_args_to_add++] =
grpc_channel_credentials_to_arg(creds_sans_call_creds);
}
grpc_channel_args* result = grpc_channel_args_copy_and_add_and_remove(
args, args_to_remove, num_args_to_remove, args_to_add, num_args_to_add);
// Clean up.
grpc_channel_args_destroy(args);
if (creds_sans_call_creds != nullptr) {
grpc_channel_credentials_unref(creds_sans_call_creds);
}
return result;
}

@ -0,0 +1,85 @@
/*
*
* Copyright 2018 gRPC authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
#include <grpc/support/port_platform.h>
#include "src/core/ext/filters/client_channel/lb_policy/xds/xds_client_stats.h"
#include <grpc/support/atm.h>
#include <grpc/support/string_util.h>
#include <string.h>
namespace grpc_core {
void XdsLbClientStats::AddCallStarted() {
gpr_atm_full_fetch_add(&num_calls_started_, (gpr_atm)1);
}
void XdsLbClientStats::AddCallFinished(bool finished_with_client_failed_to_send,
bool finished_known_received) {
gpr_atm_full_fetch_add(&num_calls_finished_, (gpr_atm)1);
if (finished_with_client_failed_to_send) {
gpr_atm_full_fetch_add(&num_calls_finished_with_client_failed_to_send_,
(gpr_atm)1);
}
if (finished_known_received) {
gpr_atm_full_fetch_add(&num_calls_finished_known_received_, (gpr_atm)1);
}
}
void XdsLbClientStats::AddCallDroppedLocked(char* token) {
// Increment num_calls_started and num_calls_finished.
gpr_atm_full_fetch_add(&num_calls_started_, (gpr_atm)1);
gpr_atm_full_fetch_add(&num_calls_finished_, (gpr_atm)1);
// Record the drop.
if (drop_token_counts_ == nullptr) {
drop_token_counts_.reset(New<DroppedCallCounts>());
}
for (size_t i = 0; i < drop_token_counts_->size(); ++i) {
if (strcmp((*drop_token_counts_)[i].token.get(), token) == 0) {
++(*drop_token_counts_)[i].count;
return;
}
}
// Not found, so add a new entry.
drop_token_counts_->emplace_back(UniquePtr<char>(gpr_strdup(token)), 1);
}
namespace {
void AtomicGetAndResetCounter(int64_t* value, gpr_atm* counter) {
*value = static_cast<int64_t>(gpr_atm_full_xchg(counter, (gpr_atm)0));
}
} // namespace
void XdsLbClientStats::GetLocked(
int64_t* num_calls_started, int64_t* num_calls_finished,
int64_t* num_calls_finished_with_client_failed_to_send,
int64_t* num_calls_finished_known_received,
UniquePtr<DroppedCallCounts>* drop_token_counts) {
AtomicGetAndResetCounter(num_calls_started, &num_calls_started_);
AtomicGetAndResetCounter(num_calls_finished, &num_calls_finished_);
AtomicGetAndResetCounter(num_calls_finished_with_client_failed_to_send,
&num_calls_finished_with_client_failed_to_send_);
AtomicGetAndResetCounter(num_calls_finished_known_received,
&num_calls_finished_known_received_);
*drop_token_counts = std::move(drop_token_counts_);
}
} // namespace grpc_core

@ -0,0 +1,72 @@
/*
*
* Copyright 2018 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_LB_POLICY_XDS_XDS_CLIENT_STATS_H
#define GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_LB_POLICY_XDS_XDS_CLIENT_STATS_H
#include <grpc/support/port_platform.h>
#include <grpc/support/atm.h>
#include "src/core/lib/gprpp/inlined_vector.h"
#include "src/core/lib/gprpp/memory.h"
#include "src/core/lib/gprpp/ref_counted.h"
namespace grpc_core {
class XdsLbClientStats : public RefCounted<XdsLbClientStats> {
public:
struct DropTokenCount {
UniquePtr<char> token;
int64_t count;
DropTokenCount(UniquePtr<char> token, int64_t count)
: token(std::move(token)), count(count) {}
};
typedef InlinedVector<DropTokenCount, 10> DroppedCallCounts;
XdsLbClientStats() {}
void AddCallStarted();
void AddCallFinished(bool finished_with_client_failed_to_send,
bool finished_known_received);
// This method is not thread-safe; caller must synchronize.
void AddCallDroppedLocked(char* token);
// This method is not thread-safe; caller must synchronize.
void GetLocked(int64_t* num_calls_started, int64_t* num_calls_finished,
int64_t* num_calls_finished_with_client_failed_to_send,
int64_t* num_calls_finished_known_received,
UniquePtr<DroppedCallCounts>* drop_token_counts);
private:
// This field must only be accessed via *_locked() methods.
UniquePtr<DroppedCallCounts> drop_token_counts_;
// These fields may be accessed from multiple threads at a time.
gpr_atm num_calls_started_ = 0;
gpr_atm num_calls_finished_ = 0;
gpr_atm num_calls_finished_with_client_failed_to_send_ = 0;
gpr_atm num_calls_finished_known_received_ = 0;
};
} // namespace grpc_core
#endif /* GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_LB_POLICY_XDS_XDS_CLIENT_STATS_H \
*/

@ -49,6 +49,8 @@
#include "src/core/lib/surface/channel.h"
#include "src/core/lib/surface/channel_init.h"
#include "src/core/lib/transport/connectivity_state.h"
#include "src/core/lib/transport/error_utils.h"
#include "src/core/lib/transport/status_metadata.h"
#define INTERNAL_REF_BITS 16
#define STRONG_REF_MASK (~(gpr_atm)((1 << INTERNAL_REF_BITS) - 1))
@ -144,6 +146,11 @@ struct grpc_subchannel {
struct grpc_subchannel_call {
grpc_core::ConnectedSubchannel* connection;
grpc_closure* schedule_closure_after_destroy;
// state needed to support channelz interception of recv trailing metadata.
grpc_closure recv_trailing_metadata_ready;
grpc_closure* original_recv_trailing_metadata;
grpc_metadata_batch* recv_trailing_metadata;
grpc_millis deadline;
};
#define SUBCHANNEL_CALL_TO_CALL_STACK(call) \
@ -421,6 +428,35 @@ intptr_t grpc_subchannel_get_child_socket_uuid(grpc_subchannel* subchannel) {
}
}
static const char* subchannel_connectivity_state_change_string(
grpc_connectivity_state state) {
switch (state) {
case GRPC_CHANNEL_IDLE:
return "Subchannel state change to IDLE";
case GRPC_CHANNEL_CONNECTING:
return "Subchannel state change to CONNECTING";
case GRPC_CHANNEL_READY:
return "Subchannel state change to READY";
case GRPC_CHANNEL_TRANSIENT_FAILURE:
return "Subchannel state change to TRANSIENT_FAILURE";
case GRPC_CHANNEL_SHUTDOWN:
return "Subchannel state change to SHUTDOWN";
}
GPR_UNREACHABLE_CODE(return "UNKNOWN");
}
static void set_subchannel_connectivity_state_locked(
grpc_subchannel* c, grpc_connectivity_state state, grpc_error* error,
const char* reason) {
if (c->channelz_subchannel != nullptr) {
c->channelz_subchannel->AddTraceEvent(
grpc_core::channelz::ChannelTrace::Severity::Info,
grpc_slice_from_static_string(
subchannel_connectivity_state_change_string(state)));
}
grpc_connectivity_state_set(&c->state_tracker, state, error, reason);
}
static void continue_connect_locked(grpc_subchannel* c) {
grpc_connect_in_args args;
args.interested_parties = c->pollset_set;
@ -429,7 +465,7 @@ static void continue_connect_locked(grpc_subchannel* c) {
c->next_attempt_deadline = c->backoff->NextAttemptTime();
args.deadline = std::max(c->next_attempt_deadline, min_deadline);
args.channel_args = c->args;
grpc_connectivity_state_set(&c->state_tracker, GRPC_CHANNEL_CONNECTING,
set_subchannel_connectivity_state_locked(c, GRPC_CHANNEL_CONNECTING,
GRPC_ERROR_NONE, "connecting");
grpc_connector_connect(c->connector, &args, &c->connecting_result,
&c->on_connected);
@ -580,9 +616,9 @@ static void on_connected_subchannel_connectivity_changed(void* p,
connected_subchannel_watcher->connectivity_state));
}
c->connected_subchannel.reset();
grpc_connectivity_state_set(&c->state_tracker,
GRPC_CHANNEL_TRANSIENT_FAILURE,
GRPC_ERROR_REF(error), "reflect_child");
set_subchannel_connectivity_state_locked(
c, GRPC_CHANNEL_TRANSIENT_FAILURE, GRPC_ERROR_REF(error),
"reflect_child");
c->backoff_begun = false;
c->backoff->Reset();
maybe_start_connecting_locked(c);
@ -593,8 +629,8 @@ static void on_connected_subchannel_connectivity_changed(void* p,
break;
}
default: {
grpc_connectivity_state_set(
&c->state_tracker, connected_subchannel_watcher->connectivity_state,
set_subchannel_connectivity_state_locked(
c, connected_subchannel_watcher->connectivity_state,
GRPC_ERROR_REF(error), "reflect_child");
GRPC_SUBCHANNEL_WEAK_REF(c, "state_watcher");
c->connected_subchannel->NotifyOnStateChange(
@ -652,7 +688,7 @@ static bool publish_transport_locked(grpc_subchannel* c) {
/* publish */
c->connected_subchannel.reset(grpc_core::New<grpc_core::ConnectedSubchannel>(
stk, c->channelz_subchannel.get(), socket_uuid));
stk, c->channelz_subchannel, socket_uuid));
gpr_log(GPR_INFO, "New connected subchannel at %p for subchannel %p",
c->connected_subchannel.get(), c);
@ -665,7 +701,7 @@ static bool publish_transport_locked(grpc_subchannel* c) {
&connected_subchannel_watcher->closure);
/* signal completion */
grpc_connectivity_state_set(&c->state_tracker, GRPC_CHANNEL_READY,
set_subchannel_connectivity_state_locked(c, GRPC_CHANNEL_READY,
GRPC_ERROR_NONE, "connected");
return true;
}
@ -683,8 +719,8 @@ static void on_subchannel_connected(void* arg, grpc_error* error) {
} else if (c->disconnected) {
GRPC_SUBCHANNEL_WEAK_UNREF(c, "connecting");
} else {
grpc_connectivity_state_set(
&c->state_tracker, GRPC_CHANNEL_TRANSIENT_FAILURE,
set_subchannel_connectivity_state_locked(
c, GRPC_CHANNEL_TRANSIENT_FAILURE,
grpc_error_set_int(GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING(
"Connect Failed", &error, 1),
GRPC_ERROR_INT_GRPC_STATUS, GRPC_STATUS_UNAVAILABLE),
@ -745,9 +781,71 @@ void grpc_subchannel_call_unref(
GRPC_CALL_STACK_UNREF(SUBCHANNEL_CALL_TO_CALL_STACK(c), REF_REASON);
}
// Sets *status based on md_batch and error.
static void get_call_status(grpc_subchannel_call* call,
grpc_metadata_batch* md_batch, grpc_error* error,
grpc_status_code* status) {
if (error != GRPC_ERROR_NONE) {
grpc_error_get_status(error, call->deadline, status, nullptr, nullptr,
nullptr);
} else {
if (md_batch->idx.named.grpc_status != nullptr) {
*status = grpc_get_status_code_from_metadata(
md_batch->idx.named.grpc_status->md);
} else {
*status = GRPC_STATUS_UNKNOWN;
}
}
GRPC_ERROR_UNREF(error);
}
static void recv_trailing_metadata_ready(void* arg, grpc_error* error) {
grpc_subchannel_call* call = static_cast<grpc_subchannel_call*>(arg);
GPR_ASSERT(call->recv_trailing_metadata != nullptr);
grpc_status_code status = GRPC_STATUS_OK;
grpc_metadata_batch* md_batch = call->recv_trailing_metadata;
get_call_status(call, md_batch, GRPC_ERROR_REF(error), &status);
grpc_core::channelz::SubchannelNode* channelz_subchannel =
call->connection->channelz_subchannel();
GPR_ASSERT(channelz_subchannel != nullptr);
if (status == GRPC_STATUS_OK) {
channelz_subchannel->RecordCallSucceeded();
} else {
channelz_subchannel->RecordCallFailed();
}
GRPC_CLOSURE_RUN(call->original_recv_trailing_metadata,
GRPC_ERROR_REF(error));
}
// If channelz is enabled, intercept recv_trailing so that we may check the
// status and associate it to a subchannel.
static void maybe_intercept_recv_trailing_metadata(
grpc_subchannel_call* call, grpc_transport_stream_op_batch* batch) {
// only intercept payloads with recv trailing.
if (!batch->recv_trailing_metadata) {
return;
}
// only add interceptor is channelz is enabled.
if (call->connection->channelz_subchannel() == nullptr) {
return;
}
GRPC_CLOSURE_INIT(&call->recv_trailing_metadata_ready,
recv_trailing_metadata_ready, call,
grpc_schedule_on_exec_ctx);
// save some state needed for the interception callback.
GPR_ASSERT(call->recv_trailing_metadata == nullptr);
call->recv_trailing_metadata =
batch->payload->recv_trailing_metadata.recv_trailing_metadata;
call->original_recv_trailing_metadata =
batch->payload->recv_trailing_metadata.recv_trailing_metadata_ready;
batch->payload->recv_trailing_metadata.recv_trailing_metadata_ready =
&call->recv_trailing_metadata_ready;
}
void grpc_subchannel_call_process_op(grpc_subchannel_call* call,
grpc_transport_stream_op_batch* batch) {
GPR_TIMER_SCOPE("grpc_subchannel_call_process_op", 0);
maybe_intercept_recv_trailing_metadata(call, batch);
grpc_call_stack* call_stack = SUBCHANNEL_CALL_TO_CALL_STACK(call);
grpc_call_element* top_elem = grpc_call_stack_element(call_stack, 0);
GRPC_CALL_LOG_OP(GPR_INFO, top_elem, batch);
@ -822,10 +920,12 @@ namespace grpc_core {
ConnectedSubchannel::ConnectedSubchannel(
grpc_channel_stack* channel_stack,
channelz::SubchannelNode* channelz_subchannel, intptr_t socket_uuid)
grpc_core::RefCountedPtr<grpc_core::channelz::SubchannelNode>
channelz_subchannel,
intptr_t socket_uuid)
: RefCountedWithTracing<ConnectedSubchannel>(&grpc_trace_stream_refcount),
channel_stack_(channel_stack),
channelz_subchannel_(channelz_subchannel),
channelz_subchannel_(std::move(channelz_subchannel)),
socket_uuid_(socket_uuid) {}
ConnectedSubchannel::~ConnectedSubchannel() {
@ -872,6 +972,7 @@ grpc_error* ConnectedSubchannel::CreateCall(const CallArgs& args,
Ref(DEBUG_LOCATION, "subchannel_call");
connection.release(); // Ref is passed to the grpc_subchannel_call object.
(*call)->connection = this;
(*call)->deadline = args.deadline;
const grpc_call_element_args call_args = {
callstk, /* call_stack */
nullptr, /* server_transport_data */

@ -85,8 +85,10 @@ class ConnectedSubchannel : public RefCountedWithTracing<ConnectedSubchannel> {
size_t parent_data_size;
};
explicit ConnectedSubchannel(grpc_channel_stack* channel_stack,
channelz::SubchannelNode* channelz_subchannel,
explicit ConnectedSubchannel(
grpc_channel_stack* channel_stack,
grpc_core::RefCountedPtr<grpc_core::channelz::SubchannelNode>
channelz_subchannel,
intptr_t socket_uuid);
~ConnectedSubchannel();
@ -97,15 +99,16 @@ class ConnectedSubchannel : public RefCountedWithTracing<ConnectedSubchannel> {
void Ping(grpc_closure* on_initiate, grpc_closure* on_ack);
grpc_error* CreateCall(const CallArgs& args, grpc_subchannel_call** call);
channelz::SubchannelNode* channelz_subchannel() {
return channelz_subchannel_;
return channelz_subchannel_.get();
}
intptr_t socket_uuid() { return socket_uuid_; }
private:
grpc_channel_stack* channel_stack_;
// backpointer to the channelz node in this connected subchannel's
// ref counted pointer to the channelz node in this connected subchannel's
// owning subchannel.
channelz::SubchannelNode* channelz_subchannel_;
grpc_core::RefCountedPtr<grpc_core::channelz::SubchannelNode>
channelz_subchannel_;
// uuid of this subchannel's socket. 0 if this subchannel is not connected.
const intptr_t socket_uuid_;
};

@ -59,9 +59,8 @@ void authority_start_transport_stream_op_batch(
initial_metadata->idx.named.authority == nullptr) {
grpc_error* error = grpc_metadata_batch_add_head(
initial_metadata, &calld->authority_storage,
grpc_mdelem_from_slices(
GRPC_MDSTR_AUTHORITY,
grpc_slice_ref_internal(chand->default_authority)));
grpc_mdelem_create(GRPC_MDSTR_AUTHORITY, chand->default_authority,
nullptr));
if (error != GRPC_ERROR_NONE) {
grpc_transport_stream_op_batch_finish_with_failure(batch, error,
calld->call_combiner);

@ -160,7 +160,7 @@ static void on_handshake_done(void* arg, grpc_error* error) {
static void start_handshake_locked(chttp2_connector* c) {
c->handshake_mgr = grpc_handshake_manager_create();
grpc_handshakers_add(HANDSHAKER_CLIENT, c->args.channel_args,
c->handshake_mgr);
c->args.interested_parties, c->handshake_mgr);
grpc_endpoint_add_to_pollset_set(c->endpoint, c->args.interested_parties);
grpc_handshake_manager_do_handshake(
c->handshake_mgr, c->args.interested_parties, c->endpoint,

@ -53,6 +53,8 @@ typedef struct {
grpc_closure tcp_server_shutdown_complete;
grpc_closure* server_destroy_listener_done;
grpc_handshake_manager* pending_handshake_mgrs;
grpc_core::RefCountedPtr<grpc_core::channelz::ListenSocketNode>
channelz_listen_socket;
} server_state;
typedef struct {
@ -67,6 +69,7 @@ typedef struct {
grpc_timer timer;
grpc_closure on_timeout;
grpc_closure on_receive_settings;
grpc_pollset_set* interested_parties;
} server_connection_state;
static void server_connection_state_unref(
@ -76,6 +79,9 @@ static void server_connection_state_unref(
GRPC_CHTTP2_UNREF_TRANSPORT(connection_state->transport,
"receive settings timeout");
}
grpc_pollset_set_del_pollset(connection_state->interested_parties,
connection_state->accepting_pollset);
grpc_pollset_set_destroy(connection_state->interested_parties);
gpr_free(connection_state);
}
}
@ -133,7 +139,8 @@ static void on_handshake_done(void* arg, grpc_error* error) {
grpc_create_chttp2_transport(args->args, args->endpoint, false);
grpc_server_setup_transport(
connection_state->svr_state->server, transport,
connection_state->accepting_pollset, args->args);
connection_state->accepting_pollset, args->args,
grpc_chttp2_transport_get_socket_uuid(transport));
// Use notify_on_receive_settings callback to enforce the
// handshake deadline.
connection_state->transport =
@ -189,7 +196,11 @@ static void on_accept(void* arg, grpc_endpoint* tcp,
connection_state->accepting_pollset = accepting_pollset;
connection_state->acceptor = acceptor;
connection_state->handshake_mgr = handshake_mgr;
connection_state->interested_parties = grpc_pollset_set_create();
grpc_pollset_set_add_pollset(connection_state->interested_parties,
connection_state->accepting_pollset);
grpc_handshakers_add(HANDSHAKER_SERVER, state->args,
connection_state->interested_parties,
connection_state->handshake_mgr);
const grpc_arg* timeout_arg =
grpc_channel_args_find(state->args, GRPC_ARG_SERVER_HANDSHAKE_TIMEOUT_MS);
@ -223,6 +234,7 @@ static void tcp_server_shutdown_complete(void* arg, grpc_error* error) {
GPR_ASSERT(state->shutdown);
grpc_handshake_manager_pending_list_shutdown_all(
state->pending_handshake_mgrs, GRPC_ERROR_REF(error));
state->channelz_listen_socket.reset();
gpr_mu_unlock(&state->mu);
// Flush queued work before destroying handshaker factory, since that
// may do a synchronous unref.
@ -262,6 +274,8 @@ grpc_error* grpc_chttp2_server_add_port(grpc_server* server, const char* addr,
server_state* state = nullptr;
grpc_error** errors = nullptr;
size_t naddrs = 0;
const grpc_arg* arg = nullptr;
intptr_t socket_uuid = 0;
*port_num = -1;
@ -323,9 +337,16 @@ grpc_error* grpc_chttp2_server_add_port(grpc_server* server, const char* addr,
}
grpc_resolved_addresses_destroy(resolved);
arg = grpc_channel_args_find(args, GRPC_ARG_ENABLE_CHANNELZ);
if (grpc_channel_arg_get_bool(arg, false)) {
state->channelz_listen_socket =
grpc_core::MakeRefCounted<grpc_core::channelz::ListenSocketNode>();
socket_uuid = state->channelz_listen_socket->uuid();
}
/* Register with the server only upon success */
grpc_server_add_listener(server, state, server_start_listener,
server_destroy_listener);
server_destroy_listener, socket_uuid);
goto done;
/* Error path: cleanup and return */

@ -61,7 +61,7 @@ void grpc_server_add_insecure_channel_from_fd(grpc_server* server,
grpc_endpoint_add_to_pollset(server_endpoint, pollsets[i]);
}
grpc_server_setup_transport(server, transport, nullptr, server_args);
grpc_server_setup_transport(server, transport, nullptr, server_args, 0);
grpc_chttp2_transport_start_reading(transport, nullptr, nullptr);
}

@ -2128,8 +2128,7 @@ void grpc_chttp2_fake_status(grpc_chttp2_transport* t, grpc_chttp2_stream* s,
"add_status_message",
grpc_chttp2_incoming_metadata_buffer_replace_or_add(
&s->metadata_buffer[1],
grpc_mdelem_from_slices(GRPC_MDSTR_GRPC_MESSAGE,
grpc_slice_ref_internal(slice))));
grpc_mdelem_create(GRPC_MDSTR_GRPC_MESSAGE, slice, nullptr)));
}
s->published_metadata[1] = GRPC_METADATA_SYNTHESIZED_FROM_FAKE;
grpc_chttp2_maybe_complete_recv_trailing_metadata(t, s);

@ -1256,7 +1256,9 @@ grpc_channel* grpc_inproc_channel_create(grpc_server* server,
inproc_transports_create(&server_transport, server_args, &client_transport,
client_args);
grpc_server_setup_transport(server, server_transport, nullptr, server_args);
// TODO(ncteisen): design and support channelz GetSocket for inproc.
grpc_server_setup_transport(server, server_transport, nullptr, server_args,
0);
grpc_channel* channel = grpc_channel_create(
"inproc", client_args, GRPC_CLIENT_DIRECT_CHANNEL, client_transport);

@ -37,13 +37,16 @@
#include "src/core/lib/iomgr/exec_ctx.h"
#include "src/core/lib/slice/slice_internal.h"
#include "src/core/lib/surface/channel.h"
#include "src/core/lib/surface/server.h"
#include "src/core/lib/transport/error_utils.h"
namespace grpc_core {
namespace channelz {
BaseNode::BaseNode(EntityType type)
: type_(type), uuid_(ChannelzRegistry::Register(this)) {}
BaseNode::BaseNode(EntityType type) : type_(type), uuid_(-1) {
// The registry will set uuid_ under its lock.
ChannelzRegistry::Register(this);
}
BaseNode::~BaseNode() { ChannelzRegistry::Unregister(uuid_); }
@ -190,11 +193,45 @@ RefCountedPtr<ChannelNode> ChannelNode::MakeChannelNode(
channel, channel_tracer_max_nodes, is_top_level_channel);
}
ServerNode::ServerNode(size_t channel_tracer_max_nodes)
: BaseNode(EntityType::kServer), trace_(channel_tracer_max_nodes) {}
ServerNode::ServerNode(grpc_server* server, size_t channel_tracer_max_nodes)
: BaseNode(EntityType::kServer),
server_(server),
trace_(channel_tracer_max_nodes) {}
ServerNode::~ServerNode() {}
char* ServerNode::RenderServerSockets(intptr_t start_socket_id) {
grpc_json* top_level_json = grpc_json_create(GRPC_JSON_OBJECT);
grpc_json* json = top_level_json;
grpc_json* json_iterator = nullptr;
ChildRefsList socket_refs;
// uuids index into entities one-off (idx 0 is really uuid 1, since 0 is
// reserved). However, we want to support requests coming in with
// start_server_id=0, which signifies "give me everything."
size_t start_idx = start_socket_id == 0 ? 0 : start_socket_id - 1;
grpc_server_populate_server_sockets(server_, &socket_refs, start_idx);
if (!socket_refs.empty()) {
// create list of socket refs
grpc_json* array_parent = grpc_json_create_child(
nullptr, json, "socketRef", nullptr, GRPC_JSON_ARRAY, false);
for (size_t i = 0; i < socket_refs.size(); ++i) {
json_iterator =
grpc_json_create_child(json_iterator, array_parent, nullptr, nullptr,
GRPC_JSON_OBJECT, false);
grpc_json_add_number_string_child(json_iterator, nullptr, "socketId",
socket_refs[i]);
}
}
// For now we do not have any pagination rules. In the future we could
// pick a constant for max_channels_sent for a GetServers request.
// Tracking: https://github.com/grpc/grpc/issues/16019.
json_iterator = grpc_json_create_child(nullptr, json, "end", nullptr,
GRPC_JSON_TRUE, false);
char* json_str = grpc_json_dump_to_string(top_level_json, 0);
grpc_json_destroy(top_level_json);
return json_str;
}
grpc_json* ServerNode::RenderJson() {
// We need to track these three json objects to build our object
grpc_json* top_level_json = grpc_json_create(GRPC_JSON_OBJECT);
@ -223,6 +260,20 @@ grpc_json* ServerNode::RenderJson() {
}
// ask CallCountingHelper to populate trace and call count data.
call_counter_.PopulateCallCounts(json);
json = top_level_json;
ChildRefsList listen_sockets;
grpc_server_populate_listen_sockets(server_, &listen_sockets);
if (!listen_sockets.empty()) {
grpc_json* array_parent = grpc_json_create_child(
nullptr, json, "listenSocket", nullptr, GRPC_JSON_ARRAY, false);
for (size_t i = 0; i < listen_sockets.size(); ++i) {
json_iterator =
grpc_json_create_child(json_iterator, array_parent, nullptr, nullptr,
GRPC_JSON_OBJECT, false);
grpc_json_add_number_string_child(json_iterator, nullptr, "socketId",
listen_sockets[i]);
}
}
return top_level_json;
}
@ -323,5 +374,22 @@ grpc_json* SocketNode::RenderJson() {
return top_level_json;
}
ListenSocketNode::ListenSocketNode() : BaseNode(EntityType::kSocket) {}
grpc_json* ListenSocketNode::RenderJson() {
// We need to track these three json objects to build our object
grpc_json* top_level_json = grpc_json_create(GRPC_JSON_OBJECT);
grpc_json* json = top_level_json;
grpc_json* json_iterator = nullptr;
// create and fill the ref child
json_iterator = grpc_json_create_child(json_iterator, json, "ref", nullptr,
GRPC_JSON_OBJECT, false);
json = json_iterator;
json_iterator = nullptr;
json_iterator = grpc_json_add_number_string_child(json, json_iterator,
"socketId", uuid());
return top_level_json;
}
} // namespace channelz
} // namespace grpc_core

@ -24,6 +24,7 @@
#include <grpc/grpc.h>
#include "src/core/lib/channel/channel_trace.h"
#include "src/core/lib/gprpp/inlined_vector.h"
#include "src/core/lib/gprpp/manual_constructor.h"
#include "src/core/lib/gprpp/ref_counted.h"
#include "src/core/lib/gprpp/ref_counted_ptr.h"
@ -41,17 +42,23 @@
/** This is the default value for whether or not to enable channelz. If
* GRPC_ARG_ENABLE_CHANNELZ is set, it will override this default value. */
#define GRPC_ENABLE_CHANNELZ_DEFAULT false
#define GRPC_ENABLE_CHANNELZ_DEFAULT true
/** This is the default value for the maximum amount of memory used by trace
* events per channel trace node. If
* GRPC_ARG_MAX_CHANNEL_TRACE_EVENT_MEMORY_PER_NODE is set, it will override
* this default value. */
#define GRPC_MAX_CHANNEL_TRACE_EVENT_MEMORY_PER_NODE_DEFAULT 0
#define GRPC_MAX_CHANNEL_TRACE_EVENT_MEMORY_PER_NODE_DEFAULT 1024 * 4
namespace grpc_core {
namespace channelz {
// TODO(ncteisen), this only contains the uuids of the children for now,
// since that is all that is strictly needed. In a future enhancement we will
// add human readable names as in the channelz.proto
typedef InlinedVector<intptr_t, 10> ChildRefsList;
namespace testing {
class CallCountingHelperPeer;
class ChannelNodePeer;
@ -85,8 +92,10 @@ class BaseNode : public RefCounted<BaseNode> {
intptr_t uuid() const { return uuid_; }
private:
// to allow the ChannelzRegistry to set uuid_ under its lock.
friend class ChannelzRegistry;
const EntityType type_;
const intptr_t uuid_;
intptr_t uuid_;
};
// This class is a helper class for channelz entities that deal with Channels,
@ -193,11 +202,13 @@ class ChannelNode : public BaseNode {
// Handles channelz bookkeeping for servers
class ServerNode : public BaseNode {
public:
explicit ServerNode(size_t channel_tracer_max_nodes);
ServerNode(grpc_server* server, size_t channel_tracer_max_nodes);
~ServerNode() override;
grpc_json* RenderJson() override;
char* RenderServerSockets(intptr_t start_socket_id);
// proxy methods to composed classes.
void AddTraceEvent(ChannelTrace::Severity severity, grpc_slice data) {
trace_.AddTraceEvent(severity, data);
@ -213,6 +224,7 @@ class ServerNode : public BaseNode {
void RecordCallSucceeded() { call_counter_.RecordCallSucceeded(); }
private:
grpc_server* server_;
CallCountingHelper call_counter_;
ChannelTrace trace_;
};
@ -253,6 +265,15 @@ class SocketNode : public BaseNode {
UniquePtr<char> peer_string_;
};
// Handles channelz bookkeeping for listen sockets
class ListenSocketNode : public BaseNode {
public:
ListenSocketNode();
~ListenSocketNode() override {}
grpc_json* RenderJson() override;
};
// Creation functions
typedef RefCountedPtr<ChannelNode> (*ChannelNodeCreationFunc)(grpc_channel*,

@ -38,6 +38,8 @@ namespace {
// singleton instance of the registry.
ChannelzRegistry* g_channelz_registry = nullptr;
const int kPaginationLimit = 100;
} // anonymous namespace
void ChannelzRegistry::Init() { g_channelz_registry = New<ChannelzRegistry>(); }
@ -53,29 +55,78 @@ ChannelzRegistry::ChannelzRegistry() { gpr_mu_init(&mu_); }
ChannelzRegistry::~ChannelzRegistry() { gpr_mu_destroy(&mu_); }
intptr_t ChannelzRegistry::InternalRegister(BaseNode* node) {
void ChannelzRegistry::InternalRegister(BaseNode* node) {
MutexLock lock(&mu_);
entities_.push_back(node);
intptr_t uuid = entities_.size();
return uuid;
node->uuid_ = ++uuid_generator_;
}
void ChannelzRegistry::MaybePerformCompactionLocked() {
constexpr double kEmptinessTheshold = 1 / 3;
double emptiness_ratio =
double(num_empty_slots_) / double(entities_.capacity());
if (emptiness_ratio > kEmptinessTheshold) {
int front = 0;
for (size_t i = 0; i < entities_.size(); ++i) {
if (entities_[i] != nullptr) {
entities_[front++] = entities_[i];
}
}
for (int i = 0; i < num_empty_slots_; ++i) {
entities_.pop_back();
}
num_empty_slots_ = 0;
}
}
int ChannelzRegistry::FindByUuidLocked(intptr_t target_uuid) {
size_t left = 0;
size_t right = entities_.size() - 1;
while (left <= right) {
size_t true_middle = left + (right - left) / 2;
size_t first_non_null = true_middle;
while (first_non_null < right && entities_[first_non_null] == nullptr) {
first_non_null++;
}
if (entities_[first_non_null] == nullptr) {
right = true_middle - 1;
continue;
}
intptr_t uuid = entities_[first_non_null]->uuid();
if (uuid == target_uuid) {
return int(first_non_null);
}
if (uuid < target_uuid) {
left = first_non_null + 1;
} else {
right = true_middle - 1;
}
}
return -1;
}
void ChannelzRegistry::InternalUnregister(intptr_t uuid) {
GPR_ASSERT(uuid >= 1);
MutexLock lock(&mu_);
GPR_ASSERT(static_cast<size_t>(uuid) <= entities_.size());
entities_[uuid - 1] = nullptr;
GPR_ASSERT(uuid <= uuid_generator_);
int idx = FindByUuidLocked(uuid);
GPR_ASSERT(idx >= 0);
entities_[idx] = nullptr;
num_empty_slots_++;
MaybePerformCompactionLocked();
}
BaseNode* ChannelzRegistry::InternalGet(intptr_t uuid) {
MutexLock lock(&mu_);
if (uuid < 1 || uuid > static_cast<intptr_t>(entities_.size())) {
if (uuid < 1 || uuid > uuid_generator_) {
return nullptr;
}
return entities_[uuid - 1];
int idx = FindByUuidLocked(uuid);
return idx < 0 ? nullptr : entities_[idx];
}
char* ChannelzRegistry::InternalGetTopChannels(intptr_t start_channel_id) {
MutexLock lock(&mu_);
grpc_json* top_level_json = grpc_json_create(GRPC_JSON_OBJECT);
grpc_json* json = top_level_json;
grpc_json* json_iterator = nullptr;
@ -85,10 +136,18 @@ char* ChannelzRegistry::InternalGetTopChannels(intptr_t start_channel_id) {
// start_channel_id=0, which signifies "give me everything." Hence this
// funky looking line below.
size_t start_idx = start_channel_id == 0 ? 0 : start_channel_id - 1;
bool reached_pagination_limit = false;
for (size_t i = start_idx; i < entities_.size(); ++i) {
if (entities_[i] != nullptr &&
entities_[i]->type() ==
grpc_core::channelz::BaseNode::EntityType::kTopLevelChannel) {
// check if we are over pagination limit to determine if we need to set
// the "end" element. If we don't go through this block, we know that
// when the loop terminates, we have <= to kPaginationLimit.
if (top_level_channels.size() == kPaginationLimit) {
reached_pagination_limit = true;
break;
}
top_level_channels.push_back(entities_[i]);
}
}
@ -102,17 +161,17 @@ char* ChannelzRegistry::InternalGetTopChannels(intptr_t start_channel_id) {
grpc_json_link_child(array_parent, channel_json, json_iterator);
}
}
// For now we do not have any pagination rules. In the future we could
// pick a constant for max_channels_sent for a GetTopChannels request.
// Tracking: https://github.com/grpc/grpc/issues/16019.
json_iterator = grpc_json_create_child(nullptr, json, "end", nullptr,
GRPC_JSON_TRUE, false);
if (!reached_pagination_limit) {
grpc_json_create_child(nullptr, json, "end", nullptr, GRPC_JSON_TRUE,
false);
}
char* json_str = grpc_json_dump_to_string(top_level_json, 0);
grpc_json_destroy(top_level_json);
return json_str;
}
char* ChannelzRegistry::InternalGetServers(intptr_t start_server_id) {
MutexLock lock(&mu_);
grpc_json* top_level_json = grpc_json_create(GRPC_JSON_OBJECT);
grpc_json* json = top_level_json;
grpc_json* json_iterator = nullptr;
@ -121,10 +180,18 @@ char* ChannelzRegistry::InternalGetServers(intptr_t start_server_id) {
// reserved). However, we want to support requests coming in with
// start_server_id=0, which signifies "give me everything."
size_t start_idx = start_server_id == 0 ? 0 : start_server_id - 1;
bool reached_pagination_limit = false;
for (size_t i = start_idx; i < entities_.size(); ++i) {
if (entities_[i] != nullptr &&
entities_[i]->type() ==
grpc_core::channelz::BaseNode::EntityType::kServer) {
// check if we are over pagination limit to determine if we need to set
// the "end" element. If we don't go through this block, we know that
// when the loop terminates, we have <= to kPaginationLimit.
if (servers.size() == kPaginationLimit) {
reached_pagination_limit = true;
break;
}
servers.push_back(entities_[i]);
}
}
@ -138,11 +205,10 @@ char* ChannelzRegistry::InternalGetServers(intptr_t start_server_id) {
grpc_json_link_child(array_parent, server_json, json_iterator);
}
}
// For now we do not have any pagination rules. In the future we could
// pick a constant for max_channels_sent for a GetServers request.
// Tracking: https://github.com/grpc/grpc/issues/16019.
json_iterator = grpc_json_create_child(nullptr, json, "end", nullptr,
GRPC_JSON_TRUE, false);
if (!reached_pagination_limit) {
grpc_json_create_child(nullptr, json, "end", nullptr, GRPC_JSON_TRUE,
false);
}
char* json_str = grpc_json_dump_to_string(top_level_json, 0);
grpc_json_destroy(top_level_json);
return json_str;
@ -160,6 +226,21 @@ char* grpc_channelz_get_servers(intptr_t start_server_id) {
return grpc_core::channelz::ChannelzRegistry::GetServers(start_server_id);
}
char* grpc_channelz_get_server_sockets(intptr_t server_id,
intptr_t start_socket_id) {
grpc_core::channelz::BaseNode* base_node =
grpc_core::channelz::ChannelzRegistry::Get(server_id);
if (base_node == nullptr ||
base_node->type() != grpc_core::channelz::BaseNode::EntityType::kServer) {
return nullptr;
}
// This cast is ok since we have just checked to make sure base_node is
// actually a server node
grpc_core::channelz::ServerNode* server_node =
static_cast<grpc_core::channelz::ServerNode*>(base_node);
return server_node->RenderServerSockets(start_socket_id);
}
char* grpc_channelz_get_channel(intptr_t channel_id) {
grpc_core::channelz::BaseNode* channel_node =
grpc_core::channelz::ChannelzRegistry::Get(channel_id);

@ -30,6 +30,10 @@
namespace grpc_core {
namespace channelz {
namespace testing {
class ChannelzRegistryPeer;
}
// singleton registry object to track all objects that are needed to support
// channelz bookkeeping. All objects share globally distributed uuids.
class ChannelzRegistry {
@ -40,7 +44,7 @@ class ChannelzRegistry {
// To be called in grpc_shutdown();
static void Shutdown();
static intptr_t Register(BaseNode* node) {
static void Register(BaseNode* node) {
return Default()->InternalRegister(node);
}
static void Unregister(intptr_t uuid) { Default()->InternalUnregister(uuid); }
@ -61,6 +65,7 @@ class ChannelzRegistry {
private:
GPRC_ALLOW_CLASS_TO_USE_NON_PUBLIC_NEW
GPRC_ALLOW_CLASS_TO_USE_NON_PUBLIC_DELETE
friend class testing::ChannelzRegistryPeer;
ChannelzRegistry();
~ChannelzRegistry();
@ -69,7 +74,7 @@ class ChannelzRegistry {
static ChannelzRegistry* Default();
// globally registers an Entry. Returns its unique uuid
intptr_t InternalRegister(BaseNode* node);
void InternalRegister(BaseNode* node);
// globally unregisters the object that is associated to uuid. Also does
// sanity check that an object doesn't try to unregister the wrong type.
@ -82,9 +87,18 @@ class ChannelzRegistry {
char* InternalGetTopChannels(intptr_t start_channel_id);
char* InternalGetServers(intptr_t start_server_id);
// protects entities_ and uuid_
// If entities_ has over a certain threshold of empty slots, it will
// compact the vector and move all used slots to the front.
void MaybePerformCompactionLocked();
// Performs binary search on entities_ to find the index with that uuid.
int FindByUuidLocked(intptr_t uuid);
// protects members
gpr_mu mu_;
InlinedVector<BaseNode*, 20> entities_;
intptr_t uuid_generator_ = 0;
int num_empty_slots_ = 0;
};
} // namespace channelz

@ -24,11 +24,12 @@
void grpc_handshaker_factory_add_handshakers(
grpc_handshaker_factory* handshaker_factory, const grpc_channel_args* args,
grpc_pollset_set* interested_parties,
grpc_handshake_manager* handshake_mgr) {
if (handshaker_factory != nullptr) {
GPR_ASSERT(handshaker_factory->vtable != nullptr);
handshaker_factory->vtable->add_handshakers(handshaker_factory, args,
handshake_mgr);
handshaker_factory->vtable->add_handshakers(
handshaker_factory, args, interested_parties, handshake_mgr);
}
}

@ -32,6 +32,7 @@ typedef struct grpc_handshaker_factory grpc_handshaker_factory;
typedef struct {
void (*add_handshakers)(grpc_handshaker_factory* handshaker_factory,
const grpc_channel_args* args,
grpc_pollset_set* interested_parties,
grpc_handshake_manager* handshake_mgr);
void (*destroy)(grpc_handshaker_factory* handshaker_factory);
} grpc_handshaker_factory_vtable;
@ -42,6 +43,7 @@ struct grpc_handshaker_factory {
void grpc_handshaker_factory_add_handshakers(
grpc_handshaker_factory* handshaker_factory, const grpc_channel_args* args,
grpc_pollset_set* interested_parties,
grpc_handshake_manager* handshake_mgr);
void grpc_handshaker_factory_destroy(

@ -51,9 +51,11 @@ static void grpc_handshaker_factory_list_register(
static void grpc_handshaker_factory_list_add_handshakers(
grpc_handshaker_factory_list* list, const grpc_channel_args* args,
grpc_pollset_set* interested_parties,
grpc_handshake_manager* handshake_mgr) {
for (size_t i = 0; i < list->num_factories; ++i) {
grpc_handshaker_factory_add_handshakers(list->list[i], args, handshake_mgr);
grpc_handshaker_factory_add_handshakers(list->list[i], args,
interested_parties, handshake_mgr);
}
}
@ -91,7 +93,9 @@ void grpc_handshaker_factory_register(bool at_start,
void grpc_handshakers_add(grpc_handshaker_type handshaker_type,
const grpc_channel_args* args,
grpc_pollset_set* interested_parties,
grpc_handshake_manager* handshake_mgr) {
grpc_handshaker_factory_list_add_handshakers(
&g_handshaker_factory_lists[handshaker_type], args, handshake_mgr);
&g_handshaker_factory_lists[handshaker_type], args, interested_parties,
handshake_mgr);
}

@ -43,6 +43,7 @@ void grpc_handshaker_factory_register(bool at_start,
void grpc_handshakers_add(grpc_handshaker_type handshaker_type,
const grpc_channel_args* args,
grpc_pollset_set* interested_parties,
grpc_handshake_manager* handshake_mgr);
#endif /* GRPC_CORE_LIB_CHANNEL_HANDSHAKER_REGISTRY_H */

@ -123,6 +123,14 @@ class InlinedVector {
void push_back(T&& value) { emplace_back(std::move(value)); }
void pop_back() {
assert(!empty());
size_t s = size();
T& value = data()[s - 1];
value.~T();
size_--;
}
void copy_from(const InlinedVector& v) {
// if v is allocated, copy over the buffer.
if (v.dynamic_ != nullptr) {

@ -29,6 +29,7 @@
#include "src/core/lib/channel/channel_args.h"
#include "src/core/lib/channel/handshaker_registry.h"
#include "src/core/lib/gpr/string.h"
#include "src/core/lib/iomgr/pollset.h"
#include "src/core/lib/security/transport/security_handshaker.h"
#include "src/core/lib/slice/slice_internal.h"
#include "src/core/tsi/ssl_transport_security.h"
@ -51,6 +52,7 @@ static void httpcli_ssl_destroy(grpc_security_connector* sc) {
}
static void httpcli_ssl_add_handshakers(grpc_channel_security_connector* sc,
grpc_pollset_set* interested_parties,
grpc_handshake_manager* handshake_mgr) {
grpc_httpcli_ssl_channel_security_connector* c =
reinterpret_cast<grpc_httpcli_ssl_channel_security_connector*>(sc);
@ -189,7 +191,8 @@ static void ssl_handshake(void* arg, grpc_endpoint* tcp, const char* host,
grpc_arg channel_arg = grpc_security_connector_to_arg(&sc->base);
grpc_channel_args args = {1, &channel_arg};
c->handshake_mgr = grpc_handshake_manager_create();
grpc_handshakers_add(HANDSHAKER_CLIENT, &args, c->handshake_mgr);
grpc_handshakers_add(HANDSHAKER_CLIENT, &args,
nullptr /* interested_parties */, c->handshake_mgr);
grpc_handshake_manager_do_handshake(
c->handshake_mgr, nullptr /* interested_parties */, tcp,
nullptr /* channel_args */, deadline, nullptr /* acceptor */,

@ -395,6 +395,4 @@ void grpc_pollset_set_del_fd(grpc_pollset_set* pollset_set, grpc_fd* fd) {
g_event_engine->pollset_set_del_fd(pollset_set, fd);
}
void grpc_use_signal(int signum) {}
#endif // GRPC_POSIX_SOCKET_EV

@ -307,7 +307,10 @@ grpc_error* grpc_set_socket_tcp_user_timeout(
}
}
#else
extern grpc_core::TraceFlag grpc_tcp_trace;
if (grpc_tcp_trace.enabled()) {
gpr_log(GPR_INFO, "TCP_USER_TIMEOUT not supported for this platform");
}
#endif /* GRPC_HAVE_TCP_USER_TIMEOUT */
return GRPC_ERROR_NONE;
}

@ -468,7 +468,9 @@ static void tcp_do_read(grpc_tcp* tcp) {
GRPC_STATS_INC_TCP_READ_SIZE(read_bytes);
add_to_estimate(tcp, static_cast<size_t>(read_bytes));
GPR_ASSERT((size_t)read_bytes <= tcp->incoming_buffer->length);
if (static_cast<size_t>(read_bytes) < tcp->incoming_buffer->length) {
if (static_cast<size_t>(read_bytes) == tcp->incoming_buffer->length) {
finish_estimate(tcp);
} else if (static_cast<size_t>(read_bytes) < tcp->incoming_buffer->length) {
grpc_slice_buffer_trim_end(
tcp->incoming_buffer,
tcp->incoming_buffer->length - static_cast<size_t>(read_bytes),
@ -498,7 +500,7 @@ static void tcp_read_allocation_done(void* tcpp, grpc_error* error) {
static void tcp_continue_read(grpc_tcp* tcp) {
size_t target_read_size = get_target_read_size(tcp);
if (tcp->incoming_buffer->length < target_read_size &&
if (tcp->incoming_buffer->length < target_read_size / 2 &&
tcp->incoming_buffer->count < MAX_READ_IOVEC) {
if (grpc_tcp_trace.enabled()) {
gpr_log(GPR_INFO, "TCP:%p alloc_slices", tcp);

@ -245,7 +245,7 @@ static void timer_main_loop() {
gpr_log(GPR_INFO, "timers not checked: expect another thread to");
}
next = GRPC_MILLIS_INF_FUTURE;
/* fall through */
// fallthrough
case GRPC_TIMERS_CHECKED_AND_EMPTY:
if (!wait_until(next)) {
return;

@ -32,12 +32,11 @@
#include "src/core/lib/profiling/timers.h"
static grpc_error* eventfd_create(grpc_wakeup_fd* fd_info) {
int efd = eventfd(0, EFD_NONBLOCK | EFD_CLOEXEC);
if (efd < 0) {
fd_info->read_fd = eventfd(0, EFD_NONBLOCK | EFD_CLOEXEC);
fd_info->write_fd = -1;
if (fd_info->read_fd < 0) {
return GRPC_OS_ERROR(errno, "eventfd");
}
fd_info->read_fd = efd;
fd_info->write_fd = -1;
return GRPC_ERROR_NONE;
}

@ -102,8 +102,7 @@ static grpc_error* process_plugin_result(
} else {
for (size_t i = 0; i < num_md; ++i) {
grpc_mdelem mdelem =
grpc_mdelem_from_slices(grpc_slice_ref_internal(md[i].key),
grpc_slice_ref_internal(md[i].value));
grpc_mdelem_create(md[i].key, md[i].value, nullptr);
grpc_credentials_mdelem_array_add(r->md_array, mdelem);
GRPC_MDELEM_UNREF(mdelem);
}

@ -64,29 +64,29 @@ static void alts_server_destroy(grpc_security_connector* sc) {
}
static void alts_channel_add_handshakers(
grpc_channel_security_connector* sc,
grpc_channel_security_connector* sc, grpc_pollset_set* interested_parties,
grpc_handshake_manager* handshake_manager) {
tsi_handshaker* handshaker = nullptr;
auto c = reinterpret_cast<grpc_alts_channel_security_connector*>(sc);
grpc_alts_credentials* creds =
reinterpret_cast<grpc_alts_credentials*>(c->base.channel_creds);
GPR_ASSERT(alts_tsi_handshaker_create(creds->options, c->target_name,
creds->handshaker_service_url, true,
&handshaker) == TSI_OK);
GPR_ASSERT(alts_tsi_handshaker_create(
creds->options, c->target_name, creds->handshaker_service_url,
true, interested_parties, &handshaker) == TSI_OK);
grpc_handshake_manager_add(handshake_manager, grpc_security_handshaker_create(
handshaker, &sc->base));
}
static void alts_server_add_handshakers(
grpc_server_security_connector* sc,
grpc_server_security_connector* sc, grpc_pollset_set* interested_parties,
grpc_handshake_manager* handshake_manager) {
tsi_handshaker* handshaker = nullptr;
auto c = reinterpret_cast<grpc_alts_server_security_connector*>(sc);
grpc_alts_server_credentials* creds =
reinterpret_cast<grpc_alts_server_credentials*>(c->base.server_creds);
GPR_ASSERT(alts_tsi_handshaker_create(creds->options, nullptr,
creds->handshaker_service_url, false,
&handshaker) == TSI_OK);
GPR_ASSERT(alts_tsi_handshaker_create(
creds->options, nullptr, creds->handshaker_service_url, false,
interested_parties, &handshaker) == TSI_OK);
grpc_handshake_manager_add(handshake_manager, grpc_security_handshaker_create(
handshaker, &sc->base));
}

@ -30,6 +30,7 @@
#include "src/core/ext/filters/client_channel/client_channel.h"
#include "src/core/lib/channel/channel_args.h"
#include "src/core/lib/iomgr/pollset.h"
#include "src/core/lib/security/credentials/local/local_credentials.h"
#include "src/core/lib/security/transport/security_handshaker.h"
#include "src/core/tsi/local_transport_security.h"
@ -68,7 +69,7 @@ static void local_server_destroy(grpc_security_connector* sc) {
}
static void local_channel_add_handshakers(
grpc_channel_security_connector* sc,
grpc_channel_security_connector* sc, grpc_pollset_set* interested_parties,
grpc_handshake_manager* handshake_manager) {
tsi_handshaker* handshaker = nullptr;
GPR_ASSERT(local_tsi_handshaker_create(true /* is_client */, &handshaker) ==
@ -78,7 +79,7 @@ static void local_channel_add_handshakers(
}
static void local_server_add_handshakers(
grpc_server_security_connector* sc,
grpc_server_security_connector* sc, grpc_pollset_set* interested_parties,
grpc_handshake_manager* handshake_manager) {
tsi_handshaker* handshaker = nullptr;
GPR_ASSERT(local_tsi_handshaker_create(false /* is_client */, &handshaker) ==

@ -120,17 +120,19 @@ const tsi_peer_property* tsi_peer_get_property_by_name(const tsi_peer* peer,
void grpc_channel_security_connector_add_handshakers(
grpc_channel_security_connector* connector,
grpc_pollset_set* interested_parties,
grpc_handshake_manager* handshake_mgr) {
if (connector != nullptr) {
connector->add_handshakers(connector, handshake_mgr);
connector->add_handshakers(connector, interested_parties, handshake_mgr);
}
}
void grpc_server_security_connector_add_handshakers(
grpc_server_security_connector* connector,
grpc_pollset_set* interested_parties,
grpc_handshake_manager* handshake_mgr) {
if (connector != nullptr) {
connector->add_handshakers(connector, handshake_mgr);
connector->add_handshakers(connector, interested_parties, handshake_mgr);
}
}
@ -519,7 +521,7 @@ static void fake_channel_cancel_check_call_host(
}
static void fake_channel_add_handshakers(
grpc_channel_security_connector* sc,
grpc_channel_security_connector* sc, grpc_pollset_set* interested_parties,
grpc_handshake_manager* handshake_mgr) {
grpc_handshake_manager_add(
handshake_mgr,
@ -528,6 +530,7 @@ static void fake_channel_add_handshakers(
}
static void fake_server_add_handshakers(grpc_server_security_connector* sc,
grpc_pollset_set* interested_parties,
grpc_handshake_manager* handshake_mgr) {
grpc_handshake_manager_add(
handshake_mgr,
@ -669,6 +672,7 @@ static void ssl_server_destroy(grpc_security_connector* sc) {
}
static void ssl_channel_add_handshakers(grpc_channel_security_connector* sc,
grpc_pollset_set* interested_parties,
grpc_handshake_manager* handshake_mgr) {
grpc_ssl_channel_security_connector* c =
reinterpret_cast<grpc_ssl_channel_security_connector*>(sc);
@ -779,6 +783,7 @@ static bool try_fetch_ssl_server_credentials(
}
static void ssl_server_add_handshakers(grpc_server_security_connector* sc,
grpc_pollset_set* interested_parties,
grpc_handshake_manager* handshake_mgr) {
grpc_ssl_server_security_connector* c =
reinterpret_cast<grpc_ssl_server_security_connector*>(sc);

@ -27,6 +27,7 @@
#include "src/core/lib/channel/handshaker.h"
#include "src/core/lib/iomgr/endpoint.h"
#include "src/core/lib/iomgr/pollset.h"
#include "src/core/lib/iomgr/tcp_server.h"
#include "src/core/tsi/ssl_transport_security.h"
#include "src/core/tsi/transport_security_interface.h"
@ -125,6 +126,7 @@ struct grpc_channel_security_connector {
grpc_closure* on_call_host_checked,
grpc_error* error);
void (*add_handshakers)(grpc_channel_security_connector* sc,
grpc_pollset_set* interested_parties,
grpc_handshake_manager* handshake_mgr);
};
@ -151,6 +153,7 @@ void grpc_channel_security_connector_cancel_check_call_host(
/* Registers handshakers with \a handshake_mgr. */
void grpc_channel_security_connector_add_handshakers(
grpc_channel_security_connector* connector,
grpc_pollset_set* interested_parties,
grpc_handshake_manager* handshake_mgr);
/* --- server_security_connector object. ---
@ -164,6 +167,7 @@ struct grpc_server_security_connector {
grpc_security_connector base;
grpc_server_credentials* server_creds;
void (*add_handshakers)(grpc_server_security_connector* sc,
grpc_pollset_set* interested_parties,
grpc_handshake_manager* handshake_mgr);
};
@ -172,7 +176,8 @@ int grpc_server_security_connector_cmp(grpc_server_security_connector* sc1,
grpc_server_security_connector* sc2);
void grpc_server_security_connector_add_handshakers(
grpc_server_security_connector* sc, grpc_handshake_manager* handshake_mgr);
grpc_server_security_connector* sc, grpc_pollset_set* interested_parties,
grpc_handshake_manager* handshake_mgr);
/* --- Creation security connectors. --- */

@ -475,22 +475,24 @@ static grpc_handshaker* fail_handshaker_create() {
static void client_handshaker_factory_add_handshakers(
grpc_handshaker_factory* handshaker_factory, const grpc_channel_args* args,
grpc_pollset_set* interested_parties,
grpc_handshake_manager* handshake_mgr) {
grpc_channel_security_connector* security_connector =
reinterpret_cast<grpc_channel_security_connector*>(
grpc_security_connector_find_in_args(args));
grpc_channel_security_connector_add_handshakers(security_connector,
handshake_mgr);
grpc_channel_security_connector_add_handshakers(
security_connector, interested_parties, handshake_mgr);
}
static void server_handshaker_factory_add_handshakers(
grpc_handshaker_factory* hf, const grpc_channel_args* args,
grpc_pollset_set* interested_parties,
grpc_handshake_manager* handshake_mgr) {
grpc_server_security_connector* security_connector =
reinterpret_cast<grpc_server_security_connector*>(
grpc_security_connector_find_in_args(args));
grpc_server_security_connector_add_handshakers(security_connector,
handshake_mgr);
grpc_server_security_connector_add_handshakers(
security_connector, interested_parties, handshake_mgr);
}
static void handshaker_factory_destroy(

@ -336,9 +336,8 @@ grpc_call* grpc_channel_create_call(grpc_channel* channel,
grpc_core::ExecCtx exec_ctx;
grpc_call* call = grpc_channel_create_call_internal(
channel, parent_call, propagation_mask, cq, nullptr,
grpc_mdelem_from_slices(GRPC_MDSTR_PATH, grpc_slice_ref_internal(method)),
host != nullptr ? grpc_mdelem_from_slices(GRPC_MDSTR_AUTHORITY,
grpc_slice_ref_internal(*host))
grpc_mdelem_create(GRPC_MDSTR_PATH, method, nullptr),
host != nullptr ? grpc_mdelem_create(GRPC_MDSTR_AUTHORITY, *host, nullptr)
: GRPC_MDNULL,
grpc_timespec_to_millis_round_up(deadline));
@ -347,14 +346,13 @@ grpc_call* grpc_channel_create_call(grpc_channel* channel,
grpc_call* grpc_channel_create_pollset_set_call(
grpc_channel* channel, grpc_call* parent_call, uint32_t propagation_mask,
grpc_pollset_set* pollset_set, grpc_slice method, const grpc_slice* host,
grpc_millis deadline, void* reserved) {
grpc_pollset_set* pollset_set, const grpc_slice& method,
const grpc_slice* host, grpc_millis deadline, void* reserved) {
GPR_ASSERT(!reserved);
return grpc_channel_create_call_internal(
channel, parent_call, propagation_mask, nullptr, pollset_set,
grpc_mdelem_from_slices(GRPC_MDSTR_PATH, grpc_slice_ref_internal(method)),
host != nullptr ? grpc_mdelem_from_slices(GRPC_MDSTR_AUTHORITY,
grpc_slice_ref_internal(*host))
grpc_mdelem_create(GRPC_MDSTR_PATH, method, nullptr),
host != nullptr ? grpc_mdelem_create(GRPC_MDSTR_AUTHORITY, *host, nullptr)
: GRPC_MDNULL,
deadline);
}

@ -45,8 +45,8 @@ grpc_channel* grpc_channel_create_with_builder(
value of \a propagation_mask (see propagation_bits.h for possible values) */
grpc_call* grpc_channel_create_pollset_set_call(
grpc_channel* channel, grpc_call* parent_call, uint32_t propagation_mask,
grpc_pollset_set* pollset_set, grpc_slice method, const grpc_slice* host,
grpc_millis deadline, void* reserved);
grpc_pollset_set* pollset_set, const grpc_slice& method,
const grpc_slice* host, grpc_millis deadline, void* reserved);
/** Get a (borrowed) pointer to this channels underlying channel stack */
grpc_channel_stack* grpc_channel_get_channel_stack(grpc_channel* channel);

@ -79,6 +79,7 @@ typedef struct non_polling_worker {
typedef struct {
gpr_mu mu;
bool kicked_without_poller;
non_polling_worker* root;
grpc_closure* shutdown;
} non_polling_poller;
@ -103,6 +104,10 @@ static grpc_error* non_polling_poller_work(grpc_pollset* pollset,
grpc_millis deadline) {
non_polling_poller* npp = reinterpret_cast<non_polling_poller*>(pollset);
if (npp->shutdown) return GRPC_ERROR_NONE;
if (npp->kicked_without_poller) {
npp->kicked_without_poller = false;
return GRPC_ERROR_NONE;
}
non_polling_worker w;
gpr_cv_init(&w.cv);
if (worker != nullptr) *worker = reinterpret_cast<grpc_pollset_worker*>(&w);
@ -148,6 +153,8 @@ static grpc_error* non_polling_poller_kick(
w->kicked = true;
gpr_cv_signal(&w->cv);
}
} else {
p->kicked_without_poller = true;
}
return GRPC_ERROR_NONE;
}

@ -54,6 +54,7 @@ struct listener {
size_t pollset_count);
void (*destroy)(grpc_server* server, void* arg, grpc_closure* closure);
struct listener* next;
intptr_t socket_uuid;
grpc_closure destroy_done;
};
@ -104,6 +105,7 @@ struct channel_data {
uint32_t registered_method_max_probes;
grpc_closure finish_destroy_channel_closure;
grpc_closure channel_connectivity_changed;
intptr_t socket_uuid;
};
typedef struct shutdown_tag {
@ -1016,7 +1018,7 @@ grpc_server* grpc_server_create(const grpc_channel_args* args, void* reserved) {
{GRPC_MAX_CHANNEL_TRACE_EVENT_MEMORY_PER_NODE_DEFAULT, 0, INT_MAX});
server->channelz_server =
grpc_core::MakeRefCounted<grpc_core::channelz::ServerNode>(
channel_tracer_max_memory);
server, channel_tracer_max_memory);
server->channelz_server->AddTraceEvent(
grpc_core::channelz::ChannelTrace::Severity::Info,
grpc_slice_from_static_string("Server created"));
@ -1119,7 +1121,8 @@ void grpc_server_get_pollsets(grpc_server* server, grpc_pollset*** pollsets,
void grpc_server_setup_transport(grpc_server* s, grpc_transport* transport,
grpc_pollset* accepting_pollset,
const grpc_channel_args* args) {
const grpc_channel_args* args,
intptr_t socket_uuid) {
size_t num_registered_methods;
size_t alloc;
registered_method* rm;
@ -1139,6 +1142,7 @@ void grpc_server_setup_transport(grpc_server* s, grpc_transport* transport,
chand->server = s;
server_ref(s);
chand->channel = channel;
chand->socket_uuid = socket_uuid;
size_t cq_idx;
for (cq_idx = 0; cq_idx < s->cq_count; cq_idx++) {
@ -1213,6 +1217,29 @@ void grpc_server_setup_transport(grpc_server* s, grpc_transport* transport,
grpc_transport_perform_op(transport, op);
}
void grpc_server_populate_server_sockets(
grpc_server* s, grpc_core::channelz::ChildRefsList* server_sockets,
intptr_t start_idx) {
gpr_mu_lock(&s->mu_global);
channel_data* c = nullptr;
for (c = s->root_channel_data.next; c != &s->root_channel_data; c = c->next) {
intptr_t socket_uuid = c->socket_uuid;
if (socket_uuid >= start_idx) {
server_sockets->push_back(socket_uuid);
}
}
gpr_mu_unlock(&s->mu_global);
}
void grpc_server_populate_listen_sockets(
grpc_server* server, grpc_core::channelz::ChildRefsList* listen_sockets) {
gpr_mu_lock(&server->mu_global);
for (listener* l = server->listeners; l != nullptr; l = l->next) {
listen_sockets->push_back(l->socket_uuid);
}
gpr_mu_unlock(&server->mu_global);
}
void done_published_shutdown(void* done_arg, grpc_cq_completion* storage) {
(void)done_arg;
gpr_free(storage);
@ -1346,11 +1373,13 @@ void grpc_server_add_listener(grpc_server* server, void* arg,
grpc_pollset** pollsets,
size_t pollset_count),
void (*destroy)(grpc_server* server, void* arg,
grpc_closure* on_done)) {
grpc_closure* on_done),
intptr_t socket_uuid) {
listener* l = static_cast<listener*>(gpr_malloc(sizeof(listener)));
l->arg = arg;
l->start = start;
l->destroy = destroy;
l->socket_uuid = socket_uuid;
l->next = server->listeners;
server->listeners = l;
}

@ -39,13 +39,24 @@ void grpc_server_add_listener(grpc_server* server, void* listener,
grpc_pollset** pollsets,
size_t npollsets),
void (*destroy)(grpc_server* server, void* arg,
grpc_closure* on_done));
grpc_closure* on_done),
intptr_t socket_uuid);
/* Setup a transport - creates a channel stack, binds the transport to the
server */
void grpc_server_setup_transport(grpc_server* server, grpc_transport* transport,
grpc_pollset* accepting_pollset,
const grpc_channel_args* args);
const grpc_channel_args* args,
intptr_t socket_uuid);
/* fills in the uuids of all sockets used for connections on this server */
void grpc_server_populate_server_sockets(
grpc_server* server, grpc_core::channelz::ChildRefsList* server_sockets,
intptr_t start_idx);
/* fills in the uuids of all listen sockets on this server */
void grpc_server_populate_listen_sockets(
grpc_server* server, grpc_core::channelz::ChildRefsList* listen_sockets);
grpc_core::channelz::ServerNode* grpc_server_get_channelz_node(
grpc_server* server);

@ -23,6 +23,6 @@
#include <grpc/grpc.h>
const char* grpc_version_string(void) { return "6.0.0-dev"; }
const char* grpc_version_string(void) { return "7.0.0-dev"; }
const char* grpc_g_stands_for(void) { return "gao"; }
const char* grpc_g_stands_for(void) { return "gizmo"; }

@ -237,7 +237,7 @@ static void rehash_mdtab(mdtab_shard* shard) {
}
grpc_mdelem grpc_mdelem_create(
grpc_slice key, grpc_slice value,
const grpc_slice& key, const grpc_slice& value,
grpc_mdelem_data* compatible_external_backing_store) {
if (!grpc_slice_is_interned(key) || !grpc_slice_is_interned(value)) {
if (compatible_external_backing_store != nullptr) {
@ -324,7 +324,8 @@ grpc_mdelem grpc_mdelem_create(
return GRPC_MAKE_MDELEM(md, GRPC_MDELEM_STORAGE_INTERNED);
}
grpc_mdelem grpc_mdelem_from_slices(grpc_slice key, grpc_slice value) {
grpc_mdelem grpc_mdelem_from_slices(const grpc_slice& key,
const grpc_slice& value) {
grpc_mdelem out = grpc_mdelem_create(key, value, nullptr);
grpc_slice_unref_internal(key);
grpc_slice_unref_internal(value);

@ -109,7 +109,8 @@ struct grpc_mdelem {
(uintptr_t)GRPC_MDELEM_STORAGE_INTERNED_BIT))
/* Unrefs the slices. */
grpc_mdelem grpc_mdelem_from_slices(grpc_slice key, grpc_slice value);
grpc_mdelem grpc_mdelem_from_slices(const grpc_slice& key,
const grpc_slice& value);
/* Cheaply convert a grpc_metadata to a grpc_mdelem; may use the grpc_metadata
object as backing storage (so lifetimes should align) */
@ -120,7 +121,7 @@ grpc_mdelem grpc_mdelem_from_grpc_metadata(grpc_metadata* metadata);
compatible_external_backing_store if it is non-NULL (in which case it's the
users responsibility to ensure that it outlives usage) */
grpc_mdelem grpc_mdelem_create(
grpc_slice key, grpc_slice value,
const grpc_slice& key, const grpc_slice& value,
grpc_mdelem_data* compatible_external_backing_store);
bool grpc_mdelem_eq(grpc_mdelem a, grpc_mdelem b);

@ -139,6 +139,7 @@ static void link_head(grpc_mdelem_list* list, grpc_linked_mdelem* storage) {
GPR_ASSERT(!GRPC_MDISNULL(storage->md));
storage->prev = nullptr;
storage->next = list->head;
storage->reserved = nullptr;
if (list->head != nullptr) {
list->head->prev = storage;
} else {

@ -347,7 +347,8 @@ static void init_shared_resources(const char* handshaker_service_url) {
tsi_result alts_tsi_handshaker_create(
const grpc_alts_credentials_options* options, const char* target_name,
const char* handshaker_service_url, bool is_client, tsi_handshaker** self) {
const char* handshaker_service_url, bool is_client,
grpc_pollset_set* interested_parties, tsi_handshaker** self) {
if (handshaker_service_url == nullptr || self == nullptr ||
options == nullptr || (is_client && target_name == nullptr)) {
gpr_log(GPR_ERROR, "Invalid arguments to alts_tsi_handshaker_create()");

@ -23,6 +23,7 @@
#include <grpc/grpc.h>
#include "src/core/lib/iomgr/pollset_set.h"
#include "src/core/lib/security/credentials/alts/grpc_alts_credentials_options.h"
#include "src/core/tsi/alts_transport_security.h"
#include "src/core/tsi/transport_security.h"
@ -51,6 +52,7 @@ typedef struct alts_tsi_handshaker alts_tsi_handshaker;
* "host:port".
* - is_client: boolean value indicating if the handshaker is used at the client
* (is_client = true) or server (is_client = false) side.
* - interested_parties: set of pollsets interested in this connection.
* - self: address of ALTS TSI handshaker instance to be returned from the
* method.
*
@ -58,7 +60,8 @@ typedef struct alts_tsi_handshaker alts_tsi_handshaker;
*/
tsi_result alts_tsi_handshaker_create(
const grpc_alts_credentials_options* options, const char* target_name,
const char* handshaker_service_url, bool is_client, tsi_handshaker** self);
const char* handshaker_service_url, bool is_client,
grpc_pollset_set* interested_parties, tsi_handshaker** self);
/**
* This method handles handshaker response returned from ALTS handshaker

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

@ -60,6 +60,23 @@ Status ChannelzService::GetServers(
return Status::OK;
}
Status ChannelzService::GetServerSockets(
ServerContext* unused, const channelz::v1::GetServerSocketsRequest* request,
channelz::v1::GetServerSocketsResponse* response) {
char* json_str = grpc_channelz_get_server_sockets(request->server_id(),
request->start_socket_id());
if (json_str == nullptr) {
return Status(INTERNAL, "grpc_channelz_get_server_sockets returned null");
}
google::protobuf::util::Status s =
google::protobuf::util::JsonStringToMessage(json_str, response);
gpr_free(json_str);
if (s != google::protobuf::util::Status::OK) {
return Status(INTERNAL, s.ToString());
}
return Status::OK;
}
Status ChannelzService::GetChannel(
ServerContext* unused, const channelz::v1::GetChannelRequest* request,
channelz::v1::GetChannelResponse* response) {
@ -96,7 +113,6 @@ Status ChannelzService::GetSocket(ServerContext* unused,
const channelz::v1::GetSocketRequest* request,
channelz::v1::GetSocketResponse* response) {
char* json_str = grpc_channelz_get_socket(request->socket_id());
gpr_log(GPR_ERROR, "%s", json_str);
if (json_str == nullptr) {
return Status(NOT_FOUND, "No object found for that SocketId");
}

@ -36,6 +36,11 @@ class ChannelzService final : public channelz::v1::Channelz::Service {
Status GetServers(ServerContext* unused,
const channelz::v1::GetServersRequest* request,
channelz::v1::GetServersResponse* response) override;
// implementation of GetServerSockets rpc
Status GetServerSockets(
ServerContext* unused,
const channelz::v1::GetServerSocketsRequest* request,
channelz::v1::GetServerSocketsResponse* response) override;
// implementation of GetChannel rpc
Status GetChannel(ServerContext* unused,
const channelz::v1::GetChannelRequest* request,

@ -6,3 +6,26 @@ indent_style = space
indent_size = 4
insert_final_newline = true
tab_width = 4
; https://docs.microsoft.com/visualstudio/ide/editorconfig-code-style-settings-reference
[*.cs]
dotnet_sort_system_directives_first = true
csharp_new_line_before_open_brace = accessors, anonymous_methods, control_blocks, events, indexers, local_functions, methods, properties, types
csharp_new_line_before_else = true
csharp_new_line_before_catch = true
csharp_new_line_before_finally = true
csharp_indent_case_contents = true
csharp_indent_switch_labels = true
csharp_space_after_cast = false
csharp_space_after_keywords_in_control_flow_statements = true
csharp_space_between_method_declaration_parameter_list_parentheses = false
csharp_space_between_method_call_parameter_list_parentheses = false
csharp_space_between_parentheses = false
csharp_space_before_colon_in_inheritance_clause = true
csharp_space_after_colon_in_inheritance_clause = true
csharp_space_around_binary_operators = before_and_after
csharp_space_between_method_declaration_empty_parameter_list_parentheses = false
csharp_space_between_method_call_name_and_opening_parenthesis = false
csharp_space_between_method_call_empty_parameter_list_parentheses = false
csharp_preserve_single_line_statements = true
csharp_preserve_single_line_blocks = true

@ -102,6 +102,7 @@ namespace Grpc.Core.Tests
"Grpc.HealthCheck.Tests",
"Grpc.IntegrationTesting",
"Grpc.Reflection.Tests",
"Grpc.Tools.Tests",
};
foreach (var assemblyName in otherAssemblies)
{

@ -51,11 +51,12 @@ namespace Grpc.Core.Internal
Logger.Debug("Attempting to load native library \"{0}\"", this.libraryPath);
this.handle = PlatformSpecificLoadLibrary(this.libraryPath);
this.handle = PlatformSpecificLoadLibrary(this.libraryPath, out string loadLibraryErrorDetail);
if (this.handle == IntPtr.Zero)
{
throw new IOException(string.Format("Error loading native library \"{0}\"", this.libraryPath));
throw new IOException(string.Format("Error loading native library \"{0}\". {1}",
this.libraryPath, loadLibraryErrorDetail));
}
}
@ -129,31 +130,44 @@ namespace Grpc.Core.Internal
/// <summary>
/// Loads library in a platform specific way.
/// </summary>
private static IntPtr PlatformSpecificLoadLibrary(string libraryPath)
private static IntPtr PlatformSpecificLoadLibrary(string libraryPath, out string errorMsg)
{
if (PlatformApis.IsWindows)
{
// TODO(jtattermusch): populate the error on Windows
errorMsg = null;
return Windows.LoadLibrary(libraryPath);
}
if (PlatformApis.IsLinux)
{
if (PlatformApis.IsMono)
{
return Mono.dlopen(libraryPath, RTLD_GLOBAL + RTLD_LAZY);
return LoadLibraryPosix(Mono.dlopen, Mono.dlerror, libraryPath, out errorMsg);
}
if (PlatformApis.IsNetCore)
{
return CoreCLR.dlopen(libraryPath, RTLD_GLOBAL + RTLD_LAZY);
return LoadLibraryPosix(CoreCLR.dlopen, CoreCLR.dlerror, libraryPath, out errorMsg);
}
return Linux.dlopen(libraryPath, RTLD_GLOBAL + RTLD_LAZY);
return LoadLibraryPosix(Linux.dlopen, Linux.dlerror, libraryPath, out errorMsg);
}
if (PlatformApis.IsMacOSX)
{
return MacOSX.dlopen(libraryPath, RTLD_GLOBAL + RTLD_LAZY);
return LoadLibraryPosix(MacOSX.dlopen, MacOSX.dlerror, libraryPath, out errorMsg);
}
throw new InvalidOperationException("Unsupported platform.");
}
private static IntPtr LoadLibraryPosix(Func<string, int, IntPtr> dlopenFunc, Func<IntPtr> dlerrorFunc, string libraryPath, out string errorMsg)
{
errorMsg = null;
IntPtr ret = dlopenFunc(libraryPath, RTLD_GLOBAL + RTLD_LAZY);
if (ret == IntPtr.Zero)
{
errorMsg = Marshal.PtrToStringAnsi(dlerrorFunc());
}
return ret;
}
private static string FirstValidLibraryPath(string[] libraryPathAlternatives)
{
GrpcPreconditions.CheckArgument(libraryPathAlternatives.Length > 0, "libraryPathAlternatives cannot be empty.");
@ -183,6 +197,9 @@ namespace Grpc.Core.Internal
[DllImport("libdl.so")]
internal static extern IntPtr dlopen(string filename, int flags);
[DllImport("libdl.so")]
internal static extern IntPtr dlerror();
[DllImport("libdl.so")]
internal static extern IntPtr dlsym(IntPtr handle, string symbol);
}
@ -192,6 +209,9 @@ namespace Grpc.Core.Internal
[DllImport("libSystem.dylib")]
internal static extern IntPtr dlopen(string filename, int flags);
[DllImport("libSystem.dylib")]
internal static extern IntPtr dlerror();
[DllImport("libSystem.dylib")]
internal static extern IntPtr dlsym(IntPtr handle, string symbol);
}
@ -208,6 +228,9 @@ namespace Grpc.Core.Internal
[DllImport("__Internal")]
internal static extern IntPtr dlopen(string filename, int flags);
[DllImport("__Internal")]
internal static extern IntPtr dlerror();
[DllImport("__Internal")]
internal static extern IntPtr dlsym(IntPtr handle, string symbol);
}
@ -222,6 +245,9 @@ namespace Grpc.Core.Internal
[DllImport("libcoreclr.so")]
internal static extern IntPtr dlopen(string filename, int flags);
[DllImport("libcoreclr.so")]
internal static extern IntPtr dlerror();
[DllImport("libcoreclr.so")]
internal static extern IntPtr dlsym(IntPtr handle, string symbol);
}

@ -1,7 +1,7 @@
<!-- This file is generated -->
<Project>
<PropertyGroup>
<GrpcCsharpVersion>1.16.0-dev</GrpcCsharpVersion>
<GrpcCsharpVersion>1.17.0-dev</GrpcCsharpVersion>
<GoogleProtobufVersion>3.6.1</GoogleProtobufVersion>
</PropertyGroup>
</Project>

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

@ -0,0 +1,85 @@
#region Copyright notice and license
// Copyright 2018 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.
#endregion
using NUnit.Framework;
namespace Grpc.Tools.Tests
{
public class CSharpGeneratorTest : GeneratorTest
{
GeneratorServices _generator;
[SetUp]
public new void SetUp()
{
_generator = GeneratorServices.GetForLanguage("CSharp", _log);
}
[TestCase("foo.proto", "Foo.cs", "FooGrpc.cs")]
[TestCase("sub/foo.proto", "Foo.cs", "FooGrpc.cs")]
[TestCase("one_two.proto", "OneTwo.cs", "OneTwoGrpc.cs")]
[TestCase("__one_two!.proto", "OneTwo!.cs", "OneTwo!Grpc.cs")]
[TestCase("one(two).proto", "One(two).cs", "One(two)Grpc.cs")]
[TestCase("one_(two).proto", "One(two).cs", "One(two)Grpc.cs")]
[TestCase("one two.proto", "One two.cs", "One twoGrpc.cs")]
[TestCase("one_ two.proto", "One two.cs", "One twoGrpc.cs")]
[TestCase("one .proto", "One .cs", "One Grpc.cs")]
public void NameMangling(string proto, string expectCs, string expectGrpcCs)
{
var poss = _generator.GetPossibleOutputs(Utils.MakeItem(proto, "grpcservices", "both"));
Assert.AreEqual(2, poss.Length);
Assert.Contains(expectCs, poss);
Assert.Contains(expectGrpcCs, poss);
}
[Test]
public void NoGrpcOneOutput()
{
var poss = _generator.GetPossibleOutputs(Utils.MakeItem("foo.proto"));
Assert.AreEqual(1, poss.Length);
}
[TestCase("none")]
[TestCase("")]
public void GrpcNoneOneOutput(string grpc)
{
var item = Utils.MakeItem("foo.proto", "grpcservices", grpc);
var poss = _generator.GetPossibleOutputs(item);
Assert.AreEqual(1, poss.Length);
}
[TestCase("client")]
[TestCase("server")]
[TestCase("both")]
public void GrpcEnabledTwoOutputs(string grpc)
{
var item = Utils.MakeItem("foo.proto", "grpcservices", grpc);
var poss = _generator.GetPossibleOutputs(item);
Assert.AreEqual(2, poss.Length);
}
[Test]
public void OutputDirMetadataRecognized()
{
var item = Utils.MakeItem("foo.proto", "OutputDir", "out");
var poss = _generator.GetPossibleOutputs(item);
Assert.AreEqual(1, poss.Length);
Assert.That(poss[0], Is.EqualTo("out/Foo.cs") | Is.EqualTo("out\\Foo.cs"));
}
};
}

@ -0,0 +1,88 @@
#region Copyright notice and license
// Copyright 2018 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.
#endregion
using System.IO;
using NUnit.Framework;
namespace Grpc.Tools.Tests
{
public class CppGeneratorTest : GeneratorTest
{
GeneratorServices _generator;
[SetUp]
public new void SetUp()
{
_generator = GeneratorServices.GetForLanguage("Cpp", _log);
}
[TestCase("foo.proto", "", "foo")]
[TestCase("foo.proto", ".", "foo")]
[TestCase("foo.proto", "./", "foo")]
[TestCase("sub/foo.proto", "", "sub/foo")]
[TestCase("root/sub/foo.proto", "root", "sub/foo")]
[TestCase("root/sub/foo.proto", "root", "sub/foo")]
[TestCase("/root/sub/foo.proto", "/root", "sub/foo")]
public void RelativeDirectoryCompute(string proto, string root, string expectStem)
{
if (Path.DirectorySeparatorChar == '\\')
expectStem = expectStem.Replace('/', '\\');
var poss = _generator.GetPossibleOutputs(Utils.MakeItem(proto, "ProtoRoot", root));
Assert.AreEqual(2, poss.Length);
Assert.Contains(expectStem + ".pb.cc", poss);
Assert.Contains(expectStem + ".pb.h", poss);
}
[Test]
public void NoGrpcTwoOutputs()
{
var poss = _generator.GetPossibleOutputs(Utils.MakeItem("foo.proto"));
Assert.AreEqual(2, poss.Length);
}
[TestCase("false")]
[TestCase("")]
public void GrpcDisabledTwoOutput(string grpc)
{
var item = Utils.MakeItem("foo.proto", "grpcservices", grpc);
var poss = _generator.GetPossibleOutputs(item);
Assert.AreEqual(2, poss.Length);
}
[TestCase("true")]
public void GrpcEnabledFourOutputs(string grpc)
{
var item = Utils.MakeItem("foo.proto", "grpcservices", grpc);
var poss = _generator.GetPossibleOutputs(item);
Assert.AreEqual(4, poss.Length);
Assert.Contains("foo.pb.cc", poss);
Assert.Contains("foo.pb.h", poss);
Assert.Contains("foo_grpc.pb.cc", poss);
Assert.Contains("foo_grpc.pb.h", poss);
}
[Test]
public void OutputDirMetadataRecognized()
{
var item = Utils.MakeItem("foo.proto", "OutputDir", "out");
var poss = _generator.GetPossibleOutputs(item);
Assert.AreEqual(2, poss.Length);
Assert.That(Path.GetDirectoryName(poss[0]), Is.EqualTo("out"));
}
};
}

@ -0,0 +1,146 @@
#region Copyright notice and license
// Copyright 2018 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.
#endregion
using System.IO;
using Microsoft.Build.Framework;
using Microsoft.Build.Utilities;
using NUnit.Framework;
namespace Grpc.Tools.Tests
{
public class DepFileUtilTest
{
[Test]
public void HashString64Hex_IsSane()
{
string hashFoo1 = DepFileUtil.HashString64Hex("foo");
string hashEmpty = DepFileUtil.HashString64Hex("");
string hashFoo2 = DepFileUtil.HashString64Hex("foo");
StringAssert.IsMatch("^[a-f0-9]{16}$", hashFoo1);
Assert.AreEqual(hashFoo1, hashFoo2);
Assert.AreNotEqual(hashFoo1, hashEmpty);
}
[Test]
public void GetDepFilenameForProto_IsSane()
{
StringAssert.IsMatch(@"^out[\\/][a-f0-9]{16}_foo.protodep$",
DepFileUtil.GetDepFilenameForProto("out", "foo.proto"));
StringAssert.IsMatch(@"^[a-f0-9]{16}_foo.protodep$",
DepFileUtil.GetDepFilenameForProto("", "foo.proto"));
}
[Test]
public void GetDepFilenameForProto_HashesDir()
{
string PickHash(string fname) =>
DepFileUtil.GetDepFilenameForProto("", fname).Substring(0, 16);
string same1 = PickHash("dir1/dir2/foo.proto");
string same2 = PickHash("dir1/dir2/proto.foo");
string same3 = PickHash("dir1/dir2/proto");
string same4 = PickHash("dir1/dir2/.proto");
string unsame1 = PickHash("dir2/foo.proto");
string unsame2 = PickHash("/dir2/foo.proto");
Assert.AreEqual(same1, same2);
Assert.AreEqual(same1, same3);
Assert.AreEqual(same1, same4);
Assert.AreNotEqual(same1, unsame1);
Assert.AreNotEqual(unsame1, unsame2);
}
//////////////////////////////////////////////////////////////////////////
// Full file reading tests
// Generated by protoc on Windows. Slashes vary.
const string depFile1 =
@"C:\projects\foo\src\./foo.grpc.pb.cc \
C:\projects\foo\src\./foo.grpc.pb.h \
C:\projects\foo\src\./foo.pb.cc \
C:\projects\foo\src\./foo.pb.h: C:/usr/include/google/protobuf/wrappers.proto\
C:/usr/include/google/protobuf/any.proto\
C:/usr/include/google/protobuf/source_context.proto\
C:/usr/include/google/protobuf/type.proto\
foo.proto";
// This has a nasty output directory with a space.
const string depFile2 =
@"obj\Release x64\net45\/Foo.cs \
obj\Release x64\net45\/FooGrpc.cs: C:/usr/include/google/protobuf/wrappers.proto\
C:/projects/foo/src//foo.proto";
[Test]
public void ReadDependencyInput_FullFile1()
{
string[] deps = ReadDependencyInputFromFileData(depFile1, "foo.proto");
Assert.NotNull(deps);
Assert.That(deps, Has.Length.InRange(4, 5)); // foo.proto may or may not be listed.
Assert.That(deps, Has.One.EndsWith("wrappers.proto"));
Assert.That(deps, Has.One.EndsWith("type.proto"));
Assert.That(deps, Has.None.StartWith(" "));
}
[Test]
public void ReadDependencyInput_FullFile2()
{
string[] deps = ReadDependencyInputFromFileData(depFile2, "C:/projects/foo/src/foo.proto");
Assert.NotNull(deps);
Assert.That(deps, Has.Length.InRange(1, 2));
Assert.That(deps, Has.One.EndsWith("wrappers.proto"));
Assert.That(deps, Has.None.StartWith(" "));
}
[Test]
public void ReadDependencyInput_FullFileUnparsable()
{
string[] deps = ReadDependencyInputFromFileData("a:/foo.proto", "/foo.proto");
Assert.NotNull(deps);
Assert.Zero(deps.Length);
}
// NB in our tests files are put into the temp directory but all have
// different names. Avoid adding files with the same directory path and
// name, or add reasonable handling for it if required. Tests are run in
// parallel and will collide otherwise.
private string[] ReadDependencyInputFromFileData(string fileData, string protoName)
{
string tempPath = Path.GetTempPath();
string tempfile = DepFileUtil.GetDepFilenameForProto(tempPath, protoName);
try
{
File.WriteAllText(tempfile, fileData);
var mockEng = new Moq.Mock<IBuildEngine>();
var log = new TaskLoggingHelper(mockEng.Object, "x");
return DepFileUtil.ReadDependencyInputs(tempPath, protoName, log);
}
finally
{
try
{
File.Delete(tempfile);
}
catch { }
}
}
};
}

@ -0,0 +1,55 @@
#region Copyright notice and license
// Copyright 2018 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.
#endregion
using Microsoft.Build.Framework;
using Microsoft.Build.Utilities;
using Moq;
using NUnit.Framework;
namespace Grpc.Tools.Tests
{
public class GeneratorTest
{
protected Mock<IBuildEngine> _mockEngine;
protected TaskLoggingHelper _log;
[SetUp]
public void SetUp()
{
_mockEngine = new Mock<IBuildEngine>();
_log = new TaskLoggingHelper(_mockEngine.Object, "dummy");
}
[TestCase("csharp")]
[TestCase("CSharp")]
[TestCase("cpp")]
public void ValidLanguages(string lang)
{
Assert.IsNotNull(GeneratorServices.GetForLanguage(lang, _log));
_mockEngine.Verify(me => me.LogErrorEvent(It.IsAny<BuildErrorEventArgs>()), Times.Never);
}
[TestCase("")]
[TestCase("COBOL")]
public void InvalidLanguages(string lang)
{
Assert.IsNull(GeneratorServices.GetForLanguage(lang, _log));
_mockEngine.Verify(me => me.LogErrorEvent(It.IsAny<BuildErrorEventArgs>()), Times.Once);
}
};
}

@ -0,0 +1,78 @@
<Project Sdk="Microsoft.NET.Sdk" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="..\Grpc.Core\Version.csproj.include" />
<PropertyGroup>
<TargetFrameworks>net45;netcoreapp1.0</TargetFrameworks>
<OutputType>Exe</OutputType>
</PropertyGroup>
<Import Project="..\Grpc.Core\SourceLink.csproj.include" />
<!-- This is copied verbatim from Grpc.Core/Common.csproj.include. Other settings
in that file conflict with the intent of this build, as it cannot be signed,
and may not compile Grpc.Core/Version.cs, as that file references constants
in Grpc.Core.dll.
TODO(kkm): Refactor imports. -->
<PropertyGroup Condition=" '$(OS)' != 'Windows_NT' and '$(MSBuildRuntimeType)' == 'Core' ">
<!-- Use Mono reference assemblies in SDK build: https://github.com/dotnet/sdk/issues/335 -->
<FrameworkPathOverride Condition="Exists('/usr/lib/mono/4.5-api')">/usr/lib/mono/4.5-api</FrameworkPathOverride>
<FrameworkPathOverride Condition="Exists('/usr/local/lib/mono/4.5-api')">/usr/local/lib/mono/4.5-api</FrameworkPathOverride>
<FrameworkPathOverride Condition="Exists('/Library/Frameworks/Mono.framework/Versions/Current/lib/mono/4.5-api')">/Library/Frameworks/Mono.framework/Versions/Current/lib/mono/4.5-api</FrameworkPathOverride>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\Grpc.Tools\Grpc.Tools.csproj" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Moq" Version="4.8.3" />
<PackageReference Include="NUnit; NUnitLite" Version="3.10.1" />
<PackageReference Include="System.Runtime.InteropServices.RuntimeInformation" Version="4.3.0" />
</ItemGroup>
<PropertyGroup Condition=" '$(TargetFramework)' != 'net45' ">
<DefineConstants>$(DefineConstants);NETCORE</DefineConstants>
</PropertyGroup>
<ItemGroup Condition=" '$(TargetFramework)' == 'net45' ">
<Reference Include="Microsoft.Build.Framework; Microsoft.Build.Utilities.v4.0" />
</ItemGroup>
<ItemGroup Condition=" '$(TargetFramework)' != 'net45' ">
<PackageReference Include="Microsoft.Build.Framework; Microsoft.Build.Utilities.Core" Version="15.6.*" />
</ItemGroup>
<!-- Groups below is a hack to allow the test to run under Mono Framework build.
========================================================================== -->
<!-- Mono unfortunately comes with broken Microsoft.Build.* assemblies installed in
the GAC, but fortunately searches for runtime assemblies in a different order
than Windows CLR host: the GAC assemblies have the lowest search priority, (see
https://www.mono-project.com/docs/advanced/assemblies-and-the-gac/), not the
highest as is in Windows (documented at
https://docs.microsoft.com/dotnet/framework/deployment/how-the-runtime-locates-assemblies).
To run the tests under Mono, we need correct assemblies in the same directory as
the test executable. Correct versions are in the MSBuild directory under Mono. -->
<ItemGroup Condition=" '$(TargetFramework)' == 'net45' and '$(OS)' != 'Windows_NT' ">
<None Include="$(_MSBuildAssemblyPath)/Microsoft.Build.Framework.dll;
$(_MSBuildAssemblyPath)/Microsoft.Build.Utilities.v4.0.dll;
$(_MSBuildAssemblyPath)/Microsoft.Build.Utilities.Core.dll"
CopyToOutputDirectory="Always" Visible="false" />
</ItemGroup>
<PropertyGroup Condition=" '$(TargetFramework)' == 'net45' and '$(OS)' != 'Windows_NT' ">
<!-- The None items are included into assembly candidate resolution by default, and
we do not want that, as they are not valid as reference assemblies (the version of
Microsoft.Build.Utilities.v4.0 is a pure facade for Microsoft.Build.Utilities.Core,
and does not define any types at all). Exclude them from assembly resolution. See
https://github.com/Microsoft/msbuild/blob/50639058f/documentation/wiki/ResolveAssemblyReference.md -->
<AssemblySearchPaths>{HintPathFromItem};{TargetFrameworkDirectory};{RawFileName}</AssemblySearchPaths>
<!-- Mono knows better where its MSBuild is. -->
<_MSBuildAssemblyPath Condition=" '$(MSBuildRuntimeType)' != 'Core' "
>$(MSBuildToolsPath)</_MSBuildAssemblyPath>
<!-- Under dotnet, make the best guess we can. -->
<_MSBuildAssemblyPath Condition=" '$(MSBuildRuntimeType)' == 'Core' "
>$(FrameworkPathOverride)/../msbuild/$(MSBuildToolsVersion)/bin</_MSBuildAssemblyPath>
</PropertyGroup>
</Project>

@ -0,0 +1,33 @@
#region Copyright notice and license
// Copyright 2018 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.
#endregion
using System.Reflection;
using NUnitLite;
namespace Grpc.Tools.Tests
{
static class NUnitMain
{
public static int Main(string[] args) =>
#if NETCOREAPP1_0 || NETCOREAPP1_1
new AutoRun(typeof(NUnitMain).GetTypeInfo().Assembly).Execute(args);
#else
new AutoRun().Execute(args);
#endif
};
}

@ -0,0 +1,76 @@
#region Copyright notice and license
// Copyright 2018 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.
#endregion
using System.Reflection; // UWYU: Object.GetType() extension.
using Microsoft.Build.Framework;
using Moq;
using NUnit.Framework;
namespace Grpc.Tools.Tests
{
public class ProtoCompileBasicTest
{
// Mock task class that stops right before invoking protoc.
public class ProtoCompileTestable : ProtoCompile
{
public string LastPathToTool { get; private set; }
public string[] LastResponseFile { get; private set; }
protected override int ExecuteTool(string pathToTool,
string response,
string commandLine)
{
// We should never be using command line commands.
Assert.That(commandLine, Is.Null | Is.Empty);
// Must receive a path to tool
Assert.That(pathToTool, Is.Not.Null & Is.Not.Empty);
Assert.That(response, Is.Not.Null & Does.EndWith("\n"));
LastPathToTool = pathToTool;
LastResponseFile = response.Remove(response.Length - 1).Split('\n');
// Do not run the tool, but pretend it ran successfully.
return 0;
}
};
protected Mock<IBuildEngine> _mockEngine;
protected ProtoCompileTestable _task;
[SetUp]
public void SetUp()
{
_mockEngine = new Mock<IBuildEngine>();
_task = new ProtoCompileTestable {
BuildEngine = _mockEngine.Object
};
}
[TestCase("ProtoBuf")]
[TestCase("Generator")]
[TestCase("OutputDir")]
[Description("We trust MSBuild to initialize these properties.")]
public void RequiredAttributePresentOnProperty(string prop)
{
var pinfo = _task.GetType()?.GetProperty(prop);
Assert.NotNull(pinfo);
Assert.That(pinfo, Has.Attribute<RequiredAttribute>());
}
};
}

@ -0,0 +1,179 @@
#region Copyright notice and license
// Copyright 2018 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.
#endregion
using System.IO;
using Microsoft.Build.Framework;
using Moq;
using NUnit.Framework;
namespace Grpc.Tools.Tests
{
public class ProtoCompileCommandLineGeneratorTest : ProtoCompileBasicTest
{
[SetUp]
public new void SetUp()
{
_task.Generator = "csharp";
_task.OutputDir = "outdir";
_task.ProtoBuf = Utils.MakeSimpleItems("a.proto");
}
void ExecuteExpectSuccess()
{
_mockEngine
.Setup(me => me.LogErrorEvent(It.IsAny<BuildErrorEventArgs>()))
.Callback((BuildErrorEventArgs e) =>
Assert.Fail($"Error logged by build engine:\n{e.Message}"));
bool result = _task.Execute();
Assert.IsTrue(result);
}
[Test]
public void MinimalCompile()
{
ExecuteExpectSuccess();
Assert.That(_task.LastPathToTool, Does.Match(@"protoc(.exe)?$"));
Assert.That(_task.LastResponseFile, Is.EqualTo(new[] {
"--csharp_out=outdir", "a.proto" }));
}
[Test]
public void CompileTwoFiles()
{
_task.ProtoBuf = Utils.MakeSimpleItems("a.proto", "foo/b.proto");
ExecuteExpectSuccess();
Assert.That(_task.LastResponseFile, Is.EqualTo(new[] {
"--csharp_out=outdir", "a.proto", "foo/b.proto" }));
}
[Test]
public void CompileWithProtoPaths()
{
_task.ProtoPath = new[] { "/path1", "/path2" };
ExecuteExpectSuccess();
Assert.That(_task.LastResponseFile, Is.EqualTo(new[] {
"--csharp_out=outdir", "--proto_path=/path1",
"--proto_path=/path2", "a.proto" }));
}
[TestCase("Cpp")]
[TestCase("CSharp")]
[TestCase("Java")]
[TestCase("Javanano")]
[TestCase("Js")]
[TestCase("Objc")]
[TestCase("Php")]
[TestCase("Python")]
[TestCase("Ruby")]
public void CompileWithOptions(string gen)
{
_task.Generator = gen;
_task.OutputOptions = new[] { "foo", "bar" };
ExecuteExpectSuccess();
gen = gen.ToLowerInvariant();
Assert.That(_task.LastResponseFile, Is.EqualTo(new[] {
$"--{gen}_out=outdir", $"--{gen}_opt=foo,bar", "a.proto" }));
}
[Test]
public void OutputDependencyFile()
{
_task.DependencyOut = "foo/my.protodep";
// Task fails trying to read the non-generated file; we ignore that.
_task.Execute();
Assert.That(_task.LastResponseFile,
Does.Contain("--dependency_out=foo/my.protodep"));
}
[Test]
public void OutputDependencyWithProtoDepDir()
{
_task.ProtoDepDir = "foo";
// Task fails trying to read the non-generated file; we ignore that.
_task.Execute();
Assert.That(_task.LastResponseFile,
Has.One.Match(@"^--dependency_out=foo[/\\].+_a.protodep$"));
}
[Test]
public void GenerateGrpc()
{
_task.GrpcPluginExe = "/foo/grpcgen";
ExecuteExpectSuccess();
Assert.That(_task.LastResponseFile, Is.SupersetOf(new[] {
"--csharp_out=outdir", "--grpc_out=outdir",
"--plugin=protoc-gen-grpc=/foo/grpcgen" }));
}
[Test]
public void GenerateGrpcWithOutDir()
{
_task.GrpcPluginExe = "/foo/grpcgen";
_task.GrpcOutputDir = "gen-out";
ExecuteExpectSuccess();
Assert.That(_task.LastResponseFile, Is.SupersetOf(new[] {
"--csharp_out=outdir", "--grpc_out=gen-out" }));
}
[Test]
public void GenerateGrpcWithOptions()
{
_task.GrpcPluginExe = "/foo/grpcgen";
_task.GrpcOutputOptions = new[] { "baz", "quux" };
ExecuteExpectSuccess();
Assert.That(_task.LastResponseFile,
Does.Contain("--grpc_opt=baz,quux"));
}
[Test]
public void DirectoryArgumentsSlashTrimmed()
{
_task.GrpcPluginExe = "/foo/grpcgen";
_task.GrpcOutputDir = "gen-out/";
_task.OutputDir = "outdir/";
_task.ProtoPath = new[] { "/path1/", "/path2/" };
ExecuteExpectSuccess();
Assert.That(_task.LastResponseFile, Is.SupersetOf(new[] {
"--proto_path=/path1", "--proto_path=/path2",
"--csharp_out=outdir", "--grpc_out=gen-out" }));
}
[TestCase(".", ".")]
[TestCase("/", "/")]
[TestCase("//", "/")]
[TestCase("/foo/", "/foo")]
[TestCase("/foo", "/foo")]
[TestCase("foo/", "foo")]
[TestCase("foo//", "foo")]
[TestCase("foo/\\", "foo")]
[TestCase("foo\\/", "foo")]
[TestCase("C:\\foo", "C:\\foo")]
[TestCase("C:", "C:")]
[TestCase("C:\\", "C:\\")]
[TestCase("C:\\\\", "C:\\")]
public void DirectorySlashTrimmingCases(string given, string expect)
{
if (Path.DirectorySeparatorChar == '/')
expect = expect.Replace('\\', '/');
_task.OutputDir = given;
ExecuteExpectSuccess();
Assert.That(_task.LastResponseFile,
Does.Contain("--csharp_out=" + expect));
}
};
}

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

Loading…
Cancel
Save