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

reviewable/pr7771/r13
Yuchen Zeng 8 years ago
commit f44e781d01
  1. 70
      BUILD
  2. 157
      CMakeLists.txt
  3. 189
      Makefile
  4. 3
      binding.gyp
  5. 90
      build.yaml
  6. 14
      cmake/msvc_static_runtime.cmake
  7. 2
      composer.json
  8. 3
      config.m4
  9. 9
      doc/PROTOCOL-WEB.md
  10. 1
      doc/environment_variables.md
  11. 53
      gRPC-Core.podspec
  12. 10
      gRPC-ProtoRPC.podspec
  13. 10
      gRPC-RxLibrary.podspec
  14. 9
      gRPC.podspec
  15. 11
      grpc.gemspec
  16. 9
      include/grpc++/impl/codegen/proto_utils.h
  17. 2
      include/grpc++/server.h
  18. 11
      include/grpc/impl/codegen/grpc_types.h
  19. 11
      package.xml
  20. 61
      src/core/ext/census/trace_label.h
  21. 63
      src/core/ext/census/trace_propagation.h
  22. 45
      src/core/ext/census/trace_status.h
  23. 50
      src/core/ext/census/trace_string.h
  24. 42
      src/core/ext/census/tracing.c
  25. 124
      src/core/ext/census/tracing.h
  26. 18
      src/core/ext/client_channel/client_channel.c
  27. 4
      src/core/ext/client_channel/client_channel.h
  28. 16
      src/core/ext/client_channel/subchannel.c
  29. 3
      src/core/ext/client_channel/subchannel.h
  30. 171
      src/core/ext/lb_policy/grpclb/grpclb.c
  31. 77
      src/core/ext/lb_policy/grpclb/grpclb_channel.c
  32. 56
      src/core/ext/lb_policy/grpclb/grpclb_channel.h
  33. 107
      src/core/ext/lb_policy/grpclb/grpclb_channel_secure.c
  34. 7
      src/core/ext/lb_policy/round_robin/round_robin.c
  35. 8
      src/core/ext/transport/chttp2/client/insecure/channel_create.c
  36. 184
      src/core/ext/transport/chttp2/client/secure/secure_channel_create.c
  37. 398
      src/core/ext/transport/chttp2/transport/chttp2_transport.c
  38. 22
      src/core/ext/transport/chttp2/transport/frame_ping.c
  39. 4
      src/core/ext/transport/chttp2/transport/frame_ping.h
  40. 9
      src/core/ext/transport/chttp2/transport/frame_rst_stream.c
  41. 7
      src/core/ext/transport/chttp2/transport/frame_settings.c
  42. 11
      src/core/ext/transport/chttp2/transport/frame_window_update.c
  43. 125
      src/core/ext/transport/chttp2/transport/internal.h
  44. 30
      src/core/ext/transport/chttp2/transport/parsing.c
  45. 43
      src/core/ext/transport/chttp2/transport/stream_lists.c
  46. 120
      src/core/ext/transport/chttp2/transport/writing.c
  47. 6
      src/core/lib/channel/connected_channel.c
  48. 5
      src/core/lib/channel/connected_channel.h
  49. 8
      src/core/lib/iomgr/closure.c
  50. 5
      src/core/lib/iomgr/closure.h
  51. 32
      src/core/lib/iomgr/resource_quota.c
  52. 6
      src/core/lib/iomgr/resource_quota.h
  53. 38
      src/core/lib/iomgr/sockaddr_utils.c
  54. 4
      src/core/lib/iomgr/sockaddr_utils.h
  55. 42
      src/core/lib/iomgr/udp_server.c
  56. 8
      src/core/lib/iomgr/udp_server.h
  57. 20
      src/core/lib/profiling/basic_timers.c
  58. 47
      src/core/lib/security/credentials/credentials.c
  59. 13
      src/core/lib/security/credentials/credentials.h
  60. 8
      src/core/lib/security/credentials/fake/fake_credentials.c
  61. 15
      src/core/lib/security/credentials/fake/fake_credentials.h
  62. 2
      src/core/lib/security/transport/client_auth_filter.c
  63. 70
      src/core/lib/security/transport/lb_targets_info.c
  64. 47
      src/core/lib/security/transport/lb_targets_info.h
  65. 141
      src/core/lib/security/transport/security_connector.c
  66. 7
      src/core/lib/security/transport/security_connector.h
  67. 4
      src/core/lib/security/transport/security_handshaker.c
  68. 6
      src/core/lib/slice/slice_intern.c
  69. 12
      src/core/lib/support/log_posix.c
  70. 7
      src/core/lib/support/sync_posix.c
  71. 7
      src/core/lib/surface/call.c
  72. 2
      src/core/lib/surface/init.c
  73. 2
      src/core/lib/surface/init_secure.c
  74. 104
      src/core/lib/transport/bdp_estimator.c
  75. 76
      src/core/lib/transport/bdp_estimator.h
  76. 36
      src/core/lib/transport/pid_controller.c
  77. 17
      src/core/lib/transport/pid_controller.h
  78. 1
      src/cpp/server/server_cc.cc
  79. 2
      src/csharp/ext/grpc_csharp_ext.c
  80. 17
      src/objective-c/!ProtoCompiler-gRPCPlugin.podspec
  81. 2
      src/objective-c/!ProtoCompiler.podspec
  82. 382
      src/objective-c/BoringSSL.podspec
  83. 2
      src/objective-c/GRPCClient/private/GRPCConnectivityMonitor.m
  84. 5
      src/objective-c/GRPCClient/private/GRPCHost.m
  85. 41
      src/objective-c/GRPCClient/private/version.h
  86. 2
      src/objective-c/tests/CoreCronetEnd2EndTests/CoreCronetEnd2EndTests.m
  87. 19
      src/objective-c/tests/Tests.xcodeproj/xcshareddata/xcschemes/AllTests.xcscheme
  88. 49
      src/php/README.md
  89. 2
      src/php/composer.json
  90. 15
      src/php/tests/generated_code/math_client.php
  91. 4
      src/python/grpcio/commands.py
  92. 57
      src/python/grpcio/grpc/__init__.py
  93. 51
      src/python/grpcio/grpc/_channel.py
  94. 12
      src/python/grpcio/grpc/_common.py
  95. 3
      src/python/grpcio/grpc/_plugin_wrapping.py
  96. 29
      src/python/grpcio/grpc/_server.py
  97. 11
      src/python/grpcio/grpc/_utilities.py
  98. 90
      src/python/grpcio/grpc/beta/_client_adaptations.py
  99. 4
      src/python/grpcio/grpc/beta/_connectivity_channel.py
  100. 11
      src/python/grpcio/grpc/beta/_server_adaptations.py
  101. Some files were not shown because too many files have changed in this diff Show More

70
BUILD

@ -63,7 +63,7 @@ grpc_cc_library(
deps = [
"census",
"grpc_base",
"grpc_lb_policy_grpclb",
"grpc_lb_policy_grpclb_secure",
"grpc_lb_policy_pick_first",
"grpc_lb_policy_round_robin",
"grpc_load_reporting",
@ -285,9 +285,15 @@ grpc_cc_library(
"src/core/ext/census/resource.h",
"src/core/ext/census/rpc_metric_id.h",
"src/core/ext/census/trace_context.h",
"src/core/ext/census/trace_label.h",
"src/core/ext/census/trace_propagation.h",
"src/core/ext/census/trace_status.h",
"src/core/ext/census/trace_string.h",
"src/core/ext/census/tracing.h",
],
external_deps = [
"nanopb",
"libssl",
],
language = "c",
public_hdrs = [
@ -527,6 +533,7 @@ grpc_cc_library(
"src/core/lib/transport/metadata.c",
"src/core/lib/transport/metadata_batch.c",
"src/core/lib/transport/pid_controller.c",
"src/core/lib/transport/bdp_estimator.c",
"src/core/lib/transport/service_config.c",
"src/core/lib/transport/static_metadata.c",
"src/core/lib/transport/status_conversion.c",
@ -624,9 +631,9 @@ grpc_cc_library(
"src/core/lib/surface/completion_queue.h",
"src/core/lib/surface/event_string.h",
"src/core/lib/surface/init.h",
"src/core/lib/surface/validate_metadata.h",
"src/core/lib/surface/lame_client.h",
"src/core/lib/surface/server.h",
"src/core/lib/surface/validate_metadata.h",
"src/core/lib/transport/byte_stream.h",
"src/core/lib/transport/connectivity_state.h",
"src/core/lib/transport/error_utils.h",
@ -634,6 +641,7 @@ grpc_cc_library(
"src/core/lib/transport/metadata.h",
"src/core/lib/transport/metadata_batch.h",
"src/core/lib/transport/pid_controller.h",
"src/core/lib/transport/bdp_estimator.h",
"src/core/lib/transport/service_config.h",
"src/core/lib/transport/static_metadata.h",
"src/core/lib/transport/status_conversion.h",
@ -664,7 +672,6 @@ grpc_cc_library(
grpc_cc_library(
name = "grpc_client_channel",
language = "c",
srcs = [
"src/core/ext/client_channel/channel_connectivity.c",
"src/core/ext/client_channel/client_channel.c",
@ -708,6 +715,7 @@ grpc_cc_library(
"src/core/ext/client_channel/subchannel_index.h",
"src/core/ext/client_channel/uri_parser.h",
],
language = "c",
deps = [
"grpc_base",
],
@ -734,11 +742,13 @@ grpc_cc_library(
name = "grpc_lb_policy_grpclb",
srcs = [
"src/core/ext/lb_policy/grpclb/grpclb.c",
"src/core/ext/lb_policy/grpclb/grpclb_channel.c",
"src/core/ext/lb_policy/grpclb/load_balancer_api.c",
"src/core/ext/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.c",
],
hdrs = [
"src/core/ext/lb_policy/grpclb/grpclb.h",
"src/core/ext/lb_policy/grpclb/grpclb_channel.h",
"src/core/ext/lb_policy/grpclb/load_balancer_api.h",
"src/core/ext/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.h",
],
@ -752,6 +762,31 @@ grpc_cc_library(
],
)
grpc_cc_library(
name = "grpc_lb_policy_grpclb_secure",
srcs = [
"src/core/ext/lb_policy/grpclb/grpclb.c",
"src/core/ext/lb_policy/grpclb/grpclb_channel_secure.c",
"src/core/ext/lb_policy/grpclb/load_balancer_api.c",
"src/core/ext/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.c",
],
hdrs = [
"src/core/ext/lb_policy/grpclb/grpclb.h",
"src/core/ext/lb_policy/grpclb/grpclb_channel.h",
"src/core/ext/lb_policy/grpclb/load_balancer_api.h",
"src/core/ext/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.h",
],
external_deps = [
"nanopb",
],
language = "c",
deps = [
"grpc_base",
"grpc_client_channel",
"grpc_secure",
],
)
grpc_cc_library(
name = "grpc_lb_policy_pick_first",
srcs = [
@ -859,6 +894,7 @@ grpc_cc_library(
"src/core/lib/security/credentials/ssl/ssl_credentials.c",
"src/core/lib/security/transport/client_auth_filter.c",
"src/core/lib/security/transport/secure_endpoint.c",
"src/core/lib/security/transport/lb_targets_info.c",
"src/core/lib/security/transport/security_connector.c",
"src/core/lib/security/transport/security_handshaker.c",
"src/core/lib/security/transport/server_auth_filter.c",
@ -882,6 +918,7 @@ grpc_cc_library(
"src/core/lib/security/credentials/ssl/ssl_credentials.h",
"src/core/lib/security/transport/auth_filters.h",
"src/core/lib/security/transport/secure_endpoint.h",
"src/core/lib/security/transport/lb_targets_info.h",
"src/core/lib/security/transport/security_connector.h",
"src/core/lib/security/transport/security_handshaker.h",
"src/core/lib/security/transport/tsi_error.h",
@ -965,22 +1002,21 @@ grpc_cc_library(
)
grpc_cc_library(
name = "grpc_transport_chttp2_client_connector",
hdrs = [
"src/core/ext/transport/chttp2/client/chttp2_connector.h",
],
srcs = [
"src/core/ext/transport/chttp2/client/chttp2_connector.c",
],
language = "c",
deps = [
"grpc_transport_chttp2",
"grpc_base",
"grpc_client_channel",
],
name = "grpc_transport_chttp2_client_connector",
srcs = [
"src/core/ext/transport/chttp2/client/chttp2_connector.c",
],
hdrs = [
"src/core/ext/transport/chttp2/client/chttp2_connector.h",
],
language = "c",
deps = [
"grpc_base",
"grpc_client_channel",
"grpc_transport_chttp2",
],
)
grpc_cc_library(
name = "grpc_transport_chttp2_client_insecure",
srcs = [

@ -90,10 +90,11 @@ if(WIN32)
set(_gRPC_PLATFORM_WINDOWS ON)
endif()
set(CMAKE_POSITION_INDEPENDENT_CODE TRUE)
if (MSVC)
include(cmake/msvc_static_runtime.cmake)
add_definitions(-D_WIN32_WINNT=0x600 -D_SCL_SECURE_NO_WARNINGS -D_CRT_SECURE_NO_WARNINGS -D_WINSOCK_DEPRECATED_NO_WARNINGS)
# needed to compile boringssl
add_definitions(/wd4464 /wd4623 /wd4668 /wd4701 /wd4702 /wd4777 /wd5027)
# needed to compile protobuf
add_definitions(/wd4065 /wd4506)
# TODO(jtattermusch): revisit C4267 occurrences throughout the code
@ -356,6 +357,7 @@ add_dependencies(buildtests_c algorithm_test)
add_dependencies(buildtests_c alloc_test)
add_dependencies(buildtests_c alpn_test)
add_dependencies(buildtests_c bad_server_response_test)
add_dependencies(buildtests_c bdp_estimator_test)
add_dependencies(buildtests_c bin_decoder_test)
add_dependencies(buildtests_c bin_encoder_test)
add_dependencies(buildtests_c census_context_test)
@ -464,6 +466,9 @@ add_dependencies(buildtests_c multiple_server_queues_test)
add_dependencies(buildtests_c murmur_hash_test)
add_dependencies(buildtests_c no_server_test)
add_dependencies(buildtests_c percent_encoding_test)
if(_gRPC_PLATFORM_LINUX)
add_dependencies(buildtests_c pollset_set_test)
endif()
if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX)
add_dependencies(buildtests_c resolve_address_posix_test)
endif()
@ -633,6 +638,7 @@ add_dependencies(buildtests_cxx metrics_client)
add_dependencies(buildtests_cxx mock_test)
add_dependencies(buildtests_cxx noop-benchmark)
add_dependencies(buildtests_cxx proto_server_reflection_test)
add_dependencies(buildtests_cxx proto_utils_test)
if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX)
add_dependencies(buildtests_cxx qps_interarrival_test)
endif()
@ -662,6 +668,9 @@ endif()
add_dependencies(buildtests_cxx stress_test)
add_dependencies(buildtests_cxx thread_manager_test)
add_dependencies(buildtests_cxx thread_stress_test)
if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX)
add_dependencies(buildtests_cxx writes_per_rpc_test)
endif()
add_custom_target(buildtests
DEPENDS buildtests_c buildtests_cxx)
@ -924,6 +933,7 @@ add_library(grpc
src/core/lib/surface/server.c
src/core/lib/surface/validate_metadata.c
src/core/lib/surface/version.c
src/core/lib/transport/bdp_estimator.c
src/core/lib/transport/byte_stream.c
src/core/lib/transport/connectivity_state.c
src/core/lib/transport/error_utils.c
@ -974,6 +984,7 @@ add_library(grpc
src/core/lib/security/credentials/plugin/plugin_credentials.c
src/core/lib/security/credentials/ssl/ssl_credentials.c
src/core/lib/security/transport/client_auth_filter.c
src/core/lib/security/transport/lb_targets_info.c
src/core/lib/security/transport/secure_endpoint.c
src/core/lib/security/transport/security_connector.c
src/core/lib/security/transport/security_handshaker.c
@ -1014,6 +1025,7 @@ add_library(grpc
src/core/ext/transport/chttp2/client/insecure/channel_create.c
src/core/ext/transport/chttp2/client/insecure/channel_create_posix.c
src/core/ext/lb_policy/grpclb/grpclb.c
src/core/ext/lb_policy/grpclb/grpclb_channel_secure.c
src/core/ext/lb_policy/grpclb/load_balancer_api.c
src/core/ext/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.c
third_party/nanopb/pb_common.c
@ -1224,6 +1236,7 @@ add_library(grpc_cronet
src/core/lib/surface/server.c
src/core/lib/surface/validate_metadata.c
src/core/lib/surface/version.c
src/core/lib/transport/bdp_estimator.c
src/core/lib/transport/byte_stream.c
src/core/lib/transport/connectivity_state.c
src/core/lib/transport/error_utils.c
@ -1298,6 +1311,7 @@ add_library(grpc_cronet
src/core/lib/security/credentials/plugin/plugin_credentials.c
src/core/lib/security/credentials/ssl/ssl_credentials.c
src/core/lib/security/transport/client_auth_filter.c
src/core/lib/security/transport/lb_targets_info.c
src/core/lib/security/transport/secure_endpoint.c
src/core/lib/security/transport/security_connector.c
src/core/lib/security/transport/security_handshaker.c
@ -1395,6 +1409,7 @@ add_library(grpc_test_util
test/core/end2end/fixtures/http_proxy.c
test/core/end2end/fixtures/proxy.c
test/core/iomgr/endpoint_tests.c
test/core/util/debugger_macros.c
test/core/util/grpc_profiler.c
test/core/util/memory_counters.c
test/core/util/mock_endpoint.c
@ -1510,6 +1525,7 @@ add_library(grpc_test_util
src/core/lib/surface/server.c
src/core/lib/surface/validate_metadata.c
src/core/lib/surface/version.c
src/core/lib/transport/bdp_estimator.c
src/core/lib/transport/byte_stream.c
src/core/lib/transport/connectivity_state.c
src/core/lib/transport/error_utils.c
@ -1591,6 +1607,7 @@ add_library(grpc_test_util_unsecure
test/core/end2end/fixtures/http_proxy.c
test/core/end2end/fixtures/proxy.c
test/core/iomgr/endpoint_tests.c
test/core/util/debugger_macros.c
test/core/util/grpc_profiler.c
test/core/util/memory_counters.c
test/core/util/mock_endpoint.c
@ -1736,6 +1753,7 @@ add_library(grpc_unsecure
src/core/lib/surface/server.c
src/core/lib/surface/validate_metadata.c
src/core/lib/surface/version.c
src/core/lib/transport/bdp_estimator.c
src/core/lib/transport/byte_stream.c
src/core/lib/transport/connectivity_state.c
src/core/lib/transport/error_utils.c
@ -1804,6 +1822,7 @@ add_library(grpc_unsecure
src/core/ext/load_reporting/load_reporting.c
src/core/ext/load_reporting/load_reporting_filter.c
src/core/ext/lb_policy/grpclb/grpclb.c
src/core/ext/lb_policy/grpclb/grpclb_channel.c
src/core/ext/lb_policy/grpclb/load_balancer_api.c
src/core/ext/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.c
third_party/nanopb/pb_common.c
@ -2292,6 +2311,7 @@ add_library(grpc++_cronet
src/core/lib/surface/server.c
src/core/lib/surface/validate_metadata.c
src/core/lib/surface/version.c
src/core/lib/transport/bdp_estimator.c
src/core/lib/transport/byte_stream.c
src/core/lib/transport/connectivity_state.c
src/core/lib/transport/error_utils.c
@ -3404,7 +3424,7 @@ target_link_libraries(qps
endif (gRPC_BUILD_TESTS)
add_library(grpc_csharp_ext
add_library(grpc_csharp_ext SHARED
src/csharp/ext/grpc_csharp_ext.c
)
@ -3880,6 +3900,33 @@ target_link_libraries(bad_server_response_test
endif (gRPC_BUILD_TESTS)
if (gRPC_BUILD_TESTS)
add_executable(bdp_estimator_test
test/core/transport/bdp_estimator_test.c
)
target_include_directories(bdp_estimator_test
PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
PRIVATE ${BORINGSSL_ROOT_DIR}/include
PRIVATE ${PROTOBUF_ROOT_DIR}/src
PRIVATE ${BENCHMARK_ROOT_DIR}/include
PRIVATE ${ZLIB_ROOT_DIR}
PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
)
target_link_libraries(bdp_estimator_test
${_gRPC_ALLTARGETS_LIBRARIES}
grpc_test_util
grpc
gpr_test_util
gpr
)
endif (gRPC_BUILD_TESTS)
if (gRPC_BUILD_TESTS)
add_executable(bin_decoder_test
test/core/transport/chttp2/bin_decoder_test.c
)
@ -6444,6 +6491,35 @@ target_link_libraries(percent_encoding_test
gpr
)
endif (gRPC_BUILD_TESTS)
if (gRPC_BUILD_TESTS)
if(_gRPC_PLATFORM_LINUX)
add_executable(pollset_set_test
test/core/iomgr/pollset_set_test.c
)
target_include_directories(pollset_set_test
PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
PRIVATE ${BORINGSSL_ROOT_DIR}/include
PRIVATE ${PROTOBUF_ROOT_DIR}/src
PRIVATE ${BENCHMARK_ROOT_DIR}/include
PRIVATE ${ZLIB_ROOT_DIR}
PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
)
target_link_libraries(pollset_set_test
${_gRPC_ALLTARGETS_LIBRARIES}
grpc_test_util
grpc
gpr_test_util
gpr
)
endif()
endif (gRPC_BUILD_TESTS)
if (gRPC_BUILD_TESTS)
if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX)
@ -8941,6 +9017,37 @@ target_link_libraries(proto_server_reflection_test
${_gRPC_GFLAGS_LIBRARIES}
)
endif (gRPC_BUILD_TESTS)
if (gRPC_BUILD_TESTS)
add_executable(proto_utils_test
test/cpp/codegen/proto_utils_test.cc
third_party/googletest/src/gtest-all.cc
)
target_include_directories(proto_utils_test
PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
PRIVATE ${BORINGSSL_ROOT_DIR}/include
PRIVATE ${PROTOBUF_ROOT_DIR}/src
PRIVATE ${BENCHMARK_ROOT_DIR}/include
PRIVATE ${ZLIB_ROOT_DIR}
PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
PRIVATE third_party/googletest/include
PRIVATE third_party/googletest
PRIVATE ${_gRPC_PROTO_GENS_DIR}
)
target_link_libraries(proto_utils_test
${_gRPC_PROTOBUF_LIBRARIES}
${_gRPC_ALLTARGETS_LIBRARIES}
grpc++
grpc
${_gRPC_GFLAGS_LIBRARIES}
)
endif (gRPC_BUILD_TESTS)
if (gRPC_BUILD_TESTS)
if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX)
@ -9738,6 +9845,43 @@ target_link_libraries(thread_stress_test
${_gRPC_GFLAGS_LIBRARIES}
)
endif (gRPC_BUILD_TESTS)
if (gRPC_BUILD_TESTS)
if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX)
add_executable(writes_per_rpc_test
test/cpp/performance/writes_per_rpc_test.cc
third_party/googletest/src/gtest-all.cc
)
target_include_directories(writes_per_rpc_test
PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
PRIVATE ${BORINGSSL_ROOT_DIR}/include
PRIVATE ${PROTOBUF_ROOT_DIR}/src
PRIVATE ${BENCHMARK_ROOT_DIR}/include
PRIVATE ${ZLIB_ROOT_DIR}
PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
PRIVATE third_party/googletest/include
PRIVATE third_party/googletest
PRIVATE ${_gRPC_PROTO_GENS_DIR}
)
target_link_libraries(writes_per_rpc_test
${_gRPC_PROTOBUF_LIBRARIES}
${_gRPC_ALLTARGETS_LIBRARIES}
grpc++_test_util
grpc_test_util
grpc++
grpc
gpr_test_util
gpr
${_gRPC_GFLAGS_LIBRARIES}
)
endif()
endif (gRPC_BUILD_TESTS)
if (gRPC_BUILD_TESTS)
@ -11478,13 +11622,6 @@ endif (gRPC_BUILD_TESTS)
if (gRPC_INSTALL)
install(EXPORT gRPCTargets
DESTINATION ${CMAKE_INSTALL_CMAKEDIR}
NAMESPACE gRPC::
)
endif()
foreach(_config gRPCConfig gRPCConfigVersion)
configure_file(tools/cmake/${_config}.cmake.in
${_config}.cmake @ONLY)

@ -212,6 +212,14 @@ CPPFLAGS_mutrace = -O3 -fno-omit-frame-pointer
LDFLAGS_mutrace = -rdynamic
DEFINES_mutrace = NDEBUG
VALID_CONFIG_counters = 1
CC_counters = $(DEFAULT_CC)
CXX_counters = $(DEFAULT_CXX)
LD_counters = $(DEFAULT_CC)
LDXX_counters = $(DEFAULT_CXX)
CPPFLAGS_counters = -O2 -DGPR_MU_COUNTERS
DEFINES_counters = NDEBUG
# General settings.
@ -943,6 +951,7 @@ alloc_test: $(BINDIR)/$(CONFIG)/alloc_test
alpn_test: $(BINDIR)/$(CONFIG)/alpn_test
api_fuzzer: $(BINDIR)/$(CONFIG)/api_fuzzer
bad_server_response_test: $(BINDIR)/$(CONFIG)/bad_server_response_test
bdp_estimator_test: $(BINDIR)/$(CONFIG)/bdp_estimator_test
bin_decoder_test: $(BINDIR)/$(CONFIG)/bin_decoder_test
bin_encoder_test: $(BINDIR)/$(CONFIG)/bin_encoder_test
census_context_test: $(BINDIR)/$(CONFIG)/census_context_test
@ -1041,6 +1050,7 @@ no_server_test: $(BINDIR)/$(CONFIG)/no_server_test
percent_decode_fuzzer: $(BINDIR)/$(CONFIG)/percent_decode_fuzzer
percent_encode_fuzzer: $(BINDIR)/$(CONFIG)/percent_encode_fuzzer
percent_encoding_test: $(BINDIR)/$(CONFIG)/percent_encoding_test
pollset_set_test: $(BINDIR)/$(CONFIG)/pollset_set_test
resolve_address_posix_test: $(BINDIR)/$(CONFIG)/resolve_address_posix_test
resolve_address_test: $(BINDIR)/$(CONFIG)/resolve_address_test
resource_quota_test: $(BINDIR)/$(CONFIG)/resource_quota_test
@ -1115,6 +1125,7 @@ metrics_client: $(BINDIR)/$(CONFIG)/metrics_client
mock_test: $(BINDIR)/$(CONFIG)/mock_test
noop-benchmark: $(BINDIR)/$(CONFIG)/noop-benchmark
proto_server_reflection_test: $(BINDIR)/$(CONFIG)/proto_server_reflection_test
proto_utils_test: $(BINDIR)/$(CONFIG)/proto_utils_test
qps_interarrival_test: $(BINDIR)/$(CONFIG)/qps_interarrival_test
qps_json_driver: $(BINDIR)/$(CONFIG)/qps_json_driver
qps_openloop_test: $(BINDIR)/$(CONFIG)/qps_openloop_test
@ -1134,6 +1145,7 @@ streaming_throughput_test: $(BINDIR)/$(CONFIG)/streaming_throughput_test
stress_test: $(BINDIR)/$(CONFIG)/stress_test
thread_manager_test: $(BINDIR)/$(CONFIG)/thread_manager_test
thread_stress_test: $(BINDIR)/$(CONFIG)/thread_stress_test
writes_per_rpc_test: $(BINDIR)/$(CONFIG)/writes_per_rpc_test
public_headers_must_be_c89: $(BINDIR)/$(CONFIG)/public_headers_must_be_c89
boringssl_aes_test: $(BINDIR)/$(CONFIG)/boringssl_aes_test
boringssl_asn1_test: $(BINDIR)/$(CONFIG)/boringssl_asn1_test
@ -1304,6 +1316,7 @@ buildtests_c: privatelibs_c \
$(BINDIR)/$(CONFIG)/alloc_test \
$(BINDIR)/$(CONFIG)/alpn_test \
$(BINDIR)/$(CONFIG)/bad_server_response_test \
$(BINDIR)/$(CONFIG)/bdp_estimator_test \
$(BINDIR)/$(CONFIG)/bin_decoder_test \
$(BINDIR)/$(CONFIG)/bin_encoder_test \
$(BINDIR)/$(CONFIG)/census_context_test \
@ -1386,6 +1399,7 @@ buildtests_c: privatelibs_c \
$(BINDIR)/$(CONFIG)/murmur_hash_test \
$(BINDIR)/$(CONFIG)/no_server_test \
$(BINDIR)/$(CONFIG)/percent_encoding_test \
$(BINDIR)/$(CONFIG)/pollset_set_test \
$(BINDIR)/$(CONFIG)/resolve_address_posix_test \
$(BINDIR)/$(CONFIG)/resolve_address_test \
$(BINDIR)/$(CONFIG)/resource_quota_test \
@ -1511,6 +1525,7 @@ buildtests_cxx: privatelibs_cxx \
$(BINDIR)/$(CONFIG)/mock_test \
$(BINDIR)/$(CONFIG)/noop-benchmark \
$(BINDIR)/$(CONFIG)/proto_server_reflection_test \
$(BINDIR)/$(CONFIG)/proto_utils_test \
$(BINDIR)/$(CONFIG)/qps_interarrival_test \
$(BINDIR)/$(CONFIG)/qps_json_driver \
$(BINDIR)/$(CONFIG)/qps_openloop_test \
@ -1530,6 +1545,7 @@ buildtests_cxx: privatelibs_cxx \
$(BINDIR)/$(CONFIG)/stress_test \
$(BINDIR)/$(CONFIG)/thread_manager_test \
$(BINDIR)/$(CONFIG)/thread_stress_test \
$(BINDIR)/$(CONFIG)/writes_per_rpc_test \
$(BINDIR)/$(CONFIG)/boringssl_aes_test \
$(BINDIR)/$(CONFIG)/boringssl_asn1_test \
$(BINDIR)/$(CONFIG)/boringssl_base64_test \
@ -1613,6 +1629,7 @@ buildtests_cxx: privatelibs_cxx \
$(BINDIR)/$(CONFIG)/mock_test \
$(BINDIR)/$(CONFIG)/noop-benchmark \
$(BINDIR)/$(CONFIG)/proto_server_reflection_test \
$(BINDIR)/$(CONFIG)/proto_utils_test \
$(BINDIR)/$(CONFIG)/qps_interarrival_test \
$(BINDIR)/$(CONFIG)/qps_json_driver \
$(BINDIR)/$(CONFIG)/qps_openloop_test \
@ -1632,6 +1649,7 @@ buildtests_cxx: privatelibs_cxx \
$(BINDIR)/$(CONFIG)/stress_test \
$(BINDIR)/$(CONFIG)/thread_manager_test \
$(BINDIR)/$(CONFIG)/thread_stress_test \
$(BINDIR)/$(CONFIG)/writes_per_rpc_test \
endif
@ -1651,6 +1669,8 @@ test_c: buildtests_c
$(Q) $(BINDIR)/$(CONFIG)/alpn_test || ( echo test alpn_test failed ; exit 1 )
$(E) "[RUN] Testing bad_server_response_test"
$(Q) $(BINDIR)/$(CONFIG)/bad_server_response_test || ( echo test bad_server_response_test failed ; exit 1 )
$(E) "[RUN] Testing bdp_estimator_test"
$(Q) $(BINDIR)/$(CONFIG)/bdp_estimator_test || ( echo test bdp_estimator_test failed ; exit 1 )
$(E) "[RUN] Testing bin_decoder_test"
$(Q) $(BINDIR)/$(CONFIG)/bin_decoder_test || ( echo test bin_decoder_test failed ; exit 1 )
$(E) "[RUN] Testing bin_encoder_test"
@ -1793,6 +1813,8 @@ test_c: buildtests_c
$(Q) $(BINDIR)/$(CONFIG)/no_server_test || ( echo test no_server_test failed ; exit 1 )
$(E) "[RUN] Testing percent_encoding_test"
$(Q) $(BINDIR)/$(CONFIG)/percent_encoding_test || ( echo test percent_encoding_test failed ; exit 1 )
$(E) "[RUN] Testing pollset_set_test"
$(Q) $(BINDIR)/$(CONFIG)/pollset_set_test || ( echo test pollset_set_test failed ; exit 1 )
$(E) "[RUN] Testing resolve_address_posix_test"
$(Q) $(BINDIR)/$(CONFIG)/resolve_address_posix_test || ( echo test resolve_address_posix_test failed ; exit 1 )
$(E) "[RUN] Testing resolve_address_test"
@ -1939,6 +1961,8 @@ test_cxx: buildtests_cxx
$(Q) $(BINDIR)/$(CONFIG)/noop-benchmark || ( echo test noop-benchmark failed ; exit 1 )
$(E) "[RUN] Testing proto_server_reflection_test"
$(Q) $(BINDIR)/$(CONFIG)/proto_server_reflection_test || ( echo test proto_server_reflection_test failed ; exit 1 )
$(E) "[RUN] Testing proto_utils_test"
$(Q) $(BINDIR)/$(CONFIG)/proto_utils_test || ( echo test proto_utils_test failed ; exit 1 )
$(E) "[RUN] Testing qps_openloop_test"
$(Q) $(BINDIR)/$(CONFIG)/qps_openloop_test || ( echo test qps_openloop_test failed ; exit 1 )
$(E) "[RUN] Testing round_robin_end2end_test"
@ -1963,6 +1987,8 @@ test_cxx: buildtests_cxx
$(Q) $(BINDIR)/$(CONFIG)/thread_manager_test || ( echo test thread_manager_test failed ; exit 1 )
$(E) "[RUN] Testing thread_stress_test"
$(Q) $(BINDIR)/$(CONFIG)/thread_stress_test || ( echo test thread_stress_test failed ; exit 1 )
$(E) "[RUN] Testing writes_per_rpc_test"
$(Q) $(BINDIR)/$(CONFIG)/writes_per_rpc_test || ( echo test writes_per_rpc_test failed ; exit 1 )
flaky_test_cxx: buildtests_cxx
@ -2774,6 +2800,7 @@ LIBGRPC_SRC = \
src/core/lib/surface/server.c \
src/core/lib/surface/validate_metadata.c \
src/core/lib/surface/version.c \
src/core/lib/transport/bdp_estimator.c \
src/core/lib/transport/byte_stream.c \
src/core/lib/transport/connectivity_state.c \
src/core/lib/transport/error_utils.c \
@ -2824,6 +2851,7 @@ LIBGRPC_SRC = \
src/core/lib/security/credentials/plugin/plugin_credentials.c \
src/core/lib/security/credentials/ssl/ssl_credentials.c \
src/core/lib/security/transport/client_auth_filter.c \
src/core/lib/security/transport/lb_targets_info.c \
src/core/lib/security/transport/secure_endpoint.c \
src/core/lib/security/transport/security_connector.c \
src/core/lib/security/transport/security_handshaker.c \
@ -2864,6 +2892,7 @@ LIBGRPC_SRC = \
src/core/ext/transport/chttp2/client/insecure/channel_create.c \
src/core/ext/transport/chttp2/client/insecure/channel_create_posix.c \
src/core/ext/lb_policy/grpclb/grpclb.c \
src/core/ext/lb_policy/grpclb/grpclb_channel_secure.c \
src/core/ext/lb_policy/grpclb/load_balancer_api.c \
src/core/ext/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.c \
third_party/nanopb/pb_common.c \
@ -3085,6 +3114,7 @@ LIBGRPC_CRONET_SRC = \
src/core/lib/surface/server.c \
src/core/lib/surface/validate_metadata.c \
src/core/lib/surface/version.c \
src/core/lib/transport/bdp_estimator.c \
src/core/lib/transport/byte_stream.c \
src/core/lib/transport/connectivity_state.c \
src/core/lib/transport/error_utils.c \
@ -3159,6 +3189,7 @@ LIBGRPC_CRONET_SRC = \
src/core/lib/security/credentials/plugin/plugin_credentials.c \
src/core/lib/security/credentials/ssl/ssl_credentials.c \
src/core/lib/security/transport/client_auth_filter.c \
src/core/lib/security/transport/lb_targets_info.c \
src/core/lib/security/transport/secure_endpoint.c \
src/core/lib/security/transport/security_connector.c \
src/core/lib/security/transport/security_handshaker.c \
@ -3268,6 +3299,7 @@ LIBGRPC_TEST_UTIL_SRC = \
test/core/end2end/fixtures/http_proxy.c \
test/core/end2end/fixtures/proxy.c \
test/core/iomgr/endpoint_tests.c \
test/core/util/debugger_macros.c \
test/core/util/grpc_profiler.c \
test/core/util/memory_counters.c \
test/core/util/mock_endpoint.c \
@ -3383,6 +3415,7 @@ LIBGRPC_TEST_UTIL_SRC = \
src/core/lib/surface/server.c \
src/core/lib/surface/validate_metadata.c \
src/core/lib/surface/version.c \
src/core/lib/transport/bdp_estimator.c \
src/core/lib/transport/byte_stream.c \
src/core/lib/transport/connectivity_state.c \
src/core/lib/transport/error_utils.c \
@ -3466,6 +3499,7 @@ LIBGRPC_TEST_UTIL_UNSECURE_SRC = \
test/core/end2end/fixtures/http_proxy.c \
test/core/end2end/fixtures/proxy.c \
test/core/iomgr/endpoint_tests.c \
test/core/util/debugger_macros.c \
test/core/util/grpc_profiler.c \
test/core/util/memory_counters.c \
test/core/util/mock_endpoint.c \
@ -3607,6 +3641,7 @@ LIBGRPC_UNSECURE_SRC = \
src/core/lib/surface/server.c \
src/core/lib/surface/validate_metadata.c \
src/core/lib/surface/version.c \
src/core/lib/transport/bdp_estimator.c \
src/core/lib/transport/byte_stream.c \
src/core/lib/transport/connectivity_state.c \
src/core/lib/transport/error_utils.c \
@ -3675,6 +3710,7 @@ LIBGRPC_UNSECURE_SRC = \
src/core/ext/load_reporting/load_reporting.c \
src/core/ext/load_reporting/load_reporting_filter.c \
src/core/ext/lb_policy/grpclb/grpclb.c \
src/core/ext/lb_policy/grpclb/grpclb_channel.c \
src/core/ext/lb_policy/grpclb/load_balancer_api.c \
src/core/ext/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.c \
third_party/nanopb/pb_common.c \
@ -4201,6 +4237,7 @@ LIBGRPC++_CRONET_SRC = \
src/core/lib/surface/server.c \
src/core/lib/surface/validate_metadata.c \
src/core/lib/surface/version.c \
src/core/lib/transport/bdp_estimator.c \
src/core/lib/transport/byte_stream.c \
src/core/lib/transport/connectivity_state.c \
src/core/lib/transport/error_utils.c \
@ -8091,6 +8128,38 @@ endif
endif
BDP_ESTIMATOR_TEST_SRC = \
test/core/transport/bdp_estimator_test.c \
BDP_ESTIMATOR_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(BDP_ESTIMATOR_TEST_SRC))))
ifeq ($(NO_SECURE),true)
# You can't build secure targets if you don't have OpenSSL.
$(BINDIR)/$(CONFIG)/bdp_estimator_test: openssl_dep_error
else
$(BINDIR)/$(CONFIG)/bdp_estimator_test: $(BDP_ESTIMATOR_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) $(BDP_ESTIMATOR_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)/bdp_estimator_test
endif
$(OBJDIR)/$(CONFIG)/test/core/transport/bdp_estimator_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
deps_bdp_estimator_test: $(BDP_ESTIMATOR_TEST_OBJS:.o=.dep)
ifneq ($(NO_SECURE),true)
ifneq ($(NO_DEPS),true)
-include $(BDP_ESTIMATOR_TEST_OBJS:.o=.dep)
endif
endif
BIN_DECODER_TEST_SRC = \
test/core/transport/chttp2/bin_decoder_test.c \
@ -11227,6 +11296,38 @@ endif
endif
POLLSET_SET_TEST_SRC = \
test/core/iomgr/pollset_set_test.c \
POLLSET_SET_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(POLLSET_SET_TEST_SRC))))
ifeq ($(NO_SECURE),true)
# You can't build secure targets if you don't have OpenSSL.
$(BINDIR)/$(CONFIG)/pollset_set_test: openssl_dep_error
else
$(BINDIR)/$(CONFIG)/pollset_set_test: $(POLLSET_SET_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) $(POLLSET_SET_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)/pollset_set_test
endif
$(OBJDIR)/$(CONFIG)/test/core/iomgr/pollset_set_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
deps_pollset_set_test: $(POLLSET_SET_TEST_OBJS:.o=.dep)
ifneq ($(NO_SECURE),true)
ifneq ($(NO_DEPS),true)
-include $(POLLSET_SET_TEST_OBJS:.o=.dep)
endif
endif
RESOLVE_ADDRESS_POSIX_TEST_SRC = \
test/core/iomgr/resolve_address_posix_test.c \
@ -13985,6 +14086,49 @@ endif
endif
PROTO_UTILS_TEST_SRC = \
test/cpp/codegen/proto_utils_test.cc \
PROTO_UTILS_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(PROTO_UTILS_TEST_SRC))))
ifeq ($(NO_SECURE),true)
# You can't build secure targets if you don't have OpenSSL.
$(BINDIR)/$(CONFIG)/proto_utils_test: openssl_dep_error
else
ifeq ($(NO_PROTOBUF),true)
# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.0.0+.
$(BINDIR)/$(CONFIG)/proto_utils_test: protobuf_dep_error
else
$(BINDIR)/$(CONFIG)/proto_utils_test: $(PROTOBUF_DEP) $(PROTO_UTILS_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a
$(E) "[LD] Linking $@"
$(Q) mkdir -p `dirname $@`
$(Q) $(LDXX) $(LDFLAGS) $(PROTO_UTILS_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/proto_utils_test
endif
endif
$(OBJDIR)/$(CONFIG)/test/cpp/codegen/proto_utils_test.o: $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a
deps_proto_utils_test: $(PROTO_UTILS_TEST_OBJS:.o=.dep)
ifneq ($(NO_SECURE),true)
ifneq ($(NO_DEPS),true)
-include $(PROTO_UTILS_TEST_OBJS:.o=.dep)
endif
endif
QPS_INTERARRIVAL_TEST_SRC = \
test/cpp/qps/qps_interarrival_test.cc \
@ -14851,6 +14995,49 @@ endif
endif
WRITES_PER_RPC_TEST_SRC = \
test/cpp/performance/writes_per_rpc_test.cc \
WRITES_PER_RPC_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(WRITES_PER_RPC_TEST_SRC))))
ifeq ($(NO_SECURE),true)
# You can't build secure targets if you don't have OpenSSL.
$(BINDIR)/$(CONFIG)/writes_per_rpc_test: openssl_dep_error
else
ifeq ($(NO_PROTOBUF),true)
# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.0.0+.
$(BINDIR)/$(CONFIG)/writes_per_rpc_test: protobuf_dep_error
else
$(BINDIR)/$(CONFIG)/writes_per_rpc_test: $(PROTOBUF_DEP) $(WRITES_PER_RPC_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
$(E) "[LD] Linking $@"
$(Q) mkdir -p `dirname $@`
$(Q) $(LDXX) $(LDFLAGS) $(WRITES_PER_RPC_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/writes_per_rpc_test
endif
endif
$(OBJDIR)/$(CONFIG)/test/cpp/performance/writes_per_rpc_test.o: $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
deps_writes_per_rpc_test: $(WRITES_PER_RPC_TEST_OBJS:.o=.dep)
ifneq ($(NO_SECURE),true)
ifneq ($(NO_DEPS),true)
-include $(WRITES_PER_RPC_TEST_OBJS:.o=.dep)
endif
endif
PUBLIC_HEADERS_MUST_BE_C89_SRC = \
test/core/surface/public_headers_must_be_c89.c \
@ -17692,6 +17879,7 @@ ifneq ($(OPENSSL_DEP),)
# This is to ensure the embedded OpenSSL is built beforehand, properly
# installing headers to their final destination on the drive. We need this
# otherwise parallel compilation will fail if a source is compiled first.
src/core/ext/lb_policy/grpclb/grpclb_channel_secure.c: $(OPENSSL_DEP)
src/core/ext/transport/chttp2/client/secure/secure_channel_create.c: $(OPENSSL_DEP)
src/core/ext/transport/chttp2/server/secure/server_secure_chttp2.c: $(OPENSSL_DEP)
src/core/ext/transport/cronet/client/secure/cronet_channel_create.c: $(OPENSSL_DEP)
@ -17713,6 +17901,7 @@ src/core/lib/security/credentials/oauth2/oauth2_credentials.c: $(OPENSSL_DEP)
src/core/lib/security/credentials/plugin/plugin_credentials.c: $(OPENSSL_DEP)
src/core/lib/security/credentials/ssl/ssl_credentials.c: $(OPENSSL_DEP)
src/core/lib/security/transport/client_auth_filter.c: $(OPENSSL_DEP)
src/core/lib/security/transport/lb_targets_info.c: $(OPENSSL_DEP)
src/core/lib/security/transport/secure_endpoint.c: $(OPENSSL_DEP)
src/core/lib/security/transport/security_connector.c: $(OPENSSL_DEP)
src/core/lib/security/transport/security_handshaker.c: $(OPENSSL_DEP)

@ -712,6 +712,7 @@
'src/core/lib/surface/server.c',
'src/core/lib/surface/validate_metadata.c',
'src/core/lib/surface/version.c',
'src/core/lib/transport/bdp_estimator.c',
'src/core/lib/transport/byte_stream.c',
'src/core/lib/transport/connectivity_state.c',
'src/core/lib/transport/error_utils.c',
@ -762,6 +763,7 @@
'src/core/lib/security/credentials/plugin/plugin_credentials.c',
'src/core/lib/security/credentials/ssl/ssl_credentials.c',
'src/core/lib/security/transport/client_auth_filter.c',
'src/core/lib/security/transport/lb_targets_info.c',
'src/core/lib/security/transport/secure_endpoint.c',
'src/core/lib/security/transport/security_connector.c',
'src/core/lib/security/transport/security_handshaker.c',
@ -802,6 +804,7 @@
'src/core/ext/transport/chttp2/client/insecure/channel_create.c',
'src/core/ext/transport/chttp2/client/insecure/channel_create_posix.c',
'src/core/ext/lb_policy/grpclb/grpclb.c',
'src/core/ext/lb_policy/grpclb/grpclb_channel_secure.c',
'src/core/ext/lb_policy/grpclb/load_balancer_api.c',
'src/core/ext/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.c',
'third_party/nanopb/pb_common.c',

@ -31,6 +31,11 @@ filegroups:
- src/core/ext/census/resource.h
- src/core/ext/census/rpc_metric_id.h
- src/core/ext/census/trace_context.h
- src/core/ext/census/trace_label.h
- src/core/ext/census/trace_propagation.h
- src/core/ext/census/trace_status.h
- src/core/ext/census/trace_string.h
- src/core/ext/census/tracing.h
src:
- src/core/ext/census/base_resources.c
- src/core/ext/census/context.c
@ -256,6 +261,7 @@ filegroups:
- src/core/lib/surface/lame_client.h
- src/core/lib/surface/server.h
- src/core/lib/surface/validate_metadata.h
- src/core/lib/transport/bdp_estimator.h
- src/core/lib/transport/byte_stream.h
- src/core/lib/transport/connectivity_state.h
- src/core/lib/transport/error_utils.h
@ -375,6 +381,7 @@ filegroups:
- src/core/lib/surface/server.c
- src/core/lib/surface/validate_metadata.c
- src/core/lib/surface/version.c
- src/core/lib/transport/bdp_estimator.c
- src/core/lib/transport/byte_stream.c
- src/core/lib/transport/connectivity_state.c
- src/core/lib/transport/error_utils.c
@ -450,10 +457,28 @@ filegroups:
- name: grpc_lb_policy_grpclb
headers:
- src/core/ext/lb_policy/grpclb/grpclb.h
- src/core/ext/lb_policy/grpclb/grpclb_channel.h
- src/core/ext/lb_policy/grpclb/load_balancer_api.h
- src/core/ext/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.h
src:
- src/core/ext/lb_policy/grpclb/grpclb.c
- src/core/ext/lb_policy/grpclb/grpclb_channel.c
- src/core/ext/lb_policy/grpclb/load_balancer_api.c
- src/core/ext/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.c
plugin: grpc_lb_policy_grpclb
uses:
- grpc_base
- grpc_client_channel
- nanopb
- name: grpc_lb_policy_grpclb_secure
headers:
- src/core/ext/lb_policy/grpclb/grpclb.h
- src/core/ext/lb_policy/grpclb/grpclb_channel.h
- src/core/ext/lb_policy/grpclb/load_balancer_api.h
- src/core/ext/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.h
src:
- src/core/ext/lb_policy/grpclb/grpclb.c
- src/core/ext/lb_policy/grpclb/grpclb_channel_secure.c
- src/core/ext/lb_policy/grpclb/load_balancer_api.c
- src/core/ext/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.c
plugin: grpc_lb_policy_grpclb
@ -528,6 +553,7 @@ filegroups:
- src/core/lib/security/credentials/plugin/plugin_credentials.h
- src/core/lib/security/credentials/ssl/ssl_credentials.h
- src/core/lib/security/transport/auth_filters.h
- src/core/lib/security/transport/lb_targets_info.h
- src/core/lib/security/transport/secure_endpoint.h
- src/core/lib/security/transport/security_connector.h
- src/core/lib/security/transport/security_handshaker.h
@ -551,6 +577,7 @@ filegroups:
- src/core/lib/security/credentials/plugin/plugin_credentials.c
- src/core/lib/security/credentials/ssl/ssl_credentials.c
- src/core/lib/security/transport/client_auth_filter.c
- src/core/lib/security/transport/lb_targets_info.c
- src/core/lib/security/transport/secure_endpoint.c
- src/core/lib/security/transport/security_connector.c
- src/core/lib/security/transport/security_handshaker.c
@ -572,6 +599,7 @@ filegroups:
- test/core/end2end/fixtures/http_proxy.h
- test/core/end2end/fixtures/proxy.h
- test/core/iomgr/endpoint_tests.h
- test/core/util/debugger_macros.h
- test/core/util/grpc_profiler.h
- test/core/util/memory_counters.h
- test/core/util/mock_endpoint.h
@ -586,6 +614,7 @@ filegroups:
- test/core/end2end/fixtures/http_proxy.c
- test/core/end2end/fixtures/proxy.c
- test/core/iomgr/endpoint_tests.c
- test/core/util/debugger_macros.c
- test/core/util/grpc_profiler.c
- test/core/util/memory_counters.c
- test/core/util/mock_endpoint.c
@ -917,7 +946,7 @@ libs:
- grpc_transport_chttp2_client_secure
- grpc_transport_chttp2_server_insecure
- grpc_transport_chttp2_client_insecure
- grpc_lb_policy_grpclb
- grpc_lb_policy_grpclb_secure
- grpc_lb_policy_pick_first
- grpc_lb_policy_round_robin
- grpc_resolver_dns_ares
@ -1454,6 +1483,16 @@ targets:
- gpr
exclude_iomgrs:
- uv
- name: bdp_estimator_test
build: test
language: c
src:
- test/core/transport/bdp_estimator_test.c
deps:
- grpc_test_util
- grpc
- gpr_test_util
- gpr
- name: bin_decoder_test
build: test
language: c
@ -2504,6 +2543,20 @@ targets:
- grpc
- gpr_test_util
- gpr
- name: pollset_set_test
build: test
language: c
src:
- test/core/iomgr/pollset_set_test.c
deps:
- grpc_test_util
- grpc
- gpr_test_util
- gpr
exclude_iomgrs:
- uv
platforms:
- linux
- name: resolve_address_posix_test
build: test
language: c
@ -2957,6 +3010,8 @@ targets:
- grpc
- gpr_test_util
- gpr
args:
- --benchmark_min_time=0
platforms:
- mac
- linux
@ -3440,6 +3495,18 @@ targets:
- grpc
- gpr_test_util
- gpr
- name: proto_utils_test
gtest: true
build: test
language: c++
src:
- test/cpp/codegen/proto_utils_test.cc
deps:
- grpc++
- grpc
filegroups:
- grpc++_codegen_base
- grpc++_codegen_proto
- name: qps_interarrival_test
build: test
run: false
@ -3739,6 +3806,24 @@ targets:
- grpc
- gpr_test_util
- gpr
- name: writes_per_rpc_test
gtest: true
cpu_cost: 0.5
build: test
language: c++
src:
- test/cpp/performance/writes_per_rpc_test.cc
deps:
- grpc++_test_util
- grpc_test_util
- grpc++
- grpc
- gpr_test_util
- gpr
platforms:
- mac
- linux
- posix
- name: public_headers_must_be_c89
build: test
language: c89
@ -3805,6 +3890,9 @@ configs:
basicprof:
CPPFLAGS: -O2 -DGRPC_BASIC_PROFILER -DGRPC_TIMERS_RDTSC
DEFINES: NDEBUG
counters:
CPPFLAGS: -O2 -DGPR_MU_COUNTERS
DEFINES: NDEBUG
dbg:
CPPFLAGS: -O0
DEFINES: _DEBUG DEBUG

@ -0,0 +1,14 @@
option(gRPC_MSVC_STATIC_RUNTIME "Link with static msvc runtime libraries" OFF)
if(gRPC_MSVC_STATIC_RUNTIME)
# switch from dynamic to static linking of msvcrt
foreach(flag_var
CMAKE_CXX_FLAGS CMAKE_CXX_FLAGS_DEBUG CMAKE_CXX_FLAGS_RELEASE
CMAKE_CXX_FLAGS_MINSIZEREL CMAKE_CXX_FLAGS_RELWITHDEBINFO)
if(${flag_var} MATCHES "/MD")
string(REGEX REPLACE "/MD" "/MT" ${flag_var} "${${flag_var}}")
endif(${flag_var} MATCHES "/MD")
endforeach(flag_var)
endif()

@ -7,7 +7,7 @@
"license": "BSD-3-Clause",
"require": {
"php": ">=5.5.0",
"google/protobuf": "v3.1.0-alpha-1"
"google/protobuf": "v3.1.0"
},
"require-dev": {
"google/auth": "v0.9"

@ -186,6 +186,7 @@ if test "$PHP_GRPC" != "no"; then
src/core/lib/surface/server.c \
src/core/lib/surface/validate_metadata.c \
src/core/lib/surface/version.c \
src/core/lib/transport/bdp_estimator.c \
src/core/lib/transport/byte_stream.c \
src/core/lib/transport/connectivity_state.c \
src/core/lib/transport/error_utils.c \
@ -236,6 +237,7 @@ if test "$PHP_GRPC" != "no"; then
src/core/lib/security/credentials/plugin/plugin_credentials.c \
src/core/lib/security/credentials/ssl/ssl_credentials.c \
src/core/lib/security/transport/client_auth_filter.c \
src/core/lib/security/transport/lb_targets_info.c \
src/core/lib/security/transport/secure_endpoint.c \
src/core/lib/security/transport/security_connector.c \
src/core/lib/security/transport/security_handshaker.c \
@ -276,6 +278,7 @@ if test "$PHP_GRPC" != "no"; then
src/core/ext/transport/chttp2/client/insecure/channel_create.c \
src/core/ext/transport/chttp2/client/insecure/channel_create_posix.c \
src/core/ext/lb_policy/grpclb/grpclb.c \
src/core/ext/lb_policy/grpclb/grpclb_channel_secure.c \
src/core/ext/lb_policy/grpclb/load_balancer_api.c \
src/core/ext/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.c \
third_party/nanopb/pb_common.c \

@ -60,21 +60,22 @@ HTTP/2 related behavior (specified in [gRPC over HTTP2](http://www.grpc.io/docs/
Message framing (vs. [http2-transport-mapping](http://www.grpc.io/docs/guides/wire.html#http2-transport-mapping))
1. Response status encoded as part of the response body
* Key-value pairs encoded in the HTTP/2 [literal header format](https://tools.ietf.org/html/rfc7541#section-6.2) as a single header block.
* Key-value pairs encoded as a HTTP/1 headers block (without the terminating newline).
2. 8th (MSB) bit of the 1st gRPC frame byte
* 0: data
* 1: trailers
3. Trailers must be the last message of the response, as enforced
by the implementation
4. Trailers-only responses: no change to the gRPC protocol spec.
Trailers will be sent together with response headers, with no message
Trailers may be sent together with response headers, with no message
in the body.
---
User Agent
User Agent and Server headers
* grpc-web-javascript/0.1
* U-A: grpc-web-javascript/0.1
* Server: grpc-web-gateway/0.1
---

@ -35,6 +35,7 @@ some configuration as environment variables that can be set.
A comma separated list of tracers that provide additional insight into how
gRPC C core is processing requests via debug logs. Available tracers include:
- api - traces api calls to the C core
- bdp_estimator - traces behavior of bdp estimation logic
- call_error - traces the possible errors contributing to final call status
- channel - traces operations on the C core channel stack
- combiner - traces combiner lock state

@ -1,8 +1,10 @@
# GRPC CocoaPods podspec
# This file has been automatically generated from a template file. Please make modifications to
# `templates/gRPC-Core.podspec.template` instead. This file can be regenerated from the template by
# running `tools/buildgen/generate_projects.sh`.
# This file has been automatically generated from a template file.
# Please make modifications to `templates/gRPC-Core.podspec.template`
# instead. This file can be regenerated from the template by running
# `tools/buildgen/generate_projects.sh`.
# gRPC Core CocoaPods podspec
#
# Copyright 2015, Google Inc.
# All rights reserved.
#
@ -35,7 +37,7 @@
Pod::Spec.new do |s|
s.name = 'gRPC-Core'
version = '1.0.2'
version = '1.2.0-dev'
s.version = version
s.summary = 'Core cross-platform gRPC library, written in C'
s.homepage = 'http://www.grpc.io'
@ -44,9 +46,7 @@ Pod::Spec.new do |s|
s.source = {
:git => 'https://github.com/grpc/grpc.git',
# TODO(mxyan): Change back to "v#{version}" for next release
#:tag => "v#{version}",
:tag => "objective-c-v#{version}",
:tag => "v#{version}",
# TODO(jcanizales): Depend explicitly on the nanopb pod, and disable submodules.
:submodules => true,
}
@ -192,7 +192,7 @@ Pod::Spec.new do |s|
ss.header_mappings_dir = '.'
ss.libraries = 'z'
ss.dependency "#{s.name}/Interface", version
ss.dependency 'BoringSSL', '~> 7.0'
ss.dependency 'BoringSSL', '~> 8.0'
# To save you from scrolling, this is the last part of the podspec.
ss.source_files = 'src/core/lib/profiling/timers.h',
@ -343,6 +343,7 @@ Pod::Spec.new do |s|
'src/core/lib/surface/lame_client.h',
'src/core/lib/surface/server.h',
'src/core/lib/surface/validate_metadata.h',
'src/core/lib/transport/bdp_estimator.h',
'src/core/lib/transport/byte_stream.h',
'src/core/lib/transport/connectivity_state.h',
'src/core/lib/transport/error_utils.h',
@ -388,6 +389,7 @@ Pod::Spec.new do |s|
'src/core/lib/security/credentials/plugin/plugin_credentials.h',
'src/core/lib/security/credentials/ssl/ssl_credentials.h',
'src/core/lib/security/transport/auth_filters.h',
'src/core/lib/security/transport/lb_targets_info.h',
'src/core/lib/security/transport/secure_endpoint.h',
'src/core/lib/security/transport/security_connector.h',
'src/core/lib/security/transport/security_handshaker.h',
@ -420,6 +422,7 @@ Pod::Spec.new do |s|
'src/core/ext/client_channel/uri_parser.h',
'src/core/ext/transport/chttp2/client/chttp2_connector.h',
'src/core/ext/lb_policy/grpclb/grpclb.h',
'src/core/ext/lb_policy/grpclb/grpclb_channel.h',
'src/core/ext/lb_policy/grpclb/load_balancer_api.h',
'src/core/ext/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.h',
'third_party/nanopb/pb.h',
@ -441,6 +444,11 @@ Pod::Spec.new do |s|
'src/core/ext/census/resource.h',
'src/core/ext/census/rpc_metric_id.h',
'src/core/ext/census/trace_context.h',
'src/core/ext/census/trace_label.h',
'src/core/ext/census/trace_propagation.h',
'src/core/ext/census/trace_status.h',
'src/core/ext/census/trace_string.h',
'src/core/ext/census/tracing.h',
'src/core/lib/surface/init.c',
'src/core/lib/channel/channel_args.c',
'src/core/lib/channel/channel_stack.c',
@ -547,6 +555,7 @@ Pod::Spec.new do |s|
'src/core/lib/surface/server.c',
'src/core/lib/surface/validate_metadata.c',
'src/core/lib/surface/version.c',
'src/core/lib/transport/bdp_estimator.c',
'src/core/lib/transport/byte_stream.c',
'src/core/lib/transport/connectivity_state.c',
'src/core/lib/transport/error_utils.c',
@ -597,6 +606,7 @@ Pod::Spec.new do |s|
'src/core/lib/security/credentials/plugin/plugin_credentials.c',
'src/core/lib/security/credentials/ssl/ssl_credentials.c',
'src/core/lib/security/transport/client_auth_filter.c',
'src/core/lib/security/transport/lb_targets_info.c',
'src/core/lib/security/transport/secure_endpoint.c',
'src/core/lib/security/transport/security_connector.c',
'src/core/lib/security/transport/security_handshaker.c',
@ -637,6 +647,7 @@ Pod::Spec.new do |s|
'src/core/ext/transport/chttp2/client/insecure/channel_create.c',
'src/core/ext/transport/chttp2/client/insecure/channel_create_posix.c',
'src/core/ext/lb_policy/grpclb/grpclb.c',
'src/core/ext/lb_policy/grpclb/grpclb_channel_secure.c',
'src/core/ext/lb_policy/grpclb/load_balancer_api.c',
'src/core/ext/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.c',
'third_party/nanopb/pb_common.c',
@ -771,6 +782,7 @@ Pod::Spec.new do |s|
'src/core/lib/surface/lame_client.h',
'src/core/lib/surface/server.h',
'src/core/lib/surface/validate_metadata.h',
'src/core/lib/transport/bdp_estimator.h',
'src/core/lib/transport/byte_stream.h',
'src/core/lib/transport/connectivity_state.h',
'src/core/lib/transport/error_utils.h',
@ -816,6 +828,7 @@ Pod::Spec.new do |s|
'src/core/lib/security/credentials/plugin/plugin_credentials.h',
'src/core/lib/security/credentials/ssl/ssl_credentials.h',
'src/core/lib/security/transport/auth_filters.h',
'src/core/lib/security/transport/lb_targets_info.h',
'src/core/lib/security/transport/secure_endpoint.h',
'src/core/lib/security/transport/security_connector.h',
'src/core/lib/security/transport/security_handshaker.h',
@ -848,6 +861,7 @@ Pod::Spec.new do |s|
'src/core/ext/client_channel/uri_parser.h',
'src/core/ext/transport/chttp2/client/chttp2_connector.h',
'src/core/ext/lb_policy/grpclb/grpclb.h',
'src/core/ext/lb_policy/grpclb/grpclb_channel.h',
'src/core/ext/lb_policy/grpclb/load_balancer_api.h',
'src/core/ext/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.h',
'third_party/nanopb/pb.h',
@ -868,7 +882,12 @@ Pod::Spec.new do |s|
'src/core/ext/census/mlog.h',
'src/core/ext/census/resource.h',
'src/core/ext/census/rpc_metric_id.h',
'src/core/ext/census/trace_context.h'
'src/core/ext/census/trace_context.h',
'src/core/ext/census/trace_label.h',
'src/core/ext/census/trace_propagation.h',
'src/core/ext/census/trace_status.h',
'src/core/ext/census/trace_string.h',
'src/core/ext/census/tracing.h'
end
s.subspec 'Cronet-Interface' do |ss|
@ -878,23 +897,31 @@ Pod::Spec.new do |s|
s.subspec 'Cronet-Implementation' do |ss|
ss.header_mappings_dir = '.'
ss.dependency "#{s.name}/Interface", version
ss.dependency "#{s.name}/Implementation", version
ss.dependency "#{s.name}/Cronet-Interface", version
ss.source_files = 'src/core/ext/transport/cronet/client/secure/cronet_channel_create.c',
'src/core/ext/transport/cronet/transport/cronet_transport.c'
'src/core/ext/transport/cronet/transport/cronet_transport.c',
'third_party/objective_c/Cronet/bidirectional_stream_c.h'
end
s.subspec 'Tests' do |ss|
ss.header_mappings_dir = '.'
ss.dependency "#{s.name}/Interface", version
ss.dependency "#{s.name}/Implementation", version
ss.source_files = 'test/core/end2end/cq_verifier.{c,h}',
'test/core/end2end/end2end_tests.{c,h}',
'test/core/end2end/end2end_test_utils.c',
'test/core/end2end/tests/*.{c,h}',
'test/core/end2end/data/*.{c,h}',
'test/core/util/debugger_macros.c',
'test/core/util/test_config.{c,h}',
'test/core/util/port.h',
'test/core/util/port_posix.c',
'test/core/util/port_server_client.{c,h}'
ss.dependency 'CronetFramework'
end
end

@ -1,3 +1,9 @@
# This file has been automatically generated from a template file.
# Please make modifications to
# `templates/gRPC-ProtoRPC.podspec.template` instead. This file can be
# regenerated from the template by running
# `tools/buildgen/generate_projects.sh`.
# Copyright 2015, Google Inc.
# All rights reserved.
#
@ -30,7 +36,7 @@
Pod::Spec.new do |s|
s.name = 'gRPC-ProtoRPC'
version = '1.0.2'
version = '1.2.0-dev'
s.version = version
s.summary = 'RPC library for Protocol Buffers, based on gRPC'
s.homepage = 'http://www.grpc.io'
@ -39,7 +45,7 @@ Pod::Spec.new do |s|
s.source = {
:git => 'https://github.com/grpc/grpc.git',
:tag => "objective-c-v#{version}",
:tag => "v#{version}",
}
s.ios.deployment_target = '7.1'

@ -1,3 +1,9 @@
# This file has been automatically generated from a template file.
# Please make modifications to
# `templates/gRPC-RxLibrary.podspec.template` instead. This file can be
# regenerated from the template by running
# `tools/buildgen/generate_projects.sh`.
# Copyright 2015, Google Inc.
# All rights reserved.
#
@ -30,7 +36,7 @@
Pod::Spec.new do |s|
s.name = 'gRPC-RxLibrary'
version = '1.0.2'
version = '1.2.0-dev'
s.version = version
s.summary = 'Reactive Extensions library for iOS/OSX.'
s.homepage = 'http://www.grpc.io'
@ -39,7 +45,7 @@ Pod::Spec.new do |s|
s.source = {
:git => 'https://github.com/grpc/grpc.git',
:tag => "objective-c-v#{version}",
:tag => "v#{version}",
}
s.ios.deployment_target = '7.1'

@ -1,3 +1,8 @@
# This file has been automatically generated from a template file.
# Please make modifications to `templates/gRPC.podspec.template`
# instead. This file can be regenerated from the template by running
# `tools/buildgen/generate_projects.sh`.
# Copyright 2015, Google Inc.
# All rights reserved.
#
@ -30,7 +35,7 @@
Pod::Spec.new do |s|
s.name = 'gRPC'
version = '1.0.2'
version = '1.2.0-dev'
s.version = version
s.summary = 'gRPC client library for iOS/OSX'
s.homepage = 'http://www.grpc.io'
@ -39,7 +44,7 @@ Pod::Spec.new do |s|
s.source = {
:git => 'https://github.com/grpc/grpc.git',
:tag => "objective-c-v#{version}",
:tag => "v#{version}",
}
s.ios.deployment_target = '7.1'

@ -259,6 +259,7 @@ Gem::Specification.new do |s|
s.files += %w( src/core/lib/surface/lame_client.h )
s.files += %w( src/core/lib/surface/server.h )
s.files += %w( src/core/lib/surface/validate_metadata.h )
s.files += %w( src/core/lib/transport/bdp_estimator.h )
s.files += %w( src/core/lib/transport/byte_stream.h )
s.files += %w( src/core/lib/transport/connectivity_state.h )
s.files += %w( src/core/lib/transport/error_utils.h )
@ -304,6 +305,7 @@ Gem::Specification.new do |s|
s.files += %w( src/core/lib/security/credentials/plugin/plugin_credentials.h )
s.files += %w( src/core/lib/security/credentials/ssl/ssl_credentials.h )
s.files += %w( src/core/lib/security/transport/auth_filters.h )
s.files += %w( src/core/lib/security/transport/lb_targets_info.h )
s.files += %w( src/core/lib/security/transport/secure_endpoint.h )
s.files += %w( src/core/lib/security/transport/security_connector.h )
s.files += %w( src/core/lib/security/transport/security_handshaker.h )
@ -336,6 +338,7 @@ Gem::Specification.new do |s|
s.files += %w( src/core/ext/client_channel/uri_parser.h )
s.files += %w( src/core/ext/transport/chttp2/client/chttp2_connector.h )
s.files += %w( src/core/ext/lb_policy/grpclb/grpclb.h )
s.files += %w( src/core/ext/lb_policy/grpclb/grpclb_channel.h )
s.files += %w( src/core/ext/lb_policy/grpclb/load_balancer_api.h )
s.files += %w( src/core/ext/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.h )
s.files += %w( third_party/nanopb/pb.h )
@ -357,6 +360,11 @@ Gem::Specification.new do |s|
s.files += %w( src/core/ext/census/resource.h )
s.files += %w( src/core/ext/census/rpc_metric_id.h )
s.files += %w( src/core/ext/census/trace_context.h )
s.files += %w( src/core/ext/census/trace_label.h )
s.files += %w( src/core/ext/census/trace_propagation.h )
s.files += %w( src/core/ext/census/trace_status.h )
s.files += %w( src/core/ext/census/trace_string.h )
s.files += %w( src/core/ext/census/tracing.h )
s.files += %w( src/core/lib/surface/init.c )
s.files += %w( src/core/lib/channel/channel_args.c )
s.files += %w( src/core/lib/channel/channel_stack.c )
@ -463,6 +471,7 @@ Gem::Specification.new do |s|
s.files += %w( src/core/lib/surface/server.c )
s.files += %w( src/core/lib/surface/validate_metadata.c )
s.files += %w( src/core/lib/surface/version.c )
s.files += %w( src/core/lib/transport/bdp_estimator.c )
s.files += %w( src/core/lib/transport/byte_stream.c )
s.files += %w( src/core/lib/transport/connectivity_state.c )
s.files += %w( src/core/lib/transport/error_utils.c )
@ -513,6 +522,7 @@ Gem::Specification.new do |s|
s.files += %w( src/core/lib/security/credentials/plugin/plugin_credentials.c )
s.files += %w( src/core/lib/security/credentials/ssl/ssl_credentials.c )
s.files += %w( src/core/lib/security/transport/client_auth_filter.c )
s.files += %w( src/core/lib/security/transport/lb_targets_info.c )
s.files += %w( src/core/lib/security/transport/secure_endpoint.c )
s.files += %w( src/core/lib/security/transport/security_connector.c )
s.files += %w( src/core/lib/security/transport/security_handshaker.c )
@ -553,6 +563,7 @@ Gem::Specification.new do |s|
s.files += %w( src/core/ext/transport/chttp2/client/insecure/channel_create.c )
s.files += %w( src/core/ext/transport/chttp2/client/insecure/channel_create_posix.c )
s.files += %w( src/core/ext/lb_policy/grpclb/grpclb.c )
s.files += %w( src/core/ext/lb_policy/grpclb/grpclb_channel_secure.c )
s.files += %w( src/core/ext/lb_policy/grpclb/load_balancer_api.c )
s.files += %w( src/core/ext/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.c )
s.files += %w( third_party/nanopb/pb_common.c )

@ -50,6 +50,8 @@ extern CoreCodegenInterface* g_core_codegen_interface;
namespace internal {
class GrpcBufferWriterPeer;
const int kGrpcBufferWriterMaxBufferLength = 8192;
class GrpcBufferWriter final
@ -91,13 +93,18 @@ class GrpcBufferWriter final
&slice_, GRPC_SLICE_LENGTH(slice_) - count);
g_core_codegen_interface->grpc_slice_buffer_add(slice_buffer_, slice_);
}
have_backup_ = true;
// It's dangerous to keep an inlined grpc_slice as the backup slice, since
// on a following Next() call, a reference will be returned to this slice
// via GRPC_SLICE_START_PTR, which will not be an adddress held by
// slice_buffer_.
have_backup_ = backup_slice_.refcount != NULL;
byte_count_ -= count;
}
grpc::protobuf::int64 ByteCount() const override { return byte_count_; }
private:
friend class GrpcBufferWriterPeer;
const int block_size_;
int64_t byte_count_;
grpc_slice_buffer* slice_buffer_;

@ -88,6 +88,8 @@ class Server final : public ServerInterface, private GrpcLibraryCodegen {
virtual void PreSynchronousRequest(ServerContext* context) = 0;
/// Called after application callback for each synchronous server request
virtual void PostSynchronousRequest(ServerContext* context) = 0;
/// Called before server is started.
virtual void PreServerStart(Server* server) {}
};
/// Set the global callback object. Can only be called once. Does not take
/// ownership of callbacks, and expects the pointed to object to be alive

@ -179,6 +179,17 @@ typedef struct {
Larger values give lower CPU usage for large messages, but more head of line
blocking for small messages. */
#define GRPC_ARG_HTTP2_MAX_FRAME_SIZE "grpc.http2.max_frame_size"
/** Should BDP probing be performed? */
#define GRPC_ARG_HTTP2_BDP_PROBE "grpc.http2.bdp_probe"
/** Minimum time (in milliseconds) between successive ping frames being sent */
#define GRPC_ARG_HTTP2_MIN_TIME_BETWEEN_PINGS_MS \
"grpc.http2.min_time_between_pings_ms"
/** How many pings can we send before needing to send a data frame or header
frame?
(0 indicates that an infinite number of pings can be sent without sending
a data frame or header frame) */
#define GRPC_ARG_HTTP2_MAX_PINGS_WITHOUT_DATA \
"grpc.http2.max_pings_without_data"
/** How much data are we willing to queue up per stream if
GRPC_WRITE_BUFFER_HINT is set? This is an upper bound */
#define GRPC_ARG_HTTP2_WRITE_BUFFER_SIZE "grpc.http2.write_buffer_size"

@ -268,6 +268,7 @@
<file baseinstalldir="/" name="src/core/lib/surface/lame_client.h" role="src" />
<file baseinstalldir="/" name="src/core/lib/surface/server.h" role="src" />
<file baseinstalldir="/" name="src/core/lib/surface/validate_metadata.h" role="src" />
<file baseinstalldir="/" name="src/core/lib/transport/bdp_estimator.h" role="src" />
<file baseinstalldir="/" name="src/core/lib/transport/byte_stream.h" role="src" />
<file baseinstalldir="/" name="src/core/lib/transport/connectivity_state.h" role="src" />
<file baseinstalldir="/" name="src/core/lib/transport/error_utils.h" role="src" />
@ -313,6 +314,7 @@
<file baseinstalldir="/" name="src/core/lib/security/credentials/plugin/plugin_credentials.h" role="src" />
<file baseinstalldir="/" name="src/core/lib/security/credentials/ssl/ssl_credentials.h" role="src" />
<file baseinstalldir="/" name="src/core/lib/security/transport/auth_filters.h" role="src" />
<file baseinstalldir="/" name="src/core/lib/security/transport/lb_targets_info.h" role="src" />
<file baseinstalldir="/" name="src/core/lib/security/transport/secure_endpoint.h" role="src" />
<file baseinstalldir="/" name="src/core/lib/security/transport/security_connector.h" role="src" />
<file baseinstalldir="/" name="src/core/lib/security/transport/security_handshaker.h" role="src" />
@ -345,6 +347,7 @@
<file baseinstalldir="/" name="src/core/ext/client_channel/uri_parser.h" role="src" />
<file baseinstalldir="/" name="src/core/ext/transport/chttp2/client/chttp2_connector.h" role="src" />
<file baseinstalldir="/" name="src/core/ext/lb_policy/grpclb/grpclb.h" role="src" />
<file baseinstalldir="/" name="src/core/ext/lb_policy/grpclb/grpclb_channel.h" role="src" />
<file baseinstalldir="/" name="src/core/ext/lb_policy/grpclb/load_balancer_api.h" role="src" />
<file baseinstalldir="/" name="src/core/ext/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.h" role="src" />
<file baseinstalldir="/" name="third_party/nanopb/pb.h" role="src" />
@ -366,6 +369,11 @@
<file baseinstalldir="/" name="src/core/ext/census/resource.h" role="src" />
<file baseinstalldir="/" name="src/core/ext/census/rpc_metric_id.h" role="src" />
<file baseinstalldir="/" name="src/core/ext/census/trace_context.h" role="src" />
<file baseinstalldir="/" name="src/core/ext/census/trace_label.h" role="src" />
<file baseinstalldir="/" name="src/core/ext/census/trace_propagation.h" role="src" />
<file baseinstalldir="/" name="src/core/ext/census/trace_status.h" role="src" />
<file baseinstalldir="/" name="src/core/ext/census/trace_string.h" role="src" />
<file baseinstalldir="/" name="src/core/ext/census/tracing.h" role="src" />
<file baseinstalldir="/" name="src/core/lib/surface/init.c" role="src" />
<file baseinstalldir="/" name="src/core/lib/channel/channel_args.c" role="src" />
<file baseinstalldir="/" name="src/core/lib/channel/channel_stack.c" role="src" />
@ -472,6 +480,7 @@
<file baseinstalldir="/" name="src/core/lib/surface/server.c" role="src" />
<file baseinstalldir="/" name="src/core/lib/surface/validate_metadata.c" role="src" />
<file baseinstalldir="/" name="src/core/lib/surface/version.c" role="src" />
<file baseinstalldir="/" name="src/core/lib/transport/bdp_estimator.c" role="src" />
<file baseinstalldir="/" name="src/core/lib/transport/byte_stream.c" role="src" />
<file baseinstalldir="/" name="src/core/lib/transport/connectivity_state.c" role="src" />
<file baseinstalldir="/" name="src/core/lib/transport/error_utils.c" role="src" />
@ -522,6 +531,7 @@
<file baseinstalldir="/" name="src/core/lib/security/credentials/plugin/plugin_credentials.c" role="src" />
<file baseinstalldir="/" name="src/core/lib/security/credentials/ssl/ssl_credentials.c" role="src" />
<file baseinstalldir="/" name="src/core/lib/security/transport/client_auth_filter.c" role="src" />
<file baseinstalldir="/" name="src/core/lib/security/transport/lb_targets_info.c" role="src" />
<file baseinstalldir="/" name="src/core/lib/security/transport/secure_endpoint.c" role="src" />
<file baseinstalldir="/" name="src/core/lib/security/transport/security_connector.c" role="src" />
<file baseinstalldir="/" name="src/core/lib/security/transport/security_handshaker.c" role="src" />
@ -562,6 +572,7 @@
<file baseinstalldir="/" name="src/core/ext/transport/chttp2/client/insecure/channel_create.c" role="src" />
<file baseinstalldir="/" name="src/core/ext/transport/chttp2/client/insecure/channel_create_posix.c" role="src" />
<file baseinstalldir="/" name="src/core/ext/lb_policy/grpclb/grpclb.c" role="src" />
<file baseinstalldir="/" name="src/core/ext/lb_policy/grpclb/grpclb_channel_secure.c" role="src" />
<file baseinstalldir="/" name="src/core/ext/lb_policy/grpclb/load_balancer_api.c" role="src" />
<file baseinstalldir="/" name="src/core/ext/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.c" role="src" />
<file baseinstalldir="/" name="third_party/nanopb/pb_common.c" role="src" />

@ -0,0 +1,61 @@
/*
*
* Copyright 2016, Google Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following disclaimer
* in the documentation and/or other materials provided with the
* distribution.
* * Neither the name of Google Inc. nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#ifndef GRPC_CORE_EXT_CENSUS_TRACE_LABEL_H
#define GRPC_CORE_EXT_CENSUS_TRACE_LABEL_H
#include "src/core/ext/census/trace_string.h"
/* Trace label (key/value pair) stores a label name and the label value. The
value can be one of trace_string/int64_t/bool. */
typedef struct trace_label {
trace_string key;
enum label_type {
/* Unknown value for debugging/error purposes */
LABEL_UNKNOWN = 0,
/* A string value */
LABEL_STRING = 1,
/* An integer value. */
LABEL_INT = 2,
/* A boolean value. */
LABEL_BOOL = 3,
} value_type;
union value {
trace_string label_str;
int64_t label_int;
bool label_bool;
} value;
} trace_label;
#endif

@ -0,0 +1,63 @@
/*
*
* Copyright 2016, Google Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following disclaimer
* in the documentation and/or other materials provided with the
* distribution.
* * Neither the name of Google Inc. nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#ifndef GRPC_CORE_EXT_CENSUS_TRACE_PROPAGATION_H
#define GRPC_CORE_EXT_CENSUS_TRACE_PROPAGATION_H
#include "src/core/ext/census/tracing.h"
/* Encoding and decoding functions for receiving and sending trace contexts
over the wire. Only RPC libraries should be calling these
functions. These functions return the number of bytes encoded/decoded
(0 if a failure has occurred). buf_size indicates the size of the
input/output buffer. trace_span_context is a struct that includes the
trace ID, span ID, and a set of option flags (is_sampled, etc.). */
/* Converts a span context to a binary byte buffer. */
size_t trace_span_context_to_binary(const trace_span_context *ctxt,
uint8_t *buf, size_t buf_size);
/* Reads a binary byte buffer and populates a span context structure. */
size_t binary_to_trace_span_context(const uint8_t *buf, size_t buf_size,
trace_span_context *ctxt);
/* Converts a span context to an http metadata compatible string. */
size_t trace_span_context_to_http_format(const trace_span_context *ctxt,
char *buf, size_t buf_size);
/* Reads an http metadata compatible string and populates a span context
structure. */
size_t http_format_to_trace_span_context(const char *buf, size_t buf_size,
trace_span_context *ctxt);
#endif

@ -0,0 +1,45 @@
/*
*
* Copyright 2016, Google Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following disclaimer
* in the documentation and/or other materials provided with the
* distribution.
* * Neither the name of Google Inc. nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#ifndef GRPC_CORE_EXT_CENSUS_TRACE_STATUS_H
#define GRPC_CORE_EXT_CENSUS_TRACE_STATUS_H
#include "src/core/ext/census/trace_string.h"
/* Stores a status code and status message for a trace. */
typedef struct trace_status {
int64_t errorCode;
trace_string errorMessage;
} trace_status;
#endif

@ -0,0 +1,50 @@
/*
*
* Copyright 2016, Google Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following disclaimer
* in the documentation and/or other materials provided with the
* distribution.
* * Neither the name of Google Inc. nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#ifndef GRPC_CORE_EXT_CENSUS_TRACE_STRING_H
#define GRPC_CORE_EXT_CENSUS_TRACE_STRING_H
#include <grpc/slice.h>
/* String struct for tracing messages. Since this is a C API, we do not have
access to a string class. This is intended for use by higher level
languages which wrap around the C API, as most of them have a string class.
This will also be more efficient when copying, as we have an explicitly
specified length. Also, grpc_slice has reference counting which allows for
interning. */
typedef struct trace_string {
char *string;
size_t length;
} trace_string;
#endif

@ -1,6 +1,6 @@
/*
*
* Copyright 2015, Google Inc.
* Copyright 2016, Google Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -31,21 +31,41 @@
*
*/
//#include "src/core/ext/census/tracing.h"
#include "src/core/ext/census/tracing.h"
#include <grpc/census.h>
#include <stdlib.h>
#include <grpc/support/alloc.h>
#include <grpc/support/log.h>
#include <openssl/rand.h>
#include "src/core/ext/census/mlog.h"
/* TODO(aveitch): These are all placeholder implementations. */
void trace_start_span(const trace_span_context *span_ctxt,
const trace_string name, const start_span_options *opts,
trace_span_context *new_span_ctxt,
bool has_remote_parent) {
// Noop implementation.
}
void trace_add_span_annotation(const trace_string description,
const trace_label *labels, const size_t n_labels,
trace_span_context *span_ctxt) {
// Noop implementation.
}
int census_trace_mask(const census_context *context) {
abort();
return CENSUS_TRACE_MASK_NONE;
void trace_add_span_network_event_annotation(const trace_string description,
const trace_label *labels,
const size_t n_labels,
const gpr_timespec timestamp,
bool sent, uint64_t id,
trace_span_context *span_ctxt) {
// Noop implementation.
}
void census_set_trace_mask(int trace_mask) { abort(); }
void trace_add_span_labels(const trace_label *labels, const size_t n_labels,
trace_span_context *span_ctxt) {
// Noop implementation.
}
void census_trace_print(census_context *context, uint32_t type,
const char *buffer, size_t n) {
abort();
void trace_end_span(const trace_status *status, trace_span_context *span_ctxt) {
// Noop implementation.
}

@ -0,0 +1,124 @@
/*
*
* Copyright 2016, Google Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following disclaimer
* in the documentation and/or other materials provided with the
* distribution.
* * Neither the name of Google Inc. nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#ifndef GRPC_CORE_EXT_CENSUS_TRACING_H
#define GRPC_CORE_EXT_CENSUS_TRACING_H
#include <grpc/support/time.h>
#include <stdbool.h>
#include "src/core/ext/census/trace_context.h"
#include "src/core/ext/census/trace_label.h"
#include "src/core/ext/census/trace_status.h"
/* This is the low level tracing API that other languages will interface with.
This is not intended to be accessed by the end-user, therefore it has been
designed with performance in mind rather than ease of use. */
/* The tracing level. */
enum TraceLevel {
/* Annotations on this context will be silently discarded. */
NO_TRACING = 0,
/* Annotations will not be saved to a persistent store. They will be
available via local APIs only. This setting is not propagated to child
spans. */
TRANSIENT_TRACING = 1,
/* Annotations are recorded for the entire distributed trace and they are
saved to a persistent store. This setting is propagated to child spans. */
PERSISTENT_TRACING = 2,
};
typedef struct trace_span_context {
/* Trace span context stores Span ID, Trace ID, and option flags. */
/* Trace ID is 128 bits split into 2 64-bit chunks (hi and lo). */
uint64_t trace_id_hi;
uint64_t trace_id_lo;
/* Span ID is 64 bits. */
uint64_t span_id;
/* Span-options is 32-bit value which contains flag options. */
uint32_t span_options;
} trace_span_context;
typedef struct start_span_options {
/* If set, this will override the Span.local_start_time for the Span. */
gpr_timespec local_start_timestamp;
/* Linked spans can be used to identify spans that are linked to this span in
a different trace. This can be used (for example) in batching operations,
where a single batch handler processes multiple requests from different
traces. If set, points to a list of Spans are linked to the created Span.*/
trace_span_context *linked_spans;
/* The number of linked spans. */
size_t n_linked_spans;
} start_span_options;
/* Create a new child Span (or root if parent is NULL), with parent being the
designated Span. The child span will have the provided name and starting
span options (optional). The bool has_remote_parent marks whether the
context refers to a remote parent span or not. */
void trace_start_span(const trace_span_context *span_ctxt,
const trace_string name, const start_span_options *opts,
trace_span_context *new_span_ctxt,
bool has_remote_parent);
/* Add a new Annotation to the Span. Annotations consist of a description
(trace_string) and a set of n labels (trace_label). This can be populated
with arbitrary user data. */
void trace_add_span_annotation(const trace_string description,
const trace_label *labels, const size_t n_labels,
trace_span_context *span_ctxt);
/* Add a new NetworkEvent annotation to a Span. This function is only intended
to be used by RPC systems (either client or server), not by higher level
applications. The timestamp type will be system-defined, the sent argument
designates whether this is a network send event (client request, server
reply)or receive (server request, client reply). The id argument corresponds
to Span.Annotation.NetworkEvent.id from the data model, and serves to uniquely
identify each network message. */
void trace_add_span_network_event(const trace_string description,
const trace_label *labels,
const size_t n_labels,
const gpr_timespec timestamp, bool sent,
uint64_t id, trace_span_context *span_ctxt);
/* Add a set of labels to the Span. These will correspond to the field
Span.labels in the data model. */
void trace_add_span_labels(const trace_label *labels, const size_t n_labels,
trace_span_context *span_ctxt);
/* Mark the end of Span Execution with the given status. Only the timing of the
first EndSpan call for a given Span will be recorded, and implementations are
free to ignore all further calls using the Span. EndSpanOptions can
optionally be NULL. */
void trace_end_span(const trace_status *status, trace_span_context *span_ctxt);
#endif

@ -546,10 +546,18 @@ static grpc_error *cc_init_channel_elem(grpc_exec_ctx *exec_ctx,
arg = grpc_channel_args_find(args->channel_args, GRPC_ARG_SERVER_URI);
GPR_ASSERT(arg != NULL);
GPR_ASSERT(arg->type == GRPC_ARG_STRING);
chand->server_name = gpr_strdup(arg->value.string);
grpc_uri *uri = grpc_uri_parse(arg->value.string, true);
if (uri == NULL) return GRPC_ERROR_CREATE("cannot parse server URI");
if (uri->path[0] == '\0') {
grpc_uri_destroy(uri);
return GRPC_ERROR_CREATE("server URI is missing path");
}
chand->server_name =
gpr_strdup(uri->path[0] == '/' ? uri->path + 1 : uri->path);
grpc_uri_destroy(uri);
chand->proxy_name = grpc_get_http_proxy_server();
char *name_to_resolve =
chand->proxy_name == NULL ? chand->server_name : chand->proxy_name;
chand->proxy_name == NULL ? arg->value.string : chand->proxy_name;
chand->resolver = grpc_resolver_create(
exec_ctx, name_to_resolve, args->channel_args, chand->interested_parties);
if (chand->resolver == NULL) {
@ -644,6 +652,12 @@ typedef struct client_channel_call_data {
grpc_linked_mdelem lb_token_mdelem;
} call_data;
grpc_subchannel_call *grpc_client_channel_get_subchannel_call(
grpc_call_element *call_elem) {
grpc_subchannel_call *scc = GET_CALL((call_data *)call_elem->call_data);
return scc == CANCELLED_CALL ? NULL : scc;
}
static void add_waiting_locked(call_data *calld, grpc_transport_stream_op *op) {
GPR_TIMER_BEGIN("add_waiting_locked", 0);
if (calld->waiting_ops_count == calld->waiting_ops_capacity) {

@ -57,4 +57,8 @@ void grpc_client_channel_watch_connectivity_state(
grpc_exec_ctx *exec_ctx, grpc_channel_element *elem, grpc_pollset *pollset,
grpc_connectivity_state *state, grpc_closure *on_complete);
/* Debug helper: pull the subchannel call from a call stack element */
grpc_subchannel_call *grpc_client_channel_get_subchannel_call(
grpc_call_element *elem);
#endif /* GRPC_CORE_EXT_CLIENT_CHANNEL_CLIENT_CHANNEL_H */

@ -788,7 +788,8 @@ grpc_call_stack *grpc_subchannel_call_get_call_stack(
return SUBCHANNEL_CALL_TO_CALL_STACK(subchannel_call);
}
static void grpc_uri_to_sockaddr(char *uri_str, grpc_resolved_address *addr) {
static void grpc_uri_to_sockaddr(const char *uri_str,
grpc_resolved_address *addr) {
grpc_uri *uri = grpc_uri_parse(uri_str, 0 /* suppress_errors */);
GPR_ASSERT(uri != NULL);
if (strcmp(uri->scheme, "ipv4") == 0) {
@ -803,14 +804,19 @@ static void grpc_uri_to_sockaddr(char *uri_str, grpc_resolved_address *addr) {
void grpc_get_subchannel_address_arg(const grpc_channel_args *args,
grpc_resolved_address *addr) {
const char *addr_uri_str = grpc_get_subchannel_address_uri_arg(args);
memset(addr, 0, sizeof(*addr));
if (*addr_uri_str != '\0') {
grpc_uri_to_sockaddr(addr_uri_str, addr);
}
}
const char *grpc_get_subchannel_address_uri_arg(const grpc_channel_args *args) {
const grpc_arg *addr_arg =
grpc_channel_args_find(args, GRPC_ARG_SUBCHANNEL_ADDRESS);
GPR_ASSERT(addr_arg != NULL); // Should have been set by LB policy.
GPR_ASSERT(addr_arg->type == GRPC_ARG_STRING);
memset(addr, 0, sizeof(*addr));
if (*addr_arg->value.string != '\0') {
grpc_uri_to_sockaddr(addr_arg->value.string, addr);
}
return addr_arg->value.string;
}
grpc_arg grpc_create_subchannel_address_arg(const grpc_resolved_address *addr) {

@ -178,6 +178,9 @@ grpc_subchannel *grpc_subchannel_create(grpc_exec_ctx *exec_ctx,
void grpc_get_subchannel_address_arg(const grpc_channel_args *args,
grpc_resolved_address *addr);
/// Returns the URI string for the address to connect to.
const char *grpc_get_subchannel_address_uri_arg(const grpc_channel_args *args);
/// Returns a new channel arg encoding the subchannel address as a string.
/// Caller is responsible for freeing the string.
grpc_arg grpc_create_subchannel_address_arg(const grpc_resolved_address *addr);

@ -112,11 +112,13 @@
#include "src/core/ext/client_channel/lb_policy_registry.h"
#include "src/core/ext/client_channel/parse_address.h"
#include "src/core/ext/lb_policy/grpclb/grpclb.h"
#include "src/core/ext/lb_policy/grpclb/grpclb_channel.h"
#include "src/core/ext/lb_policy/grpclb/load_balancer_api.h"
#include "src/core/lib/channel/channel_args.h"
#include "src/core/lib/iomgr/sockaddr.h"
#include "src/core/lib/iomgr/sockaddr_utils.h"
#include "src/core/lib/iomgr/timer.h"
#include "src/core/lib/slice/slice_hash_table.h"
#include "src/core/lib/slice/slice_internal.h"
#include "src/core/lib/slice/slice_string_helpers.h"
#include "src/core/lib/support/backoff.h"
@ -751,6 +753,96 @@ static void glb_rr_connectivity_changed(grpc_exec_ctx *exec_ctx, void *arg,
GRPC_ERROR_UNREF(error);
}
static void destroy_balancer_name(grpc_exec_ctx *exec_ctx,
void *balancer_name) {
gpr_free(balancer_name);
}
static void *copy_balancer_name(void *balancer_name) {
return gpr_strdup(balancer_name);
}
static grpc_slice_hash_table_entry targets_info_entry_create(
const char *address, const char *balancer_name) {
static const grpc_slice_hash_table_vtable vtable = {destroy_balancer_name,
copy_balancer_name};
grpc_slice_hash_table_entry entry;
entry.key = grpc_slice_from_copied_string(address);
entry.value = (void *)balancer_name;
entry.vtable = &vtable;
return entry;
}
/* Returns the target URI for the LB service whose addresses are in \a
* addresses. Using this URI, a bidirectional streaming channel will be created
* for the reception of load balancing updates.
*
* The output argument \a targets_info will be updated to contain a mapping of
* "LB server address" to "balancer name", as reported by the naming system.
* This mapping will be propagated via the channel arguments of the
* aforementioned LB streaming channel, to be used by the security connector for
* secure naming checks. The user is responsible for freeing \a targets_info. */
static char *get_lb_uri_target_addresses(grpc_exec_ctx *exec_ctx,
const grpc_lb_addresses *addresses,
grpc_slice_hash_table **targets_info) {
size_t num_grpclb_addrs = 0;
for (size_t i = 0; i < addresses->num_addresses; ++i) {
if (addresses->addresses[i].is_balancer) ++num_grpclb_addrs;
}
/* All input addresses come from a resolver that claims they are LB services.
* It's the resolver's responsibility to make sure this policy is only
* instantiated and used in that case. Otherwise, something has gone wrong. */
GPR_ASSERT(num_grpclb_addrs > 0);
grpc_slice_hash_table_entry *targets_info_entries =
gpr_malloc(sizeof(*targets_info_entries) * num_grpclb_addrs);
/* construct a target ipvX://ip1:port1,ip2:port2,... from the addresses in \a
* addresses */
/* TODO(dgq): support mixed ip version */
char **addr_strs = gpr_malloc(sizeof(char *) * num_grpclb_addrs);
size_t addr_index = 0;
for (size_t i = 0; i < addresses->num_addresses; i++) {
if (addresses->addresses[i].user_data != NULL) {
gpr_log(GPR_ERROR,
"This LB policy doesn't support user data. It will be ignored");
}
if (addresses->addresses[i].is_balancer) {
char *addr_str;
GPR_ASSERT(grpc_sockaddr_to_string(
&addr_str, &addresses->addresses[i].address, true) > 0);
targets_info_entries[addr_index] = targets_info_entry_create(
addr_str, addresses->addresses[i].balancer_name);
addr_strs[addr_index++] = addr_str;
}
}
GPR_ASSERT(addr_index == num_grpclb_addrs);
size_t uri_path_len;
char *uri_path = gpr_strjoin_sep((const char **)addr_strs, num_grpclb_addrs,
",", &uri_path_len);
for (size_t i = 0; i < num_grpclb_addrs; i++) gpr_free(addr_strs[i]);
gpr_free(addr_strs);
char *target_uri_str = NULL;
/* TODO(dgq): Don't assume all addresses will share the scheme of the first
* one */
gpr_asprintf(&target_uri_str, "%s:%s",
grpc_sockaddr_get_uri_scheme(&addresses->addresses[0].address),
uri_path);
gpr_free(uri_path);
*targets_info =
grpc_slice_hash_table_create(num_grpclb_addrs, targets_info_entries);
for (size_t i = 0; i < num_grpclb_addrs; i++) {
grpc_slice_unref_internal(exec_ctx, targets_info_entries[i].key);
}
gpr_free(targets_info_entries);
return target_uri_str;
}
static grpc_lb_policy *glb_create(grpc_exec_ctx *exec_ctx,
grpc_lb_policy_factory *factory,
grpc_lb_policy_args *args) {
@ -788,85 +880,30 @@ static grpc_lb_policy *glb_create(grpc_exec_ctx *exec_ctx,
}
grpc_uri_destroy(uri);
/* All input addresses in addresses come from a resolver that claims
* they are LB services. It's the resolver's responsibility to make sure
* this policy is only instantiated and used in that case.
*
* Create a client channel over them to communicate with a LB service */
glb_policy->cc_factory = args->client_channel_factory;
glb_policy->args = grpc_channel_args_copy(args->args);
GPR_ASSERT(glb_policy->cc_factory != NULL);
/* construct a target from the addresses in args, given in the form
* ipvX://ip1:port1,ip2:port2,...
* TODO(dgq): support mixed ip version */
char **addr_strs = gpr_malloc(sizeof(char *) * num_grpclb_addrs);
size_t addr_index = 0;
for (size_t i = 0; i < addresses->num_addresses; i++) {
if (addresses->addresses[i].user_data != NULL) {
gpr_log(GPR_ERROR,
"This LB policy doesn't support user data. It will be ignored");
}
if (addresses->addresses[i].is_balancer) {
if (addr_index == 0) {
addr_strs[addr_index++] =
grpc_sockaddr_to_uri(&addresses->addresses[i].address);
} else {
GPR_ASSERT(grpc_sockaddr_to_string(&addr_strs[addr_index++],
&addresses->addresses[i].address,
true) > 0);
}
}
}
size_t uri_path_len;
char *target_uri_str = gpr_strjoin_sep((const char **)addr_strs,
num_grpclb_addrs, ",", &uri_path_len);
/* Create a channel to talk to the LBs.
*
* We strip out the channel arg for the LB policy name, since we want
* to use the default (pick_first) in this case.
*
* We also strip out the channel arg for the resolved addresses, since
* that will be generated by the name resolver used in the LB channel.
* Note that the LB channel will use the sockaddr resolver, so this
* won't actually generate a query to DNS (or some other name service).
* However, the addresses returned by the sockaddr resolver will have
* is_balancer=false, whereas our own addresses have is_balancer=true.
* We need the LB channel to return addresses with is_balancer=false
* so that it does not wind up recursively using the grpclb LB policy,
* as per the special case logic in client_channel.c.
*
* Finally, we also strip out the channel arg for the server URI,
* since that will be different for the LB channel than for the parent
* channel. (The client channel factory will re-add this arg with
* the right value.)
*/
static const char *keys_to_remove[] = {
GRPC_ARG_LB_POLICY_NAME, GRPC_ARG_LB_ADDRESSES, GRPC_ARG_SERVER_URI};
grpc_channel_args *new_args = grpc_channel_args_copy_and_remove(
args->args, keys_to_remove, GPR_ARRAY_SIZE(keys_to_remove));
glb_policy->lb_channel = grpc_client_channel_factory_create_channel(
exec_ctx, glb_policy->cc_factory, target_uri_str,
GRPC_CLIENT_CHANNEL_TYPE_LOAD_BALANCING, new_args);
grpc_channel_args_destroy(exec_ctx, new_args);
gpr_free(target_uri_str);
for (size_t i = 0; i < num_grpclb_addrs; i++) {
gpr_free(addr_strs[i]);
}
gpr_free(addr_strs);
grpc_slice_hash_table *targets_info = NULL;
/* Create a client channel over them to communicate with a LB service */
char *lb_service_target_addresses =
get_lb_uri_target_addresses(exec_ctx, addresses, &targets_info);
grpc_channel_args *lb_channel_args =
get_lb_channel_args(exec_ctx, targets_info, args->args);
glb_policy->lb_channel = grpc_lb_policy_grpclb_create_lb_channel(
exec_ctx, lb_service_target_addresses, args->client_channel_factory,
lb_channel_args);
grpc_slice_hash_table_unref(exec_ctx, targets_info);
grpc_channel_args_destroy(exec_ctx, lb_channel_args);
gpr_free(lb_service_target_addresses);
if (glb_policy->lb_channel == NULL) {
gpr_free(glb_policy);
return NULL;
}
grpc_lb_policy_init(&glb_policy->base, &glb_lb_policy_vtable);
gpr_mu_init(&glb_policy->mu);
grpc_connectivity_state_init(&glb_policy->state_tracker, GRPC_CHANNEL_IDLE,
"grpclb");
return &glb_policy->base;
}

@ -0,0 +1,77 @@
/*
*
* Copyright 2017, Google Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following disclaimer
* in the documentation and/or other materials provided with the
* distribution.
* * Neither the name of Google Inc. nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#include <grpc/support/alloc.h>
#include <grpc/support/string_util.h>
#include "src/core/ext/client_channel/client_channel.h"
#include "src/core/ext/lb_policy/grpclb/grpclb_channel.h"
#include "src/core/lib/channel/channel_args.h"
#include "src/core/lib/iomgr/sockaddr_utils.h"
#include "src/core/lib/support/string.h"
grpc_channel *grpc_lb_policy_grpclb_create_lb_channel(
grpc_exec_ctx *exec_ctx, const char *lb_service_target_addresses,
grpc_client_channel_factory *client_channel_factory,
grpc_channel_args *args) {
grpc_channel *lb_channel = grpc_client_channel_factory_create_channel(
exec_ctx, client_channel_factory, lb_service_target_addresses,
GRPC_CLIENT_CHANNEL_TYPE_LOAD_BALANCING, args);
return lb_channel;
}
grpc_channel_args *get_lb_channel_args(grpc_exec_ctx *exec_ctx,
grpc_slice_hash_table *targets_info,
const grpc_channel_args *args) {
/* We strip out the channel arg for the LB policy name, since we want
* to use the default (pick_first) in this case.
*
* We also strip out the channel arg for the resolved addresses, since
* that will be generated by the name resolver used in the LB channel.
* Note that the LB channel will use the sockaddr resolver, so this
* won't actually generate a query to DNS (or some other name service).
* However, the addresses returned by the sockaddr resolver will have
* is_balancer=false, whereas our own addresses have is_balancer=true.
* We need the LB channel to return addresses with is_balancer=false
* so that it does not wind up recursively using the grpclb LB policy,
* as per the special case logic in client_channel.c.
*
* Lastly, we also strip out the channel arg for the server URI,
* since that will be different for the LB channel than for the parent
* channel (the client channel factory will re-add this arg with
* the right value). */
static const char *keys_to_remove[] = {
GRPC_ARG_LB_POLICY_NAME, GRPC_ARG_LB_ADDRESSES, GRPC_ARG_SERVER_URI};
return grpc_channel_args_copy_and_remove(args, keys_to_remove,
GPR_ARRAY_SIZE(keys_to_remove));
}

@ -0,0 +1,56 @@
/*
*
* Copyright 2017, Google Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following disclaimer
* in the documentation and/or other materials provided with the
* distribution.
* * Neither the name of Google Inc. nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#ifndef GRPC_CORE_EXT_LB_POLICY_GRPCLB_GRPCLB_CHANNEL_H
#define GRPC_CORE_EXT_LB_POLICY_GRPCLB_GRPCLB_CHANNEL_H
#include "src/core/ext/client_channel/lb_policy_factory.h"
#include "src/core/lib/slice/slice_hash_table.h"
/** Create the channel used for communicating with an LB service.
* Note that an LB *service* may be comprised of several LB *servers*.
*
* \a lb_service_target_addresses is the target URI containing the addresses
* from resolving the LB service's name (eg, ipv4:10.0.0.1:1234,10.2.3.4:9876).
* \a client_channel_factory will be used for the creation of the LB channel,
* alongside the channel args passed in \a args. */
grpc_channel *grpc_lb_policy_grpclb_create_lb_channel(
grpc_exec_ctx *exec_ctx, const char *lb_service_target_addresses,
grpc_client_channel_factory *client_channel_factory,
grpc_channel_args *args);
grpc_channel_args *get_lb_channel_args(grpc_exec_ctx *exec_ctx,
grpc_slice_hash_table *targets_info,
const grpc_channel_args *args);
#endif /* GRPC_CORE_EXT_LB_POLICY_GRPCLB_GRPCLB_CHANNEL_H */

@ -0,0 +1,107 @@
/*
*
* Copyright 2017, Google Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following disclaimer
* in the documentation and/or other materials provided with the
* distribution.
* * Neither the name of Google Inc. nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#include <grpc/support/alloc.h>
#include <grpc/support/string_util.h>
#include "src/core/ext/client_channel/client_channel.h"
#include "src/core/ext/lb_policy/grpclb/grpclb_channel.h"
#include "src/core/lib/channel/channel_args.h"
#include "src/core/lib/iomgr/sockaddr_utils.h"
#include "src/core/lib/security/credentials/credentials.h"
#include "src/core/lib/security/transport/lb_targets_info.h"
#include "src/core/lib/slice/slice_internal.h"
#include "src/core/lib/support/string.h"
grpc_channel *grpc_lb_policy_grpclb_create_lb_channel(
grpc_exec_ctx *exec_ctx, const char *lb_service_target_addresses,
grpc_client_channel_factory *client_channel_factory,
grpc_channel_args *args) {
grpc_channel_args *new_args = args;
grpc_channel_credentials *channel_credentials =
grpc_channel_credentials_find_in_args(args);
if (channel_credentials != NULL) {
/* Substitute the channel credentials with a version without call
* credentials: the load balancer is not necessarily trusted to handle
* bearer token credentials */
static const char *keys_to_remove[] = {GRPC_ARG_CHANNEL_CREDENTIALS};
grpc_channel_credentials *creds_sans_call_creds =
grpc_channel_credentials_duplicate_without_call_credentials(
channel_credentials);
GPR_ASSERT(creds_sans_call_creds != NULL);
grpc_arg args_to_add[] = {
grpc_channel_credentials_to_arg(creds_sans_call_creds)};
/* Create the new set of channel args */
new_args = grpc_channel_args_copy_and_add_and_remove(
args, keys_to_remove, GPR_ARRAY_SIZE(keys_to_remove), args_to_add,
GPR_ARRAY_SIZE(args_to_add));
grpc_channel_credentials_unref(exec_ctx, creds_sans_call_creds);
}
grpc_channel *lb_channel = grpc_client_channel_factory_create_channel(
exec_ctx, client_channel_factory, lb_service_target_addresses,
GRPC_CLIENT_CHANNEL_TYPE_LOAD_BALANCING, new_args);
if (channel_credentials != NULL) {
grpc_channel_args_destroy(exec_ctx, new_args);
}
return lb_channel;
}
grpc_channel_args *get_lb_channel_args(grpc_exec_ctx *exec_ctx,
grpc_slice_hash_table *targets_info,
const grpc_channel_args *args) {
const grpc_arg targets_info_arg =
grpc_lb_targets_info_create_channel_arg(targets_info);
/* We strip out the channel arg for the LB policy name, since we want
* to use the default (pick_first) in this case.
*
* We also strip out the channel arg for the resolved addresses, since
* that will be generated by the name resolver used in the LB channel.
* Note that the LB channel will use the sockaddr resolver, so this
* won't actually generate a query to DNS (or some other name service).
* However, the addresses returned by the sockaddr resolver will have
* is_balancer=false, whereas our own addresses have is_balancer=true.
* We need the LB channel to return addresses with is_balancer=false
* so that it does not wind up recursively using the grpclb LB policy,
* as per the special case logic in client_channel.c.
*
* Lastly, we also strip out the channel arg for the server URI,
* since that will be different for the LB channel than for the parent
* channel (the client channel factory will re-add this arg with
* the right value). */
static const char *keys_to_remove[] = {
GRPC_ARG_LB_POLICY_NAME, GRPC_ARG_LB_ADDRESSES, GRPC_ARG_SERVER_URI};
/* Add the targets info table to be used for secure naming */
return grpc_channel_args_copy_and_add_and_remove(
args, keys_to_remove, GPR_ARRAY_SIZE(keys_to_remove), &targets_info_arg,
1);
}

@ -739,6 +739,13 @@ static grpc_lb_policy *round_robin_create(grpc_exec_ctx *exec_ctx,
sc_args.args = new_args;
grpc_subchannel *subchannel = grpc_client_channel_factory_create_subchannel(
exec_ctx, args->client_channel_factory, &sc_args);
if (grpc_lb_round_robin_trace) {
char *address_uri =
grpc_sockaddr_to_uri(&addresses->addresses[i].address);
gpr_log(GPR_DEBUG, "Created subchannel %p for address uri %s",
(void *)subchannel, address_uri);
gpr_free(address_uri);
}
grpc_channel_args_destroy(exec_ctx, new_args);
if (subchannel != NULL) {

@ -39,6 +39,7 @@
#include <grpc/support/string_util.h>
#include "src/core/ext/client_channel/client_channel.h"
#include "src/core/ext/client_channel/resolver_registry.h"
#include "src/core/ext/transport/chttp2/client/chttp2_connector.h"
#include "src/core/lib/channel/channel_args.h"
#include "src/core/lib/surface/api_trace.h"
@ -63,12 +64,17 @@ static grpc_channel *client_channel_factory_create_channel(
grpc_exec_ctx *exec_ctx, grpc_client_channel_factory *cc_factory,
const char *target, grpc_client_channel_type type,
const grpc_channel_args *args) {
if (target == NULL) {
gpr_log(GPR_ERROR, "cannot create channel with NULL target name");
return NULL;
}
// Add channel arg containing the server URI.
grpc_arg arg;
arg.type = GRPC_ARG_STRING;
arg.key = GRPC_ARG_SERVER_URI;
arg.value.string = (char *)target;
arg.value.string = grpc_resolver_factory_add_default_prefix_if_needed(target);
grpc_channel_args *new_args = grpc_channel_args_copy_and_add(args, &arg, 1);
gpr_free(arg.value.string);
grpc_channel *channel = grpc_channel_create(exec_ctx, target, new_args,
GRPC_CLIENT_CHANNEL, NULL);
grpc_channel_args_destroy(exec_ctx, new_args);

@ -39,10 +39,16 @@
#include <grpc/support/string_util.h>
#include "src/core/ext/client_channel/client_channel.h"
#include "src/core/ext/client_channel/resolver_registry.h"
#include "src/core/ext/client_channel/uri_parser.h"
#include "src/core/ext/transport/chttp2/client/chttp2_connector.h"
#include "src/core/lib/channel/channel_args.h"
#include "src/core/lib/iomgr/sockaddr_utils.h"
#include "src/core/lib/security/credentials/credentials.h"
#include "src/core/lib/security/transport/lb_targets_info.h"
#include "src/core/lib/security/transport/security_connector.h"
#include "src/core/lib/slice/slice_hash_table.h"
#include "src/core/lib/slice/slice_internal.h"
#include "src/core/lib/surface/api_trace.h"
#include "src/core/lib/surface/channel.h"
@ -52,12 +58,114 @@ static void client_channel_factory_ref(
static void client_channel_factory_unref(
grpc_exec_ctx *exec_ctx, grpc_client_channel_factory *cc_factory) {}
static grpc_subchannel_args *get_secure_naming_subchannel_args(
grpc_exec_ctx *exec_ctx, const grpc_subchannel_args *args) {
grpc_channel_credentials *channel_credentials =
grpc_channel_credentials_find_in_args(args->args);
if (channel_credentials == NULL) {
gpr_log(GPR_ERROR,
"Can't create subchannel: channel credentials missing for secure "
"channel.");
return NULL;
}
// Make sure security connector does not already exist in args.
if (grpc_security_connector_find_in_args(args->args) != NULL) {
gpr_log(GPR_ERROR,
"Can't create subchannel: security connector already present in "
"channel args.");
return NULL;
}
// To which address are we connecting? By default, use the server URI.
const grpc_arg *server_uri_arg =
grpc_channel_args_find(args->args, GRPC_ARG_SERVER_URI);
GPR_ASSERT(server_uri_arg != NULL);
GPR_ASSERT(server_uri_arg->type == GRPC_ARG_STRING);
const char *server_uri_str = server_uri_arg->value.string;
GPR_ASSERT(server_uri_str != NULL);
grpc_uri *server_uri =
grpc_uri_parse(server_uri_str, true /* supress errors */);
GPR_ASSERT(server_uri != NULL);
const char *server_uri_path;
server_uri_path =
server_uri->path[0] == '/' ? server_uri->path + 1 : server_uri->path;
const grpc_slice_hash_table *targets_info =
grpc_lb_targets_info_find_in_args(args->args);
char *target_name_to_check = NULL;
if (targets_info != NULL) { // LB channel
// Find the balancer name for the target.
const char *target_uri_str =
grpc_get_subchannel_address_uri_arg(args->args);
grpc_uri *target_uri =
grpc_uri_parse(target_uri_str, false /* suppress errors */);
GPR_ASSERT(target_uri != NULL);
if (target_uri->path[0] != '\0') { // "path" may be empty
const grpc_slice key = grpc_slice_from_static_string(
target_uri->path[0] == '/' ? target_uri->path + 1 : target_uri->path);
const char *value = grpc_slice_hash_table_get(targets_info, key);
if (value != NULL) target_name_to_check = gpr_strdup(value);
grpc_slice_unref_internal(exec_ctx, key);
}
if (target_name_to_check == NULL) {
// If the target name to check hasn't already been set, fall back to using
// SERVER_URI
target_name_to_check = gpr_strdup(server_uri_path);
}
grpc_uri_destroy(target_uri);
} else { // regular channel: the secure name is the original server URI.
target_name_to_check = gpr_strdup(server_uri_path);
}
grpc_uri_destroy(server_uri);
GPR_ASSERT(target_name_to_check != NULL);
grpc_channel_security_connector *subchannel_security_connector = NULL;
// Create the security connector using the credentials and target name.
grpc_channel_args *new_args_from_connector = NULL;
const grpc_security_status security_status =
grpc_channel_credentials_create_security_connector(
exec_ctx, channel_credentials, target_name_to_check, args->args,
&subchannel_security_connector, &new_args_from_connector);
if (security_status != GRPC_SECURITY_OK) {
gpr_log(GPR_ERROR,
"Failed to create secure subchannel for secure name '%s'",
target_name_to_check);
gpr_free(target_name_to_check);
return NULL;
}
gpr_free(target_name_to_check);
grpc_arg new_security_connector_arg =
grpc_security_connector_to_arg(&subchannel_security_connector->base);
grpc_channel_args *new_args = grpc_channel_args_copy_and_add(
new_args_from_connector != NULL ? new_args_from_connector : args->args,
&new_security_connector_arg, 1);
GRPC_SECURITY_CONNECTOR_UNREF(exec_ctx, &subchannel_security_connector->base,
"lb_channel_create");
if (new_args_from_connector != NULL) {
grpc_channel_args_destroy(exec_ctx, new_args_from_connector);
}
grpc_subchannel_args *final_sc_args = gpr_malloc(sizeof(*final_sc_args));
memcpy(final_sc_args, args, sizeof(*args));
final_sc_args->args = new_args;
return final_sc_args;
}
static grpc_subchannel *client_channel_factory_create_subchannel(
grpc_exec_ctx *exec_ctx, grpc_client_channel_factory *cc_factory,
const grpc_subchannel_args *args) {
grpc_subchannel_args *subchannel_args =
get_secure_naming_subchannel_args(exec_ctx, args);
if (subchannel_args == NULL) {
gpr_log(
GPR_ERROR,
"Failed to create subchannel arguments during subchannel creation.");
return NULL;
}
grpc_connector *connector = grpc_chttp2_connector_create();
grpc_subchannel *s = grpc_subchannel_create(exec_ctx, connector, args);
grpc_subchannel *s =
grpc_subchannel_create(exec_ctx, connector, subchannel_args);
grpc_connector_unref(exec_ctx, connector);
grpc_channel_args_destroy(exec_ctx,
(grpc_channel_args *)subchannel_args->args);
gpr_free(subchannel_args);
return s;
}
@ -65,12 +173,17 @@ static grpc_channel *client_channel_factory_create_channel(
grpc_exec_ctx *exec_ctx, grpc_client_channel_factory *cc_factory,
const char *target, grpc_client_channel_type type,
const grpc_channel_args *args) {
if (target == NULL) {
gpr_log(GPR_ERROR, "cannot create channel with NULL target name");
return NULL;
}
// Add channel arg containing the server URI.
grpc_arg arg;
arg.type = GRPC_ARG_STRING;
arg.key = GRPC_ARG_SERVER_URI;
arg.value.string = (char *)target;
arg.value.string = grpc_resolver_factory_add_default_prefix_if_needed(target);
grpc_channel_args *new_args = grpc_channel_args_copy_and_add(args, &arg, 1);
gpr_free(arg.value.string);
grpc_channel *channel = grpc_channel_create(exec_ctx, target, new_args,
GRPC_CLIENT_CHANNEL, NULL);
grpc_channel_args_destroy(exec_ctx, new_args);
@ -85,10 +198,10 @@ static const grpc_client_channel_factory_vtable client_channel_factory_vtable =
static grpc_client_channel_factory client_channel_factory = {
&client_channel_factory_vtable};
/* Create a secure client channel:
Asynchronously: - resolve target
- connect to it (trying alternatives as presented)
- perform handshakes */
// Create a secure client channel:
// Asynchronously: - resolve target
// - connect to it (trying alternatives as presented)
// - perform handshakes
grpc_channel *grpc_secure_channel_create(grpc_channel_credentials *creds,
const char *target,
const grpc_channel_args *args,
@ -97,46 +210,27 @@ grpc_channel *grpc_secure_channel_create(grpc_channel_credentials *creds,
GRPC_API_TRACE(
"grpc_secure_channel_create(creds=%p, target=%s, args=%p, "
"reserved=%p)",
4, (creds, target, args, reserved));
4, ((void *)creds, target, (void *)args, (void *)reserved));
GPR_ASSERT(reserved == NULL);
// Make sure security connector does not already exist in args.
if (grpc_find_security_connector_in_args(args) != NULL) {
gpr_log(GPR_ERROR, "Cannot set security context in channel args.");
grpc_channel *channel = NULL;
if (creds != NULL) {
// Add channel args containing the client channel factory and channel
// credentials.
grpc_arg args_to_add[] = {
grpc_client_channel_factory_create_channel_arg(&client_channel_factory),
grpc_channel_credentials_to_arg(creds)};
grpc_channel_args *new_args = grpc_channel_args_copy_and_add(
args, args_to_add, GPR_ARRAY_SIZE(args_to_add));
// Create channel.
channel = client_channel_factory_create_channel(
&exec_ctx, &client_channel_factory, target,
GRPC_CLIENT_CHANNEL_TYPE_REGULAR, new_args);
// Clean up.
grpc_channel_args_destroy(&exec_ctx, new_args);
grpc_exec_ctx_finish(&exec_ctx);
return grpc_lame_client_channel_create(
target, GRPC_STATUS_INTERNAL,
"Security connector exists in channel args.");
}
// Create security connector and construct new channel args.
grpc_channel_security_connector *security_connector;
grpc_channel_args *new_args_from_connector;
if (grpc_channel_credentials_create_security_connector(
&exec_ctx, creds, target, args, &security_connector,
&new_args_from_connector) != GRPC_SECURITY_OK) {
grpc_exec_ctx_finish(&exec_ctx);
return grpc_lame_client_channel_create(
target, GRPC_STATUS_INTERNAL, "Failed to create security connector.");
}
// Add channel args containing the client channel factory and security
// connector.
grpc_arg args_to_add[2];
args_to_add[0] =
grpc_client_channel_factory_create_channel_arg(&client_channel_factory);
args_to_add[1] = grpc_security_connector_to_arg(&security_connector->base);
grpc_channel_args *new_args = grpc_channel_args_copy_and_add(
new_args_from_connector != NULL ? new_args_from_connector : args,
args_to_add, GPR_ARRAY_SIZE(args_to_add));
if (new_args_from_connector != NULL) {
grpc_channel_args_destroy(&exec_ctx, new_args_from_connector);
}
// Create channel.
grpc_channel *channel = client_channel_factory_create_channel(
&exec_ctx, &client_channel_factory, target,
GRPC_CLIENT_CHANNEL_TYPE_REGULAR, new_args);
// Clean up.
GRPC_SECURITY_CONNECTOR_UNREF(&exec_ctx, &security_connector->base,
"secure_client_channel_factory_create_channel");
grpc_channel_args_destroy(&exec_ctx, new_args);
grpc_exec_ctx_finish(&exec_ctx);
return channel; /* may be NULL */
return channel != NULL ? channel
: grpc_lame_client_channel_create(
target, GRPC_STATUS_INTERNAL,
"Failed to create secure client channel");
}

@ -124,6 +124,21 @@ static void close_transport_locked(grpc_exec_ctx *exec_ctx,
static void end_all_the_calls(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t,
grpc_error *error);
static void start_bdp_ping_locked(grpc_exec_ctx *exec_ctx, void *tp,
grpc_error *error);
static void finish_bdp_ping_locked(grpc_exec_ctx *exec_ctx, void *tp,
grpc_error *error);
static void cancel_pings(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t,
grpc_error *error);
static void send_ping_locked(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t,
grpc_chttp2_ping_type ping_type,
grpc_closure *on_initiate,
grpc_closure *on_complete);
#define DEFAULT_MIN_TIME_BETWEEN_PINGS_MS 0
#define DEFAULT_MAX_PINGS_BETWEEN_DATA 3
/*******************************************************************************
* CONSTRUCTION/DESTRUCTION/REFCOUNTING
*/
@ -155,16 +170,7 @@ static void destruct_transport(grpc_exec_ctx *exec_ctx,
grpc_combiner_destroy(exec_ctx, t->combiner);
/* callback remaining pings: they're not allowed to call into the transpot,
and maybe they hold resources that need to be freed */
while (t->pings.next != &t->pings) {
grpc_chttp2_outstanding_ping *ping = t->pings.next;
grpc_closure_sched(exec_ctx, ping->on_recv,
GRPC_ERROR_CREATE("Transport closed"));
ping->next->prev = ping->prev;
ping->prev->next = ping->next;
gpr_free(ping);
}
cancel_pings(exec_ctx, t, GRPC_ERROR_CREATE("Transport destroyed"));
while (t->write_cb_pool) {
grpc_chttp2_write_cb *next = t->write_cb_pool->next;
@ -172,6 +178,7 @@ static void destruct_transport(grpc_exec_ctx *exec_ctx,
t->write_cb_pool = next;
}
gpr_free(t->ping_acks);
gpr_free(t->peer_string);
gpr_free(t);
}
@ -224,10 +231,6 @@ static void init_transport(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t,
t->is_client = is_client;
t->outgoing_window = DEFAULT_WINDOW;
t->incoming_window = DEFAULT_WINDOW;
t->stream_lookahead = DEFAULT_WINDOW;
t->connection_window_target = DEFAULT_CONNECTION_WINDOW_TARGET;
t->ping_counter = 1;
t->pings.next = t->pings.prev = &t->pings;
t->deframe_state = is_client ? GRPC_DTS_FH_0 : GRPC_DTS_CLIENT_PREFIX_0;
t->is_first_frame = true;
grpc_connectivity_state_init(
@ -248,6 +251,22 @@ static void init_transport(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t,
grpc_closure_init(&t->destructive_reclaimer_locked,
destructive_reclaimer_locked, t,
grpc_combiner_scheduler(t->combiner, false));
grpc_closure_init(&t->start_bdp_ping_locked, start_bdp_ping_locked, t,
grpc_combiner_scheduler(t->combiner, false));
grpc_closure_init(&t->finish_bdp_ping_locked, finish_bdp_ping_locked, t,
grpc_combiner_scheduler(t->combiner, false));
grpc_bdp_estimator_init(&t->bdp_estimator, t->peer_string);
t->last_pid_update = gpr_now(GPR_CLOCK_MONOTONIC);
grpc_pid_controller_init(
&t->pid_controller,
(grpc_pid_controller_args){.gain_p = 4,
.gain_i = 8,
.gain_d = 0,
.initial_control_value = log2(DEFAULT_WINDOW),
.min_control_value = -1,
.max_control_value = 22,
.integral_range = 10});
grpc_chttp2_goaway_parser_init(&t->goaway_parser);
grpc_chttp2_hpack_parser_init(exec_ctx, &t->hpack_parser);
@ -273,6 +292,7 @@ static void init_transport(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t,
t->force_send_settings = 1 << GRPC_CHTTP2_SETTINGS_INITIAL_WINDOW_SIZE;
t->sent_local_settings = 0;
t->write_buffer_size = DEFAULT_WINDOW;
t->enable_bdp_probe = true;
if (is_client) {
grpc_slice_buffer_add(&t->outbuf, grpc_slice_from_copied_string(
@ -290,6 +310,12 @@ static void init_transport(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t,
push_setting(exec_ctx, t, GRPC_CHTTP2_SETTINGS_MAX_HEADER_LIST_SIZE,
DEFAULT_MAX_HEADER_LIST_SIZE);
t->ping_policy = (grpc_chttp2_repeated_ping_policy){
.max_pings_without_data = DEFAULT_MAX_PINGS_BETWEEN_DATA,
.min_time_between_pings =
gpr_time_from_millis(DEFAULT_MIN_TIME_BETWEEN_PINGS_MS, GPR_TIMESPAN),
};
if (channel_args) {
for (i = 0; i < channel_args->num_args; i++) {
if (0 == strcmp(channel_args->args[i].key,
@ -306,14 +332,6 @@ static void init_transport(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t,
t->next_stream_id = (uint32_t)value;
}
}
} else if (0 == strcmp(channel_args->args[i].key,
GRPC_ARG_HTTP2_STREAM_LOOKAHEAD_BYTES)) {
const grpc_integer_options options = {-1, 5, INT_MAX};
const int value =
grpc_channel_arg_get_integer(&channel_args->args[i], options);
if (value >= 0) {
t->stream_lookahead = (uint32_t)value;
}
} else if (0 == strcmp(channel_args->args[i].key,
GRPC_ARG_HTTP2_HPACK_TABLE_SIZE_ENCODER)) {
const grpc_integer_options options = {-1, 0, INT_MAX};
@ -323,35 +341,54 @@ static void init_transport(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t,
grpc_chttp2_hpack_compressor_set_max_usable_size(&t->hpack_compressor,
(uint32_t)value);
}
} else if (0 == strcmp(channel_args->args[i].key,
GRPC_ARG_HTTP2_MAX_PINGS_WITHOUT_DATA)) {
t->ping_policy.max_pings_without_data = grpc_channel_arg_get_integer(
&channel_args->args[i],
(grpc_integer_options){DEFAULT_MAX_PINGS_BETWEEN_DATA, 0, INT_MAX});
} else if (0 == strcmp(channel_args->args[i].key,
GRPC_ARG_HTTP2_MIN_TIME_BETWEEN_PINGS_MS)) {
t->ping_policy.min_time_between_pings = gpr_time_from_millis(
grpc_channel_arg_get_integer(
&channel_args->args[i],
(grpc_integer_options){DEFAULT_MIN_TIME_BETWEEN_PINGS_MS, 0,
INT_MAX}),
GPR_TIMESPAN);
} else if (0 == strcmp(channel_args->args[i].key,
GRPC_ARG_HTTP2_WRITE_BUFFER_SIZE)) {
t->write_buffer_size = (uint32_t)grpc_channel_arg_get_integer(
&channel_args->args[i],
(grpc_integer_options){0, 0, MAX_WRITE_BUFFER_SIZE});
} else if (0 ==
strcmp(channel_args->args[i].key, GRPC_ARG_HTTP2_BDP_PROBE)) {
t->enable_bdp_probe = grpc_channel_arg_get_integer(
&channel_args->args[i], (grpc_integer_options){1, 0, 1});
} else {
static const struct {
const char *channel_arg_name;
grpc_chttp2_setting_id setting_id;
grpc_integer_options integer_options;
bool availability[2] /* server, client */;
} settings_map[] = {
{GRPC_ARG_MAX_CONCURRENT_STREAMS,
GRPC_CHTTP2_SETTINGS_MAX_CONCURRENT_STREAMS,
{-1, 0, INT_MAX},
{true, false}},
{GRPC_ARG_HTTP2_HPACK_TABLE_SIZE_DECODER,
GRPC_CHTTP2_SETTINGS_HEADER_TABLE_SIZE,
{-1, 0, INT_MAX},
{true, true}},
{GRPC_ARG_MAX_METADATA_SIZE,
GRPC_CHTTP2_SETTINGS_MAX_HEADER_LIST_SIZE,
{-1, 0, INT_MAX},
{true, true}},
{GRPC_ARG_HTTP2_MAX_FRAME_SIZE,
GRPC_CHTTP2_SETTINGS_MAX_FRAME_SIZE,
{-1, 16384, 16777215},
{true, true}},
};
} settings_map[] = {{GRPC_ARG_MAX_CONCURRENT_STREAMS,
GRPC_CHTTP2_SETTINGS_MAX_CONCURRENT_STREAMS,
{-1, 0, INT32_MAX},
{true, false}},
{GRPC_ARG_HTTP2_HPACK_TABLE_SIZE_DECODER,
GRPC_CHTTP2_SETTINGS_HEADER_TABLE_SIZE,
{-1, 0, INT32_MAX},
{true, true}},
{GRPC_ARG_MAX_METADATA_SIZE,
GRPC_CHTTP2_SETTINGS_MAX_HEADER_LIST_SIZE,
{-1, 0, INT32_MAX},
{true, true}},
{GRPC_ARG_HTTP2_MAX_FRAME_SIZE,
GRPC_CHTTP2_SETTINGS_MAX_FRAME_SIZE,
{-1, 16384, 16777215},
{true, true}},
{GRPC_ARG_HTTP2_STREAM_LOOKAHEAD_BYTES,
GRPC_CHTTP2_SETTINGS_INITIAL_WINDOW_SIZE,
{-1, 5, INT32_MAX},
{true, true}}};
for (j = 0; j < (int)GPR_ARRAY_SIZE(settings_map); j++) {
if (0 == strcmp(channel_args->args[i].key,
settings_map[j].channel_arg_name)) {
@ -374,6 +411,9 @@ static void init_transport(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t,
}
}
t->ping_state.pings_before_data_required =
t->ping_policy.max_pings_without_data;
grpc_chttp2_initiate_write(exec_ctx, t, false, "init");
post_benign_reclaimer(exec_ctx, t);
}
@ -425,6 +465,7 @@ static void close_transport_locked(grpc_exec_ctx *exec_ctx,
GRPC_CHTTP2_STREAM_UNREF(exec_ctx, s, "chttp2_writing:close");
}
end_all_the_calls(exec_ctx, t, GRPC_ERROR_REF(error));
cancel_pings(exec_ctx, t, GRPC_ERROR_REF(error));
}
GRPC_ERROR_UNREF(error);
}
@ -475,11 +516,6 @@ static int init_stream(grpc_exec_ctx *exec_ctx, grpc_transport *gt,
if (server_data) {
s->id = (uint32_t)(uintptr_t)server_data;
s->outgoing_window = t->settings[GRPC_PEER_SETTINGS]
[GRPC_CHTTP2_SETTINGS_INITIAL_WINDOW_SIZE];
s->incoming_window = s->max_recv_bytes =
t->settings[GRPC_SENT_SETTINGS]
[GRPC_CHTTP2_SETTINGS_INITIAL_WINDOW_SIZE];
*t->accepting_stream = s;
grpc_chttp2_stream_map_add(&t->stream_map, s->id, s);
post_destructive_reclaimer(exec_ctx, t);
@ -508,6 +544,7 @@ static void destroy_stream_locked(grpc_exec_ctx *exec_ctx, void *sp,
}
grpc_chttp2_list_remove_stalled_by_transport(t, s);
grpc_chttp2_list_remove_stalled_by_stream(t, s);
for (int i = 0; i < STREAM_LIST_COUNT; i++) {
if (s->included[i]) {
@ -647,13 +684,21 @@ void grpc_chttp2_initiate_write(grpc_exec_ctx *exec_ctx,
GPR_TIMER_END("grpc_chttp2_initiate_write", 0);
}
void grpc_chttp2_become_writable(grpc_exec_ctx *exec_ctx,
grpc_chttp2_transport *t,
grpc_chttp2_stream *s, bool covered_by_poller,
const char *reason) {
void grpc_chttp2_become_writable(
grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t, grpc_chttp2_stream *s,
grpc_chttp2_stream_write_type stream_write_type, const char *reason) {
if (!t->closed && grpc_chttp2_list_add_writable_stream(t, s)) {
GRPC_CHTTP2_STREAM_REF(s, "chttp2_writing:become");
grpc_chttp2_initiate_write(exec_ctx, t, covered_by_poller, reason);
}
switch (stream_write_type) {
case GRPC_CHTTP2_STREAM_WRITE_PIGGYBACK:
break;
case GRPC_CHTTP2_STREAM_WRITE_INITIATE_COVERED:
grpc_chttp2_initiate_write(exec_ctx, t, true, reason);
break;
case GRPC_CHTTP2_STREAM_WRITE_INITIATE_UNCOVERED:
grpc_chttp2_initiate_write(exec_ctx, t, false, reason);
break;
}
}
@ -781,7 +826,6 @@ void grpc_chttp2_add_incoming_goaway(grpc_exec_ctx *exec_ctx,
static void maybe_start_some_streams(grpc_exec_ctx *exec_ctx,
grpc_chttp2_transport *t) {
grpc_chttp2_stream *s;
uint32_t stream_incoming_window;
/* start streams where we have free grpc_chttp2_stream ids and free
* concurrency */
while (t->next_stream_id <= MAX_CLIENT_STREAM_ID &&
@ -804,15 +848,11 @@ static void maybe_start_some_streams(grpc_exec_ctx *exec_ctx,
"no_more_stream_ids");
}
s->outgoing_window = t->settings[GRPC_PEER_SETTINGS]
[GRPC_CHTTP2_SETTINGS_INITIAL_WINDOW_SIZE];
s->incoming_window = stream_incoming_window =
t->settings[GRPC_SENT_SETTINGS]
[GRPC_CHTTP2_SETTINGS_INITIAL_WINDOW_SIZE];
s->max_recv_bytes = GPR_MAX(stream_incoming_window, s->max_recv_bytes);
grpc_chttp2_stream_map_add(&t->stream_map, s->id, s);
post_destructive_reclaimer(exec_ctx, t);
grpc_chttp2_become_writable(exec_ctx, t, s, true, "new_stream");
grpc_chttp2_become_writable(exec_ctx, t, s,
GRPC_CHTTP2_STREAM_WRITE_INITIATE_COVERED,
"new_stream");
}
/* cancel out streams that will never be started */
while (t->next_stream_id >= MAX_CLIENT_STREAM_ID &&
@ -907,7 +947,9 @@ static void maybe_become_writable_due_to_send_msg(grpc_exec_ctx *exec_ctx,
grpc_chttp2_stream *s) {
if (s->id != 0 && (!s->write_buffering ||
s->flow_controlled_buffer.length > t->write_buffer_size)) {
grpc_chttp2_become_writable(exec_ctx, t, s, true, "op.send_message");
grpc_chttp2_become_writable(exec_ctx, t, s,
GRPC_CHTTP2_STREAM_WRITE_INITIATE_COVERED,
"op.send_message");
}
}
@ -1069,7 +1111,8 @@ static void perform_stream_op_locked(grpc_exec_ctx *exec_ctx, void *stream_op,
}
} else {
GPR_ASSERT(s->id != 0);
grpc_chttp2_become_writable(exec_ctx, t, s, true,
grpc_chttp2_become_writable(exec_ctx, t, s,
GRPC_CHTTP2_STREAM_WRITE_INITIATE_COVERED,
"op.send_initial_metadata");
}
} else {
@ -1160,7 +1203,8 @@ static void perform_stream_op_locked(grpc_exec_ctx *exec_ctx, void *stream_op,
} else if (s->id != 0) {
/* TODO(ctiller): check if there's flow control for any outstanding
bytes before going writable */
grpc_chttp2_become_writable(exec_ctx, t, s, true,
grpc_chttp2_become_writable(exec_ctx, t, s,
GRPC_CHTTP2_STREAM_WRITE_INITIATE_COVERED,
"op.send_trailing_metadata");
}
}
@ -1179,8 +1223,7 @@ static void perform_stream_op_locked(grpc_exec_ctx *exec_ctx, void *stream_op,
s->recv_message = op->recv_message;
if (s->id != 0 &&
(s->incoming_frames.head == NULL || s->incoming_frames.head->is_tail)) {
incoming_byte_stream_update_flow_control(exec_ctx, t, s,
t->stream_lookahead, 0);
incoming_byte_stream_update_flow_control(exec_ctx, t, s, 5, 0);
}
grpc_chttp2_maybe_complete_recv_message(exec_ctx, t, s);
}
@ -1224,43 +1267,46 @@ static void perform_stream_op(grpc_exec_ctx *exec_ctx, grpc_transport *gt,
GPR_TIMER_END("perform_stream_op", 0);
}
static void cancel_pings(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t,
grpc_error *error) {
/* callback remaining pings: they're not allowed to call into the transpot,
and maybe they hold resources that need to be freed */
for (size_t i = 0; i < GRPC_CHTTP2_PING_TYPE_COUNT; i++) {
grpc_chttp2_ping_queue *pq = &t->ping_queues[i];
for (size_t j = 0; j < GRPC_CHTTP2_PCL_COUNT; j++) {
grpc_closure_list_fail_all(&pq->lists[j], GRPC_ERROR_REF(error));
grpc_closure_list_sched(exec_ctx, &pq->lists[j]);
}
}
GRPC_ERROR_UNREF(error);
}
static void send_ping_locked(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t,
grpc_closure *on_recv) {
grpc_chttp2_outstanding_ping *p = gpr_malloc(sizeof(*p));
p->next = &t->pings;
p->prev = p->next->prev;
p->prev->next = p->next->prev = p;
p->id[0] = (uint8_t)((t->ping_counter >> 56) & 0xff);
p->id[1] = (uint8_t)((t->ping_counter >> 48) & 0xff);
p->id[2] = (uint8_t)((t->ping_counter >> 40) & 0xff);
p->id[3] = (uint8_t)((t->ping_counter >> 32) & 0xff);
p->id[4] = (uint8_t)((t->ping_counter >> 24) & 0xff);
p->id[5] = (uint8_t)((t->ping_counter >> 16) & 0xff);
p->id[6] = (uint8_t)((t->ping_counter >> 8) & 0xff);
p->id[7] = (uint8_t)(t->ping_counter & 0xff);
t->ping_counter++;
p->on_recv = on_recv;
grpc_slice_buffer_add(&t->qbuf, grpc_chttp2_ping_create(0, p->id));
grpc_chttp2_initiate_write(exec_ctx, t, true, "send_ping");
grpc_chttp2_ping_type ping_type,
grpc_closure *on_initiate, grpc_closure *on_ack) {
grpc_chttp2_ping_queue *pq = &t->ping_queues[ping_type];
grpc_closure_list_append(&pq->lists[GRPC_CHTTP2_PCL_INITIATE], on_initiate,
GRPC_ERROR_NONE);
if (grpc_closure_list_append(&pq->lists[GRPC_CHTTP2_PCL_NEXT], on_ack,
GRPC_ERROR_NONE)) {
grpc_chttp2_initiate_write(exec_ctx, t, false, "send_ping");
}
}
void grpc_chttp2_ack_ping(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t,
const uint8_t *opaque_8bytes) {
grpc_chttp2_outstanding_ping *ping;
for (ping = t->pings.next; ping != &t->pings; ping = ping->next) {
if (0 == memcmp(opaque_8bytes, ping->id, 8)) {
grpc_closure_sched(exec_ctx, ping->on_recv, GRPC_ERROR_NONE);
ping->next->prev = ping->prev;
ping->prev->next = ping->next;
gpr_free(ping);
return;
}
uint64_t id) {
grpc_chttp2_ping_queue *pq =
&t->ping_queues[id % GRPC_CHTTP2_PING_TYPE_COUNT];
if (pq->inflight_id != id) {
char *from = grpc_endpoint_get_peer(t->ep);
gpr_log(GPR_DEBUG, "Unknown ping response from %s: %" PRIx64, from, id);
gpr_free(from);
return;
}
grpc_closure_list_sched(exec_ctx, &pq->lists[GRPC_CHTTP2_PCL_INFLIGHT]);
if (!grpc_closure_list_empty(pq->lists[GRPC_CHTTP2_PCL_NEXT])) {
grpc_chttp2_initiate_write(exec_ctx, t, false, "continue_pings");
}
char *msg = gpr_dump((const char *)opaque_8bytes, 8, GPR_DUMP_HEX);
char *from = grpc_endpoint_get_peer(t->ep);
gpr_log(GPR_DEBUG, "Unknown ping response from %s: %s", from, msg);
gpr_free(from);
gpr_free(msg);
}
static void send_goaway(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t,
@ -1308,7 +1354,8 @@ static void perform_transport_op_locked(grpc_exec_ctx *exec_ctx,
}
if (op->send_ping) {
send_ping_locked(exec_ctx, t, op->send_ping);
send_ping_locked(exec_ctx, t, GRPC_CHTTP2_PING_ON_NEXT_WRITE, NULL,
op->send_ping);
}
if (close_transport != GRPC_ERROR_NONE) {
@ -1733,34 +1780,28 @@ static void end_all_the_calls(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t,
GRPC_ERROR_UNREF(error);
}
/** update window from a settings change */
typedef struct {
grpc_chttp2_transport *t;
grpc_exec_ctx *exec_ctx;
} update_global_window_args;
/*******************************************************************************
* INPUT PROCESSING - PARSING
*/
static void update_global_window(void *args, uint32_t id, void *stream) {
update_global_window_args *a = args;
grpc_chttp2_transport *t = a->t;
grpc_chttp2_stream *s = stream;
int was_zero;
int is_zero;
int64_t initial_window_update = t->initial_window_update;
if (initial_window_update > 0) {
was_zero = s->outgoing_window <= 0;
GRPC_CHTTP2_FLOW_CREDIT_STREAM("settings", t, s, outgoing_window,
initial_window_update);
is_zero = s->outgoing_window <= 0;
if (was_zero && !is_zero) {
grpc_chttp2_become_writable(a->exec_ctx, t, s, true,
"update_global_window");
}
static void update_bdp(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t,
double bdp_dbl) {
uint32_t bdp;
if (bdp_dbl <= 0) {
bdp = 0;
} else if (bdp_dbl > UINT32_MAX) {
bdp = UINT32_MAX;
} else {
GRPC_CHTTP2_FLOW_DEBIT_STREAM("settings", t, s, outgoing_window,
-initial_window_update);
bdp = (uint32_t)(bdp_dbl);
}
int64_t delta =
(int64_t)bdp -
(int64_t)t->settings[GRPC_LOCAL_SETTINGS]
[GRPC_CHTTP2_SETTINGS_INITIAL_WINDOW_SIZE];
if (delta == 0 || (bdp != 0 && delta > -1024 && delta < 1024)) {
return;
}
push_setting(exec_ctx, t, GRPC_CHTTP2_SETTINGS_INITIAL_WINDOW_SIZE, bdp);
}
/*******************************************************************************
@ -1802,6 +1843,7 @@ static void read_action_locked(grpc_exec_ctx *exec_ctx, void *tp,
GPR_TIMER_BEGIN("reading_action_locked", 0);
grpc_chttp2_transport *t = tp;
bool need_bdp_ping = false;
GRPC_ERROR_REF(error);
@ -1819,9 +1861,14 @@ static void read_action_locked(grpc_exec_ctx *exec_ctx, void *tp,
grpc_error *errors[3] = {GRPC_ERROR_REF(error), GRPC_ERROR_NONE,
GRPC_ERROR_NONE};
for (; i < t->read_buffer.count && errors[1] == GRPC_ERROR_NONE; i++) {
if (grpc_bdp_estimator_add_incoming_bytes(
&t->bdp_estimator,
(int64_t)GRPC_SLICE_LENGTH(t->read_buffer.slices[i]))) {
need_bdp_ping = true;
}
errors[1] =
grpc_chttp2_perform_read(exec_ctx, t, t->read_buffer.slices[i]);
};
}
if (errors[1] != GRPC_ERROR_NONE) {
errors[2] = try_http_parsing(exec_ctx, t);
GRPC_ERROR_UNREF(error);
@ -1835,21 +1882,16 @@ static void read_action_locked(grpc_exec_ctx *exec_ctx, void *tp,
GPR_TIMER_BEGIN("post_parse_locked", 0);
if (t->initial_window_update != 0) {
update_global_window_args args = {t, exec_ctx};
grpc_chttp2_stream_map_for_each(&t->stream_map, update_global_window,
&args);
if (t->initial_window_update > 0) {
grpc_chttp2_stream *s;
while (grpc_chttp2_list_pop_stalled_by_stream(t, &s)) {
grpc_chttp2_become_writable(
exec_ctx, t, s, GRPC_CHTTP2_STREAM_WRITE_INITIATE_UNCOVERED,
"unstalled");
}
}
t->initial_window_update = 0;
}
/* handle higher level things */
if (t->incoming_window < t->connection_window_target * 3 / 4) {
int64_t announce_bytes = t->connection_window_target - t->incoming_window;
GRPC_CHTTP2_FLOW_CREDIT_TRANSPORT("parsed", t, announce_incoming_window,
announce_bytes);
GRPC_CHTTP2_FLOW_CREDIT_TRANSPORT("parsed", t, incoming_window,
announce_bytes);
grpc_chttp2_initiate_write(exec_ctx, t, false, "global incoming window");
}
GPR_TIMER_END("post_parse_locked", 0);
}
@ -1870,6 +1912,38 @@ static void read_action_locked(grpc_exec_ctx *exec_ctx, void *tp,
if (keep_reading) {
grpc_endpoint_read(exec_ctx, t->ep, &t->read_buffer,
&t->read_action_locked);
if (t->enable_bdp_probe) {
if (need_bdp_ping) {
GRPC_CHTTP2_REF_TRANSPORT(t, "bdp_ping");
grpc_bdp_estimator_schedule_ping(&t->bdp_estimator);
send_ping_locked(exec_ctx, t,
GRPC_CHTTP2_PING_BEFORE_TRANSPORT_WINDOW_UPDATE,
&t->start_bdp_ping_locked, &t->finish_bdp_ping_locked);
}
int64_t estimate = -1;
if (grpc_bdp_estimator_get_estimate(&t->bdp_estimator, &estimate)) {
double target = 1 + log2((double)estimate);
double memory_pressure = grpc_resource_quota_get_memory_pressure(
grpc_resource_user_quota(grpc_endpoint_get_resource_user(t->ep)));
if (memory_pressure > 0.8) {
target *= 1 - GPR_MIN(1, (memory_pressure - 0.8) / 0.1);
}
double bdp_error =
target - grpc_pid_controller_last(&t->pid_controller);
gpr_timespec now = gpr_now(GPR_CLOCK_MONOTONIC);
gpr_timespec dt_timespec = gpr_time_sub(now, t->last_pid_update);
double dt = (double)dt_timespec.tv_sec + dt_timespec.tv_nsec * 1e-9;
if (dt > 0.1) {
dt = 0.1;
}
double log2_bdp_guess =
grpc_pid_controller_update(&t->pid_controller, bdp_error, dt);
update_bdp(exec_ctx, t, pow(2, log2_bdp_guess));
t->last_pid_update = now;
}
}
GRPC_CHTTP2_UNREF_TRANSPORT(exec_ctx, t, "keep_reading");
} else {
GRPC_CHTTP2_UNREF_TRANSPORT(exec_ctx, t, "reading_action");
@ -1882,6 +1956,26 @@ static void read_action_locked(grpc_exec_ctx *exec_ctx, void *tp,
GPR_TIMER_END("reading_action_locked", 0);
}
static void start_bdp_ping_locked(grpc_exec_ctx *exec_ctx, void *tp,
grpc_error *error) {
grpc_chttp2_transport *t = tp;
if (grpc_http_trace) {
gpr_log(GPR_DEBUG, "%s: Start BDP ping", t->peer_string);
}
grpc_bdp_estimator_start_ping(&t->bdp_estimator);
}
static void finish_bdp_ping_locked(grpc_exec_ctx *exec_ctx, void *tp,
grpc_error *error) {
grpc_chttp2_transport *t = tp;
if (grpc_http_trace) {
gpr_log(GPR_DEBUG, "%s: Complete BDP ping", t->peer_string);
}
grpc_bdp_estimator_complete_ping(&t->bdp_estimator);
GRPC_CHTTP2_UNREF_TRANSPORT(exec_ctx, t, "bdp_ping");
}
/*******************************************************************************
* CALLBACK LOOP
*/
@ -1932,10 +2026,12 @@ static void incoming_byte_stream_update_flow_control(grpc_exec_ctx *exec_ctx,
size_t max_size_hint,
size_t have_already) {
uint32_t max_recv_bytes;
uint32_t initial_window_size =
t->settings[GRPC_SENT_SETTINGS][GRPC_CHTTP2_SETTINGS_INITIAL_WINDOW_SIZE];
/* clamp max recv hint to an allowable size */
if (max_size_hint >= UINT32_MAX - t->stream_lookahead) {
max_recv_bytes = UINT32_MAX - t->stream_lookahead;
if (max_size_hint >= UINT32_MAX - initial_window_size) {
max_recv_bytes = UINT32_MAX - initial_window_size;
} else {
max_recv_bytes = (uint32_t)max_size_hint;
}
@ -1948,20 +2044,26 @@ static void incoming_byte_stream_update_flow_control(grpc_exec_ctx *exec_ctx,
}
/* add some small lookahead to keep pipelines flowing */
GPR_ASSERT(max_recv_bytes <= UINT32_MAX - t->stream_lookahead);
max_recv_bytes += t->stream_lookahead;
if (s->max_recv_bytes < max_recv_bytes) {
uint32_t add_max_recv_bytes = max_recv_bytes - s->max_recv_bytes;
bool new_window_write_is_covered_by_poller =
s->max_recv_bytes < have_already;
GRPC_CHTTP2_FLOW_CREDIT_STREAM("op", t, s, max_recv_bytes,
add_max_recv_bytes);
GRPC_CHTTP2_FLOW_CREDIT_STREAM("op", t, s, incoming_window,
GPR_ASSERT(max_recv_bytes <= UINT32_MAX - initial_window_size);
if (s->incoming_window_delta < max_recv_bytes && !s->read_closed) {
uint32_t add_max_recv_bytes =
(uint32_t)(max_recv_bytes - s->incoming_window_delta);
grpc_chttp2_stream_write_type write_type =
GRPC_CHTTP2_STREAM_WRITE_INITIATE_UNCOVERED;
if (s->incoming_window_delta + initial_window_size <
(int64_t)have_already) {
write_type = GRPC_CHTTP2_STREAM_WRITE_INITIATE_COVERED;
}
GRPC_CHTTP2_FLOW_CREDIT_STREAM("op", t, s, incoming_window_delta,
add_max_recv_bytes);
GRPC_CHTTP2_FLOW_CREDIT_STREAM("op", t, s, announce_window,
add_max_recv_bytes);
grpc_chttp2_become_writable(exec_ctx, t, s,
new_window_write_is_covered_by_poller,
if ((int64_t)s->incoming_window_delta + (int64_t)initial_window_size -
(int64_t)s->announce_window >
(int64_t)initial_window_size / 2) {
write_type = GRPC_CHTTP2_STREAM_WRITE_PIGGYBACK;
}
grpc_chttp2_become_writable(exec_ctx, t, s, write_type,
"read_incoming_stream");
}
}

@ -40,7 +40,7 @@
#include <grpc/support/log.h>
#include <grpc/support/string_util.h>
grpc_slice grpc_chttp2_ping_create(uint8_t ack, uint8_t *opaque_8bytes) {
grpc_slice grpc_chttp2_ping_create(uint8_t ack, uint64_t opaque_8bytes) {
grpc_slice slice = grpc_slice_malloc(9 + 8);
uint8_t *p = GRPC_SLICE_START_PTR(slice);
@ -53,7 +53,14 @@ grpc_slice grpc_chttp2_ping_create(uint8_t ack, uint8_t *opaque_8bytes) {
*p++ = 0;
*p++ = 0;
*p++ = 0;
memcpy(p, opaque_8bytes, 8);
*p++ = (uint8_t)(opaque_8bytes >> 56);
*p++ = (uint8_t)(opaque_8bytes >> 48);
*p++ = (uint8_t)(opaque_8bytes >> 40);
*p++ = (uint8_t)(opaque_8bytes >> 32);
*p++ = (uint8_t)(opaque_8bytes >> 24);
*p++ = (uint8_t)(opaque_8bytes >> 16);
*p++ = (uint8_t)(opaque_8bytes >> 8);
*p++ = (uint8_t)(opaque_8bytes);
return slice;
}
@ -70,6 +77,7 @@ grpc_error *grpc_chttp2_ping_parser_begin_frame(grpc_chttp2_ping_parser *parser,
}
parser->byte = 0;
parser->is_ack = flags;
parser->opaque_8bytes = 0;
return GRPC_ERROR_NONE;
}
@ -83,7 +91,7 @@ grpc_error *grpc_chttp2_ping_parser_parse(grpc_exec_ctx *exec_ctx, void *parser,
grpc_chttp2_ping_parser *p = parser;
while (p->byte != 8 && cur != end) {
p->opaque_8bytes[p->byte] = *cur;
p->opaque_8bytes |= (((uint64_t)*cur) << (8 * p->byte));
cur++;
p->byte++;
}
@ -93,8 +101,12 @@ grpc_error *grpc_chttp2_ping_parser_parse(grpc_exec_ctx *exec_ctx, void *parser,
if (p->is_ack) {
grpc_chttp2_ack_ping(exec_ctx, t, p->opaque_8bytes);
} else {
grpc_slice_buffer_add(&t->qbuf,
grpc_chttp2_ping_create(1, p->opaque_8bytes));
if (t->ping_ack_count == t->ping_ack_capacity) {
t->ping_ack_capacity = GPR_MAX(t->ping_ack_capacity * 3 / 2, 3);
t->ping_acks = gpr_realloc(
t->ping_acks, t->ping_ack_capacity * sizeof(*t->ping_acks));
}
t->ping_acks[t->ping_ack_count++] = p->opaque_8bytes;
grpc_chttp2_initiate_write(exec_ctx, t, false, "ping response");
}
}

@ -41,10 +41,10 @@
typedef struct {
uint8_t byte;
uint8_t is_ack;
uint8_t opaque_8bytes[8];
uint64_t opaque_8bytes;
} grpc_chttp2_ping_parser;
grpc_slice grpc_chttp2_ping_create(uint8_t ack, uint8_t *opaque_8bytes);
grpc_slice grpc_chttp2_ping_create(uint8_t ack, uint64_t opaque_8bytes);
grpc_error *grpc_chttp2_ping_parser_begin_frame(grpc_chttp2_ping_parser *parser,
uint32_t length, uint8_t flags);

@ -109,8 +109,13 @@ grpc_error *grpc_chttp2_rst_stream_parser_parse(grpc_exec_ctx *exec_ctx,
(((uint32_t)p->reason_bytes[3]));
grpc_error *error = GRPC_ERROR_NONE;
if (reason != GRPC_HTTP2_NO_ERROR || s->header_frames_received < 2) {
error = grpc_error_set_int(GRPC_ERROR_CREATE("RST_STREAM"),
GRPC_ERROR_INT_HTTP2_ERROR, (intptr_t)reason);
char *message;
gpr_asprintf(&message, "Received RST_STREAM with error code %d", reason);
error = grpc_error_set_int(
grpc_error_set_str(GRPC_ERROR_CREATE("RST_STREAM"),
GRPC_ERROR_STR_GRPC_MESSAGE, message),
GRPC_ERROR_INT_HTTP2_ERROR, (intptr_t)reason);
gpr_free(message);
}
grpc_chttp2_mark_stream_closed(exec_ctx, t, s, true, true, error);
}

@ -236,7 +236,7 @@ grpc_error *grpc_chttp2_settings_parser_parse(grpc_exec_ctx *exec_ctx, void *p,
}
if (parser->id == GRPC_CHTTP2_SETTINGS_INITIAL_WINDOW_SIZE &&
parser->incoming_settings[parser->id] != parser->value) {
t->initial_window_update =
t->initial_window_update +=
(int64_t)parser->value - parser->incoming_settings[parser->id];
if (grpc_http_trace) {
gpr_log(GPR_DEBUG, "adding %d for initial_window change",
@ -245,8 +245,9 @@ grpc_error *grpc_chttp2_settings_parser_parse(grpc_exec_ctx *exec_ctx, void *p,
}
parser->incoming_settings[parser->id] = parser->value;
if (grpc_http_trace) {
gpr_log(GPR_DEBUG, "CHTTP2:%s: got setting %d = %d",
t->is_client ? "CLI" : "SVR", parser->id, parser->value);
gpr_log(GPR_DEBUG, "CHTTP2:%s:%s: got setting %d = %d",
t->is_client ? "CLI" : "SVR", t->peer_string, parser->id,
parser->value);
}
} else if (grpc_http_trace) {
gpr_log(GPR_ERROR, "CHTTP2: Ignoring unknown setting %d (value %d)",

@ -110,13 +110,12 @@ grpc_error *grpc_chttp2_window_update_parser_parse(
if (t->incoming_stream_id != 0) {
if (s != NULL) {
bool was_zero = s->outgoing_window <= 0;
GRPC_CHTTP2_FLOW_CREDIT_STREAM("parse", t, s, outgoing_window,
GRPC_CHTTP2_FLOW_CREDIT_STREAM("parse", t, s, outgoing_window_delta,
received_update);
bool is_zero = s->outgoing_window <= 0;
if (was_zero && !is_zero) {
grpc_chttp2_become_writable(exec_ctx, t, s, false,
"stream.read_flow_control");
if (grpc_chttp2_list_remove_stalled_by_stream(t, s)) {
grpc_chttp2_become_writable(
exec_ctx, t, s, GRPC_CHTTP2_STREAM_WRITE_INITIATE_UNCOVERED,
"stream.read_flow_control");
}
}
} else {

@ -50,7 +50,9 @@
#include "src/core/ext/transport/chttp2/transport/stream_map.h"
#include "src/core/lib/iomgr/combiner.h"
#include "src/core/lib/iomgr/endpoint.h"
#include "src/core/lib/transport/bdp_estimator.h"
#include "src/core/lib/transport/connectivity_state.h"
#include "src/core/lib/transport/pid_controller.h"
#include "src/core/lib/transport/transport_impl.h"
/* streams are kept in various linked lists depending on what things need to
@ -59,6 +61,7 @@ typedef enum {
GRPC_CHTTP2_LIST_WRITABLE,
GRPC_CHTTP2_LIST_WRITING,
GRPC_CHTTP2_LIST_STALLED_BY_TRANSPORT,
GRPC_CHTTP2_LIST_STALLED_BY_STREAM,
/** streams that are waiting to start because there are too many concurrent
streams on the connection */
GRPC_CHTTP2_LIST_WAITING_FOR_CONCURRENCY,
@ -72,6 +75,34 @@ typedef enum {
GRPC_CHTTP2_WRITE_STATE_WRITING_WITH_MORE_AND_COVERED_BY_POLLER,
} grpc_chttp2_write_state;
typedef enum {
GRPC_CHTTP2_PING_ON_NEXT_WRITE = 0,
GRPC_CHTTP2_PING_BEFORE_TRANSPORT_WINDOW_UPDATE,
GRPC_CHTTP2_PING_TYPE_COUNT /* must be last */
} grpc_chttp2_ping_type;
typedef enum {
GRPC_CHTTP2_PCL_INITIATE = 0,
GRPC_CHTTP2_PCL_NEXT,
GRPC_CHTTP2_PCL_INFLIGHT,
GRPC_CHTTP2_PCL_COUNT /* must be last */
} grpc_chttp2_ping_closure_list;
typedef struct {
grpc_closure_list lists[GRPC_CHTTP2_PCL_COUNT];
uint64_t inflight_id;
} grpc_chttp2_ping_queue;
typedef struct {
gpr_timespec min_time_between_pings;
int max_pings_without_data;
} grpc_chttp2_repeated_ping_policy;
typedef struct {
gpr_timespec last_ping_sent_time;
int pings_before_data_required;
} grpc_chttp2_repeated_ping_state;
/* deframer state for the overall http2 stream of bytes */
typedef enum {
/* prefix: one entry per http2 connection prefix byte */
@ -144,14 +175,6 @@ typedef enum {
GRPC_CHTTP2_GOAWAY_SENT,
} grpc_chttp2_sent_goaway_state;
/* Outstanding ping request data */
typedef struct grpc_chttp2_outstanding_ping {
uint8_t id[8];
grpc_closure *on_recv;
struct grpc_chttp2_outstanding_ping *next;
struct grpc_chttp2_outstanding_ping *prev;
} grpc_chttp2_outstanding_ping;
typedef struct grpc_chttp2_write_cb {
int64_t call_at_byte;
grpc_closure *closure;
@ -204,6 +227,9 @@ struct grpc_chttp2_transport {
/** is there a read request to the endpoint outstanding? */
uint8_t endpoint_reading;
/** should we probe bdp? */
bool enable_bdp_probe;
/** various lists of streams */
grpc_chttp2_stream_list lists[STREAM_LIST_COUNT];
@ -271,16 +297,19 @@ struct grpc_chttp2_transport {
copied to next_stream_id in parsing when parsing commences */
uint32_t next_stream_id;
/** how far to lookahead in a stream? */
uint32_t stream_lookahead;
/** last new stream id */
uint32_t last_new_stream_id;
/** pings awaiting responses */
grpc_chttp2_outstanding_ping pings;
/** next payload for an outgoing ping */
uint64_t ping_counter;
/** ping queues for various ping insertion points */
grpc_chttp2_ping_queue ping_queues[GRPC_CHTTP2_PING_TYPE_COUNT];
grpc_chttp2_repeated_ping_policy ping_policy;
grpc_chttp2_repeated_ping_state ping_state;
uint64_t ping_ctr; /* unique id for pings */
/** ping acks */
size_t ping_ack_count;
size_t ping_ack_capacity;
uint64_t *ping_acks;
/** parser for headers */
grpc_chttp2_hpack_parser hpack_parser;
@ -324,6 +353,13 @@ struct grpc_chttp2_transport {
grpc_chttp2_write_cb *write_cb_pool;
/* bdp estimator */
grpc_bdp_estimator bdp_estimator;
grpc_pid_controller pid_controller;
grpc_closure start_bdp_ping_locked;
grpc_closure finish_bdp_ping_locked;
gpr_timespec last_pid_update;
/* if non-NULL, close the transport with this error when writes are finished
*/
grpc_error *close_transport_on_writes_finished;
@ -362,12 +398,10 @@ struct grpc_chttp2_stream {
/** HTTP2 stream id for this stream, or zero if one has not been assigned */
uint32_t id;
/** window available for us to send to peer */
int64_t outgoing_window;
/** The number of bytes the upper layers have offered to receive.
As the upper layer offers more bytes, this value increases.
As bytes are read, this value decreases. */
uint32_t max_recv_bytes;
/** window available for us to send to peer, over or under the initial window
* size of the transport... ie:
* outgoing_window = outgoing_window_delta + transport.initial_window_size */
int64_t outgoing_window_delta;
/** things the upper layers would like to send */
grpc_metadata_batch *send_initial_metadata;
grpc_closure *send_initial_metadata_finished;
@ -428,8 +462,10 @@ struct grpc_chttp2_stream {
grpc_error *forced_close_error;
/** how many header frames have we received? */
uint8_t header_frames_received;
/** window available for peer to send to us */
int64_t incoming_window;
/** window available for peer to send to us (as a delta on
* transport.initial_window_size)
* incoming_window = incoming_window_delta + transport.initial_window_size */
int64_t incoming_window_delta;
/** parsing state for data frames */
grpc_chttp2_data_parser data_parser;
/** number of bytes received - reset at end of parse thread execution */
@ -478,36 +514,43 @@ bool grpc_chttp2_list_add_writable_stream(grpc_chttp2_transport *t,
grpc_chttp2_stream *s);
/** Get a writable stream
returns non-zero if there was a stream available */
int grpc_chttp2_list_pop_writable_stream(grpc_chttp2_transport *t,
grpc_chttp2_stream **s);
bool grpc_chttp2_list_pop_writable_stream(grpc_chttp2_transport *t,
grpc_chttp2_stream **s);
bool grpc_chttp2_list_remove_writable_stream(
grpc_chttp2_transport *t, grpc_chttp2_stream *s) GRPC_MUST_USE_RESULT;
bool grpc_chttp2_list_add_writing_stream(grpc_chttp2_transport *t,
grpc_chttp2_stream *s);
int grpc_chttp2_list_have_writing_streams(grpc_chttp2_transport *t);
int grpc_chttp2_list_pop_writing_stream(grpc_chttp2_transport *t,
grpc_chttp2_stream **s);
bool grpc_chttp2_list_have_writing_streams(grpc_chttp2_transport *t);
bool grpc_chttp2_list_pop_writing_stream(grpc_chttp2_transport *t,
grpc_chttp2_stream **s);
void grpc_chttp2_list_add_written_stream(grpc_chttp2_transport *t,
grpc_chttp2_stream *s);
int grpc_chttp2_list_pop_written_stream(grpc_chttp2_transport *t,
grpc_chttp2_stream **s);
bool grpc_chttp2_list_pop_written_stream(grpc_chttp2_transport *t,
grpc_chttp2_stream **s);
void grpc_chttp2_list_add_waiting_for_concurrency(grpc_chttp2_transport *t,
grpc_chttp2_stream *s);
int grpc_chttp2_list_pop_waiting_for_concurrency(grpc_chttp2_transport *t,
grpc_chttp2_stream **s);
bool grpc_chttp2_list_pop_waiting_for_concurrency(grpc_chttp2_transport *t,
grpc_chttp2_stream **s);
void grpc_chttp2_list_remove_waiting_for_concurrency(grpc_chttp2_transport *t,
grpc_chttp2_stream *s);
void grpc_chttp2_list_add_stalled_by_transport(grpc_chttp2_transport *t,
grpc_chttp2_stream *s);
int grpc_chttp2_list_pop_stalled_by_transport(grpc_chttp2_transport *t,
grpc_chttp2_stream **s);
bool grpc_chttp2_list_pop_stalled_by_transport(grpc_chttp2_transport *t,
grpc_chttp2_stream **s);
void grpc_chttp2_list_remove_stalled_by_transport(grpc_chttp2_transport *t,
grpc_chttp2_stream *s);
void grpc_chttp2_list_add_stalled_by_stream(grpc_chttp2_transport *t,
grpc_chttp2_stream *s);
bool grpc_chttp2_list_pop_stalled_by_stream(grpc_chttp2_transport *t,
grpc_chttp2_stream **s);
bool grpc_chttp2_list_remove_stalled_by_stream(grpc_chttp2_transport *t,
grpc_chttp2_stream *s);
grpc_chttp2_stream *grpc_chttp2_parsing_lookup_stream(grpc_chttp2_transport *t,
uint32_t id);
grpc_chttp2_stream *grpc_chttp2_parsing_accept_stream(grpc_exec_ctx *exec_ctx,
@ -672,13 +715,23 @@ void grpc_chttp2_incoming_byte_stream_finished(
grpc_error *error);
void grpc_chttp2_ack_ping(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t,
const uint8_t *opaque_8bytes);
uint64_t id);
typedef enum {
/* don't initiate a transport write, but piggyback on the next one */
GRPC_CHTTP2_STREAM_WRITE_PIGGYBACK,
/* initiate a covered write */
GRPC_CHTTP2_STREAM_WRITE_INITIATE_COVERED,
/* initiate an uncovered write */
GRPC_CHTTP2_STREAM_WRITE_INITIATE_UNCOVERED
} grpc_chttp2_stream_write_type;
/** add a ref to the stream and add it to the writable list;
ref will be dropped in writing.c */
void grpc_chttp2_become_writable(grpc_exec_ctx *exec_ctx,
grpc_chttp2_transport *t,
grpc_chttp2_stream *s, bool covered_by_poller,
grpc_chttp2_stream *s,
grpc_chttp2_stream_write_type type,
const char *reason);
void grpc_chttp2_cancel_stream(grpc_exec_ctx *exec_ctx,

@ -376,25 +376,45 @@ static grpc_error *update_incoming_window(grpc_exec_ctx *exec_ctx,
return err;
}
uint32_t target_incoming_window = GPR_MAX(
t->settings[GRPC_SENT_SETTINGS][GRPC_CHTTP2_SETTINGS_INITIAL_WINDOW_SIZE],
1024);
GRPC_CHTTP2_FLOW_DEBIT_TRANSPORT("parse", t, incoming_window,
incoming_frame_size);
if (t->incoming_window <= target_incoming_window / 2) {
grpc_chttp2_initiate_write(exec_ctx, t, false, "flow_control");
}
if (s != NULL) {
if (incoming_frame_size > s->incoming_window) {
if (incoming_frame_size >
s->incoming_window_delta +
t->settings[GRPC_ACKED_SETTINGS]
[GRPC_CHTTP2_SETTINGS_INITIAL_WINDOW_SIZE]) {
char *msg;
gpr_asprintf(&msg,
"frame of size %d overflows incoming window of %" PRId64,
t->incoming_frame_size, s->incoming_window);
t->incoming_frame_size,
s->incoming_window_delta +
t->settings[GRPC_ACKED_SETTINGS]
[GRPC_CHTTP2_SETTINGS_INITIAL_WINDOW_SIZE]);
grpc_error *err = GRPC_ERROR_CREATE(msg);
gpr_free(msg);
return err;
}
GRPC_CHTTP2_FLOW_DEBIT_STREAM("parse", t, s, incoming_window,
GRPC_CHTTP2_FLOW_DEBIT_STREAM("parse", t, s, incoming_window_delta,
incoming_frame_size);
if ((int64_t)t->settings[GRPC_SENT_SETTINGS]
[GRPC_CHTTP2_SETTINGS_INITIAL_WINDOW_SIZE] +
(int64_t)s->incoming_window_delta - (int64_t)s->announce_window <=
(int64_t)t->settings[GRPC_SENT_SETTINGS]
[GRPC_CHTTP2_SETTINGS_INITIAL_WINDOW_SIZE] /
2) {
grpc_chttp2_become_writable(exec_ctx, t, s,
GRPC_CHTTP2_STREAM_WRITE_INITIATE_UNCOVERED,
"window-update-required");
}
s->received_bytes += incoming_frame_size;
s->max_recv_bytes -=
(uint32_t)GPR_MIN(s->max_recv_bytes, incoming_frame_size);
}
return GRPC_ERROR_NONE;

@ -37,14 +37,14 @@
/* core list management */
static int stream_list_empty(grpc_chttp2_transport *t,
grpc_chttp2_stream_list_id id) {
static bool stream_list_empty(grpc_chttp2_transport *t,
grpc_chttp2_stream_list_id id) {
return t->lists[id].head == NULL;
}
static int stream_list_pop(grpc_chttp2_transport *t,
grpc_chttp2_stream **stream,
grpc_chttp2_stream_list_id id) {
static bool stream_list_pop(grpc_chttp2_transport *t,
grpc_chttp2_stream **stream,
grpc_chttp2_stream_list_id id) {
grpc_chttp2_stream *s = t->lists[id].head;
if (s) {
grpc_chttp2_stream *new_head = s->links[id].next;
@ -124,8 +124,8 @@ bool grpc_chttp2_list_add_writable_stream(grpc_chttp2_transport *t,
return stream_list_add(t, s, GRPC_CHTTP2_LIST_WRITABLE);
}
int grpc_chttp2_list_pop_writable_stream(grpc_chttp2_transport *t,
grpc_chttp2_stream **s) {
bool grpc_chttp2_list_pop_writable_stream(grpc_chttp2_transport *t,
grpc_chttp2_stream **s) {
return stream_list_pop(t, s, GRPC_CHTTP2_LIST_WRITABLE);
}
@ -139,12 +139,12 @@ bool grpc_chttp2_list_add_writing_stream(grpc_chttp2_transport *t,
return stream_list_add(t, s, GRPC_CHTTP2_LIST_WRITING);
}
int grpc_chttp2_list_have_writing_streams(grpc_chttp2_transport *t) {
bool grpc_chttp2_list_have_writing_streams(grpc_chttp2_transport *t) {
return !stream_list_empty(t, GRPC_CHTTP2_LIST_WRITING);
}
int grpc_chttp2_list_pop_writing_stream(grpc_chttp2_transport *t,
grpc_chttp2_stream **s) {
bool grpc_chttp2_list_pop_writing_stream(grpc_chttp2_transport *t,
grpc_chttp2_stream **s) {
return stream_list_pop(t, s, GRPC_CHTTP2_LIST_WRITING);
}
@ -153,8 +153,8 @@ void grpc_chttp2_list_add_waiting_for_concurrency(grpc_chttp2_transport *t,
stream_list_add(t, s, GRPC_CHTTP2_LIST_WAITING_FOR_CONCURRENCY);
}
int grpc_chttp2_list_pop_waiting_for_concurrency(grpc_chttp2_transport *t,
grpc_chttp2_stream **s) {
bool grpc_chttp2_list_pop_waiting_for_concurrency(grpc_chttp2_transport *t,
grpc_chttp2_stream **s) {
return stream_list_pop(t, s, GRPC_CHTTP2_LIST_WAITING_FOR_CONCURRENCY);
}
@ -168,8 +168,8 @@ void grpc_chttp2_list_add_stalled_by_transport(grpc_chttp2_transport *t,
stream_list_add(t, s, GRPC_CHTTP2_LIST_STALLED_BY_TRANSPORT);
}
int grpc_chttp2_list_pop_stalled_by_transport(grpc_chttp2_transport *t,
grpc_chttp2_stream **s) {
bool grpc_chttp2_list_pop_stalled_by_transport(grpc_chttp2_transport *t,
grpc_chttp2_stream **s) {
return stream_list_pop(t, s, GRPC_CHTTP2_LIST_STALLED_BY_TRANSPORT);
}
@ -177,3 +177,18 @@ void grpc_chttp2_list_remove_stalled_by_transport(grpc_chttp2_transport *t,
grpc_chttp2_stream *s) {
stream_list_maybe_remove(t, s, GRPC_CHTTP2_LIST_STALLED_BY_TRANSPORT);
}
void grpc_chttp2_list_add_stalled_by_stream(grpc_chttp2_transport *t,
grpc_chttp2_stream *s) {
stream_list_add(t, s, GRPC_CHTTP2_LIST_STALLED_BY_STREAM);
}
bool grpc_chttp2_list_pop_stalled_by_stream(grpc_chttp2_transport *t,
grpc_chttp2_stream **s) {
return stream_list_pop(t, s, GRPC_CHTTP2_LIST_STALLED_BY_STREAM);
}
bool grpc_chttp2_list_remove_stalled_by_stream(grpc_chttp2_transport *t,
grpc_chttp2_stream *s) {
return stream_list_maybe_remove(t, s, GRPC_CHTTP2_LIST_STALLED_BY_STREAM);
}

@ -56,6 +56,75 @@ static void finish_write_cb(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t,
t->write_cb_pool = cb;
}
static void collapse_pings_from_into(grpc_chttp2_transport *t,
grpc_chttp2_ping_type ping_type,
grpc_chttp2_ping_queue *pq) {
for (size_t i = 0; i < GRPC_CHTTP2_PCL_COUNT; i++) {
grpc_closure_list_move(&t->ping_queues[ping_type].lists[i], &pq->lists[i]);
}
}
static void maybe_initiate_ping(grpc_exec_ctx *exec_ctx,
grpc_chttp2_transport *t,
grpc_chttp2_ping_type ping_type) {
grpc_chttp2_ping_queue *pq = &t->ping_queues[ping_type];
if (grpc_closure_list_empty(pq->lists[GRPC_CHTTP2_PCL_NEXT])) {
/* no ping needed: wait */
return;
}
if (!grpc_closure_list_empty(pq->lists[GRPC_CHTTP2_PCL_INFLIGHT])) {
/* ping already in-flight: wait */
if (grpc_http_trace || grpc_bdp_estimator_trace) {
gpr_log(GPR_DEBUG, "Ping delayed [%p]: already pinging", t->peer_string);
}
return;
}
if (t->ping_state.pings_before_data_required == 0 &&
t->ping_policy.max_pings_without_data != 0) {
/* need to send something of substance before sending a ping again */
if (grpc_http_trace || grpc_bdp_estimator_trace) {
gpr_log(GPR_DEBUG, "Ping delayed [%p]: too many recent pings: %d/%d",
t->peer_string, t->ping_state.pings_before_data_required,
t->ping_policy.max_pings_without_data);
}
return;
}
gpr_timespec now = gpr_now(GPR_CLOCK_MONOTONIC);
gpr_timespec elapsed = gpr_time_sub(now, t->ping_state.last_ping_sent_time);
/*gpr_log(GPR_DEBUG, "elapsed:%d.%09d min:%d.%09d", (int)elapsed.tv_sec,
elapsed.tv_nsec, (int)t->ping_policy.min_time_between_pings.tv_sec,
(int)t->ping_policy.min_time_between_pings.tv_nsec);*/
if (gpr_time_cmp(elapsed, t->ping_policy.min_time_between_pings) < 0) {
/* not enough elapsed time between successive pings */
if (grpc_http_trace || grpc_bdp_estimator_trace) {
gpr_log(GPR_DEBUG,
"Ping delayed [%p]: not enough time elapsed since last ping",
t->peer_string);
}
return;
}
/* coalesce equivalent pings into this one */
switch (ping_type) {
case GRPC_CHTTP2_PING_BEFORE_TRANSPORT_WINDOW_UPDATE:
collapse_pings_from_into(t, GRPC_CHTTP2_PING_ON_NEXT_WRITE, pq);
break;
case GRPC_CHTTP2_PING_ON_NEXT_WRITE:
break;
case GRPC_CHTTP2_PING_TYPE_COUNT:
GPR_UNREACHABLE_CODE(break);
}
pq->inflight_id = t->ping_ctr * GRPC_CHTTP2_PING_TYPE_COUNT + ping_type;
t->ping_ctr++;
grpc_closure_list_sched(exec_ctx, &pq->lists[GRPC_CHTTP2_PCL_INITIATE]);
grpc_closure_list_move(&pq->lists[GRPC_CHTTP2_PCL_NEXT],
&pq->lists[GRPC_CHTTP2_PCL_INFLIGHT]);
grpc_slice_buffer_add(&t->outbuf,
grpc_chttp2_ping_create(false, pq->inflight_id));
t->ping_state.last_ping_sent_time = now;
t->ping_state.pings_before_data_required -=
(t->ping_state.pings_before_data_required != 0);
}
static void update_list(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t,
grpc_chttp2_stream *s, int64_t send_bytes,
grpc_chttp2_write_cb **list, grpc_error *error) {
@ -139,6 +208,8 @@ bool grpc_chttp2_begin_write(grpc_exec_ctx *exec_ctx,
s->sent_initial_metadata = true;
sent_initial_metadata = true;
now_writing = true;
t->ping_state.pings_before_data_required =
t->ping_policy.max_pings_without_data;
}
/* send any window updates */
if (s->announce_window > 0) {
@ -146,15 +217,22 @@ bool grpc_chttp2_begin_write(grpc_exec_ctx *exec_ctx,
grpc_slice_buffer_add(&t->outbuf,
grpc_chttp2_window_update_create(
s->id, s->announce_window, &s->stats.outgoing));
t->ping_state.pings_before_data_required =
t->ping_policy.max_pings_without_data;
GRPC_CHTTP2_FLOW_DEBIT_STREAM("write", t, s, announce_window, announce);
}
if (sent_initial_metadata) {
/* send any body bytes, if allowed by flow control */
if (s->flow_controlled_buffer.length > 0) {
uint32_t max_outgoing =
(uint32_t)GPR_MIN(t->settings[GRPC_ACKED_SETTINGS]
[GRPC_CHTTP2_SETTINGS_MAX_FRAME_SIZE],
GPR_MIN(s->outgoing_window, t->outgoing_window));
uint32_t stream_outgoing_window = (uint32_t)GPR_MAX(
0,
s->outgoing_window_delta +
(int64_t)t->settings[GRPC_PEER_SETTINGS]
[GRPC_CHTTP2_SETTINGS_INITIAL_WINDOW_SIZE]);
uint32_t max_outgoing = (uint32_t)GPR_MIN(
t->settings[GRPC_ACKED_SETTINGS]
[GRPC_CHTTP2_SETTINGS_MAX_FRAME_SIZE],
GPR_MIN(stream_outgoing_window, t->outgoing_window));
if (max_outgoing > 0) {
uint32_t send_bytes =
(uint32_t)GPR_MIN(max_outgoing, s->flow_controlled_buffer.length);
@ -167,10 +245,12 @@ bool grpc_chttp2_begin_write(grpc_exec_ctx *exec_ctx,
grpc_chttp2_encode_data(s->id, &s->flow_controlled_buffer, send_bytes,
is_last_frame, &s->stats.outgoing,
&t->outbuf);
GRPC_CHTTP2_FLOW_DEBIT_STREAM("write", t, s, outgoing_window,
GRPC_CHTTP2_FLOW_DEBIT_STREAM("write", t, s, outgoing_window_delta,
send_bytes);
GRPC_CHTTP2_FLOW_DEBIT_TRANSPORT("write", t, outgoing_window,
send_bytes);
t->ping_state.pings_before_data_required =
t->ping_policy.max_pings_without_data;
if (is_last_frame) {
s->send_trailing_metadata = NULL;
s->sent_trailing_metadata = true;
@ -189,6 +269,9 @@ bool grpc_chttp2_begin_write(grpc_exec_ctx *exec_ctx,
} else if (t->outgoing_window == 0) {
grpc_chttp2_list_add_stalled_by_transport(t, s);
now_writing = true;
} else if (stream_outgoing_window == 0) {
grpc_chttp2_list_add_stalled_by_stream(t, s);
now_writing = true;
}
}
if (s->send_trailing_metadata != NULL &&
@ -227,15 +310,32 @@ bool grpc_chttp2_begin_write(grpc_exec_ctx *exec_ctx,
/* if the grpc_chttp2_transport is ready to send a window update, do so here
also; 3/4 is a magic number that will likely get tuned soon */
if (t->announce_incoming_window > 0) {
uint32_t announced =
(uint32_t)GPR_MIN(t->announce_incoming_window, UINT32_MAX);
GRPC_CHTTP2_FLOW_DEBIT_TRANSPORT("write", t, announce_incoming_window,
announced);
uint32_t target_incoming_window = GPR_MAX(
t->settings[GRPC_SENT_SETTINGS][GRPC_CHTTP2_SETTINGS_INITIAL_WINDOW_SIZE],
1024);
uint32_t threshold_to_send_transport_window_update =
t->outbuf.count > 0 ? 3 * target_incoming_window / 4
: target_incoming_window / 2;
if (t->incoming_window <= threshold_to_send_transport_window_update) {
maybe_initiate_ping(exec_ctx, t,
GRPC_CHTTP2_PING_BEFORE_TRANSPORT_WINDOW_UPDATE);
uint32_t announced = (uint32_t)GPR_CLAMP(
target_incoming_window - t->incoming_window, 0, UINT32_MAX);
GRPC_CHTTP2_FLOW_CREDIT_TRANSPORT("write", t, incoming_window, announced);
grpc_transport_one_way_stats throwaway_stats;
grpc_slice_buffer_add(&t->outbuf, grpc_chttp2_window_update_create(
0, announced, &throwaway_stats));
t->ping_state.pings_before_data_required =
t->ping_policy.max_pings_without_data;
}
for (size_t i = 0; i < t->ping_ack_count; i++) {
grpc_slice_buffer_add(&t->outbuf,
grpc_chttp2_ping_create(1, t->ping_acks[i]));
}
t->ping_ack_count = 0;
maybe_initiate_ping(exec_ctx, t, GRPC_CHTTP2_PING_ON_NEXT_WRITE);
GPR_TIMER_END("grpc_chttp2_begin_write", 0);

@ -140,7 +140,7 @@ static void con_get_channel_info(grpc_exec_ctx *exec_ctx,
grpc_channel_element *elem,
const grpc_channel_info *channel_info) {}
static const grpc_channel_filter connected_channel_filter = {
const grpc_channel_filter grpc_connected_filter = {
con_start_transport_stream_op,
con_start_transport_op,
sizeof(call_data),
@ -158,7 +158,7 @@ static const grpc_channel_filter connected_channel_filter = {
static void bind_transport(grpc_channel_stack *channel_stack,
grpc_channel_element *elem, void *t) {
channel_data *cd = (channel_data *)elem->channel_data;
GPR_ASSERT(elem->filter == &connected_channel_filter);
GPR_ASSERT(elem->filter == &grpc_connected_filter);
GPR_ASSERT(cd->transport == NULL);
cd->transport = t;
@ -178,7 +178,7 @@ bool grpc_add_connected_filter(grpc_exec_ctx *exec_ctx,
grpc_transport *t = grpc_channel_stack_builder_get_transport(builder);
GPR_ASSERT(t != NULL);
return grpc_channel_stack_builder_append_filter(
builder, &connected_channel_filter, bind_transport, t);
builder, &grpc_connected_filter, bind_transport, t);
}
grpc_stream *grpc_connected_channel_get_stream(grpc_call_element *elem) {

@ -36,8 +36,13 @@
#include "src/core/lib/channel/channel_stack_builder.h"
extern const grpc_channel_filter grpc_connected_filter;
bool grpc_add_connected_filter(grpc_exec_ctx *exec_ctx,
grpc_channel_stack_builder *builder,
void *arg_must_be_null);
/* Debug helper to dig the transport stream out of a call element */
grpc_stream *grpc_connected_channel_get_stream(grpc_call_element *elem);
#endif /* GRPC_CORE_LIB_CHANNEL_CONNECTED_CHANNEL_H */

@ -51,20 +51,22 @@ void grpc_closure_list_init(grpc_closure_list *closure_list) {
closure_list->head = closure_list->tail = NULL;
}
void grpc_closure_list_append(grpc_closure_list *closure_list,
bool grpc_closure_list_append(grpc_closure_list *closure_list,
grpc_closure *closure, grpc_error *error) {
if (closure == NULL) {
GRPC_ERROR_UNREF(error);
return;
return false;
}
closure->error_data.error = error;
closure->next_data.next = NULL;
if (closure_list->head == NULL) {
bool was_empty = (closure_list->head == NULL);
if (was_empty) {
closure_list->head = closure;
} else {
closure_list->tail->next_data.next = closure;
}
closure_list->tail = closure;
return was_empty;
}
void grpc_closure_list_fail_all(grpc_closure_list *list,

@ -116,8 +116,9 @@ grpc_closure *grpc_closure_create(grpc_iomgr_cb_func cb, void *cb_arg,
void grpc_closure_list_init(grpc_closure_list *list);
/** add \a closure to the end of \a list
and set \a closure's result to \a error */
void grpc_closure_list_append(grpc_closure_list *list, grpc_closure *closure,
and set \a closure's result to \a error
Returns true if \a list becomes non-empty */
bool grpc_closure_list_append(grpc_closure_list *list, grpc_closure *closure,
grpc_error *error);
/** force all success bits in \a list to false */

@ -33,6 +33,8 @@
#include "src/core/lib/iomgr/resource_quota.h"
#include <limits.h>
#include <stdint.h>
#include <string.h>
#include <grpc/support/alloc.h>
@ -44,6 +46,8 @@
int grpc_resource_quota_trace = 0;
#define MEMORY_USAGE_ESTIMATION_MAX 65536
/* Internal linked list pointers for a resource user */
typedef struct {
grpc_resource_user *next;
@ -126,9 +130,12 @@ struct grpc_resource_quota {
/* refcount */
gpr_refcount refs;
/* estimate of current memory usage
scaled to the range [0..RESOURCE_USAGE_ESTIMATION_MAX] */
gpr_atm memory_usage_estimation;
/* Master combiner lock: all activity on a quota executes under this combiner
* (so no mutex is needed for this data structure)
*/
* (so no mutex is needed for this data structure) */
grpc_combiner *combiner;
/* Size of the resource quota */
int64_t size;
@ -269,6 +276,16 @@ static void rq_step_sched(grpc_exec_ctx *exec_ctx,
GRPC_ERROR_NONE);
}
/* update the atomically available resource estimate - use no barriers since
timeliness of delivery really doesn't matter much */
static void rq_update_estimate(grpc_resource_quota *resource_quota) {
gpr_atm_no_barrier_store(&resource_quota->memory_usage_estimation,
(gpr_atm)((1.0 -
((double)resource_quota->free_pool) /
((double)resource_quota->size)) *
MEMORY_USAGE_ESTIMATION_MAX));
}
/* returns true if all allocations are completed */
static bool rq_alloc(grpc_exec_ctx *exec_ctx,
grpc_resource_quota *resource_quota) {
@ -281,6 +298,7 @@ static bool rq_alloc(grpc_exec_ctx *exec_ctx,
int64_t amt = -resource_user->free_pool;
resource_user->free_pool = 0;
resource_quota->free_pool -= amt;
rq_update_estimate(resource_quota);
if (grpc_resource_quota_trace) {
gpr_log(GPR_DEBUG, "RQ %s %s: grant alloc %" PRId64
" bytes; rq_free_pool -> %" PRId64,
@ -315,6 +333,7 @@ static bool rq_reclaim_from_per_user_free_pool(
int64_t amt = resource_user->free_pool;
resource_user->free_pool = 0;
resource_quota->free_pool += amt;
rq_update_estimate(resource_quota);
if (grpc_resource_quota_trace) {
gpr_log(GPR_DEBUG, "RQ %s %s: reclaim_from_per_user_free_pool %" PRId64
" bytes; rq_free_pool -> %" PRId64,
@ -531,6 +550,7 @@ static void rq_resize(grpc_exec_ctx *exec_ctx, void *args, grpc_error *error) {
int64_t delta = a->size - a->resource_quota->size;
a->resource_quota->size += delta;
a->resource_quota->free_pool += delta;
rq_update_estimate(a->resource_quota);
rq_step_sched(exec_ctx, a->resource_quota);
grpc_resource_quota_unref_internal(exec_ctx, a->resource_quota);
gpr_free(a);
@ -557,6 +577,7 @@ grpc_resource_quota *grpc_resource_quota_create(const char *name) {
resource_quota->size = INT64_MAX;
resource_quota->step_scheduled = false;
resource_quota->reclaiming = false;
gpr_atm_no_barrier_store(&resource_quota->memory_usage_estimation, 0);
if (name != NULL) {
resource_quota->name = gpr_strdup(name);
} else {
@ -602,6 +623,13 @@ void grpc_resource_quota_ref(grpc_resource_quota *resource_quota) {
grpc_resource_quota_ref_internal(resource_quota);
}
double grpc_resource_quota_get_memory_pressure(
grpc_resource_quota *resource_quota) {
return ((double)(gpr_atm_no_barrier_load(
&resource_quota->memory_usage_estimation))) /
((double)MEMORY_USAGE_ESTIMATION_MAX);
}
/* Public API */
void grpc_resource_quota_resize(grpc_resource_quota *resource_quota,
size_t size) {

@ -84,6 +84,12 @@ void grpc_resource_quota_unref_internal(grpc_exec_ctx *exec_ctx,
grpc_resource_quota *grpc_resource_quota_from_channel_args(
const grpc_channel_args *channel_args);
/* Return a number indicating current memory pressure:
0.0 ==> no memory usage
1.0 ==> maximum memory usage */
double grpc_resource_quota_get_memory_pressure(
grpc_resource_quota *resource_quota);
typedef struct grpc_resource_user grpc_resource_user;
grpc_resource_user *grpc_resource_user_create(

@ -190,31 +190,37 @@ int grpc_sockaddr_to_string(char **out,
}
char *grpc_sockaddr_to_uri(const grpc_resolved_address *resolved_addr) {
char *temp;
char *result;
grpc_resolved_address addr_normalized;
const struct sockaddr *addr;
if (grpc_sockaddr_is_v4mapped(resolved_addr, &addr_normalized)) {
resolved_addr = &addr_normalized;
}
const char *scheme = grpc_sockaddr_get_uri_scheme(resolved_addr);
if (scheme == NULL || strcmp("unix", scheme) == 0) {
return grpc_sockaddr_to_uri_unix_if_possible(resolved_addr);
}
char *path = NULL;
char *uri_str = NULL;
if (grpc_sockaddr_to_string(&path, resolved_addr,
false /* suppress errors */) &&
scheme != NULL) {
gpr_asprintf(&uri_str, "%s:%s", scheme, path);
}
gpr_free(path);
return uri_str != NULL ? uri_str : NULL;
}
addr = (const struct sockaddr *)resolved_addr->addr;
const char *grpc_sockaddr_get_uri_scheme(
const grpc_resolved_address *resolved_addr) {
const struct sockaddr *addr = (const struct sockaddr *)resolved_addr->addr;
switch (addr->sa_family) {
case AF_INET:
grpc_sockaddr_to_string(&temp, resolved_addr, 0);
gpr_asprintf(&result, "ipv4:%s", temp);
gpr_free(temp);
return result;
return "ipv4";
case AF_INET6:
grpc_sockaddr_to_string(&temp, resolved_addr, 0);
gpr_asprintf(&result, "ipv6:%s", temp);
gpr_free(temp);
return result;
default:
return grpc_sockaddr_to_uri_unix_if_possible(resolved_addr);
return "ipv6";
case AF_UNIX:
return "unix";
}
return NULL;
}
int grpc_sockaddr_get_port(const grpc_resolved_address *resolved_addr) {

@ -84,6 +84,10 @@ int grpc_sockaddr_set_port(const grpc_resolved_address *addr, int port);
int grpc_sockaddr_to_string(char **out, const grpc_resolved_address *addr,
int normalize);
/* Returns the URI string corresponding to \a addr */
char *grpc_sockaddr_to_uri(const grpc_resolved_address *addr);
/* Returns the URI scheme corresponding to \a addr */
const char *grpc_sockaddr_get_uri_scheme(const grpc_resolved_address *addr);
#endif /* GRPC_CORE_LIB_IOMGR_SOCKADDR_UTILS_H */

@ -76,8 +76,10 @@ struct grpc_udp_listener {
grpc_udp_server *server;
grpc_resolved_address addr;
grpc_closure read_closure;
grpc_closure write_closure;
grpc_closure destroyed_closure;
grpc_udp_server_read_cb read_cb;
grpc_udp_server_write_cb write_cb;
grpc_udp_server_orphan_cb orphan_cb;
struct grpc_udp_listener *next;
@ -176,7 +178,7 @@ static void deactivated_all_ports(grpc_exec_ctx *exec_ctx, grpc_udp_server *s) {
/* Call the orphan_cb to signal that the FD is about to be closed and
* should no longer be used. */
GPR_ASSERT(sp->orphan_cb);
sp->orphan_cb(sp->emfd);
sp->orphan_cb(exec_ctx, sp->emfd);
grpc_fd_orphan(exec_ctx, sp->emfd, &sp->destroyed_closure, NULL,
"udp_listener_shutdown");
@ -202,7 +204,7 @@ void grpc_udp_server_destroy(grpc_exec_ctx *exec_ctx, grpc_udp_server *s,
if (s->active_ports) {
for (sp = s->head; sp; sp = sp->next) {
GPR_ASSERT(sp->orphan_cb);
sp->orphan_cb(sp->emfd);
sp->orphan_cb(exec_ctx, sp->emfd);
grpc_fd_shutdown(exec_ctx, sp->emfd,
GRPC_ERROR_CREATE("Server destroyed"));
}
@ -304,9 +306,33 @@ static void on_read(grpc_exec_ctx *exec_ctx, void *arg, grpc_error *error) {
gpr_mu_unlock(&sp->server->mu);
}
static void on_write(grpc_exec_ctx *exec_ctx, void *arg, grpc_error *error) {
grpc_udp_listener *sp = arg;
gpr_mu_lock(&(sp->server->mu));
if (error != GRPC_ERROR_NONE) {
if (0 == --sp->server->active_ports) {
gpr_mu_unlock(&sp->server->mu);
deactivated_all_ports(exec_ctx, sp->server);
} else {
gpr_mu_unlock(&sp->server->mu);
}
return;
}
/* Tell the registered callback that the socket is writeable. */
GPR_ASSERT(sp->write_cb);
sp->write_cb(exec_ctx, sp->emfd);
/* Re-arm the notification event so we get another chance to write. */
grpc_fd_notify_on_write(exec_ctx, sp->emfd, &sp->write_closure);
gpr_mu_unlock(&sp->server->mu);
}
static int add_socket_to_server(grpc_udp_server *s, int fd,
const grpc_resolved_address *addr,
grpc_udp_server_read_cb read_cb,
grpc_udp_server_write_cb write_cb,
grpc_udp_server_orphan_cb orphan_cb) {
grpc_udp_listener *sp;
int port;
@ -333,6 +359,7 @@ static int add_socket_to_server(grpc_udp_server *s, int fd,
sp->emfd = grpc_fd_create(fd, name);
memcpy(&sp->addr, addr, sizeof(grpc_resolved_address));
sp->read_cb = read_cb;
sp->write_cb = write_cb;
sp->orphan_cb = orphan_cb;
GPR_ASSERT(sp->emfd);
gpr_mu_unlock(&s->mu);
@ -345,6 +372,7 @@ static int add_socket_to_server(grpc_udp_server *s, int fd,
int grpc_udp_server_add_port(grpc_udp_server *s,
const grpc_resolved_address *addr,
grpc_udp_server_read_cb read_cb,
grpc_udp_server_write_cb write_cb,
grpc_udp_server_orphan_cb orphan_cb) {
grpc_udp_listener *sp;
int allocated_port1 = -1;
@ -391,7 +419,8 @@ int grpc_udp_server_add_port(grpc_udp_server *s,
// TODO(rjshade): Test and propagate the returned grpc_error*:
GRPC_ERROR_UNREF(grpc_create_dualstack_socket(addr, SOCK_DGRAM, IPPROTO_UDP,
&dsmode, &fd));
allocated_port1 = add_socket_to_server(s, fd, addr, read_cb, orphan_cb);
allocated_port1 =
add_socket_to_server(s, fd, addr, read_cb, write_cb, orphan_cb);
if (fd >= 0 && dsmode == GRPC_DSMODE_DUALSTACK) {
goto done;
}
@ -413,7 +442,8 @@ int grpc_udp_server_add_port(grpc_udp_server *s,
grpc_sockaddr_is_v4mapped(addr, &addr4_copy)) {
addr = &addr4_copy;
}
allocated_port2 = add_socket_to_server(s, fd, addr, read_cb, orphan_cb);
allocated_port2 =
add_socket_to_server(s, fd, addr, read_cb, write_cb, orphan_cb);
done:
gpr_free(allocated_addr);
@ -451,6 +481,10 @@ void grpc_udp_server_start(grpc_exec_ctx *exec_ctx, grpc_udp_server *s,
grpc_schedule_on_exec_ctx);
grpc_fd_notify_on_read(exec_ctx, sp->emfd, &sp->read_closure);
grpc_closure_init(&sp->write_closure, on_write, sp,
grpc_schedule_on_exec_ctx);
grpc_fd_notify_on_write(exec_ctx, sp->emfd, &sp->write_closure);
s->active_ports++;
sp = sp->next;
}

@ -49,8 +49,13 @@ typedef struct grpc_udp_server grpc_udp_server;
typedef void (*grpc_udp_server_read_cb)(grpc_exec_ctx *exec_ctx, grpc_fd *emfd,
struct grpc_server *server);
/* Called when the socket is writeable. */
typedef void (*grpc_udp_server_write_cb)(grpc_exec_ctx *exec_ctx,
grpc_fd *emfd);
/* Called when the grpc_fd is about to be orphaned (and the FD closed). */
typedef void (*grpc_udp_server_orphan_cb)(grpc_fd *emfd);
typedef void (*grpc_udp_server_orphan_cb)(grpc_exec_ctx *exec_ctx,
grpc_fd *emfd);
/* Create a server, initially not bound to any ports */
grpc_udp_server *grpc_udp_server_create(void);
@ -75,6 +80,7 @@ int grpc_udp_server_get_fd(grpc_udp_server *s, unsigned port_index);
int grpc_udp_server_add_port(grpc_udp_server *s,
const grpc_resolved_address *addr,
grpc_udp_server_read_cb read_cb,
grpc_udp_server_write_cb write_cb,
grpc_udp_server_orphan_cb orphan_cb);
void grpc_udp_server_destroy(grpc_exec_ctx *exec_ctx, grpc_udp_server *server,

@ -43,6 +43,9 @@
#include <grpc/support/thd.h>
#include <grpc/support/time.h>
#include <stdio.h>
#include <string.h>
#include "src/core/lib/support/env.h"
typedef enum { BEGIN = '{', END = '}', MARK = '.' } marker_type;
@ -74,7 +77,7 @@ typedef struct gpr_timer_log_list {
static __thread gpr_timer_log *g_thread_log;
static gpr_once g_once_init = GPR_ONCE_INIT;
static FILE *output_file;
static const char *output_filename = "latency_trace.txt";
static const char *output_filename_or_null = NULL;
static pthread_mutex_t g_mu;
static pthread_cond_t g_cv;
static gpr_timer_log_list g_in_progress_logs;
@ -85,6 +88,17 @@ static __thread int g_thread_id;
static int g_next_thread_id;
static int g_writing_enabled = 1;
static const char *output_filename() {
if (output_filename_or_null == NULL) {
output_filename_or_null = gpr_getenv("LATENCY_TRACE");
if (output_filename_or_null == NULL ||
strlen(output_filename_or_null) == 0) {
output_filename_or_null = "latency_trace.txt";
}
}
return output_filename_or_null;
}
static int timer_log_push_back(gpr_timer_log_list *list, gpr_timer_log *log) {
if (list->head == NULL) {
list->head = list->tail = log;
@ -134,7 +148,7 @@ static void timer_log_remove(gpr_timer_log_list *list, gpr_timer_log *log) {
static void write_log(gpr_timer_log *log) {
size_t i;
if (output_file == NULL) {
output_file = fopen(output_filename, "w");
output_file = fopen(output_filename(), "w");
}
for (i = 0; i < log->num_entries; i++) {
gpr_timer_entry *entry = &(log->log[i]);
@ -198,7 +212,7 @@ static void finish_writing(void) {
}
void gpr_timers_set_log_filename(const char *filename) {
output_filename = filename;
output_filename_or_null = filename;
}
static void init_output() {

@ -160,6 +160,53 @@ grpc_channel_credentials_duplicate_without_call_credentials(
}
}
static void credentials_pointer_arg_destroy(grpc_exec_ctx *exec_ctx, void *p) {
grpc_channel_credentials_unref(exec_ctx, p);
}
static void *credentials_pointer_arg_copy(void *p) {
return grpc_channel_credentials_ref(p);
}
static int credentials_pointer_cmp(void *a, void *b) { return GPR_ICMP(a, b); }
static const grpc_arg_pointer_vtable credentials_pointer_vtable = {
credentials_pointer_arg_copy, credentials_pointer_arg_destroy,
credentials_pointer_cmp};
grpc_arg grpc_channel_credentials_to_arg(
grpc_channel_credentials *credentials) {
grpc_arg result;
result.type = GRPC_ARG_POINTER;
result.key = GRPC_ARG_CHANNEL_CREDENTIALS;
result.value.pointer.vtable = &credentials_pointer_vtable;
result.value.pointer.p = credentials;
return result;
}
grpc_channel_credentials *grpc_channel_credentials_from_arg(
const grpc_arg *arg) {
if (strcmp(arg->key, GRPC_ARG_CHANNEL_CREDENTIALS)) return NULL;
if (arg->type != GRPC_ARG_POINTER) {
gpr_log(GPR_ERROR, "Invalid type %d for arg %s", arg->type,
GRPC_ARG_CHANNEL_CREDENTIALS);
return NULL;
}
return arg->value.pointer.p;
}
grpc_channel_credentials *grpc_channel_credentials_find_in_args(
const grpc_channel_args *args) {
size_t i;
if (args == NULL) return NULL;
for (i = 0; i < args->num_args; i++) {
grpc_channel_credentials *credentials =
grpc_channel_credentials_from_arg(&args->args[i]);
if (credentials != NULL) return credentials;
}
return NULL;
}
grpc_server_credentials *grpc_server_credentials_ref(
grpc_server_credentials *creds) {
if (creds == NULL) return NULL;

@ -100,6 +100,8 @@ void grpc_override_well_known_credentials_path_getter(
/* --- grpc_channel_credentials. --- */
#define GRPC_ARG_CHANNEL_CREDENTIALS "grpc.channel_credentials"
typedef struct {
void (*destruct)(grpc_exec_ctx *exec_ctx, grpc_channel_credentials *c);
@ -140,6 +142,17 @@ grpc_channel_credentials *
grpc_channel_credentials_duplicate_without_call_credentials(
grpc_channel_credentials *creds);
/* Util to encapsulate the channel credentials in a channel arg. */
grpc_arg grpc_channel_credentials_to_arg(grpc_channel_credentials *credentials);
/* Util to get the channel credentials from a channel arg. */
grpc_channel_credentials *grpc_channel_credentials_from_arg(
const grpc_arg *arg);
/* Util to find the channel credentials from channel args. */
grpc_channel_credentials *grpc_channel_credentials_find_in_args(
const grpc_channel_args *args);
/* --- grpc_credentials_md. --- */
typedef struct {

@ -35,13 +35,13 @@
#include <string.h>
#include "src/core/lib/channel/channel_args.h"
#include "src/core/lib/iomgr/executor.h"
#include <grpc/support/alloc.h>
#include <grpc/support/log.h>
#include <grpc/support/string_util.h>
#include "src/core/lib/iomgr/executor.h"
#include "src/core/lib/support/string.h"
/* -- Fake transport security credentials. -- */
static grpc_security_status fake_transport_security_create_security_connector(
@ -49,7 +49,7 @@ static grpc_security_status fake_transport_security_create_security_connector(
grpc_call_credentials *call_creds, const char *target,
const grpc_channel_args *args, grpc_channel_security_connector **sc,
grpc_channel_args **new_args) {
*sc = grpc_fake_channel_security_connector_create(call_creds);
*sc = grpc_fake_channel_security_connector_create(call_creds, target, args);
return GRPC_SECURITY_OK;
}

@ -38,6 +38,21 @@
/* -- Fake transport security credentials. -- */
/* Used to verify the target names given to the fake transport security
* connector.
*
* Its syntax by example:
* For LB channels:
* "backend_target_1,backend_target_2,...;lb_target_1,lb_target_2,..."
* For regular channels:
* "backend_taget_1,backend_target_2,..."
*
* That is to say, LB channels have a heading list of LB targets separated from
* the list of backend targets by a semicolon. For non-LB channels, only the
* latter is present. */
#define GRPC_ARG_FAKE_SECURITY_EXPECTED_TARGETS \
"grpc.test_only.fake_security.expected_target"
/* Creates a fake transport security credentials object for testing. */
grpc_channel_credentials *grpc_fake_transport_security_credentials_create(void);

@ -335,7 +335,7 @@ static grpc_error *init_channel_elem(grpc_exec_ctx *exec_ctx,
grpc_channel_element *elem,
grpc_channel_element_args *args) {
grpc_security_connector *sc =
grpc_find_security_connector_in_args(args->channel_args);
grpc_security_connector_find_in_args(args->channel_args);
grpc_auth_context *auth_context =
grpc_find_auth_context_in_args(args->channel_args);

@ -0,0 +1,70 @@
/*
*
* Copyright 2017, Google Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following disclaimer
* in the documentation and/or other materials provided with the
* distribution.
* * Neither the name of Google Inc. nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#include <grpc/support/log.h>
#include "src/core/lib/channel/channel_args.h"
#include "src/core/lib/security/transport/lb_targets_info.h"
/* Channel arg key for the mapping of LB server addresses to their names for
* secure naming purposes. */
#define GRPC_ARG_LB_SECURE_NAMING_MAP "grpc.lb_secure_naming_map"
static void *targets_info_copy(void *p) { return grpc_slice_hash_table_ref(p); }
static void targets_info_destroy(grpc_exec_ctx *exec_ctx, void *p) {
grpc_slice_hash_table_unref(exec_ctx, p);
}
static int targets_info_cmp(void *a, void *b) { return GPR_ICMP(a, b); }
static const grpc_arg_pointer_vtable server_to_balancer_names_vtable = {
targets_info_copy, targets_info_destroy, targets_info_cmp};
grpc_arg grpc_lb_targets_info_create_channel_arg(
grpc_slice_hash_table *targets_info) {
grpc_arg arg;
arg.type = GRPC_ARG_POINTER;
arg.key = GRPC_ARG_LB_SECURE_NAMING_MAP;
arg.value.pointer.p = targets_info;
arg.value.pointer.vtable = &server_to_balancer_names_vtable;
return arg;
}
grpc_slice_hash_table *grpc_lb_targets_info_find_in_args(
const grpc_channel_args *args) {
const grpc_arg *targets_info_arg =
grpc_channel_args_find(args, GRPC_ARG_LB_SECURE_NAMING_MAP);
if (targets_info_arg != NULL) {
GPR_ASSERT(targets_info_arg->type == GRPC_ARG_POINTER);
return targets_info_arg->value.pointer.p;
}
return NULL;
}

@ -0,0 +1,47 @@
/*
*
* Copyright 2017, Google Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following disclaimer
* in the documentation and/or other materials provided with the
* distribution.
* * Neither the name of Google Inc. nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#ifndef GRPC_CORE_LIB_SECURITY_TRANSPORT_LB_TARGETS_INFO_H
#define GRPC_CORE_LIB_SECURITY_TRANSPORT_LB_TARGETS_INFO_H
#include "src/core/lib/slice/slice_hash_table.h"
/** Return a channel argument containing \a targets_info. */
grpc_arg grpc_lb_targets_info_create_channel_arg(
grpc_slice_hash_table *targets_info);
/** Return the instance of targets info in \a args or NULL */
grpc_slice_hash_table *grpc_lb_targets_info_find_in_args(
const grpc_channel_args *args);
#endif /* GRPC_CORE_LIB_SECURITY_TRANSPORT_LB_TARGETS_INFO_H */

@ -43,10 +43,13 @@
#include <grpc/support/string_util.h>
#include "src/core/ext/transport/chttp2/alpn/alpn.h"
#include "src/core/lib/channel/channel_args.h"
#include "src/core/lib/channel/handshaker.h"
#include "src/core/lib/iomgr/load_file.h"
#include "src/core/lib/security/context/security_context.h"
#include "src/core/lib/security/credentials/credentials.h"
#include "src/core/lib/security/credentials/fake/fake_credentials.h"
#include "src/core/lib/security/transport/lb_targets_info.h"
#include "src/core/lib/security/transport/secure_endpoint.h"
#include "src/core/lib/security/transport/security_handshaker.h"
#include "src/core/lib/support/env.h"
@ -205,23 +208,23 @@ static const grpc_arg_pointer_vtable connector_pointer_vtable = {
grpc_arg grpc_security_connector_to_arg(grpc_security_connector *sc) {
grpc_arg result;
result.type = GRPC_ARG_POINTER;
result.key = GRPC_SECURITY_CONNECTOR_ARG;
result.key = GRPC_ARG_SECURITY_CONNECTOR;
result.value.pointer.vtable = &connector_pointer_vtable;
result.value.pointer.p = sc;
return result;
}
grpc_security_connector *grpc_security_connector_from_arg(const grpc_arg *arg) {
if (strcmp(arg->key, GRPC_SECURITY_CONNECTOR_ARG)) return NULL;
if (strcmp(arg->key, GRPC_ARG_SECURITY_CONNECTOR)) return NULL;
if (arg->type != GRPC_ARG_POINTER) {
gpr_log(GPR_ERROR, "Invalid type %d for arg %s", arg->type,
GRPC_SECURITY_CONNECTOR_ARG);
GRPC_ARG_SECURITY_CONNECTOR);
return NULL;
}
return arg->value.pointer.p;
}
grpc_security_connector *grpc_find_security_connector_in_args(
grpc_security_connector *grpc_security_connector_find_in_args(
const grpc_channel_args *args) {
size_t i;
if (args == NULL) return NULL;
@ -235,11 +238,21 @@ grpc_security_connector *grpc_find_security_connector_in_args(
/* -- Fake implementation. -- */
typedef struct {
grpc_channel_security_connector base;
char *target;
char *expected_targets;
bool is_lb_channel;
} grpc_fake_channel_security_connector;
static void fake_channel_destroy(grpc_exec_ctx *exec_ctx,
grpc_security_connector *sc) {
grpc_channel_security_connector *c = (grpc_channel_security_connector *)sc;
grpc_call_credentials_unref(exec_ctx, c->request_metadata_creds);
gpr_free(sc);
grpc_fake_channel_security_connector *c =
(grpc_fake_channel_security_connector *)sc;
grpc_call_credentials_unref(exec_ctx, c->base.request_metadata_creds);
gpr_free(c->target);
gpr_free(c->expected_targets);
gpr_free(c);
}
static void fake_server_destroy(grpc_exec_ctx *exec_ctx,
@ -247,6 +260,68 @@ static void fake_server_destroy(grpc_exec_ctx *exec_ctx,
gpr_free(sc);
}
static bool fake_check_target(const char *target_type, const char *target,
const char *set_str) {
GPR_ASSERT(target_type != NULL);
GPR_ASSERT(target != NULL);
char **set = NULL;
size_t set_size = 0;
gpr_string_split(set_str, ",", &set, &set_size);
bool found = false;
for (size_t i = 0; i < set_size; ++i) {
if (set[i] != NULL && strcmp(target, set[i]) == 0) found = true;
}
for (size_t i = 0; i < set_size; ++i) {
gpr_free(set[i]);
}
gpr_free(set);
return found;
}
static void fake_secure_name_check(const char *target,
const char *expected_targets,
bool is_lb_channel) {
if (expected_targets == NULL) return;
char **lbs_and_backends = NULL;
size_t lbs_and_backends_size = 0;
bool success = false;
gpr_string_split(expected_targets, ";", &lbs_and_backends,
&lbs_and_backends_size);
if (lbs_and_backends_size > 2 || lbs_and_backends_size == 0) {
gpr_log(GPR_ERROR, "Invalid expected targets arg value: '%s'",
expected_targets);
goto done;
}
if (is_lb_channel) {
if (lbs_and_backends_size != 2) {
gpr_log(GPR_ERROR,
"Invalid expected targets arg value: '%s'. Expectations for LB "
"channels must be of the form 'be1,be2,be3,...;lb1,lb2,...",
expected_targets);
goto done;
}
if (!fake_check_target("LB", target, lbs_and_backends[1])) {
gpr_log(GPR_ERROR, "LB target '%s' not found in expected set '%s'",
target, lbs_and_backends[1]);
goto done;
}
success = true;
} else {
if (!fake_check_target("Backend", target, lbs_and_backends[0])) {
gpr_log(GPR_ERROR, "Backend target '%s' not found in expected set '%s'",
target, lbs_and_backends[0]);
goto done;
}
success = true;
}
done:
for (size_t i = 0; i < lbs_and_backends_size; ++i) {
gpr_free(lbs_and_backends[i]);
}
gpr_free(lbs_and_backends);
if (!success) abort();
}
static void fake_check_peer(grpc_exec_ctx *exec_ctx,
grpc_security_connector *sc, tsi_peer peer,
grpc_auth_context **auth_context,
@ -277,12 +352,28 @@ static void fake_check_peer(grpc_exec_ctx *exec_ctx,
grpc_auth_context_add_cstring_property(
*auth_context, GRPC_TRANSPORT_SECURITY_TYPE_PROPERTY_NAME,
GRPC_FAKE_TRANSPORT_SECURITY_TYPE);
end:
grpc_closure_sched(exec_ctx, on_peer_checked, error);
tsi_peer_destruct(&peer);
}
static void fake_channel_check_peer(grpc_exec_ctx *exec_ctx,
grpc_security_connector *sc, tsi_peer peer,
grpc_auth_context **auth_context,
grpc_closure *on_peer_checked) {
fake_check_peer(exec_ctx, sc, peer, auth_context, on_peer_checked);
grpc_fake_channel_security_connector *c =
(grpc_fake_channel_security_connector *)sc;
fake_secure_name_check(c->target, c->expected_targets, c->is_lb_channel);
}
static void fake_server_check_peer(grpc_exec_ctx *exec_ctx,
grpc_security_connector *sc, tsi_peer peer,
grpc_auth_context **auth_context,
grpc_closure *on_peer_checked) {
fake_check_peer(exec_ctx, sc, peer, auth_context, on_peer_checked);
}
static void fake_channel_check_call_host(grpc_exec_ctx *exec_ctx,
grpc_channel_security_connector *sc,
const char *host,
@ -313,22 +404,32 @@ static void fake_server_add_handshakers(grpc_exec_ctx *exec_ctx,
}
static grpc_security_connector_vtable fake_channel_vtable = {
fake_channel_destroy, fake_check_peer};
fake_channel_destroy, fake_channel_check_peer};
static grpc_security_connector_vtable fake_server_vtable = {fake_server_destroy,
fake_check_peer};
static grpc_security_connector_vtable fake_server_vtable = {
fake_server_destroy, fake_server_check_peer};
grpc_channel_security_connector *grpc_fake_channel_security_connector_create(
grpc_call_credentials *request_metadata_creds) {
grpc_channel_security_connector *c = gpr_malloc(sizeof(*c));
grpc_call_credentials *request_metadata_creds, const char *target,
const grpc_channel_args *args) {
grpc_fake_channel_security_connector *c = gpr_malloc(sizeof(*c));
memset(c, 0, sizeof(*c));
gpr_ref_init(&c->base.refcount, 1);
c->base.url_scheme = GRPC_FAKE_SECURITY_URL_SCHEME;
c->base.vtable = &fake_channel_vtable;
c->request_metadata_creds = grpc_call_credentials_ref(request_metadata_creds);
c->check_call_host = fake_channel_check_call_host;
c->add_handshakers = fake_channel_add_handshakers;
return c;
gpr_ref_init(&c->base.base.refcount, 1);
c->base.base.url_scheme = GRPC_FAKE_SECURITY_URL_SCHEME;
c->base.base.vtable = &fake_channel_vtable;
c->base.request_metadata_creds =
grpc_call_credentials_ref(request_metadata_creds);
c->base.check_call_host = fake_channel_check_call_host;
c->base.add_handshakers = fake_channel_add_handshakers;
c->target = gpr_strdup(target);
const grpc_arg *expected_target_arg =
grpc_channel_args_find(args, GRPC_ARG_FAKE_SECURITY_EXPECTED_TARGETS);
if (expected_target_arg != NULL) {
GPR_ASSERT(expected_target_arg->type == GRPC_ARG_STRING);
c->expected_targets = gpr_strdup(expected_target_arg->value.string);
}
c->is_lb_channel = (grpc_lb_targets_info_find_in_args(args) != NULL);
return &c->base;
}
grpc_server_security_connector *grpc_fake_server_security_connector_create(

@ -57,7 +57,7 @@ typedef enum { GRPC_SECURITY_OK = 0, GRPC_SECURITY_ERROR } grpc_security_status;
typedef struct grpc_security_connector grpc_security_connector;
#define GRPC_SECURITY_CONNECTOR_ARG "grpc.security_connector"
#define GRPC_ARG_SECURITY_CONNECTOR "grpc.security_connector"
typedef struct {
void (*destroy)(grpc_exec_ctx *exec_ctx, grpc_security_connector *sc);
@ -115,7 +115,7 @@ grpc_arg grpc_security_connector_to_arg(grpc_security_connector *sc);
grpc_security_connector *grpc_security_connector_from_arg(const grpc_arg *arg);
/* Util to find the connector from channel args. */
grpc_security_connector *grpc_find_security_connector_in_args(
grpc_security_connector *grpc_security_connector_find_in_args(
const grpc_channel_args *args);
/* --- channel_security_connector object. ---
@ -175,7 +175,8 @@ void grpc_server_security_connector_add_handshakers(
/* For TESTING ONLY!
Creates a fake connector that emulates real channel security. */
grpc_channel_security_connector *grpc_fake_channel_security_connector_create(
grpc_call_credentials *request_metadata_creds);
grpc_call_credentials *request_metadata_creds, const char *target,
const grpc_channel_args *args);
/* For TESTING ONLY!
Creates a fake connector that emulates real server security. */

@ -451,7 +451,7 @@ static void client_handshaker_factory_add_handshakers(
grpc_exec_ctx *exec_ctx, grpc_handshaker_factory *handshaker_factory,
const grpc_channel_args *args, grpc_handshake_manager *handshake_mgr) {
grpc_channel_security_connector *security_connector =
(grpc_channel_security_connector *)grpc_find_security_connector_in_args(
(grpc_channel_security_connector *)grpc_security_connector_find_in_args(
args);
grpc_channel_security_connector_add_handshakers(exec_ctx, security_connector,
handshake_mgr);
@ -461,7 +461,7 @@ static void server_handshaker_factory_add_handshakers(
grpc_exec_ctx *exec_ctx, grpc_handshaker_factory *hf,
const grpc_channel_args *args, grpc_handshake_manager *handshake_mgr) {
grpc_server_security_connector *security_connector =
(grpc_server_security_connector *)grpc_find_security_connector_in_args(
(grpc_server_security_connector *)grpc_security_connector_find_in_args(
args);
grpc_server_security_connector_add_handshakers(exec_ctx, security_connector,
handshake_mgr);

@ -215,7 +215,9 @@ bool grpc_slice_is_interned(grpc_slice slice) {
}
grpc_slice grpc_slice_intern(grpc_slice slice) {
GPR_TIMER_BEGIN("grpc_slice_intern", 0);
if (GRPC_IS_STATIC_METADATA_STRING(slice)) {
GPR_TIMER_END("grpc_slice_intern", 0);
return slice;
}
@ -225,6 +227,7 @@ grpc_slice grpc_slice_intern(grpc_slice slice) {
static_metadata_hash[(hash + i) % GPR_ARRAY_SIZE(static_metadata_hash)];
if (ent.hash == hash && ent.idx < GRPC_STATIC_MDSTR_COUNT &&
grpc_slice_eq(grpc_static_slice_table[ent.idx], slice)) {
GPR_TIMER_END("grpc_slice_intern", 0);
return grpc_static_slice_table[ent.idx];
}
}
@ -247,7 +250,7 @@ grpc_slice grpc_slice_intern(grpc_slice slice) {
/* and treat this as if we were never here... sshhh */
} else {
gpr_mu_unlock(&shard->mu);
GPR_TIMER_END("grpc_mdstr_from_buffer", 0);
GPR_TIMER_END("grpc_slice_intern", 0);
return materialize(s);
}
}
@ -275,6 +278,7 @@ grpc_slice grpc_slice_intern(grpc_slice slice) {
gpr_mu_unlock(&shard->mu);
GPR_TIMER_END("grpc_slice_intern", 0);
return materialize(s);
}

@ -37,6 +37,7 @@
#include <grpc/support/alloc.h>
#include <grpc/support/log.h>
#include <grpc/support/string_util.h>
#include <grpc/support/time.h>
#include <pthread.h>
#include <stdarg.h>
@ -93,10 +94,13 @@ void gpr_default_log(gpr_log_func_args *args) {
strcpy(time_buffer, "error:strftime");
}
fprintf(stderr, "%s%s.%09d %7tu %s:%d] %s\n",
gpr_log_severity_string(args->severity), time_buffer,
(int)(now.tv_nsec), gettid(), display_file, args->line,
args->message);
char *prefix;
gpr_asprintf(&prefix, "%s%s.%09d %7tu %s:%d]",
gpr_log_severity_string(args->severity), time_buffer,
(int)(now.tv_nsec), gettid(), display_file, args->line);
fprintf(stderr, "%-70s %s\n", prefix, args->message);
gpr_free(prefix);
}
#endif /* defined(GPR_POSIX_LOG) */

@ -42,11 +42,18 @@
#include <time.h>
#include "src/core/lib/profiling/timers.h"
#ifdef GPR_MU_COUNTERS
gpr_atm grpc_mu_locks = 0;
#endif
void gpr_mu_init(gpr_mu* mu) { GPR_ASSERT(pthread_mutex_init(mu, NULL) == 0); }
void gpr_mu_destroy(gpr_mu* mu) { GPR_ASSERT(pthread_mutex_destroy(mu) == 0); }
void gpr_mu_lock(gpr_mu* mu) {
#ifdef GPR_MU_COUNTERS
gpr_atm_no_barrier_fetch_add(&grpc_mu_locks, 1);
#endif
GPR_TIMER_BEGIN("gpr_mu_lock", 0);
GPR_ASSERT(pthread_mutex_lock(mu) == 0);
GPR_TIMER_END("gpr_mu_lock", 0);

@ -897,7 +897,7 @@ static void recv_common_filter(grpc_exec_ctx *exec_ctx, grpc_call *call,
error = grpc_error_set_str(error, GRPC_ERROR_STR_GRPC_MESSAGE, msg);
gpr_free(msg);
grpc_metadata_batch_remove(exec_ctx, b, b->idx.named.grpc_message);
} else {
} else if (error != GRPC_ERROR_NONE) {
error = grpc_error_set_str(error, GRPC_ERROR_STR_GRPC_MESSAGE, "");
}
@ -1483,6 +1483,7 @@ static grpc_call_error call_start_batch(grpc_exec_ctx *exec_ctx,
}
bctl->send_final_op = 1;
call->sent_final_op = 1;
GPR_ASSERT(call->send_extra_metadata_count == 0);
call->send_extra_metadata_count = 1;
call->send_extra_metadata[0].md = grpc_channel_get_reffed_status_elem(
exec_ctx, call->channel, op->data.send_status_from_server.status);
@ -1511,6 +1512,10 @@ static grpc_call_error call_start_batch(grpc_exec_ctx *exec_ctx,
(int)op->data.send_status_from_server.trailing_metadata_count,
op->data.send_status_from_server.trailing_metadata, 1, 1, NULL,
0)) {
for (int n = 0; n < call->send_extra_metadata_count; n++) {
GRPC_MDELEM_UNREF(exec_ctx, call->send_extra_metadata[n].md);
}
call->send_extra_metadata_count = 0;
error = GRPC_CALL_ERROR_INVALID_METADATA;
goto done_with_error;
}

@ -63,6 +63,7 @@
#include "src/core/lib/surface/init.h"
#include "src/core/lib/surface/lame_client.h"
#include "src/core/lib/surface/server.h"
#include "src/core/lib/transport/bdp_estimator.h"
#include "src/core/lib/transport/connectivity_state.h"
#include "src/core/lib/transport/transport_impl.h"
@ -192,6 +193,7 @@ void grpc_init(void) {
grpc_register_tracer("queue_pluck", &grpc_cq_pluck_trace);
grpc_register_tracer("combiner", &grpc_combiner_trace);
grpc_register_tracer("server_channel", &grpc_server_channel_trace);
grpc_register_tracer("bdp_estimator", &grpc_bdp_estimator_trace);
// Default pluck trace to 1
grpc_cq_pluck_trace = 1;
grpc_register_tracer("queue_timeout", &grpc_cq_event_timeout_trace);

@ -56,7 +56,7 @@ static bool maybe_prepend_client_auth_filter(
grpc_channel_stack_builder_get_channel_arguments(builder);
if (args) {
for (size_t i = 0; i < args->num_args; i++) {
if (0 == strcmp(GRPC_SECURITY_CONNECTOR_ARG, args->args[i].key)) {
if (0 == strcmp(GRPC_ARG_SECURITY_CONNECTOR, args->args[i].key)) {
return grpc_channel_stack_builder_prepend_filter(
builder, &grpc_client_auth_filter, NULL, NULL);
}

@ -0,0 +1,104 @@
/*
*
* Copyright 2016, Google Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following disclaimer
* in the documentation and/or other materials provided with the
* distribution.
* * Neither the name of Google Inc. nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#include "src/core/lib/transport/bdp_estimator.h"
#include <stdlib.h>
#include <grpc/support/log.h>
#include <grpc/support/useful.h>
int grpc_bdp_estimator_trace = 0;
void grpc_bdp_estimator_init(grpc_bdp_estimator *estimator, const char *name) {
estimator->estimate = 65536;
estimator->ping_state = GRPC_BDP_PING_UNSCHEDULED;
estimator->name = name;
}
bool grpc_bdp_estimator_get_estimate(grpc_bdp_estimator *estimator,
int64_t *estimate) {
*estimate = estimator->estimate;
return true;
}
bool grpc_bdp_estimator_add_incoming_bytes(grpc_bdp_estimator *estimator,
int64_t num_bytes) {
estimator->accumulator += num_bytes;
switch (estimator->ping_state) {
case GRPC_BDP_PING_UNSCHEDULED:
return true;
case GRPC_BDP_PING_SCHEDULED:
return false;
case GRPC_BDP_PING_STARTED:
return false;
}
GPR_UNREACHABLE_CODE(return false);
}
void grpc_bdp_estimator_schedule_ping(grpc_bdp_estimator *estimator) {
if (grpc_bdp_estimator_trace) {
gpr_log(GPR_DEBUG, "bdp[%s]:sched acc=%" PRId64 " est=%" PRId64,
estimator->name, estimator->accumulator, estimator->estimate);
}
GPR_ASSERT(estimator->ping_state == GRPC_BDP_PING_UNSCHEDULED);
estimator->ping_state = GRPC_BDP_PING_SCHEDULED;
estimator->accumulator = 0;
}
void grpc_bdp_estimator_start_ping(grpc_bdp_estimator *estimator) {
if (grpc_bdp_estimator_trace) {
gpr_log(GPR_DEBUG, "bdp[%s]:start acc=%" PRId64 " est=%" PRId64,
estimator->name, estimator->accumulator, estimator->estimate);
}
GPR_ASSERT(estimator->ping_state == GRPC_BDP_PING_SCHEDULED);
estimator->ping_state = GRPC_BDP_PING_STARTED;
estimator->accumulator = 0;
}
void grpc_bdp_estimator_complete_ping(grpc_bdp_estimator *estimator) {
if (grpc_bdp_estimator_trace) {
gpr_log(GPR_DEBUG, "bdp[%s]:complete acc=%" PRId64 " est=%" PRId64,
estimator->name, estimator->accumulator, estimator->estimate);
}
GPR_ASSERT(estimator->ping_state == GRPC_BDP_PING_STARTED);
if (estimator->accumulator > 2 * estimator->estimate / 3) {
estimator->estimate *= 2;
if (grpc_bdp_estimator_trace) {
gpr_log(GPR_DEBUG, "bdp[%s]: estimate increased to %" PRId64,
estimator->name, estimator->estimate);
}
}
estimator->ping_state = GRPC_BDP_PING_UNSCHEDULED;
estimator->accumulator = 0;
}

@ -0,0 +1,76 @@
/*
*
* Copyright 2016, Google Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following disclaimer
* in the documentation and/or other materials provided with the
* distribution.
* * Neither the name of Google Inc. nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#ifndef GRPC_CORE_LIB_TRANSPORT_BDP_ESTIMATOR_H
#define GRPC_CORE_LIB_TRANSPORT_BDP_ESTIMATOR_H
#include <stdbool.h>
#include <stdint.h>
#define GRPC_BDP_SAMPLES 16
#define GRPC_BDP_MIN_SAMPLES_FOR_ESTIMATE 3
extern int grpc_bdp_estimator_trace;
typedef enum {
GRPC_BDP_PING_UNSCHEDULED,
GRPC_BDP_PING_SCHEDULED,
GRPC_BDP_PING_STARTED
} grpc_bdp_estimator_ping_state;
typedef struct grpc_bdp_estimator {
grpc_bdp_estimator_ping_state ping_state;
int64_t accumulator;
int64_t estimate;
const char *name;
} grpc_bdp_estimator;
void grpc_bdp_estimator_init(grpc_bdp_estimator *estimator, const char *name);
// Returns true if a reasonable estimate could be obtained
bool grpc_bdp_estimator_get_estimate(grpc_bdp_estimator *estimator,
int64_t *estimate);
// Returns true if the user should schedule a ping
bool grpc_bdp_estimator_add_incoming_bytes(grpc_bdp_estimator *estimator,
int64_t num_bytes);
// Schedule a ping: call in response to receiving a true from
// grpc_bdp_estimator_add_incoming_bytes once a ping has been scheduled by a
// transport (but not necessarily started)
void grpc_bdp_estimator_schedule_ping(grpc_bdp_estimator *estimator);
// Start a ping: call after calling grpc_bdp_estimator_schedule_ping and once
// the ping is on the wire
void grpc_bdp_estimator_start_ping(grpc_bdp_estimator *estimator);
// Completes a previously started ping
void grpc_bdp_estimator_complete_ping(grpc_bdp_estimator *estimator);
#endif

@ -32,26 +32,46 @@
*/
#include "src/core/lib/transport/pid_controller.h"
#include <grpc/support/useful.h>
void grpc_pid_controller_init(grpc_pid_controller *pid_controller,
double gain_p, double gain_i, double gain_d) {
pid_controller->gain_p = gain_p;
pid_controller->gain_i = gain_i;
pid_controller->gain_d = gain_d;
grpc_pid_controller_args args) {
pid_controller->args = args;
pid_controller->last_control_value = args.initial_control_value;
grpc_pid_controller_reset(pid_controller);
}
void grpc_pid_controller_reset(grpc_pid_controller *pid_controller) {
pid_controller->last_error = 0.0;
pid_controller->last_dc_dt = 0.0;
pid_controller->error_integral = 0.0;
}
double grpc_pid_controller_update(grpc_pid_controller *pid_controller,
double error, double dt) {
pid_controller->error_integral += error * dt;
/* integrate error using the trapezoid rule */
pid_controller->error_integral +=
dt * (pid_controller->last_error + error) * 0.5;
pid_controller->error_integral = GPR_CLAMP(
pid_controller->error_integral, -pid_controller->args.integral_range,
pid_controller->args.integral_range);
double diff_error = (error - pid_controller->last_error) / dt;
/* calculate derivative of control value vs time */
double dc_dt = pid_controller->args.gain_p * error +
pid_controller->args.gain_i * pid_controller->error_integral +
pid_controller->args.gain_d * diff_error;
/* and perform trapezoidal integration */
double new_control_value = pid_controller->last_control_value +
dt * (pid_controller->last_dc_dt + dc_dt) * 0.5;
new_control_value =
GPR_CLAMP(new_control_value, pid_controller->args.min_control_value,
pid_controller->args.max_control_value);
pid_controller->last_error = error;
return dt * (pid_controller->gain_p * error +
pid_controller->gain_i * pid_controller->error_integral +
pid_controller->gain_d * diff_error);
pid_controller->last_dc_dt = dc_dt;
pid_controller->last_control_value = new_control_value;
return new_control_value;
}
double grpc_pid_controller_last(grpc_pid_controller *pid_controller) {
return pid_controller->last_control_value;
}

@ -45,20 +45,33 @@ typedef struct {
double gain_p;
double gain_i;
double gain_d;
double initial_control_value;
double min_control_value;
double max_control_value;
double integral_range;
} grpc_pid_controller_args;
typedef struct {
double last_error;
double error_integral;
double last_control_value;
double last_dc_dt;
grpc_pid_controller_args args;
} grpc_pid_controller;
/** Initialize the controller */
void grpc_pid_controller_init(grpc_pid_controller *pid_controller,
double gain_p, double gain_i, double gain_d);
grpc_pid_controller_args args);
/** Reset the controller: useful when things have changed significantly */
void grpc_pid_controller_reset(grpc_pid_controller *pid_controller);
/** Update the controller: given a current error estimate, and the time since
the last update, returns a delta to the control value */
the last update, returns a new control value */
double grpc_pid_controller_update(grpc_pid_controller *pid_controller,
double error, double dt);
/** Returns the last control value calculated */
double grpc_pid_controller_last(grpc_pid_controller *pid_controller);
#endif /* GRPC_CORE_LIB_TRANSPORT_PID_CONTROLLER_H */

@ -478,6 +478,7 @@ int Server::AddListeningPort(const grpc::string& addr,
bool Server::Start(ServerCompletionQueue** cqs, size_t num_cqs) {
GPR_ASSERT(!started_);
global_callbacks_->PreServerStart(this);
started_ = true;
grpc_server_start(server_);

@ -761,7 +761,7 @@ GPR_EXPORT grpc_call_error GPR_CALLTYPE grpcsharp_call_send_status_from_server(
ops[nops].data.send_message.send_message = ctx->send_message;
ops[nops].flags = write_flags;
ops[nops].reserved = NULL;
nops ++;
nops++;
}
if (send_empty_initial_metadata) {
ops[nops].op = GRPC_OP_SEND_INITIAL_METADATA;

@ -1,5 +1,11 @@
# CocoaPods podspec for the gRPC Proto Compiler Plugin
# This file has been automatically generated from a template file.
# Please make modifications to
# `templates/src/objective-c/!ProtoCompiler-gRPCPlugin.podspec.template`
# instead. This file can be regenerated from the template by running
# `tools/buildgen/generate_projects.sh`.
# CocoaPods podspec for the gRPC Proto Compiler Plugin
#
# Copyright 2016, Google Inc.
# All rights reserved.
#
@ -36,7 +42,7 @@ Pod::Spec.new do |s|
# exclamation mark ensures that other "regular" pods will be able to find it as it'll be installed
# before them.
s.name = '!ProtoCompiler-gRPCPlugin'
v = '1.0.2'
v = '1.2.0-dev'
s.version = v
s.summary = 'The gRPC ProtoC plugin generates Objective-C files from .proto services.'
s.description = <<-DESC
@ -84,10 +90,7 @@ Pod::Spec.new do |s|
repo = 'grpc/grpc'
file = "grpc_objective_c_plugin-#{v}-macos-x86_64.zip"
s.source = {
# TODO(mxyan): Change back to "https://github.com/#{repo}/releases/download/v#{v}/#{file}" for
# next release
# :http => "https://github.com/#{repo}/releases/download/v#{v}/#{file}",
:http => "https://github.com/#{repo}/releases/download/objective-c-v#{v}/#{file}",
:http => "https://github.com/#{repo}/releases/download/v#{v}/#{file}",
# TODO(jcanizales): Add sha1 or sha256
# :sha1 => '??',
}
@ -98,7 +101,7 @@ Pod::Spec.new do |s|
s.preserve_paths = plugin
# Restrict the protoc version to the one supported by this plugin.
s.dependency '!ProtoCompiler', '3.0.2'
s.dependency '!ProtoCompiler', '3.1.0'
# For the Protobuf dependency not to complain:
s.ios.deployment_target = '7.1'
s.osx.deployment_target = '10.9'

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

@ -31,7 +31,7 @@
Pod::Spec.new do |s|
s.name = 'BoringSSL'
version = '7.0'
version = '8.0'
s.version = version
s.summary = 'BoringSSL is a fork of OpenSSL that is designed to meet Google’s needs.'
# Adapted from the homepage:
@ -388,42 +388,42 @@ Pod::Spec.new do |s|
0x28340c19,
0x283480ac,
0x283500ea,
0x2c322910,
0x2c32a91e,
0x2c332930,
0x2c33a942,
0x2c342956,
0x2c34a968,
0x2c352983,
0x2c35a995,
0x2c3629a8,
0x2c3228ca,
0x2c32a8d8,
0x2c3328ea,
0x2c33a8fc,
0x2c342910,
0x2c34a922,
0x2c35293d,
0x2c35a94f,
0x2c362962,
0x2c36832d,
0x2c3729b5,
0x2c37a9c7,
0x2c3829da,
0x2c38a9f1,
0x2c3929ff,
0x2c39aa0f,
0x2c3a2a21,
0x2c3aaa35,
0x2c3b2a46,
0x2c3baa65,
0x2c3c2a79,
0x2c3caa8f,
0x2c3d2aa8,
0x2c3daac5,
0x2c3e2ad6,
0x2c3eaae4,
0x2c3f2afc,
0x2c3fab14,
0x2c402b21,
0x2c37296f,
0x2c37a981,
0x2c382994,
0x2c38a9ab,
0x2c3929b9,
0x2c39a9c9,
0x2c3a29db,
0x2c3aa9ef,
0x2c3b2a00,
0x2c3baa1f,
0x2c3c2a33,
0x2c3caa49,
0x2c3d2a62,
0x2c3daa7f,
0x2c3e2a90,
0x2c3eaa9e,
0x2c3f2ab6,
0x2c3faace,
0x2c402adb,
0x2c4090e7,
0x2c412b32,
0x2c41ab45,
0x2c412aec,
0x2c41aaff,
0x2c4210c0,
0x2c42ab56,
0x2c42ab10,
0x2c430720,
0x2c43aa57,
0x2c43aa11,
0x30320000,
0x30328015,
0x3033001f,
@ -639,74 +639,74 @@ Pod::Spec.new do |s|
0x405b1e9e,
0x405b9eaf,
0x405c1ec2,
0x405c9ee3,
0x405d1ef0,
0x405d9f07,
0x405e1f27,
0x405c9ed3,
0x405d1ee0,
0x405d9ef7,
0x405e1f17,
0x405e8a95,
0x405f1f48,
0x405f9f55,
0x40601f63,
0x40609f85,
0x40611fad,
0x40619fc2,
0x40621fd9,
0x40629fea,
0x40631ffb,
0x4063a010,
0x40642027,
0x4064a053,
0x4065206e,
0x4065a085,
0x4066209d,
0x4066a0c7,
0x406720f2,
0x4067a113,
0x40682126,
0x4068a147,
0x40692179,
0x4069a1a7,
0x406a21c8,
0x406aa1e8,
0x406b2370,
0x406ba393,
0x406c23a9,
0x406ca60b,
0x406d263a,
0x406da662,
0x406e2690,
0x406ea6a8,
0x406f26c7,
0x406fa6dc,
0x407026ef,
0x4070a70c,
0x405f1f38,
0x405f9f45,
0x40601f53,
0x40609f75,
0x40611f9d,
0x40619fb2,
0x40621fc9,
0x40629fda,
0x40631feb,
0x4063a000,
0x40642017,
0x4064a043,
0x4065205e,
0x4065a075,
0x4066208d,
0x4066a0b7,
0x406720e2,
0x4067a103,
0x40682116,
0x4068a137,
0x40692169,
0x4069a197,
0x406a21b8,
0x406aa1d8,
0x406b2360,
0x406ba383,
0x406c2399,
0x406ca5c5,
0x406d25f4,
0x406da61c,
0x406e264a,
0x406ea662,
0x406f2681,
0x406fa696,
0x407026a9,
0x4070a6c6,
0x40710800,
0x4071a71e,
0x40722731,
0x4072a74a,
0x40732762,
0x4071a6d8,
0x407226eb,
0x4072a704,
0x4073271c,
0x4073936d,
0x40742776,
0x4074a790,
0x407527a1,
0x4075a7b5,
0x407627c3,
0x40742730,
0x4074a74a,
0x4075275b,
0x4075a76f,
0x4076277d,
0x407691aa,
0x407727e8,
0x4077a80a,
0x40782825,
0x4078a85e,
0x40792875,
0x4079a88b,
0x407a2897,
0x407aa8aa,
0x407b28bf,
0x407ba8d1,
0x407c28e6,
0x407ca8ef,
0x407d2162,
0x407727a2,
0x4077a7c4,
0x407827df,
0x4078a818,
0x4079282f,
0x4079a845,
0x407a2851,
0x407aa864,
0x407b2879,
0x407ba88b,
0x407c28a0,
0x407ca8a9,
0x407d2152,
0x407d9c57,
0x407e283a,
0x407e27f4,
0x407e9e16,
0x407f1a67,
0x407f9887,
@ -714,45 +714,42 @@ Pod::Spec.new do |s|
0x40809a8f,
0x40811cd9,
0x40819c08,
0x4082267b,
0x40822635,
0x4082986d,
0x40831df1,
0x4083a038,
0x4083a028,
0x40841aa3,
0x40849e4e,
0x40851ed3,
0x41f4229b,
0x41f9232d,
0x41fe2220,
0x41fea3fc,
0x41ff24ed,
0x420322b4,
0x420822d6,
0x4208a312,
0x42092204,
0x4209a34c,
0x420a225b,
0x420aa23b,
0x420b227b,
0x420ba2f4,
0x420c2509,
0x420ca3c9,
0x420d23e3,
0x420da41a,
0x42122434,
0x421724d0,
0x4217a476,
0x421c2498,
0x421f2453,
0x42212520,
0x422624b3,
0x422b25ef,
0x422ba59d,
0x422c25d7,
0x422ca55c,
0x422d253b,
0x422da5bc,
0x422e2582,
0x41f4228b,
0x41f9231d,
0x41fe2210,
0x41fea3ec,
0x41ff24dd,
0x420322a4,
0x420822c6,
0x4208a302,
0x420921f4,
0x4209a33c,
0x420a224b,
0x420aa22b,
0x420b226b,
0x420ba2e4,
0x420c24f9,
0x420ca3b9,
0x420d23d3,
0x420da40a,
0x42122424,
0x421724c0,
0x4217a466,
0x421c2488,
0x421f2443,
0x42212510,
0x422624a3,
0x422b25a9,
0x422ba572,
0x422c2591,
0x422ca54c,
0x422d252b,
0x4432072b,
0x4432873a,
0x44330746,
@ -795,69 +792,69 @@ Pod::Spec.new do |s|
0x4c3d136d,
0x4c3d937c,
0x4c3e1389,
0x50322b68,
0x5032ab77,
0x50332b82,
0x5033ab92,
0x50342bab,
0x5034abc5,
0x50352bd3,
0x5035abe9,
0x50362bfb,
0x5036ac11,
0x50372c2a,
0x5037ac3d,
0x50382c55,
0x5038ac66,
0x50392c7b,
0x5039ac8f,
0x503a2caf,
0x503aacc5,
0x503b2cdd,
0x503bacef,
0x503c2d0b,
0x503cad22,
0x503d2d3b,
0x503dad51,
0x503e2d5e,
0x503ead74,
0x503f2d86,
0x50322b22,
0x5032ab31,
0x50332b3c,
0x5033ab4c,
0x50342b65,
0x5034ab7f,
0x50352b8d,
0x5035aba3,
0x50362bb5,
0x5036abcb,
0x50372be4,
0x5037abf7,
0x50382c0f,
0x5038ac20,
0x50392c35,
0x5039ac49,
0x503a2c69,
0x503aac7f,
0x503b2c97,
0x503baca9,
0x503c2cc5,
0x503cacdc,
0x503d2cf5,
0x503dad0b,
0x503e2d18,
0x503ead2e,
0x503f2d40,
0x503f8382,
0x50402d99,
0x5040ada9,
0x50412dc3,
0x5041add2,
0x50422dec,
0x5042ae09,
0x50432e19,
0x5043ae29,
0x50442e38,
0x50402d53,
0x5040ad63,
0x50412d7d,
0x5041ad8c,
0x50422da6,
0x5042adc3,
0x50432dd3,
0x5043ade3,
0x50442df2,
0x5044843f,
0x50452e4c,
0x5045ae6a,
0x50462e7d,
0x5046ae93,
0x50472ea5,
0x5047aeba,
0x50482ee0,
0x5048aeee,
0x50492f01,
0x5049af16,
0x504a2f2c,
0x504aaf3c,
0x504b2f5c,
0x504baf6f,
0x504c2f92,
0x504cafc0,
0x504d2fd2,
0x504dafef,
0x504e300a,
0x504eb026,
0x504f3038,
0x504fb04f,
0x5050305e,
0x50452e06,
0x5045ae24,
0x50462e37,
0x5046ae4d,
0x50472e5f,
0x5047ae74,
0x50482e9a,
0x5048aea8,
0x50492ebb,
0x5049aed0,
0x504a2ee6,
0x504aaef6,
0x504b2f16,
0x504baf29,
0x504c2f4c,
0x504caf7a,
0x504d2f8c,
0x504dafa9,
0x504e2fc4,
0x504eafe0,
0x504f2ff2,
0x504fb009,
0x50503018,
0x505086ef,
0x50513071,
0x5051302b,
0x58320ec9,
0x68320e8b,
0x68328c25,
@ -1292,7 +1289,6 @@ Pod::Spec.new do |s|
"NO_RENEGOTIATION\\0"
"NO_REQUIRED_DIGEST\\0"
"NO_SHARED_CIPHER\\0"
"NO_SHARED_GROUP\\0"
"NULL_SSL_CTX\\0"
"NULL_SSL_METHOD_PASSED\\0"
"OLD_SESSION_CIPHER_NOT_RETURNED\\0"
@ -1353,9 +1349,7 @@ Pod::Spec.new do |s|
"TLSV1_ALERT_USER_CANCELLED\\0"
"TLSV1_BAD_CERTIFICATE_HASH_VALUE\\0"
"TLSV1_BAD_CERTIFICATE_STATUS_RESPONSE\\0"
"TLSV1_CERTIFICATE_REQUIRED\\0"
"TLSV1_CERTIFICATE_UNOBTAINABLE\\0"
"TLSV1_UNKNOWN_PSK_IDENTITY\\0"
"TLSV1_UNRECOGNIZED_NAME\\0"
"TLSV1_UNSUPPORTED_EXTENSION\\0"
"TLS_PEER_DID_NOT_RESPOND_WITH_CERTIFICATE_LIST\\0"

@ -159,11 +159,13 @@ static void PassFlagsToContextInfoBlock(SCNetworkReachabilityRef target,
if (strongSelf) {
if (lossHandler && !flags.reachable) {
lossHandler();
#if TARGET_OS_IPHONE
} else if (wifiStatusChangeHandler &&
strongSelf->_previousReachabilityFlags &&
(flags.isWWAN ^
strongSelf->_previousReachabilityFlags.isWWAN)) {
wifiStatusChangeHandler();
#endif
}
strongSelf->_previousReachabilityFlags = flags;
}

@ -45,13 +45,10 @@
#import "GRPCCompletionQueue.h"
#import "GRPCConnectivityMonitor.h"
#import "NSDictionary+GRPC.h"
#import "version.h"
NS_ASSUME_NONNULL_BEGIN
// TODO(jcanizales): Generate the version in a standalone header, from templates. Like
// templates/src/core/surface/version.c.template .
#define GRPC_OBJC_VERSION_STRING @"1.0.2"
static NSMutableDictionary *kHostCache;
// This connectivity monitor flushes the host cache when connectivity status

@ -0,0 +1,41 @@
/*
*
* Copyright 2015, Google Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following disclaimer
* in the documentation and/or other materials provided with the
* distribution.
* * Neither the name of Google Inc. nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
// This file is autogenerated from a template file. Please make
// modifications to
// `templates/src/objective-c/GRPCClient/private/version.h.template`
// instead. This file can be regenerated from the template by running
// `tools/buildgen/generate_projects.sh`.
#define GRPC_OBJC_VERSION_STRING @"1.2.0-dev"

@ -206,7 +206,7 @@ static char *roots_filename;
inDomains:NSUserDomainMask] lastObject];
NSLog(@"Documents directory: %@", url);
[Cronet start];
[Cronet startNetLogToFile:@"Documents/cronet_netlog.json" logBytes:YES];
[Cronet startNetLogToFile:@"cronet_netlog.json" logBytes:YES];
}
// The tearDown() function is run after all test cases finish running

@ -49,6 +49,16 @@
</Test>
</SkippedTests>
</TestableReference>
<TestableReference
skipped = "NO">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "5E8A5DA31D3840B4000F8BC4"
BuildableName = "CoreCronetEnd2EndTests.xctest"
BlueprintName = "CoreCronetEnd2EndTests"
ReferencedContainer = "container:Tests.xcodeproj">
</BuildableReference>
</TestableReference>
</Testables>
<MacroExpansion>
<BuildableReference
@ -90,15 +100,6 @@
savedToolIdentifier = ""
useCustomWorkingDirectory = "NO"
debugDocumentVersioning = "YES">
<MacroExpansion>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "63423F431B150A5F006CF63C"
BuildableName = "AllTests.xctest"
BlueprintName = "AllTests"
ReferencedContainer = "container:Tests.xcodeproj">
</BuildableReference>
</MacroExpansion>
</ProfileAction>
<AnalyzeAction
buildConfiguration = "Debug">

@ -12,24 +12,28 @@ shared C library.
* `composer`
* `phpunit` (optional)
**Ubuntu/Debian:**
**Install PHP and PECL on Ubuntu/Debian:**
```sh
$ sudo apt-get install php5 php5-dev
$ sudo apt-get install php5 php5-dev php-pear
OR
$ sudo apt-get install php7.0 php7.0-dev php-pear
```
**PEAR/PECL:**
**Install PECL on Mac:**
```sh
$ curl -O http://pear.php.net/go-pear.phar
$ sudo php -d detect_unicode=0 go-pear.phar
```
**Composer:**
**Install Composer (Linux or Mac):**
```sh
$ curl -sS https://getcomposer.org/installer | php
$ sudo mv composer.phar /usr/local/bin/composer
```
**PHPUnit:**
**Install PHPUnit (Linux or Mac):**
```sh
$ wget https://phar.phpunit.de/phpunit-old.phar
$ chmod +x phpunit-old.phar
@ -48,6 +52,14 @@ This will compile and install the gRPC PHP extension into the standard PHP
extension directory. You should be able to run the [unit tests](#unit-tests),
with the PHP extension installed.
**Update php.ini**
Add this line to your `php.ini` file, e.g. `/etc/php5/cli/php.ini`
```sh
extension=grpc.so
```
**Add the gRPC PHP library as a Composer dependency**
@ -55,7 +67,7 @@ You need to add this to your project's `composer.json` file.
```
"require": {
"grpc/grpc": "v1.0.0"
"grpc/grpc": "v1.1.0"
}
```
@ -96,14 +108,6 @@ $ make
$ sudo make install
```
### Update php.ini
Add this line to your `php.ini` file, e.g. `/etc/php5/cli/php.ini`
```sh
extension=grpc.so
```
## Unit Tests
You will need the source code to run tests
@ -138,7 +142,7 @@ $ composer install
### Protobuf compiler
Again if you don't have it already, you need to install the protobuf compiler
`protoc`, version 3.1.0+.
`protoc`, version 3.2.0+.
If `protoc` hasn't been installed, you can download the `protoc` binaries from
[the protocol buffers Github repository](https://github.com/google/protobuf/releases).
@ -209,6 +213,7 @@ $ sudo apt-get install apache2
```
Add this line to your `php.ini` file, e.g. `/etc/php5/apache2/php.ini`
or `/etc/php/7.0/apache2/php.ini`
```sh
extension=grpc.so
@ -235,7 +240,7 @@ $ cd grpc/src/php
$ composer install
```
Make sure you have generated the client stub `math.php`
Make sure you have generated the client stubs
```sh
$ ./bin/generate_proto_php.sh
@ -247,11 +252,10 @@ Copy the `math_client.php` file into your Apache document root, e.g.
$ cp tests/generated_code/math_client.php /var/www/html
```
You may have to fix the first two lines to point the includes to your installation:
You may have to fix the first line to point the includes to your installation:
```php
include 'vendor/autoload.php';
include 'tests/generated_code/math.php';
```
Connect to `localhost/math_client.php` in your browser, or run this from command line:
@ -266,6 +270,10 @@ Install `nginx` and `php5-fpm`, in addition to `php5` above
```sh
$ sudo apt-get install nginx php5-fpm
OR
$ sudo apt-get install nginx php7.0-fpm
```
Add this line to your `php.ini` file, e.g. `/etc/php5/fpm/php.ini`
@ -305,7 +313,7 @@ $ cd grpc/src/php
$ composer install
```
Make sure you have generated the client stub `math.php`
Make sure you have generated the client stubs
```sh
$ ./bin/generate_proto_php.sh
@ -317,11 +325,10 @@ Copy the `math_client.php` file into your Nginx document root, e.g.
$ cp tests/generated_code/math_client.php /var/www/html
```
You may have to fix the first two lines to point the includes to your installation:
You may have to fix the first line to point the includes to your installation:
```php
include 'vendor/autoload.php';
include 'tests/generated_code/math.php';
```
Connect to `localhost/math_client.php` in your browser, or run this from command line:

@ -5,7 +5,7 @@
"version": "1.2.0",
"require": {
"php": ">=5.5.0",
"google/protobuf": "v3.1.0-alpha-1"
"google/protobuf": "v3.1.0"
},
"require-dev": {
"google/auth": "v0.9"

@ -32,9 +32,10 @@
*
*/
# Fix the following two lines to point to your installation
# Fix the following line to point to your installation
# This assumes that you are using protoc 3.2.0+ and the generated stubs
# were being autoloaded via composer.
include 'vendor/autoload.php';
include 'tests/generated_code/math.php';
function p($line)
{
@ -43,7 +44,7 @@ function p($line)
$host = 'localhost:50051';
p("Connecting to host: $host");
$client = new math\MathClient($host, [
$client = new Math\MathClient($host, [
'credentials' => Grpc\ChannelCredentials::createInsecure(),
]);
p('Client class: '.get_class($client));
@ -52,7 +53,7 @@ p('');
p('Running unary call test:');
$dividend = 7;
$divisor = 4;
$div_arg = new math\DivArgs();
$div_arg = new Math\DivArgs();
$div_arg->setDividend($dividend);
$div_arg->setDivisor($divisor);
$call = $client->Div($div_arg);
@ -65,7 +66,7 @@ p('');
p('Running server streaming test:');
$limit = 7;
$fib_arg = new math\FibArgs();
$fib_arg = new Math\FibArgs();
$fib_arg->setLimit($limit);
$call = $client->Fib($fib_arg);
$result_array = iterator_to_array($call->responses());
@ -79,7 +80,7 @@ p('');
p('Running client streaming test:');
$call = $client->Sum();
for ($i = 0; $i <= $limit; ++$i) {
$num = new math\Num();
$num = new Math\Num();
$num->setNum($i);
$call->write($num);
}
@ -91,7 +92,7 @@ p('');
p('Running bidi-streaming test:');
$call = $client->DivMany();
for ($i = 0; $i < 7; ++$i) {
$div_arg = new math\DivArgs();
$div_arg = new Math\DivArgs();
$dividend = 2 * $i + 1;
$divisor = 3;
$div_arg->setDividend($dividend);

@ -205,9 +205,7 @@ def check_and_update_cythonization(extensions):
base, file_ext = os.path.splitext(source)
if file_ext == '.pyx':
generated_pyx_source = next((base + gen_ext
for gen_ext in (
'.c',
'.cpp',)
for gen_ext in ('.c', '.cpp',)
if os.path.isfile(base + gen_ext)),
None)
if generated_pyx_source:

@ -1297,47 +1297,22 @@ def server(thread_pool, handlers=None, options=None):
################################### __all__ #################################
__all__ = (
'FutureTimeoutError',
'FutureCancelledError',
'Future',
'ChannelConnectivity',
'StatusCode',
'RpcError',
'RpcContext',
'Call',
'ChannelCredentials',
'CallCredentials',
'AuthMetadataContext',
'AuthMetadataPluginCallback',
'AuthMetadataPlugin',
'ServerCredentials',
'UnaryUnaryMultiCallable',
'UnaryStreamMultiCallable',
'StreamUnaryMultiCallable',
'StreamStreamMultiCallable',
'Channel',
'ServicerContext',
'RpcMethodHandler',
'HandlerCallDetails',
'GenericRpcHandler',
'ServiceRpcHandler',
'Server',
'unary_unary_rpc_method_handler',
'unary_stream_rpc_method_handler',
'stream_unary_rpc_method_handler',
'stream_stream_rpc_method_handler',
'method_handlers_generic_handler',
'ssl_channel_credentials',
'metadata_call_credentials',
'access_token_call_credentials',
'composite_call_credentials',
'composite_channel_credentials',
'ssl_server_credentials',
'channel_ready_future',
'insecure_channel',
'secure_channel',
'server',)
__all__ = ('FutureTimeoutError', 'FutureCancelledError', 'Future',
'ChannelConnectivity', 'StatusCode', 'RpcError', 'RpcContext',
'Call', 'ChannelCredentials', 'CallCredentials',
'AuthMetadataContext', 'AuthMetadataPluginCallback',
'AuthMetadataPlugin', 'ServerCredentials', 'UnaryUnaryMultiCallable',
'UnaryStreamMultiCallable', 'StreamUnaryMultiCallable',
'StreamStreamMultiCallable', 'Channel', 'ServicerContext',
'RpcMethodHandler', 'HandlerCallDetails', 'GenericRpcHandler',
'ServiceRpcHandler', 'Server', 'unary_unary_rpc_method_handler',
'unary_stream_rpc_method_handler', 'stream_unary_rpc_method_handler',
'stream_stream_rpc_method_handler',
'method_handlers_generic_handler', 'ssl_channel_credentials',
'metadata_call_credentials', 'access_token_call_credentials',
'composite_call_credentials', 'composite_channel_credentials',
'ssl_server_credentials', 'channel_ready_future', 'insecure_channel',
'secure_channel', 'server',)
############################### Extension Shims ################################

@ -45,28 +45,24 @@ _EMPTY_FLAGS = 0
_INFINITE_FUTURE = cygrpc.Timespec(float('+inf'))
_EMPTY_METADATA = cygrpc.Metadata(())
_UNARY_UNARY_INITIAL_DUE = (
cygrpc.OperationType.send_initial_metadata,
cygrpc.OperationType.send_message,
cygrpc.OperationType.send_close_from_client,
cygrpc.OperationType.receive_initial_metadata,
cygrpc.OperationType.receive_message,
cygrpc.OperationType.receive_status_on_client,)
_UNARY_STREAM_INITIAL_DUE = (
cygrpc.OperationType.send_initial_metadata,
cygrpc.OperationType.send_message,
cygrpc.OperationType.send_close_from_client,
cygrpc.OperationType.receive_initial_metadata,
cygrpc.OperationType.receive_status_on_client,)
_STREAM_UNARY_INITIAL_DUE = (
cygrpc.OperationType.send_initial_metadata,
cygrpc.OperationType.receive_initial_metadata,
cygrpc.OperationType.receive_message,
cygrpc.OperationType.receive_status_on_client,)
_STREAM_STREAM_INITIAL_DUE = (
cygrpc.OperationType.send_initial_metadata,
cygrpc.OperationType.receive_initial_metadata,
cygrpc.OperationType.receive_status_on_client,)
_UNARY_UNARY_INITIAL_DUE = (cygrpc.OperationType.send_initial_metadata,
cygrpc.OperationType.send_message,
cygrpc.OperationType.send_close_from_client,
cygrpc.OperationType.receive_initial_metadata,
cygrpc.OperationType.receive_message,
cygrpc.OperationType.receive_status_on_client,)
_UNARY_STREAM_INITIAL_DUE = (cygrpc.OperationType.send_initial_metadata,
cygrpc.OperationType.send_message,
cygrpc.OperationType.send_close_from_client,
cygrpc.OperationType.receive_initial_metadata,
cygrpc.OperationType.receive_status_on_client,)
_STREAM_UNARY_INITIAL_DUE = (cygrpc.OperationType.send_initial_metadata,
cygrpc.OperationType.receive_initial_metadata,
cygrpc.OperationType.receive_message,
cygrpc.OperationType.receive_status_on_client,)
_STREAM_STREAM_INITIAL_DUE = (cygrpc.OperationType.send_initial_metadata,
cygrpc.OperationType.receive_initial_metadata,
cygrpc.OperationType.receive_status_on_client,)
_CHANNEL_SUBSCRIPTION_CALLBACK_ERROR_LOG_MESSAGE = (
'Exception calling channel subscription callback!')
@ -568,9 +564,9 @@ class _UnaryStreamMultiCallable(grpc.UnaryStreamMultiCallable):
)), event_handler)
operations = (
cygrpc.operation_send_initial_metadata(
_common.cygrpc_metadata(metadata), _EMPTY_FLAGS),
cygrpc.operation_send_message(serialized_request,
_EMPTY_FLAGS),
_common.cygrpc_metadata(metadata),
_EMPTY_FLAGS), cygrpc.operation_send_message(
serialized_request, _EMPTY_FLAGS),
cygrpc.operation_send_close_from_client(_EMPTY_FLAGS),
cygrpc.operation_receive_status_on_client(_EMPTY_FLAGS),)
call_error = call.start_client_batch(
@ -828,10 +824,7 @@ def _deliver(state, initial_connectivity, initial_callbacks):
def _spawn_delivery(state, callbacks):
delivering_thread = threading.Thread(
target=_deliver, args=(
state,
state.connectivity,
callbacks,))
target=_deliver, args=(state, state.connectivity, callbacks,))
delivering_thread.start()
state.delivering = True

@ -40,12 +40,16 @@ from grpc._cython import cygrpc
_EMPTY_METADATA = cygrpc.Metadata(())
CYGRPC_CONNECTIVITY_STATE_TO_CHANNEL_CONNECTIVITY = {
cygrpc.ConnectivityState.idle: grpc.ChannelConnectivity.IDLE,
cygrpc.ConnectivityState.connecting: grpc.ChannelConnectivity.CONNECTING,
cygrpc.ConnectivityState.ready: grpc.ChannelConnectivity.READY,
cygrpc.ConnectivityState.idle:
grpc.ChannelConnectivity.IDLE,
cygrpc.ConnectivityState.connecting:
grpc.ChannelConnectivity.CONNECTING,
cygrpc.ConnectivityState.ready:
grpc.ChannelConnectivity.READY,
cygrpc.ConnectivityState.transient_failure:
grpc.ChannelConnectivity.TRANSIENT_FAILURE,
cygrpc.ConnectivityState.shutdown: grpc.ChannelConnectivity.SHUTDOWN,
cygrpc.ConnectivityState.shutdown:
grpc.ChannelConnectivity.SHUTDOWN,
}
CYGRPC_STATUS_CODE_TO_STATUS_CODE = {

@ -37,8 +37,7 @@ from grpc._cython import cygrpc
class AuthMetadataContext(
collections.namedtuple('AuthMetadataContext', (
'service_url',
'method_name',)), grpc.AuthMetadataContext):
'service_url', 'method_name',)), grpc.AuthMetadataContext):
pass

@ -91,8 +91,7 @@ def _details(state):
class _HandlerCallDetails(
collections.namedtuple('_HandlerCallDetails', (
'method',
'invocation_metadata',)), grpc.HandlerCallDetails):
'method', 'invocation_metadata',)), grpc.HandlerCallDetails):
pass
@ -143,12 +142,11 @@ def _abort(state, call, code, details):
effective_code = _abortion_code(state, code)
effective_details = details if state.details is None else state.details
if state.initial_metadata_allowed:
operations = (
cygrpc.operation_send_initial_metadata(_EMPTY_METADATA,
_EMPTY_FLAGS),
cygrpc.operation_send_status_from_server(
_common.cygrpc_metadata(state.trailing_metadata),
effective_code, effective_details, _EMPTY_FLAGS),)
operations = (cygrpc.operation_send_initial_metadata(
_EMPTY_METADATA, _EMPTY_FLAGS),
cygrpc.operation_send_status_from_server(
_common.cygrpc_metadata(state.trailing_metadata),
effective_code, effective_details, _EMPTY_FLAGS),)
token = _SEND_INITIAL_METADATA_AND_SEND_STATUS_FROM_SERVER_TOKEN
else:
operations = (cygrpc.operation_send_status_from_server(
@ -417,11 +415,10 @@ def _send_response(rpc_event, state, serialized_response):
return False
else:
if state.initial_metadata_allowed:
operations = (
cygrpc.operation_send_initial_metadata(_EMPTY_METADATA,
_EMPTY_FLAGS),
cygrpc.operation_send_message(serialized_response,
_EMPTY_FLAGS),)
operations = (cygrpc.operation_send_initial_metadata(
_EMPTY_METADATA, _EMPTY_FLAGS),
cygrpc.operation_send_message(serialized_response,
_EMPTY_FLAGS),)
state.initial_metadata_allowed = False
token = _SEND_INITIAL_METADATA_AND_SEND_MESSAGE_TOKEN
else:
@ -559,10 +556,8 @@ def _handle_unrecognized_method(rpc_event):
_EMPTY_METADATA, cygrpc.StatusCode.unimplemented,
b'Method not found!', _EMPTY_FLAGS),)
rpc_state = _RPCState()
rpc_event.operation_call.start_server_batch(operations,
lambda ignored_event: (
rpc_state,
(),))
rpc_event.operation_call.start_server_batch(
operations, lambda ignored_event: (rpc_state, (),))
return rpc_state

@ -44,14 +44,9 @@ _DONE_CALLBACK_EXCEPTION_LOG_MESSAGE = (
class RpcMethodHandler(
collections.namedtuple('_RpcMethodHandler', (
'request_streaming',
'response_streaming',
'request_deserializer',
'response_serializer',
'unary_unary',
'unary_stream',
'stream_unary',
'stream_stream',)), grpc.RpcMethodHandler):
'request_streaming', 'response_streaming', 'request_deserializer',
'response_serializer', 'unary_unary', 'unary_stream',
'stream_unary', 'stream_stream',)), grpc.RpcMethodHandler):
pass

@ -454,12 +454,9 @@ class _GenericStub(face.GenericStub):
metadata=None,
with_call=None,
protocol_options=None):
request_serializer = self._request_serializers.get((
group,
method,))
response_deserializer = self._response_deserializers.get((
group,
method,))
request_serializer = self._request_serializers.get((group, method,))
response_deserializer = self._response_deserializers.get((group,
method,))
return _blocking_unary_unary(self._channel, group, method, timeout,
with_call, protocol_options, metadata,
self._metadata_transformer, request,
@ -472,12 +469,9 @@ class _GenericStub(face.GenericStub):
timeout,
metadata=None,
protocol_options=None):
request_serializer = self._request_serializers.get((
group,
method,))
response_deserializer = self._response_deserializers.get((
group,
method,))
request_serializer = self._request_serializers.get((group, method,))
response_deserializer = self._response_deserializers.get((group,
method,))
return _future_unary_unary(self._channel, group, method, timeout,
protocol_options, metadata,
self._metadata_transformer, request,
@ -490,12 +484,9 @@ class _GenericStub(face.GenericStub):
timeout,
metadata=None,
protocol_options=None):
request_serializer = self._request_serializers.get((
group,
method,))
response_deserializer = self._response_deserializers.get((
group,
method,))
request_serializer = self._request_serializers.get((group, method,))
response_deserializer = self._response_deserializers.get((group,
method,))
return _unary_stream(self._channel, group, method, timeout,
protocol_options, metadata,
self._metadata_transformer, request,
@ -509,12 +500,9 @@ class _GenericStub(face.GenericStub):
metadata=None,
with_call=None,
protocol_options=None):
request_serializer = self._request_serializers.get((
group,
method,))
response_deserializer = self._response_deserializers.get((
group,
method,))
request_serializer = self._request_serializers.get((group, method,))
response_deserializer = self._response_deserializers.get((group,
method,))
return _blocking_stream_unary(
self._channel, group, method, timeout, with_call, protocol_options,
metadata, self._metadata_transformer, request_iterator,
@ -527,12 +515,9 @@ class _GenericStub(face.GenericStub):
timeout,
metadata=None,
protocol_options=None):
request_serializer = self._request_serializers.get((
group,
method,))
response_deserializer = self._response_deserializers.get((
group,
method,))
request_serializer = self._request_serializers.get((group, method,))
response_deserializer = self._response_deserializers.get((group,
method,))
return _future_stream_unary(
self._channel, group, method, timeout, protocol_options, metadata,
self._metadata_transformer, request_iterator, request_serializer,
@ -545,12 +530,9 @@ class _GenericStub(face.GenericStub):
timeout,
metadata=None,
protocol_options=None):
request_serializer = self._request_serializers.get((
group,
method,))
response_deserializer = self._response_deserializers.get((
group,
method,))
request_serializer = self._request_serializers.get((group, method,))
response_deserializer = self._response_deserializers.get((group,
method,))
return _stream_stream(self._channel, group, method, timeout,
protocol_options, metadata,
self._metadata_transformer, request_iterator,
@ -599,45 +581,33 @@ class _GenericStub(face.GenericStub):
raise NotImplementedError()
def unary_unary(self, group, method):
request_serializer = self._request_serializers.get((
group,
method,))
response_deserializer = self._response_deserializers.get((
group,
method,))
request_serializer = self._request_serializers.get((group, method,))
response_deserializer = self._response_deserializers.get((group,
method,))
return _UnaryUnaryMultiCallable(
self._channel, group, method, self._metadata_transformer,
request_serializer, response_deserializer)
def unary_stream(self, group, method):
request_serializer = self._request_serializers.get((
group,
method,))
response_deserializer = self._response_deserializers.get((
group,
method,))
request_serializer = self._request_serializers.get((group, method,))
response_deserializer = self._response_deserializers.get((group,
method,))
return _UnaryStreamMultiCallable(
self._channel, group, method, self._metadata_transformer,
request_serializer, response_deserializer)
def stream_unary(self, group, method):
request_serializer = self._request_serializers.get((
group,
method,))
response_deserializer = self._response_deserializers.get((
group,
method,))
request_serializer = self._request_serializers.get((group, method,))
response_deserializer = self._response_deserializers.get((group,
method,))
return _StreamUnaryMultiCallable(
self._channel, group, method, self._metadata_transformer,
request_serializer, response_deserializer)
def stream_stream(self, group, method):
request_serializer = self._request_serializers.get((
group,
method,))
response_deserializer = self._response_deserializers.get((
group,
method,))
request_serializer = self._request_serializers.get((group, method,))
response_deserializer = self._response_deserializers.get((group,
method,))
return _StreamStreamMultiCallable(
self._channel, group, method, self._metadata_transformer,
request_serializer, response_deserializer)

@ -85,9 +85,7 @@ class ConnectivityChannel(object):
def _spawn_delivery(self, connectivity, callbacks):
delivering_thread = threading.Thread(
target=self._deliver, args=(
connectivity,
callbacks,))
target=self._deliver, args=(connectivity, callbacks,))
delivering_thread.start()
self._delivering = True

@ -256,14 +256,9 @@ def _adapt_stream_stream_event(stream_stream_event):
class _SimpleMethodHandler(
collections.namedtuple('_MethodHandler', (
'request_streaming',
'response_streaming',
'request_deserializer',
'response_serializer',
'unary_unary',
'unary_stream',
'stream_unary',
'stream_stream',)), grpc.RpcMethodHandler):
'request_streaming', 'response_streaming', 'request_deserializer',
'response_serializer', 'unary_unary', 'unary_stream',
'stream_unary', 'stream_stream',)), grpc.RpcMethodHandler):
pass

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

Loading…
Cancel
Save