merge master and fix conflict on bm_fullstack

pull/9964/head
Yuxuan Li 8 years ago
commit 0574b58869
  1. 2
      .gitignore
  2. 14
      .pylintrc
  3. 8
      BUILD
  4. 405
      CMakeLists.txt
  5. 515
      Makefile
  6. 7
      bazel/cc_grpc_library.bzl
  7. 17
      bazel/generate_cc.bzl
  8. 4
      bazel/grpc_build_system.bzl
  9. 4
      binding.gyp
  10. 197
      build.yaml
  11. 4
      config.m4
  12. 1
      doc/g_stands_for.md
  13. 16
      doc/status_ordering.md
  14. 5
      examples/csharp/helloworld-from-cli/global.json
  15. 10
      gRPC-Core.podspec
  16. 2
      gRPC-ProtoRPC.podspec
  17. 2
      gRPC-RxLibrary.podspec
  18. 2
      gRPC.podspec
  19. 1
      grpc.def
  20. 6
      grpc.gemspec
  21. 52
      include/grpc++/impl/channel_argument_option.h
  22. 8
      include/grpc++/server_builder.h
  23. 2
      include/grpc++/support/channel_arguments.h
  24. 8
      include/grpc/impl/codegen/sync.h
  25. 4
      include/grpc/support/sync.h
  26. 2
      package.json
  27. 10
      package.xml
  28. 2
      requirements.txt
  29. 22
      src/compiler/python_generator.cc
  30. 3
      src/compiler/python_generator.h
  31. 4
      src/core/ext/census/grpc_filter.c
  32. 173
      src/core/ext/client_channel/client_channel.c
  33. 5
      src/core/ext/client_channel/parse_address.c
  34. 12
      src/core/ext/client_channel/proxy_mapper_registry.c
  35. 43
      src/core/ext/client_channel/subchannel.c
  36. 18
      src/core/ext/client_channel/subchannel.h
  37. 2
      src/core/ext/load_reporting/load_reporting_filter.c
  38. 31
      src/core/ext/transport/chttp2/transport/chttp2_transport.c
  39. 2
      src/core/ext/transport/chttp2/transport/frame_ping.c
  40. 65
      src/core/ext/transport/chttp2/transport/incoming_metadata.c
  41. 18
      src/core/ext/transport/chttp2/transport/incoming_metadata.h
  42. 2
      src/core/ext/transport/chttp2/transport/internal.h
  43. 40
      src/core/ext/transport/chttp2/transport/parsing.c
  44. 156
      src/core/ext/transport/cronet/transport/cronet_transport.c
  45. 36
      src/core/lib/channel/channel_stack.c
  46. 23
      src/core/lib/channel/channel_stack.h
  47. 2
      src/core/lib/channel/compress_filter.c
  48. 6
      src/core/lib/channel/connected_channel.c
  49. 2
      src/core/lib/channel/deadline_filter.c
  50. 2
      src/core/lib/channel/http_client_filter.c
  51. 2
      src/core/lib/channel/http_server_filter.c
  52. 2
      src/core/lib/channel/message_size_filter.c
  53. 456
      src/core/lib/iomgr/error.c
  54. 11
      src/core/lib/iomgr/error.h
  55. 35
      src/core/lib/iomgr/error_internal.h
  56. 22
      src/core/lib/iomgr/pollset_uv.c
  57. 4
      src/core/lib/iomgr/port.h
  58. 52
      src/core/lib/iomgr/resolve_address_uv.c
  59. 1
      src/core/lib/iomgr/tcp_client_uv.c
  60. 427
      src/core/lib/iomgr/tcp_server_posix.c
  61. 134
      src/core/lib/iomgr/tcp_server_utils_posix.h
  62. 220
      src/core/lib/iomgr/tcp_server_utils_posix_common.c
  63. 195
      src/core/lib/iomgr/tcp_server_utils_posix_ifaddrs.c
  64. 49
      src/core/lib/iomgr/tcp_server_utils_posix_noifaddrs.c
  65. 22
      src/core/lib/iomgr/udp_server.c
  66. 12
      src/core/lib/iomgr/udp_server.h
  67. 2
      src/core/lib/iomgr/wakeup_fd_posix.h
  68. 2
      src/core/lib/security/transport/client_auth_filter.c
  69. 2
      src/core/lib/security/transport/server_auth_filter.c
  70. 98
      src/core/lib/support/arena.c
  71. 54
      src/core/lib/support/arena.h
  72. 4
      src/core/lib/support/sync.c
  73. 146
      src/core/lib/surface/call.c
  74. 32
      src/core/lib/surface/channel.c
  75. 3
      src/core/lib/surface/channel.h
  76. 4
      src/core/lib/surface/lame_client.c
  77. 2
      src/core/lib/surface/server.c
  78. 2
      src/core/lib/surface/version.c
  79. 22
      src/core/lib/transport/error_utils.c
  80. 12
      src/core/lib/transport/transport.c
  81. 6
      src/core/lib/transport/transport.h
  82. 5
      src/core/lib/transport/transport_impl.h
  83. 14
      src/cpp/common/channel_arguments.cc
  84. 3
      src/cpp/common/channel_filter.h
  85. 2
      src/cpp/common/version_cc.cc
  86. 78
      src/cpp/server/channel_argument_option.cc
  87. 8
      src/cpp/server/server_builder.cc
  88. 2
      src/cpp/server/server_cc.cc
  89. 4
      src/csharp/Grpc.Auth/project.json
  90. 4
      src/csharp/Grpc.Core.Testing/project.json
  91. 41
      src/csharp/Grpc.Core.Tests/TestResult.xml
  92. 4
      src/csharp/Grpc.Core/VersionInfo.cs
  93. 2
      src/csharp/Grpc.Core/project.json
  94. 4
      src/csharp/Grpc.HealthCheck/project.json
  95. 4
      src/csharp/Grpc.Reflection/project.json
  96. 2
      src/csharp/build_packages_dotnetcli.bat
  97. 4
      src/csharp/build_packages_dotnetcli.sh
  98. 5
      src/csharp/global.json
  99. 4
      src/node/health_check/package.json
  100. 2
      src/node/src/server.js
  101. Some files were not shown because too many files have changed in this diff Show More

2
.gitignore vendored

@ -8,7 +8,7 @@ objs
# Python items # Python items
cython_debug/ cython_debug/
python_build/ python_build/
python_format_venv/ yapf_virtual_environment/
python_pylint_venv/ python_pylint_venv/
.coverage* .coverage*
.eggs .eggs

@ -3,6 +3,12 @@
# not include "unused_" and "ignored_" by default? # not include "unused_" and "ignored_" by default?
dummy-variables-rgx=^ignored_|^unused_ dummy-variables-rgx=^ignored_|^unused_
[DESIGN]
# NOTE(nathaniel): Not particularly attached to this value; it just seems to
# be what works for us at the moment (excepting the dead-code-walking Beta
# API).
max-args=6
[MISCELLANEOUS] [MISCELLANEOUS]
# NOTE(nathaniel): We are big fans of "TODO(<issue link>): " and # NOTE(nathaniel): We are big fans of "TODO(<issue link>): " and
# "NOTE(<username or issue link>): ". We do not allow "TODO:", # "NOTE(<username or issue link>): ". We do not allow "TODO:",
@ -13,28 +19,22 @@ notes=FIXME,XXX
#TODO: Enable missing-docstring #TODO: Enable missing-docstring
#TODO: Enable too-few-public-methods #TODO: Enable too-few-public-methods
#TODO: Enable too-many-arguments
#TODO: Enable no-init #TODO: Enable no-init
#TODO: Enable duplicate-code #TODO: Enable duplicate-code
#TODO: Enable invalid-name #TODO: Enable invalid-name
#TODO: Enable suppressed-message
#TODO: Enable locally-disabled #TODO: Enable locally-disabled
#TODO: Enable protected-access #TODO: Enable protected-access
#TODO: Enable no-name-in-module #TODO: Enable no-name-in-module
#TODO: Enable unused-argument
#TODO: Enable wrong-import-order #TODO: Enable wrong-import-order
# TODO(https://github.com/PyCQA/pylint/issues/59#issuecomment-283774279): # TODO(https://github.com/PyCQA/pylint/issues/59#issuecomment-283774279):
# enable cyclic-import after a 1.7-or-later pylint release that recognizes our # enable cyclic-import after a 1.7-or-later pylint release that recognizes our
# disable=cyclic-import suppressions. # disable=cyclic-import suppressions.
#TODO: Enable too-many-instance-attributes #TODO: Enable too-many-instance-attributes
#TODO: Enable too-many-locals
#TODO: Enable too-many-lines #TODO: Enable too-many-lines
#TODO: Enable redefined-variable-type #TODO: Enable redefined-variable-type
#TODO: Enable next-method-called #TODO: Enable next-method-called
#TODO: Enable import-error #TODO: Enable import-error
#TODO: Enable useless-else-on-loop #TODO: Enable useless-else-on-loop
#TODO: Enable too-many-return-statements
#TODO: Enable too-many-nested-blocks #TODO: Enable too-many-nested-blocks
#TODO: Enable super-init-not-called
disable=missing-docstring,too-few-public-methods,too-many-arguments,no-init,duplicate-code,invalid-name,suppressed-message,locally-disabled,protected-access,no-name-in-module,unused-argument,wrong-import-order,cyclic-import,too-many-instance-attributes,too-many-locals,too-many-lines,redefined-variable-type,next-method-called,import-error,useless-else-on-loop,too-many-return-statements,too-many-nested-blocks,super-init-not-called disable=missing-docstring,too-few-public-methods,no-init,duplicate-code,invalid-name,locally-disabled,protected-access,no-name-in-module,wrong-import-order,cyclic-import,too-many-instance-attributes,too-many-lines,redefined-variable-type,next-method-called,import-error,useless-else-on-loop,too-many-nested-blocks

@ -308,6 +308,7 @@ grpc_cc_library(
srcs = [ srcs = [
"src/core/lib/profiling/basic_timers.c", "src/core/lib/profiling/basic_timers.c",
"src/core/lib/profiling/stap_timers.c", "src/core/lib/profiling/stap_timers.c",
"src/core/lib/support/arena.c",
"src/core/lib/support/alloc.c", "src/core/lib/support/alloc.c",
"src/core/lib/support/avl.c", "src/core/lib/support/avl.c",
"src/core/lib/support/backoff.c", "src/core/lib/support/backoff.c",
@ -352,6 +353,7 @@ grpc_cc_library(
"src/core/lib/support/wrap_memcpy.c", "src/core/lib/support/wrap_memcpy.c",
], ],
hdrs = [ hdrs = [
"src/core/lib/support/arena.h",
"src/core/lib/profiling/timers.h", "src/core/lib/profiling/timers.h",
"src/core/lib/support/backoff.h", "src/core/lib/support/backoff.h",
"src/core/lib/support/block_annotate.h", "src/core/lib/support/block_annotate.h",
@ -481,6 +483,9 @@ grpc_cc_library(
"src/core/lib/iomgr/tcp_client_windows.c", "src/core/lib/iomgr/tcp_client_windows.c",
"src/core/lib/iomgr/tcp_posix.c", "src/core/lib/iomgr/tcp_posix.c",
"src/core/lib/iomgr/tcp_server_posix.c", "src/core/lib/iomgr/tcp_server_posix.c",
"src/core/lib/iomgr/tcp_server_utils_posix_common.c",
"src/core/lib/iomgr/tcp_server_utils_posix_ifaddrs.c",
"src/core/lib/iomgr/tcp_server_utils_posix_noifaddrs.c",
"src/core/lib/iomgr/tcp_server_uv.c", "src/core/lib/iomgr/tcp_server_uv.c",
"src/core/lib/iomgr/tcp_server_windows.c", "src/core/lib/iomgr/tcp_server_windows.c",
"src/core/lib/iomgr/tcp_uv.c", "src/core/lib/iomgr/tcp_uv.c",
@ -599,6 +604,7 @@ grpc_cc_library(
"src/core/lib/iomgr/tcp_client_posix.h", "src/core/lib/iomgr/tcp_client_posix.h",
"src/core/lib/iomgr/tcp_posix.h", "src/core/lib/iomgr/tcp_posix.h",
"src/core/lib/iomgr/tcp_server.h", "src/core/lib/iomgr/tcp_server.h",
"src/core/lib/iomgr/tcp_server_utils_posix.h",
"src/core/lib/iomgr/tcp_uv.h", "src/core/lib/iomgr/tcp_uv.h",
"src/core/lib/iomgr/tcp_windows.h", "src/core/lib/iomgr/tcp_windows.h",
"src/core/lib/iomgr/time_averaged_stats.h", "src/core/lib/iomgr/time_averaged_stats.h",
@ -1132,6 +1138,7 @@ grpc_cc_library(
"src/cpp/common/rpc_method.cc", "src/cpp/common/rpc_method.cc",
"src/cpp/common/version_cc.cc", "src/cpp/common/version_cc.cc",
"src/cpp/server/async_generic_service.cc", "src/cpp/server/async_generic_service.cc",
"src/cpp/server/channel_argument_option.cc",
"src/cpp/server/create_default_thread_pool.cc", "src/cpp/server/create_default_thread_pool.cc",
"src/cpp/server/dynamic_thread_pool.cc", "src/cpp/server/dynamic_thread_pool.cc",
"src/cpp/server/health/default_health_check_service.cc", "src/cpp/server/health/default_health_check_service.cc",
@ -1173,6 +1180,7 @@ grpc_cc_library(
"include/grpc++/grpc++.h", "include/grpc++/grpc++.h",
"include/grpc++/health_check_service_interface.h", "include/grpc++/health_check_service_interface.h",
"include/grpc++/impl/call.h", "include/grpc++/impl/call.h",
"include/grpc++/impl/channel_argument_option.h",
"include/grpc++/impl/client_unary_call.h", "include/grpc++/impl/client_unary_call.h",
"include/grpc++/impl/codegen/core_codegen.h", "include/grpc++/impl/codegen/core_codegen.h",
"include/grpc++/impl/grpc_library.h", "include/grpc++/impl/grpc_library.h",

@ -42,7 +42,7 @@
cmake_minimum_required(VERSION 2.8) cmake_minimum_required(VERSION 2.8)
set(PACKAGE_NAME "grpc") set(PACKAGE_NAME "grpc")
set(PACKAGE_VERSION "1.2.0-dev") set(PACKAGE_VERSION "1.3.0-dev")
set(PACKAGE_STRING "${PACKAGE_NAME} ${PACKAGE_VERSION}") set(PACKAGE_STRING "${PACKAGE_NAME} ${PACKAGE_VERSION}")
set(PACKAGE_TARNAME "${PACKAGE_NAME}-${PACKAGE_VERSION}") set(PACKAGE_TARNAME "${PACKAGE_NAME}-${PACKAGE_VERSION}")
set(PACKAGE_BUGREPORT "https://github.com/grpc/grpc/issues/") set(PACKAGE_BUGREPORT "https://github.com/grpc/grpc/issues/")
@ -332,6 +332,7 @@ add_dependencies(buildtests_c alarm_test)
add_dependencies(buildtests_c algorithm_test) add_dependencies(buildtests_c algorithm_test)
add_dependencies(buildtests_c alloc_test) add_dependencies(buildtests_c alloc_test)
add_dependencies(buildtests_c alpn_test) add_dependencies(buildtests_c alpn_test)
add_dependencies(buildtests_c arena_test)
add_dependencies(buildtests_c bad_server_response_test) add_dependencies(buildtests_c bad_server_response_test)
add_dependencies(buildtests_c bdp_estimator_test) add_dependencies(buildtests_c bdp_estimator_test)
add_dependencies(buildtests_c bin_decoder_test) add_dependencies(buildtests_c bin_decoder_test)
@ -353,6 +354,7 @@ if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX)
add_dependencies(buildtests_c dualstack_socket_test) add_dependencies(buildtests_c dualstack_socket_test)
endif() endif()
add_dependencies(buildtests_c endpoint_pair_test) add_dependencies(buildtests_c endpoint_pair_test)
add_dependencies(buildtests_c error_test)
if(_gRPC_PLATFORM_LINUX) if(_gRPC_PLATFORM_LINUX)
add_dependencies(buildtests_c ev_epoll_linux_test) add_dependencies(buildtests_c ev_epoll_linux_test)
endif() endif()
@ -573,6 +575,9 @@ add_dependencies(buildtests_cxx alarm_cpp_test)
add_dependencies(buildtests_cxx async_end2end_test) add_dependencies(buildtests_cxx async_end2end_test)
add_dependencies(buildtests_cxx auth_property_iterator_test) add_dependencies(buildtests_cxx auth_property_iterator_test)
if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX) if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX)
add_dependencies(buildtests_cxx bm_arena)
endif()
if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX)
add_dependencies(buildtests_cxx bm_call_create) add_dependencies(buildtests_cxx bm_call_create)
endif() endif()
if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX) if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX)
@ -588,11 +593,23 @@ if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX)
add_dependencies(buildtests_cxx bm_error) add_dependencies(buildtests_cxx bm_error)
endif() endif()
if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX) if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX)
add_dependencies(buildtests_cxx bm_fullstack) add_dependencies(buildtests_cxx bm_fullstack_streaming_ping_pong)
endif()
if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX)
add_dependencies(buildtests_cxx bm_fullstack_streaming_pump)
endif()
if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX)
add_dependencies(buildtests_cxx bm_fullstack_trickle)
endif()
if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX)
add_dependencies(buildtests_cxx bm_fullstack_unary_ping_pong)
endif() endif()
if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX) if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX)
add_dependencies(buildtests_cxx bm_metadata) add_dependencies(buildtests_cxx bm_metadata)
endif() endif()
if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX)
add_dependencies(buildtests_cxx bm_pollset)
endif()
add_dependencies(buildtests_cxx channel_arguments_test) add_dependencies(buildtests_cxx channel_arguments_test)
add_dependencies(buildtests_cxx channel_filter_test) add_dependencies(buildtests_cxx channel_filter_test)
add_dependencies(buildtests_cxx cli_call_test) add_dependencies(buildtests_cxx cli_call_test)
@ -653,6 +670,7 @@ if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX)
add_dependencies(buildtests_cxx secure_sync_unary_ping_pong_test) add_dependencies(buildtests_cxx secure_sync_unary_ping_pong_test)
endif() endif()
add_dependencies(buildtests_cxx server_builder_plugin_test) add_dependencies(buildtests_cxx server_builder_plugin_test)
add_dependencies(buildtests_cxx server_builder_test)
add_dependencies(buildtests_cxx server_context_test_spouse_test) add_dependencies(buildtests_cxx server_context_test_spouse_test)
if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX) if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX)
add_dependencies(buildtests_cxx server_crash_test) add_dependencies(buildtests_cxx server_crash_test)
@ -679,6 +697,7 @@ add_library(gpr
src/core/lib/profiling/basic_timers.c src/core/lib/profiling/basic_timers.c
src/core/lib/profiling/stap_timers.c src/core/lib/profiling/stap_timers.c
src/core/lib/support/alloc.c src/core/lib/support/alloc.c
src/core/lib/support/arena.c
src/core/lib/support/avl.c src/core/lib/support/avl.c
src/core/lib/support/backoff.c src/core/lib/support/backoff.c
src/core/lib/support/cmdline.c src/core/lib/support/cmdline.c
@ -903,6 +922,9 @@ add_library(grpc
src/core/lib/iomgr/tcp_client_windows.c src/core/lib/iomgr/tcp_client_windows.c
src/core/lib/iomgr/tcp_posix.c src/core/lib/iomgr/tcp_posix.c
src/core/lib/iomgr/tcp_server_posix.c src/core/lib/iomgr/tcp_server_posix.c
src/core/lib/iomgr/tcp_server_utils_posix_common.c
src/core/lib/iomgr/tcp_server_utils_posix_ifaddrs.c
src/core/lib/iomgr/tcp_server_utils_posix_noifaddrs.c
src/core/lib/iomgr/tcp_server_uv.c src/core/lib/iomgr/tcp_server_uv.c
src/core/lib/iomgr/tcp_server_windows.c src/core/lib/iomgr/tcp_server_windows.c
src/core/lib/iomgr/tcp_uv.c src/core/lib/iomgr/tcp_uv.c
@ -1212,6 +1234,9 @@ add_library(grpc_cronet
src/core/lib/iomgr/tcp_client_windows.c src/core/lib/iomgr/tcp_client_windows.c
src/core/lib/iomgr/tcp_posix.c src/core/lib/iomgr/tcp_posix.c
src/core/lib/iomgr/tcp_server_posix.c src/core/lib/iomgr/tcp_server_posix.c
src/core/lib/iomgr/tcp_server_utils_posix_common.c
src/core/lib/iomgr/tcp_server_utils_posix_ifaddrs.c
src/core/lib/iomgr/tcp_server_utils_posix_noifaddrs.c
src/core/lib/iomgr/tcp_server_uv.c src/core/lib/iomgr/tcp_server_uv.c
src/core/lib/iomgr/tcp_server_windows.c src/core/lib/iomgr/tcp_server_windows.c
src/core/lib/iomgr/tcp_uv.c src/core/lib/iomgr/tcp_uv.c
@ -1440,7 +1465,7 @@ add_library(grpc_test_util
test/core/security/oauth2_utils.c test/core/security/oauth2_utils.c
test/core/end2end/cq_verifier.c test/core/end2end/cq_verifier.c
test/core/end2end/fake_resolver.c test/core/end2end/fake_resolver.c
test/core/end2end/fixtures/http_proxy.c test/core/end2end/fixtures/http_proxy_fixture.c
test/core/end2end/fixtures/proxy.c test/core/end2end/fixtures/proxy.c
test/core/iomgr/endpoint_tests.c test/core/iomgr/endpoint_tests.c
test/core/util/debugger_macros.c test/core/util/debugger_macros.c
@ -1512,6 +1537,9 @@ add_library(grpc_test_util
src/core/lib/iomgr/tcp_client_windows.c src/core/lib/iomgr/tcp_client_windows.c
src/core/lib/iomgr/tcp_posix.c src/core/lib/iomgr/tcp_posix.c
src/core/lib/iomgr/tcp_server_posix.c src/core/lib/iomgr/tcp_server_posix.c
src/core/lib/iomgr/tcp_server_utils_posix_common.c
src/core/lib/iomgr/tcp_server_utils_posix_ifaddrs.c
src/core/lib/iomgr/tcp_server_utils_posix_noifaddrs.c
src/core/lib/iomgr/tcp_server_uv.c src/core/lib/iomgr/tcp_server_uv.c
src/core/lib/iomgr/tcp_server_windows.c src/core/lib/iomgr/tcp_server_windows.c
src/core/lib/iomgr/tcp_uv.c src/core/lib/iomgr/tcp_uv.c
@ -1647,7 +1675,7 @@ if (gRPC_BUILD_TESTS)
add_library(grpc_test_util_unsecure add_library(grpc_test_util_unsecure
test/core/end2end/cq_verifier.c test/core/end2end/cq_verifier.c
test/core/end2end/fake_resolver.c test/core/end2end/fake_resolver.c
test/core/end2end/fixtures/http_proxy.c test/core/end2end/fixtures/http_proxy_fixture.c
test/core/end2end/fixtures/proxy.c test/core/end2end/fixtures/proxy.c
test/core/iomgr/endpoint_tests.c test/core/iomgr/endpoint_tests.c
test/core/util/debugger_macros.c test/core/util/debugger_macros.c
@ -1758,6 +1786,9 @@ add_library(grpc_unsecure
src/core/lib/iomgr/tcp_client_windows.c src/core/lib/iomgr/tcp_client_windows.c
src/core/lib/iomgr/tcp_posix.c src/core/lib/iomgr/tcp_posix.c
src/core/lib/iomgr/tcp_server_posix.c src/core/lib/iomgr/tcp_server_posix.c
src/core/lib/iomgr/tcp_server_utils_posix_common.c
src/core/lib/iomgr/tcp_server_utils_posix_ifaddrs.c
src/core/lib/iomgr/tcp_server_utils_posix_noifaddrs.c
src/core/lib/iomgr/tcp_server_uv.c src/core/lib/iomgr/tcp_server_uv.c
src/core/lib/iomgr/tcp_server_windows.c src/core/lib/iomgr/tcp_server_windows.c
src/core/lib/iomgr/tcp_uv.c src/core/lib/iomgr/tcp_uv.c
@ -2076,6 +2107,7 @@ add_library(grpc++
src/cpp/common/rpc_method.cc src/cpp/common/rpc_method.cc
src/cpp/common/version_cc.cc src/cpp/common/version_cc.cc
src/cpp/server/async_generic_service.cc src/cpp/server/async_generic_service.cc
src/cpp/server/channel_argument_option.cc
src/cpp/server/create_default_thread_pool.cc src/cpp/server/create_default_thread_pool.cc
src/cpp/server/dynamic_thread_pool.cc src/cpp/server/dynamic_thread_pool.cc
src/cpp/server/health/default_health_check_service.cc src/cpp/server/health/default_health_check_service.cc
@ -2141,6 +2173,7 @@ foreach(_hdr
include/grpc++/grpc++.h include/grpc++/grpc++.h
include/grpc++/health_check_service_interface.h include/grpc++/health_check_service_interface.h
include/grpc++/impl/call.h include/grpc++/impl/call.h
include/grpc++/impl/channel_argument_option.h
include/grpc++/impl/client_unary_call.h include/grpc++/impl/client_unary_call.h
include/grpc++/impl/codegen/core_codegen.h include/grpc++/impl/codegen/core_codegen.h
include/grpc++/impl/grpc_library.h include/grpc++/impl/grpc_library.h
@ -2262,6 +2295,7 @@ add_library(grpc++_cronet
src/cpp/common/rpc_method.cc src/cpp/common/rpc_method.cc
src/cpp/common/version_cc.cc src/cpp/common/version_cc.cc
src/cpp/server/async_generic_service.cc src/cpp/server/async_generic_service.cc
src/cpp/server/channel_argument_option.cc
src/cpp/server/create_default_thread_pool.cc src/cpp/server/create_default_thread_pool.cc
src/cpp/server/dynamic_thread_pool.cc src/cpp/server/dynamic_thread_pool.cc
src/cpp/server/health/default_health_check_service.cc src/cpp/server/health/default_health_check_service.cc
@ -2362,6 +2396,9 @@ add_library(grpc++_cronet
src/core/lib/iomgr/tcp_client_windows.c src/core/lib/iomgr/tcp_client_windows.c
src/core/lib/iomgr/tcp_posix.c src/core/lib/iomgr/tcp_posix.c
src/core/lib/iomgr/tcp_server_posix.c src/core/lib/iomgr/tcp_server_posix.c
src/core/lib/iomgr/tcp_server_utils_posix_common.c
src/core/lib/iomgr/tcp_server_utils_posix_ifaddrs.c
src/core/lib/iomgr/tcp_server_utils_posix_noifaddrs.c
src/core/lib/iomgr/tcp_server_uv.c src/core/lib/iomgr/tcp_server_uv.c
src/core/lib/iomgr/tcp_server_windows.c src/core/lib/iomgr/tcp_server_windows.c
src/core/lib/iomgr/tcp_uv.c src/core/lib/iomgr/tcp_uv.c
@ -2511,6 +2548,7 @@ foreach(_hdr
include/grpc++/grpc++.h include/grpc++/grpc++.h
include/grpc++/health_check_service_interface.h include/grpc++/health_check_service_interface.h
include/grpc++/impl/call.h include/grpc++/impl/call.h
include/grpc++/impl/channel_argument_option.h
include/grpc++/impl/client_unary_call.h include/grpc++/impl/client_unary_call.h
include/grpc++/impl/codegen/core_codegen.h include/grpc++/impl/codegen/core_codegen.h
include/grpc++/impl/grpc_library.h include/grpc++/impl/grpc_library.h
@ -2933,6 +2971,7 @@ add_library(grpc++_unsecure
src/cpp/common/rpc_method.cc src/cpp/common/rpc_method.cc
src/cpp/common/version_cc.cc src/cpp/common/version_cc.cc
src/cpp/server/async_generic_service.cc src/cpp/server/async_generic_service.cc
src/cpp/server/channel_argument_option.cc
src/cpp/server/create_default_thread_pool.cc src/cpp/server/create_default_thread_pool.cc
src/cpp/server/dynamic_thread_pool.cc src/cpp/server/dynamic_thread_pool.cc
src/cpp/server/health/default_health_check_service.cc src/cpp/server/health/default_health_check_service.cc
@ -2998,6 +3037,7 @@ foreach(_hdr
include/grpc++/grpc++.h include/grpc++/grpc++.h
include/grpc++/health_check_service_interface.h include/grpc++/health_check_service_interface.h
include/grpc++/impl/call.h include/grpc++/impl/call.h
include/grpc++/impl/channel_argument_option.h
include/grpc++/impl/client_unary_call.h include/grpc++/impl/client_unary_call.h
include/grpc++/impl/codegen/core_codegen.h include/grpc++/impl/codegen/core_codegen.h
include/grpc++/impl/grpc_library.h include/grpc++/impl/grpc_library.h
@ -3098,6 +3138,50 @@ endif()
if (gRPC_BUILD_TESTS) if (gRPC_BUILD_TESTS)
add_library(grpc_benchmark
test/cpp/microbenchmarks/helpers.cc
)
if(WIN32 AND MSVC)
set_target_properties(grpc_benchmark PROPERTIES COMPILE_PDB_NAME "grpc_benchmark"
COMPILE_PDB_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}"
)
if (gRPC_INSTALL)
install(FILES ${CMAKE_CURRENT_BINARY_DIR}/grpc_benchmark.pdb
DESTINATION ${CMAKE_INSTALL_LIBDIR} OPTIONAL
)
endif()
endif()
target_include_directories(grpc_benchmark
PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
PRIVATE ${BORINGSSL_ROOT_DIR}/include
PRIVATE ${PROTOBUF_ROOT_DIR}/src
PRIVATE ${ZLIB_INCLUDE_DIR}
PRIVATE ${BENCHMARK}/include
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(grpc_benchmark
${_gRPC_PROTOBUF_LIBRARIES}
${_gRPC_ALLTARGETS_LIBRARIES}
benchmark
grpc++
grpc_test_util
grpc
${_gRPC_GFLAGS_LIBRARIES}
)
endif (gRPC_BUILD_TESTS)
if (gRPC_BUILD_TESTS)
add_library(grpc_cli_libs add_library(grpc_cli_libs
test/cpp/util/cli_call.cc test/cpp/util/cli_call.cc
test/cpp/util/cli_credentials.cc test/cpp/util/cli_credentials.cc
@ -4051,6 +4135,31 @@ target_link_libraries(alpn_test
endif (gRPC_BUILD_TESTS) endif (gRPC_BUILD_TESTS)
if (gRPC_BUILD_TESTS) if (gRPC_BUILD_TESTS)
add_executable(arena_test
test/core/support/arena_test.c
)
target_include_directories(arena_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(arena_test
${_gRPC_ALLTARGETS_LIBRARIES}
gpr_test_util
gpr
)
endif (gRPC_BUILD_TESTS)
if (gRPC_BUILD_TESTS)
add_executable(bad_server_response_test add_executable(bad_server_response_test
test/core/end2end/bad_server_response_test.c test/core/end2end/bad_server_response_test.c
) )
@ -4560,6 +4669,33 @@ target_link_libraries(endpoint_pair_test
gpr gpr
) )
endif (gRPC_BUILD_TESTS)
if (gRPC_BUILD_TESTS)
add_executable(error_test
test/core/iomgr/error_test.c
)
target_include_directories(error_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(error_test
${_gRPC_ALLTARGETS_LIBRARIES}
grpc_test_util
grpc
gpr_test_util
gpr
)
endif (gRPC_BUILD_TESTS) endif (gRPC_BUILD_TESTS)
if (gRPC_BUILD_TESTS) if (gRPC_BUILD_TESTS)
if(_gRPC_PLATFORM_LINUX) if(_gRPC_PLATFORM_LINUX)
@ -7538,6 +7674,45 @@ endif (gRPC_BUILD_TESTS)
if (gRPC_BUILD_TESTS) if (gRPC_BUILD_TESTS)
if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX) if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX)
add_executable(bm_arena
test/cpp/microbenchmarks/bm_arena.cc
third_party/googletest/src/gtest-all.cc
)
target_include_directories(bm_arena
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(bm_arena
${_gRPC_PROTOBUF_LIBRARIES}
${_gRPC_ALLTARGETS_LIBRARIES}
grpc_benchmark
benchmark
grpc++_test_util
grpc_test_util
grpc++
grpc
gpr_test_util
gpr
${_gRPC_GFLAGS_LIBRARIES}
)
endif()
endif (gRPC_BUILD_TESTS)
if (gRPC_BUILD_TESTS)
if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX)
add_executable(bm_call_create add_executable(bm_call_create
test/cpp/microbenchmarks/bm_call_create.cc test/cpp/microbenchmarks/bm_call_create.cc
third_party/googletest/src/gtest-all.cc third_party/googletest/src/gtest-all.cc
@ -7561,6 +7736,7 @@ target_include_directories(bm_call_create
target_link_libraries(bm_call_create target_link_libraries(bm_call_create
${_gRPC_PROTOBUF_LIBRARIES} ${_gRPC_PROTOBUF_LIBRARIES}
${_gRPC_ALLTARGETS_LIBRARIES} ${_gRPC_ALLTARGETS_LIBRARIES}
grpc_benchmark
benchmark benchmark
grpc++_test_util grpc++_test_util
grpc_test_util grpc_test_util
@ -7599,6 +7775,7 @@ target_include_directories(bm_chttp2_hpack
target_link_libraries(bm_chttp2_hpack target_link_libraries(bm_chttp2_hpack
${_gRPC_PROTOBUF_LIBRARIES} ${_gRPC_PROTOBUF_LIBRARIES}
${_gRPC_ALLTARGETS_LIBRARIES} ${_gRPC_ALLTARGETS_LIBRARIES}
grpc_benchmark
benchmark benchmark
grpc++_test_util grpc++_test_util
grpc_test_util grpc_test_util
@ -7637,6 +7814,7 @@ target_include_directories(bm_closure
target_link_libraries(bm_closure target_link_libraries(bm_closure
${_gRPC_PROTOBUF_LIBRARIES} ${_gRPC_PROTOBUF_LIBRARIES}
${_gRPC_ALLTARGETS_LIBRARIES} ${_gRPC_ALLTARGETS_LIBRARIES}
grpc_benchmark
benchmark benchmark
grpc++_test_util grpc++_test_util
grpc_test_util grpc_test_util
@ -7675,6 +7853,7 @@ target_include_directories(bm_cq
target_link_libraries(bm_cq target_link_libraries(bm_cq
${_gRPC_PROTOBUF_LIBRARIES} ${_gRPC_PROTOBUF_LIBRARIES}
${_gRPC_ALLTARGETS_LIBRARIES} ${_gRPC_ALLTARGETS_LIBRARIES}
grpc_benchmark
benchmark benchmark
grpc++_test_util grpc++_test_util
grpc_test_util grpc_test_util
@ -7713,6 +7892,7 @@ target_include_directories(bm_error
target_link_libraries(bm_error target_link_libraries(bm_error
${_gRPC_PROTOBUF_LIBRARIES} ${_gRPC_PROTOBUF_LIBRARIES}
${_gRPC_ALLTARGETS_LIBRARIES} ${_gRPC_ALLTARGETS_LIBRARIES}
grpc_benchmark
benchmark benchmark
grpc++_test_util grpc++_test_util
grpc_test_util grpc_test_util
@ -7728,13 +7908,13 @@ endif (gRPC_BUILD_TESTS)
if (gRPC_BUILD_TESTS) if (gRPC_BUILD_TESTS)
if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX) if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX)
add_executable(bm_fullstack add_executable(bm_fullstack_streaming_ping_pong
test/cpp/microbenchmarks/bm_fullstack.cc test/cpp/microbenchmarks/bm_fullstack_streaming_ping_pong.cc
third_party/googletest/src/gtest-all.cc third_party/googletest/src/gtest-all.cc
) )
target_include_directories(bm_fullstack target_include_directories(bm_fullstack_streaming_ping_pong
PRIVATE ${CMAKE_CURRENT_SOURCE_DIR} PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
PRIVATE ${BORINGSSL_ROOT_DIR}/include PRIVATE ${BORINGSSL_ROOT_DIR}/include
@ -7748,9 +7928,127 @@ target_include_directories(bm_fullstack
PRIVATE ${_gRPC_PROTO_GENS_DIR} PRIVATE ${_gRPC_PROTO_GENS_DIR}
) )
target_link_libraries(bm_fullstack target_link_libraries(bm_fullstack_streaming_ping_pong
${_gRPC_PROTOBUF_LIBRARIES} ${_gRPC_PROTOBUF_LIBRARIES}
${_gRPC_ALLTARGETS_LIBRARIES} ${_gRPC_ALLTARGETS_LIBRARIES}
grpc_benchmark
benchmark
grpc++_test_util
grpc_test_util
grpc++
grpc
gpr_test_util
gpr
${_gRPC_GFLAGS_LIBRARIES}
)
endif()
endif (gRPC_BUILD_TESTS)
if (gRPC_BUILD_TESTS)
if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX)
add_executable(bm_fullstack_streaming_pump
test/cpp/microbenchmarks/bm_fullstack_streaming_pump.cc
third_party/googletest/src/gtest-all.cc
)
target_include_directories(bm_fullstack_streaming_pump
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(bm_fullstack_streaming_pump
${_gRPC_PROTOBUF_LIBRARIES}
${_gRPC_ALLTARGETS_LIBRARIES}
grpc_benchmark
benchmark
grpc++_test_util
grpc_test_util
grpc++
grpc
gpr_test_util
gpr
${_gRPC_GFLAGS_LIBRARIES}
)
endif()
endif (gRPC_BUILD_TESTS)
if (gRPC_BUILD_TESTS)
if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX)
add_executable(bm_fullstack_trickle
test/cpp/microbenchmarks/bm_fullstack_trickle.cc
third_party/googletest/src/gtest-all.cc
)
target_include_directories(bm_fullstack_trickle
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(bm_fullstack_trickle
${_gRPC_PROTOBUF_LIBRARIES}
${_gRPC_ALLTARGETS_LIBRARIES}
grpc_benchmark
benchmark
grpc++_test_util
grpc_test_util
grpc++
grpc
gpr_test_util
gpr
${_gRPC_GFLAGS_LIBRARIES}
)
endif()
endif (gRPC_BUILD_TESTS)
if (gRPC_BUILD_TESTS)
if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX)
add_executable(bm_fullstack_unary_ping_pong
test/cpp/microbenchmarks/bm_fullstack_unary_ping_pong.cc
third_party/googletest/src/gtest-all.cc
)
target_include_directories(bm_fullstack_unary_ping_pong
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(bm_fullstack_unary_ping_pong
${_gRPC_PROTOBUF_LIBRARIES}
${_gRPC_ALLTARGETS_LIBRARIES}
grpc_benchmark
benchmark benchmark
grpc++_test_util grpc++_test_util
grpc_test_util grpc_test_util
@ -7789,8 +8087,50 @@ target_include_directories(bm_metadata
target_link_libraries(bm_metadata target_link_libraries(bm_metadata
${_gRPC_PROTOBUF_LIBRARIES} ${_gRPC_PROTOBUF_LIBRARIES}
${_gRPC_ALLTARGETS_LIBRARIES} ${_gRPC_ALLTARGETS_LIBRARIES}
grpc_benchmark
benchmark
grpc++_test_util
grpc_test_util
grpc++
grpc
gpr_test_util
gpr
${_gRPC_GFLAGS_LIBRARIES}
)
endif()
endif (gRPC_BUILD_TESTS)
if (gRPC_BUILD_TESTS)
if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX)
add_executable(bm_pollset
test/cpp/microbenchmarks/bm_pollset.cc
third_party/googletest/src/gtest-all.cc
)
target_include_directories(bm_pollset
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(bm_pollset
${_gRPC_PROTOBUF_LIBRARIES}
${_gRPC_ALLTARGETS_LIBRARIES}
grpc_benchmark
benchmark benchmark
grpc++_test_util
grpc_test_util grpc_test_util
grpc++
grpc grpc
gpr_test_util gpr_test_util
gpr gpr
@ -9662,6 +10002,55 @@ target_link_libraries(server_builder_plugin_test
endif (gRPC_BUILD_TESTS) endif (gRPC_BUILD_TESTS)
if (gRPC_BUILD_TESTS) if (gRPC_BUILD_TESTS)
add_executable(server_builder_test
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo_messages.pb.cc
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo_messages.grpc.pb.cc
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo_messages.pb.h
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo_messages.grpc.pb.h
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo.pb.cc
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo.grpc.pb.cc
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo.pb.h
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo.grpc.pb.h
test/cpp/server/server_builder_test.cc
third_party/googletest/src/gtest-all.cc
)
protobuf_generate_grpc_cpp(
src/proto/grpc/testing/echo_messages.proto
)
protobuf_generate_grpc_cpp(
src/proto/grpc/testing/echo.proto
)
target_include_directories(server_builder_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(server_builder_test
${_gRPC_PROTOBUF_LIBRARIES}
${_gRPC_ALLTARGETS_LIBRARIES}
grpc++_test_util
grpc_test_util
gpr_test_util
grpc++
grpc
gpr
${_gRPC_GFLAGS_LIBRARIES}
)
endif (gRPC_BUILD_TESTS)
if (gRPC_BUILD_TESTS)
add_executable(server_context_test_spouse_test add_executable(server_context_test_spouse_test
test/cpp/test/server_context_test_spouse_test.cc test/cpp/test/server_context_test_spouse_test.cc
third_party/googletest/src/gtest-all.cc third_party/googletest/src/gtest-all.cc

@ -189,7 +189,7 @@ CC_ubsan = clang
CXX_ubsan = clang++ CXX_ubsan = clang++
LD_ubsan = clang LD_ubsan = clang
LDXX_ubsan = clang++ LDXX_ubsan = clang++
CPPFLAGS_ubsan = -O0 -fsanitize-coverage=edge -fsanitize=undefined,unsigned-integer-overflow -fno-omit-frame-pointer -Wno-unused-command-line-argument -Wvarargs CPPFLAGS_ubsan = -O0 -fsanitize-coverage=edge -fsanitize=undefined -fno-omit-frame-pointer -Wno-unused-command-line-argument -Wvarargs
LDFLAGS_ubsan = -fsanitize=undefined,unsigned-integer-overflow LDFLAGS_ubsan = -fsanitize=undefined,unsigned-integer-overflow
DEFINES_ubsan = NDEBUG DEFINES_ubsan = NDEBUG
@ -412,8 +412,8 @@ Q = @
endif endif
CORE_VERSION = 3.0.0-dev CORE_VERSION = 3.0.0-dev
CPP_VERSION = 1.2.0-dev CPP_VERSION = 1.3.0-dev
CSHARP_VERSION = 1.2.0-dev CSHARP_VERSION = 1.3.0-dev
CPPFLAGS_NO_ARCH += $(addprefix -I, $(INCLUDES)) $(addprefix -D, $(DEFINES)) CPPFLAGS_NO_ARCH += $(addprefix -I, $(INCLUDES)) $(addprefix -D, $(DEFINES))
CPPFLAGS += $(CPPFLAGS_NO_ARCH) $(ARCH_FLAGS) CPPFLAGS += $(CPPFLAGS_NO_ARCH) $(ARCH_FLAGS)
@ -906,6 +906,7 @@ algorithm_test: $(BINDIR)/$(CONFIG)/algorithm_test
alloc_test: $(BINDIR)/$(CONFIG)/alloc_test alloc_test: $(BINDIR)/$(CONFIG)/alloc_test
alpn_test: $(BINDIR)/$(CONFIG)/alpn_test alpn_test: $(BINDIR)/$(CONFIG)/alpn_test
api_fuzzer: $(BINDIR)/$(CONFIG)/api_fuzzer api_fuzzer: $(BINDIR)/$(CONFIG)/api_fuzzer
arena_test: $(BINDIR)/$(CONFIG)/arena_test
bad_server_response_test: $(BINDIR)/$(CONFIG)/bad_server_response_test bad_server_response_test: $(BINDIR)/$(CONFIG)/bad_server_response_test
bdp_estimator_test: $(BINDIR)/$(CONFIG)/bdp_estimator_test bdp_estimator_test: $(BINDIR)/$(CONFIG)/bdp_estimator_test
bin_decoder_test: $(BINDIR)/$(CONFIG)/bin_decoder_test bin_decoder_test: $(BINDIR)/$(CONFIG)/bin_decoder_test
@ -926,6 +927,7 @@ dns_resolver_connectivity_test: $(BINDIR)/$(CONFIG)/dns_resolver_connectivity_te
dns_resolver_test: $(BINDIR)/$(CONFIG)/dns_resolver_test dns_resolver_test: $(BINDIR)/$(CONFIG)/dns_resolver_test
dualstack_socket_test: $(BINDIR)/$(CONFIG)/dualstack_socket_test dualstack_socket_test: $(BINDIR)/$(CONFIG)/dualstack_socket_test
endpoint_pair_test: $(BINDIR)/$(CONFIG)/endpoint_pair_test endpoint_pair_test: $(BINDIR)/$(CONFIG)/endpoint_pair_test
error_test: $(BINDIR)/$(CONFIG)/error_test
ev_epoll_linux_test: $(BINDIR)/$(CONFIG)/ev_epoll_linux_test ev_epoll_linux_test: $(BINDIR)/$(CONFIG)/ev_epoll_linux_test
fd_conservation_posix_test: $(BINDIR)/$(CONFIG)/fd_conservation_posix_test fd_conservation_posix_test: $(BINDIR)/$(CONFIG)/fd_conservation_posix_test
fd_posix_test: $(BINDIR)/$(CONFIG)/fd_posix_test fd_posix_test: $(BINDIR)/$(CONFIG)/fd_posix_test
@ -1046,13 +1048,18 @@ wakeup_fd_cv_test: $(BINDIR)/$(CONFIG)/wakeup_fd_cv_test
alarm_cpp_test: $(BINDIR)/$(CONFIG)/alarm_cpp_test alarm_cpp_test: $(BINDIR)/$(CONFIG)/alarm_cpp_test
async_end2end_test: $(BINDIR)/$(CONFIG)/async_end2end_test async_end2end_test: $(BINDIR)/$(CONFIG)/async_end2end_test
auth_property_iterator_test: $(BINDIR)/$(CONFIG)/auth_property_iterator_test auth_property_iterator_test: $(BINDIR)/$(CONFIG)/auth_property_iterator_test
bm_arena: $(BINDIR)/$(CONFIG)/bm_arena
bm_call_create: $(BINDIR)/$(CONFIG)/bm_call_create bm_call_create: $(BINDIR)/$(CONFIG)/bm_call_create
bm_chttp2_hpack: $(BINDIR)/$(CONFIG)/bm_chttp2_hpack bm_chttp2_hpack: $(BINDIR)/$(CONFIG)/bm_chttp2_hpack
bm_closure: $(BINDIR)/$(CONFIG)/bm_closure bm_closure: $(BINDIR)/$(CONFIG)/bm_closure
bm_cq: $(BINDIR)/$(CONFIG)/bm_cq bm_cq: $(BINDIR)/$(CONFIG)/bm_cq
bm_error: $(BINDIR)/$(CONFIG)/bm_error bm_error: $(BINDIR)/$(CONFIG)/bm_error
bm_fullstack: $(BINDIR)/$(CONFIG)/bm_fullstack bm_fullstack_streaming_ping_pong: $(BINDIR)/$(CONFIG)/bm_fullstack_streaming_ping_pong
bm_fullstack_streaming_pump: $(BINDIR)/$(CONFIG)/bm_fullstack_streaming_pump
bm_fullstack_trickle: $(BINDIR)/$(CONFIG)/bm_fullstack_trickle
bm_fullstack_unary_ping_pong: $(BINDIR)/$(CONFIG)/bm_fullstack_unary_ping_pong
bm_metadata: $(BINDIR)/$(CONFIG)/bm_metadata bm_metadata: $(BINDIR)/$(CONFIG)/bm_metadata
bm_pollset: $(BINDIR)/$(CONFIG)/bm_pollset
channel_arguments_test: $(BINDIR)/$(CONFIG)/channel_arguments_test channel_arguments_test: $(BINDIR)/$(CONFIG)/channel_arguments_test
channel_filter_test: $(BINDIR)/$(CONFIG)/channel_filter_test channel_filter_test: $(BINDIR)/$(CONFIG)/channel_filter_test
cli_call_test: $(BINDIR)/$(CONFIG)/cli_call_test cli_call_test: $(BINDIR)/$(CONFIG)/cli_call_test
@ -1102,6 +1109,7 @@ round_robin_end2end_test: $(BINDIR)/$(CONFIG)/round_robin_end2end_test
secure_auth_context_test: $(BINDIR)/$(CONFIG)/secure_auth_context_test secure_auth_context_test: $(BINDIR)/$(CONFIG)/secure_auth_context_test
secure_sync_unary_ping_pong_test: $(BINDIR)/$(CONFIG)/secure_sync_unary_ping_pong_test secure_sync_unary_ping_pong_test: $(BINDIR)/$(CONFIG)/secure_sync_unary_ping_pong_test
server_builder_plugin_test: $(BINDIR)/$(CONFIG)/server_builder_plugin_test server_builder_plugin_test: $(BINDIR)/$(CONFIG)/server_builder_plugin_test
server_builder_test: $(BINDIR)/$(CONFIG)/server_builder_test
server_context_test_spouse_test: $(BINDIR)/$(CONFIG)/server_context_test_spouse_test server_context_test_spouse_test: $(BINDIR)/$(CONFIG)/server_context_test_spouse_test
server_crash_test: $(BINDIR)/$(CONFIG)/server_crash_test server_crash_test: $(BINDIR)/$(CONFIG)/server_crash_test
server_crash_test_client: $(BINDIR)/$(CONFIG)/server_crash_test_client server_crash_test_client: $(BINDIR)/$(CONFIG)/server_crash_test_client
@ -1280,6 +1288,7 @@ buildtests_c: privatelibs_c \
$(BINDIR)/$(CONFIG)/algorithm_test \ $(BINDIR)/$(CONFIG)/algorithm_test \
$(BINDIR)/$(CONFIG)/alloc_test \ $(BINDIR)/$(CONFIG)/alloc_test \
$(BINDIR)/$(CONFIG)/alpn_test \ $(BINDIR)/$(CONFIG)/alpn_test \
$(BINDIR)/$(CONFIG)/arena_test \
$(BINDIR)/$(CONFIG)/bad_server_response_test \ $(BINDIR)/$(CONFIG)/bad_server_response_test \
$(BINDIR)/$(CONFIG)/bdp_estimator_test \ $(BINDIR)/$(CONFIG)/bdp_estimator_test \
$(BINDIR)/$(CONFIG)/bin_decoder_test \ $(BINDIR)/$(CONFIG)/bin_decoder_test \
@ -1299,6 +1308,7 @@ buildtests_c: privatelibs_c \
$(BINDIR)/$(CONFIG)/dns_resolver_test \ $(BINDIR)/$(CONFIG)/dns_resolver_test \
$(BINDIR)/$(CONFIG)/dualstack_socket_test \ $(BINDIR)/$(CONFIG)/dualstack_socket_test \
$(BINDIR)/$(CONFIG)/endpoint_pair_test \ $(BINDIR)/$(CONFIG)/endpoint_pair_test \
$(BINDIR)/$(CONFIG)/error_test \
$(BINDIR)/$(CONFIG)/ev_epoll_linux_test \ $(BINDIR)/$(CONFIG)/ev_epoll_linux_test \
$(BINDIR)/$(CONFIG)/fd_conservation_posix_test \ $(BINDIR)/$(CONFIG)/fd_conservation_posix_test \
$(BINDIR)/$(CONFIG)/fd_posix_test \ $(BINDIR)/$(CONFIG)/fd_posix_test \
@ -1462,13 +1472,18 @@ buildtests_cxx: privatelibs_cxx \
$(BINDIR)/$(CONFIG)/alarm_cpp_test \ $(BINDIR)/$(CONFIG)/alarm_cpp_test \
$(BINDIR)/$(CONFIG)/async_end2end_test \ $(BINDIR)/$(CONFIG)/async_end2end_test \
$(BINDIR)/$(CONFIG)/auth_property_iterator_test \ $(BINDIR)/$(CONFIG)/auth_property_iterator_test \
$(BINDIR)/$(CONFIG)/bm_arena \
$(BINDIR)/$(CONFIG)/bm_call_create \ $(BINDIR)/$(CONFIG)/bm_call_create \
$(BINDIR)/$(CONFIG)/bm_chttp2_hpack \ $(BINDIR)/$(CONFIG)/bm_chttp2_hpack \
$(BINDIR)/$(CONFIG)/bm_closure \ $(BINDIR)/$(CONFIG)/bm_closure \
$(BINDIR)/$(CONFIG)/bm_cq \ $(BINDIR)/$(CONFIG)/bm_cq \
$(BINDIR)/$(CONFIG)/bm_error \ $(BINDIR)/$(CONFIG)/bm_error \
$(BINDIR)/$(CONFIG)/bm_fullstack \ $(BINDIR)/$(CONFIG)/bm_fullstack_streaming_ping_pong \
$(BINDIR)/$(CONFIG)/bm_fullstack_streaming_pump \
$(BINDIR)/$(CONFIG)/bm_fullstack_trickle \
$(BINDIR)/$(CONFIG)/bm_fullstack_unary_ping_pong \
$(BINDIR)/$(CONFIG)/bm_metadata \ $(BINDIR)/$(CONFIG)/bm_metadata \
$(BINDIR)/$(CONFIG)/bm_pollset \
$(BINDIR)/$(CONFIG)/channel_arguments_test \ $(BINDIR)/$(CONFIG)/channel_arguments_test \
$(BINDIR)/$(CONFIG)/channel_filter_test \ $(BINDIR)/$(CONFIG)/channel_filter_test \
$(BINDIR)/$(CONFIG)/cli_call_test \ $(BINDIR)/$(CONFIG)/cli_call_test \
@ -1511,6 +1526,7 @@ buildtests_cxx: privatelibs_cxx \
$(BINDIR)/$(CONFIG)/secure_auth_context_test \ $(BINDIR)/$(CONFIG)/secure_auth_context_test \
$(BINDIR)/$(CONFIG)/secure_sync_unary_ping_pong_test \ $(BINDIR)/$(CONFIG)/secure_sync_unary_ping_pong_test \
$(BINDIR)/$(CONFIG)/server_builder_plugin_test \ $(BINDIR)/$(CONFIG)/server_builder_plugin_test \
$(BINDIR)/$(CONFIG)/server_builder_test \
$(BINDIR)/$(CONFIG)/server_context_test_spouse_test \ $(BINDIR)/$(CONFIG)/server_context_test_spouse_test \
$(BINDIR)/$(CONFIG)/server_crash_test \ $(BINDIR)/$(CONFIG)/server_crash_test \
$(BINDIR)/$(CONFIG)/server_crash_test_client \ $(BINDIR)/$(CONFIG)/server_crash_test_client \
@ -1573,13 +1589,18 @@ buildtests_cxx: privatelibs_cxx \
$(BINDIR)/$(CONFIG)/alarm_cpp_test \ $(BINDIR)/$(CONFIG)/alarm_cpp_test \
$(BINDIR)/$(CONFIG)/async_end2end_test \ $(BINDIR)/$(CONFIG)/async_end2end_test \
$(BINDIR)/$(CONFIG)/auth_property_iterator_test \ $(BINDIR)/$(CONFIG)/auth_property_iterator_test \
$(BINDIR)/$(CONFIG)/bm_arena \
$(BINDIR)/$(CONFIG)/bm_call_create \ $(BINDIR)/$(CONFIG)/bm_call_create \
$(BINDIR)/$(CONFIG)/bm_chttp2_hpack \ $(BINDIR)/$(CONFIG)/bm_chttp2_hpack \
$(BINDIR)/$(CONFIG)/bm_closure \ $(BINDIR)/$(CONFIG)/bm_closure \
$(BINDIR)/$(CONFIG)/bm_cq \ $(BINDIR)/$(CONFIG)/bm_cq \
$(BINDIR)/$(CONFIG)/bm_error \ $(BINDIR)/$(CONFIG)/bm_error \
$(BINDIR)/$(CONFIG)/bm_fullstack \ $(BINDIR)/$(CONFIG)/bm_fullstack_streaming_ping_pong \
$(BINDIR)/$(CONFIG)/bm_fullstack_streaming_pump \
$(BINDIR)/$(CONFIG)/bm_fullstack_trickle \
$(BINDIR)/$(CONFIG)/bm_fullstack_unary_ping_pong \
$(BINDIR)/$(CONFIG)/bm_metadata \ $(BINDIR)/$(CONFIG)/bm_metadata \
$(BINDIR)/$(CONFIG)/bm_pollset \
$(BINDIR)/$(CONFIG)/channel_arguments_test \ $(BINDIR)/$(CONFIG)/channel_arguments_test \
$(BINDIR)/$(CONFIG)/channel_filter_test \ $(BINDIR)/$(CONFIG)/channel_filter_test \
$(BINDIR)/$(CONFIG)/cli_call_test \ $(BINDIR)/$(CONFIG)/cli_call_test \
@ -1622,6 +1643,7 @@ buildtests_cxx: privatelibs_cxx \
$(BINDIR)/$(CONFIG)/secure_auth_context_test \ $(BINDIR)/$(CONFIG)/secure_auth_context_test \
$(BINDIR)/$(CONFIG)/secure_sync_unary_ping_pong_test \ $(BINDIR)/$(CONFIG)/secure_sync_unary_ping_pong_test \
$(BINDIR)/$(CONFIG)/server_builder_plugin_test \ $(BINDIR)/$(CONFIG)/server_builder_plugin_test \
$(BINDIR)/$(CONFIG)/server_builder_test \
$(BINDIR)/$(CONFIG)/server_context_test_spouse_test \ $(BINDIR)/$(CONFIG)/server_context_test_spouse_test \
$(BINDIR)/$(CONFIG)/server_crash_test \ $(BINDIR)/$(CONFIG)/server_crash_test \
$(BINDIR)/$(CONFIG)/server_crash_test_client \ $(BINDIR)/$(CONFIG)/server_crash_test_client \
@ -1649,6 +1671,8 @@ test_c: buildtests_c
$(Q) $(BINDIR)/$(CONFIG)/alloc_test || ( echo test alloc_test failed ; exit 1 ) $(Q) $(BINDIR)/$(CONFIG)/alloc_test || ( echo test alloc_test failed ; exit 1 )
$(E) "[RUN] Testing alpn_test" $(E) "[RUN] Testing alpn_test"
$(Q) $(BINDIR)/$(CONFIG)/alpn_test || ( echo test alpn_test failed ; exit 1 ) $(Q) $(BINDIR)/$(CONFIG)/alpn_test || ( echo test alpn_test failed ; exit 1 )
$(E) "[RUN] Testing arena_test"
$(Q) $(BINDIR)/$(CONFIG)/arena_test || ( echo test arena_test failed ; exit 1 )
$(E) "[RUN] Testing bad_server_response_test" $(E) "[RUN] Testing bad_server_response_test"
$(Q) $(BINDIR)/$(CONFIG)/bad_server_response_test || ( echo test bad_server_response_test failed ; exit 1 ) $(Q) $(BINDIR)/$(CONFIG)/bad_server_response_test || ( echo test bad_server_response_test failed ; exit 1 )
$(E) "[RUN] Testing bdp_estimator_test" $(E) "[RUN] Testing bdp_estimator_test"
@ -1687,6 +1711,8 @@ test_c: buildtests_c
$(Q) $(BINDIR)/$(CONFIG)/dualstack_socket_test || ( echo test dualstack_socket_test failed ; exit 1 ) $(Q) $(BINDIR)/$(CONFIG)/dualstack_socket_test || ( echo test dualstack_socket_test failed ; exit 1 )
$(E) "[RUN] Testing endpoint_pair_test" $(E) "[RUN] Testing endpoint_pair_test"
$(Q) $(BINDIR)/$(CONFIG)/endpoint_pair_test || ( echo test endpoint_pair_test failed ; exit 1 ) $(Q) $(BINDIR)/$(CONFIG)/endpoint_pair_test || ( echo test endpoint_pair_test failed ; exit 1 )
$(E) "[RUN] Testing error_test"
$(Q) $(BINDIR)/$(CONFIG)/error_test || ( echo test error_test failed ; exit 1 )
$(E) "[RUN] Testing ev_epoll_linux_test" $(E) "[RUN] Testing ev_epoll_linux_test"
$(Q) $(BINDIR)/$(CONFIG)/ev_epoll_linux_test || ( echo test ev_epoll_linux_test failed ; exit 1 ) $(Q) $(BINDIR)/$(CONFIG)/ev_epoll_linux_test || ( echo test ev_epoll_linux_test failed ; exit 1 )
$(E) "[RUN] Testing fd_conservation_posix_test" $(E) "[RUN] Testing fd_conservation_posix_test"
@ -1907,6 +1933,8 @@ test_cxx: buildtests_cxx
$(Q) $(BINDIR)/$(CONFIG)/async_end2end_test || ( echo test async_end2end_test failed ; exit 1 ) $(Q) $(BINDIR)/$(CONFIG)/async_end2end_test || ( echo test async_end2end_test failed ; exit 1 )
$(E) "[RUN] Testing auth_property_iterator_test" $(E) "[RUN] Testing auth_property_iterator_test"
$(Q) $(BINDIR)/$(CONFIG)/auth_property_iterator_test || ( echo test auth_property_iterator_test failed ; exit 1 ) $(Q) $(BINDIR)/$(CONFIG)/auth_property_iterator_test || ( echo test auth_property_iterator_test failed ; exit 1 )
$(E) "[RUN] Testing bm_arena"
$(Q) $(BINDIR)/$(CONFIG)/bm_arena || ( echo test bm_arena failed ; exit 1 )
$(E) "[RUN] Testing bm_call_create" $(E) "[RUN] Testing bm_call_create"
$(Q) $(BINDIR)/$(CONFIG)/bm_call_create || ( echo test bm_call_create failed ; exit 1 ) $(Q) $(BINDIR)/$(CONFIG)/bm_call_create || ( echo test bm_call_create failed ; exit 1 )
$(E) "[RUN] Testing bm_chttp2_hpack" $(E) "[RUN] Testing bm_chttp2_hpack"
@ -1917,10 +1945,18 @@ test_cxx: buildtests_cxx
$(Q) $(BINDIR)/$(CONFIG)/bm_cq || ( echo test bm_cq failed ; exit 1 ) $(Q) $(BINDIR)/$(CONFIG)/bm_cq || ( echo test bm_cq failed ; exit 1 )
$(E) "[RUN] Testing bm_error" $(E) "[RUN] Testing bm_error"
$(Q) $(BINDIR)/$(CONFIG)/bm_error || ( echo test bm_error failed ; exit 1 ) $(Q) $(BINDIR)/$(CONFIG)/bm_error || ( echo test bm_error failed ; exit 1 )
$(E) "[RUN] Testing bm_fullstack" $(E) "[RUN] Testing bm_fullstack_streaming_ping_pong"
$(Q) $(BINDIR)/$(CONFIG)/bm_fullstack || ( echo test bm_fullstack failed ; exit 1 ) $(Q) $(BINDIR)/$(CONFIG)/bm_fullstack_streaming_ping_pong || ( echo test bm_fullstack_streaming_ping_pong failed ; exit 1 )
$(E) "[RUN] Testing bm_fullstack_streaming_pump"
$(Q) $(BINDIR)/$(CONFIG)/bm_fullstack_streaming_pump || ( echo test bm_fullstack_streaming_pump failed ; exit 1 )
$(E) "[RUN] Testing bm_fullstack_trickle"
$(Q) $(BINDIR)/$(CONFIG)/bm_fullstack_trickle || ( echo test bm_fullstack_trickle failed ; exit 1 )
$(E) "[RUN] Testing bm_fullstack_unary_ping_pong"
$(Q) $(BINDIR)/$(CONFIG)/bm_fullstack_unary_ping_pong || ( echo test bm_fullstack_unary_ping_pong failed ; exit 1 )
$(E) "[RUN] Testing bm_metadata" $(E) "[RUN] Testing bm_metadata"
$(Q) $(BINDIR)/$(CONFIG)/bm_metadata || ( echo test bm_metadata failed ; exit 1 ) $(Q) $(BINDIR)/$(CONFIG)/bm_metadata || ( echo test bm_metadata failed ; exit 1 )
$(E) "[RUN] Testing bm_pollset"
$(Q) $(BINDIR)/$(CONFIG)/bm_pollset || ( echo test bm_pollset failed ; exit 1 )
$(E) "[RUN] Testing channel_arguments_test" $(E) "[RUN] Testing channel_arguments_test"
$(Q) $(BINDIR)/$(CONFIG)/channel_arguments_test || ( echo test channel_arguments_test failed ; exit 1 ) $(Q) $(BINDIR)/$(CONFIG)/channel_arguments_test || ( echo test channel_arguments_test failed ; exit 1 )
$(E) "[RUN] Testing channel_filter_test" $(E) "[RUN] Testing channel_filter_test"
@ -1979,6 +2015,8 @@ test_cxx: buildtests_cxx
$(Q) $(BINDIR)/$(CONFIG)/secure_sync_unary_ping_pong_test || ( echo test secure_sync_unary_ping_pong_test failed ; exit 1 ) $(Q) $(BINDIR)/$(CONFIG)/secure_sync_unary_ping_pong_test || ( echo test secure_sync_unary_ping_pong_test failed ; exit 1 )
$(E) "[RUN] Testing server_builder_plugin_test" $(E) "[RUN] Testing server_builder_plugin_test"
$(Q) $(BINDIR)/$(CONFIG)/server_builder_plugin_test || ( echo test server_builder_plugin_test failed ; exit 1 ) $(Q) $(BINDIR)/$(CONFIG)/server_builder_plugin_test || ( echo test server_builder_plugin_test failed ; exit 1 )
$(E) "[RUN] Testing server_builder_test"
$(Q) $(BINDIR)/$(CONFIG)/server_builder_test || ( echo test server_builder_test failed ; exit 1 )
$(E) "[RUN] Testing server_context_test_spouse_test" $(E) "[RUN] Testing server_context_test_spouse_test"
$(Q) $(BINDIR)/$(CONFIG)/server_context_test_spouse_test || ( echo test server_context_test_spouse_test failed ; exit 1 ) $(Q) $(BINDIR)/$(CONFIG)/server_context_test_spouse_test || ( echo test server_context_test_spouse_test failed ; exit 1 )
$(E) "[RUN] Testing server_crash_test" $(E) "[RUN] Testing server_crash_test"
@ -2570,6 +2608,7 @@ LIBGPR_SRC = \
src/core/lib/profiling/basic_timers.c \ src/core/lib/profiling/basic_timers.c \
src/core/lib/profiling/stap_timers.c \ src/core/lib/profiling/stap_timers.c \
src/core/lib/support/alloc.c \ src/core/lib/support/alloc.c \
src/core/lib/support/arena.c \
src/core/lib/support/avl.c \ src/core/lib/support/avl.c \
src/core/lib/support/backoff.c \ src/core/lib/support/backoff.c \
src/core/lib/support/cmdline.c \ src/core/lib/support/cmdline.c \
@ -2775,6 +2814,9 @@ LIBGRPC_SRC = \
src/core/lib/iomgr/tcp_client_windows.c \ src/core/lib/iomgr/tcp_client_windows.c \
src/core/lib/iomgr/tcp_posix.c \ src/core/lib/iomgr/tcp_posix.c \
src/core/lib/iomgr/tcp_server_posix.c \ src/core/lib/iomgr/tcp_server_posix.c \
src/core/lib/iomgr/tcp_server_utils_posix_common.c \
src/core/lib/iomgr/tcp_server_utils_posix_ifaddrs.c \
src/core/lib/iomgr/tcp_server_utils_posix_noifaddrs.c \
src/core/lib/iomgr/tcp_server_uv.c \ src/core/lib/iomgr/tcp_server_uv.c \
src/core/lib/iomgr/tcp_server_windows.c \ src/core/lib/iomgr/tcp_server_windows.c \
src/core/lib/iomgr/tcp_uv.c \ src/core/lib/iomgr/tcp_uv.c \
@ -3087,6 +3129,9 @@ LIBGRPC_CRONET_SRC = \
src/core/lib/iomgr/tcp_client_windows.c \ src/core/lib/iomgr/tcp_client_windows.c \
src/core/lib/iomgr/tcp_posix.c \ src/core/lib/iomgr/tcp_posix.c \
src/core/lib/iomgr/tcp_server_posix.c \ src/core/lib/iomgr/tcp_server_posix.c \
src/core/lib/iomgr/tcp_server_utils_posix_common.c \
src/core/lib/iomgr/tcp_server_utils_posix_ifaddrs.c \
src/core/lib/iomgr/tcp_server_utils_posix_noifaddrs.c \
src/core/lib/iomgr/tcp_server_uv.c \ src/core/lib/iomgr/tcp_server_uv.c \
src/core/lib/iomgr/tcp_server_windows.c \ src/core/lib/iomgr/tcp_server_windows.c \
src/core/lib/iomgr/tcp_uv.c \ src/core/lib/iomgr/tcp_uv.c \
@ -3318,7 +3363,7 @@ LIBGRPC_TEST_UTIL_SRC = \
test/core/security/oauth2_utils.c \ test/core/security/oauth2_utils.c \
test/core/end2end/cq_verifier.c \ test/core/end2end/cq_verifier.c \
test/core/end2end/fake_resolver.c \ test/core/end2end/fake_resolver.c \
test/core/end2end/fixtures/http_proxy.c \ test/core/end2end/fixtures/http_proxy_fixture.c \
test/core/end2end/fixtures/proxy.c \ test/core/end2end/fixtures/proxy.c \
test/core/iomgr/endpoint_tests.c \ test/core/iomgr/endpoint_tests.c \
test/core/util/debugger_macros.c \ test/core/util/debugger_macros.c \
@ -3390,6 +3435,9 @@ LIBGRPC_TEST_UTIL_SRC = \
src/core/lib/iomgr/tcp_client_windows.c \ src/core/lib/iomgr/tcp_client_windows.c \
src/core/lib/iomgr/tcp_posix.c \ src/core/lib/iomgr/tcp_posix.c \
src/core/lib/iomgr/tcp_server_posix.c \ src/core/lib/iomgr/tcp_server_posix.c \
src/core/lib/iomgr/tcp_server_utils_posix_common.c \
src/core/lib/iomgr/tcp_server_utils_posix_ifaddrs.c \
src/core/lib/iomgr/tcp_server_utils_posix_noifaddrs.c \
src/core/lib/iomgr/tcp_server_uv.c \ src/core/lib/iomgr/tcp_server_uv.c \
src/core/lib/iomgr/tcp_server_windows.c \ src/core/lib/iomgr/tcp_server_windows.c \
src/core/lib/iomgr/tcp_uv.c \ src/core/lib/iomgr/tcp_uv.c \
@ -3518,7 +3566,7 @@ endif
LIBGRPC_TEST_UTIL_UNSECURE_SRC = \ LIBGRPC_TEST_UTIL_UNSECURE_SRC = \
test/core/end2end/cq_verifier.c \ test/core/end2end/cq_verifier.c \
test/core/end2end/fake_resolver.c \ test/core/end2end/fake_resolver.c \
test/core/end2end/fixtures/http_proxy.c \ test/core/end2end/fixtures/http_proxy_fixture.c \
test/core/end2end/fixtures/proxy.c \ test/core/end2end/fixtures/proxy.c \
test/core/iomgr/endpoint_tests.c \ test/core/iomgr/endpoint_tests.c \
test/core/util/debugger_macros.c \ test/core/util/debugger_macros.c \
@ -3616,6 +3664,9 @@ LIBGRPC_UNSECURE_SRC = \
src/core/lib/iomgr/tcp_client_windows.c \ src/core/lib/iomgr/tcp_client_windows.c \
src/core/lib/iomgr/tcp_posix.c \ src/core/lib/iomgr/tcp_posix.c \
src/core/lib/iomgr/tcp_server_posix.c \ src/core/lib/iomgr/tcp_server_posix.c \
src/core/lib/iomgr/tcp_server_utils_posix_common.c \
src/core/lib/iomgr/tcp_server_utils_posix_ifaddrs.c \
src/core/lib/iomgr/tcp_server_utils_posix_noifaddrs.c \
src/core/lib/iomgr/tcp_server_uv.c \ src/core/lib/iomgr/tcp_server_uv.c \
src/core/lib/iomgr/tcp_server_windows.c \ src/core/lib/iomgr/tcp_server_windows.c \
src/core/lib/iomgr/tcp_uv.c \ src/core/lib/iomgr/tcp_uv.c \
@ -3923,6 +3974,7 @@ LIBGRPC++_SRC = \
src/cpp/common/rpc_method.cc \ src/cpp/common/rpc_method.cc \
src/cpp/common/version_cc.cc \ src/cpp/common/version_cc.cc \
src/cpp/server/async_generic_service.cc \ src/cpp/server/async_generic_service.cc \
src/cpp/server/channel_argument_option.cc \
src/cpp/server/create_default_thread_pool.cc \ src/cpp/server/create_default_thread_pool.cc \
src/cpp/server/dynamic_thread_pool.cc \ src/cpp/server/dynamic_thread_pool.cc \
src/cpp/server/health/default_health_check_service.cc \ src/cpp/server/health/default_health_check_service.cc \
@ -3955,6 +4007,7 @@ PUBLIC_HEADERS_CXX += \
include/grpc++/grpc++.h \ include/grpc++/grpc++.h \
include/grpc++/health_check_service_interface.h \ include/grpc++/health_check_service_interface.h \
include/grpc++/impl/call.h \ include/grpc++/impl/call.h \
include/grpc++/impl/channel_argument_option.h \
include/grpc++/impl/client_unary_call.h \ include/grpc++/impl/client_unary_call.h \
include/grpc++/impl/codegen/core_codegen.h \ include/grpc++/impl/codegen/core_codegen.h \
include/grpc++/impl/grpc_library.h \ include/grpc++/impl/grpc_library.h \
@ -4122,6 +4175,7 @@ LIBGRPC++_CRONET_SRC = \
src/cpp/common/rpc_method.cc \ src/cpp/common/rpc_method.cc \
src/cpp/common/version_cc.cc \ src/cpp/common/version_cc.cc \
src/cpp/server/async_generic_service.cc \ src/cpp/server/async_generic_service.cc \
src/cpp/server/channel_argument_option.cc \
src/cpp/server/create_default_thread_pool.cc \ src/cpp/server/create_default_thread_pool.cc \
src/cpp/server/dynamic_thread_pool.cc \ src/cpp/server/dynamic_thread_pool.cc \
src/cpp/server/health/default_health_check_service.cc \ src/cpp/server/health/default_health_check_service.cc \
@ -4222,6 +4276,9 @@ LIBGRPC++_CRONET_SRC = \
src/core/lib/iomgr/tcp_client_windows.c \ src/core/lib/iomgr/tcp_client_windows.c \
src/core/lib/iomgr/tcp_posix.c \ src/core/lib/iomgr/tcp_posix.c \
src/core/lib/iomgr/tcp_server_posix.c \ src/core/lib/iomgr/tcp_server_posix.c \
src/core/lib/iomgr/tcp_server_utils_posix_common.c \
src/core/lib/iomgr/tcp_server_utils_posix_ifaddrs.c \
src/core/lib/iomgr/tcp_server_utils_posix_noifaddrs.c \
src/core/lib/iomgr/tcp_server_uv.c \ src/core/lib/iomgr/tcp_server_uv.c \
src/core/lib/iomgr/tcp_server_windows.c \ src/core/lib/iomgr/tcp_server_windows.c \
src/core/lib/iomgr/tcp_uv.c \ src/core/lib/iomgr/tcp_uv.c \
@ -4337,6 +4394,7 @@ PUBLIC_HEADERS_CXX += \
include/grpc++/grpc++.h \ include/grpc++/grpc++.h \
include/grpc++/health_check_service_interface.h \ include/grpc++/health_check_service_interface.h \
include/grpc++/impl/call.h \ include/grpc++/impl/call.h \
include/grpc++/impl/channel_argument_option.h \
include/grpc++/impl/client_unary_call.h \ include/grpc++/impl/client_unary_call.h \
include/grpc++/impl/codegen/core_codegen.h \ include/grpc++/impl/codegen/core_codegen.h \
include/grpc++/impl/grpc_library.h \ include/grpc++/impl/grpc_library.h \
@ -4805,6 +4863,7 @@ LIBGRPC++_UNSECURE_SRC = \
src/cpp/common/rpc_method.cc \ src/cpp/common/rpc_method.cc \
src/cpp/common/version_cc.cc \ src/cpp/common/version_cc.cc \
src/cpp/server/async_generic_service.cc \ src/cpp/server/async_generic_service.cc \
src/cpp/server/channel_argument_option.cc \
src/cpp/server/create_default_thread_pool.cc \ src/cpp/server/create_default_thread_pool.cc \
src/cpp/server/dynamic_thread_pool.cc \ src/cpp/server/dynamic_thread_pool.cc \
src/cpp/server/health/default_health_check_service.cc \ src/cpp/server/health/default_health_check_service.cc \
@ -4837,6 +4896,7 @@ PUBLIC_HEADERS_CXX += \
include/grpc++/grpc++.h \ include/grpc++/grpc++.h \
include/grpc++/health_check_service_interface.h \ include/grpc++/health_check_service_interface.h \
include/grpc++/impl/call.h \ include/grpc++/impl/call.h \
include/grpc++/impl/channel_argument_option.h \
include/grpc++/impl/client_unary_call.h \ include/grpc++/impl/client_unary_call.h \
include/grpc++/impl/codegen/core_codegen.h \ include/grpc++/impl/codegen/core_codegen.h \
include/grpc++/impl/grpc_library.h \ include/grpc++/impl/grpc_library.h \
@ -4968,6 +5028,55 @@ ifneq ($(NO_DEPS),true)
endif endif
LIBGRPC_BENCHMARK_SRC = \
test/cpp/microbenchmarks/helpers.cc \
PUBLIC_HEADERS_CXX += \
LIBGRPC_BENCHMARK_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(LIBGRPC_BENCHMARK_SRC))))
ifeq ($(NO_SECURE),true)
# You can't build secure libraries if you don't have OpenSSL.
$(LIBDIR)/$(CONFIG)/libgrpc_benchmark.a: openssl_dep_error
else
ifeq ($(NO_PROTOBUF),true)
# You can't build a C++ library if you don't have protobuf - a bit overreached, but still okay.
$(LIBDIR)/$(CONFIG)/libgrpc_benchmark.a: protobuf_dep_error
else
$(LIBDIR)/$(CONFIG)/libgrpc_benchmark.a: $(ZLIB_DEP) $(OPENSSL_DEP) $(PROTOBUF_DEP) $(LIBGRPC_BENCHMARK_OBJS)
$(E) "[AR] Creating $@"
$(Q) mkdir -p `dirname $@`
$(Q) rm -f $(LIBDIR)/$(CONFIG)/libgrpc_benchmark.a
$(Q) $(AR) $(AROPTS) $(LIBDIR)/$(CONFIG)/libgrpc_benchmark.a $(LIBGRPC_BENCHMARK_OBJS)
ifeq ($(SYSTEM),Darwin)
$(Q) ranlib -no_warning_for_no_symbols $(LIBDIR)/$(CONFIG)/libgrpc_benchmark.a
endif
endif
endif
ifneq ($(NO_SECURE),true)
ifneq ($(NO_DEPS),true)
-include $(LIBGRPC_BENCHMARK_OBJS:.o=.dep)
endif
endif
LIBGRPC_CLI_LIBS_SRC = \ LIBGRPC_CLI_LIBS_SRC = \
test/cpp/util/cli_call.cc \ test/cpp/util/cli_call.cc \
test/cpp/util/cli_credentials.cc \ test/cpp/util/cli_credentials.cc \
@ -8015,6 +8124,38 @@ endif
endif endif
ARENA_TEST_SRC = \
test/core/support/arena_test.c \
ARENA_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(ARENA_TEST_SRC))))
ifeq ($(NO_SECURE),true)
# You can't build secure targets if you don't have OpenSSL.
$(BINDIR)/$(CONFIG)/arena_test: openssl_dep_error
else
$(BINDIR)/$(CONFIG)/arena_test: $(ARENA_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
$(E) "[LD] Linking $@"
$(Q) mkdir -p `dirname $@`
$(Q) $(LD) $(LDFLAGS) $(ARENA_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/arena_test
endif
$(OBJDIR)/$(CONFIG)/test/core/support/arena_test.o: $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
deps_arena_test: $(ARENA_TEST_OBJS:.o=.dep)
ifneq ($(NO_SECURE),true)
ifneq ($(NO_DEPS),true)
-include $(ARENA_TEST_OBJS:.o=.dep)
endif
endif
BAD_SERVER_RESPONSE_TEST_SRC = \ BAD_SERVER_RESPONSE_TEST_SRC = \
test/core/end2end/bad_server_response_test.c \ test/core/end2end/bad_server_response_test.c \
@ -8655,6 +8796,38 @@ endif
endif endif
ERROR_TEST_SRC = \
test/core/iomgr/error_test.c \
ERROR_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(ERROR_TEST_SRC))))
ifeq ($(NO_SECURE),true)
# You can't build secure targets if you don't have OpenSSL.
$(BINDIR)/$(CONFIG)/error_test: openssl_dep_error
else
$(BINDIR)/$(CONFIG)/error_test: $(ERROR_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) $(ERROR_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)/error_test
endif
$(OBJDIR)/$(CONFIG)/test/core/iomgr/error_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
deps_error_test: $(ERROR_TEST_OBJS:.o=.dep)
ifneq ($(NO_SECURE),true)
ifneq ($(NO_DEPS),true)
-include $(ERROR_TEST_OBJS:.o=.dep)
endif
endif
EV_EPOLL_LINUX_TEST_SRC = \ EV_EPOLL_LINUX_TEST_SRC = \
test/core/iomgr/ev_epoll_linux_test.c \ test/core/iomgr/ev_epoll_linux_test.c \
@ -12528,6 +12701,49 @@ endif
endif endif
BM_ARENA_SRC = \
test/cpp/microbenchmarks/bm_arena.cc \
BM_ARENA_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(BM_ARENA_SRC))))
ifeq ($(NO_SECURE),true)
# You can't build secure targets if you don't have OpenSSL.
$(BINDIR)/$(CONFIG)/bm_arena: 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)/bm_arena: protobuf_dep_error
else
$(BINDIR)/$(CONFIG)/bm_arena: $(PROTOBUF_DEP) $(BM_ARENA_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_benchmark.a $(LIBDIR)/$(CONFIG)/libbenchmark.a $(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) $(BM_ARENA_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_benchmark.a $(LIBDIR)/$(CONFIG)/libbenchmark.a $(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)/bm_arena
endif
endif
$(OBJDIR)/$(CONFIG)/test/cpp/microbenchmarks/bm_arena.o: $(LIBDIR)/$(CONFIG)/libgrpc_benchmark.a $(LIBDIR)/$(CONFIG)/libbenchmark.a $(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_bm_arena: $(BM_ARENA_OBJS:.o=.dep)
ifneq ($(NO_SECURE),true)
ifneq ($(NO_DEPS),true)
-include $(BM_ARENA_OBJS:.o=.dep)
endif
endif
BM_CALL_CREATE_SRC = \ BM_CALL_CREATE_SRC = \
test/cpp/microbenchmarks/bm_call_create.cc \ test/cpp/microbenchmarks/bm_call_create.cc \
@ -12551,16 +12767,16 @@ $(BINDIR)/$(CONFIG)/bm_call_create: protobuf_dep_error
else else
$(BINDIR)/$(CONFIG)/bm_call_create: $(PROTOBUF_DEP) $(BM_CALL_CREATE_OBJS) $(LIBDIR)/$(CONFIG)/libbenchmark.a $(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 $(BINDIR)/$(CONFIG)/bm_call_create: $(PROTOBUF_DEP) $(BM_CALL_CREATE_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_benchmark.a $(LIBDIR)/$(CONFIG)/libbenchmark.a $(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 $@" $(E) "[LD] Linking $@"
$(Q) mkdir -p `dirname $@` $(Q) mkdir -p `dirname $@`
$(Q) $(LDXX) $(LDFLAGS) $(BM_CALL_CREATE_OBJS) $(LIBDIR)/$(CONFIG)/libbenchmark.a $(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)/bm_call_create $(Q) $(LDXX) $(LDFLAGS) $(BM_CALL_CREATE_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_benchmark.a $(LIBDIR)/$(CONFIG)/libbenchmark.a $(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)/bm_call_create
endif endif
endif endif
$(OBJDIR)/$(CONFIG)/test/cpp/microbenchmarks/bm_call_create.o: $(LIBDIR)/$(CONFIG)/libbenchmark.a $(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 $(OBJDIR)/$(CONFIG)/test/cpp/microbenchmarks/bm_call_create.o: $(LIBDIR)/$(CONFIG)/libgrpc_benchmark.a $(LIBDIR)/$(CONFIG)/libbenchmark.a $(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_bm_call_create: $(BM_CALL_CREATE_OBJS:.o=.dep) deps_bm_call_create: $(BM_CALL_CREATE_OBJS:.o=.dep)
@ -12594,16 +12810,16 @@ $(BINDIR)/$(CONFIG)/bm_chttp2_hpack: protobuf_dep_error
else else
$(BINDIR)/$(CONFIG)/bm_chttp2_hpack: $(PROTOBUF_DEP) $(BM_CHTTP2_HPACK_OBJS) $(LIBDIR)/$(CONFIG)/libbenchmark.a $(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 $(BINDIR)/$(CONFIG)/bm_chttp2_hpack: $(PROTOBUF_DEP) $(BM_CHTTP2_HPACK_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_benchmark.a $(LIBDIR)/$(CONFIG)/libbenchmark.a $(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 $@" $(E) "[LD] Linking $@"
$(Q) mkdir -p `dirname $@` $(Q) mkdir -p `dirname $@`
$(Q) $(LDXX) $(LDFLAGS) $(BM_CHTTP2_HPACK_OBJS) $(LIBDIR)/$(CONFIG)/libbenchmark.a $(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)/bm_chttp2_hpack $(Q) $(LDXX) $(LDFLAGS) $(BM_CHTTP2_HPACK_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_benchmark.a $(LIBDIR)/$(CONFIG)/libbenchmark.a $(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)/bm_chttp2_hpack
endif endif
endif endif
$(OBJDIR)/$(CONFIG)/test/cpp/microbenchmarks/bm_chttp2_hpack.o: $(LIBDIR)/$(CONFIG)/libbenchmark.a $(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 $(OBJDIR)/$(CONFIG)/test/cpp/microbenchmarks/bm_chttp2_hpack.o: $(LIBDIR)/$(CONFIG)/libgrpc_benchmark.a $(LIBDIR)/$(CONFIG)/libbenchmark.a $(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_bm_chttp2_hpack: $(BM_CHTTP2_HPACK_OBJS:.o=.dep) deps_bm_chttp2_hpack: $(BM_CHTTP2_HPACK_OBJS:.o=.dep)
@ -12637,16 +12853,16 @@ $(BINDIR)/$(CONFIG)/bm_closure: protobuf_dep_error
else else
$(BINDIR)/$(CONFIG)/bm_closure: $(PROTOBUF_DEP) $(BM_CLOSURE_OBJS) $(LIBDIR)/$(CONFIG)/libbenchmark.a $(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 $(BINDIR)/$(CONFIG)/bm_closure: $(PROTOBUF_DEP) $(BM_CLOSURE_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_benchmark.a $(LIBDIR)/$(CONFIG)/libbenchmark.a $(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 $@" $(E) "[LD] Linking $@"
$(Q) mkdir -p `dirname $@` $(Q) mkdir -p `dirname $@`
$(Q) $(LDXX) $(LDFLAGS) $(BM_CLOSURE_OBJS) $(LIBDIR)/$(CONFIG)/libbenchmark.a $(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)/bm_closure $(Q) $(LDXX) $(LDFLAGS) $(BM_CLOSURE_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_benchmark.a $(LIBDIR)/$(CONFIG)/libbenchmark.a $(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)/bm_closure
endif endif
endif endif
$(OBJDIR)/$(CONFIG)/test/cpp/microbenchmarks/bm_closure.o: $(LIBDIR)/$(CONFIG)/libbenchmark.a $(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 $(OBJDIR)/$(CONFIG)/test/cpp/microbenchmarks/bm_closure.o: $(LIBDIR)/$(CONFIG)/libgrpc_benchmark.a $(LIBDIR)/$(CONFIG)/libbenchmark.a $(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_bm_closure: $(BM_CLOSURE_OBJS:.o=.dep) deps_bm_closure: $(BM_CLOSURE_OBJS:.o=.dep)
@ -12680,16 +12896,16 @@ $(BINDIR)/$(CONFIG)/bm_cq: protobuf_dep_error
else else
$(BINDIR)/$(CONFIG)/bm_cq: $(PROTOBUF_DEP) $(BM_CQ_OBJS) $(LIBDIR)/$(CONFIG)/libbenchmark.a $(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 $(BINDIR)/$(CONFIG)/bm_cq: $(PROTOBUF_DEP) $(BM_CQ_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_benchmark.a $(LIBDIR)/$(CONFIG)/libbenchmark.a $(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 $@" $(E) "[LD] Linking $@"
$(Q) mkdir -p `dirname $@` $(Q) mkdir -p `dirname $@`
$(Q) $(LDXX) $(LDFLAGS) $(BM_CQ_OBJS) $(LIBDIR)/$(CONFIG)/libbenchmark.a $(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)/bm_cq $(Q) $(LDXX) $(LDFLAGS) $(BM_CQ_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_benchmark.a $(LIBDIR)/$(CONFIG)/libbenchmark.a $(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)/bm_cq
endif endif
endif endif
$(OBJDIR)/$(CONFIG)/test/cpp/microbenchmarks/bm_cq.o: $(LIBDIR)/$(CONFIG)/libbenchmark.a $(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 $(OBJDIR)/$(CONFIG)/test/cpp/microbenchmarks/bm_cq.o: $(LIBDIR)/$(CONFIG)/libgrpc_benchmark.a $(LIBDIR)/$(CONFIG)/libbenchmark.a $(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_bm_cq: $(BM_CQ_OBJS:.o=.dep) deps_bm_cq: $(BM_CQ_OBJS:.o=.dep)
@ -12723,16 +12939,16 @@ $(BINDIR)/$(CONFIG)/bm_error: protobuf_dep_error
else else
$(BINDIR)/$(CONFIG)/bm_error: $(PROTOBUF_DEP) $(BM_ERROR_OBJS) $(LIBDIR)/$(CONFIG)/libbenchmark.a $(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 $(BINDIR)/$(CONFIG)/bm_error: $(PROTOBUF_DEP) $(BM_ERROR_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_benchmark.a $(LIBDIR)/$(CONFIG)/libbenchmark.a $(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 $@" $(E) "[LD] Linking $@"
$(Q) mkdir -p `dirname $@` $(Q) mkdir -p `dirname $@`
$(Q) $(LDXX) $(LDFLAGS) $(BM_ERROR_OBJS) $(LIBDIR)/$(CONFIG)/libbenchmark.a $(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)/bm_error $(Q) $(LDXX) $(LDFLAGS) $(BM_ERROR_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_benchmark.a $(LIBDIR)/$(CONFIG)/libbenchmark.a $(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)/bm_error
endif endif
endif endif
$(OBJDIR)/$(CONFIG)/test/cpp/microbenchmarks/bm_error.o: $(LIBDIR)/$(CONFIG)/libbenchmark.a $(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 $(OBJDIR)/$(CONFIG)/test/cpp/microbenchmarks/bm_error.o: $(LIBDIR)/$(CONFIG)/libgrpc_benchmark.a $(LIBDIR)/$(CONFIG)/libbenchmark.a $(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_bm_error: $(BM_ERROR_OBJS:.o=.dep) deps_bm_error: $(BM_ERROR_OBJS:.o=.dep)
@ -12743,15 +12959,15 @@ endif
endif endif
BM_FULLSTACK_SRC = \ BM_FULLSTACK_STREAMING_PING_PONG_SRC = \
test/cpp/microbenchmarks/bm_fullstack.cc \ test/cpp/microbenchmarks/bm_fullstack_streaming_ping_pong.cc \
BM_FULLSTACK_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(BM_FULLSTACK_SRC)))) BM_FULLSTACK_STREAMING_PING_PONG_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(BM_FULLSTACK_STREAMING_PING_PONG_SRC))))
ifeq ($(NO_SECURE),true) ifeq ($(NO_SECURE),true)
# You can't build secure targets if you don't have OpenSSL. # You can't build secure targets if you don't have OpenSSL.
$(BINDIR)/$(CONFIG)/bm_fullstack: openssl_dep_error $(BINDIR)/$(CONFIG)/bm_fullstack_streaming_ping_pong: openssl_dep_error
else else
@ -12762,26 +12978,155 @@ ifeq ($(NO_PROTOBUF),true)
# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.0.0+. # You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.0.0+.
$(BINDIR)/$(CONFIG)/bm_fullstack: protobuf_dep_error $(BINDIR)/$(CONFIG)/bm_fullstack_streaming_ping_pong: protobuf_dep_error
else else
$(BINDIR)/$(CONFIG)/bm_fullstack: $(PROTOBUF_DEP) $(BM_FULLSTACK_OBJS) $(LIBDIR)/$(CONFIG)/libbenchmark.a $(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 $(BINDIR)/$(CONFIG)/bm_fullstack_streaming_ping_pong: $(PROTOBUF_DEP) $(BM_FULLSTACK_STREAMING_PING_PONG_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_benchmark.a $(LIBDIR)/$(CONFIG)/libbenchmark.a $(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 $@" $(E) "[LD] Linking $@"
$(Q) mkdir -p `dirname $@` $(Q) mkdir -p `dirname $@`
$(Q) $(LDXX) $(LDFLAGS) $(BM_FULLSTACK_OBJS) $(LIBDIR)/$(CONFIG)/libbenchmark.a $(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)/bm_fullstack $(Q) $(LDXX) $(LDFLAGS) $(BM_FULLSTACK_STREAMING_PING_PONG_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_benchmark.a $(LIBDIR)/$(CONFIG)/libbenchmark.a $(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)/bm_fullstack_streaming_ping_pong
endif endif
endif endif
$(OBJDIR)/$(CONFIG)/test/cpp/microbenchmarks/bm_fullstack.o: $(LIBDIR)/$(CONFIG)/libbenchmark.a $(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 $(OBJDIR)/$(CONFIG)/test/cpp/microbenchmarks/bm_fullstack_streaming_ping_pong.o: $(LIBDIR)/$(CONFIG)/libgrpc_benchmark.a $(LIBDIR)/$(CONFIG)/libbenchmark.a $(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_bm_fullstack: $(BM_FULLSTACK_OBJS:.o=.dep) deps_bm_fullstack_streaming_ping_pong: $(BM_FULLSTACK_STREAMING_PING_PONG_OBJS:.o=.dep)
ifneq ($(NO_SECURE),true) ifneq ($(NO_SECURE),true)
ifneq ($(NO_DEPS),true) ifneq ($(NO_DEPS),true)
-include $(BM_FULLSTACK_OBJS:.o=.dep) -include $(BM_FULLSTACK_STREAMING_PING_PONG_OBJS:.o=.dep)
endif
endif
BM_FULLSTACK_STREAMING_PUMP_SRC = \
test/cpp/microbenchmarks/bm_fullstack_streaming_pump.cc \
BM_FULLSTACK_STREAMING_PUMP_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(BM_FULLSTACK_STREAMING_PUMP_SRC))))
ifeq ($(NO_SECURE),true)
# You can't build secure targets if you don't have OpenSSL.
$(BINDIR)/$(CONFIG)/bm_fullstack_streaming_pump: 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)/bm_fullstack_streaming_pump: protobuf_dep_error
else
$(BINDIR)/$(CONFIG)/bm_fullstack_streaming_pump: $(PROTOBUF_DEP) $(BM_FULLSTACK_STREAMING_PUMP_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_benchmark.a $(LIBDIR)/$(CONFIG)/libbenchmark.a $(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) $(BM_FULLSTACK_STREAMING_PUMP_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_benchmark.a $(LIBDIR)/$(CONFIG)/libbenchmark.a $(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)/bm_fullstack_streaming_pump
endif
endif
$(OBJDIR)/$(CONFIG)/test/cpp/microbenchmarks/bm_fullstack_streaming_pump.o: $(LIBDIR)/$(CONFIG)/libgrpc_benchmark.a $(LIBDIR)/$(CONFIG)/libbenchmark.a $(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_bm_fullstack_streaming_pump: $(BM_FULLSTACK_STREAMING_PUMP_OBJS:.o=.dep)
ifneq ($(NO_SECURE),true)
ifneq ($(NO_DEPS),true)
-include $(BM_FULLSTACK_STREAMING_PUMP_OBJS:.o=.dep)
endif
endif
BM_FULLSTACK_TRICKLE_SRC = \
test/cpp/microbenchmarks/bm_fullstack_trickle.cc \
BM_FULLSTACK_TRICKLE_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(BM_FULLSTACK_TRICKLE_SRC))))
ifeq ($(NO_SECURE),true)
# You can't build secure targets if you don't have OpenSSL.
$(BINDIR)/$(CONFIG)/bm_fullstack_trickle: 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)/bm_fullstack_trickle: protobuf_dep_error
else
$(BINDIR)/$(CONFIG)/bm_fullstack_trickle: $(PROTOBUF_DEP) $(BM_FULLSTACK_TRICKLE_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_benchmark.a $(LIBDIR)/$(CONFIG)/libbenchmark.a $(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) $(BM_FULLSTACK_TRICKLE_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_benchmark.a $(LIBDIR)/$(CONFIG)/libbenchmark.a $(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)/bm_fullstack_trickle
endif
endif
$(OBJDIR)/$(CONFIG)/test/cpp/microbenchmarks/bm_fullstack_trickle.o: $(LIBDIR)/$(CONFIG)/libgrpc_benchmark.a $(LIBDIR)/$(CONFIG)/libbenchmark.a $(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_bm_fullstack_trickle: $(BM_FULLSTACK_TRICKLE_OBJS:.o=.dep)
ifneq ($(NO_SECURE),true)
ifneq ($(NO_DEPS),true)
-include $(BM_FULLSTACK_TRICKLE_OBJS:.o=.dep)
endif
endif
BM_FULLSTACK_UNARY_PING_PONG_SRC = \
test/cpp/microbenchmarks/bm_fullstack_unary_ping_pong.cc \
BM_FULLSTACK_UNARY_PING_PONG_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(BM_FULLSTACK_UNARY_PING_PONG_SRC))))
ifeq ($(NO_SECURE),true)
# You can't build secure targets if you don't have OpenSSL.
$(BINDIR)/$(CONFIG)/bm_fullstack_unary_ping_pong: 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)/bm_fullstack_unary_ping_pong: protobuf_dep_error
else
$(BINDIR)/$(CONFIG)/bm_fullstack_unary_ping_pong: $(PROTOBUF_DEP) $(BM_FULLSTACK_UNARY_PING_PONG_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_benchmark.a $(LIBDIR)/$(CONFIG)/libbenchmark.a $(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) $(BM_FULLSTACK_UNARY_PING_PONG_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_benchmark.a $(LIBDIR)/$(CONFIG)/libbenchmark.a $(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)/bm_fullstack_unary_ping_pong
endif
endif
$(OBJDIR)/$(CONFIG)/test/cpp/microbenchmarks/bm_fullstack_unary_ping_pong.o: $(LIBDIR)/$(CONFIG)/libgrpc_benchmark.a $(LIBDIR)/$(CONFIG)/libbenchmark.a $(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_bm_fullstack_unary_ping_pong: $(BM_FULLSTACK_UNARY_PING_PONG_OBJS:.o=.dep)
ifneq ($(NO_SECURE),true)
ifneq ($(NO_DEPS),true)
-include $(BM_FULLSTACK_UNARY_PING_PONG_OBJS:.o=.dep)
endif endif
endif endif
@ -12809,16 +13154,16 @@ $(BINDIR)/$(CONFIG)/bm_metadata: protobuf_dep_error
else else
$(BINDIR)/$(CONFIG)/bm_metadata: $(PROTOBUF_DEP) $(BM_METADATA_OBJS) $(LIBDIR)/$(CONFIG)/libbenchmark.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(BINDIR)/$(CONFIG)/bm_metadata: $(PROTOBUF_DEP) $(BM_METADATA_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_benchmark.a $(LIBDIR)/$(CONFIG)/libbenchmark.a $(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 $@" $(E) "[LD] Linking $@"
$(Q) mkdir -p `dirname $@` $(Q) mkdir -p `dirname $@`
$(Q) $(LDXX) $(LDFLAGS) $(BM_METADATA_OBJS) $(LIBDIR)/$(CONFIG)/libbenchmark.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.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)/bm_metadata $(Q) $(LDXX) $(LDFLAGS) $(BM_METADATA_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_benchmark.a $(LIBDIR)/$(CONFIG)/libbenchmark.a $(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)/bm_metadata
endif endif
endif endif
$(OBJDIR)/$(CONFIG)/test/cpp/microbenchmarks/bm_metadata.o: $(LIBDIR)/$(CONFIG)/libbenchmark.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(OBJDIR)/$(CONFIG)/test/cpp/microbenchmarks/bm_metadata.o: $(LIBDIR)/$(CONFIG)/libgrpc_benchmark.a $(LIBDIR)/$(CONFIG)/libbenchmark.a $(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_bm_metadata: $(BM_METADATA_OBJS:.o=.dep) deps_bm_metadata: $(BM_METADATA_OBJS:.o=.dep)
@ -12829,6 +13174,49 @@ endif
endif endif
BM_POLLSET_SRC = \
test/cpp/microbenchmarks/bm_pollset.cc \
BM_POLLSET_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(BM_POLLSET_SRC))))
ifeq ($(NO_SECURE),true)
# You can't build secure targets if you don't have OpenSSL.
$(BINDIR)/$(CONFIG)/bm_pollset: 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)/bm_pollset: protobuf_dep_error
else
$(BINDIR)/$(CONFIG)/bm_pollset: $(PROTOBUF_DEP) $(BM_POLLSET_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_benchmark.a $(LIBDIR)/$(CONFIG)/libbenchmark.a $(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) $(BM_POLLSET_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_benchmark.a $(LIBDIR)/$(CONFIG)/libbenchmark.a $(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)/bm_pollset
endif
endif
$(OBJDIR)/$(CONFIG)/test/cpp/microbenchmarks/bm_pollset.o: $(LIBDIR)/$(CONFIG)/libgrpc_benchmark.a $(LIBDIR)/$(CONFIG)/libbenchmark.a $(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_bm_pollset: $(BM_POLLSET_OBJS:.o=.dep)
ifneq ($(NO_SECURE),true)
ifneq ($(NO_DEPS),true)
-include $(BM_POLLSET_OBJS:.o=.dep)
endif
endif
CHANNEL_ARGUMENTS_TEST_SRC = \ CHANNEL_ARGUMENTS_TEST_SRC = \
test/cpp/common/channel_arguments_test.cc \ test/cpp/common/channel_arguments_test.cc \
@ -14895,6 +15283,56 @@ endif
endif endif
SERVER_BUILDER_TEST_SRC = \
$(GENDIR)/src/proto/grpc/testing/echo_messages.pb.cc $(GENDIR)/src/proto/grpc/testing/echo_messages.grpc.pb.cc \
$(GENDIR)/src/proto/grpc/testing/echo.pb.cc $(GENDIR)/src/proto/grpc/testing/echo.grpc.pb.cc \
test/cpp/server/server_builder_test.cc \
SERVER_BUILDER_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(SERVER_BUILDER_TEST_SRC))))
ifeq ($(NO_SECURE),true)
# You can't build secure targets if you don't have OpenSSL.
$(BINDIR)/$(CONFIG)/server_builder_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)/server_builder_test: protobuf_dep_error
else
$(BINDIR)/$(CONFIG)/server_builder_test: $(PROTOBUF_DEP) $(SERVER_BUILDER_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a
$(E) "[LD] Linking $@"
$(Q) mkdir -p `dirname $@`
$(Q) $(LDXX) $(LDFLAGS) $(SERVER_BUILDER_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/server_builder_test
endif
endif
$(OBJDIR)/$(CONFIG)/src/proto/grpc/testing/echo_messages.o: $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a
$(OBJDIR)/$(CONFIG)/src/proto/grpc/testing/echo.o: $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a
$(OBJDIR)/$(CONFIG)/test/cpp/server/server_builder_test.o: $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a
deps_server_builder_test: $(SERVER_BUILDER_TEST_OBJS:.o=.dep)
ifneq ($(NO_SECURE),true)
ifneq ($(NO_DEPS),true)
-include $(SERVER_BUILDER_TEST_OBJS:.o=.dep)
endif
endif
$(OBJDIR)/$(CONFIG)/test/cpp/server/server_builder_test.o: $(GENDIR)/src/proto/grpc/testing/echo_messages.pb.cc $(GENDIR)/src/proto/grpc/testing/echo_messages.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/echo.pb.cc $(GENDIR)/src/proto/grpc/testing/echo.grpc.pb.cc
SERVER_CONTEXT_TEST_SPOUSE_TEST_SRC = \ SERVER_CONTEXT_TEST_SPOUSE_TEST_SRC = \
test/cpp/test/server_context_test_spouse_test.cc \ test/cpp/test/server_context_test_spouse_test.cc \
@ -18260,6 +18698,7 @@ test/cpp/interop/interop_client.cc: $(OPENSSL_DEP)
test/cpp/interop/interop_server.cc: $(OPENSSL_DEP) test/cpp/interop/interop_server.cc: $(OPENSSL_DEP)
test/cpp/interop/interop_server_bootstrap.cc: $(OPENSSL_DEP) test/cpp/interop/interop_server_bootstrap.cc: $(OPENSSL_DEP)
test/cpp/interop/server_helper.cc: $(OPENSSL_DEP) test/cpp/interop/server_helper.cc: $(OPENSSL_DEP)
test/cpp/microbenchmarks/helpers.cc: $(OPENSSL_DEP)
test/cpp/qps/client_async.cc: $(OPENSSL_DEP) test/cpp/qps/client_async.cc: $(OPENSSL_DEP)
test/cpp/qps/client_sync.cc: $(OPENSSL_DEP) test/cpp/qps/client_sync.cc: $(OPENSSL_DEP)
test/cpp/qps/driver.cc: $(OPENSSL_DEP) test/cpp/qps/driver.cc: $(OPENSSL_DEP)

@ -2,7 +2,7 @@
load("//:bazel/generate_cc.bzl", "generate_cc") load("//:bazel/generate_cc.bzl", "generate_cc")
def cc_grpc_library(name, srcs, deps, proto_only, use_external = False, **kwargs): def cc_grpc_library(name, srcs, deps, proto_only, well_known_protos, use_external = False, **kwargs):
"""Generates C++ grpc classes from a .proto file. """Generates C++ grpc classes from a .proto file.
Assumes the generated classes will be used in cc_api_version = 2. Assumes the generated classes will be used in cc_api_version = 2.
@ -12,6 +12,9 @@ def cc_grpc_library(name, srcs, deps, proto_only, use_external = False, **kwargs
srcs: a single proto_library, which wraps the .proto files with services. srcs: a single proto_library, which wraps the .proto files with services.
deps: a list of C++ proto_library (or cc_proto_library) which provides deps: a list of C++ proto_library (or cc_proto_library) which provides
the compiled code of any message that the services depend on. the compiled code of any message that the services depend on.
well_known_protos: The target from protobuf library that exports well
known protos. Currently it will only work if the value is
"@submodule_protobuf//:well_known_protos"
use_external: When True the grpc deps are prefixed with //external. This use_external: When True the grpc deps are prefixed with //external. This
allows grpc to be used as a dependency in other bazel projects. allows grpc to be used as a dependency in other bazel projects.
**kwargs: rest of arguments, e.g., compatible_with and visibility. **kwargs: rest of arguments, e.g., compatible_with and visibility.
@ -35,6 +38,7 @@ def cc_grpc_library(name, srcs, deps, proto_only, use_external = False, **kwargs
generate_cc( generate_cc(
name = codegen_target, name = codegen_target,
srcs = [proto_target], srcs = [proto_target],
well_known_protos = well_known_protos,
**kwargs **kwargs
) )
@ -49,6 +53,7 @@ def cc_grpc_library(name, srcs, deps, proto_only, use_external = False, **kwargs
name = codegen_grpc_target, name = codegen_grpc_target,
srcs = [proto_target], srcs = [proto_target],
plugin = plugin, plugin = plugin,
well_known_protos = well_known_protos,
**kwargs **kwargs
) )

@ -31,8 +31,20 @@ def generate_cc_impl(ctx):
arguments += ["-I{0}={0}".format(include.path) for include in includes] arguments += ["-I{0}={0}".format(include.path) for include in includes]
arguments += [proto.path for proto in protos] arguments += [proto.path for proto in protos]
# create a list of well known proto files if the argument is non-None
well_known_proto_files = []
if ctx.attr.well_known_protos:
f = ctx.attr.well_known_protos.files.to_list()[0].dirname
if f != "external/submodule_protobuf/src/google/protobuf":
print("Error: Only @submodule_protobuf//:well_known_protos is supported")
else:
# f points to "external/submodule_protobuf/src/google/protobuf"
# add -I argument to protoc so it knows where to look for the proto files.
arguments += ["-I{0}".format(f + "/../..")]
well_known_proto_files = [f for f in ctx.attr.well_known_protos.files]
ctx.action( ctx.action(
inputs = protos + includes + additional_input, inputs = protos + includes + additional_input + well_known_proto_files,
outputs = out_files, outputs = out_files,
executable = ctx.executable._protoc, executable = ctx.executable._protoc,
arguments = arguments, arguments = arguments,
@ -56,6 +68,9 @@ generate_cc = rule(
mandatory = False, mandatory = False,
allow_empty = True, allow_empty = True,
), ),
"well_known_protos" : attr.label(
mandatory = False,
),
"_protoc": attr.label( "_protoc": attr.label(
default = Label("//external:protocol_compiler"), default = Label("//external:protocol_compiler"),
executable = True, executable = True,

@ -58,11 +58,13 @@ def grpc_proto_plugin(name, srcs = [], deps = []):
load("//:bazel/cc_grpc_library.bzl", "cc_grpc_library") load("//:bazel/cc_grpc_library.bzl", "cc_grpc_library")
def grpc_proto_library(name, srcs = [], deps = [], well_known_deps = [], has_services = True, use_external = False): def grpc_proto_library(name, srcs = [], deps = [], well_known_protos = None,
has_services = True, use_external = False):
cc_grpc_library( cc_grpc_library(
name = name, name = name,
srcs = srcs, srcs = srcs,
deps = deps, deps = deps,
well_known_protos = well_known_protos,
proto_only = not has_services, proto_only = not has_services,
use_external = use_external, use_external = use_external,
) )

@ -544,6 +544,7 @@
'src/core/lib/profiling/basic_timers.c', 'src/core/lib/profiling/basic_timers.c',
'src/core/lib/profiling/stap_timers.c', 'src/core/lib/profiling/stap_timers.c',
'src/core/lib/support/alloc.c', 'src/core/lib/support/alloc.c',
'src/core/lib/support/arena.c',
'src/core/lib/support/avl.c', 'src/core/lib/support/avl.c',
'src/core/lib/support/backoff.c', 'src/core/lib/support/backoff.c',
'src/core/lib/support/cmdline.c', 'src/core/lib/support/cmdline.c',
@ -667,6 +668,9 @@
'src/core/lib/iomgr/tcp_client_windows.c', 'src/core/lib/iomgr/tcp_client_windows.c',
'src/core/lib/iomgr/tcp_posix.c', 'src/core/lib/iomgr/tcp_posix.c',
'src/core/lib/iomgr/tcp_server_posix.c', 'src/core/lib/iomgr/tcp_server_posix.c',
'src/core/lib/iomgr/tcp_server_utils_posix_common.c',
'src/core/lib/iomgr/tcp_server_utils_posix_ifaddrs.c',
'src/core/lib/iomgr/tcp_server_utils_posix_noifaddrs.c',
'src/core/lib/iomgr/tcp_server_uv.c', 'src/core/lib/iomgr/tcp_server_uv.c',
'src/core/lib/iomgr/tcp_server_windows.c', 'src/core/lib/iomgr/tcp_server_windows.c',
'src/core/lib/iomgr/tcp_uv.c', 'src/core/lib/iomgr/tcp_uv.c',

@ -13,8 +13,8 @@ settings:
'#09': Per-language overrides are possible with (eg) ruby_version tag here '#09': Per-language overrides are possible with (eg) ruby_version tag here
'#10': See the expand_version.py for all the quirks here '#10': See the expand_version.py for all the quirks here
core_version: 3.0.0-dev core_version: 3.0.0-dev
g_stands_for: green g_stands_for: gentle
version: 1.2.0-dev version: 1.3.0-dev
filegroups: filegroups:
- name: census - name: census
public_headers: public_headers:
@ -85,6 +85,7 @@ filegroups:
- include/grpc/support/useful.h - include/grpc/support/useful.h
headers: headers:
- src/core/lib/profiling/timers.h - src/core/lib/profiling/timers.h
- src/core/lib/support/arena.h
- src/core/lib/support/backoff.h - src/core/lib/support/backoff.h
- src/core/lib/support/block_annotate.h - src/core/lib/support/block_annotate.h
- src/core/lib/support/env.h - src/core/lib/support/env.h
@ -101,6 +102,7 @@ filegroups:
- src/core/lib/profiling/basic_timers.c - src/core/lib/profiling/basic_timers.c
- src/core/lib/profiling/stap_timers.c - src/core/lib/profiling/stap_timers.c
- src/core/lib/support/alloc.c - src/core/lib/support/alloc.c
- src/core/lib/support/arena.c
- src/core/lib/support/avl.c - src/core/lib/support/avl.c
- src/core/lib/support/backoff.c - src/core/lib/support/backoff.c
- src/core/lib/support/cmdline.c - src/core/lib/support/cmdline.c
@ -228,6 +230,7 @@ filegroups:
- src/core/lib/iomgr/tcp_client_posix.h - src/core/lib/iomgr/tcp_client_posix.h
- src/core/lib/iomgr/tcp_posix.h - src/core/lib/iomgr/tcp_posix.h
- src/core/lib/iomgr/tcp_server.h - src/core/lib/iomgr/tcp_server.h
- src/core/lib/iomgr/tcp_server_utils_posix.h
- src/core/lib/iomgr/tcp_uv.h - src/core/lib/iomgr/tcp_uv.h
- src/core/lib/iomgr/tcp_windows.h - src/core/lib/iomgr/tcp_windows.h
- src/core/lib/iomgr/time_averaged_stats.h - src/core/lib/iomgr/time_averaged_stats.h
@ -337,6 +340,9 @@ filegroups:
- src/core/lib/iomgr/tcp_client_windows.c - src/core/lib/iomgr/tcp_client_windows.c
- src/core/lib/iomgr/tcp_posix.c - src/core/lib/iomgr/tcp_posix.c
- src/core/lib/iomgr/tcp_server_posix.c - src/core/lib/iomgr/tcp_server_posix.c
- src/core/lib/iomgr/tcp_server_utils_posix_common.c
- src/core/lib/iomgr/tcp_server_utils_posix_ifaddrs.c
- src/core/lib/iomgr/tcp_server_utils_posix_noifaddrs.c
- src/core/lib/iomgr/tcp_server_uv.c - src/core/lib/iomgr/tcp_server_uv.c
- src/core/lib/iomgr/tcp_server_windows.c - src/core/lib/iomgr/tcp_server_windows.c
- src/core/lib/iomgr/tcp_uv.c - src/core/lib/iomgr/tcp_uv.c
@ -586,7 +592,7 @@ filegroups:
headers: headers:
- test/core/end2end/cq_verifier.h - test/core/end2end/cq_verifier.h
- test/core/end2end/fake_resolver.h - test/core/end2end/fake_resolver.h
- test/core/end2end/fixtures/http_proxy.h - test/core/end2end/fixtures/http_proxy_fixture.h
- test/core/end2end/fixtures/proxy.h - test/core/end2end/fixtures/proxy.h
- test/core/iomgr/endpoint_tests.h - test/core/iomgr/endpoint_tests.h
- test/core/util/debugger_macros.h - test/core/util/debugger_macros.h
@ -602,7 +608,7 @@ filegroups:
src: src:
- test/core/end2end/cq_verifier.c - test/core/end2end/cq_verifier.c
- test/core/end2end/fake_resolver.c - test/core/end2end/fake_resolver.c
- test/core/end2end/fixtures/http_proxy.c - test/core/end2end/fixtures/http_proxy_fixture.c
- test/core/end2end/fixtures/proxy.c - test/core/end2end/fixtures/proxy.c
- test/core/iomgr/endpoint_tests.c - test/core/iomgr/endpoint_tests.c
- test/core/util/debugger_macros.c - test/core/util/debugger_macros.c
@ -774,6 +780,7 @@ filegroups:
- include/grpc++/grpc++.h - include/grpc++/grpc++.h
- include/grpc++/health_check_service_interface.h - include/grpc++/health_check_service_interface.h
- include/grpc++/impl/call.h - include/grpc++/impl/call.h
- include/grpc++/impl/channel_argument_option.h
- include/grpc++/impl/client_unary_call.h - include/grpc++/impl/client_unary_call.h
- include/grpc++/impl/codegen/core_codegen.h - include/grpc++/impl/codegen/core_codegen.h
- include/grpc++/impl/grpc_library.h - include/grpc++/impl/grpc_library.h
@ -830,6 +837,7 @@ filegroups:
- src/cpp/common/rpc_method.cc - src/cpp/common/rpc_method.cc
- src/cpp/common/version_cc.cc - src/cpp/common/version_cc.cc
- src/cpp/server/async_generic_service.cc - src/cpp/server/async_generic_service.cc
- src/cpp/server/channel_argument_option.cc
- src/cpp/server/create_default_thread_pool.cc - src/cpp/server/create_default_thread_pool.cc
- src/cpp/server/dynamic_thread_pool.cc - src/cpp/server/dynamic_thread_pool.cc
- src/cpp/server/health/default_health_check_service.cc - src/cpp/server/health/default_health_check_service.cc
@ -1214,6 +1222,20 @@ libs:
- grpc++_codegen_base_src - grpc++_codegen_base_src
secure: false secure: false
vs_project_guid: '{6EE56155-DF7C-4F6E-BFC4-F6F776BEB211}' vs_project_guid: '{6EE56155-DF7C-4F6E-BFC4-F6F776BEB211}'
- name: grpc_benchmark
build: test
language: c++
headers:
- test/cpp/microbenchmarks/fullstack_context_mutators.h
- test/cpp/microbenchmarks/fullstack_fixtures.h
- test/cpp/microbenchmarks/helpers.h
src:
- test/cpp/microbenchmarks/helpers.cc
deps:
- benchmark
- grpc++
- grpc_test_util
- grpc
- name: grpc_cli_libs - name: grpc_cli_libs
build: private build: private
language: c++ language: c++
@ -1467,6 +1489,14 @@ targets:
- test/core/end2end/fuzzers/api_fuzzer_corpus - test/core/end2end/fuzzers/api_fuzzer_corpus
dict: test/core/end2end/fuzzers/api_fuzzer.dictionary dict: test/core/end2end/fuzzers/api_fuzzer.dictionary
maxlen: 2048 maxlen: 2048
- name: arena_test
build: test
language: c
src:
- test/core/support/arena_test.c
deps:
- gpr_test_util
- gpr
- name: bad_server_response_test - name: bad_server_response_test
build: test build: test
language: c language: c
@ -1686,6 +1716,17 @@ targets:
- gpr - gpr
exclude_iomgrs: exclude_iomgrs:
- uv - uv
- name: error_test
cpu_cost: 30
build: test
language: c
src:
- test/core/iomgr/error_test.c
deps:
- grpc_test_util
- grpc
- gpr_test_util
- gpr
- name: ev_epoll_linux_test - name: ev_epoll_linux_test
build: test build: test
language: c language: c
@ -2562,6 +2603,8 @@ targets:
- grpc - grpc
- gpr_test_util - gpr_test_util
- gpr - gpr
exclude_iomgrs:
- uv
platforms: platforms:
- mac - mac
- linux - linux
@ -3025,12 +3068,33 @@ targets:
- grpc - grpc
- gpr_test_util - gpr_test_util
- gpr - gpr
- name: bm_arena
build: test
language: c++
src:
- test/cpp/microbenchmarks/bm_arena.cc
deps:
- grpc_benchmark
- benchmark
- grpc++_test_util
- grpc_test_util
- grpc++
- grpc
- gpr_test_util
- gpr
args:
- --benchmark_min_time=0
platforms:
- mac
- linux
- posix
- name: bm_call_create - name: bm_call_create
build: test build: test
language: c++ language: c++
src: src:
- test/cpp/microbenchmarks/bm_call_create.cc - test/cpp/microbenchmarks/bm_call_create.cc
deps: deps:
- grpc_benchmark
- benchmark - benchmark
- grpc++_test_util - grpc++_test_util
- grpc_test_util - grpc_test_util
@ -3050,6 +3114,7 @@ targets:
src: src:
- test/cpp/microbenchmarks/bm_chttp2_hpack.cc - test/cpp/microbenchmarks/bm_chttp2_hpack.cc
deps: deps:
- grpc_benchmark
- benchmark - benchmark
- grpc++_test_util - grpc++_test_util
- grpc_test_util - grpc_test_util
@ -3069,6 +3134,7 @@ targets:
src: src:
- test/cpp/microbenchmarks/bm_closure.cc - test/cpp/microbenchmarks/bm_closure.cc
deps: deps:
- grpc_benchmark
- benchmark - benchmark
- grpc++_test_util - grpc++_test_util
- grpc_test_util - grpc_test_util
@ -3088,6 +3154,7 @@ targets:
src: src:
- test/cpp/microbenchmarks/bm_cq.cc - test/cpp/microbenchmarks/bm_cq.cc
deps: deps:
- grpc_benchmark
- benchmark - benchmark
- grpc++_test_util - grpc++_test_util
- grpc_test_util - grpc_test_util
@ -3107,6 +3174,51 @@ targets:
src: src:
- test/cpp/microbenchmarks/bm_error.cc - test/cpp/microbenchmarks/bm_error.cc
deps: deps:
- grpc_benchmark
- benchmark
- grpc++_test_util
- grpc_test_util
- grpc++
- grpc
- gpr_test_util
- gpr
args:
- --benchmark_min_time=0
platforms:
- mac
- linux
- posix
- name: bm_fullstack_streaming_ping_pong
build: test
language: c++
src:
- test/cpp/microbenchmarks/bm_fullstack_streaming_ping_pong.cc
deps:
- grpc_benchmark
- benchmark
- grpc++_test_util
- grpc_test_util
- grpc++
- grpc
- gpr_test_util
- gpr
args:
- --benchmark_min_time=0
excluded_poll_engines:
- poll
- poll-cv
platforms:
- mac
- linux
- posix
timeout_seconds: 1200
- name: bm_fullstack_streaming_pump
build: test
language: c++
src:
- test/cpp/microbenchmarks/bm_fullstack_streaming_pump.cc
deps:
- grpc_benchmark
- benchmark - benchmark
- grpc++_test_util - grpc++_test_util
- grpc_test_util - grpc_test_util
@ -3116,16 +3228,45 @@ targets:
- gpr - gpr
args: args:
- --benchmark_min_time=0 - --benchmark_min_time=0
excluded_poll_engines:
- poll
- poll-cv
platforms: platforms:
- mac - mac
- linux - linux
- posix - posix
- name: bm_fullstack timeout_seconds: 1200
- name: bm_fullstack_trickle
build: test build: test
language: c++ language: c++
src: src:
- test/cpp/microbenchmarks/bm_fullstack.cc - test/cpp/microbenchmarks/bm_fullstack_trickle.cc
deps: deps:
- grpc_benchmark
- benchmark
- grpc++_test_util
- grpc_test_util
- grpc++
- grpc
- gpr_test_util
- gpr
args:
- --benchmark_min_time=0
excluded_poll_engines:
- poll
- poll-cv
platforms:
- mac
- linux
- posix
timeout_seconds: 1200
- name: bm_fullstack_unary_ping_pong
build: test
language: c++
src:
- test/cpp/microbenchmarks/bm_fullstack_unary_ping_pong.cc
deps:
- grpc_benchmark
- benchmark - benchmark
- grpc++_test_util - grpc++_test_util
- grpc_test_util - grpc_test_util
@ -3149,8 +3290,31 @@ targets:
src: src:
- test/cpp/microbenchmarks/bm_metadata.cc - test/cpp/microbenchmarks/bm_metadata.cc
deps: deps:
- grpc_benchmark
- benchmark
- grpc++_test_util
- grpc_test_util
- grpc++
- grpc
- gpr_test_util
- gpr
args:
- --benchmark_min_time=0
platforms:
- mac
- linux
- posix
- name: bm_pollset
build: test
language: c++
src:
- test/cpp/microbenchmarks/bm_pollset.cc
deps:
- grpc_benchmark
- benchmark - benchmark
- grpc++_test_util
- grpc_test_util - grpc_test_util
- grpc++
- grpc - grpc
- gpr_test_util - gpr_test_util
- gpr - gpr
@ -3828,6 +3992,21 @@ targets:
- grpc - grpc
- gpr_test_util - gpr_test_util
- gpr - gpr
- name: server_builder_test
gtest: true
build: test
language: c++
src:
- src/proto/grpc/testing/echo_messages.proto
- src/proto/grpc/testing/echo.proto
- test/cpp/server/server_builder_test.cc
deps:
- grpc++_test_util
- grpc_test_util
- gpr_test_util
- grpc++
- grpc
- gpr
- name: server_context_test_spouse_test - name: server_context_test_spouse_test
gtest: true gtest: true
build: test build: test
@ -4110,8 +4289,8 @@ configs:
TSAN_OPTIONS: suppressions=tools/tsan_suppressions.txt:halt_on_error=1:second_deadlock_stack=1 TSAN_OPTIONS: suppressions=tools/tsan_suppressions.txt:halt_on_error=1:second_deadlock_stack=1
ubsan: ubsan:
CC: clang CC: clang
CPPFLAGS: -O0 -fsanitize-coverage=edge -fsanitize=undefined,unsigned-integer-overflow CPPFLAGS: -O0 -fsanitize-coverage=edge -fsanitize=undefined -fno-omit-frame-pointer
-fno-omit-frame-pointer -Wno-unused-command-line-argument -Wvarargs -Wno-unused-command-line-argument -Wvarargs
CXX: clang++ CXX: clang++
DEFINES: NDEBUG DEFINES: NDEBUG
LD: clang LD: clang
@ -4119,7 +4298,7 @@ configs:
LDXX: clang++ LDXX: clang++
compile_the_world: true compile_the_world: true
test_environ: test_environ:
UBSAN_OPTIONS: halt_on_error=1:print_stacktrace=1 UBSAN_OPTIONS: halt_on_error=1:print_stacktrace=1:suppressions=tools/ubsan_suppressions.txt
defaults: defaults:
benchmark: benchmark:
CPPFLAGS: -Ithird_party/benchmark/include -DHAVE_POSIX_REGEX CPPFLAGS: -Ithird_party/benchmark/include -DHAVE_POSIX_REGEX

@ -39,6 +39,7 @@ if test "$PHP_GRPC" != "no"; then
src/core/lib/profiling/basic_timers.c \ src/core/lib/profiling/basic_timers.c \
src/core/lib/profiling/stap_timers.c \ src/core/lib/profiling/stap_timers.c \
src/core/lib/support/alloc.c \ src/core/lib/support/alloc.c \
src/core/lib/support/arena.c \
src/core/lib/support/avl.c \ src/core/lib/support/avl.c \
src/core/lib/support/backoff.c \ src/core/lib/support/backoff.c \
src/core/lib/support/cmdline.c \ src/core/lib/support/cmdline.c \
@ -140,6 +141,9 @@ if test "$PHP_GRPC" != "no"; then
src/core/lib/iomgr/tcp_client_windows.c \ src/core/lib/iomgr/tcp_client_windows.c \
src/core/lib/iomgr/tcp_posix.c \ src/core/lib/iomgr/tcp_posix.c \
src/core/lib/iomgr/tcp_server_posix.c \ src/core/lib/iomgr/tcp_server_posix.c \
src/core/lib/iomgr/tcp_server_utils_posix_common.c \
src/core/lib/iomgr/tcp_server_utils_posix_ifaddrs.c \
src/core/lib/iomgr/tcp_server_utils_posix_noifaddrs.c \
src/core/lib/iomgr/tcp_server_uv.c \ src/core/lib/iomgr/tcp_server_uv.c \
src/core/lib/iomgr/tcp_server_windows.c \ src/core/lib/iomgr/tcp_server_windows.c \
src/core/lib/iomgr/tcp_uv.c \ src/core/lib/iomgr/tcp_uv.c \

@ -7,3 +7,4 @@ future), and the corresponding version numbers that used them:
- 1.0 'g' stands for 'gRPC' - 1.0 'g' stands for 'gRPC'
- 1.1 'g' stands for 'good' - 1.1 'g' stands for 'good'
- 1.2 'g' stands for 'green' - 1.2 'g' stands for 'green'
- 1.3 'g' stands for 'gentle'

@ -0,0 +1,16 @@
Ordering Status and Reads in the gRPC API
-----------------------------------------
Rules for implementors:
1. Reads and Writes Must not succeed after Status has been delivered.
2. OK Status is only delivered after all buffered messages are read.
3. Reads May continue to succeed after a failing write.
However, once a write fails, all subsequent writes Must fail,
and similarly, once a read fails, all subsequent reads Must fail.
4. When an error status is known to the library, if the user asks for status,
the library Should discard messages received in the library but not delivered
to the user and then deliver the status. If the user does not ask for status
but continues reading, the library Should deliver buffered messages before
delivering status. The library MAY choose to implement the stricter version
where errors cause all buffered messages to be dropped, but this is not a
requirement.

@ -0,0 +1,5 @@
{
"sdk": {
"version": "1.0.0-preview2-003121"
}
}

@ -37,7 +37,7 @@
Pod::Spec.new do |s| Pod::Spec.new do |s|
s.name = 'gRPC-Core' s.name = 'gRPC-Core'
version = '1.2.0-dev' version = '1.3.0-dev'
s.version = version s.version = version
s.summary = 'Core cross-platform gRPC library, written in C' s.summary = 'Core cross-platform gRPC library, written in C'
s.homepage = 'http://www.grpc.io' s.homepage = 'http://www.grpc.io'
@ -196,6 +196,7 @@ Pod::Spec.new do |s|
# To save you from scrolling, this is the last part of the podspec. # To save you from scrolling, this is the last part of the podspec.
ss.source_files = 'src/core/lib/profiling/timers.h', ss.source_files = 'src/core/lib/profiling/timers.h',
'src/core/lib/support/arena.h',
'src/core/lib/support/backoff.h', 'src/core/lib/support/backoff.h',
'src/core/lib/support/block_annotate.h', 'src/core/lib/support/block_annotate.h',
'src/core/lib/support/env.h', 'src/core/lib/support/env.h',
@ -211,6 +212,7 @@ Pod::Spec.new do |s|
'src/core/lib/profiling/basic_timers.c', 'src/core/lib/profiling/basic_timers.c',
'src/core/lib/profiling/stap_timers.c', 'src/core/lib/profiling/stap_timers.c',
'src/core/lib/support/alloc.c', 'src/core/lib/support/alloc.c',
'src/core/lib/support/arena.c',
'src/core/lib/support/avl.c', 'src/core/lib/support/avl.c',
'src/core/lib/support/backoff.c', 'src/core/lib/support/backoff.c',
'src/core/lib/support/cmdline.c', 'src/core/lib/support/cmdline.c',
@ -309,6 +311,7 @@ Pod::Spec.new do |s|
'src/core/lib/iomgr/tcp_client_posix.h', 'src/core/lib/iomgr/tcp_client_posix.h',
'src/core/lib/iomgr/tcp_posix.h', 'src/core/lib/iomgr/tcp_posix.h',
'src/core/lib/iomgr/tcp_server.h', 'src/core/lib/iomgr/tcp_server.h',
'src/core/lib/iomgr/tcp_server_utils_posix.h',
'src/core/lib/iomgr/tcp_uv.h', 'src/core/lib/iomgr/tcp_uv.h',
'src/core/lib/iomgr/tcp_windows.h', 'src/core/lib/iomgr/tcp_windows.h',
'src/core/lib/iomgr/time_averaged_stats.h', 'src/core/lib/iomgr/time_averaged_stats.h',
@ -508,6 +511,9 @@ Pod::Spec.new do |s|
'src/core/lib/iomgr/tcp_client_windows.c', 'src/core/lib/iomgr/tcp_client_windows.c',
'src/core/lib/iomgr/tcp_posix.c', 'src/core/lib/iomgr/tcp_posix.c',
'src/core/lib/iomgr/tcp_server_posix.c', 'src/core/lib/iomgr/tcp_server_posix.c',
'src/core/lib/iomgr/tcp_server_utils_posix_common.c',
'src/core/lib/iomgr/tcp_server_utils_posix_ifaddrs.c',
'src/core/lib/iomgr/tcp_server_utils_posix_noifaddrs.c',
'src/core/lib/iomgr/tcp_server_uv.c', 'src/core/lib/iomgr/tcp_server_uv.c',
'src/core/lib/iomgr/tcp_server_windows.c', 'src/core/lib/iomgr/tcp_server_windows.c',
'src/core/lib/iomgr/tcp_uv.c', 'src/core/lib/iomgr/tcp_uv.c',
@ -675,6 +681,7 @@ Pod::Spec.new do |s|
'src/core/plugin_registry/grpc_plugin_registry.c' 'src/core/plugin_registry/grpc_plugin_registry.c'
ss.private_header_files = 'src/core/lib/profiling/timers.h', ss.private_header_files = 'src/core/lib/profiling/timers.h',
'src/core/lib/support/arena.h',
'src/core/lib/support/backoff.h', 'src/core/lib/support/backoff.h',
'src/core/lib/support/block_annotate.h', 'src/core/lib/support/block_annotate.h',
'src/core/lib/support/env.h', 'src/core/lib/support/env.h',
@ -744,6 +751,7 @@ Pod::Spec.new do |s|
'src/core/lib/iomgr/tcp_client_posix.h', 'src/core/lib/iomgr/tcp_client_posix.h',
'src/core/lib/iomgr/tcp_posix.h', 'src/core/lib/iomgr/tcp_posix.h',
'src/core/lib/iomgr/tcp_server.h', 'src/core/lib/iomgr/tcp_server.h',
'src/core/lib/iomgr/tcp_server_utils_posix.h',
'src/core/lib/iomgr/tcp_uv.h', 'src/core/lib/iomgr/tcp_uv.h',
'src/core/lib/iomgr/tcp_windows.h', 'src/core/lib/iomgr/tcp_windows.h',
'src/core/lib/iomgr/time_averaged_stats.h', 'src/core/lib/iomgr/time_averaged_stats.h',

@ -36,7 +36,7 @@
Pod::Spec.new do |s| Pod::Spec.new do |s|
s.name = 'gRPC-ProtoRPC' s.name = 'gRPC-ProtoRPC'
version = '1.2.0-dev' version = '1.3.0-dev'
s.version = version s.version = version
s.summary = 'RPC library for Protocol Buffers, based on gRPC' s.summary = 'RPC library for Protocol Buffers, based on gRPC'
s.homepage = 'http://www.grpc.io' s.homepage = 'http://www.grpc.io'

@ -36,7 +36,7 @@
Pod::Spec.new do |s| Pod::Spec.new do |s|
s.name = 'gRPC-RxLibrary' s.name = 'gRPC-RxLibrary'
version = '1.2.0-dev' version = '1.3.0-dev'
s.version = version s.version = version
s.summary = 'Reactive Extensions library for iOS/OSX.' s.summary = 'Reactive Extensions library for iOS/OSX.'
s.homepage = 'http://www.grpc.io' s.homepage = 'http://www.grpc.io'

@ -35,7 +35,7 @@
Pod::Spec.new do |s| Pod::Spec.new do |s|
s.name = 'gRPC' s.name = 'gRPC'
version = '1.2.0-dev' version = '1.3.0-dev'
s.version = version s.version = version
s.summary = 'gRPC client library for iOS/OSX' s.summary = 'gRPC client library for iOS/OSX'
s.homepage = 'http://www.grpc.io' s.homepage = 'http://www.grpc.io'

@ -258,6 +258,7 @@ EXPORTS
gpr_ref_non_zero gpr_ref_non_zero
gpr_refn gpr_refn
gpr_unref gpr_unref
gpr_ref_is_unique
gpr_stats_init gpr_stats_init
gpr_stats_inc gpr_stats_inc
gpr_stats_read gpr_stats_read

@ -82,6 +82,7 @@ Gem::Specification.new do |s|
s.files += %w( include/grpc/impl/codegen/sync_posix.h ) s.files += %w( include/grpc/impl/codegen/sync_posix.h )
s.files += %w( include/grpc/impl/codegen/sync_windows.h ) s.files += %w( include/grpc/impl/codegen/sync_windows.h )
s.files += %w( src/core/lib/profiling/timers.h ) s.files += %w( src/core/lib/profiling/timers.h )
s.files += %w( src/core/lib/support/arena.h )
s.files += %w( src/core/lib/support/backoff.h ) s.files += %w( src/core/lib/support/backoff.h )
s.files += %w( src/core/lib/support/block_annotate.h ) s.files += %w( src/core/lib/support/block_annotate.h )
s.files += %w( src/core/lib/support/env.h ) s.files += %w( src/core/lib/support/env.h )
@ -97,6 +98,7 @@ Gem::Specification.new do |s|
s.files += %w( src/core/lib/profiling/basic_timers.c ) s.files += %w( src/core/lib/profiling/basic_timers.c )
s.files += %w( src/core/lib/profiling/stap_timers.c ) s.files += %w( src/core/lib/profiling/stap_timers.c )
s.files += %w( src/core/lib/support/alloc.c ) s.files += %w( src/core/lib/support/alloc.c )
s.files += %w( src/core/lib/support/arena.c )
s.files += %w( src/core/lib/support/avl.c ) s.files += %w( src/core/lib/support/avl.c )
s.files += %w( src/core/lib/support/backoff.c ) s.files += %w( src/core/lib/support/backoff.c )
s.files += %w( src/core/lib/support/cmdline.c ) s.files += %w( src/core/lib/support/cmdline.c )
@ -226,6 +228,7 @@ Gem::Specification.new do |s|
s.files += %w( src/core/lib/iomgr/tcp_client_posix.h ) s.files += %w( src/core/lib/iomgr/tcp_client_posix.h )
s.files += %w( src/core/lib/iomgr/tcp_posix.h ) s.files += %w( src/core/lib/iomgr/tcp_posix.h )
s.files += %w( src/core/lib/iomgr/tcp_server.h ) s.files += %w( src/core/lib/iomgr/tcp_server.h )
s.files += %w( src/core/lib/iomgr/tcp_server_utils_posix.h )
s.files += %w( src/core/lib/iomgr/tcp_uv.h ) s.files += %w( src/core/lib/iomgr/tcp_uv.h )
s.files += %w( src/core/lib/iomgr/tcp_windows.h ) s.files += %w( src/core/lib/iomgr/tcp_windows.h )
s.files += %w( src/core/lib/iomgr/time_averaged_stats.h ) s.files += %w( src/core/lib/iomgr/time_averaged_stats.h )
@ -425,6 +428,9 @@ Gem::Specification.new do |s|
s.files += %w( src/core/lib/iomgr/tcp_client_windows.c ) s.files += %w( src/core/lib/iomgr/tcp_client_windows.c )
s.files += %w( src/core/lib/iomgr/tcp_posix.c ) s.files += %w( src/core/lib/iomgr/tcp_posix.c )
s.files += %w( src/core/lib/iomgr/tcp_server_posix.c ) s.files += %w( src/core/lib/iomgr/tcp_server_posix.c )
s.files += %w( src/core/lib/iomgr/tcp_server_utils_posix_common.c )
s.files += %w( src/core/lib/iomgr/tcp_server_utils_posix_ifaddrs.c )
s.files += %w( src/core/lib/iomgr/tcp_server_utils_posix_noifaddrs.c )
s.files += %w( src/core/lib/iomgr/tcp_server_uv.c ) s.files += %w( src/core/lib/iomgr/tcp_server_uv.c )
s.files += %w( src/core/lib/iomgr/tcp_server_windows.c ) s.files += %w( src/core/lib/iomgr/tcp_server_windows.c )
s.files += %w( src/core/lib/iomgr/tcp_uv.c ) s.files += %w( src/core/lib/iomgr/tcp_uv.c )

@ -0,0 +1,52 @@
/*
*
* 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 GRPCXX_IMPL_CHANNEL_ARGUMENT_OPTION_H
#define GRPCXX_IMPL_CHANNEL_ARGUMENT_OPTION_H
#include <map>
#include <memory>
#include <grpc++/impl/server_builder_option.h>
#include <grpc++/support/channel_arguments.h>
namespace grpc {
std::unique_ptr<ServerBuilderOption> MakeChannelArgumentOption(
const grpc::string &name, const grpc::string &value);
std::unique_ptr<ServerBuilderOption> MakeChannelArgumentOption(
const grpc::string &name, int value);
} // namespace grpc
#endif // GRPCXX_IMPL_CHANNEL_ARGUMENT_OPTION_H

@ -39,6 +39,7 @@
#include <memory> #include <memory>
#include <vector> #include <vector>
#include <grpc++/impl/channel_argument_option.h>
#include <grpc++/impl/server_builder_option.h> #include <grpc++/impl/server_builder_option.h>
#include <grpc++/impl/server_builder_plugin.h> #include <grpc++/impl/server_builder_plugin.h>
#include <grpc++/support/config.h> #include <grpc++/support/config.h>
@ -130,6 +131,13 @@ class ServerBuilder {
/// Only useful if this is a Synchronous server. /// Only useful if this is a Synchronous server.
ServerBuilder& SetSyncServerOption(SyncServerOption option, int value); ServerBuilder& SetSyncServerOption(SyncServerOption option, int value);
/// Add a channel argument (an escape hatch to tuning core library parameters
/// directly)
template <class T>
ServerBuilder& AddChannelArgument(const grpc::string& arg, const T& value) {
return SetOption(MakeChannelArgumentOption(arg, value));
}
/// Tries to bind \a server to the given \a addr. /// Tries to bind \a server to the given \a addr.
/// ///
/// It can be invoked multiple times. /// It can be invoked multiple times.

@ -54,7 +54,7 @@ class ResourceQuota;
class ChannelArguments { class ChannelArguments {
public: public:
ChannelArguments(); ChannelArguments();
~ChannelArguments() {} ~ChannelArguments();
ChannelArguments(const ChannelArguments& other); ChannelArguments(const ChannelArguments& other);
ChannelArguments& operator=(ChannelArguments other) { ChannelArguments& operator=(ChannelArguments other) {

@ -52,6 +52,10 @@
provides no memory barriers. provides no memory barriers.
*/ */
#ifdef __cplusplus
extern "C" {
#endif
/* Platform-specific type declarations of gpr_mu and gpr_cv. */ /* Platform-specific type declarations of gpr_mu and gpr_cv. */
#include <grpc/impl/codegen/port_platform.h> #include <grpc/impl/codegen/port_platform.h>
#include <grpc/impl/codegen/sync_generic.h> #include <grpc/impl/codegen/sync_generic.h>
@ -64,4 +68,8 @@
#error Unable to determine platform for sync #error Unable to determine platform for sync
#endif #endif
#ifdef __cplusplus
}
#endif
#endif /* GRPC_IMPL_CODEGEN_SYNC_H */ #endif /* GRPC_IMPL_CODEGEN_SYNC_H */

@ -164,6 +164,10 @@ GPRAPI void gpr_refn(gpr_refcount *r, int n);
zero. . Requires *r initialized. */ zero. . Requires *r initialized. */
GPRAPI int gpr_unref(gpr_refcount *r); GPRAPI int gpr_unref(gpr_refcount *r);
/* Return non-zero iff the reference count of *r is one, and thus is owned
by exactly one object. */
GPRAPI int gpr_ref_is_unique(gpr_refcount *r);
/* --- Stats counters --- /* --- Stats counters ---
These calls act on the integral type gpr_stats_counter. It requires no These calls act on the integral type gpr_stats_counter. It requires no

@ -1,6 +1,6 @@
{ {
"name": "grpc", "name": "grpc",
"version": "1.2.0-dev", "version": "1.3.0-dev",
"author": "Google Inc.", "author": "Google Inc.",
"description": "gRPC Library for Node", "description": "gRPC Library for Node",
"homepage": "http://www.grpc.io/", "homepage": "http://www.grpc.io/",

@ -13,8 +13,8 @@
<date>2017-03-01</date> <date>2017-03-01</date>
<time>16:06:07</time> <time>16:06:07</time>
<version> <version>
<release>1.2.0dev</release> <release>1.3.0dev</release>
<api>1.2.0dev</api> <api>1.3.0dev</api>
</version> </version>
<stability> <stability>
<release>beta</release> <release>beta</release>
@ -91,6 +91,7 @@
<file baseinstalldir="/" name="include/grpc/impl/codegen/sync_posix.h" role="src" /> <file baseinstalldir="/" name="include/grpc/impl/codegen/sync_posix.h" role="src" />
<file baseinstalldir="/" name="include/grpc/impl/codegen/sync_windows.h" role="src" /> <file baseinstalldir="/" name="include/grpc/impl/codegen/sync_windows.h" role="src" />
<file baseinstalldir="/" name="src/core/lib/profiling/timers.h" role="src" /> <file baseinstalldir="/" name="src/core/lib/profiling/timers.h" role="src" />
<file baseinstalldir="/" name="src/core/lib/support/arena.h" role="src" />
<file baseinstalldir="/" name="src/core/lib/support/backoff.h" role="src" /> <file baseinstalldir="/" name="src/core/lib/support/backoff.h" role="src" />
<file baseinstalldir="/" name="src/core/lib/support/block_annotate.h" role="src" /> <file baseinstalldir="/" name="src/core/lib/support/block_annotate.h" role="src" />
<file baseinstalldir="/" name="src/core/lib/support/env.h" role="src" /> <file baseinstalldir="/" name="src/core/lib/support/env.h" role="src" />
@ -106,6 +107,7 @@
<file baseinstalldir="/" name="src/core/lib/profiling/basic_timers.c" role="src" /> <file baseinstalldir="/" name="src/core/lib/profiling/basic_timers.c" role="src" />
<file baseinstalldir="/" name="src/core/lib/profiling/stap_timers.c" role="src" /> <file baseinstalldir="/" name="src/core/lib/profiling/stap_timers.c" role="src" />
<file baseinstalldir="/" name="src/core/lib/support/alloc.c" role="src" /> <file baseinstalldir="/" name="src/core/lib/support/alloc.c" role="src" />
<file baseinstalldir="/" name="src/core/lib/support/arena.c" role="src" />
<file baseinstalldir="/" name="src/core/lib/support/avl.c" role="src" /> <file baseinstalldir="/" name="src/core/lib/support/avl.c" role="src" />
<file baseinstalldir="/" name="src/core/lib/support/backoff.c" role="src" /> <file baseinstalldir="/" name="src/core/lib/support/backoff.c" role="src" />
<file baseinstalldir="/" name="src/core/lib/support/cmdline.c" role="src" /> <file baseinstalldir="/" name="src/core/lib/support/cmdline.c" role="src" />
@ -235,6 +237,7 @@
<file baseinstalldir="/" name="src/core/lib/iomgr/tcp_client_posix.h" role="src" /> <file baseinstalldir="/" name="src/core/lib/iomgr/tcp_client_posix.h" role="src" />
<file baseinstalldir="/" name="src/core/lib/iomgr/tcp_posix.h" role="src" /> <file baseinstalldir="/" name="src/core/lib/iomgr/tcp_posix.h" role="src" />
<file baseinstalldir="/" name="src/core/lib/iomgr/tcp_server.h" role="src" /> <file baseinstalldir="/" name="src/core/lib/iomgr/tcp_server.h" role="src" />
<file baseinstalldir="/" name="src/core/lib/iomgr/tcp_server_utils_posix.h" role="src" />
<file baseinstalldir="/" name="src/core/lib/iomgr/tcp_uv.h" role="src" /> <file baseinstalldir="/" name="src/core/lib/iomgr/tcp_uv.h" role="src" />
<file baseinstalldir="/" name="src/core/lib/iomgr/tcp_windows.h" role="src" /> <file baseinstalldir="/" name="src/core/lib/iomgr/tcp_windows.h" role="src" />
<file baseinstalldir="/" name="src/core/lib/iomgr/time_averaged_stats.h" role="src" /> <file baseinstalldir="/" name="src/core/lib/iomgr/time_averaged_stats.h" role="src" />
@ -434,6 +437,9 @@
<file baseinstalldir="/" name="src/core/lib/iomgr/tcp_client_windows.c" role="src" /> <file baseinstalldir="/" name="src/core/lib/iomgr/tcp_client_windows.c" role="src" />
<file baseinstalldir="/" name="src/core/lib/iomgr/tcp_posix.c" role="src" /> <file baseinstalldir="/" name="src/core/lib/iomgr/tcp_posix.c" role="src" />
<file baseinstalldir="/" name="src/core/lib/iomgr/tcp_server_posix.c" role="src" /> <file baseinstalldir="/" name="src/core/lib/iomgr/tcp_server_posix.c" role="src" />
<file baseinstalldir="/" name="src/core/lib/iomgr/tcp_server_utils_posix_common.c" role="src" />
<file baseinstalldir="/" name="src/core/lib/iomgr/tcp_server_utils_posix_ifaddrs.c" role="src" />
<file baseinstalldir="/" name="src/core/lib/iomgr/tcp_server_utils_posix_noifaddrs.c" role="src" />
<file baseinstalldir="/" name="src/core/lib/iomgr/tcp_server_uv.c" role="src" /> <file baseinstalldir="/" name="src/core/lib/iomgr/tcp_server_uv.c" role="src" />
<file baseinstalldir="/" name="src/core/lib/iomgr/tcp_server_windows.c" role="src" /> <file baseinstalldir="/" name="src/core/lib/iomgr/tcp_server_windows.c" role="src" />
<file baseinstalldir="/" name="src/core/lib/iomgr/tcp_uv.c" role="src" /> <file baseinstalldir="/" name="src/core/lib/iomgr/tcp_uv.c" role="src" />

@ -3,6 +3,6 @@ coverage>=4.0
cython>=0.23 cython>=0.23
enum34>=1.0.4 enum34>=1.0.4
futures>=2.2.0 futures>=2.2.0
protobuf>=3.0.0 protobuf>=3.2.0
six>=1.10 six>=1.10
wheel>=0.29 wheel>=0.29

@ -101,18 +101,20 @@ class IndentScope {
// TODO(https://github.com/google/protobuf/issues/888): // TODO(https://github.com/google/protobuf/issues/888):
// Export `ModuleName` from protobuf's // Export `ModuleName` from protobuf's
// `src/google/protobuf/compiler/python/python_generator.cc` file. // `src/google/protobuf/compiler/python/python_generator.cc` file.
grpc::string ModuleName(const grpc::string& filename) { grpc::string ModuleName(const grpc::string& filename,
const grpc::string& import_prefix) {
grpc::string basename = StripProto(filename); grpc::string basename = StripProto(filename);
basename = StringReplace(basename, "-", "_"); basename = StringReplace(basename, "-", "_");
basename = StringReplace(basename, "/", "."); basename = StringReplace(basename, "/", ".");
return basename + "_pb2"; return import_prefix + basename + "_pb2";
} }
// TODO(https://github.com/google/protobuf/issues/888): // TODO(https://github.com/google/protobuf/issues/888):
// Export `ModuleAlias` from protobuf's // Export `ModuleAlias` from protobuf's
// `src/google/protobuf/compiler/python/python_generator.cc` file. // `src/google/protobuf/compiler/python/python_generator.cc` file.
grpc::string ModuleAlias(const grpc::string& filename) { grpc::string ModuleAlias(const grpc::string& filename,
grpc::string module_name = ModuleName(filename); const grpc::string& import_prefix) {
grpc::string module_name = ModuleName(filename, import_prefix);
// We can't have dots in the module name, so we replace each with _dot_. // We can't have dots in the module name, so we replace each with _dot_.
// But that could lead to a collision between a.b and a_dot_b, so we also // But that could lead to a collision between a.b and a_dot_b, so we also
// duplicate each underscore. // duplicate each underscore.
@ -189,7 +191,7 @@ bool PrivateGenerator::GetModuleAndMessagePath(const Descriptor* type,
grpc::string generator_file_name = file->name(); grpc::string generator_file_name = file->name();
grpc::string module; grpc::string module;
if (generator_file_name != file_name || generate_in_pb2_grpc) { if (generator_file_name != file_name || generate_in_pb2_grpc) {
module = ModuleAlias(file_name) + "."; module = ModuleAlias(file_name, config.import_prefix) + ".";
} else { } else {
module = ""; module = "";
} }
@ -666,8 +668,10 @@ bool PrivateGenerator::PrintPreamble() {
for (int k = 0; k < 2; ++k) { for (int k = 0; k < 2; ++k) {
const Descriptor* type = types[k]; const Descriptor* type = types[k];
grpc::string type_file_name = type->file()->name(); grpc::string type_file_name = type->file()->name();
grpc::string module_name = ModuleName(type_file_name); grpc::string module_name =
grpc::string module_alias = ModuleAlias(type_file_name); ModuleName(type_file_name, config.import_prefix);
grpc::string module_alias =
ModuleAlias(type_file_name, config.import_prefix);
imports_set.insert(std::make_tuple(module_name, module_alias)); imports_set.insert(std::make_tuple(module_name, module_alias));
} }
} }
@ -766,7 +770,9 @@ pair<bool, grpc::string> PrivateGenerator::GetGrpcServices() {
} // namespace } // namespace
GeneratorConfiguration::GeneratorConfiguration() GeneratorConfiguration::GeneratorConfiguration()
: grpc_package_root("grpc"), beta_package_root("grpc.beta") {} : grpc_package_root("grpc"),
beta_package_root("grpc.beta"),
import_prefix("") {}
PythonGrpcGenerator::PythonGrpcGenerator(const GeneratorConfiguration& config) PythonGrpcGenerator::PythonGrpcGenerator(const GeneratorConfiguration& config)
: config_(config) {} : config_(config) {}

@ -45,7 +45,10 @@ namespace grpc_python_generator {
struct GeneratorConfiguration { struct GeneratorConfiguration {
GeneratorConfiguration(); GeneratorConfiguration();
grpc::string grpc_package_root; grpc::string grpc_package_root;
// TODO(https://github.com/grpc/grpc/issues/8622): Drop this.
grpc::string beta_package_root; grpc::string beta_package_root;
// TODO(https://github.com/google/protobuf/issues/888): Drop this.
grpc::string import_prefix;
}; };
class PythonGrpcGenerator : public grpc::protobuf::compiler::CodeGenerator { class PythonGrpcGenerator : public grpc::protobuf::compiler::CodeGenerator {

@ -138,7 +138,7 @@ static grpc_error *client_init_call_elem(grpc_exec_ctx *exec_ctx,
static void client_destroy_call_elem(grpc_exec_ctx *exec_ctx, static void client_destroy_call_elem(grpc_exec_ctx *exec_ctx,
grpc_call_element *elem, grpc_call_element *elem,
const grpc_call_final_info *final_info, const grpc_call_final_info *final_info,
void *ignored) { grpc_closure *ignored) {
call_data *d = elem->call_data; call_data *d = elem->call_data;
GPR_ASSERT(d != NULL); GPR_ASSERT(d != NULL);
/* TODO(hongyu): record rpc client stats and census_rpc_end_op here */ /* TODO(hongyu): record rpc client stats and census_rpc_end_op here */
@ -160,7 +160,7 @@ static grpc_error *server_init_call_elem(grpc_exec_ctx *exec_ctx,
static void server_destroy_call_elem(grpc_exec_ctx *exec_ctx, static void server_destroy_call_elem(grpc_exec_ctx *exec_ctx,
grpc_call_element *elem, grpc_call_element *elem,
const grpc_call_final_info *final_info, const grpc_call_final_info *final_info,
void *ignored) { grpc_closure *ignored) {
call_data *d = elem->call_data; call_data *d = elem->call_data;
GPR_ASSERT(d != NULL); GPR_ASSERT(d != NULL);
/* TODO(hongyu): record rpc server stats and census_tracing_end_op here */ /* TODO(hongyu): record rpc server stats and census_tracing_end_op here */

@ -71,7 +71,8 @@
*/ */
typedef enum { typedef enum {
WAIT_FOR_READY_UNSET, /* zero so it can be default initialized */
WAIT_FOR_READY_UNSET = 0,
WAIT_FOR_READY_FALSE, WAIT_FOR_READY_FALSE,
WAIT_FOR_READY_TRUE WAIT_FOR_READY_TRUE
} wait_for_ready_value; } wait_for_ready_value;
@ -631,7 +632,8 @@ static void cc_destroy_channel_elem(grpc_exec_ctx *exec_ctx,
#define CANCELLED_CALL ((grpc_subchannel_call *)1) #define CANCELLED_CALL ((grpc_subchannel_call *)1)
typedef enum { typedef enum {
GRPC_SUBCHANNEL_CALL_HOLDER_NOT_CREATING, /* zero so that it can be default-initialized */
GRPC_SUBCHANNEL_CALL_HOLDER_NOT_CREATING = 0,
GRPC_SUBCHANNEL_CALL_HOLDER_PICKING_SUBCHANNEL GRPC_SUBCHANNEL_CALL_HOLDER_PICKING_SUBCHANNEL
} subchannel_creation_phase; } subchannel_creation_phase;
@ -653,13 +655,13 @@ typedef struct client_channel_call_data {
gpr_timespec call_start_time; gpr_timespec call_start_time;
gpr_timespec deadline; gpr_timespec deadline;
method_parameters *method_params; method_parameters *method_params;
grpc_closure read_service_config;
grpc_error *cancel_error; grpc_error *cancel_error;
/** either 0 for no call, 1 for cancelled, or a pointer to a /** either 0 for no call, 1 for cancelled, or a pointer to a
grpc_subchannel_call */ grpc_subchannel_call */
gpr_atm subchannel_call; gpr_atm subchannel_call;
gpr_arena *arena;
subchannel_creation_phase creation_phase; subchannel_creation_phase creation_phase;
grpc_connected_subchannel *connected_subchannel; grpc_connected_subchannel *connected_subchannel;
@ -726,6 +728,47 @@ static void retry_waiting_locked(grpc_exec_ctx *exec_ctx, call_data *calld) {
gpr_free(ops); gpr_free(ops);
} }
// Sets calld->method_params.
// If the method params specify a timeout, populates
// *per_method_deadline and returns true.
static bool set_call_method_params_from_service_config_locked(
grpc_exec_ctx *exec_ctx, grpc_call_element *elem,
gpr_timespec *per_method_deadline) {
channel_data *chand = elem->channel_data;
call_data *calld = elem->call_data;
if (chand->method_params_table != NULL) {
calld->method_params = grpc_method_config_table_get(
exec_ctx, chand->method_params_table, calld->path);
if (calld->method_params != NULL) {
method_parameters_ref(calld->method_params);
if (gpr_time_cmp(calld->method_params->timeout,
gpr_time_0(GPR_TIMESPAN)) != 0) {
*per_method_deadline =
gpr_time_add(calld->call_start_time, calld->method_params->timeout);
return true;
}
}
}
return false;
}
static void apply_final_configuration_locked(grpc_exec_ctx *exec_ctx,
grpc_call_element *elem) {
/* apply service-config level configuration to the call (now that we're
* certain it exists) */
call_data *calld = elem->call_data;
gpr_timespec per_method_deadline;
if (set_call_method_params_from_service_config_locked(exec_ctx, elem,
&per_method_deadline)) {
// If the deadline from the service config is shorter than the one
// from the client API, reset the deadline timer.
if (gpr_time_cmp(per_method_deadline, calld->deadline) < 0) {
calld->deadline = per_method_deadline;
grpc_deadline_state_reset(exec_ctx, elem, calld->deadline);
}
}
}
static void subchannel_ready_locked(grpc_exec_ctx *exec_ctx, void *arg, static void subchannel_ready_locked(grpc_exec_ctx *exec_ctx, void *arg,
grpc_error *error) { grpc_error *error) {
grpc_call_element *elem = arg; grpc_call_element *elem = arg;
@ -754,9 +797,14 @@ static void subchannel_ready_locked(grpc_exec_ctx *exec_ctx, void *arg,
} else { } else {
/* Create call on subchannel. */ /* Create call on subchannel. */
grpc_subchannel_call *subchannel_call = NULL; grpc_subchannel_call *subchannel_call = NULL;
const grpc_connected_subchannel_call_args call_args = {
.pollent = calld->pollent,
.path = calld->path,
.start_time = calld->call_start_time,
.deadline = calld->deadline,
.arena = calld->arena};
grpc_error *new_error = grpc_connected_subchannel_create_call( grpc_error *new_error = grpc_connected_subchannel_create_call(
exec_ctx, calld->connected_subchannel, calld->pollent, calld->path, exec_ctx, calld->connected_subchannel, &call_args, &subchannel_call);
calld->call_start_time, calld->deadline, &subchannel_call);
if (new_error != GRPC_ERROR_NONE) { if (new_error != GRPC_ERROR_NONE) {
new_error = grpc_error_add_child(new_error, error); new_error = grpc_error_add_child(new_error, error);
subchannel_call = CANCELLED_CALL; subchannel_call = CANCELLED_CALL;
@ -851,6 +899,7 @@ static bool pick_subchannel_locked(
} }
GPR_ASSERT(error == GRPC_ERROR_NONE); GPR_ASSERT(error == GRPC_ERROR_NONE);
if (chand->lb_policy != NULL) { if (chand->lb_policy != NULL) {
apply_final_configuration_locked(exec_ctx, elem);
grpc_lb_policy *lb_policy = chand->lb_policy; grpc_lb_policy *lb_policy = chand->lb_policy;
GRPC_LB_POLICY_REF(lb_policy, "pick_subchannel"); GRPC_LB_POLICY_REF(lb_policy, "pick_subchannel");
// If the application explicitly set wait_for_ready, use that. // If the application explicitly set wait_for_ready, use that.
@ -982,9 +1031,14 @@ static void start_transport_stream_op_locked_inner(grpc_exec_ctx *exec_ctx,
if (calld->creation_phase == GRPC_SUBCHANNEL_CALL_HOLDER_NOT_CREATING && if (calld->creation_phase == GRPC_SUBCHANNEL_CALL_HOLDER_NOT_CREATING &&
calld->connected_subchannel != NULL) { calld->connected_subchannel != NULL) {
grpc_subchannel_call *subchannel_call = NULL; grpc_subchannel_call *subchannel_call = NULL;
const grpc_connected_subchannel_call_args call_args = {
.pollent = calld->pollent,
.path = calld->path,
.start_time = calld->call_start_time,
.deadline = calld->deadline,
.arena = calld->arena};
grpc_error *error = grpc_connected_subchannel_create_call( grpc_error *error = grpc_connected_subchannel_create_call(
exec_ctx, calld->connected_subchannel, calld->pollent, calld->path, exec_ctx, calld->connected_subchannel, &call_args, &subchannel_call);
calld->call_start_time, calld->deadline, &subchannel_call);
if (error != GRPC_ERROR_NONE) { if (error != GRPC_ERROR_NONE) {
subchannel_call = CANCELLED_CALL; subchannel_call = CANCELLED_CALL;
fail_locked(exec_ctx, calld, GRPC_ERROR_REF(error)); fail_locked(exec_ctx, calld, GRPC_ERROR_REF(error));
@ -1060,114 +1114,19 @@ static void cc_start_transport_stream_op(grpc_exec_ctx *exec_ctx,
GPR_TIMER_END("cc_start_transport_stream_op", 0); GPR_TIMER_END("cc_start_transport_stream_op", 0);
} }
// Sets calld->method_params.
// If the method params specify a timeout, populates
// *per_method_deadline and returns true.
static bool set_call_method_params_from_service_config_locked(
grpc_exec_ctx *exec_ctx, grpc_call_element *elem,
gpr_timespec *per_method_deadline) {
channel_data *chand = elem->channel_data;
call_data *calld = elem->call_data;
if (chand->method_params_table != NULL) {
calld->method_params = grpc_method_config_table_get(
exec_ctx, chand->method_params_table, calld->path);
if (calld->method_params != NULL) {
method_parameters_ref(calld->method_params);
if (gpr_time_cmp(calld->method_params->timeout,
gpr_time_0(GPR_TIMESPAN)) != 0) {
*per_method_deadline =
gpr_time_add(calld->call_start_time, calld->method_params->timeout);
return true;
}
}
}
return false;
}
// Gets data from the service config. Invoked when the resolver returns
// its initial result.
static void read_service_config_locked(grpc_exec_ctx *exec_ctx, void *arg,
grpc_error *error) {
grpc_call_element *elem = arg;
call_data *calld = elem->call_data;
// If this is an error, there's no point in looking at the service config.
if (error == GRPC_ERROR_NONE) {
gpr_timespec per_method_deadline;
if (set_call_method_params_from_service_config_locked(
exec_ctx, elem, &per_method_deadline)) {
// If the deadline from the service config is shorter than the one
// from the client API, reset the deadline timer.
if (gpr_time_cmp(per_method_deadline, calld->deadline) < 0) {
calld->deadline = per_method_deadline;
grpc_deadline_state_reset(exec_ctx, elem, calld->deadline);
}
}
}
GRPC_CALL_STACK_UNREF(exec_ctx, calld->owning_call, "read_service_config");
}
static void initial_read_service_config_locked(grpc_exec_ctx *exec_ctx,
void *arg,
grpc_error *error_ignored) {
grpc_call_element *elem = arg;
channel_data *chand = elem->channel_data;
call_data *calld = elem->call_data;
// If the resolver has already returned results, then we can access
// the service config parameters immediately. Otherwise, we need to
// defer that work until the resolver returns an initial result.
if (chand->lb_policy != NULL) {
// We already have a resolver result, so check for service config.
gpr_timespec per_method_deadline;
if (set_call_method_params_from_service_config_locked(
exec_ctx, elem, &per_method_deadline)) {
calld->deadline = gpr_time_min(calld->deadline, per_method_deadline);
}
} else {
// We don't yet have a resolver result, so register a callback to
// get the service config data once the resolver returns.
// Take a reference to the call stack to be owned by the callback.
GRPC_CALL_STACK_REF(calld->owning_call, "read_service_config");
grpc_closure_init(&calld->read_service_config, read_service_config_locked,
elem, grpc_combiner_scheduler(chand->combiner, false));
grpc_closure_list_append(&chand->waiting_for_config_closures,
&calld->read_service_config, GRPC_ERROR_NONE);
}
// Start the deadline timer with the current deadline value. If we
// do not yet have service config data, then the timer may be reset
// later.
grpc_deadline_state_start(exec_ctx, elem, calld->deadline);
GRPC_CALL_STACK_UNREF(exec_ctx, calld->owning_call,
"initial_read_service_config");
}
/* Constructor for call_data */ /* Constructor for call_data */
static grpc_error *cc_init_call_elem(grpc_exec_ctx *exec_ctx, static grpc_error *cc_init_call_elem(grpc_exec_ctx *exec_ctx,
grpc_call_element *elem, grpc_call_element *elem,
const grpc_call_element_args *args) { const grpc_call_element_args *args) {
channel_data *chand = elem->channel_data;
call_data *calld = elem->call_data; call_data *calld = elem->call_data;
// Initialize data members. // Initialize data members.
grpc_deadline_state_init(exec_ctx, elem, args->call_stack); grpc_deadline_state_init(exec_ctx, elem, args->call_stack);
calld->path = grpc_slice_ref_internal(args->path); calld->path = grpc_slice_ref_internal(args->path);
calld->call_start_time = args->start_time; calld->call_start_time = args->start_time;
calld->deadline = gpr_convert_clock_type(args->deadline, GPR_CLOCK_MONOTONIC); calld->deadline = gpr_convert_clock_type(args->deadline, GPR_CLOCK_MONOTONIC);
calld->method_params = NULL;
calld->cancel_error = GRPC_ERROR_NONE;
gpr_atm_rel_store(&calld->subchannel_call, 0);
calld->connected_subchannel = NULL;
calld->waiting_ops = NULL;
calld->waiting_ops_count = 0;
calld->waiting_ops_capacity = 0;
calld->creation_phase = GRPC_SUBCHANNEL_CALL_HOLDER_NOT_CREATING;
calld->owning_call = args->call_stack; calld->owning_call = args->call_stack;
calld->pollent = NULL; calld->arena = args->arena;
GRPC_CALL_STACK_REF(calld->owning_call, "initial_read_service_config"); grpc_deadline_state_start(exec_ctx, elem, calld->deadline);
grpc_closure_sched(
exec_ctx,
grpc_closure_init(&calld->read_service_config,
initial_read_service_config_locked, elem,
grpc_combiner_scheduler(chand->combiner, false)),
GRPC_ERROR_NONE);
return GRPC_ERROR_NONE; return GRPC_ERROR_NONE;
} }
@ -1175,7 +1134,7 @@ static grpc_error *cc_init_call_elem(grpc_exec_ctx *exec_ctx,
static void cc_destroy_call_elem(grpc_exec_ctx *exec_ctx, static void cc_destroy_call_elem(grpc_exec_ctx *exec_ctx,
grpc_call_element *elem, grpc_call_element *elem,
const grpc_call_final_info *final_info, const grpc_call_final_info *final_info,
void *and_free_memory) { grpc_closure *then_schedule_closure) {
call_data *calld = elem->call_data; call_data *calld = elem->call_data;
grpc_deadline_state_destroy(exec_ctx, elem); grpc_deadline_state_destroy(exec_ctx, elem);
grpc_slice_unref_internal(exec_ctx, calld->path); grpc_slice_unref_internal(exec_ctx, calld->path);
@ -1185,6 +1144,8 @@ static void cc_destroy_call_elem(grpc_exec_ctx *exec_ctx,
GRPC_ERROR_UNREF(calld->cancel_error); GRPC_ERROR_UNREF(calld->cancel_error);
grpc_subchannel_call *call = GET_CALL(calld); grpc_subchannel_call *call = GET_CALL(calld);
if (call != NULL && call != CANCELLED_CALL) { if (call != NULL && call != CANCELLED_CALL) {
grpc_subchannel_call_set_cleanup_closure(call, then_schedule_closure);
then_schedule_closure = NULL;
GRPC_SUBCHANNEL_CALL_UNREF(exec_ctx, call, "client_channel_destroy_call"); GRPC_SUBCHANNEL_CALL_UNREF(exec_ctx, call, "client_channel_destroy_call");
} }
GPR_ASSERT(calld->creation_phase == GRPC_SUBCHANNEL_CALL_HOLDER_NOT_CREATING); GPR_ASSERT(calld->creation_phase == GRPC_SUBCHANNEL_CALL_HOLDER_NOT_CREATING);
@ -1194,7 +1155,7 @@ static void cc_destroy_call_elem(grpc_exec_ctx *exec_ctx,
"picked"); "picked");
} }
gpr_free(calld->waiting_ops); gpr_free(calld->waiting_ops);
gpr_free(and_free_memory); grpc_closure_sched(exec_ctx, then_schedule_closure, GRPC_ERROR_NONE);
} }
static void cc_set_pollset_or_pollset_set(grpc_exec_ctx *exec_ctx, static void cc_set_pollset_or_pollset_set(grpc_exec_ctx *exec_ctx,

@ -128,6 +128,7 @@ int parse_ipv6(grpc_uri *uri, grpc_resolved_address *resolved_addr) {
GPR_ASSERT(host_end >= host); GPR_ASSERT(host_end >= host);
char host_without_scope[INET6_ADDRSTRLEN]; char host_without_scope[INET6_ADDRSTRLEN];
size_t host_without_scope_len = (size_t)(host_end - host); size_t host_without_scope_len = (size_t)(host_end - host);
uint32_t sin6_scope_id = 0;
strncpy(host_without_scope, host, host_without_scope_len); strncpy(host_without_scope, host, host_without_scope_len);
host_without_scope[host_without_scope_len] = '\0'; host_without_scope[host_without_scope_len] = '\0';
if (inet_pton(AF_INET6, host_without_scope, &in6->sin6_addr) == 0) { if (inet_pton(AF_INET6, host_without_scope, &in6->sin6_addr) == 0) {
@ -136,10 +137,12 @@ int parse_ipv6(grpc_uri *uri, grpc_resolved_address *resolved_addr) {
} }
if (gpr_parse_bytes_to_uint32(host_end + 1, if (gpr_parse_bytes_to_uint32(host_end + 1,
strlen(host) - host_without_scope_len - 1, strlen(host) - host_without_scope_len - 1,
&in6->sin6_scope_id) == 0) { &sin6_scope_id) == 0) {
gpr_log(GPR_ERROR, "invalid ipv6 scope id: '%s'", host_end + 1); gpr_log(GPR_ERROR, "invalid ipv6 scope id: '%s'", host_end + 1);
goto done; goto done;
} }
// Handle "sin6_scope_id" being type "u_long". See grpc issue ##10027.
in6->sin6_scope_id = sin6_scope_id;
} else { } else {
if (inet_pton(AF_INET6, host, &in6->sin6_addr) == 0) { if (inet_pton(AF_INET6, host, &in6->sin6_addr) == 0) {
gpr_log(GPR_ERROR, "invalid ipv6 address: '%s'", host); gpr_log(GPR_ERROR, "invalid ipv6 address: '%s'", host);

@ -94,6 +94,14 @@ static void grpc_proxy_mapper_list_destroy(grpc_proxy_mapper_list* list) {
grpc_proxy_mapper_destroy(list->list[i]); grpc_proxy_mapper_destroy(list->list[i]);
} }
gpr_free(list->list); gpr_free(list->list);
// Clean up in case we re-initialze later.
// TODO(ctiller): This should ideally live in
// grpc_proxy_mapper_registry_init(). However, if we did this there,
// then we would do it AFTER we start registering proxy mappers from
// third-party plugins, so they'd never show up (and would leak memory).
// We probably need some sort of dependency system for plugins to fix
// this.
memset(list, 0, sizeof(*list));
} }
// //
@ -102,9 +110,7 @@ static void grpc_proxy_mapper_list_destroy(grpc_proxy_mapper_list* list) {
static grpc_proxy_mapper_list g_proxy_mapper_list; static grpc_proxy_mapper_list g_proxy_mapper_list;
void grpc_proxy_mapper_registry_init() { void grpc_proxy_mapper_registry_init() {}
memset(&g_proxy_mapper_list, 0, sizeof(g_proxy_mapper_list));
}
void grpc_proxy_mapper_registry_shutdown() { void grpc_proxy_mapper_registry_shutdown() {
grpc_proxy_mapper_list_destroy(&g_proxy_mapper_list); grpc_proxy_mapper_list_destroy(&g_proxy_mapper_list);

@ -148,6 +148,7 @@ struct grpc_subchannel {
struct grpc_subchannel_call { struct grpc_subchannel_call {
grpc_connected_subchannel *connection; grpc_connected_subchannel *connection;
grpc_closure *schedule_closure_after_destroy;
}; };
#define SUBCHANNEL_CALL_TO_CALL_STACK(call) ((grpc_call_stack *)((call) + 1)) #define SUBCHANNEL_CALL_TO_CALL_STACK(call) ((grpc_call_stack *)((call) + 1))
@ -340,17 +341,15 @@ grpc_subchannel *grpc_subchannel_create(grpc_exec_ctx *exec_ctx,
GPR_ASSERT(new_address != NULL); GPR_ASSERT(new_address != NULL);
gpr_free(addr); gpr_free(addr);
addr = new_address; addr = new_address;
if (new_args != NULL) c->args = new_args;
} }
if (c->args == NULL) {
static const char *keys_to_remove[] = {GRPC_ARG_SUBCHANNEL_ADDRESS}; static const char *keys_to_remove[] = {GRPC_ARG_SUBCHANNEL_ADDRESS};
grpc_arg new_arg = grpc_create_subchannel_address_arg(addr); grpc_arg new_arg = grpc_create_subchannel_address_arg(addr);
gpr_free(addr);
c->args = grpc_channel_args_copy_and_add_and_remove( c->args = grpc_channel_args_copy_and_add_and_remove(
args->args, keys_to_remove, GPR_ARRAY_SIZE(keys_to_remove), &new_arg, new_args != NULL ? new_args : args->args, keys_to_remove,
1); GPR_ARRAY_SIZE(keys_to_remove), &new_arg, 1);
gpr_free(new_arg.value.string); gpr_free(new_arg.value.string);
} if (new_args != NULL) grpc_channel_args_destroy(exec_ctx, new_args);
gpr_free(addr);
c->root_external_state_watcher.next = c->root_external_state_watcher.prev = c->root_external_state_watcher.next = c->root_external_state_watcher.prev =
&c->root_external_state_watcher; &c->root_external_state_watcher;
grpc_closure_init(&c->connected, subchannel_connected, c, grpc_closure_init(&c->connected, subchannel_connected, c,
@ -719,13 +718,22 @@ static void subchannel_connected(grpc_exec_ctx *exec_ctx, void *arg,
static void subchannel_call_destroy(grpc_exec_ctx *exec_ctx, void *call, static void subchannel_call_destroy(grpc_exec_ctx *exec_ctx, void *call,
grpc_error *error) { grpc_error *error) {
grpc_subchannel_call *c = call; grpc_subchannel_call *c = call;
GPR_ASSERT(c->schedule_closure_after_destroy != NULL);
GPR_TIMER_BEGIN("grpc_subchannel_call_unref.destroy", 0); GPR_TIMER_BEGIN("grpc_subchannel_call_unref.destroy", 0);
grpc_connected_subchannel *connection = c->connection; grpc_connected_subchannel *connection = c->connection;
grpc_call_stack_destroy(exec_ctx, SUBCHANNEL_CALL_TO_CALL_STACK(c), NULL, c); grpc_call_stack_destroy(exec_ctx, SUBCHANNEL_CALL_TO_CALL_STACK(c), NULL,
c->schedule_closure_after_destroy);
GRPC_CONNECTED_SUBCHANNEL_UNREF(exec_ctx, connection, "subchannel_call"); GRPC_CONNECTED_SUBCHANNEL_UNREF(exec_ctx, connection, "subchannel_call");
GPR_TIMER_END("grpc_subchannel_call_unref.destroy", 0); GPR_TIMER_END("grpc_subchannel_call_unref.destroy", 0);
} }
void grpc_subchannel_call_set_cleanup_closure(grpc_subchannel_call *call,
grpc_closure *closure) {
GPR_ASSERT(call->schedule_closure_after_destroy == NULL);
GPR_ASSERT(closure != NULL);
call->schedule_closure_after_destroy = closure;
}
void grpc_subchannel_call_ref( void grpc_subchannel_call_ref(
grpc_subchannel_call *c GRPC_SUBCHANNEL_REF_EXTRA_ARGS) { grpc_subchannel_call *c GRPC_SUBCHANNEL_REF_EXTRA_ARGS) {
GRPC_CALL_STACK_REF(SUBCHANNEL_CALL_TO_CALL_STACK(c), REF_REASON); GRPC_CALL_STACK_REF(SUBCHANNEL_CALL_TO_CALL_STACK(c), REF_REASON);
@ -761,15 +769,22 @@ grpc_connected_subchannel *grpc_subchannel_get_connected_subchannel(
grpc_error *grpc_connected_subchannel_create_call( grpc_error *grpc_connected_subchannel_create_call(
grpc_exec_ctx *exec_ctx, grpc_connected_subchannel *con, grpc_exec_ctx *exec_ctx, grpc_connected_subchannel *con,
grpc_polling_entity *pollent, grpc_slice path, gpr_timespec start_time, const grpc_connected_subchannel_call_args *args,
gpr_timespec deadline, grpc_subchannel_call **call) { grpc_subchannel_call **call) {
grpc_channel_stack *chanstk = CHANNEL_STACK_FROM_CONNECTION(con); grpc_channel_stack *chanstk = CHANNEL_STACK_FROM_CONNECTION(con);
*call = gpr_zalloc(sizeof(grpc_subchannel_call) + chanstk->call_stack_size); *call = gpr_arena_alloc(
args->arena, sizeof(grpc_subchannel_call) + chanstk->call_stack_size);
grpc_call_stack *callstk = SUBCHANNEL_CALL_TO_CALL_STACK(*call); grpc_call_stack *callstk = SUBCHANNEL_CALL_TO_CALL_STACK(*call);
(*call)->connection = con; // Ref is added below. (*call)->connection = con; // Ref is added below.
grpc_error *error = const grpc_call_element_args call_args = {.call_stack = callstk,
grpc_call_stack_init(exec_ctx, chanstk, 1, subchannel_call_destroy, *call, .server_transport_data = NULL,
NULL, NULL, path, start_time, deadline, callstk); .context = NULL,
.path = args->path,
.start_time = args->start_time,
.deadline = args->deadline,
.arena = args->arena};
grpc_error *error = grpc_call_stack_init(
exec_ctx, chanstk, 1, subchannel_call_destroy, *call, &call_args);
if (error != GRPC_ERROR_NONE) { if (error != GRPC_ERROR_NONE) {
const char *error_string = grpc_error_string(error); const char *error_string = grpc_error_string(error);
gpr_log(GPR_ERROR, "error: %s", error_string); gpr_log(GPR_ERROR, "error: %s", error_string);
@ -778,7 +793,7 @@ grpc_error *grpc_connected_subchannel_create_call(
return error; return error;
} }
GRPC_CONNECTED_SUBCHANNEL_REF(con, "subchannel_call"); GRPC_CONNECTED_SUBCHANNEL_REF(con, "subchannel_call");
grpc_call_stack_set_pollset_or_pollset_set(exec_ctx, callstk, pollent); grpc_call_stack_set_pollset_or_pollset_set(exec_ctx, callstk, args->pollent);
return GRPC_ERROR_NONE; return GRPC_ERROR_NONE;
} }

@ -37,6 +37,7 @@
#include "src/core/ext/client_channel/connector.h" #include "src/core/ext/client_channel/connector.h"
#include "src/core/lib/channel/channel_stack.h" #include "src/core/lib/channel/channel_stack.h"
#include "src/core/lib/iomgr/polling_entity.h" #include "src/core/lib/iomgr/polling_entity.h"
#include "src/core/lib/support/arena.h"
#include "src/core/lib/transport/connectivity_state.h" #include "src/core/lib/transport/connectivity_state.h"
#include "src/core/lib/transport/metadata.h" #include "src/core/lib/transport/metadata.h"
@ -112,10 +113,18 @@ void grpc_subchannel_call_unref(grpc_exec_ctx *exec_ctx,
GRPC_SUBCHANNEL_REF_EXTRA_ARGS); GRPC_SUBCHANNEL_REF_EXTRA_ARGS);
/** construct a subchannel call */ /** construct a subchannel call */
typedef struct {
grpc_polling_entity *pollent;
grpc_slice path;
gpr_timespec start_time;
gpr_timespec deadline;
gpr_arena *arena;
} grpc_connected_subchannel_call_args;
grpc_error *grpc_connected_subchannel_create_call( grpc_error *grpc_connected_subchannel_create_call(
grpc_exec_ctx *exec_ctx, grpc_connected_subchannel *connected_subchannel, grpc_exec_ctx *exec_ctx, grpc_connected_subchannel *connected_subchannel,
grpc_polling_entity *pollent, grpc_slice path, gpr_timespec start_time, const grpc_connected_subchannel_call_args *args,
gpr_timespec deadline, grpc_subchannel_call **subchannel_call); grpc_subchannel_call **subchannel_call);
/** process a transport level op */ /** process a transport level op */
void grpc_connected_subchannel_process_transport_op( void grpc_connected_subchannel_process_transport_op(
@ -154,6 +163,11 @@ void grpc_subchannel_call_process_op(grpc_exec_ctx *exec_ctx,
char *grpc_subchannel_call_get_peer(grpc_exec_ctx *exec_ctx, char *grpc_subchannel_call_get_peer(grpc_exec_ctx *exec_ctx,
grpc_subchannel_call *subchannel_call); grpc_subchannel_call *subchannel_call);
/** Must be called once per call. Sets the 'then_schedule_closure' argument for
call stack destruction. */
void grpc_subchannel_call_set_cleanup_closure(
grpc_subchannel_call *subchannel_call, grpc_closure *closure);
grpc_call_stack *grpc_subchannel_call_get_call_stack( grpc_call_stack *grpc_subchannel_call_get_call_stack(
grpc_subchannel_call *subchannel_call); grpc_subchannel_call *subchannel_call);

@ -123,7 +123,7 @@ static grpc_error *init_call_elem(grpc_exec_ctx *exec_ctx,
/* Destructor for call_data */ /* Destructor for call_data */
static void destroy_call_elem(grpc_exec_ctx *exec_ctx, grpc_call_element *elem, static void destroy_call_elem(grpc_exec_ctx *exec_ctx, grpc_call_element *elem,
const grpc_call_final_info *final_info, const grpc_call_final_info *final_info,
void *ignored) { grpc_closure *ignored) {
call_data *calld = elem->call_data; call_data *calld = elem->call_data;
/* TODO(dgq): do something with the data /* TODO(dgq): do something with the data

@ -512,6 +512,10 @@ static void close_transport_locked(grpc_exec_ctx *exec_ctx,
grpc_chttp2_transport *t, grpc_chttp2_transport *t,
grpc_error *error) { grpc_error *error) {
if (!t->closed) { if (!t->closed) {
if (!grpc_error_has_clear_grpc_status(error)) {
error = grpc_error_set_int(error, GRPC_ERROR_INT_GRPC_STATUS,
GRPC_STATUS_UNAVAILABLE);
}
if (t->write_state != GRPC_CHTTP2_WRITE_STATE_IDLE) { if (t->write_state != GRPC_CHTTP2_WRITE_STATE_IDLE) {
if (t->close_transport_on_writes_finished == NULL) { if (t->close_transport_on_writes_finished == NULL) {
t->close_transport_on_writes_finished = t->close_transport_on_writes_finished =
@ -521,10 +525,6 @@ static void close_transport_locked(grpc_exec_ctx *exec_ctx,
grpc_error_add_child(t->close_transport_on_writes_finished, error); grpc_error_add_child(t->close_transport_on_writes_finished, error);
return; return;
} }
if (!grpc_error_has_clear_grpc_status(error)) {
error = grpc_error_set_int(error, GRPC_ERROR_INT_GRPC_STATUS,
GRPC_STATUS_UNAVAILABLE);
}
t->closed = 1; t->closed = 1;
connectivity_state_set(exec_ctx, t, GRPC_CHANNEL_SHUTDOWN, connectivity_state_set(exec_ctx, t, GRPC_CHANNEL_SHUTDOWN,
GRPC_ERROR_REF(error), "close_transport"); GRPC_ERROR_REF(error), "close_transport");
@ -576,7 +576,7 @@ void grpc_chttp2_stream_unref(grpc_exec_ctx *exec_ctx, grpc_chttp2_stream *s) {
static int init_stream(grpc_exec_ctx *exec_ctx, grpc_transport *gt, static int init_stream(grpc_exec_ctx *exec_ctx, grpc_transport *gt,
grpc_stream *gs, grpc_stream_refcount *refcount, grpc_stream *gs, grpc_stream_refcount *refcount,
const void *server_data) { const void *server_data, gpr_arena *arena) {
GPR_TIMER_BEGIN("init_stream", 0); GPR_TIMER_BEGIN("init_stream", 0);
grpc_chttp2_transport *t = (grpc_chttp2_transport *)gt; grpc_chttp2_transport *t = (grpc_chttp2_transport *)gt;
grpc_chttp2_stream *s = (grpc_chttp2_stream *)gs; grpc_chttp2_stream *s = (grpc_chttp2_stream *)gs;
@ -589,8 +589,8 @@ static int init_stream(grpc_exec_ctx *exec_ctx, grpc_transport *gt,
gpr_ref_init(&s->active_streams, 1); gpr_ref_init(&s->active_streams, 1);
GRPC_CHTTP2_STREAM_REF(s, "chttp2"); GRPC_CHTTP2_STREAM_REF(s, "chttp2");
grpc_chttp2_incoming_metadata_buffer_init(&s->metadata_buffer[0]); grpc_chttp2_incoming_metadata_buffer_init(&s->metadata_buffer[0], arena);
grpc_chttp2_incoming_metadata_buffer_init(&s->metadata_buffer[1]); grpc_chttp2_incoming_metadata_buffer_init(&s->metadata_buffer[1], arena);
grpc_chttp2_data_parser_init(&s->data_parser); grpc_chttp2_data_parser_init(&s->data_parser);
grpc_slice_buffer_init(&s->flow_controlled_buffer); grpc_slice_buffer_init(&s->flow_controlled_buffer);
s->deadline = gpr_inf_future(GPR_CLOCK_MONOTONIC); s->deadline = gpr_inf_future(GPR_CLOCK_MONOTONIC);
@ -666,16 +666,17 @@ static void destroy_stream_locked(grpc_exec_ctx *exec_ctx, void *sp,
GPR_TIMER_END("destroy_stream", 0); GPR_TIMER_END("destroy_stream", 0);
gpr_free(s->destroy_stream_arg); grpc_closure_sched(exec_ctx, s->destroy_stream_arg, GRPC_ERROR_NONE);
} }
static void destroy_stream(grpc_exec_ctx *exec_ctx, grpc_transport *gt, static void destroy_stream(grpc_exec_ctx *exec_ctx, grpc_transport *gt,
grpc_stream *gs, void *and_free_memory) { grpc_stream *gs,
grpc_closure *then_schedule_closure) {
GPR_TIMER_BEGIN("destroy_stream", 0); GPR_TIMER_BEGIN("destroy_stream", 0);
grpc_chttp2_transport *t = (grpc_chttp2_transport *)gt; grpc_chttp2_transport *t = (grpc_chttp2_transport *)gt;
grpc_chttp2_stream *s = (grpc_chttp2_stream *)gs; grpc_chttp2_stream *s = (grpc_chttp2_stream *)gs;
s->destroy_stream_arg = and_free_memory; s->destroy_stream_arg = then_schedule_closure;
grpc_closure_sched( grpc_closure_sched(
exec_ctx, exec_ctx,
grpc_closure_init(&s->destroy_stream, destroy_stream_locked, s, grpc_closure_init(&s->destroy_stream, destroy_stream_locked, s,
@ -1637,15 +1638,19 @@ void grpc_chttp2_fake_status(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t,
s->recv_trailing_metadata_finished != NULL) { s->recv_trailing_metadata_finished != NULL) {
char status_string[GPR_LTOA_MIN_BUFSIZE]; char status_string[GPR_LTOA_MIN_BUFSIZE];
gpr_ltoa(status, status_string); gpr_ltoa(status, status_string);
GRPC_LOG_IF_ERROR("add_status",
grpc_chttp2_incoming_metadata_buffer_replace_or_add( grpc_chttp2_incoming_metadata_buffer_replace_or_add(
exec_ctx, &s->metadata_buffer[1], exec_ctx, &s->metadata_buffer[1],
grpc_mdelem_from_slices(exec_ctx, GRPC_MDSTR_GRPC_STATUS, grpc_mdelem_from_slices(
grpc_slice_from_copied_string(status_string))); exec_ctx, GRPC_MDSTR_GRPC_STATUS,
grpc_slice_from_copied_string(status_string))));
if (msg != NULL) { if (msg != NULL) {
GRPC_LOG_IF_ERROR(
"add_status_message",
grpc_chttp2_incoming_metadata_buffer_replace_or_add( grpc_chttp2_incoming_metadata_buffer_replace_or_add(
exec_ctx, &s->metadata_buffer[1], exec_ctx, &s->metadata_buffer[1],
grpc_mdelem_from_slices(exec_ctx, GRPC_MDSTR_GRPC_MESSAGE, grpc_mdelem_from_slices(exec_ctx, GRPC_MDSTR_GRPC_MESSAGE,
grpc_slice_from_copied_string(msg))); grpc_slice_from_copied_string(msg))));
} }
s->published_metadata[1] = GRPC_METADATA_SYNTHESIZED_FROM_FAKE; s->published_metadata[1] = GRPC_METADATA_SYNTHESIZED_FROM_FAKE;
grpc_chttp2_maybe_complete_recv_trailing_metadata(exec_ctx, t, s); grpc_chttp2_maybe_complete_recv_trailing_metadata(exec_ctx, t, s);

@ -91,7 +91,7 @@ grpc_error *grpc_chttp2_ping_parser_parse(grpc_exec_ctx *exec_ctx, void *parser,
grpc_chttp2_ping_parser *p = parser; grpc_chttp2_ping_parser *p = parser;
while (p->byte != 8 && cur != end) { while (p->byte != 8 && cur != end) {
p->opaque_8bytes |= (((uint64_t)*cur) << (8 * p->byte)); p->opaque_8bytes |= (((uint64_t)*cur) << (56 - 8 * p->byte));
cur++; cur++;
p->byte++; p->byte++;
} }

@ -41,69 +41,48 @@
#include <grpc/support/log.h> #include <grpc/support/log.h>
void grpc_chttp2_incoming_metadata_buffer_init( void grpc_chttp2_incoming_metadata_buffer_init(
grpc_chttp2_incoming_metadata_buffer *buffer) { grpc_chttp2_incoming_metadata_buffer *buffer, gpr_arena *arena) {
buffer->deadline = gpr_inf_future(GPR_CLOCK_REALTIME); buffer->arena = arena;
grpc_metadata_batch_init(&buffer->batch);
buffer->batch.deadline = gpr_inf_future(GPR_CLOCK_REALTIME);
} }
void grpc_chttp2_incoming_metadata_buffer_destroy( void grpc_chttp2_incoming_metadata_buffer_destroy(
grpc_exec_ctx *exec_ctx, grpc_chttp2_incoming_metadata_buffer *buffer) { grpc_exec_ctx *exec_ctx, grpc_chttp2_incoming_metadata_buffer *buffer) {
size_t i; grpc_metadata_batch_destroy(exec_ctx, &buffer->batch);
if (!buffer->published) {
for (i = 0; i < buffer->count; i++) {
GRPC_MDELEM_UNREF(exec_ctx, buffer->elems[i].md);
}
}
gpr_free(buffer->elems);
} }
void grpc_chttp2_incoming_metadata_buffer_add( grpc_error *grpc_chttp2_incoming_metadata_buffer_add(
grpc_chttp2_incoming_metadata_buffer *buffer, grpc_mdelem elem) { grpc_exec_ctx *exec_ctx, grpc_chttp2_incoming_metadata_buffer *buffer,
GPR_ASSERT(!buffer->published); grpc_mdelem elem) {
if (buffer->capacity == buffer->count) {
buffer->capacity = GPR_MAX(8, 2 * buffer->capacity);
buffer->elems =
gpr_realloc(buffer->elems, sizeof(*buffer->elems) * buffer->capacity);
}
buffer->elems[buffer->count++].md = elem;
buffer->size += GRPC_MDELEM_LENGTH(elem); buffer->size += GRPC_MDELEM_LENGTH(elem);
return grpc_metadata_batch_add_tail(
exec_ctx, &buffer->batch,
gpr_arena_alloc(buffer->arena, sizeof(grpc_linked_mdelem)), elem);
} }
void grpc_chttp2_incoming_metadata_buffer_replace_or_add( grpc_error *grpc_chttp2_incoming_metadata_buffer_replace_or_add(
grpc_exec_ctx *exec_ctx, grpc_chttp2_incoming_metadata_buffer *buffer, grpc_exec_ctx *exec_ctx, grpc_chttp2_incoming_metadata_buffer *buffer,
grpc_mdelem elem) { grpc_mdelem elem) {
for (size_t i = 0; i < buffer->count; i++) { for (grpc_linked_mdelem *l = buffer->batch.list.head; l != NULL;
if (grpc_slice_eq(GRPC_MDKEY(buffer->elems[i].md), GRPC_MDKEY(elem))) { l = l->next) {
GRPC_MDELEM_UNREF(exec_ctx, buffer->elems[i].md); if (grpc_slice_eq(GRPC_MDKEY(l->md), GRPC_MDKEY(elem))) {
buffer->elems[i].md = elem; GRPC_MDELEM_UNREF(exec_ctx, l->md);
return; l->md = elem;
return GRPC_ERROR_NONE;
} }
} }
grpc_chttp2_incoming_metadata_buffer_add(buffer, elem); return grpc_chttp2_incoming_metadata_buffer_add(exec_ctx, buffer, elem);
} }
void grpc_chttp2_incoming_metadata_buffer_set_deadline( void grpc_chttp2_incoming_metadata_buffer_set_deadline(
grpc_chttp2_incoming_metadata_buffer *buffer, gpr_timespec deadline) { grpc_chttp2_incoming_metadata_buffer *buffer, gpr_timespec deadline) {
GPR_ASSERT(!buffer->published); buffer->batch.deadline = deadline;
buffer->deadline = deadline;
} }
void grpc_chttp2_incoming_metadata_buffer_publish( void grpc_chttp2_incoming_metadata_buffer_publish(
grpc_exec_ctx *exec_ctx, grpc_chttp2_incoming_metadata_buffer *buffer, grpc_exec_ctx *exec_ctx, grpc_chttp2_incoming_metadata_buffer *buffer,
grpc_metadata_batch *batch) { grpc_metadata_batch *batch) {
GPR_ASSERT(!buffer->published); *batch = buffer->batch;
buffer->published = 1; grpc_metadata_batch_init(&buffer->batch);
if (buffer->count > 0) {
size_t i;
for (i = 0; i < buffer->count; i++) {
/* TODO(ctiller): do something better here */
if (!GRPC_LOG_IF_ERROR("grpc_chttp2_incoming_metadata_buffer_publish",
grpc_metadata_batch_link_tail(
exec_ctx, batch, &buffer->elems[i]))) {
GRPC_MDELEM_UNREF(exec_ctx, buffer->elems[i].md);
}
}
} else {
batch->list.head = batch->list.tail = NULL;
}
batch->deadline = buffer->deadline;
} }

@ -37,28 +37,26 @@
#include "src/core/lib/transport/transport.h" #include "src/core/lib/transport/transport.h"
typedef struct { typedef struct {
grpc_linked_mdelem *elems; gpr_arena *arena;
size_t count; grpc_metadata_batch batch;
size_t capacity;
gpr_timespec deadline;
int published;
size_t size; // total size of metadata size_t size; // total size of metadata
} grpc_chttp2_incoming_metadata_buffer; } grpc_chttp2_incoming_metadata_buffer;
/** assumes everything initially zeroed */ /** assumes everything initially zeroed */
void grpc_chttp2_incoming_metadata_buffer_init( void grpc_chttp2_incoming_metadata_buffer_init(
grpc_chttp2_incoming_metadata_buffer *buffer); grpc_chttp2_incoming_metadata_buffer *buffer, gpr_arena *arena);
void grpc_chttp2_incoming_metadata_buffer_destroy( void grpc_chttp2_incoming_metadata_buffer_destroy(
grpc_exec_ctx *exec_ctx, grpc_chttp2_incoming_metadata_buffer *buffer); grpc_exec_ctx *exec_ctx, grpc_chttp2_incoming_metadata_buffer *buffer);
void grpc_chttp2_incoming_metadata_buffer_publish( void grpc_chttp2_incoming_metadata_buffer_publish(
grpc_exec_ctx *exec_ctx, grpc_chttp2_incoming_metadata_buffer *buffer, grpc_exec_ctx *exec_ctx, grpc_chttp2_incoming_metadata_buffer *buffer,
grpc_metadata_batch *batch); grpc_metadata_batch *batch);
void grpc_chttp2_incoming_metadata_buffer_add( grpc_error *grpc_chttp2_incoming_metadata_buffer_add(
grpc_chttp2_incoming_metadata_buffer *buffer, grpc_mdelem elem);
void grpc_chttp2_incoming_metadata_buffer_replace_or_add(
grpc_exec_ctx *exec_ctx, grpc_chttp2_incoming_metadata_buffer *buffer, grpc_exec_ctx *exec_ctx, grpc_chttp2_incoming_metadata_buffer *buffer,
grpc_mdelem elem); grpc_mdelem elem) GRPC_MUST_USE_RESULT;
grpc_error *grpc_chttp2_incoming_metadata_buffer_replace_or_add(
grpc_exec_ctx *exec_ctx, grpc_chttp2_incoming_metadata_buffer *buffer,
grpc_mdelem elem) GRPC_MUST_USE_RESULT;
void grpc_chttp2_incoming_metadata_buffer_set_deadline( void grpc_chttp2_incoming_metadata_buffer_set_deadline(
grpc_chttp2_incoming_metadata_buffer *buffer, gpr_timespec deadline); grpc_chttp2_incoming_metadata_buffer *buffer, gpr_timespec deadline);

@ -425,7 +425,7 @@ struct grpc_chttp2_stream {
grpc_stream_refcount *refcount; grpc_stream_refcount *refcount;
grpc_closure destroy_stream; grpc_closure destroy_stream;
void *destroy_stream_arg; grpc_closure *destroy_stream_arg;
grpc_chttp2_stream_link links[STREAM_LIST_COUNT]; grpc_chttp2_stream_link links[STREAM_LIST_COUNT];
uint8_t included[STREAM_LIST_COUNT]; uint8_t included[STREAM_LIST_COUNT];

@ -381,6 +381,27 @@ static grpc_error *update_incoming_window(grpc_exec_ctx *exec_ctx,
s->incoming_window_delta + s->incoming_window_delta +
t->settings[GRPC_ACKED_SETTINGS] t->settings[GRPC_ACKED_SETTINGS]
[GRPC_CHTTP2_SETTINGS_INITIAL_WINDOW_SIZE]) { [GRPC_CHTTP2_SETTINGS_INITIAL_WINDOW_SIZE]) {
if (incoming_frame_size <=
s->incoming_window_delta +
t->settings[GRPC_SENT_SETTINGS]
[GRPC_CHTTP2_SETTINGS_INITIAL_WINDOW_SIZE]) {
gpr_log(
GPR_ERROR,
"Incoming frame of size %d exceeds incoming window size of %" PRId64
".\n"
"The (un-acked, future) window size would be %" PRId64
" which is not exceeded.\n"
"This would usually cause a disconnection, but allowing it due to "
"broken HTTP2 implementations in the wild.\n"
"See (for example) https://github.com/netty/netty/issues/6520.",
t->incoming_frame_size,
s->incoming_window_delta +
t->settings[GRPC_ACKED_SETTINGS]
[GRPC_CHTTP2_SETTINGS_INITIAL_WINDOW_SIZE],
s->incoming_window_delta +
t->settings[GRPC_SENT_SETTINGS]
[GRPC_CHTTP2_SETTINGS_INITIAL_WINDOW_SIZE]);
} else {
char *msg; char *msg;
gpr_asprintf(&msg, gpr_asprintf(&msg,
"frame of size %d overflows incoming window of %" PRId64, "frame of size %d overflows incoming window of %" PRId64,
@ -392,6 +413,7 @@ static grpc_error *update_incoming_window(grpc_exec_ctx *exec_ctx,
gpr_free(msg); gpr_free(msg);
return err; return err;
} }
}
GRPC_CHTTP2_FLOW_DEBIT_STREAM_INCOMING_WINDOW_DELTA("parse", t, s, GRPC_CHTTP2_FLOW_DEBIT_STREAM_INCOMING_WINDOW_DELTA("parse", t, s,
incoming_frame_size); incoming_frame_size);
@ -526,7 +548,14 @@ static void on_initial_header(grpc_exec_ctx *exec_ctx, void *tp,
s->seen_error = true; s->seen_error = true;
GRPC_MDELEM_UNREF(exec_ctx, md); GRPC_MDELEM_UNREF(exec_ctx, md);
} else { } else {
grpc_chttp2_incoming_metadata_buffer_add(&s->metadata_buffer[0], md); grpc_error *error = grpc_chttp2_incoming_metadata_buffer_add(
exec_ctx, &s->metadata_buffer[0], md);
if (error != GRPC_ERROR_NONE) {
grpc_chttp2_cancel_stream(exec_ctx, t, s, error);
grpc_chttp2_parsing_become_skip_parser(exec_ctx, t);
s->seen_error = true;
GRPC_MDELEM_UNREF(exec_ctx, md);
}
} }
} }
@ -576,7 +605,14 @@ static void on_trailing_header(grpc_exec_ctx *exec_ctx, void *tp,
s->seen_error = true; s->seen_error = true;
GRPC_MDELEM_UNREF(exec_ctx, md); GRPC_MDELEM_UNREF(exec_ctx, md);
} else { } else {
grpc_chttp2_incoming_metadata_buffer_add(&s->metadata_buffer[1], md); grpc_error *error = grpc_chttp2_incoming_metadata_buffer_add(
exec_ctx, &s->metadata_buffer[1], md);
if (error != GRPC_ERROR_NONE) {
grpc_chttp2_cancel_stream(exec_ctx, t, s, error);
grpc_chttp2_parsing_become_skip_parser(exec_ctx, t);
s->seen_error = true;
GRPC_MDELEM_UNREF(exec_ctx, md);
}
} }
GPR_TIMER_END("on_trailing_header", 0); GPR_TIMER_END("on_trailing_header", 0);

@ -54,6 +54,7 @@
#include "third_party/objective_c/Cronet/bidirectional_stream_c.h" #include "third_party/objective_c/Cronet/bidirectional_stream_c.h"
#define GRPC_HEADER_SIZE_IN_BYTES 5 #define GRPC_HEADER_SIZE_IN_BYTES 5
#define GRPC_FLUSH_READ_SIZE 4096
#define CRONET_LOG(...) \ #define CRONET_LOG(...) \
do { \ do { \
@ -151,11 +152,17 @@ struct write_state {
struct op_state { struct op_state {
bool state_op_done[OP_NUM_OPS]; bool state_op_done[OP_NUM_OPS];
bool state_callback_received[OP_NUM_OPS]; bool state_callback_received[OP_NUM_OPS];
/* A non-zero gRPC status code has been seen */
bool fail_state; bool fail_state;
/* Transport is discarding all buffered messages */
bool flush_read; bool flush_read;
bool flush_cronet_when_ready; bool flush_cronet_when_ready;
bool pending_write_for_trailer; bool pending_write_for_trailer;
bool unprocessed_send_message; bool pending_send_message;
/* User requested RECV_TRAILING_METADATA */
bool pending_recv_trailing_metadata;
/* Cronet has not issued a callback of a bidirectional read */
bool pending_read_from_cronet;
grpc_error *cancel_error; grpc_error *cancel_error;
/* data structure for storing data coming from server */ /* data structure for storing data coming from server */
struct read_state rs; struct read_state rs;
@ -177,6 +184,7 @@ struct op_storage {
}; };
struct stream_obj { struct stream_obj {
gpr_arena *arena;
struct op_and_state *oas; struct op_and_state *oas;
grpc_transport_stream_op *curr_op; grpc_transport_stream_op *curr_op;
grpc_cronet_transport *curr_ct; grpc_cronet_transport *curr_ct;
@ -248,12 +256,36 @@ static const char *op_id_string(enum e_op_id i) {
return "UNKNOWN"; return "UNKNOWN";
} }
static void free_read_buffer(stream_obj *s) { static void null_and_maybe_free_read_buffer(stream_obj *s) {
if (s->state.rs.read_buffer && if (s->state.rs.read_buffer &&
s->state.rs.read_buffer != s->state.rs.grpc_header_bytes) { s->state.rs.read_buffer != s->state.rs.grpc_header_bytes) {
gpr_free(s->state.rs.read_buffer); gpr_free(s->state.rs.read_buffer);
}
s->state.rs.read_buffer = NULL; s->state.rs.read_buffer = NULL;
} }
static void maybe_flush_read(stream_obj *s) {
/* To enter flush read state (discarding all the buffered messages in
* transport layer), two conditions must be satisfied: 1) non-zero grpc status
* has been received, and 2) an op requesting the status code
* (RECV_TRAILING_METADATA) is issued by the user. (See
* doc/status_ordering.md) */
/* Whenever the evaluation of any of the two condition is changed, we check
* whether we should enter the flush read state. */
if (s->state.pending_recv_trailing_metadata && s->state.fail_state) {
if (!s->state.flush_read && !s->state.rs.read_stream_closed) {
CRONET_LOG(GPR_DEBUG, "%p: Flush read", s);
s->state.flush_read = true;
null_and_maybe_free_read_buffer(s);
s->state.rs.read_buffer = gpr_malloc(GRPC_FLUSH_READ_SIZE);
if (!s->state.pending_read_from_cronet) {
CRONET_LOG(GPR_DEBUG, "bidirectional_stream_read(%p)", s->cbs);
bidirectional_stream_read(s->cbs, s->state.rs.read_buffer,
GRPC_FLUSH_READ_SIZE);
s->state.pending_read_from_cronet = true;
}
}
}
} }
static grpc_error *make_error_with_desc(int error_code, const char *desc) { static grpc_error *make_error_with_desc(int error_code, const char *desc) {
@ -279,7 +311,11 @@ static void add_to_storage(struct stream_obj *s, grpc_transport_stream_op *op) {
storage->head = new_op; storage->head = new_op;
storage->num_pending_ops++; storage->num_pending_ops++;
if (op->send_message) { if (op->send_message) {
s->state.unprocessed_send_message = true; s->state.pending_send_message = true;
}
if (op->recv_trailing_metadata) {
s->state.pending_recv_trailing_metadata = true;
maybe_flush_read(s);
} }
CRONET_LOG(GPR_DEBUG, "adding new op %p. %d in the queue.", new_op, CRONET_LOG(GPR_DEBUG, "adding new op %p. %d in the queue.", new_op,
storage->num_pending_ops); storage->num_pending_ops);
@ -367,7 +403,7 @@ static void on_failed(bidirectional_stream *stream, int net_error) {
gpr_free(s->state.ws.write_buffer); gpr_free(s->state.ws.write_buffer);
s->state.ws.write_buffer = NULL; s->state.ws.write_buffer = NULL;
} }
free_read_buffer(s); null_and_maybe_free_read_buffer(s);
gpr_mu_unlock(&s->mu); gpr_mu_unlock(&s->mu);
execute_from_storage(s); execute_from_storage(s);
} }
@ -390,7 +426,7 @@ static void on_canceled(bidirectional_stream *stream) {
gpr_free(s->state.ws.write_buffer); gpr_free(s->state.ws.write_buffer);
s->state.ws.write_buffer = NULL; s->state.ws.write_buffer = NULL;
} }
free_read_buffer(s); null_and_maybe_free_read_buffer(s);
gpr_mu_unlock(&s->mu); gpr_mu_unlock(&s->mu);
execute_from_storage(s); execute_from_storage(s);
} }
@ -405,7 +441,7 @@ static void on_succeeded(bidirectional_stream *stream) {
bidirectional_stream_destroy(s->cbs); bidirectional_stream_destroy(s->cbs);
s->state.state_callback_received[OP_SUCCEEDED] = true; s->state.state_callback_received[OP_SUCCEEDED] = true;
s->cbs = NULL; s->cbs = NULL;
free_read_buffer(s); null_and_maybe_free_read_buffer(s);
gpr_mu_unlock(&s->mu); gpr_mu_unlock(&s->mu);
execute_from_storage(s); execute_from_storage(s);
} }
@ -451,15 +487,18 @@ static void on_response_headers_received(
gpr_mu_lock(&s->mu); gpr_mu_lock(&s->mu);
memset(&s->state.rs.initial_metadata, 0, memset(&s->state.rs.initial_metadata, 0,
sizeof(s->state.rs.initial_metadata)); sizeof(s->state.rs.initial_metadata));
grpc_chttp2_incoming_metadata_buffer_init(&s->state.rs.initial_metadata); grpc_chttp2_incoming_metadata_buffer_init(&s->state.rs.initial_metadata,
s->arena);
for (size_t i = 0; i < headers->count; i++) { for (size_t i = 0; i < headers->count; i++) {
GRPC_LOG_IF_ERROR(
"on_response_headers_received",
grpc_chttp2_incoming_metadata_buffer_add( grpc_chttp2_incoming_metadata_buffer_add(
&s->state.rs.initial_metadata, &exec_ctx, &s->state.rs.initial_metadata,
grpc_mdelem_from_slices( grpc_mdelem_from_slices(
&exec_ctx, grpc_slice_intern(grpc_slice_from_static_string( &exec_ctx, grpc_slice_intern(grpc_slice_from_static_string(
headers->headers[i].key)), headers->headers[i].key)),
grpc_slice_intern( grpc_slice_intern(grpc_slice_from_static_string(
grpc_slice_from_static_string(headers->headers[i].value)))); headers->headers[i].value)))));
} }
s->state.state_callback_received[OP_RECV_INITIAL_METADATA] = true; s->state.state_callback_received[OP_RECV_INITIAL_METADATA] = true;
if (!(s->state.state_op_done[OP_CANCEL_ERROR] || if (!(s->state.state_op_done[OP_CANCEL_ERROR] ||
@ -473,6 +512,7 @@ static void on_response_headers_received(
CRONET_LOG(GPR_DEBUG, "bidirectional_stream_read(%p)", s->cbs); CRONET_LOG(GPR_DEBUG, "bidirectional_stream_read(%p)", s->cbs);
bidirectional_stream_read(s->cbs, s->state.rs.read_buffer, bidirectional_stream_read(s->cbs, s->state.rs.read_buffer,
s->state.rs.remaining_bytes); s->state.rs.remaining_bytes);
s->state.pending_read_from_cronet = true;
} }
gpr_mu_unlock(&s->mu); gpr_mu_unlock(&s->mu);
grpc_exec_ctx_finish(&exec_ctx); grpc_exec_ctx_finish(&exec_ctx);
@ -504,10 +544,13 @@ static void on_read_completed(bidirectional_stream *stream, char *data,
CRONET_LOG(GPR_DEBUG, "R: on_read_completed(%p, %p, %d)", stream, data, CRONET_LOG(GPR_DEBUG, "R: on_read_completed(%p, %p, %d)", stream, data,
count); count);
gpr_mu_lock(&s->mu); gpr_mu_lock(&s->mu);
s->state.pending_read_from_cronet = false;
s->state.state_callback_received[OP_RECV_MESSAGE] = true; s->state.state_callback_received[OP_RECV_MESSAGE] = true;
if (count > 0 && s->state.flush_read) { if (count > 0 && s->state.flush_read) {
CRONET_LOG(GPR_DEBUG, "bidirectional_stream_read(%p)", s->cbs); CRONET_LOG(GPR_DEBUG, "bidirectional_stream_read(%p)", s->cbs);
bidirectional_stream_read(s->cbs, s->state.rs.read_buffer, 4096); bidirectional_stream_read(s->cbs, s->state.rs.read_buffer,
GRPC_FLUSH_READ_SIZE);
s->state.pending_read_from_cronet = true;
gpr_mu_unlock(&s->mu); gpr_mu_unlock(&s->mu);
} else if (count > 0) { } else if (count > 0) {
s->state.rs.received_bytes += count; s->state.rs.received_bytes += count;
@ -518,16 +561,14 @@ static void on_read_completed(bidirectional_stream *stream, char *data,
bidirectional_stream_read( bidirectional_stream_read(
s->cbs, s->state.rs.read_buffer + s->state.rs.received_bytes, s->cbs, s->state.rs.read_buffer + s->state.rs.received_bytes,
s->state.rs.remaining_bytes); s->state.rs.remaining_bytes);
s->state.pending_read_from_cronet = true;
gpr_mu_unlock(&s->mu); gpr_mu_unlock(&s->mu);
} else { } else {
gpr_mu_unlock(&s->mu); gpr_mu_unlock(&s->mu);
execute_from_storage(s); execute_from_storage(s);
} }
} else { } else {
if (s->state.flush_read) { null_and_maybe_free_read_buffer(s);
gpr_free(s->state.rs.read_buffer);
s->state.rs.read_buffer = NULL;
}
s->state.rs.read_stream_closed = true; s->state.rs.read_stream_closed = true;
gpr_mu_unlock(&s->mu); gpr_mu_unlock(&s->mu);
execute_from_storage(s); execute_from_storage(s);
@ -549,21 +590,25 @@ static void on_response_trailers_received(
memset(&s->state.rs.trailing_metadata, 0, memset(&s->state.rs.trailing_metadata, 0,
sizeof(s->state.rs.trailing_metadata)); sizeof(s->state.rs.trailing_metadata));
s->state.rs.trailing_metadata_valid = false; s->state.rs.trailing_metadata_valid = false;
grpc_chttp2_incoming_metadata_buffer_init(&s->state.rs.trailing_metadata); grpc_chttp2_incoming_metadata_buffer_init(&s->state.rs.trailing_metadata,
s->arena);
for (size_t i = 0; i < trailers->count; i++) { for (size_t i = 0; i < trailers->count; i++) {
CRONET_LOG(GPR_DEBUG, "trailer key=%s, value=%s", trailers->headers[i].key, CRONET_LOG(GPR_DEBUG, "trailer key=%s, value=%s", trailers->headers[i].key,
trailers->headers[i].value); trailers->headers[i].value);
GRPC_LOG_IF_ERROR(
"on_response_trailers_received",
grpc_chttp2_incoming_metadata_buffer_add( grpc_chttp2_incoming_metadata_buffer_add(
&s->state.rs.trailing_metadata, &exec_ctx, &s->state.rs.trailing_metadata,
grpc_mdelem_from_slices( grpc_mdelem_from_slices(
&exec_ctx, grpc_slice_intern(grpc_slice_from_static_string( &exec_ctx, grpc_slice_intern(grpc_slice_from_static_string(
trailers->headers[i].key)), trailers->headers[i].key)),
grpc_slice_intern( grpc_slice_intern(grpc_slice_from_static_string(
grpc_slice_from_static_string(trailers->headers[i].value)))); trailers->headers[i].value)))));
s->state.rs.trailing_metadata_valid = true; s->state.rs.trailing_metadata_valid = true;
if (0 == strcmp(trailers->headers[i].key, "grpc-status") && if (0 == strcmp(trailers->headers[i].key, "grpc-status") &&
0 != strcmp(trailers->headers[i].value, "0")) { 0 != strcmp(trailers->headers[i].value, "0")) {
s->state.fail_state = true; s->state.fail_state = true;
maybe_flush_read(s);
} }
} }
s->state.state_callback_received[OP_RECV_TRAILING_METADATA] = true; s->state.state_callback_received[OP_RECV_TRAILING_METADATA] = true;
@ -778,7 +823,7 @@ static bool op_can_be_run(grpc_transport_stream_op *curr_op,
else if (!stream_state->state_callback_received[OP_SEND_INITIAL_METADATA]) else if (!stream_state->state_callback_received[OP_SEND_INITIAL_METADATA])
result = false; result = false;
/* we haven't sent message yet */ /* we haven't sent message yet */
else if (stream_state->unprocessed_send_message && else if (stream_state->pending_send_message &&
!stream_state->state_op_done[OP_SEND_MESSAGE]) !stream_state->state_op_done[OP_SEND_MESSAGE])
result = false; result = false;
/* we haven't got on_write_completed for the send yet */ /* we haven't got on_write_completed for the send yet */
@ -900,7 +945,7 @@ static enum e_op_result execute_stream_op(grpc_exec_ctx *exec_ctx,
} else if (stream_op->send_message && } else if (stream_op->send_message &&
op_can_be_run(stream_op, s, &oas->state, OP_SEND_MESSAGE)) { op_can_be_run(stream_op, s, &oas->state, OP_SEND_MESSAGE)) {
CRONET_LOG(GPR_DEBUG, "running: %p OP_SEND_MESSAGE", oas); CRONET_LOG(GPR_DEBUG, "running: %p OP_SEND_MESSAGE", oas);
stream_state->unprocessed_send_message = false; stream_state->pending_send_message = false;
if (stream_state->state_callback_received[OP_FAILED]) { if (stream_state->state_callback_received[OP_FAILED]) {
result = NO_ACTION_POSSIBLE; result = NO_ACTION_POSSIBLE;
CRONET_LOG(GPR_DEBUG, "Stream is either cancelled or failed."); CRONET_LOG(GPR_DEBUG, "Stream is either cancelled or failed.");
@ -1009,6 +1054,13 @@ static enum e_op_result execute_stream_op(grpc_exec_ctx *exec_ctx,
stream_state->state_op_done[OP_RECV_MESSAGE] = true; stream_state->state_op_done[OP_RECV_MESSAGE] = true;
oas->state.state_op_done[OP_RECV_MESSAGE] = true; oas->state.state_op_done[OP_RECV_MESSAGE] = true;
result = ACTION_TAKEN_NO_CALLBACK; result = ACTION_TAKEN_NO_CALLBACK;
} else if (stream_state->flush_read) {
CRONET_LOG(GPR_DEBUG, "flush read");
grpc_closure_sched(exec_ctx, stream_op->recv_message_ready,
GRPC_ERROR_NONE);
stream_state->state_op_done[OP_RECV_MESSAGE] = true;
oas->state.state_op_done[OP_RECV_MESSAGE] = true;
result = ACTION_TAKEN_NO_CALLBACK;
} else if (stream_state->rs.length_field_received == false) { } else if (stream_state->rs.length_field_received == false) {
if (stream_state->rs.received_bytes == GRPC_HEADER_SIZE_IN_BYTES && if (stream_state->rs.received_bytes == GRPC_HEADER_SIZE_IN_BYTES &&
stream_state->rs.remaining_bytes == 0) { stream_state->rs.remaining_bytes == 0) {
@ -1029,6 +1081,7 @@ static enum e_op_result execute_stream_op(grpc_exec_ctx *exec_ctx,
true; /* Indicates that at least one read request has been made */ true; /* Indicates that at least one read request has been made */
bidirectional_stream_read(s->cbs, stream_state->rs.read_buffer, bidirectional_stream_read(s->cbs, stream_state->rs.read_buffer,
stream_state->rs.remaining_bytes); stream_state->rs.remaining_bytes);
stream_state->pending_read_from_cronet = true;
result = ACTION_TAKEN_WITH_CALLBACK; result = ACTION_TAKEN_WITH_CALLBACK;
} else { } else {
stream_state->rs.remaining_bytes = 0; stream_state->rs.remaining_bytes = 0;
@ -1047,11 +1100,13 @@ static enum e_op_result execute_stream_op(grpc_exec_ctx *exec_ctx,
stream_state->rs.read_buffer = stream_state->rs.grpc_header_bytes; stream_state->rs.read_buffer = stream_state->rs.grpc_header_bytes;
stream_state->rs.remaining_bytes = GRPC_HEADER_SIZE_IN_BYTES; stream_state->rs.remaining_bytes = GRPC_HEADER_SIZE_IN_BYTES;
stream_state->rs.received_bytes = 0; stream_state->rs.received_bytes = 0;
stream_state->rs.length_field_received = false;
CRONET_LOG(GPR_DEBUG, "bidirectional_stream_read(%p)", s->cbs); CRONET_LOG(GPR_DEBUG, "bidirectional_stream_read(%p)", s->cbs);
stream_state->state_op_done[OP_READ_REQ_MADE] = stream_state->state_op_done[OP_READ_REQ_MADE] =
true; /* Indicates that at least one read request has been made */ true; /* Indicates that at least one read request has been made */
bidirectional_stream_read(s->cbs, stream_state->rs.read_buffer, bidirectional_stream_read(s->cbs, stream_state->rs.read_buffer,
stream_state->rs.remaining_bytes); stream_state->rs.remaining_bytes);
stream_state->pending_read_from_cronet = true;
result = ACTION_TAKEN_NO_CALLBACK; result = ACTION_TAKEN_NO_CALLBACK;
} }
} else if (stream_state->rs.remaining_bytes == 0) { } else if (stream_state->rs.remaining_bytes == 0) {
@ -1064,6 +1119,7 @@ static enum e_op_result execute_stream_op(grpc_exec_ctx *exec_ctx,
true; /* Indicates that at least one read request has been made */ true; /* Indicates that at least one read request has been made */
bidirectional_stream_read(s->cbs, stream_state->rs.read_buffer, bidirectional_stream_read(s->cbs, stream_state->rs.read_buffer,
stream_state->rs.remaining_bytes); stream_state->rs.remaining_bytes);
stream_state->pending_read_from_cronet = true;
result = ACTION_TAKEN_WITH_CALLBACK; result = ACTION_TAKEN_WITH_CALLBACK;
} else { } else {
result = NO_ACTION_POSSIBLE; result = NO_ACTION_POSSIBLE;
@ -1075,7 +1131,7 @@ static enum e_op_result execute_stream_op(grpc_exec_ctx *exec_ctx,
uint8_t *dst_p = GRPC_SLICE_START_PTR(read_data_slice); uint8_t *dst_p = GRPC_SLICE_START_PTR(read_data_slice);
memcpy(dst_p, stream_state->rs.read_buffer, memcpy(dst_p, stream_state->rs.read_buffer,
(size_t)stream_state->rs.length_field); (size_t)stream_state->rs.length_field);
free_read_buffer(s); null_and_maybe_free_read_buffer(s);
grpc_slice_buffer_init(&stream_state->rs.read_slice_buffer); grpc_slice_buffer_init(&stream_state->rs.read_slice_buffer);
grpc_slice_buffer_add(&stream_state->rs.read_slice_buffer, grpc_slice_buffer_add(&stream_state->rs.read_slice_buffer,
read_data_slice); read_data_slice);
@ -1096,6 +1152,7 @@ static enum e_op_result execute_stream_op(grpc_exec_ctx *exec_ctx,
CRONET_LOG(GPR_DEBUG, "bidirectional_stream_read(%p)", s->cbs); CRONET_LOG(GPR_DEBUG, "bidirectional_stream_read(%p)", s->cbs);
bidirectional_stream_read(s->cbs, stream_state->rs.read_buffer, bidirectional_stream_read(s->cbs, stream_state->rs.read_buffer,
stream_state->rs.remaining_bytes); stream_state->rs.remaining_bytes);
stream_state->pending_read_from_cronet = true;
result = ACTION_TAKEN_NO_CALLBACK; result = ACTION_TAKEN_NO_CALLBACK;
} }
} else if (stream_op->recv_trailing_metadata && } else if (stream_op->recv_trailing_metadata &&
@ -1153,15 +1210,6 @@ static enum e_op_result execute_stream_op(grpc_exec_ctx *exec_ctx,
make a note */ make a note */
if (stream_op->recv_message) if (stream_op->recv_message)
stream_state->state_op_done[OP_RECV_MESSAGE_AND_ON_COMPLETE] = true; stream_state->state_op_done[OP_RECV_MESSAGE_AND_ON_COMPLETE] = true;
} else if (stream_state->fail_state && !stream_state->flush_read) {
CRONET_LOG(GPR_DEBUG, "running: %p flush read", oas);
if (stream_state->rs.read_buffer &&
stream_state->rs.read_buffer != stream_state->rs.grpc_header_bytes) {
gpr_free(stream_state->rs.read_buffer);
stream_state->rs.read_buffer = NULL;
}
stream_state->rs.read_buffer = gpr_malloc(4096);
stream_state->flush_read = true;
} else { } else {
result = NO_ACTION_POSSIBLE; result = NO_ACTION_POSSIBLE;
} }
@ -1174,7 +1222,7 @@ static enum e_op_result execute_stream_op(grpc_exec_ctx *exec_ctx,
static int init_stream(grpc_exec_ctx *exec_ctx, grpc_transport *gt, static int init_stream(grpc_exec_ctx *exec_ctx, grpc_transport *gt,
grpc_stream *gs, grpc_stream_refcount *refcount, grpc_stream *gs, grpc_stream_refcount *refcount,
const void *server_data) { const void *server_data, gpr_arena *arena) {
stream_obj *s = (stream_obj *)gs; stream_obj *s = (stream_obj *)gs;
memset(&s->storage, 0, sizeof(s->storage)); memset(&s->storage, 0, sizeof(s->storage));
s->storage.head = NULL; s->storage.head = NULL;
@ -1190,10 +1238,13 @@ static int init_stream(grpc_exec_ctx *exec_ctx, grpc_transport *gt,
s->state.fail_state = s->state.flush_read = false; s->state.fail_state = s->state.flush_read = false;
s->state.cancel_error = NULL; s->state.cancel_error = NULL;
s->state.flush_cronet_when_ready = s->state.pending_write_for_trailer = false; s->state.flush_cronet_when_ready = s->state.pending_write_for_trailer = false;
s->state.unprocessed_send_message = false; s->state.pending_send_message = false;
s->state.pending_recv_trailing_metadata = false;
s->state.pending_read_from_cronet = false;
s->curr_gs = gs; s->curr_gs = gs;
s->curr_ct = (grpc_cronet_transport *)gt; s->curr_ct = (grpc_cronet_transport *)gt;
s->arena = arena;
gpr_mu_init(&s->mu); gpr_mu_init(&s->mu);
return 0; return 0;
@ -1209,38 +1260,33 @@ static void set_pollset_set_do_nothing(grpc_exec_ctx *exec_ctx,
static void perform_stream_op(grpc_exec_ctx *exec_ctx, grpc_transport *gt, static void perform_stream_op(grpc_exec_ctx *exec_ctx, grpc_transport *gt,
grpc_stream *gs, grpc_transport_stream_op *op) { grpc_stream *gs, grpc_transport_stream_op *op) {
CRONET_LOG(GPR_DEBUG, "perform_stream_op"); CRONET_LOG(GPR_DEBUG, "perform_stream_op");
stream_obj *s = (stream_obj *)gs;
add_to_storage(s, op);
if (op->send_initial_metadata && if (op->send_initial_metadata &&
header_has_authority(op->send_initial_metadata->list.head)) { header_has_authority(op->send_initial_metadata->list.head)) {
/* Cronet does not support :authority header field. We cancel the call when /* Cronet does not support :authority header field. We cancel the call when
this field is present in metadata */ this field is present in metadata */
bidirectional_stream_header_array header_array; if (op->recv_initial_metadata_ready) {
bidirectional_stream_header *header; grpc_closure_sched(exec_ctx, op->recv_initial_metadata_ready,
bidirectional_stream cbs; GRPC_ERROR_CANCELLED);
CRONET_LOG(GPR_DEBUG, }
":authority header is provided but not supported;" if (op->recv_message_ready) {
" cancel operations"); grpc_closure_sched(exec_ctx, op->recv_message_ready,
/* Notify application that operation is cancelled by forging trailers */ GRPC_ERROR_CANCELLED);
header_array.count = 1; }
header_array.capacity = 1; grpc_closure_sched(exec_ctx, op->on_complete, GRPC_ERROR_CANCELLED);
header_array.headers = gpr_malloc(sizeof(bidirectional_stream_header)); return;
header = (bidirectional_stream_header *)header_array.headers;
header->key = "grpc-status";
header->value = "1"; /* Return status GRPC_STATUS_CANCELLED */
cbs.annotation = (void *)s;
s->state.state_op_done[OP_CANCEL_ERROR] = true;
on_response_trailers_received(&cbs, &header_array);
gpr_free(header_array.headers);
} else {
execute_from_storage(s);
} }
stream_obj *s = (stream_obj *)gs;
add_to_storage(s, op);
execute_from_storage(s);
} }
static void destroy_stream(grpc_exec_ctx *exec_ctx, grpc_transport *gt, static void destroy_stream(grpc_exec_ctx *exec_ctx, grpc_transport *gt,
grpc_stream *gs, void *and_free_memory) { grpc_stream *gs,
grpc_closure *then_schedule_closure) {
stream_obj *s = (stream_obj *)gs; stream_obj *s = (stream_obj *)gs;
null_and_maybe_free_read_buffer(s);
GRPC_ERROR_UNREF(s->state.cancel_error); GRPC_ERROR_UNREF(s->state.cancel_error);
grpc_closure_sched(exec_ctx, then_schedule_closure, GRPC_ERROR_NONE);
} }
static void destroy_transport(grpc_exec_ctx *exec_ctx, grpc_transport *gt) {} static void destroy_transport(grpc_exec_ctx *exec_ctx, grpc_transport *gt) {}

@ -166,41 +166,32 @@ void grpc_channel_stack_destroy(grpc_exec_ctx *exec_ctx,
} }
} }
grpc_error *grpc_call_stack_init( grpc_error *grpc_call_stack_init(grpc_exec_ctx *exec_ctx,
grpc_exec_ctx *exec_ctx, grpc_channel_stack *channel_stack, grpc_channel_stack *channel_stack,
int initial_refs, grpc_iomgr_cb_func destroy, void *destroy_arg, int initial_refs, grpc_iomgr_cb_func destroy,
grpc_call_context_element *context, const void *transport_server_data, void *destroy_arg,
grpc_slice path, gpr_timespec start_time, gpr_timespec deadline, const grpc_call_element_args *elem_args) {
grpc_call_stack *call_stack) {
grpc_channel_element *channel_elems = CHANNEL_ELEMS_FROM_STACK(channel_stack); grpc_channel_element *channel_elems = CHANNEL_ELEMS_FROM_STACK(channel_stack);
size_t count = channel_stack->count; size_t count = channel_stack->count;
grpc_call_element *call_elems; grpc_call_element *call_elems;
char *user_data; char *user_data;
size_t i; size_t i;
call_stack->count = count; elem_args->call_stack->count = count;
GRPC_STREAM_REF_INIT(&call_stack->refcount, initial_refs, destroy, GRPC_STREAM_REF_INIT(&elem_args->call_stack->refcount, initial_refs, destroy,
destroy_arg, "CALL_STACK"); destroy_arg, "CALL_STACK");
call_elems = CALL_ELEMS_FROM_STACK(call_stack); call_elems = CALL_ELEMS_FROM_STACK(elem_args->call_stack);
user_data = ((char *)call_elems) + user_data = ((char *)call_elems) +
ROUND_UP_TO_ALIGNMENT_SIZE(count * sizeof(grpc_call_element)); ROUND_UP_TO_ALIGNMENT_SIZE(count * sizeof(grpc_call_element));
/* init per-filter data */ /* init per-filter data */
grpc_error *first_error = GRPC_ERROR_NONE; grpc_error *first_error = GRPC_ERROR_NONE;
const grpc_call_element_args args = {
.start_time = start_time,
.call_stack = call_stack,
.server_transport_data = transport_server_data,
.context = context,
.path = path,
.deadline = deadline,
};
for (i = 0; i < count; i++) { for (i = 0; i < count; i++) {
call_elems[i].filter = channel_elems[i].filter; call_elems[i].filter = channel_elems[i].filter;
call_elems[i].channel_data = channel_elems[i].channel_data; call_elems[i].channel_data = channel_elems[i].channel_data;
call_elems[i].call_data = user_data; call_elems[i].call_data = user_data;
grpc_error *error = grpc_error *error = call_elems[i].filter->init_call_elem(
call_elems[i].filter->init_call_elem(exec_ctx, &call_elems[i], &args); exec_ctx, &call_elems[i], elem_args);
if (error != GRPC_ERROR_NONE) { if (error != GRPC_ERROR_NONE) {
if (first_error == GRPC_ERROR_NONE) { if (first_error == GRPC_ERROR_NONE) {
first_error = error; first_error = error;
@ -241,15 +232,16 @@ void grpc_call_stack_ignore_set_pollset_or_pollset_set(
void grpc_call_stack_destroy(grpc_exec_ctx *exec_ctx, grpc_call_stack *stack, void grpc_call_stack_destroy(grpc_exec_ctx *exec_ctx, grpc_call_stack *stack,
const grpc_call_final_info *final_info, const grpc_call_final_info *final_info,
void *and_free_memory) { grpc_closure *then_schedule_closure) {
grpc_call_element *elems = CALL_ELEMS_FROM_STACK(stack); grpc_call_element *elems = CALL_ELEMS_FROM_STACK(stack);
size_t count = stack->count; size_t count = stack->count;
size_t i; size_t i;
/* destroy per-filter data */ /* destroy per-filter data */
for (i = 0; i < count; i++) { for (i = 0; i < count; i++) {
elems[i].filter->destroy_call_elem(exec_ctx, &elems[i], final_info, elems[i].filter->destroy_call_elem(
i == count - 1 ? and_free_memory : NULL); exec_ctx, &elems[i], final_info,
i == count - 1 ? then_schedule_closure : NULL);
} }
} }

@ -56,6 +56,7 @@
#include "src/core/lib/debug/trace.h" #include "src/core/lib/debug/trace.h"
#include "src/core/lib/iomgr/polling_entity.h" #include "src/core/lib/iomgr/polling_entity.h"
#include "src/core/lib/support/arena.h"
#include "src/core/lib/transport/transport.h" #include "src/core/lib/transport/transport.h"
#ifdef __cplusplus #ifdef __cplusplus
@ -84,6 +85,7 @@ typedef struct {
grpc_slice path; grpc_slice path;
gpr_timespec start_time; gpr_timespec start_time;
gpr_timespec deadline; gpr_timespec deadline;
gpr_arena *arena;
} grpc_call_element_args; } grpc_call_element_args;
typedef struct { typedef struct {
@ -139,12 +141,12 @@ typedef struct {
/* Destroy per call data. /* Destroy per call data.
The filter does not need to do any chaining. The filter does not need to do any chaining.
The bottom filter of a stack will be passed a non-NULL pointer to The bottom filter of a stack will be passed a non-NULL pointer to
\a and_free_memory that should be passed to gpr_free when destruction \a then_schedule_closure that should be passed to grpc_closure_sched when
is complete. \a final_info contains data about the completed call, mainly destruction is complete. \a final_info contains data about the completed
for reporting purposes. */ call, mainly for reporting purposes. */
void (*destroy_call_elem)(grpc_exec_ctx *exec_ctx, grpc_call_element *elem, void (*destroy_call_elem)(grpc_exec_ctx *exec_ctx, grpc_call_element *elem,
const grpc_call_final_info *final_info, const grpc_call_final_info *final_info,
void *and_free_memory); grpc_closure *then_schedule_closure);
/* sizeof(per channel data) */ /* sizeof(per channel data) */
size_t sizeof_channel_data; size_t sizeof_channel_data;
@ -236,12 +238,11 @@ void grpc_channel_stack_destroy(grpc_exec_ctx *exec_ctx,
/* Initialize a call stack given a channel stack. transport_server_data is /* Initialize a call stack given a channel stack. transport_server_data is
expected to be NULL on a client, or an opaque transport owned pointer on the expected to be NULL on a client, or an opaque transport owned pointer on the
server. */ server. */
grpc_error *grpc_call_stack_init( grpc_error *grpc_call_stack_init(grpc_exec_ctx *exec_ctx,
grpc_exec_ctx *exec_ctx, grpc_channel_stack *channel_stack, grpc_channel_stack *channel_stack,
int initial_refs, grpc_iomgr_cb_func destroy, void *destroy_arg, int initial_refs, grpc_iomgr_cb_func destroy,
grpc_call_context_element *context, const void *transport_server_data, void *destroy_arg,
grpc_slice path, gpr_timespec start_time, gpr_timespec deadline, const grpc_call_element_args *elem_args);
grpc_call_stack *call_stack);
/* Set a pollset or a pollset_set for a call stack: must occur before the first /* Set a pollset or a pollset_set for a call stack: must occur before the first
* op is started */ * op is started */
void grpc_call_stack_set_pollset_or_pollset_set(grpc_exec_ctx *exec_ctx, void grpc_call_stack_set_pollset_or_pollset_set(grpc_exec_ctx *exec_ctx,
@ -271,7 +272,7 @@ void grpc_call_stack_set_pollset_or_pollset_set(grpc_exec_ctx *exec_ctx,
/* Destroy a call stack */ /* Destroy a call stack */
void grpc_call_stack_destroy(grpc_exec_ctx *exec_ctx, grpc_call_stack *stack, void grpc_call_stack_destroy(grpc_exec_ctx *exec_ctx, grpc_call_stack *stack,
const grpc_call_final_info *final_info, const grpc_call_final_info *final_info,
void *and_free_memory); grpc_closure *then_schedule_closure);
/* Ignore set pollset{_set} - used by filters if they don't care about pollsets /* Ignore set pollset{_set} - used by filters if they don't care about pollsets
* at all. Does nothing. */ * at all. Does nothing. */

@ -292,7 +292,7 @@ static grpc_error *init_call_elem(grpc_exec_ctx *exec_ctx,
/* Destructor for call_data */ /* Destructor for call_data */
static void destroy_call_elem(grpc_exec_ctx *exec_ctx, grpc_call_element *elem, static void destroy_call_elem(grpc_exec_ctx *exec_ctx, grpc_call_element *elem,
const grpc_call_final_info *final_info, const grpc_call_final_info *final_info,
void *ignored) { grpc_closure *ignored) {
/* grab pointers to our data from the call element */ /* grab pointers to our data from the call element */
call_data *calld = elem->call_data; call_data *calld = elem->call_data;
grpc_slice_buffer_destroy_internal(exec_ctx, &calld->slices); grpc_slice_buffer_destroy_internal(exec_ctx, &calld->slices);

@ -88,7 +88,7 @@ static grpc_error *init_call_elem(grpc_exec_ctx *exec_ctx,
channel_data *chand = elem->channel_data; channel_data *chand = elem->channel_data;
int r = grpc_transport_init_stream( int r = grpc_transport_init_stream(
exec_ctx, chand->transport, TRANSPORT_STREAM_FROM_CALL_DATA(calld), exec_ctx, chand->transport, TRANSPORT_STREAM_FROM_CALL_DATA(calld),
&args->call_stack->refcount, args->server_transport_data); &args->call_stack->refcount, args->server_transport_data, args->arena);
return r == 0 ? GRPC_ERROR_NONE return r == 0 ? GRPC_ERROR_NONE
: GRPC_ERROR_CREATE("transport stream initialization failed"); : GRPC_ERROR_CREATE("transport stream initialization failed");
} }
@ -105,12 +105,12 @@ static void set_pollset_or_pollset_set(grpc_exec_ctx *exec_ctx,
/* Destructor for call_data */ /* Destructor for call_data */
static void destroy_call_elem(grpc_exec_ctx *exec_ctx, grpc_call_element *elem, static void destroy_call_elem(grpc_exec_ctx *exec_ctx, grpc_call_element *elem,
const grpc_call_final_info *final_info, const grpc_call_final_info *final_info,
void *and_free_memory) { grpc_closure *then_schedule_closure) {
call_data *calld = elem->call_data; call_data *calld = elem->call_data;
channel_data *chand = elem->channel_data; channel_data *chand = elem->channel_data;
grpc_transport_destroy_stream(exec_ctx, chand->transport, grpc_transport_destroy_stream(exec_ctx, chand->transport,
TRANSPORT_STREAM_FROM_CALL_DATA(calld), TRANSPORT_STREAM_FROM_CALL_DATA(calld),
and_free_memory); then_schedule_closure);
} }
/* Constructor for channel_data */ /* Constructor for channel_data */

@ -256,7 +256,7 @@ static grpc_error* init_call_elem(grpc_exec_ctx* exec_ctx,
// Destructor for call_data. Used for both client and server filters. // Destructor for call_data. Used for both client and server filters.
static void destroy_call_elem(grpc_exec_ctx* exec_ctx, grpc_call_element* elem, static void destroy_call_elem(grpc_exec_ctx* exec_ctx, grpc_call_element* elem,
const grpc_call_final_info* final_info, const grpc_call_final_info* final_info,
void* and_free_memory) { grpc_closure* ignored) {
grpc_deadline_state_destroy(exec_ctx, elem); grpc_deadline_state_destroy(exec_ctx, elem);
} }

@ -412,7 +412,7 @@ static grpc_error *init_call_elem(grpc_exec_ctx *exec_ctx,
/* Destructor for call_data */ /* Destructor for call_data */
static void destroy_call_elem(grpc_exec_ctx *exec_ctx, grpc_call_element *elem, static void destroy_call_elem(grpc_exec_ctx *exec_ctx, grpc_call_element *elem,
const grpc_call_final_info *final_info, const grpc_call_final_info *final_info,
void *ignored) { grpc_closure *ignored) {
call_data *calld = elem->call_data; call_data *calld = elem->call_data;
grpc_slice_buffer_destroy_internal(exec_ctx, &calld->slices); grpc_slice_buffer_destroy_internal(exec_ctx, &calld->slices);
} }

@ -358,7 +358,7 @@ static grpc_error *init_call_elem(grpc_exec_ctx *exec_ctx,
/* Destructor for call_data */ /* Destructor for call_data */
static void destroy_call_elem(grpc_exec_ctx *exec_ctx, grpc_call_element *elem, static void destroy_call_elem(grpc_exec_ctx *exec_ctx, grpc_call_element *elem,
const grpc_call_final_info *final_info, const grpc_call_final_info *final_info,
void *ignored) { grpc_closure *ignored) {
call_data *calld = elem->call_data; call_data *calld = elem->call_data;
grpc_slice_buffer_destroy_internal(exec_ctx, &calld->read_slice_buffer); grpc_slice_buffer_destroy_internal(exec_ctx, &calld->read_slice_buffer);
} }

@ -200,7 +200,7 @@ static grpc_error* init_call_elem(grpc_exec_ctx* exec_ctx,
// Destructor for call_data. // Destructor for call_data.
static void destroy_call_elem(grpc_exec_ctx* exec_ctx, grpc_call_element* elem, static void destroy_call_elem(grpc_exec_ctx* exec_ctx, grpc_call_element* elem,
const grpc_call_final_info* final_info, const grpc_call_final_info* final_info,
void* ignored) {} grpc_closure* ignored) {}
// Constructor for channel_data. // Constructor for channel_data.
static grpc_error* init_channel_elem(grpc_exec_ctx* exec_ctx, static grpc_error* init_channel_elem(grpc_exec_ctx* exec_ctx,

@ -35,6 +35,7 @@
#include <string.h> #include <string.h>
#include <grpc/slice.h>
#include <grpc/status.h> #include <grpc/status.h>
#include <grpc/support/alloc.h> #include <grpc/support/alloc.h>
#include <grpc/support/log.h> #include <grpc/support/log.h>
@ -47,46 +48,7 @@
#include "src/core/lib/iomgr/error_internal.h" #include "src/core/lib/iomgr/error_internal.h"
#include "src/core/lib/profiling/timers.h" #include "src/core/lib/profiling/timers.h"
#include "src/core/lib/slice/slice_internal.h"
static void destroy_integer(void *key) {}
static void *copy_integer(void *key) { return key; }
static long compare_integers(void *key1, void *key2) {
return GPR_ICMP((uintptr_t)key1, (uintptr_t)key2);
}
static void destroy_string(void *str) { gpr_free(str); }
static void *copy_string(void *str) { return gpr_strdup(str); }
static void destroy_err(void *err) { GRPC_ERROR_UNREF(err); }
static void *copy_err(void *err) { return GRPC_ERROR_REF(err); }
static void destroy_time(void *tm) { gpr_free(tm); }
static gpr_timespec *box_time(gpr_timespec tm) {
gpr_timespec *out = gpr_malloc(sizeof(*out));
*out = tm;
return out;
}
static void *copy_time(void *tm) { return box_time(*(gpr_timespec *)tm); }
static const gpr_avl_vtable avl_vtable_ints = {destroy_integer, copy_integer,
compare_integers,
destroy_integer, copy_integer};
static const gpr_avl_vtable avl_vtable_strs = {destroy_integer, copy_integer,
compare_integers, destroy_string,
copy_string};
static const gpr_avl_vtable avl_vtable_times = {
destroy_integer, copy_integer, compare_integers, destroy_time, copy_time};
static const gpr_avl_vtable avl_vtable_errs = {
destroy_integer, copy_integer, compare_integers, destroy_err, copy_err};
static const char *error_int_name(grpc_error_ints key) { static const char *error_int_name(grpc_error_ints key) {
switch (key) { switch (key) {
@ -120,6 +82,8 @@ static const char *error_int_name(grpc_error_ints key) {
return "limit"; return "limit";
case GRPC_ERROR_INT_OCCURRED_DURING_WRITE: case GRPC_ERROR_INT_OCCURRED_DURING_WRITE:
return "occurred_during_write"; return "occurred_during_write";
case GRPC_ERROR_INT_MAX:
GPR_UNREACHABLE_CODE(return "unknown");
} }
GPR_UNREACHABLE_CODE(return "unknown"); GPR_UNREACHABLE_CODE(return "unknown");
} }
@ -150,6 +114,8 @@ static const char *error_str_name(grpc_error_strs key) {
return "filename"; return "filename";
case GRPC_ERROR_STR_QUEUED_BUFFERS: case GRPC_ERROR_STR_QUEUED_BUFFERS:
return "queued_buffers"; return "queued_buffers";
case GRPC_ERROR_STR_MAX:
GPR_UNREACHABLE_CODE(return "unknown");
} }
GPR_UNREACHABLE_CODE(return "unknown"); GPR_UNREACHABLE_CODE(return "unknown");
} }
@ -158,6 +124,8 @@ static const char *error_time_name(grpc_error_times key) {
switch (key) { switch (key) {
case GRPC_ERROR_TIME_CREATED: case GRPC_ERROR_TIME_CREATED:
return "created"; return "created";
case GRPC_ERROR_TIME_MAX:
GPR_UNREACHABLE_CODE(return "unknown");
} }
GPR_UNREACHABLE_CODE(return "unknown"); GPR_UNREACHABLE_CODE(return "unknown");
} }
@ -172,25 +140,51 @@ grpc_error *grpc_error_ref(grpc_error *err, const char *file, int line,
const char *func) { const char *func) {
if (grpc_error_is_special(err)) return err; if (grpc_error_is_special(err)) return err;
gpr_log(GPR_DEBUG, "%p: %" PRIdPTR " -> %" PRIdPTR " [%s:%d %s]", err, gpr_log(GPR_DEBUG, "%p: %" PRIdPTR " -> %" PRIdPTR " [%s:%d %s]", err,
err->refs.count, err->refs.count + 1, file, line, func); gpr_atm_no_barrier_load(&err->atomics.refs.count),
gpr_ref(&err->refs); gpr_atm_no_barrier_load(&err->atomics.refs.count) + 1, file, line,
func);
gpr_ref(&err->atomics.refs);
return err; return err;
} }
#else #else
grpc_error *grpc_error_ref(grpc_error *err) { grpc_error *grpc_error_ref(grpc_error *err) {
if (grpc_error_is_special(err)) return err; if (grpc_error_is_special(err)) return err;
gpr_ref(&err->refs); gpr_ref(&err->atomics.refs);
return err; return err;
} }
#endif #endif
static void unref_errs(grpc_error *err) {
uint8_t slot = err->first_err;
while (slot != UINT8_MAX) {
grpc_linked_error *lerr = (grpc_linked_error *)(err->arena + slot);
GRPC_ERROR_UNREF(lerr->err);
GPR_ASSERT(err->last_err == slot ? lerr->next == UINT8_MAX
: lerr->next != UINT8_MAX);
slot = lerr->next;
}
}
static void unref_slice(grpc_slice slice) {
grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
grpc_slice_unref_internal(&exec_ctx, slice);
grpc_exec_ctx_finish(&exec_ctx);
}
static void unref_strs(grpc_error *err) {
for (size_t which = 0; which < GRPC_ERROR_STR_MAX; ++which) {
uint8_t slot = err->strs[which];
if (slot != UINT8_MAX) {
unref_slice(*(grpc_slice *)(err->arena + slot));
}
}
}
static void error_destroy(grpc_error *err) { static void error_destroy(grpc_error *err) {
GPR_ASSERT(!grpc_error_is_special(err)); GPR_ASSERT(!grpc_error_is_special(err));
gpr_avl_unref(err->ints); unref_errs(err);
gpr_avl_unref(err->strs); unref_strs(err);
gpr_avl_unref(err->errs); gpr_free((void *)gpr_atm_acq_load(&err->atomics.error_string));
gpr_avl_unref(err->times);
gpr_free((void *)gpr_atm_acq_load(&err->error_string));
gpr_free(err); gpr_free(err);
} }
@ -199,81 +193,209 @@ void grpc_error_unref(grpc_error *err, const char *file, int line,
const char *func) { const char *func) {
if (grpc_error_is_special(err)) return; if (grpc_error_is_special(err)) return;
gpr_log(GPR_DEBUG, "%p: %" PRIdPTR " -> %" PRIdPTR " [%s:%d %s]", err, gpr_log(GPR_DEBUG, "%p: %" PRIdPTR " -> %" PRIdPTR " [%s:%d %s]", err,
err->refs.count, err->refs.count - 1, file, line, func); gpr_atm_no_barrier_load(&err->atomics.refs.count),
if (gpr_unref(&err->refs)) { gpr_atm_no_barrier_load(&err->atomics.refs.count) - 1, file, line,
func);
if (gpr_unref(&err->atomics.refs)) {
error_destroy(err); error_destroy(err);
} }
} }
#else #else
void grpc_error_unref(grpc_error *err) { void grpc_error_unref(grpc_error *err) {
if (grpc_error_is_special(err)) return; if (grpc_error_is_special(err)) return;
if (gpr_unref(&err->refs)) { if (gpr_unref(&err->atomics.refs)) {
error_destroy(err); error_destroy(err);
} }
} }
#endif #endif
static uint8_t get_placement(grpc_error **err, size_t size) {
GPR_ASSERT(*err);
uint8_t slots = (uint8_t)(size / sizeof(intptr_t));
if ((*err)->arena_size + slots > (*err)->arena_capacity) {
(*err)->arena_capacity = (uint8_t)(3 * (*err)->arena_capacity / 2);
*err = gpr_realloc(
*err, sizeof(grpc_error) + (*err)->arena_capacity * sizeof(intptr_t));
}
uint8_t placement = (*err)->arena_size;
(*err)->arena_size = (uint8_t)((*err)->arena_size + slots);
return placement;
}
static void internal_set_int(grpc_error **err, grpc_error_ints which,
intptr_t value) {
// GPR_ASSERT((*err)->ints[which] == UINT8_MAX); // TODO, enforce this
uint8_t slot = (*err)->ints[which];
if (slot == UINT8_MAX) {
slot = get_placement(err, sizeof(value));
}
(*err)->ints[which] = slot;
(*err)->arena[slot] = value;
}
static void internal_set_str(grpc_error **err, grpc_error_strs which,
grpc_slice value) {
// GPR_ASSERT((*err)->strs[which] == UINT8_MAX); // TODO, enforce this
uint8_t slot = (*err)->strs[which];
if (slot == UINT8_MAX) {
slot = get_placement(err, sizeof(value));
} else {
unref_slice(*(grpc_slice *)((*err)->arena + slot));
}
(*err)->strs[which] = slot;
memcpy((*err)->arena + slot, &value, sizeof(value));
}
static void internal_set_time(grpc_error **err, grpc_error_times which,
gpr_timespec value) {
// GPR_ASSERT((*err)->times[which] == UINT8_MAX); // TODO, enforce this
uint8_t slot = (*err)->times[which];
if (slot == UINT8_MAX) {
slot = get_placement(err, sizeof(value));
}
(*err)->times[which] = slot;
memcpy((*err)->arena + slot, &value, sizeof(value));
}
static void internal_add_error(grpc_error **err, grpc_error *new) {
grpc_linked_error new_last = {new, UINT8_MAX};
uint8_t slot = get_placement(err, sizeof(grpc_linked_error));
if ((*err)->first_err == UINT8_MAX) {
GPR_ASSERT((*err)->last_err == UINT8_MAX);
(*err)->last_err = slot;
(*err)->first_err = slot;
} else {
GPR_ASSERT((*err)->last_err != UINT8_MAX);
grpc_linked_error *old_last =
(grpc_linked_error *)((*err)->arena + (*err)->last_err);
old_last->next = slot;
(*err)->last_err = slot;
}
memcpy((*err)->arena + slot, &new_last, sizeof(grpc_linked_error));
}
#define SLOTS_PER_INT (sizeof(intptr_t) / sizeof(intptr_t))
#define SLOTS_PER_STR (sizeof(grpc_slice) / sizeof(intptr_t))
#define SLOTS_PER_TIME (sizeof(gpr_timespec) / sizeof(intptr_t))
#define SLOTS_PER_LINKED_ERROR (sizeof(grpc_linked_error) / sizeof(intptr_t))
// size of storing one int and two slices and a timespec. For line, desc, file,
// and time created
#define DEFAULT_ERROR_CAPACITY \
(SLOTS_PER_INT + (SLOTS_PER_STR * 2) + SLOTS_PER_TIME)
// It is very common to include and extra int and string in an error
#define SURPLUS_CAPACITY (2 * SLOTS_PER_INT + SLOTS_PER_TIME)
grpc_error *grpc_error_create(const char *file, int line, const char *desc, grpc_error *grpc_error_create(const char *file, int line, const char *desc,
grpc_error **referencing, grpc_error **referencing,
size_t num_referencing) { size_t num_referencing) {
GPR_TIMER_BEGIN("grpc_error_create", 0); GPR_TIMER_BEGIN("grpc_error_create", 0);
grpc_error *err = gpr_malloc(sizeof(*err)); uint8_t initial_arena_capacity = (uint8_t)(
DEFAULT_ERROR_CAPACITY +
(uint8_t)(num_referencing * SLOTS_PER_LINKED_ERROR) + SURPLUS_CAPACITY);
grpc_error *err =
gpr_malloc(sizeof(*err) + initial_arena_capacity * sizeof(intptr_t));
if (err == NULL) { // TODO(ctiller): make gpr_malloc return NULL if (err == NULL) { // TODO(ctiller): make gpr_malloc return NULL
return GRPC_ERROR_OOM; return GRPC_ERROR_OOM;
} }
#ifdef GRPC_ERROR_REFCOUNT_DEBUG #ifdef GRPC_ERROR_REFCOUNT_DEBUG
gpr_log(GPR_DEBUG, "%p create [%s:%d]", err, file, line); gpr_log(GPR_DEBUG, "%p create [%s:%d]", err, file, line);
#endif #endif
err->ints = gpr_avl_add(gpr_avl_create(&avl_vtable_ints),
(void *)(uintptr_t)GRPC_ERROR_INT_FILE_LINE, err->arena_size = 0;
(void *)(uintptr_t)line); err->arena_capacity = initial_arena_capacity;
err->strs = gpr_avl_add( err->first_err = UINT8_MAX;
gpr_avl_add(gpr_avl_create(&avl_vtable_strs), err->last_err = UINT8_MAX;
(void *)(uintptr_t)GRPC_ERROR_STR_FILE, gpr_strdup(file)),
(void *)(uintptr_t)GRPC_ERROR_STR_DESCRIPTION, gpr_strdup(desc)); memset(err->ints, UINT8_MAX, GRPC_ERROR_INT_MAX);
err->errs = gpr_avl_create(&avl_vtable_errs); memset(err->strs, UINT8_MAX, GRPC_ERROR_STR_MAX);
err->next_err = 0; memset(err->times, UINT8_MAX, GRPC_ERROR_TIME_MAX);
for (size_t i = 0; i < num_referencing; i++) {
internal_set_int(&err, GRPC_ERROR_INT_FILE_LINE, line);
internal_set_str(&err, GRPC_ERROR_STR_FILE,
grpc_slice_from_static_string(file));
internal_set_str(
&err, GRPC_ERROR_STR_DESCRIPTION,
grpc_slice_from_copied_buffer(
desc,
strlen(desc) +
1)); // TODO, pull this up. // TODO(ncteisen), pull this up.
for (size_t i = 0; i < num_referencing; ++i) {
if (referencing[i] == GRPC_ERROR_NONE) continue; if (referencing[i] == GRPC_ERROR_NONE) continue;
err->errs = gpr_avl_add(err->errs, (void *)(err->next_err++), internal_add_error(
GRPC_ERROR_REF(referencing[i])); &err,
} GRPC_ERROR_REF(
err->times = gpr_avl_add(gpr_avl_create(&avl_vtable_times), referencing[i])); // TODO(ncteisen), change ownership semantics
(void *)(uintptr_t)GRPC_ERROR_TIME_CREATED, }
box_time(gpr_now(GPR_CLOCK_REALTIME)));
gpr_atm_no_barrier_store(&err->error_string, 0); internal_set_time(&err, GRPC_ERROR_TIME_CREATED, gpr_now(GPR_CLOCK_REALTIME));
gpr_ref_init(&err->refs, 1);
gpr_atm_no_barrier_store(&err->atomics.error_string, 0);
gpr_ref_init(&err->atomics.refs, 1);
GPR_TIMER_END("grpc_error_create", 0); GPR_TIMER_END("grpc_error_create", 0);
return err; return err;
} }
static void ref_strs(grpc_error *err) {
for (size_t i = 0; i < GRPC_ERROR_STR_MAX; ++i) {
uint8_t slot = err->strs[i];
if (slot != UINT8_MAX) {
grpc_slice_ref_internal(*(grpc_slice *)(err->arena + slot));
}
}
}
static void ref_errs(grpc_error *err) {
uint8_t slot = err->first_err;
while (slot != UINT8_MAX) {
grpc_linked_error *lerr = (grpc_linked_error *)(err->arena + slot);
GRPC_ERROR_REF(lerr->err);
slot = lerr->next;
}
}
static grpc_error *copy_error_and_unref(grpc_error *in) { static grpc_error *copy_error_and_unref(grpc_error *in) {
GPR_TIMER_BEGIN("copy_error_and_unref", 0); GPR_TIMER_BEGIN("copy_error_and_unref", 0);
grpc_error *out; grpc_error *out;
if (grpc_error_is_special(in)) { if (grpc_error_is_special(in)) {
if (in == GRPC_ERROR_NONE)
out = grpc_error_set_int(GRPC_ERROR_CREATE("no error"),
GRPC_ERROR_INT_GRPC_STATUS, GRPC_STATUS_OK);
else if (in == GRPC_ERROR_OOM)
out = GRPC_ERROR_CREATE("oom");
else if (in == GRPC_ERROR_CANCELLED)
out =
grpc_error_set_int(GRPC_ERROR_CREATE("cancelled"),
GRPC_ERROR_INT_GRPC_STATUS, GRPC_STATUS_CANCELLED);
else
out = GRPC_ERROR_CREATE("unknown"); out = GRPC_ERROR_CREATE("unknown");
if (in == GRPC_ERROR_NONE) {
internal_set_str(&out, GRPC_ERROR_STR_DESCRIPTION,
grpc_slice_from_static_string("no error"));
internal_set_int(&out, GRPC_ERROR_INT_GRPC_STATUS, GRPC_STATUS_OK);
} else if (in == GRPC_ERROR_OOM) {
internal_set_str(&out, GRPC_ERROR_STR_DESCRIPTION,
grpc_slice_from_static_string("oom"));
} else if (in == GRPC_ERROR_CANCELLED) {
internal_set_str(&out, GRPC_ERROR_STR_DESCRIPTION,
grpc_slice_from_static_string("cancelled"));
internal_set_int(&out, GRPC_ERROR_INT_GRPC_STATUS, GRPC_STATUS_CANCELLED);
}
} else if (gpr_ref_is_unique(&in->atomics.refs)) {
out = in;
} else { } else {
out = gpr_malloc(sizeof(*out)); uint8_t new_arena_capacity = in->arena_capacity;
// the returned err will be added to, so we ensure this is room to avoid
// unneeded allocations.
if (in->arena_capacity - in->arena_size < (uint8_t)SLOTS_PER_STR) {
new_arena_capacity = (uint8_t)(3 * new_arena_capacity / 2);
}
out = gpr_malloc(sizeof(*in) + new_arena_capacity * sizeof(intptr_t));
#ifdef GRPC_ERROR_REFCOUNT_DEBUG #ifdef GRPC_ERROR_REFCOUNT_DEBUG
gpr_log(GPR_DEBUG, "%p create copying %p", out, in); gpr_log(GPR_DEBUG, "%p create copying %p", out, in);
#endif #endif
out->ints = gpr_avl_ref(in->ints); // bulk memcpy of the rest of the struct.
out->strs = gpr_avl_ref(in->strs); size_t skip = sizeof(&out->atomics);
out->errs = gpr_avl_ref(in->errs); memcpy((void *)((uintptr_t)out + skip), (void *)((uintptr_t)in + skip),
out->times = gpr_avl_ref(in->times); sizeof(*in) + (in->arena_size * sizeof(intptr_t)) - skip);
gpr_atm_no_barrier_store(&out->error_string, 0); // manually set the atomics and the new capacity
out->next_err = in->next_err; gpr_atm_no_barrier_store(&out->atomics.error_string, 0);
gpr_ref_init(&out->refs, 1); gpr_ref_init(&out->atomics.refs, 1);
out->arena_capacity = new_arena_capacity;
ref_strs(out);
ref_errs(out);
GRPC_ERROR_UNREF(in); GRPC_ERROR_UNREF(in);
} }
GPR_TIMER_END("copy_error_and_unref", 0); GPR_TIMER_END("copy_error_and_unref", 0);
@ -284,7 +406,7 @@ grpc_error *grpc_error_set_int(grpc_error *src, grpc_error_ints which,
intptr_t value) { intptr_t value) {
GPR_TIMER_BEGIN("grpc_error_set_int", 0); GPR_TIMER_BEGIN("grpc_error_set_int", 0);
grpc_error *new = copy_error_and_unref(src); grpc_error *new = copy_error_and_unref(src);
new->ints = gpr_avl_add(new->ints, (void *)(uintptr_t)which, (void *)value); internal_set_int(&new, which, value);
GPR_TIMER_END("grpc_error_set_int", 0); GPR_TIMER_END("grpc_error_set_int", 0);
return new; return new;
} }
@ -302,7 +424,6 @@ static special_error_status_map error_status_map[] = {
bool grpc_error_get_int(grpc_error *err, grpc_error_ints which, intptr_t *p) { bool grpc_error_get_int(grpc_error *err, grpc_error_ints which, intptr_t *p) {
GPR_TIMER_BEGIN("grpc_error_get_int", 0); GPR_TIMER_BEGIN("grpc_error_get_int", 0);
void *pp;
if (grpc_error_is_special(err)) { if (grpc_error_is_special(err)) {
if (which == GRPC_ERROR_INT_GRPC_STATUS) { if (which == GRPC_ERROR_INT_GRPC_STATUS) {
for (size_t i = 0; i < GPR_ARRAY_SIZE(error_status_map); i++) { for (size_t i = 0; i < GPR_ARRAY_SIZE(error_status_map); i++) {
@ -316,8 +437,9 @@ bool grpc_error_get_int(grpc_error *err, grpc_error_ints which, intptr_t *p) {
GPR_TIMER_END("grpc_error_get_int", 0); GPR_TIMER_END("grpc_error_get_int", 0);
return false; return false;
} }
if (gpr_avl_maybe_get(err->ints, (void *)(uintptr_t)which, &pp)) { uint8_t slot = err->ints[which];
if (p != NULL) *p = (intptr_t)pp; if (slot != UINT8_MAX) {
if (p != NULL) *p = err->arena[slot];
GPR_TIMER_END("grpc_error_get_int", 0); GPR_TIMER_END("grpc_error_get_int", 0);
return true; return true;
} }
@ -329,8 +451,9 @@ grpc_error *grpc_error_set_str(grpc_error *src, grpc_error_strs which,
const char *value) { const char *value) {
GPR_TIMER_BEGIN("grpc_error_set_str", 0); GPR_TIMER_BEGIN("grpc_error_set_str", 0);
grpc_error *new = copy_error_and_unref(src); grpc_error *new = copy_error_and_unref(src);
new->strs = internal_set_str(&new, which,
gpr_avl_add(new->strs, (void *)(uintptr_t)which, gpr_strdup(value)); grpc_slice_from_copied_buffer(
value, strlen(value) + 1)); // TODO, pull this up.
GPR_TIMER_END("grpc_error_set_str", 0); GPR_TIMER_END("grpc_error_set_str", 0);
return new; return new;
} }
@ -346,13 +469,19 @@ const char *grpc_error_get_str(grpc_error *err, grpc_error_strs which) {
} }
return NULL; return NULL;
} }
return gpr_avl_get(err->strs, (void *)(uintptr_t)which); uint8_t slot = err->strs[which];
if (slot != UINT8_MAX) {
return (const char *)GRPC_SLICE_START_PTR(
*(grpc_slice *)(err->arena + slot));
} else {
return NULL;
}
} }
grpc_error *grpc_error_add_child(grpc_error *src, grpc_error *child) { grpc_error *grpc_error_add_child(grpc_error *src, grpc_error *child) {
GPR_TIMER_BEGIN("grpc_error_add_child", 0); GPR_TIMER_BEGIN("grpc_error_add_child", 0);
grpc_error *new = copy_error_and_unref(src); grpc_error *new = copy_error_and_unref(src);
new->errs = gpr_avl_add(new->errs, (void *)(new->next_err++), child); internal_add_error(&new, child);
GPR_TIMER_END("grpc_error_add_child", 0); GPR_TIMER_END("grpc_error_add_child", 0);
return new; return new;
} }
@ -372,42 +501,6 @@ typedef struct {
size_t cap_kvs; size_t cap_kvs;
} kv_pairs; } kv_pairs;
static void append_kv(kv_pairs *kvs, char *key, char *value) {
if (kvs->num_kvs == kvs->cap_kvs) {
kvs->cap_kvs = GPR_MAX(3 * kvs->cap_kvs / 2, 4);
kvs->kvs = gpr_realloc(kvs->kvs, sizeof(*kvs->kvs) * kvs->cap_kvs);
}
kvs->kvs[kvs->num_kvs].key = key;
kvs->kvs[kvs->num_kvs].value = value;
kvs->num_kvs++;
}
static void collect_kvs(gpr_avl_node *node, char *key(void *k),
char *fmt(void *v), kv_pairs *kvs) {
if (node == NULL) return;
append_kv(kvs, key(node->key), fmt(node->value));
collect_kvs(node->left, key, fmt, kvs);
collect_kvs(node->right, key, fmt, kvs);
}
static char *key_int(void *p) {
return gpr_strdup(error_int_name((grpc_error_ints)(uintptr_t)p));
}
static char *key_str(void *p) {
return gpr_strdup(error_str_name((grpc_error_strs)(uintptr_t)p));
}
static char *key_time(void *p) {
return gpr_strdup(error_time_name((grpc_error_times)(uintptr_t)p));
}
static char *fmt_int(void *p) {
char *s;
gpr_asprintf(&s, "%" PRIdPTR, (intptr_t)p);
return s;
}
static void append_chr(char c, char **s, size_t *sz, size_t *cap) { static void append_chr(char c, char **s, size_t *sz, size_t *cap) {
if (*sz == *cap) { if (*sz == *cap) {
*cap = GPR_MAX(8, 3 * *cap / 2); *cap = GPR_MAX(8, 3 * *cap / 2);
@ -459,6 +552,40 @@ static void append_esc_str(const char *str, char **s, size_t *sz, size_t *cap) {
append_chr('"', s, sz, cap); append_chr('"', s, sz, cap);
} }
static void append_kv(kv_pairs *kvs, char *key, char *value) {
if (kvs->num_kvs == kvs->cap_kvs) {
kvs->cap_kvs = GPR_MAX(3 * kvs->cap_kvs / 2, 4);
kvs->kvs = gpr_realloc(kvs->kvs, sizeof(*kvs->kvs) * kvs->cap_kvs);
}
kvs->kvs[kvs->num_kvs].key = key;
kvs->kvs[kvs->num_kvs].value = value;
kvs->num_kvs++;
}
static char *key_int(grpc_error_ints which) {
return gpr_strdup(error_int_name(which));
}
static char *fmt_int(intptr_t p) {
char *s;
gpr_asprintf(&s, "%" PRIdPTR, p);
return s;
}
static void collect_ints_kvs(grpc_error *err, kv_pairs *kvs) {
for (size_t which = 0; which < GRPC_ERROR_INT_MAX; ++which) {
uint8_t slot = err->ints[which];
if (slot != UINT8_MAX) {
append_kv(kvs, key_int((grpc_error_ints)which),
fmt_int(err->arena[slot]));
}
}
}
static char *key_str(grpc_error_strs which) {
return gpr_strdup(error_str_name(which));
}
static char *fmt_str(void *p) { static char *fmt_str(void *p) {
char *s = NULL; char *s = NULL;
size_t sz = 0; size_t sz = 0;
@ -468,8 +595,22 @@ static char *fmt_str(void *p) {
return s; return s;
} }
static char *fmt_time(void *p) { static void collect_strs_kvs(grpc_error *err, kv_pairs *kvs) {
gpr_timespec tm = *(gpr_timespec *)p; for (size_t which = 0; which < GRPC_ERROR_STR_MAX; ++which) {
uint8_t slot = err->strs[which];
if (slot != UINT8_MAX) {
append_kv(
kvs, key_str((grpc_error_strs)which),
fmt_str(GRPC_SLICE_START_PTR(*(grpc_slice *)(err->arena + slot))));
}
}
}
static char *key_time(grpc_error_times which) {
return gpr_strdup(error_time_name(which));
}
static char *fmt_time(gpr_timespec tm) {
char *out; char *out;
char *pfx = "!!"; char *pfx = "!!";
switch (tm.clock_type) { switch (tm.clock_type) {
@ -490,24 +631,37 @@ static char *fmt_time(void *p) {
return out; return out;
} }
static void add_errs(gpr_avl_node *n, char **s, size_t *sz, size_t *cap, static void collect_times_kvs(grpc_error *err, kv_pairs *kvs) {
bool *first) { for (size_t which = 0; which < GRPC_ERROR_TIME_MAX; ++which) {
if (n == NULL) return; uint8_t slot = err->times[which];
add_errs(n->left, s, sz, cap, first); if (slot != UINT8_MAX) {
if (!*first) append_chr(',', s, sz, cap); append_kv(kvs, key_time((grpc_error_times)which),
*first = false; fmt_time(*(gpr_timespec *)(err->arena + slot)));
const char *e = grpc_error_string(n->value); }
}
}
static void add_errs(grpc_error *err, char **s, size_t *sz, size_t *cap) {
uint8_t slot = err->first_err;
bool first = true;
while (slot != UINT8_MAX) {
grpc_linked_error *lerr = (grpc_linked_error *)(err->arena + slot);
if (!first) append_chr(',', s, sz, cap);
first = false;
const char *e = grpc_error_string(lerr->err);
append_str(e, s, sz, cap); append_str(e, s, sz, cap);
add_errs(n->right, s, sz, cap, first); GPR_ASSERT(err->last_err == slot ? lerr->next == UINT8_MAX
: lerr->next != UINT8_MAX);
slot = lerr->next;
}
} }
static char *errs_string(grpc_error *err) { static char *errs_string(grpc_error *err) {
char *s = NULL; char *s = NULL;
size_t sz = 0; size_t sz = 0;
size_t cap = 0; size_t cap = 0;
bool first = true;
append_chr('[', &s, &sz, &cap); append_chr('[', &s, &sz, &cap);
add_errs(err->errs.root, &s, &sz, &cap, &first); add_errs(err, &s, &sz, &cap);
append_chr(']', &s, &sz, &cap); append_chr(']', &s, &sz, &cap);
append_chr(0, &s, &sz, &cap); append_chr(0, &s, &sz, &cap);
return s; return s;
@ -546,7 +700,7 @@ const char *grpc_error_string(grpc_error *err) {
if (err == GRPC_ERROR_OOM) return oom_error_string; if (err == GRPC_ERROR_OOM) return oom_error_string;
if (err == GRPC_ERROR_CANCELLED) return cancelled_error_string; if (err == GRPC_ERROR_CANCELLED) return cancelled_error_string;
void *p = (void *)gpr_atm_acq_load(&err->error_string); void *p = (void *)gpr_atm_acq_load(&err->atomics.error_string);
if (p != NULL) { if (p != NULL) {
GPR_TIMER_END("grpc_error_string", 0); GPR_TIMER_END("grpc_error_string", 0);
return p; return p;
@ -555,10 +709,10 @@ const char *grpc_error_string(grpc_error *err) {
kv_pairs kvs; kv_pairs kvs;
memset(&kvs, 0, sizeof(kvs)); memset(&kvs, 0, sizeof(kvs));
collect_kvs(err->ints.root, key_int, fmt_int, &kvs); collect_ints_kvs(err, &kvs);
collect_kvs(err->strs.root, key_str, fmt_str, &kvs); collect_strs_kvs(err, &kvs);
collect_kvs(err->times.root, key_time, fmt_time, &kvs); collect_times_kvs(err, &kvs);
if (!gpr_avl_is_empty(err->errs)) { if (err->first_err != UINT8_MAX) {
append_kv(&kvs, gpr_strdup("referenced_errors"), errs_string(err)); append_kv(&kvs, gpr_strdup("referenced_errors"), errs_string(err));
} }
@ -566,9 +720,9 @@ const char *grpc_error_string(grpc_error *err) {
char *out = finish_kvs(&kvs); char *out = finish_kvs(&kvs);
if (!gpr_atm_rel_cas(&err->error_string, 0, (gpr_atm)out)) { if (!gpr_atm_rel_cas(&err->atomics.error_string, 0, (gpr_atm)out)) {
gpr_free(out); gpr_free(out);
out = (char *)gpr_atm_no_barrier_load(&err->error_string); out = (char *)gpr_atm_no_barrier_load(&err->atomics.error_string);
} }
GPR_TIMER_END("grpc_error_string", 0); GPR_TIMER_END("grpc_error_string", 0);

@ -102,6 +102,9 @@ typedef enum {
GRPC_ERROR_INT_LIMIT, GRPC_ERROR_INT_LIMIT,
/// chttp2: did the error occur while a write was in progress /// chttp2: did the error occur while a write was in progress
GRPC_ERROR_INT_OCCURRED_DURING_WRITE, GRPC_ERROR_INT_OCCURRED_DURING_WRITE,
/// Must always be last
GRPC_ERROR_INT_MAX,
} grpc_error_ints; } grpc_error_ints;
typedef enum { typedef enum {
@ -129,11 +132,17 @@ typedef enum {
GRPC_ERROR_STR_KEY, GRPC_ERROR_STR_KEY,
/// value associated with the error /// value associated with the error
GRPC_ERROR_STR_VALUE, GRPC_ERROR_STR_VALUE,
/// Must always be last
GRPC_ERROR_STR_MAX,
} grpc_error_strs; } grpc_error_strs;
typedef enum { typedef enum {
/// timestamp of error creation /// timestamp of error creation
GRPC_ERROR_TIME_CREATED, GRPC_ERROR_TIME_CREATED,
/// Must always be last
GRPC_ERROR_TIME_MAX,
} grpc_error_times; } grpc_error_times;
/// The following "special" errors can be propagated without allocating memory. /// The following "special" errors can be propagated without allocating memory.
@ -184,8 +193,6 @@ void grpc_error_unref(grpc_error *err);
grpc_error *grpc_error_set_int(grpc_error *src, grpc_error_ints which, grpc_error *grpc_error_set_int(grpc_error *src, grpc_error_ints which,
intptr_t value) GRPC_MUST_USE_RESULT; intptr_t value) GRPC_MUST_USE_RESULT;
bool grpc_error_get_int(grpc_error *error, grpc_error_ints which, intptr_t *p); bool grpc_error_get_int(grpc_error *error, grpc_error_ints which, intptr_t *p);
grpc_error *grpc_error_set_time(grpc_error *src, grpc_error_times which,
gpr_timespec value) GRPC_MUST_USE_RESULT;
grpc_error *grpc_error_set_str(grpc_error *src, grpc_error_strs which, grpc_error *grpc_error_set_str(grpc_error *src, grpc_error_strs which,
const char *value) GRPC_MUST_USE_RESULT; const char *value) GRPC_MUST_USE_RESULT;
/// Returns NULL if the specified string is not set. /// Returns NULL if the specified string is not set.

@ -35,18 +35,39 @@
#define GRPC_CORE_LIB_IOMGR_ERROR_INTERNAL_H #define GRPC_CORE_LIB_IOMGR_ERROR_INTERNAL_H
#include <inttypes.h> #include <inttypes.h>
#include <stdbool.h> #include <stdbool.h> // TODO, do we need this?
#include <grpc/support/avl.h> #include <grpc/support/sync.h>
typedef struct grpc_linked_error grpc_linked_error;
struct grpc_linked_error {
grpc_error *err;
uint8_t next;
};
// c core representation of an error. See error.h for high level description of
// this object.
struct grpc_error { struct grpc_error {
// All atomics in grpc_error must be stored in this nested struct. The rest of
// the object is memcpy-ed in bulk in copy_and_unref.
struct atomics {
gpr_refcount refs; gpr_refcount refs;
gpr_avl ints;
gpr_avl strs;
gpr_avl times;
gpr_avl errs;
uintptr_t next_err;
gpr_atm error_string; gpr_atm error_string;
} atomics;
// These arrays index into dynamic arena at the bottom of the struct.
// UINT8_MAX is used as a sentinel value.
uint8_t ints[GRPC_ERROR_INT_MAX];
uint8_t strs[GRPC_ERROR_STR_MAX];
uint8_t times[GRPC_ERROR_TIME_MAX];
// The child errors are stored in the arena, but are effectively a linked list
// structure, since they are contained withing grpc_linked_error objects.
uint8_t first_err;
uint8_t last_err;
// The arena is dynamically reallocated with a grow factor of 1.5.
uint8_t arena_size;
uint8_t arena_capacity;
intptr_t arena[0];
}; };
bool grpc_error_is_special(grpc_error *err); bool grpc_error_is_special(grpc_error *err);

@ -39,6 +39,7 @@
#include <string.h> #include <string.h>
#include <grpc/support/alloc.h>
#include <grpc/support/log.h> #include <grpc/support/log.h>
#include <grpc/support/sync.h> #include <grpc/support/sync.h>
@ -61,25 +62,30 @@ gpr_mu grpc_polling_mu;
immediately in the next loop iteration. immediately in the next loop iteration.
Note: In the future, if there is a bug that involves missing wakeups in the Note: In the future, if there is a bug that involves missing wakeups in the
future, try adding a uv_async_t to kick the loop differently */ future, try adding a uv_async_t to kick the loop differently */
uv_timer_t dummy_uv_handle; uv_timer_t *dummy_uv_handle;
size_t grpc_pollset_size() { return sizeof(grpc_pollset); } size_t grpc_pollset_size() { return sizeof(grpc_pollset); }
void dummy_timer_cb(uv_timer_t *handle) {} void dummy_timer_cb(uv_timer_t *handle) {}
void dummy_handle_close_cb(uv_handle_t *handle) { gpr_free(handle); }
void grpc_pollset_global_init(void) { void grpc_pollset_global_init(void) {
gpr_mu_init(&grpc_polling_mu); gpr_mu_init(&grpc_polling_mu);
uv_timer_init(uv_default_loop(), &dummy_uv_handle); dummy_uv_handle = gpr_malloc(sizeof(uv_timer_t));
uv_timer_init(uv_default_loop(), dummy_uv_handle);
grpc_pollset_work_run_loop = 1; grpc_pollset_work_run_loop = 1;
} }
static void timer_close_cb(uv_handle_t *handle) { handle->data = (void *)1; }
void grpc_pollset_global_shutdown(void) { void grpc_pollset_global_shutdown(void) {
gpr_mu_destroy(&grpc_polling_mu); gpr_mu_destroy(&grpc_polling_mu);
uv_close((uv_handle_t *)&dummy_uv_handle, timer_close_cb); uv_close((uv_handle_t *)dummy_uv_handle, dummy_handle_close_cb);
} }
static void timer_run_cb(uv_timer_t *timer) {}
static void timer_close_cb(uv_handle_t *handle) { handle->data = (void *)1; }
void grpc_pollset_init(grpc_pollset *pollset, gpr_mu **mu) { void grpc_pollset_init(grpc_pollset *pollset, gpr_mu **mu) {
*mu = &grpc_polling_mu; *mu = &grpc_polling_mu;
uv_timer_init(uv_default_loop(), &pollset->timer); uv_timer_init(uv_default_loop(), &pollset->timer);
@ -95,7 +101,7 @@ void grpc_pollset_shutdown(grpc_exec_ctx *exec_ctx, grpc_pollset *pollset,
uv_run(uv_default_loop(), UV_RUN_NOWAIT); uv_run(uv_default_loop(), UV_RUN_NOWAIT);
} else { } else {
// kick the loop once // kick the loop once
uv_timer_start(&dummy_uv_handle, dummy_timer_cb, 0, 0); uv_timer_start(dummy_uv_handle, dummy_timer_cb, 0, 0);
} }
grpc_closure_sched(exec_ctx, closure, GRPC_ERROR_NONE); grpc_closure_sched(exec_ctx, closure, GRPC_ERROR_NONE);
} }
@ -111,8 +117,6 @@ void grpc_pollset_destroy(grpc_pollset *pollset) {
} }
} }
static void timer_run_cb(uv_timer_t *timer) {}
grpc_error *grpc_pollset_work(grpc_exec_ctx *exec_ctx, grpc_pollset *pollset, grpc_error *grpc_pollset_work(grpc_exec_ctx *exec_ctx, grpc_pollset *pollset,
grpc_pollset_worker **worker_hdl, grpc_pollset_worker **worker_hdl,
gpr_timespec now, gpr_timespec deadline) { gpr_timespec now, gpr_timespec deadline) {
@ -145,7 +149,7 @@ grpc_error *grpc_pollset_work(grpc_exec_ctx *exec_ctx, grpc_pollset *pollset,
grpc_error *grpc_pollset_kick(grpc_pollset *pollset, grpc_error *grpc_pollset_kick(grpc_pollset *pollset,
grpc_pollset_worker *specific_worker) { grpc_pollset_worker *specific_worker) {
uv_timer_start(&dummy_uv_handle, dummy_timer_cb, 0, 0); uv_timer_start(dummy_uv_handle, dummy_timer_cb, 0, 0);
return GRPC_ERROR_NONE; return GRPC_ERROR_NONE;
} }

@ -39,6 +39,7 @@
#if defined(GRPC_UV) #if defined(GRPC_UV)
// Do nothing // Do nothing
#elif defined(GPR_MANYLINUX1) #elif defined(GPR_MANYLINUX1)
#define GRPC_HAVE_IFADDRS 1
#define GRPC_HAVE_IPV6_RECVPKTINFO 1 #define GRPC_HAVE_IPV6_RECVPKTINFO 1
#define GRPC_HAVE_IP_PKTINFO 1 #define GRPC_HAVE_IP_PKTINFO 1
#define GRPC_HAVE_MSG_NOSIGNAL 1 #define GRPC_HAVE_MSG_NOSIGNAL 1
@ -65,6 +66,7 @@
#define GRPC_POSIX_WAKEUP_FD 1 #define GRPC_POSIX_WAKEUP_FD 1
#define GRPC_TIMER_USE_GENERIC 1 #define GRPC_TIMER_USE_GENERIC 1
#elif defined(GPR_LINUX) #elif defined(GPR_LINUX)
#define GRPC_HAVE_IFADDRS 1
#define GRPC_HAVE_IPV6_RECVPKTINFO 1 #define GRPC_HAVE_IPV6_RECVPKTINFO 1
#define GRPC_HAVE_IP_PKTINFO 1 #define GRPC_HAVE_IP_PKTINFO 1
#define GRPC_HAVE_MSG_NOSIGNAL 1 #define GRPC_HAVE_MSG_NOSIGNAL 1
@ -90,6 +92,7 @@
#define GRPC_POSIX_SOCKETUTILS #define GRPC_POSIX_SOCKETUTILS
#endif #endif
#elif defined(GPR_APPLE) #elif defined(GPR_APPLE)
#define GRPC_HAVE_IFADDRS 1
#define GRPC_HAVE_SO_NOSIGPIPE 1 #define GRPC_HAVE_SO_NOSIGPIPE 1
#define GRPC_HAVE_UNIX_SOCKET 1 #define GRPC_HAVE_UNIX_SOCKET 1
#define GRPC_MSG_IOVLEN_TYPE int #define GRPC_MSG_IOVLEN_TYPE int
@ -100,6 +103,7 @@
#define GRPC_POSIX_WAKEUP_FD 1 #define GRPC_POSIX_WAKEUP_FD 1
#define GRPC_TIMER_USE_GENERIC 1 #define GRPC_TIMER_USE_GENERIC 1
#elif defined(GPR_FREEBSD) #elif defined(GPR_FREEBSD)
#define GRPC_HAVE_IFADDRS 1
#define GRPC_HAVE_IPV6_RECVPKTINFO 1 #define GRPC_HAVE_IPV6_RECVPKTINFO 1
#define GRPC_HAVE_SO_NOSIGPIPE 1 #define GRPC_HAVE_SO_NOSIGPIPE 1
#define GRPC_HAVE_UNIX_SOCKET 1 #define GRPC_HAVE_UNIX_SOCKET 1

@ -40,6 +40,7 @@
#include <grpc/support/host_port.h> #include <grpc/support/host_port.h>
#include <grpc/support/log.h> #include <grpc/support/log.h>
#include <grpc/support/string_util.h> #include <grpc/support/string_util.h>
#include <grpc/support/useful.h>
#include "src/core/lib/iomgr/closure.h" #include "src/core/lib/iomgr/closure.h"
#include "src/core/lib/iomgr/error.h" #include "src/core/lib/iomgr/error.h"
@ -54,8 +55,36 @@ typedef struct request {
grpc_closure *on_done; grpc_closure *on_done;
grpc_resolved_addresses **addresses; grpc_resolved_addresses **addresses;
struct addrinfo *hints; struct addrinfo *hints;
char *host;
char *port;
} request; } request;
static int retry_named_port_failure(int status, request *r,
uv_getaddrinfo_cb getaddrinfo_cb) {
if (status != 0) {
// This loop is copied from resolve_address_posix.c
char *svc[][2] = {{"http", "80"}, {"https", "443"}};
for (size_t i = 0; i < GPR_ARRAY_SIZE(svc); i++) {
if (strcmp(r->port, svc[i][0]) == 0) {
int retry_status;
uv_getaddrinfo_t *req = gpr_malloc(sizeof(uv_getaddrinfo_t));
req->data = r;
retry_status = uv_getaddrinfo(uv_default_loop(), req, getaddrinfo_cb,
r->host, svc[i][1], r->hints);
if (retry_status < 0 || getaddrinfo_cb == NULL) {
// The callback will not be called
gpr_free(req);
}
return retry_status;
}
}
}
/* If this function calls uv_getaddrinfo, it will return that function's
return value. That function only returns numbers <=0, so we can safely
return 1 to indicate that we never retried */
return 1;
}
static grpc_error *handle_addrinfo_result(int status, struct addrinfo *result, static grpc_error *handle_addrinfo_result(int status, struct addrinfo *result,
grpc_resolved_addresses **addresses) { grpc_resolved_addresses **addresses) {
struct addrinfo *resp; struct addrinfo *resp;
@ -97,13 +126,21 @@ static void getaddrinfo_callback(uv_getaddrinfo_t *req, int status,
request *r = (request *)req->data; request *r = (request *)req->data;
grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT; grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
grpc_error *error; grpc_error *error;
int retry_status;
gpr_free(req);
retry_status = retry_named_port_failure(status, r, getaddrinfo_callback);
if (retry_status == 0) {
// The request is being retried. Nothing should be done here
return;
}
/* Either no retry was attempted, or the retry failed. Either way, the
original error probably has more interesting information */
error = handle_addrinfo_result(status, res, r->addresses); error = handle_addrinfo_result(status, res, r->addresses);
grpc_closure_sched(&exec_ctx, r->on_done, error); grpc_closure_sched(&exec_ctx, r->on_done, error);
grpc_exec_ctx_finish(&exec_ctx); grpc_exec_ctx_finish(&exec_ctx);
gpr_free(r->hints); gpr_free(r->hints);
gpr_free(r); gpr_free(r);
gpr_free(req);
uv_freeaddrinfo(res); uv_freeaddrinfo(res);
} }
@ -143,6 +180,7 @@ static grpc_error *blocking_resolve_address_impl(
uv_getaddrinfo_t req; uv_getaddrinfo_t req;
int s; int s;
grpc_error *err; grpc_error *err;
int retry_status;
req.addrinfo = NULL; req.addrinfo = NULL;
@ -158,6 +196,12 @@ static grpc_error *blocking_resolve_address_impl(
hints.ai_flags = AI_PASSIVE; /* for wildcard IP address */ hints.ai_flags = AI_PASSIVE; /* for wildcard IP address */
s = uv_getaddrinfo(uv_default_loop(), &req, NULL, host, port, &hints); s = uv_getaddrinfo(uv_default_loop(), &req, NULL, host, port, &hints);
request r = {
.addresses = addresses, .hints = &hints, .host = host, .port = port};
retry_status = retry_named_port_failure(s, &r, NULL);
if (retry_status <= 0) {
s = retry_status;
}
err = handle_addrinfo_result(s, req.addrinfo, addresses); err = handle_addrinfo_result(s, req.addrinfo, addresses);
done: done:
@ -200,6 +244,8 @@ static void resolve_address_impl(grpc_exec_ctx *exec_ctx, const char *name,
r = gpr_malloc(sizeof(request)); r = gpr_malloc(sizeof(request));
r->on_done = on_done; r->on_done = on_done;
r->addresses = addrs; r->addresses = addrs;
r->host = host;
r->port = port;
req = gpr_malloc(sizeof(uv_getaddrinfo_t)); req = gpr_malloc(sizeof(uv_getaddrinfo_t));
req->data = r; req->data = r;
@ -222,6 +268,8 @@ static void resolve_address_impl(grpc_exec_ctx *exec_ctx, const char *name,
gpr_free(r); gpr_free(r);
gpr_free(req); gpr_free(req);
gpr_free(hints); gpr_free(hints);
gpr_free(host);
gpr_free(port);
} }
} }

@ -76,7 +76,6 @@ static void uv_tc_on_alarm(grpc_exec_ctx *exec_ctx, void *acp,
const char *str = grpc_error_string(error); const char *str = grpc_error_string(error);
gpr_log(GPR_DEBUG, "CLIENT_CONNECT: %s: on_alarm: error=%s", gpr_log(GPR_DEBUG, "CLIENT_CONNECT: %s: on_alarm: error=%s",
connect->addr_name, str); connect->addr_name, str);
grpc_error_free_string(str);
} }
if (error == GRPC_ERROR_NONE) { if (error == GRPC_ERROR_NONE) {
/* error == NONE implies that the timer ran out, and wasn't cancelled. If /* error == NONE implies that the timer ran out, and wasn't cancelled. If

@ -44,11 +44,8 @@
#include <errno.h> #include <errno.h>
#include <fcntl.h> #include <fcntl.h>
#include <ifaddrs.h>
#include <limits.h>
#include <netinet/in.h> #include <netinet/in.h>
#include <netinet/tcp.h> #include <netinet/tcp.h>
#include <stdio.h>
#include <string.h> #include <string.h>
#include <sys/socket.h> #include <sys/socket.h>
#include <sys/stat.h> #include <sys/stat.h>
@ -67,80 +64,10 @@
#include "src/core/lib/iomgr/sockaddr_utils.h" #include "src/core/lib/iomgr/sockaddr_utils.h"
#include "src/core/lib/iomgr/socket_utils_posix.h" #include "src/core/lib/iomgr/socket_utils_posix.h"
#include "src/core/lib/iomgr/tcp_posix.h" #include "src/core/lib/iomgr/tcp_posix.h"
#include "src/core/lib/iomgr/tcp_server_utils_posix.h"
#include "src/core/lib/iomgr/unix_sockets_posix.h" #include "src/core/lib/iomgr/unix_sockets_posix.h"
#include "src/core/lib/support/string.h" #include "src/core/lib/support/string.h"
#define MIN_SAFE_ACCEPT_QUEUE_SIZE 100
static gpr_once s_init_max_accept_queue_size;
static int s_max_accept_queue_size;
/* one listening port */
typedef struct grpc_tcp_listener grpc_tcp_listener;
struct grpc_tcp_listener {
int fd;
grpc_fd *emfd;
grpc_tcp_server *server;
grpc_resolved_address addr;
int port;
unsigned port_index;
unsigned fd_index;
grpc_closure read_closure;
grpc_closure destroyed_closure;
struct grpc_tcp_listener *next;
/* sibling is a linked list of all listeners for a given port. add_port and
clone_port place all new listeners in the same sibling list. A member of
the 'sibling' list is also a member of the 'next' list. The head of each
sibling list has is_sibling==0, and subsequent members of sibling lists
have is_sibling==1. is_sibling allows separate sibling lists to be
identified while iterating through 'next'. */
struct grpc_tcp_listener *sibling;
int is_sibling;
};
/* the overall server */
struct grpc_tcp_server {
gpr_refcount refs;
/* Called whenever accept() succeeds on a server port. */
grpc_tcp_server_cb on_accept_cb;
void *on_accept_cb_arg;
gpr_mu mu;
/* active port count: how many ports are actually still listening */
size_t active_ports;
/* destroyed port count: how many ports are completely destroyed */
size_t destroyed_ports;
/* is this server shutting down? */
bool shutdown;
/* use SO_REUSEPORT */
bool so_reuseport;
/* expand wildcard addresses to a list of all local addresses */
bool expand_wildcard_addrs;
/* linked list of server ports */
grpc_tcp_listener *head;
grpc_tcp_listener *tail;
unsigned nports;
/* List of closures passed to shutdown_starting_add(). */
grpc_closure_list shutdown_starting;
/* shutdown callback */
grpc_closure *shutdown_complete;
/* all pollsets interested in new connections */
grpc_pollset **pollsets;
/* number of pollsets in the pollsets array */
size_t pollset_count;
/* next pollset to assign a channel to */
gpr_atm next_pollset_to_assign;
grpc_resource_quota *resource_quota;
};
static gpr_once check_init = GPR_ONCE_INIT; static gpr_once check_init = GPR_ONCE_INIT;
static bool has_so_reuseport = false; static bool has_so_reuseport = false;
@ -161,7 +88,7 @@ grpc_error *grpc_tcp_server_create(grpc_exec_ctx *exec_ctx,
grpc_tcp_server **server) { grpc_tcp_server **server) {
gpr_once_init(&check_init, init); gpr_once_init(&check_init, init);
grpc_tcp_server *s = gpr_malloc(sizeof(grpc_tcp_server)); grpc_tcp_server *s = gpr_zalloc(sizeof(grpc_tcp_server));
s->so_reuseport = has_so_reuseport; s->so_reuseport = has_so_reuseport;
s->resource_quota = grpc_resource_quota_create(NULL); s->resource_quota = grpc_resource_quota_create(NULL);
s->expand_wildcard_addrs = false; s->expand_wildcard_addrs = false;
@ -299,99 +226,6 @@ static void tcp_server_destroy(grpc_exec_ctx *exec_ctx, grpc_tcp_server *s) {
} }
} }
/* get max listen queue size on linux */
static void init_max_accept_queue_size(void) {
int n = SOMAXCONN;
char buf[64];
FILE *fp = fopen("/proc/sys/net/core/somaxconn", "r");
if (fp == NULL) {
/* 2.4 kernel. */
s_max_accept_queue_size = SOMAXCONN;
return;
}
if (fgets(buf, sizeof buf, fp)) {
char *end;
long i = strtol(buf, &end, 10);
if (i > 0 && i <= INT_MAX && end && *end == 0) {
n = (int)i;
}
}
fclose(fp);
s_max_accept_queue_size = n;
if (s_max_accept_queue_size < MIN_SAFE_ACCEPT_QUEUE_SIZE) {
gpr_log(GPR_INFO,
"Suspiciously small accept queue (%d) will probably lead to "
"connection drops",
s_max_accept_queue_size);
}
}
static int get_max_accept_queue_size(void) {
gpr_once_init(&s_init_max_accept_queue_size, init_max_accept_queue_size);
return s_max_accept_queue_size;
}
/* Prepare a recently-created socket for listening. */
static grpc_error *prepare_socket(int fd, const grpc_resolved_address *addr,
bool so_reuseport, int *port) {
grpc_resolved_address sockname_temp;
grpc_error *err = GRPC_ERROR_NONE;
GPR_ASSERT(fd >= 0);
if (so_reuseport && !grpc_is_unix_socket(addr)) {
err = grpc_set_socket_reuse_port(fd, 1);
if (err != GRPC_ERROR_NONE) goto error;
}
err = grpc_set_socket_nonblocking(fd, 1);
if (err != GRPC_ERROR_NONE) goto error;
err = grpc_set_socket_cloexec(fd, 1);
if (err != GRPC_ERROR_NONE) goto error;
if (!grpc_is_unix_socket(addr)) {
err = grpc_set_socket_low_latency(fd, 1);
if (err != GRPC_ERROR_NONE) goto error;
err = grpc_set_socket_reuse_addr(fd, 1);
if (err != GRPC_ERROR_NONE) goto error;
}
err = grpc_set_socket_no_sigpipe_if_possible(fd);
if (err != GRPC_ERROR_NONE) goto error;
GPR_ASSERT(addr->len < ~(socklen_t)0);
if (bind(fd, (struct sockaddr *)addr->addr, (socklen_t)addr->len) < 0) {
err = GRPC_OS_ERROR(errno, "bind");
goto error;
}
if (listen(fd, get_max_accept_queue_size()) < 0) {
err = GRPC_OS_ERROR(errno, "listen");
goto error;
}
sockname_temp.len = sizeof(struct sockaddr_storage);
if (getsockname(fd, (struct sockaddr *)sockname_temp.addr,
(socklen_t *)&sockname_temp.len) < 0) {
err = GRPC_OS_ERROR(errno, "getsockname");
goto error;
}
*port = grpc_sockaddr_get_port(&sockname_temp);
return GRPC_ERROR_NONE;
error:
GPR_ASSERT(err != GRPC_ERROR_NONE);
if (fd >= 0) {
close(fd);
}
grpc_error *ret = grpc_error_set_int(
GRPC_ERROR_CREATE_REFERENCING("Unable to configure socket", &err, 1),
GRPC_ERROR_INT_FD, fd);
GRPC_ERROR_UNREF(err);
return ret;
}
/* event manager callback when reads are ready */ /* event manager callback when reads are ready */
static void on_read(grpc_exec_ctx *exec_ctx, void *arg, grpc_error *err) { static void on_read(grpc_exec_ctx *exec_ctx, void *arg, grpc_error *err) {
grpc_tcp_listener *sp = arg; grpc_tcp_listener *sp = arg;
@ -422,7 +256,14 @@ static void on_read(grpc_exec_ctx *exec_ctx, void *arg, grpc_error *err) {
grpc_fd_notify_on_read(exec_ctx, sp->emfd, &sp->read_closure); grpc_fd_notify_on_read(exec_ctx, sp->emfd, &sp->read_closure);
return; return;
default: default:
gpr_mu_lock(&sp->server->mu);
if (!sp->server->shutdown_listeners) {
gpr_log(GPR_ERROR, "Failed accept4: %s", strerror(errno)); gpr_log(GPR_ERROR, "Failed accept4: %s", strerror(errno));
} else {
/* if we have shutdown listeners, accept4 could fail, and we
needn't notify users */
}
gpr_mu_unlock(&sp->server->mu);
goto error; goto error;
} }
} }
@ -438,11 +279,6 @@ static void on_read(grpc_exec_ctx *exec_ctx, void *arg, grpc_error *err) {
grpc_fd *fdobj = grpc_fd_create(fd, name); grpc_fd *fdobj = grpc_fd_create(fd, name);
if (read_notifier_pollset == NULL) {
gpr_log(GPR_ERROR, "Read notifier pollset is not set on the fd");
goto error;
}
grpc_pollset_add_fd(exec_ctx, read_notifier_pollset, fdobj); grpc_pollset_add_fd(exec_ctx, read_notifier_pollset, fdobj);
// Create acceptor. // Create acceptor.
@ -473,216 +309,6 @@ error:
} }
} }
static grpc_error *add_socket_to_server(grpc_tcp_server *s, int fd,
const grpc_resolved_address *addr,
unsigned port_index, unsigned fd_index,
grpc_tcp_listener **listener) {
grpc_tcp_listener *sp = NULL;
int port = -1;
char *addr_str;
char *name;
grpc_error *err = prepare_socket(fd, addr, s->so_reuseport, &port);
if (err == GRPC_ERROR_NONE) {
GPR_ASSERT(port > 0);
grpc_sockaddr_to_string(&addr_str, addr, 1);
gpr_asprintf(&name, "tcp-server-listener:%s", addr_str);
gpr_mu_lock(&s->mu);
s->nports++;
GPR_ASSERT(!s->on_accept_cb && "must add ports before starting server");
sp = gpr_malloc(sizeof(grpc_tcp_listener));
sp->next = NULL;
if (s->head == NULL) {
s->head = sp;
} else {
s->tail->next = sp;
}
s->tail = sp;
sp->server = s;
sp->fd = fd;
sp->emfd = grpc_fd_create(fd, name);
memcpy(&sp->addr, addr, sizeof(grpc_resolved_address));
sp->port = port;
sp->port_index = port_index;
sp->fd_index = fd_index;
sp->is_sibling = 0;
sp->sibling = NULL;
GPR_ASSERT(sp->emfd);
gpr_mu_unlock(&s->mu);
gpr_free(addr_str);
gpr_free(name);
}
*listener = sp;
return err;
}
/* If successful, add a listener to s for addr, set *dsmode for the socket, and
return the *listener. */
static grpc_error *add_addr_to_server(grpc_tcp_server *s,
const grpc_resolved_address *addr,
unsigned port_index, unsigned fd_index,
grpc_dualstack_mode *dsmode,
grpc_tcp_listener **listener) {
grpc_resolved_address addr4_copy;
int fd;
grpc_error *err =
grpc_create_dualstack_socket(addr, SOCK_STREAM, 0, dsmode, &fd);
if (err != GRPC_ERROR_NONE) {
return err;
}
if (*dsmode == GRPC_DSMODE_IPV4 &&
grpc_sockaddr_is_v4mapped(addr, &addr4_copy)) {
addr = &addr4_copy;
}
return add_socket_to_server(s, fd, addr, port_index, fd_index, listener);
}
/* Bind to "::" to get a port number not used by any address. */
static grpc_error *get_unused_port(int *port) {
grpc_resolved_address wild;
grpc_sockaddr_make_wildcard6(0, &wild);
grpc_dualstack_mode dsmode;
int fd;
grpc_error *err =
grpc_create_dualstack_socket(&wild, SOCK_STREAM, 0, &dsmode, &fd);
if (err != GRPC_ERROR_NONE) {
return err;
}
if (dsmode == GRPC_DSMODE_IPV4) {
grpc_sockaddr_make_wildcard4(0, &wild);
}
if (bind(fd, (const struct sockaddr *)wild.addr, (socklen_t)wild.len) != 0) {
err = GRPC_OS_ERROR(errno, "bind");
close(fd);
return err;
}
if (getsockname(fd, (struct sockaddr *)wild.addr, (socklen_t *)&wild.len) !=
0) {
err = GRPC_OS_ERROR(errno, "getsockname");
close(fd);
return err;
}
close(fd);
*port = grpc_sockaddr_get_port(&wild);
return *port <= 0 ? GRPC_ERROR_CREATE("Bad port") : GRPC_ERROR_NONE;
}
/* Return the listener in s with address addr or NULL. */
static grpc_tcp_listener *find_listener_with_addr(grpc_tcp_server *s,
grpc_resolved_address *addr) {
grpc_tcp_listener *l;
gpr_mu_lock(&s->mu);
for (l = s->head; l != NULL; l = l->next) {
if (l->addr.len != addr->len) {
continue;
}
if (memcmp(l->addr.addr, addr->addr, addr->len) == 0) {
break;
}
}
gpr_mu_unlock(&s->mu);
return l;
}
/* Get all addresses assigned to network interfaces on the machine and create a
listener for each. requested_port is the port to use for every listener, or 0
to select one random port that will be used for every listener. Set *out_port
to the port selected. Return GRPC_ERROR_NONE only if all listeners were
added. */
static grpc_error *add_all_local_addrs_to_server(grpc_tcp_server *s,
unsigned port_index,
int requested_port,
int *out_port) {
struct ifaddrs *ifa = NULL;
struct ifaddrs *ifa_it;
unsigned fd_index = 0;
grpc_tcp_listener *sp = NULL;
grpc_error *err = GRPC_ERROR_NONE;
if (requested_port == 0) {
/* Note: There could be a race where some local addrs can listen on the
selected port and some can't. The sane way to handle this would be to
retry by recreating the whole grpc_tcp_server. Backing out individual
listeners and orphaning the FDs looks like too much trouble. */
if ((err = get_unused_port(&requested_port)) != GRPC_ERROR_NONE) {
return err;
} else if (requested_port <= 0) {
return GRPC_ERROR_CREATE("Bad get_unused_port()");
}
gpr_log(GPR_DEBUG, "Picked unused port %d", requested_port);
}
if (getifaddrs(&ifa) != 0 || ifa == NULL) {
return GRPC_OS_ERROR(errno, "getifaddrs");
}
for (ifa_it = ifa; ifa_it != NULL; ifa_it = ifa_it->ifa_next) {
grpc_resolved_address addr;
char *addr_str = NULL;
grpc_dualstack_mode dsmode;
grpc_tcp_listener *new_sp = NULL;
const char *ifa_name = (ifa_it->ifa_name ? ifa_it->ifa_name : "<unknown>");
if (ifa_it->ifa_addr == NULL) {
continue;
} else if (ifa_it->ifa_addr->sa_family == AF_INET) {
addr.len = sizeof(struct sockaddr_in);
} else if (ifa_it->ifa_addr->sa_family == AF_INET6) {
addr.len = sizeof(struct sockaddr_in6);
} else {
continue;
}
memcpy(addr.addr, ifa_it->ifa_addr, addr.len);
if (!grpc_sockaddr_set_port(&addr, requested_port)) {
/* Should never happen, because we check sa_family above. */
err = GRPC_ERROR_CREATE("Failed to set port");
break;
}
if (grpc_sockaddr_to_string(&addr_str, &addr, 0) < 0) {
addr_str = gpr_strdup("<error>");
}
gpr_log(GPR_DEBUG,
"Adding local addr from interface %s flags 0x%x to server: %s",
ifa_name, ifa_it->ifa_flags, addr_str);
/* We could have multiple interfaces with the same address (e.g., bonding),
so look for duplicates. */
if (find_listener_with_addr(s, &addr) != NULL) {
gpr_log(GPR_DEBUG, "Skipping duplicate addr %s on interface %s", addr_str,
ifa_name);
gpr_free(addr_str);
continue;
}
if ((err = add_addr_to_server(s, &addr, port_index, fd_index, &dsmode,
&new_sp)) != GRPC_ERROR_NONE) {
char *err_str = NULL;
grpc_error *root_err;
if (gpr_asprintf(&err_str, "Failed to add listener: %s", addr_str) < 0) {
err_str = gpr_strdup("Failed to add listener");
}
root_err = GRPC_ERROR_CREATE(err_str);
gpr_free(err_str);
gpr_free(addr_str);
err = grpc_error_add_child(root_err, err);
break;
} else {
GPR_ASSERT(requested_port == new_sp->port);
++fd_index;
if (sp != NULL) {
new_sp->is_sibling = 1;
sp->sibling = new_sp;
}
sp = new_sp;
}
gpr_free(addr_str);
}
freeifaddrs(ifa);
if (err != GRPC_ERROR_NONE) {
return err;
} else if (sp == NULL) {
return GRPC_ERROR_CREATE("No local addresses");
} else {
*out_port = sp->port;
return GRPC_ERROR_NONE;
}
}
/* Treat :: or 0.0.0.0 as a family-agnostic wildcard. */ /* Treat :: or 0.0.0.0 as a family-agnostic wildcard. */
static grpc_error *add_wildcard_addrs_to_server(grpc_tcp_server *s, static grpc_error *add_wildcard_addrs_to_server(grpc_tcp_server *s,
unsigned port_index, unsigned port_index,
@ -697,14 +323,16 @@ static grpc_error *add_wildcard_addrs_to_server(grpc_tcp_server *s,
grpc_error *v6_err = GRPC_ERROR_NONE; grpc_error *v6_err = GRPC_ERROR_NONE;
grpc_error *v4_err = GRPC_ERROR_NONE; grpc_error *v4_err = GRPC_ERROR_NONE;
*out_port = -1; *out_port = -1;
if (s->expand_wildcard_addrs) {
return add_all_local_addrs_to_server(s, port_index, requested_port, if (grpc_tcp_server_have_ifaddrs() && s->expand_wildcard_addrs) {
return grpc_tcp_server_add_all_local_addrs(s, port_index, requested_port,
out_port); out_port);
} }
grpc_sockaddr_make_wildcards(requested_port, &wild4, &wild6); grpc_sockaddr_make_wildcards(requested_port, &wild4, &wild6);
/* Try listening on IPv6 first. */ /* Try listening on IPv6 first. */
if ((v6_err = add_addr_to_server(s, &wild6, port_index, fd_index, &dsmode, if ((v6_err = grpc_tcp_server_add_addr(s, &wild6, port_index, fd_index,
&sp)) == GRPC_ERROR_NONE) { &dsmode, &sp)) == GRPC_ERROR_NONE) {
++fd_index; ++fd_index;
requested_port = *out_port = sp->port; requested_port = *out_port = sp->port;
if (dsmode == GRPC_DSMODE_DUALSTACK || dsmode == GRPC_DSMODE_IPV4) { if (dsmode == GRPC_DSMODE_DUALSTACK || dsmode == GRPC_DSMODE_IPV4) {
@ -713,8 +341,8 @@ static grpc_error *add_wildcard_addrs_to_server(grpc_tcp_server *s,
} }
/* If we got a v6-only socket or nothing, try adding 0.0.0.0. */ /* If we got a v6-only socket or nothing, try adding 0.0.0.0. */
grpc_sockaddr_set_port(&wild4, requested_port); grpc_sockaddr_set_port(&wild4, requested_port);
if ((v4_err = add_addr_to_server(s, &wild4, port_index, fd_index, &dsmode, if ((v4_err = grpc_tcp_server_add_addr(s, &wild4, port_index, fd_index,
&sp2)) == GRPC_ERROR_NONE) { &dsmode, &sp2)) == GRPC_ERROR_NONE) {
*out_port = sp2->port; *out_port = sp2->port;
if (sp != NULL) { if (sp != NULL) {
sp2->is_sibling = 1; sp2->is_sibling = 1;
@ -722,8 +350,20 @@ static grpc_error *add_wildcard_addrs_to_server(grpc_tcp_server *s,
} }
} }
if (*out_port > 0) { if (*out_port > 0) {
GRPC_LOG_IF_ERROR("Failed to add :: listener", v6_err); if (v6_err != GRPC_ERROR_NONE) {
GRPC_LOG_IF_ERROR("Failed to add 0.0.0.0 listener", v4_err); gpr_log(GPR_INFO,
"Failed to add :: listener, "
"the environment may not support IPv6: %s",
grpc_error_string(v6_err));
GRPC_ERROR_UNREF(v6_err);
}
if (v4_err != GRPC_ERROR_NONE) {
gpr_log(GPR_INFO,
"Failed to add 0.0.0.0 listener, "
"the environment may not support IPv4: %s",
grpc_error_string(v4_err));
GRPC_ERROR_UNREF(v4_err);
}
return GRPC_ERROR_NONE; return GRPC_ERROR_NONE;
} else { } else {
grpc_error *root_err = grpc_error *root_err =
@ -752,7 +392,7 @@ static grpc_error *clone_port(grpc_tcp_listener *listener, unsigned count) {
err = grpc_create_dualstack_socket(&listener->addr, SOCK_STREAM, 0, &dsmode, err = grpc_create_dualstack_socket(&listener->addr, SOCK_STREAM, 0, &dsmode,
&fd); &fd);
if (err != GRPC_ERROR_NONE) return err; if (err != GRPC_ERROR_NONE) return err;
err = prepare_socket(fd, &listener->addr, true, &port); err = grpc_tcp_server_prepare_socket(fd, &listener->addr, true, &port);
if (err != GRPC_ERROR_NONE) return err; if (err != GRPC_ERROR_NONE) return err;
listener->server->nports++; listener->server->nports++;
grpc_sockaddr_to_string(&addr_str, &listener->addr, 1); grpc_sockaddr_to_string(&addr_str, &listener->addr, 1);
@ -824,7 +464,7 @@ grpc_error *grpc_tcp_server_add_port(grpc_tcp_server *s,
if (grpc_sockaddr_to_v4mapped(addr, &addr6_v4mapped)) { if (grpc_sockaddr_to_v4mapped(addr, &addr6_v4mapped)) {
addr = &addr6_v4mapped; addr = &addr6_v4mapped;
} }
if ((err = add_addr_to_server(s, addr, port_index, 0, &dsmode, &sp)) == if ((err = grpc_tcp_server_add_addr(s, addr, port_index, 0, &dsmode, &sp)) ==
GRPC_ERROR_NONE) { GRPC_ERROR_NONE) {
*out_port = sp->port; *out_port = sp->port;
} }
@ -941,6 +581,7 @@ void grpc_tcp_server_unref(grpc_exec_ctx *exec_ctx, grpc_tcp_server *s) {
void grpc_tcp_server_shutdown_listeners(grpc_exec_ctx *exec_ctx, void grpc_tcp_server_shutdown_listeners(grpc_exec_ctx *exec_ctx,
grpc_tcp_server *s) { grpc_tcp_server *s) {
gpr_mu_lock(&s->mu); gpr_mu_lock(&s->mu);
s->shutdown_listeners = true;
/* shutdown all fd's */ /* shutdown all fd's */
if (s->active_ports) { if (s->active_ports) {
grpc_tcp_listener *sp; grpc_tcp_listener *sp;

@ -0,0 +1,134 @@
/*
*
* 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_IOMGR_TCP_SERVER_UTILS_POSIX_H
#define GRPC_CORE_LIB_IOMGR_TCP_SERVER_UTILS_POSIX_H
#include "src/core/lib/iomgr/ev_posix.h"
#include "src/core/lib/iomgr/resolve_address.h"
#include "src/core/lib/iomgr/socket_utils_posix.h"
#include "src/core/lib/iomgr/tcp_server.h"
/* one listening port */
typedef struct grpc_tcp_listener {
int fd;
grpc_fd *emfd;
grpc_tcp_server *server;
grpc_resolved_address addr;
int port;
unsigned port_index;
unsigned fd_index;
grpc_closure read_closure;
grpc_closure destroyed_closure;
struct grpc_tcp_listener *next;
/* sibling is a linked list of all listeners for a given port. add_port and
clone_port place all new listeners in the same sibling list. A member of
the 'sibling' list is also a member of the 'next' list. The head of each
sibling list has is_sibling==0, and subsequent members of sibling lists
have is_sibling==1. is_sibling allows separate sibling lists to be
identified while iterating through 'next'. */
struct grpc_tcp_listener *sibling;
int is_sibling;
} grpc_tcp_listener;
/* the overall server */
struct grpc_tcp_server {
gpr_refcount refs;
/* Called whenever accept() succeeds on a server port. */
grpc_tcp_server_cb on_accept_cb;
void *on_accept_cb_arg;
gpr_mu mu;
/* active port count: how many ports are actually still listening */
size_t active_ports;
/* destroyed port count: how many ports are completely destroyed */
size_t destroyed_ports;
/* is this server shutting down? */
bool shutdown;
/* have listeners been shutdown? */
bool shutdown_listeners;
/* use SO_REUSEPORT */
bool so_reuseport;
/* expand wildcard addresses to a list of all local addresses */
bool expand_wildcard_addrs;
/* linked list of server ports */
grpc_tcp_listener *head;
grpc_tcp_listener *tail;
unsigned nports;
/* List of closures passed to shutdown_starting_add(). */
grpc_closure_list shutdown_starting;
/* shutdown callback */
grpc_closure *shutdown_complete;
/* all pollsets interested in new connections */
grpc_pollset **pollsets;
/* number of pollsets in the pollsets array */
size_t pollset_count;
/* next pollset to assign a channel to */
gpr_atm next_pollset_to_assign;
grpc_resource_quota *resource_quota;
};
/* If successful, add a listener to \a s for \a addr, set \a dsmode for the
socket, and return the \a listener. */
grpc_error *grpc_tcp_server_add_addr(grpc_tcp_server *s,
const grpc_resolved_address *addr,
unsigned port_index, unsigned fd_index,
grpc_dualstack_mode *dsmode,
grpc_tcp_listener **listener);
/* Get all addresses assigned to network interfaces on the machine and create a
listener for each. requested_port is the port to use for every listener, or 0
to select one random port that will be used for every listener. Set *out_port
to the port selected. Return GRPC_ERROR_NONE only if all listeners were
added. */
grpc_error *grpc_tcp_server_add_all_local_addrs(grpc_tcp_server *s,
unsigned port_index,
int requested_port,
int *out_port);
/* Prepare a recently-created socket for listening. */
grpc_error *grpc_tcp_server_prepare_socket(int fd,
const grpc_resolved_address *addr,
bool so_reuseport, int *port);
/* Ruturn true if the platform supports ifaddrs */
bool grpc_tcp_server_have_ifaddrs(void);
#endif /* GRPC_CORE_LIB_IOMGR_TCP_SERVER_UTILS_POSIX_H */

@ -0,0 +1,220 @@
/*
*
* 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 "src/core/lib/iomgr/port.h"
#ifdef GRPC_HAVE_IFADDRS
#include "src/core/lib/iomgr/tcp_server_utils_posix.h"
#include <errno.h>
#include <limits.h>
#include <stdio.h>
#include <string.h>
#include <grpc/support/alloc.h>
#include <grpc/support/log.h>
#include <grpc/support/string_util.h>
#include <grpc/support/sync.h>
#include "src/core/lib/iomgr/error.h"
#include "src/core/lib/iomgr/sockaddr.h"
#include "src/core/lib/iomgr/sockaddr_utils.h"
#include "src/core/lib/iomgr/unix_sockets_posix.h"
#define MIN_SAFE_ACCEPT_QUEUE_SIZE 100
static gpr_once s_init_max_accept_queue_size;
static int s_max_accept_queue_size;
/* get max listen queue size on linux */
static void init_max_accept_queue_size(void) {
int n = SOMAXCONN;
char buf[64];
FILE *fp = fopen("/proc/sys/net/core/somaxconn", "r");
if (fp == NULL) {
/* 2.4 kernel. */
s_max_accept_queue_size = SOMAXCONN;
return;
}
if (fgets(buf, sizeof buf, fp)) {
char *end;
long i = strtol(buf, &end, 10);
if (i > 0 && i <= INT_MAX && end && *end == 0) {
n = (int)i;
}
}
fclose(fp);
s_max_accept_queue_size = n;
if (s_max_accept_queue_size < MIN_SAFE_ACCEPT_QUEUE_SIZE) {
gpr_log(GPR_INFO,
"Suspiciously small accept queue (%d) will probably lead to "
"connection drops",
s_max_accept_queue_size);
}
}
static int get_max_accept_queue_size(void) {
gpr_once_init(&s_init_max_accept_queue_size, init_max_accept_queue_size);
return s_max_accept_queue_size;
}
static grpc_error *add_socket_to_server(grpc_tcp_server *s, int fd,
const grpc_resolved_address *addr,
unsigned port_index, unsigned fd_index,
grpc_tcp_listener **listener) {
grpc_tcp_listener *sp = NULL;
int port = -1;
char *addr_str;
char *name;
grpc_error *err =
grpc_tcp_server_prepare_socket(fd, addr, s->so_reuseport, &port);
if (err == GRPC_ERROR_NONE) {
GPR_ASSERT(port > 0);
grpc_sockaddr_to_string(&addr_str, addr, 1);
gpr_asprintf(&name, "tcp-server-listener:%s", addr_str);
gpr_mu_lock(&s->mu);
s->nports++;
GPR_ASSERT(!s->on_accept_cb && "must add ports before starting server");
sp = gpr_malloc(sizeof(grpc_tcp_listener));
sp->next = NULL;
if (s->head == NULL) {
s->head = sp;
} else {
s->tail->next = sp;
}
s->tail = sp;
sp->server = s;
sp->fd = fd;
sp->emfd = grpc_fd_create(fd, name);
memcpy(&sp->addr, addr, sizeof(grpc_resolved_address));
sp->port = port;
sp->port_index = port_index;
sp->fd_index = fd_index;
sp->is_sibling = 0;
sp->sibling = NULL;
GPR_ASSERT(sp->emfd);
gpr_mu_unlock(&s->mu);
gpr_free(addr_str);
gpr_free(name);
}
*listener = sp;
return err;
}
/* If successful, add a listener to s for addr, set *dsmode for the socket, and
return the *listener. */
grpc_error *grpc_tcp_server_add_addr(grpc_tcp_server *s,
const grpc_resolved_address *addr,
unsigned port_index, unsigned fd_index,
grpc_dualstack_mode *dsmode,
grpc_tcp_listener **listener) {
grpc_resolved_address addr4_copy;
int fd;
grpc_error *err =
grpc_create_dualstack_socket(addr, SOCK_STREAM, 0, dsmode, &fd);
if (err != GRPC_ERROR_NONE) {
return err;
}
if (*dsmode == GRPC_DSMODE_IPV4 &&
grpc_sockaddr_is_v4mapped(addr, &addr4_copy)) {
addr = &addr4_copy;
}
return add_socket_to_server(s, fd, addr, port_index, fd_index, listener);
}
/* Prepare a recently-created socket for listening. */
grpc_error *grpc_tcp_server_prepare_socket(int fd,
const grpc_resolved_address *addr,
bool so_reuseport, int *port) {
grpc_resolved_address sockname_temp;
grpc_error *err = GRPC_ERROR_NONE;
GPR_ASSERT(fd >= 0);
if (so_reuseport && !grpc_is_unix_socket(addr)) {
err = grpc_set_socket_reuse_port(fd, 1);
if (err != GRPC_ERROR_NONE) goto error;
}
err = grpc_set_socket_nonblocking(fd, 1);
if (err != GRPC_ERROR_NONE) goto error;
err = grpc_set_socket_cloexec(fd, 1);
if (err != GRPC_ERROR_NONE) goto error;
if (!grpc_is_unix_socket(addr)) {
err = grpc_set_socket_low_latency(fd, 1);
if (err != GRPC_ERROR_NONE) goto error;
err = grpc_set_socket_reuse_addr(fd, 1);
if (err != GRPC_ERROR_NONE) goto error;
}
err = grpc_set_socket_no_sigpipe_if_possible(fd);
if (err != GRPC_ERROR_NONE) goto error;
GPR_ASSERT(addr->len < ~(socklen_t)0);
if (bind(fd, (struct sockaddr *)addr->addr, (socklen_t)addr->len) < 0) {
err = GRPC_OS_ERROR(errno, "bind");
goto error;
}
if (listen(fd, get_max_accept_queue_size()) < 0) {
err = GRPC_OS_ERROR(errno, "listen");
goto error;
}
sockname_temp.len = sizeof(struct sockaddr_storage);
if (getsockname(fd, (struct sockaddr *)sockname_temp.addr,
(socklen_t *)&sockname_temp.len) < 0) {
err = GRPC_OS_ERROR(errno, "getsockname");
goto error;
}
*port = grpc_sockaddr_get_port(&sockname_temp);
return GRPC_ERROR_NONE;
error:
GPR_ASSERT(err != GRPC_ERROR_NONE);
if (fd >= 0) {
close(fd);
}
grpc_error *ret = grpc_error_set_int(
GRPC_ERROR_CREATE_REFERENCING("Unable to configure socket", &err, 1),
GRPC_ERROR_INT_FD, fd);
GRPC_ERROR_UNREF(err);
return ret;
}
#endif /* GRPC_HAVE_IFADDRS */

@ -0,0 +1,195 @@
/*
*
* 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 "src/core/lib/iomgr/port.h"
#ifdef GRPC_HAVE_IFADDRS
#include "src/core/lib/iomgr/tcp_server_utils_posix.h"
#include <errno.h>
#include <ifaddrs.h>
#include <stddef.h>
#include <string.h>
#include <grpc/support/alloc.h>
#include <grpc/support/log.h>
#include <grpc/support/string_util.h>
#include "src/core/lib/iomgr/error.h"
#include "src/core/lib/iomgr/sockaddr.h"
#include "src/core/lib/iomgr/sockaddr_utils.h"
/* Return the listener in s with address addr or NULL. */
static grpc_tcp_listener *find_listener_with_addr(grpc_tcp_server *s,
grpc_resolved_address *addr) {
grpc_tcp_listener *l;
gpr_mu_lock(&s->mu);
for (l = s->head; l != NULL; l = l->next) {
if (l->addr.len != addr->len) {
continue;
}
if (memcmp(l->addr.addr, addr->addr, addr->len) == 0) {
break;
}
}
gpr_mu_unlock(&s->mu);
return l;
}
/* Bind to "::" to get a port number not used by any address. */
static grpc_error *get_unused_port(int *port) {
grpc_resolved_address wild;
grpc_sockaddr_make_wildcard6(0, &wild);
grpc_dualstack_mode dsmode;
int fd;
grpc_error *err =
grpc_create_dualstack_socket(&wild, SOCK_STREAM, 0, &dsmode, &fd);
if (err != GRPC_ERROR_NONE) {
return err;
}
if (dsmode == GRPC_DSMODE_IPV4) {
grpc_sockaddr_make_wildcard4(0, &wild);
}
if (bind(fd, (const struct sockaddr *)wild.addr, (socklen_t)wild.len) != 0) {
err = GRPC_OS_ERROR(errno, "bind");
close(fd);
return err;
}
if (getsockname(fd, (struct sockaddr *)wild.addr, (socklen_t *)&wild.len) !=
0) {
err = GRPC_OS_ERROR(errno, "getsockname");
close(fd);
return err;
}
close(fd);
*port = grpc_sockaddr_get_port(&wild);
return *port <= 0 ? GRPC_ERROR_CREATE("Bad port") : GRPC_ERROR_NONE;
}
grpc_error *grpc_tcp_server_add_all_local_addrs(grpc_tcp_server *s,
unsigned port_index,
int requested_port,
int *out_port) {
struct ifaddrs *ifa = NULL;
struct ifaddrs *ifa_it;
unsigned fd_index = 0;
grpc_tcp_listener *sp = NULL;
grpc_error *err = GRPC_ERROR_NONE;
if (requested_port == 0) {
/* Note: There could be a race where some local addrs can listen on the
selected port and some can't. The sane way to handle this would be to
retry by recreating the whole grpc_tcp_server. Backing out individual
listeners and orphaning the FDs looks like too much trouble. */
if ((err = get_unused_port(&requested_port)) != GRPC_ERROR_NONE) {
return err;
} else if (requested_port <= 0) {
return GRPC_ERROR_CREATE("Bad get_unused_port()");
}
gpr_log(GPR_DEBUG, "Picked unused port %d", requested_port);
}
if (getifaddrs(&ifa) != 0 || ifa == NULL) {
return GRPC_OS_ERROR(errno, "getifaddrs");
}
for (ifa_it = ifa; ifa_it != NULL; ifa_it = ifa_it->ifa_next) {
grpc_resolved_address addr;
char *addr_str = NULL;
grpc_dualstack_mode dsmode;
grpc_tcp_listener *new_sp = NULL;
const char *ifa_name = (ifa_it->ifa_name ? ifa_it->ifa_name : "<unknown>");
if (ifa_it->ifa_addr == NULL) {
continue;
} else if (ifa_it->ifa_addr->sa_family == AF_INET) {
addr.len = sizeof(struct sockaddr_in);
} else if (ifa_it->ifa_addr->sa_family == AF_INET6) {
addr.len = sizeof(struct sockaddr_in6);
} else {
continue;
}
memcpy(addr.addr, ifa_it->ifa_addr, addr.len);
if (!grpc_sockaddr_set_port(&addr, requested_port)) {
/* Should never happen, because we check sa_family above. */
err = GRPC_ERROR_CREATE("Failed to set port");
break;
}
if (grpc_sockaddr_to_string(&addr_str, &addr, 0) < 0) {
addr_str = gpr_strdup("<error>");
}
gpr_log(GPR_DEBUG,
"Adding local addr from interface %s flags 0x%x to server: %s",
ifa_name, ifa_it->ifa_flags, addr_str);
/* We could have multiple interfaces with the same address (e.g., bonding),
so look for duplicates. */
if (find_listener_with_addr(s, &addr) != NULL) {
gpr_log(GPR_DEBUG, "Skipping duplicate addr %s on interface %s", addr_str,
ifa_name);
gpr_free(addr_str);
continue;
}
if ((err = grpc_tcp_server_add_addr(s, &addr, port_index, fd_index, &dsmode,
&new_sp)) != GRPC_ERROR_NONE) {
char *err_str = NULL;
grpc_error *root_err;
if (gpr_asprintf(&err_str, "Failed to add listener: %s", addr_str) < 0) {
err_str = gpr_strdup("Failed to add listener");
}
root_err = GRPC_ERROR_CREATE(err_str);
gpr_free(err_str);
gpr_free(addr_str);
err = grpc_error_add_child(root_err, err);
break;
} else {
GPR_ASSERT(requested_port == new_sp->port);
++fd_index;
if (sp != NULL) {
new_sp->is_sibling = 1;
sp->sibling = new_sp;
}
sp = new_sp;
}
gpr_free(addr_str);
}
freeifaddrs(ifa);
if (err != GRPC_ERROR_NONE) {
return err;
} else if (sp == NULL) {
return GRPC_ERROR_CREATE("No local addresses");
} else {
*out_port = sp->port;
return GRPC_ERROR_NONE;
}
}
bool grpc_tcp_server_have_ifaddrs(void) { return true; }
#endif /* GRPC_HAVE_IFADDRS */

@ -0,0 +1,49 @@
/*
*
* 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 "src/core/lib/iomgr/port.h"
#if defined(GRPC_POSIX_SOCKET) && !defined(GRPC_HAVE_IFADDRS)
#include "src/core/lib/iomgr/tcp_server_utils_posix.h"
grpc_error *grpc_tcp_server_add_all_local_addrs(grpc_tcp_server *s,
unsigned port_index,
int requested_port,
int *out_port) {
return GRPC_ERROR_CREATE("no ifaddrs available");
}
bool grpc_tcp_server_have_ifaddrs(void) { return false; }
#endif /* defined(GRPC_POSIX_SOCKET) && !defined(GRPC_HAVE_IFADDRS) */

@ -109,8 +109,8 @@ struct grpc_udp_server {
grpc_pollset **pollsets; grpc_pollset **pollsets;
/* number of pollsets in the pollsets array */ /* number of pollsets in the pollsets array */
size_t pollset_count; size_t pollset_count;
/* The parent grpc server */ /* opaque object to pass to callbacks */
grpc_server *grpc_server; void *user_data;
}; };
grpc_udp_server *grpc_udp_server_create(void) { grpc_udp_server *grpc_udp_server_create(void) {
@ -178,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 /* Call the orphan_cb to signal that the FD is about to be closed and
* should no longer be used. */ * should no longer be used. */
GPR_ASSERT(sp->orphan_cb); GPR_ASSERT(sp->orphan_cb);
sp->orphan_cb(exec_ctx, sp->emfd); sp->orphan_cb(exec_ctx, sp->emfd, sp->server->user_data);
grpc_fd_orphan(exec_ctx, sp->emfd, &sp->destroyed_closure, NULL, grpc_fd_orphan(exec_ctx, sp->emfd, &sp->destroyed_closure, NULL,
"udp_listener_shutdown"); "udp_listener_shutdown");
@ -204,7 +204,7 @@ void grpc_udp_server_destroy(grpc_exec_ctx *exec_ctx, grpc_udp_server *s,
if (s->active_ports) { if (s->active_ports) {
for (sp = s->head; sp; sp = sp->next) { for (sp = s->head; sp; sp = sp->next) {
GPR_ASSERT(sp->orphan_cb); GPR_ASSERT(sp->orphan_cb);
sp->orphan_cb(exec_ctx, sp->emfd); sp->orphan_cb(exec_ctx, sp->emfd, sp->server->user_data);
grpc_fd_shutdown(exec_ctx, sp->emfd, grpc_fd_shutdown(exec_ctx, sp->emfd,
GRPC_ERROR_CREATE("Server destroyed")); GRPC_ERROR_CREATE("Server destroyed"));
} }
@ -299,7 +299,7 @@ static void on_read(grpc_exec_ctx *exec_ctx, void *arg, grpc_error *error) {
/* Tell the registered callback that data is available to read. */ /* Tell the registered callback that data is available to read. */
GPR_ASSERT(sp->read_cb); GPR_ASSERT(sp->read_cb);
sp->read_cb(exec_ctx, sp->emfd, sp->server->grpc_server); sp->read_cb(exec_ctx, sp->emfd, sp->server->user_data);
/* Re-arm the notification event so we get another chance to read. */ /* Re-arm the notification event so we get another chance to read. */
grpc_fd_notify_on_read(exec_ctx, sp->emfd, &sp->read_closure); grpc_fd_notify_on_read(exec_ctx, sp->emfd, &sp->read_closure);
@ -322,7 +322,7 @@ static void on_write(grpc_exec_ctx *exec_ctx, void *arg, grpc_error *error) {
/* Tell the registered callback that the socket is writeable. */ /* Tell the registered callback that the socket is writeable. */
GPR_ASSERT(sp->write_cb); GPR_ASSERT(sp->write_cb);
sp->write_cb(exec_ctx, sp->emfd); sp->write_cb(exec_ctx, sp->emfd, sp->server->user_data);
/* Re-arm the notification event so we get another chance to write. */ /* Re-arm the notification event so we get another chance to write. */
grpc_fd_notify_on_write(exec_ctx, sp->emfd, &sp->write_closure); grpc_fd_notify_on_write(exec_ctx, sp->emfd, &sp->write_closure);
@ -464,13 +464,13 @@ int grpc_udp_server_get_fd(grpc_udp_server *s, unsigned port_index) {
void grpc_udp_server_start(grpc_exec_ctx *exec_ctx, grpc_udp_server *s, void grpc_udp_server_start(grpc_exec_ctx *exec_ctx, grpc_udp_server *s,
grpc_pollset **pollsets, size_t pollset_count, grpc_pollset **pollsets, size_t pollset_count,
grpc_server *server) { void *user_data) {
size_t i; size_t i;
gpr_mu_lock(&s->mu); gpr_mu_lock(&s->mu);
grpc_udp_listener *sp; grpc_udp_listener *sp;
GPR_ASSERT(s->active_ports == 0); GPR_ASSERT(s->active_ports == 0);
s->pollsets = pollsets; s->pollsets = pollsets;
s->grpc_server = server; s->user_data = user_data;
sp = s->head; sp = s->head;
while (sp != NULL) { while (sp != NULL) {
@ -485,7 +485,11 @@ void grpc_udp_server_start(grpc_exec_ctx *exec_ctx, grpc_udp_server *s,
grpc_schedule_on_exec_ctx); grpc_schedule_on_exec_ctx);
grpc_fd_notify_on_write(exec_ctx, sp->emfd, &sp->write_closure); grpc_fd_notify_on_write(exec_ctx, sp->emfd, &sp->write_closure);
s->active_ports++; /* Registered for both read and write callbacks: increment active_ports
* twice to account for this, and delay free-ing of memory until both
* on_read and on_write have fired. */
s->active_ports += 2;
sp = sp->next; sp = sp->next;
} }

@ -47,23 +47,23 @@ typedef struct grpc_udp_server grpc_udp_server;
/* Called when data is available to read from the socket. */ /* Called when data is available to read from the socket. */
typedef void (*grpc_udp_server_read_cb)(grpc_exec_ctx *exec_ctx, grpc_fd *emfd, typedef void (*grpc_udp_server_read_cb)(grpc_exec_ctx *exec_ctx, grpc_fd *emfd,
struct grpc_server *server); void *user_data);
/* Called when the socket is writeable. */ /* Called when the socket is writeable. */
typedef void (*grpc_udp_server_write_cb)(grpc_exec_ctx *exec_ctx, typedef void (*grpc_udp_server_write_cb)(grpc_exec_ctx *exec_ctx, grpc_fd *emfd,
grpc_fd *emfd); void *user_data);
/* Called when the grpc_fd is about to be orphaned (and the FD closed). */ /* Called when the grpc_fd is about to be orphaned (and the FD closed). */
typedef void (*grpc_udp_server_orphan_cb)(grpc_exec_ctx *exec_ctx, typedef void (*grpc_udp_server_orphan_cb)(grpc_exec_ctx *exec_ctx,
grpc_fd *emfd); grpc_fd *emfd, void *user_data);
/* Create a server, initially not bound to any ports */ /* Create a server, initially not bound to any ports */
grpc_udp_server *grpc_udp_server_create(void); grpc_udp_server *grpc_udp_server_create(void);
/* Start listening to bound ports */ /* Start listening to bound ports. user_data is passed to callbacks. */
void grpc_udp_server_start(grpc_exec_ctx *exec_ctx, grpc_udp_server *udp_server, void grpc_udp_server_start(grpc_exec_ctx *exec_ctx, grpc_udp_server *udp_server,
grpc_pollset **pollsets, size_t pollset_count, grpc_pollset **pollsets, size_t pollset_count,
struct grpc_server *server); void *user_data);
int grpc_udp_server_get_fd(grpc_udp_server *s, unsigned port_index); int grpc_udp_server_get_fd(grpc_udp_server *s, unsigned port_index);

@ -46,7 +46,7 @@
* *
* Setup: * Setup:
* 1. Before calling anything, call global_init() at least once. * 1. Before calling anything, call global_init() at least once.
* 1. Call grpc_wakeup_fd_create() to get a wakeup_fd. * 1. Call grpc_wakeup_fd_init() to set up a wakeup_fd.
* 2. Add the result of GRPC_WAKEUP_FD_FD to the set of monitored file * 2. Add the result of GRPC_WAKEUP_FD_FD to the set of monitored file
* descriptors for the poll() style API you are using. Monitor the file * descriptors for the poll() style API you are using. Monitor the file
* descriptor for readability. * descriptor for readability.

@ -318,7 +318,7 @@ static void set_pollset_or_pollset_set(grpc_exec_ctx *exec_ctx,
/* Destructor for call_data */ /* Destructor for call_data */
static void destroy_call_elem(grpc_exec_ctx *exec_ctx, grpc_call_element *elem, static void destroy_call_elem(grpc_exec_ctx *exec_ctx, grpc_call_element *elem,
const grpc_call_final_info *final_info, const grpc_call_final_info *final_info,
void *ignored) { grpc_closure *ignored) {
call_data *calld = elem->call_data; call_data *calld = elem->call_data;
grpc_call_credentials_unref(exec_ctx, calld->creds); grpc_call_credentials_unref(exec_ctx, calld->creds);
if (calld->have_host) { if (calld->have_host) {

@ -227,7 +227,7 @@ static grpc_error *init_call_elem(grpc_exec_ctx *exec_ctx,
/* Destructor for call_data */ /* Destructor for call_data */
static void destroy_call_elem(grpc_exec_ctx *exec_ctx, grpc_call_element *elem, static void destroy_call_elem(grpc_exec_ctx *exec_ctx, grpc_call_element *elem,
const grpc_call_final_info *final_info, const grpc_call_final_info *final_info,
void *ignored) {} grpc_closure *ignored) {}
/* Constructor for channel_data */ /* Constructor for channel_data */
static grpc_error *init_channel_elem(grpc_exec_ctx *exec_ctx, static grpc_error *init_channel_elem(grpc_exec_ctx *exec_ctx,

@ -0,0 +1,98 @@
/*
*
* 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 "src/core/lib/support/arena.h"
#include <grpc/support/alloc.h>
#include <grpc/support/atm.h>
#include <grpc/support/log.h>
#include <grpc/support/useful.h>
#define ROUND_UP_TO_ALIGNMENT_SIZE(x) \
(((x) + GPR_MAX_ALIGNMENT - 1u) & ~(GPR_MAX_ALIGNMENT - 1u))
typedef struct zone {
size_t size_begin;
size_t size_end;
gpr_atm next_atm;
} zone;
struct gpr_arena {
gpr_atm size_so_far;
zone initial_zone;
};
gpr_arena *gpr_arena_create(size_t initial_size) {
initial_size = ROUND_UP_TO_ALIGNMENT_SIZE(initial_size);
gpr_arena *a = gpr_zalloc(sizeof(gpr_arena) + initial_size);
a->initial_zone.size_end = initial_size;
return a;
}
size_t gpr_arena_destroy(gpr_arena *arena) {
gpr_atm size = gpr_atm_no_barrier_load(&arena->size_so_far);
zone *z = (zone *)gpr_atm_no_barrier_load(&arena->initial_zone.next_atm);
gpr_free(arena);
while (z) {
zone *next_z = (zone *)gpr_atm_no_barrier_load(&z->next_atm);
gpr_free(z);
z = next_z;
}
return (size_t)size;
}
void *gpr_arena_alloc(gpr_arena *arena, size_t size) {
size = ROUND_UP_TO_ALIGNMENT_SIZE(size);
size_t start =
(size_t)gpr_atm_no_barrier_fetch_add(&arena->size_so_far, size);
zone *z = &arena->initial_zone;
while (start > z->size_end) {
zone *next_z = (zone *)gpr_atm_acq_load(&z->next_atm);
if (next_z == NULL) {
size_t next_z_size = (size_t)gpr_atm_no_barrier_load(&arena->size_so_far);
next_z = gpr_zalloc(sizeof(zone) + next_z_size);
next_z->size_begin = z->size_end;
next_z->size_end = z->size_end + next_z_size;
if (!gpr_atm_rel_cas(&z->next_atm, (gpr_atm)NULL, (gpr_atm)next_z)) {
gpr_free(next_z);
next_z = (zone *)gpr_atm_acq_load(&z->next_atm);
}
}
z = next_z;
}
if (start + size > z->size_end) {
return gpr_arena_alloc(arena, size);
}
GPR_ASSERT(start >= z->size_begin);
GPR_ASSERT(start + size <= z->size_end);
return ((char *)(z + 1)) + start - z->size_begin;
}

@ -0,0 +1,54 @@
/*
*
* 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.
*
*/
// \file Arena based allocator
// Allows very fast allocation of memory, but that memory cannot be freed until
// the arena as a whole is freed
// Tracks the total memory allocated against it, so that future arenas can
// pre-allocate the right amount of memory
#ifndef GRPC_CORE_LIB_SUPPORT_ARENA_H
#define GRPC_CORE_LIB_SUPPORT_ARENA_H
#include <stddef.h>
typedef struct gpr_arena gpr_arena;
// Create an arena, with \a initial_size bytes in the first allocated buffer
gpr_arena *gpr_arena_create(size_t initial_size);
// Allocate \a size bytes from the arena
void *gpr_arena_alloc(gpr_arena *arena, size_t size);
// Destroy an arena, returning the total number of bytes allocated
size_t gpr_arena_destroy(gpr_arena *arena);
#endif /* GRPC_CORE_LIB_SUPPORT_ARENA_H */

@ -119,6 +119,10 @@ int gpr_unref(gpr_refcount *r) {
return prior == 1; return prior == 1;
} }
int gpr_ref_is_unique(gpr_refcount *r) {
return gpr_atm_acq_load(&r->count) == 1;
}
void gpr_stats_init(gpr_stats_counter *c, intptr_t n) { void gpr_stats_init(gpr_stats_counter *c, intptr_t n) {
gpr_atm_rel_store(&c->value, n); gpr_atm_rel_store(&c->value, n);
} }

@ -51,6 +51,7 @@
#include "src/core/lib/profiling/timers.h" #include "src/core/lib/profiling/timers.h"
#include "src/core/lib/slice/slice_internal.h" #include "src/core/lib/slice/slice_internal.h"
#include "src/core/lib/slice/slice_string_helpers.h" #include "src/core/lib/slice/slice_string_helpers.h"
#include "src/core/lib/support/arena.h"
#include "src/core/lib/support/string.h" #include "src/core/lib/support/string.h"
#include "src/core/lib/surface/api_trace.h" #include "src/core/lib/surface/api_trace.h"
#include "src/core/lib/surface/call.h" #include "src/core/lib/surface/call.h"
@ -138,14 +139,15 @@ typedef struct batch_control {
} batch_control; } batch_control;
struct grpc_call { struct grpc_call {
gpr_arena *arena;
grpc_completion_queue *cq; grpc_completion_queue *cq;
grpc_polling_entity pollent; grpc_polling_entity pollent;
grpc_channel *channel; grpc_channel *channel;
grpc_call *parent; grpc_call *parent;
grpc_call *first_child; grpc_call *first_child;
gpr_timespec start_time; gpr_timespec start_time;
/* TODO(ctiller): share with cq if possible? */ /* protects first_child, and child next/prev links */
gpr_mu mu; gpr_mu child_list_mu;
/* client or server call */ /* client or server call */
bool is_client; bool is_client;
@ -160,8 +162,8 @@ struct grpc_call {
bool received_initial_metadata; bool received_initial_metadata;
bool receiving_message; bool receiving_message;
bool requested_final_op; bool requested_final_op;
bool received_final_op; gpr_atm any_ops_sent_atm;
bool sent_any_op; gpr_atm received_final_op_atm;
/* have we received initial metadata */ /* have we received initial metadata */
bool has_initial_md_been_received; bool has_initial_md_been_received;
@ -212,6 +214,8 @@ struct grpc_call {
grpc_closure receiving_initial_metadata_ready; grpc_closure receiving_initial_metadata_ready;
uint32_t test_only_last_message_flags; uint32_t test_only_last_message_flags;
grpc_closure release_call;
union { union {
struct { struct {
grpc_status_code *status; grpc_status_code *status;
@ -273,9 +277,13 @@ grpc_error *grpc_call_create(grpc_exec_ctx *exec_ctx,
grpc_channel_get_channel_stack(args->channel); grpc_channel_get_channel_stack(args->channel);
grpc_call *call; grpc_call *call;
GPR_TIMER_BEGIN("grpc_call_create", 0); GPR_TIMER_BEGIN("grpc_call_create", 0);
call = gpr_zalloc(sizeof(grpc_call) + channel_stack->call_stack_size); gpr_arena *arena =
gpr_arena_create(grpc_channel_get_call_size_estimate(args->channel));
call = gpr_arena_alloc(arena,
sizeof(grpc_call) + channel_stack->call_stack_size);
call->arena = arena;
*out_call = call; *out_call = call;
gpr_mu_init(&call->mu); gpr_mu_init(&call->child_list_mu);
call->channel = args->channel; call->channel = args->channel;
call->cq = args->cq; call->cq = args->cq;
call->parent = args->parent_call; call->parent = args->parent_call;
@ -313,7 +321,7 @@ grpc_error *grpc_call_create(grpc_exec_ctx *exec_ctx,
GPR_ASSERT(call->is_client); GPR_ASSERT(call->is_client);
GPR_ASSERT(!args->parent_call->is_client); GPR_ASSERT(!args->parent_call->is_client);
gpr_mu_lock(&args->parent_call->mu); gpr_mu_lock(&args->parent_call->child_list_mu);
if (args->propagation_mask & GRPC_PROPAGATE_DEADLINE) { if (args->propagation_mask & GRPC_PROPAGATE_DEADLINE) {
send_deadline = gpr_time_min( send_deadline = gpr_time_min(
@ -341,6 +349,10 @@ grpc_error *grpc_call_create(grpc_exec_ctx *exec_ctx,
} }
if (args->propagation_mask & GRPC_PROPAGATE_CANCELLATION) { if (args->propagation_mask & GRPC_PROPAGATE_CANCELLATION) {
call->cancellation_is_inherited = 1; call->cancellation_is_inherited = 1;
if (gpr_atm_acq_load(&args->parent_call->received_final_op_atm)) {
cancel_with_error(exec_ctx, call, STATUS_FROM_API_OVERRIDE,
GRPC_ERROR_CANCELLED);
}
} }
if (args->parent_call->first_child == NULL) { if (args->parent_call->first_child == NULL) {
@ -353,18 +365,23 @@ grpc_error *grpc_call_create(grpc_exec_ctx *exec_ctx,
call; call;
} }
gpr_mu_unlock(&args->parent_call->mu); gpr_mu_unlock(&args->parent_call->child_list_mu);
} }
call->send_deadline = send_deadline; call->send_deadline = send_deadline;
GRPC_CHANNEL_INTERNAL_REF(args->channel, "call"); GRPC_CHANNEL_INTERNAL_REF(args->channel, "call");
/* initial refcount dropped by grpc_call_destroy */ /* initial refcount dropped by grpc_call_destroy */
grpc_call_element_args call_args = {
.call_stack = CALL_STACK_FROM_CALL(call),
.server_transport_data = args->server_transport_data,
.context = call->context,
.path = path,
.start_time = call->start_time,
.deadline = send_deadline,
.arena = call->arena};
add_init_error(&error, grpc_call_stack_init(exec_ctx, channel_stack, 1, add_init_error(&error, grpc_call_stack_init(exec_ctx, channel_stack, 1,
destroy_call, call, call->context, destroy_call, call, &call_args));
args->server_transport_data, path,
call->start_time, send_deadline,
CALL_STACK_FROM_CALL(call)));
if (error != GRPC_ERROR_NONE) { if (error != GRPC_ERROR_NONE) {
cancel_with_error(exec_ctx, call, STATUS_FROM_SURFACE, cancel_with_error(exec_ctx, call, STATUS_FROM_SURFACE,
GRPC_ERROR_REF(error)); GRPC_ERROR_REF(error));
@ -421,6 +438,14 @@ void grpc_call_internal_unref(grpc_exec_ctx *exec_ctx, grpc_call *c REF_ARG) {
GRPC_CALL_STACK_UNREF(exec_ctx, CALL_STACK_FROM_CALL(c), REF_REASON); GRPC_CALL_STACK_UNREF(exec_ctx, CALL_STACK_FROM_CALL(c), REF_REASON);
} }
static void release_call(grpc_exec_ctx *exec_ctx, void *call,
grpc_error *error) {
grpc_call *c = call;
grpc_channel *channel = c->channel;
grpc_channel_update_call_size_estimate(channel, gpr_arena_destroy(c->arena));
GRPC_CHANNEL_INTERNAL_UNREF(exec_ctx, channel, "call");
}
static void set_status_value_directly(grpc_status_code status, void *dest); static void set_status_value_directly(grpc_status_code status, void *dest);
static void destroy_call(grpc_exec_ctx *exec_ctx, void *call, static void destroy_call(grpc_exec_ctx *exec_ctx, void *call,
grpc_error *error) { grpc_error *error) {
@ -435,7 +460,7 @@ static void destroy_call(grpc_exec_ctx *exec_ctx, void *call,
if (c->receiving_stream != NULL) { if (c->receiving_stream != NULL) {
grpc_byte_stream_destroy(exec_ctx, c->receiving_stream); grpc_byte_stream_destroy(exec_ctx, c->receiving_stream);
} }
gpr_mu_destroy(&c->mu); gpr_mu_destroy(&c->child_list_mu);
for (ii = 0; ii < c->send_extra_metadata_count; ii++) { for (ii = 0; ii < c->send_extra_metadata_count; ii++) {
GRPC_MDELEM_UNREF(exec_ctx, c->send_extra_metadata[ii].md); GRPC_MDELEM_UNREF(exec_ctx, c->send_extra_metadata[ii].md);
} }
@ -447,7 +472,6 @@ static void destroy_call(grpc_exec_ctx *exec_ctx, void *call,
if (c->cq) { if (c->cq) {
GRPC_CQ_INTERNAL_UNREF(c->cq, "bind"); GRPC_CQ_INTERNAL_UNREF(c->cq, "bind");
} }
grpc_channel *channel = c->channel;
get_final_status(call, set_status_value_directly, &c->final_info.final_status, get_final_status(call, set_status_value_directly, &c->final_info.final_status,
NULL); NULL);
@ -456,11 +480,12 @@ static void destroy_call(grpc_exec_ctx *exec_ctx, void *call,
for (i = 0; i < STATUS_SOURCE_COUNT; i++) { for (i = 0; i < STATUS_SOURCE_COUNT; i++) {
GRPC_ERROR_UNREF( GRPC_ERROR_UNREF(
unpack_received_status(gpr_atm_no_barrier_load(&c->status[i])).error); unpack_received_status(gpr_atm_acq_load(&c->status[i])).error);
} }
grpc_call_stack_destroy(exec_ctx, CALL_STACK_FROM_CALL(c), &c->final_info, c); grpc_call_stack_destroy(exec_ctx, CALL_STACK_FROM_CALL(c), &c->final_info,
GRPC_CHANNEL_INTERNAL_UNREF(exec_ctx, channel, "call"); grpc_closure_init(&c->release_call, release_call, c,
grpc_schedule_on_exec_ctx));
GPR_TIMER_END("destroy_call", 0); GPR_TIMER_END("destroy_call", 0);
} }
@ -473,7 +498,7 @@ void grpc_call_destroy(grpc_call *c) {
GRPC_API_TRACE("grpc_call_destroy(c=%p)", 1, (c)); GRPC_API_TRACE("grpc_call_destroy(c=%p)", 1, (c));
if (parent) { if (parent) {
gpr_mu_lock(&parent->mu); gpr_mu_lock(&parent->child_list_mu);
if (c == parent->first_child) { if (c == parent->first_child) {
parent->first_child = c->sibling_next; parent->first_child = c->sibling_next;
if (c == parent->first_child) { if (c == parent->first_child) {
@ -482,15 +507,14 @@ void grpc_call_destroy(grpc_call *c) {
c->sibling_prev->sibling_next = c->sibling_next; c->sibling_prev->sibling_next = c->sibling_next;
c->sibling_next->sibling_prev = c->sibling_prev; c->sibling_next->sibling_prev = c->sibling_prev;
} }
gpr_mu_unlock(&parent->mu); gpr_mu_unlock(&parent->child_list_mu);
GRPC_CALL_INTERNAL_UNREF(&exec_ctx, parent, "child"); GRPC_CALL_INTERNAL_UNREF(&exec_ctx, parent, "child");
} }
gpr_mu_lock(&c->mu);
GPR_ASSERT(!c->destroy_called); GPR_ASSERT(!c->destroy_called);
c->destroy_called = 1; c->destroy_called = 1;
cancel = c->sent_any_op && !c->received_final_op; cancel = gpr_atm_acq_load(&c->any_ops_sent_atm) &&
gpr_mu_unlock(&c->mu); !gpr_atm_acq_load(&c->received_final_op_atm);
if (cancel) { if (cancel) {
cancel_with_error(&exec_ctx, c, STATUS_FROM_API_OVERRIDE, cancel_with_error(&exec_ctx, c, STATUS_FROM_API_OVERRIDE,
GRPC_ERROR_CANCELLED); GRPC_ERROR_CANCELLED);
@ -555,53 +579,25 @@ grpc_call_error grpc_call_cancel_with_status(grpc_call *c,
"c=%p, status=%d, description=%s, reserved=%p)", "c=%p, status=%d, description=%s, reserved=%p)",
4, (c, (int)status, description, reserved)); 4, (c, (int)status, description, reserved));
GPR_ASSERT(reserved == NULL); GPR_ASSERT(reserved == NULL);
gpr_mu_lock(&c->mu);
cancel_with_status(&exec_ctx, c, STATUS_FROM_API_OVERRIDE, status, cancel_with_status(&exec_ctx, c, STATUS_FROM_API_OVERRIDE, status,
description); description);
gpr_mu_unlock(&c->mu);
grpc_exec_ctx_finish(&exec_ctx); grpc_exec_ctx_finish(&exec_ctx);
return GRPC_CALL_OK; return GRPC_CALL_OK;
} }
typedef struct termination_closure { static void done_termination(grpc_exec_ctx *exec_ctx, void *call,
grpc_closure closure;
grpc_call *call;
grpc_transport_stream_op op;
} termination_closure;
static void done_termination(grpc_exec_ctx *exec_ctx, void *tcp,
grpc_error *error) {
termination_closure *tc = tcp;
GRPC_CALL_INTERNAL_UNREF(exec_ctx, tc->call, "termination");
gpr_free(tc);
}
static void send_termination(grpc_exec_ctx *exec_ctx, void *tcp,
grpc_error *error) {
termination_closure *tc = tcp;
memset(&tc->op, 0, sizeof(tc->op));
tc->op.cancel_error = GRPC_ERROR_REF(error);
/* reuse closure to catch completion */
tc->op.on_complete = grpc_closure_init(&tc->closure, done_termination, tc,
grpc_schedule_on_exec_ctx);
execute_op(exec_ctx, tc->call, &tc->op);
}
static void terminate_with_error(grpc_exec_ctx *exec_ctx, grpc_call *c,
grpc_error *error) { grpc_error *error) {
termination_closure *tc = gpr_malloc(sizeof(*tc)); GRPC_CALL_INTERNAL_UNREF(exec_ctx, call, "termination");
memset(tc, 0, sizeof(*tc));
tc->call = c;
GRPC_CALL_INTERNAL_REF(tc->call, "termination");
grpc_closure_sched(exec_ctx, grpc_closure_init(&tc->closure, send_termination,
tc, grpc_schedule_on_exec_ctx),
error);
} }
static void cancel_with_error(grpc_exec_ctx *exec_ctx, grpc_call *c, static void cancel_with_error(grpc_exec_ctx *exec_ctx, grpc_call *c,
status_source source, grpc_error *error) { status_source source, grpc_error *error) {
GRPC_CALL_INTERNAL_REF(c, "termination");
set_status_from_error(exec_ctx, c, source, GRPC_ERROR_REF(error)); set_status_from_error(exec_ctx, c, source, GRPC_ERROR_REF(error));
terminate_with_error(exec_ctx, c, error); grpc_transport_stream_op *op = grpc_make_transport_stream_op(
grpc_closure_create(done_termination, c, grpc_schedule_on_exec_ctx));
op->cancel_error = error;
execute_op(exec_ctx, c, op);
} }
static grpc_error *error_from_status(grpc_status_code status, static grpc_error *error_from_status(grpc_status_code status,
@ -715,9 +711,7 @@ static void set_incoming_compression_algorithm(
grpc_compression_algorithm grpc_call_test_only_get_compression_algorithm( grpc_compression_algorithm grpc_call_test_only_get_compression_algorithm(
grpc_call *call) { grpc_call *call) {
grpc_compression_algorithm algorithm; grpc_compression_algorithm algorithm;
gpr_mu_lock(&call->mu);
algorithm = call->incoming_compression_algorithm; algorithm = call->incoming_compression_algorithm;
gpr_mu_unlock(&call->mu);
return algorithm; return algorithm;
} }
@ -729,9 +723,7 @@ static grpc_compression_algorithm compression_algorithm_for_level_locked(
uint32_t grpc_call_test_only_get_message_flags(grpc_call *call) { uint32_t grpc_call_test_only_get_message_flags(grpc_call *call) {
uint32_t flags; uint32_t flags;
gpr_mu_lock(&call->mu);
flags = call->test_only_last_message_flags; flags = call->test_only_last_message_flags;
gpr_mu_unlock(&call->mu);
return flags; return flags;
} }
@ -785,9 +777,7 @@ static void set_encodings_accepted_by_peer(grpc_exec_ctx *exec_ctx,
uint32_t grpc_call_test_only_get_encodings_accepted_by_peer(grpc_call *call) { uint32_t grpc_call_test_only_get_encodings_accepted_by_peer(grpc_call *call) {
uint32_t encodings_accepted_by_peer; uint32_t encodings_accepted_by_peer;
gpr_mu_lock(&call->mu);
encodings_accepted_by_peer = call->encodings_accepted_by_peer; encodings_accepted_by_peer = call->encodings_accepted_by_peer;
gpr_mu_unlock(&call->mu);
return encodings_accepted_by_peer; return encodings_accepted_by_peer;
} }
@ -1056,7 +1046,7 @@ static void finish_batch_completion(grpc_exec_ctx *exec_ctx, void *user_data,
} }
static grpc_error *consolidate_batch_errors(batch_control *bctl) { static grpc_error *consolidate_batch_errors(batch_control *bctl) {
size_t n = (size_t)gpr_atm_no_barrier_load(&bctl->num_errors); size_t n = (size_t)gpr_atm_acq_load(&bctl->num_errors);
if (n == 0) { if (n == 0) {
return GRPC_ERROR_NONE; return GRPC_ERROR_NONE;
} else if (n == 1) { } else if (n == 1) {
@ -1083,8 +1073,6 @@ static void post_batch_completion(grpc_exec_ctx *exec_ctx,
grpc_call *call = bctl->call; grpc_call *call = bctl->call;
grpc_error *error = consolidate_batch_errors(bctl); grpc_error *error = consolidate_batch_errors(bctl);
gpr_mu_lock(&call->mu);
if (bctl->send_initial_metadata) { if (bctl->send_initial_metadata) {
grpc_metadata_batch_destroy( grpc_metadata_batch_destroy(
exec_ctx, exec_ctx,
@ -1103,20 +1091,23 @@ static void post_batch_completion(grpc_exec_ctx *exec_ctx,
&call->metadata_batch[1 /* is_receiving */][1 /* is_trailing */]; &call->metadata_batch[1 /* is_receiving */][1 /* is_trailing */];
recv_trailing_filter(exec_ctx, call, md); recv_trailing_filter(exec_ctx, call, md);
call->received_final_op = true;
/* propagate cancellation to any interested children */ /* propagate cancellation to any interested children */
gpr_atm_rel_store(&call->received_final_op_atm, 1);
gpr_mu_lock(&call->child_list_mu);
child_call = call->first_child; child_call = call->first_child;
if (child_call != NULL) { if (child_call != NULL) {
do { do {
next_child_call = child_call->sibling_next; next_child_call = child_call->sibling_next;
if (child_call->cancellation_is_inherited) { if (child_call->cancellation_is_inherited) {
GRPC_CALL_INTERNAL_REF(child_call, "propagate_cancel"); GRPC_CALL_INTERNAL_REF(child_call, "propagate_cancel");
grpc_call_cancel(child_call, NULL); cancel_with_error(exec_ctx, child_call, STATUS_FROM_API_OVERRIDE,
GRPC_ERROR_CANCELLED);
GRPC_CALL_INTERNAL_UNREF(exec_ctx, child_call, "propagate_cancel"); GRPC_CALL_INTERNAL_UNREF(exec_ctx, child_call, "propagate_cancel");
} }
child_call = next_child_call; child_call = next_child_call;
} while (child_call != call->first_child); } while (child_call != call->first_child);
} }
gpr_mu_unlock(&call->child_list_mu);
if (call->is_client) { if (call->is_client) {
get_final_status(call, set_status_value_directly, get_final_status(call, set_status_value_directly,
@ -1130,7 +1121,6 @@ static void post_batch_completion(grpc_exec_ctx *exec_ctx,
GRPC_ERROR_UNREF(error); GRPC_ERROR_UNREF(error);
error = GRPC_ERROR_NONE; error = GRPC_ERROR_NONE;
} }
gpr_mu_unlock(&call->mu);
if (bctl->is_notify_tag_closure) { if (bctl->is_notify_tag_closure) {
/* unrefs bctl->error */ /* unrefs bctl->error */
@ -1221,7 +1211,6 @@ static void receiving_stream_ready(grpc_exec_ctx *exec_ctx, void *bctlp,
grpc_error *error) { grpc_error *error) {
batch_control *bctl = bctlp; batch_control *bctl = bctlp;
grpc_call *call = bctl->call; grpc_call *call = bctl->call;
gpr_mu_lock(&bctl->call->mu);
if (error != GRPC_ERROR_NONE) { if (error != GRPC_ERROR_NONE) {
if (call->receiving_stream != NULL) { if (call->receiving_stream != NULL) {
grpc_byte_stream_destroy(exec_ctx, call->receiving_stream); grpc_byte_stream_destroy(exec_ctx, call->receiving_stream);
@ -1233,11 +1222,9 @@ static void receiving_stream_ready(grpc_exec_ctx *exec_ctx, void *bctlp,
} }
if (call->has_initial_md_been_received || error != GRPC_ERROR_NONE || if (call->has_initial_md_been_received || error != GRPC_ERROR_NONE ||
call->receiving_stream == NULL) { call->receiving_stream == NULL) {
gpr_mu_unlock(&bctl->call->mu);
process_data_after_md(exec_ctx, bctlp); process_data_after_md(exec_ctx, bctlp);
} else { } else {
call->saved_receiving_stream_ready_bctlp = bctlp; call->saved_receiving_stream_ready_bctlp = bctlp;
gpr_mu_unlock(&bctl->call->mu);
} }
} }
@ -1296,7 +1283,7 @@ static void validate_filtered_metadata(grpc_exec_ctx *exec_ctx,
static void add_batch_error(grpc_exec_ctx *exec_ctx, batch_control *bctl, static void add_batch_error(grpc_exec_ctx *exec_ctx, batch_control *bctl,
grpc_error *error, bool has_cancelled) { grpc_error *error, bool has_cancelled) {
if (error == GRPC_ERROR_NONE) return; if (error == GRPC_ERROR_NONE) return;
int idx = (int)gpr_atm_no_barrier_fetch_add(&bctl->num_errors, 1); int idx = (int)gpr_atm_full_fetch_add(&bctl->num_errors, 1);
if (idx == 0 && !has_cancelled) { if (idx == 0 && !has_cancelled) {
cancel_with_error(exec_ctx, bctl->call, STATUS_FROM_CORE, cancel_with_error(exec_ctx, bctl->call, STATUS_FROM_CORE,
GRPC_ERROR_REF(error)); GRPC_ERROR_REF(error));
@ -1309,8 +1296,6 @@ static void receiving_initial_metadata_ready(grpc_exec_ctx *exec_ctx,
batch_control *bctl = bctlp; batch_control *bctl = bctlp;
grpc_call *call = bctl->call; grpc_call *call = bctl->call;
gpr_mu_lock(&call->mu);
add_batch_error(exec_ctx, bctl, GRPC_ERROR_REF(error), false); add_batch_error(exec_ctx, bctl, GRPC_ERROR_REF(error), false);
if (error == GRPC_ERROR_NONE) { if (error == GRPC_ERROR_NONE) {
grpc_metadata_batch *md = grpc_metadata_batch *md =
@ -1336,11 +1321,9 @@ static void receiving_initial_metadata_ready(grpc_exec_ctx *exec_ctx,
receiving_stream_ready, call->saved_receiving_stream_ready_bctlp, receiving_stream_ready, call->saved_receiving_stream_ready_bctlp,
grpc_schedule_on_exec_ctx); grpc_schedule_on_exec_ctx);
call->saved_receiving_stream_ready_bctlp = NULL; call->saved_receiving_stream_ready_bctlp = NULL;
grpc_closure_sched(exec_ctx, saved_rsr_closure, GRPC_ERROR_REF(error)); grpc_closure_run(exec_ctx, saved_rsr_closure, GRPC_ERROR_REF(error));
} }
gpr_mu_unlock(&call->mu);
finish_batch_step(exec_ctx, bctl); finish_batch_step(exec_ctx, bctl);
} }
@ -1393,7 +1376,6 @@ static grpc_call_error call_start_batch(grpc_exec_ctx *exec_ctx,
bctl->notify_tag = notify_tag; bctl->notify_tag = notify_tag;
bctl->is_notify_tag_closure = (uint8_t)(is_notify_tag_closure != 0); bctl->is_notify_tag_closure = (uint8_t)(is_notify_tag_closure != 0);
gpr_mu_lock(&call->mu);
grpc_transport_stream_op *stream_op = &bctl->op; grpc_transport_stream_op *stream_op = &bctl->op;
memset(stream_op, 0, sizeof(*stream_op)); memset(stream_op, 0, sizeof(*stream_op));
stream_op->covered_by_poller = true; stream_op->covered_by_poller = true;
@ -1679,8 +1661,7 @@ static grpc_call_error call_start_batch(grpc_exec_ctx *exec_ctx,
grpc_closure_init(&bctl->finish_batch, finish_batch, bctl, grpc_closure_init(&bctl->finish_batch, finish_batch, bctl,
grpc_schedule_on_exec_ctx); grpc_schedule_on_exec_ctx);
stream_op->on_complete = &bctl->finish_batch; stream_op->on_complete = &bctl->finish_batch;
call->sent_any_op = true; gpr_atm_rel_store(&call->any_ops_sent_atm, 1);
gpr_mu_unlock(&call->mu);
execute_op(exec_ctx, call, stream_op); execute_op(exec_ctx, call, stream_op);
@ -1711,7 +1692,6 @@ done_with_error:
if (bctl->recv_final_op) { if (bctl->recv_final_op) {
call->requested_final_op = 0; call->requested_final_op = 0;
} }
gpr_mu_unlock(&call->mu);
goto done; goto done;
} }
@ -1760,10 +1740,8 @@ uint8_t grpc_call_is_client(grpc_call *call) { return call->is_client; }
grpc_compression_algorithm grpc_call_compression_for_level( grpc_compression_algorithm grpc_call_compression_for_level(
grpc_call *call, grpc_compression_level level) { grpc_call *call, grpc_compression_level level) {
gpr_mu_lock(&call->mu);
grpc_compression_algorithm algo = grpc_compression_algorithm algo =
compression_algorithm_for_level_locked(call, level); compression_algorithm_for_level_locked(call, level);
gpr_mu_unlock(&call->mu);
return algo; return algo;
} }

@ -68,6 +68,8 @@ struct grpc_channel {
grpc_compression_options compression_options; grpc_compression_options compression_options;
grpc_mdelem default_authority; grpc_mdelem default_authority;
gpr_atm call_size_estimate;
gpr_mu registered_call_mu; gpr_mu registered_call_mu;
registered_call *registered_calls; registered_call *registered_calls;
@ -115,6 +117,10 @@ grpc_channel *grpc_channel_create(grpc_exec_ctx *exec_ctx, const char *target,
gpr_mu_init(&channel->registered_call_mu); gpr_mu_init(&channel->registered_call_mu);
channel->registered_calls = NULL; channel->registered_calls = NULL;
gpr_atm_no_barrier_store(
&channel->call_size_estimate,
(gpr_atm)CHANNEL_STACK_FROM_CHANNEL(channel)->call_stack_size);
grpc_compression_options_init(&channel->compression_options); grpc_compression_options_init(&channel->compression_options);
for (size_t i = 0; i < args->num_args; i++) { for (size_t i = 0; i < args->num_args; i++) {
if (0 == strcmp(args->args[i].key, GRPC_ARG_DEFAULT_AUTHORITY)) { if (0 == strcmp(args->args[i].key, GRPC_ARG_DEFAULT_AUTHORITY)) {
@ -177,6 +183,32 @@ done:
return channel; return channel;
} }
size_t grpc_channel_get_call_size_estimate(grpc_channel *channel) {
#define ROUND_UP_SIZE 256
return ((size_t)gpr_atm_no_barrier_load(&channel->call_size_estimate) +
ROUND_UP_SIZE) &
~(size_t)(ROUND_UP_SIZE - 1);
}
void grpc_channel_update_call_size_estimate(grpc_channel *channel,
size_t size) {
size_t cur = (size_t)gpr_atm_no_barrier_load(&channel->call_size_estimate);
if (cur < size) {
/* size grew: update estimate */
gpr_atm_no_barrier_cas(&channel->call_size_estimate, (gpr_atm)cur,
(gpr_atm)size);
/* if we lose: never mind, something else will likely update soon enough */
} else if (cur == size) {
/* no change: holding pattern */
} else if (cur > 0) {
/* size shrank: decrease estimate */
gpr_atm_no_barrier_cas(
&channel->call_size_estimate, (gpr_atm)cur,
(gpr_atm)(GPR_MIN(cur - 1, (255 * cur + size) / 256)));
/* if we lose: never mind, something else will likely update soon enough */
}
}
char *grpc_channel_get_target(grpc_channel *channel) { char *grpc_channel_get_target(grpc_channel *channel) {
GRPC_API_TRACE("grpc_channel_get_target(channel=%p)", 1, (channel)); GRPC_API_TRACE("grpc_channel_get_target(channel=%p)", 1, (channel));
return gpr_strdup(channel->target); return gpr_strdup(channel->target);

@ -66,6 +66,9 @@ grpc_mdelem grpc_channel_get_reffed_status_elem(grpc_exec_ctx *exec_ctx,
grpc_channel *channel, grpc_channel *channel,
int status_code); int status_code);
size_t grpc_channel_get_call_size_estimate(grpc_channel *channel);
void grpc_channel_update_call_size_estimate(grpc_channel *channel, size_t size);
#ifdef GRPC_STREAM_REFCOUNT_DEBUG #ifdef GRPC_STREAM_REFCOUNT_DEBUG
void grpc_channel_internal_ref(grpc_channel *channel, const char *reason); void grpc_channel_internal_ref(grpc_channel *channel, const char *reason);
void grpc_channel_internal_unref(grpc_exec_ctx *exec_ctx, grpc_channel *channel, void grpc_channel_internal_unref(grpc_exec_ctx *exec_ctx, grpc_channel *channel,

@ -130,8 +130,8 @@ static grpc_error *init_call_elem(grpc_exec_ctx *exec_ctx,
static void destroy_call_elem(grpc_exec_ctx *exec_ctx, grpc_call_element *elem, static void destroy_call_elem(grpc_exec_ctx *exec_ctx, grpc_call_element *elem,
const grpc_call_final_info *final_info, const grpc_call_final_info *final_info,
void *and_free_memory) { grpc_closure *then_schedule_closure) {
gpr_free(and_free_memory); grpc_closure_sched(exec_ctx, then_schedule_closure, GRPC_ERROR_NONE);
} }
static grpc_error *init_channel_elem(grpc_exec_ctx *exec_ctx, static grpc_error *init_channel_elem(grpc_exec_ctx *exec_ctx,

@ -898,7 +898,7 @@ static grpc_error *init_call_elem(grpc_exec_ctx *exec_ctx,
static void destroy_call_elem(grpc_exec_ctx *exec_ctx, grpc_call_element *elem, static void destroy_call_elem(grpc_exec_ctx *exec_ctx, grpc_call_element *elem,
const grpc_call_final_info *final_info, const grpc_call_final_info *final_info,
void *ignored) { grpc_closure *ignored) {
channel_data *chand = elem->channel_data; channel_data *chand = elem->channel_data;
call_data *calld = elem->call_data; call_data *calld = elem->call_data;

@ -38,4 +38,4 @@
const char *grpc_version_string(void) { return "3.0.0-dev"; } const char *grpc_version_string(void) { return "3.0.0-dev"; }
const char *grpc_g_stands_for(void) { return "green"; } const char *grpc_g_stands_for(void) { return "gentle"; }

@ -44,12 +44,12 @@ static grpc_error *recursively_find_error_with_field(grpc_error *error,
} }
if (grpc_error_is_special(error)) return NULL; if (grpc_error_is_special(error)) return NULL;
// Otherwise, search through its children. // Otherwise, search through its children.
intptr_t key = 0; uint8_t slot = error->first_err;
while (true) { while (slot != UINT8_MAX) {
grpc_error *child_error = gpr_avl_get(error->errs, (void *)key++); grpc_linked_error *lerr = (grpc_linked_error *)(error->arena + slot);
if (child_error == NULL) break; grpc_error *result = recursively_find_error_with_field(lerr->err, which);
grpc_error *result = recursively_find_error_with_field(child_error, which); if (result) return result;
if (result != NULL) return result; slot = lerr->next;
} }
return NULL; return NULL;
} }
@ -112,13 +112,13 @@ bool grpc_error_has_clear_grpc_status(grpc_error *error) {
if (grpc_error_get_int(error, GRPC_ERROR_INT_GRPC_STATUS, NULL)) { if (grpc_error_get_int(error, GRPC_ERROR_INT_GRPC_STATUS, NULL)) {
return true; return true;
} }
intptr_t key = 0; uint8_t slot = error->first_err;
while (true) { while (slot != UINT8_MAX) {
grpc_error *child_error = gpr_avl_get(error->errs, (void *)key++); grpc_linked_error *lerr = (grpc_linked_error *)(error->arena + slot);
if (child_error == NULL) break; if (grpc_error_has_clear_grpc_status(lerr->err)) {
if (grpc_error_has_clear_grpc_status(child_error)) {
return true; return true;
} }
slot = lerr->next;
} }
return false; return false;
} }

@ -162,9 +162,9 @@ void grpc_transport_destroy(grpc_exec_ctx *exec_ctx,
int grpc_transport_init_stream(grpc_exec_ctx *exec_ctx, int grpc_transport_init_stream(grpc_exec_ctx *exec_ctx,
grpc_transport *transport, grpc_stream *stream, grpc_transport *transport, grpc_stream *stream,
grpc_stream_refcount *refcount, grpc_stream_refcount *refcount,
const void *server_data) { const void *server_data, gpr_arena *arena) {
return transport->vtable->init_stream(exec_ctx, transport, stream, refcount, return transport->vtable->init_stream(exec_ctx, transport, stream, refcount,
server_data); server_data, arena);
} }
void grpc_transport_perform_stream_op(grpc_exec_ctx *exec_ctx, void grpc_transport_perform_stream_op(grpc_exec_ctx *exec_ctx,
@ -197,9 +197,10 @@ void grpc_transport_set_pops(grpc_exec_ctx *exec_ctx, grpc_transport *transport,
void grpc_transport_destroy_stream(grpc_exec_ctx *exec_ctx, void grpc_transport_destroy_stream(grpc_exec_ctx *exec_ctx,
grpc_transport *transport, grpc_transport *transport,
grpc_stream *stream, void *and_free_memory) { grpc_stream *stream,
grpc_closure *then_schedule_closure) {
transport->vtable->destroy_stream(exec_ctx, transport, stream, transport->vtable->destroy_stream(exec_ctx, transport, stream,
and_free_memory); then_schedule_closure);
} }
char *grpc_transport_get_peer(grpc_exec_ctx *exec_ctx, char *grpc_transport_get_peer(grpc_exec_ctx *exec_ctx,
@ -254,8 +255,9 @@ typedef struct {
static void destroy_made_transport_stream_op(grpc_exec_ctx *exec_ctx, void *arg, static void destroy_made_transport_stream_op(grpc_exec_ctx *exec_ctx, void *arg,
grpc_error *error) { grpc_error *error) {
made_transport_stream_op *op = arg; made_transport_stream_op *op = arg;
grpc_closure_sched(exec_ctx, op->inner_on_complete, GRPC_ERROR_REF(error)); grpc_closure *c = op->inner_on_complete;
gpr_free(op); gpr_free(op);
grpc_closure_run(exec_ctx, c, GRPC_ERROR_REF(error));
} }
grpc_transport_stream_op *grpc_make_transport_stream_op( grpc_transport_stream_op *grpc_make_transport_stream_op(

@ -41,6 +41,7 @@
#include "src/core/lib/iomgr/polling_entity.h" #include "src/core/lib/iomgr/polling_entity.h"
#include "src/core/lib/iomgr/pollset.h" #include "src/core/lib/iomgr/pollset.h"
#include "src/core/lib/iomgr/pollset_set.h" #include "src/core/lib/iomgr/pollset_set.h"
#include "src/core/lib/support/arena.h"
#include "src/core/lib/transport/byte_stream.h" #include "src/core/lib/transport/byte_stream.h"
#include "src/core/lib/transport/metadata_batch.h" #include "src/core/lib/transport/metadata_batch.h"
@ -229,7 +230,7 @@ size_t grpc_transport_stream_size(grpc_transport *transport);
int grpc_transport_init_stream(grpc_exec_ctx *exec_ctx, int grpc_transport_init_stream(grpc_exec_ctx *exec_ctx,
grpc_transport *transport, grpc_stream *stream, grpc_transport *transport, grpc_stream *stream,
grpc_stream_refcount *refcount, grpc_stream_refcount *refcount,
const void *server_data); const void *server_data, gpr_arena *arena);
void grpc_transport_set_pops(grpc_exec_ctx *exec_ctx, grpc_transport *transport, void grpc_transport_set_pops(grpc_exec_ctx *exec_ctx, grpc_transport *transport,
grpc_stream *stream, grpc_polling_entity *pollent); grpc_stream *stream, grpc_polling_entity *pollent);
@ -246,7 +247,8 @@ void grpc_transport_set_pops(grpc_exec_ctx *exec_ctx, grpc_transport *transport,
caller, but any child memory must be cleaned up) */ caller, but any child memory must be cleaned up) */
void grpc_transport_destroy_stream(grpc_exec_ctx *exec_ctx, void grpc_transport_destroy_stream(grpc_exec_ctx *exec_ctx,
grpc_transport *transport, grpc_transport *transport,
grpc_stream *stream, void *and_free_memory); grpc_stream *stream,
grpc_closure *then_schedule_closure);
void grpc_transport_stream_op_finish_with_failure(grpc_exec_ctx *exec_ctx, void grpc_transport_stream_op_finish_with_failure(grpc_exec_ctx *exec_ctx,
grpc_transport_stream_op *op, grpc_transport_stream_op *op,

@ -47,7 +47,7 @@ typedef struct grpc_transport_vtable {
/* implementation of grpc_transport_init_stream */ /* implementation of grpc_transport_init_stream */
int (*init_stream)(grpc_exec_ctx *exec_ctx, grpc_transport *self, int (*init_stream)(grpc_exec_ctx *exec_ctx, grpc_transport *self,
grpc_stream *stream, grpc_stream_refcount *refcount, grpc_stream *stream, grpc_stream_refcount *refcount,
const void *server_data); const void *server_data, gpr_arena *arena);
/* implementation of grpc_transport_set_pollset */ /* implementation of grpc_transport_set_pollset */
void (*set_pollset)(grpc_exec_ctx *exec_ctx, grpc_transport *self, void (*set_pollset)(grpc_exec_ctx *exec_ctx, grpc_transport *self,
@ -67,7 +67,8 @@ typedef struct grpc_transport_vtable {
/* implementation of grpc_transport_destroy_stream */ /* implementation of grpc_transport_destroy_stream */
void (*destroy_stream)(grpc_exec_ctx *exec_ctx, grpc_transport *self, void (*destroy_stream)(grpc_exec_ctx *exec_ctx, grpc_transport *self,
grpc_stream *stream, void *and_free_memory); grpc_stream *stream,
grpc_closure *then_schedule_closure);
/* implementation of grpc_transport_destroy */ /* implementation of grpc_transport_destroy */
void (*destroy)(grpc_exec_ctx *exec_ctx, grpc_transport *self); void (*destroy)(grpc_exec_ctx *exec_ctx, grpc_transport *self);

@ -81,6 +81,16 @@ ChannelArguments::ChannelArguments(const ChannelArguments& other)
} }
} }
ChannelArguments::~ChannelArguments() {
grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
for (auto it = args_.begin(); it != args_.end(); ++it) {
if (it->type == GRPC_ARG_POINTER) {
it->value.pointer.vtable->destroy(&exec_ctx, it->value.pointer.p);
}
}
grpc_exec_ctx_finish(&exec_ctx);
}
void ChannelArguments::Swap(ChannelArguments& other) { void ChannelArguments::Swap(ChannelArguments& other) {
args_.swap(other.args_); args_.swap(other.args_);
strings_.swap(other.strings_); strings_.swap(other.strings_);
@ -101,8 +111,10 @@ void ChannelArguments::SetSocketMutator(grpc_socket_mutator* mutator) {
for (auto it = args_.begin(); it != args_.end(); ++it) { for (auto it = args_.begin(); it != args_.end(); ++it) {
if (it->type == mutator_arg.type && if (it->type == mutator_arg.type &&
grpc::string(it->key) == grpc::string(mutator_arg.key)) { grpc::string(it->key) == grpc::string(mutator_arg.key)) {
GPR_ASSERT(!replaced);
it->value.pointer.vtable->destroy(&exec_ctx, it->value.pointer.p); it->value.pointer.vtable->destroy(&exec_ctx, it->value.pointer.p);
it->value.pointer = mutator_arg.value.pointer; it->value.pointer = mutator_arg.value.pointer;
replaced = true;
} }
} }
grpc_exec_ctx_finish(&exec_ctx); grpc_exec_ctx_finish(&exec_ctx);
@ -185,7 +197,7 @@ void ChannelArguments::SetPointerWithVtable(
arg.type = GRPC_ARG_POINTER; arg.type = GRPC_ARG_POINTER;
strings_.push_back(key); strings_.push_back(key);
arg.key = const_cast<char*>(strings_.back().c_str()); arg.key = const_cast<char*>(strings_.back().c_str());
arg.value.pointer.p = value; arg.value.pointer.p = vtable->copy(value);
arg.value.pointer.vtable = vtable; arg.value.pointer.vtable = vtable;
args_.push_back(arg); args_.push_back(arg);
} }

@ -318,7 +318,8 @@ class ChannelFilter final {
static void DestroyCallElement(grpc_exec_ctx *exec_ctx, static void DestroyCallElement(grpc_exec_ctx *exec_ctx,
grpc_call_element *elem, grpc_call_element *elem,
const grpc_call_final_info *final_info, const grpc_call_final_info *final_info,
void *and_free_memory) { grpc_closure *then_call_closure) {
GPR_ASSERT(then_call_closure == NULL);
reinterpret_cast<CallDataType *>(elem->call_data)->~CallDataType(); reinterpret_cast<CallDataType *>(elem->call_data)->~CallDataType();
} }

@ -37,5 +37,5 @@
#include <grpc++/grpc++.h> #include <grpc++/grpc++.h>
namespace grpc { namespace grpc {
grpc::string Version() { return "1.2.0-dev"; } grpc::string Version() { return "1.3.0-dev"; }
} }

@ -0,0 +1,78 @@
/*
*
* 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++/impl/channel_argument_option.h>
namespace grpc {
std::unique_ptr<ServerBuilderOption> MakeChannelArgumentOption(
const grpc::string &name, const grpc::string &value) {
class StringOption final : public ServerBuilderOption {
public:
StringOption(const grpc::string &name, const grpc::string &value)
: name_(name), value_(value) {}
virtual void UpdateArguments(ChannelArguments *args) override {
args->SetString(name_, value_);
}
virtual void UpdatePlugins(
std::vector<std::unique_ptr<ServerBuilderPlugin>> *plugins) override {}
private:
const grpc::string name_;
const grpc::string value_;
};
return std::unique_ptr<ServerBuilderOption>(new StringOption(name, value));
}
std::unique_ptr<ServerBuilderOption> MakeChannelArgumentOption(
const grpc::string &name, int value) {
class IntOption final : public ServerBuilderOption {
public:
IntOption(const grpc::string &name, int value)
: name_(name), value_(value) {}
virtual void UpdateArguments(ChannelArguments *args) override {
args->SetInt(name_, value_);
}
virtual void UpdatePlugins(
std::vector<std::unique_ptr<ServerBuilderPlugin>> *plugins) override {}
private:
const grpc::string name_;
const int value_;
};
return std::unique_ptr<ServerBuilderOption>(new IntOption(name, value));
}
} // namespace grpc

@ -323,9 +323,14 @@ std::unique_ptr<Server> ServerBuilder::BuildAndStart() {
} }
} }
bool added_port = false;
for (auto port = ports_.begin(); port != ports_.end(); port++) { for (auto port = ports_.begin(); port != ports_.end(); port++) {
int r = server->AddListeningPort(port->addr, port->creds.get()); int r = server->AddListeningPort(port->addr, port->creds.get());
if (!r) return nullptr; if (!r) {
if (added_port) server->Shutdown();
return nullptr;
}
added_port = true;
if (port->selected_port != nullptr) { if (port->selected_port != nullptr) {
*port->selected_port = r; *port->selected_port = r;
} }
@ -333,6 +338,7 @@ std::unique_ptr<Server> ServerBuilder::BuildAndStart() {
auto cqs_data = cqs_.empty() ? nullptr : &cqs_[0]; auto cqs_data = cqs_.empty() ? nullptr : &cqs_[0];
if (!server->Start(cqs_data, cqs_.size())) { if (!server->Start(cqs_data, cqs_.size())) {
if (added_port) server->Shutdown();
return nullptr; return nullptr;
} }

@ -534,7 +534,7 @@ bool Server::Start(ServerCompletionQueue** cqs, size_t num_cqs) {
void Server::ShutdownInternal(gpr_timespec deadline) { void Server::ShutdownInternal(gpr_timespec deadline) {
std::unique_lock<std::mutex> lock(mu_); std::unique_lock<std::mutex> lock(mu_);
if (started_ && !shutdown_) { if (!shutdown_) {
shutdown_ = true; shutdown_ = true;
/// The completion queue to use for server shutdown completion notification /// The completion queue to use for server shutdown completion notification

@ -1,5 +1,5 @@
{ {
"version": "1.2.0-dev", "version": "1.3.0-dev",
"title": "gRPC C# Auth", "title": "gRPC C# Auth",
"authors": [ "Google Inc." ], "authors": [ "Google Inc." ],
"copyright": "Copyright 2015, Google Inc.", "copyright": "Copyright 2015, Google Inc.",
@ -21,7 +21,7 @@
} }
}, },
"dependencies": { "dependencies": {
"Grpc.Core": "1.2.0-dev", "Grpc.Core": "1.3.0-dev",
"Google.Apis.Auth": "1.21.0" "Google.Apis.Auth": "1.21.0"
}, },
"frameworks": { "frameworks": {

@ -1,5 +1,5 @@
{ {
"version": "1.2.0-dev", "version": "1.3.0-dev",
"title": "gRPC C# Core Testing", "title": "gRPC C# Core Testing",
"authors": [ "Google Inc." ], "authors": [ "Google Inc." ],
"copyright": "Copyright 2017, Google Inc.", "copyright": "Copyright 2017, Google Inc.",
@ -21,7 +21,7 @@
} }
}, },
"dependencies": { "dependencies": {
"Grpc.Core": "1.2.0-dev" "Grpc.Core": "1.3.0-dev"
}, },
"frameworks": { "frameworks": {
"net45": { "net45": {

@ -1,41 +0,0 @@
<?xml version="1.0" encoding="utf-8" standalone="no"?>
<!--This file represents the results of running a test suite-->
<test-results name="/usr/local/google/home/jtattermusch/github/grpc/src/csharp/GrpcCoreTests/bin/Debug/GrpcCoreTests.dll" total="3" errors="0" failures="0" not-run="0" inconclusive="0" ignored="0" skipped="0" invalid="0" date="2015-01-29" time="19:40:47">
<environment nunit-version="2.6.0.0" clr-version="4.0.30319.17020" os-version="Unix 3.13.0.43" platform="Unix" cwd="/usr/local/google/home/jtattermusch/github/grpc/src/csharp/GrpcCoreTests" machine-name="jtattermusch.mtv.corp.google.com" user="jtattermusch" user-domain="jtattermusch.mtv.corp.google.com" />
<culture-info current-culture="en-US" current-uiculture="en-US" />
<test-suite type="Assembly" name="/usr/local/google/home/jtattermusch/github/grpc/src/csharp/GrpcCoreTests/bin/Debug/GrpcCoreTests.dll" executed="True" result="Success" success="True" time="0.172" asserts="0">
<results>
<test-suite type="Namespace" name="Google" executed="True" result="Success" success="True" time="0.166" asserts="0">
<results>
<test-suite type="Namespace" name="GRPC" executed="True" result="Success" success="True" time="0.166" asserts="0">
<results>
<test-suite type="Namespace" name="Core" executed="True" result="Success" success="True" time="0.166" asserts="0">
<results>
<test-suite type="Namespace" name="Tests" executed="True" result="Success" success="True" time="0.166" asserts="0">
<results>
<test-suite type="TestFixture" name="CallsTest" executed="True" result="Success" success="True" time="0.009" asserts="0">
<results>
<test-case name="Grpc.Core.Tests.CallsTest.Test1" executed="True" result="Success" success="True" time="0.004" asserts="0" />
</results>
</test-suite>
<test-suite type="TestFixture" name="ClientServerTest" executed="True" result="Success" success="True" time="0.149" asserts="0">
<results>
<test-case name="Grpc.Core.Tests.ClientServerTest.EmptyCall" executed="True" result="Success" success="True" time="0.111" asserts="0" />
</results>
</test-suite>
<test-suite type="TestFixture" name="ServerTest" executed="True" result="Success" success="True" time="0.001" asserts="0">
<results>
<test-case name="Grpc.Core.Tests.ServerTest.StartAndShutdownServer" executed="True" result="Success" success="True" time="0.001" asserts="0" />
</results>
</test-suite>
</results>
</test-suite>
</results>
</test-suite>
</results>
</test-suite>
</results>
</test-suite>
</results>
</test-suite>
</test-results>

@ -48,11 +48,11 @@ namespace Grpc.Core
/// <summary> /// <summary>
/// Current <c>AssemblyFileVersion</c> of gRPC C# assemblies /// Current <c>AssemblyFileVersion</c> of gRPC C# assemblies
/// </summary> /// </summary>
public const string CurrentAssemblyFileVersion = "1.2.0.0"; public const string CurrentAssemblyFileVersion = "1.3.0.0";
/// <summary> /// <summary>
/// Current version of gRPC C# /// Current version of gRPC C#
/// </summary> /// </summary>
public const string CurrentVersion = "1.2.0-dev"; public const string CurrentVersion = "1.3.0-dev";
} }
} }

@ -1,5 +1,5 @@
{ {
"version": "1.2.0-dev", "version": "1.3.0-dev",
"title": "gRPC C# Core", "title": "gRPC C# Core",
"authors": [ "Google Inc." ], "authors": [ "Google Inc." ],
"copyright": "Copyright 2015, Google Inc.", "copyright": "Copyright 2015, Google Inc.",

@ -1,5 +1,5 @@
{ {
"version": "1.2.0-dev", "version": "1.3.0-dev",
"title": "gRPC C# Healthchecking", "title": "gRPC C# Healthchecking",
"authors": [ "Google Inc." ], "authors": [ "Google Inc." ],
"copyright": "Copyright 2015, Google Inc.", "copyright": "Copyright 2015, Google Inc.",
@ -21,7 +21,7 @@
} }
}, },
"dependencies": { "dependencies": {
"Grpc.Core": "1.2.0-dev", "Grpc.Core": "1.3.0-dev",
"Google.Protobuf": "3.2.0" "Google.Protobuf": "3.2.0"
}, },
"frameworks": { "frameworks": {

@ -1,5 +1,5 @@
{ {
"version": "1.2.0-dev", "version": "1.3.0-dev",
"title": "gRPC C# Reflection", "title": "gRPC C# Reflection",
"authors": [ "Google Inc." ], "authors": [ "Google Inc." ],
"copyright": "Copyright 2016, Google Inc.", "copyright": "Copyright 2016, Google Inc.",
@ -21,7 +21,7 @@
} }
}, },
"dependencies": { "dependencies": {
"Grpc.Core": "1.2.0-dev", "Grpc.Core": "1.3.0-dev",
"Google.Protobuf": "3.2.0" "Google.Protobuf": "3.2.0"
}, },
"frameworks": { "frameworks": {

@ -28,7 +28,7 @@
@rem OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. @rem OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
@rem Current package versions @rem Current package versions
set VERSION=1.2.0-dev set VERSION=1.3.0-dev
set PROTOBUF_VERSION=3.0.0 set PROTOBUF_VERSION=3.0.0
@rem Adjust the location of nuget.exe @rem Adjust the location of nuget.exe

@ -66,7 +66,7 @@ dotnet pack --configuration Release Grpc.Auth/project.json --output ../../artifa
dotnet pack --configuration Release Grpc.HealthCheck/project.json --output ../../artifacts dotnet pack --configuration Release Grpc.HealthCheck/project.json --output ../../artifacts
dotnet pack --configuration Release Grpc.Reflection/project.json --output ../../artifacts dotnet pack --configuration Release Grpc.Reflection/project.json --output ../../artifacts
nuget pack Grpc.nuspec -Version "1.2.0-dev" -OutputDirectory ../../artifacts nuget pack Grpc.nuspec -Version "1.3.0-dev" -OutputDirectory ../../artifacts
nuget pack Grpc.Tools.nuspec -Version "1.2.0-dev" -OutputDirectory ../../artifacts nuget pack Grpc.Tools.nuspec -Version "1.3.0-dev" -OutputDirectory ../../artifacts
(cd ../../artifacts && zip csharp_nugets_dotnetcli.zip *.nupkg) (cd ../../artifacts && zip csharp_nugets_dotnetcli.zip *.nupkg)

@ -0,0 +1,5 @@
{
"sdk": {
"version": "1.0.0-preview2-003121"
}
}

@ -1,6 +1,6 @@
{ {
"name": "grpc-health-check", "name": "grpc-health-check",
"version": "1.2.0-dev", "version": "1.3.0-dev",
"author": "Google Inc.", "author": "Google Inc.",
"description": "Health check service for use with gRPC", "description": "Health check service for use with gRPC",
"repository": { "repository": {
@ -15,7 +15,7 @@
} }
], ],
"dependencies": { "dependencies": {
"grpc": "^1.2.0-dev", "grpc": "^1.3.0-dev",
"lodash": "^3.9.3", "lodash": "^3.9.3",
"google-protobuf": "^3.0.0" "google-protobuf": "^3.0.0"
}, },

@ -728,7 +728,7 @@ var defaultHandler = {
* method implementation for the provided service. * method implementation for the provided service.
*/ */
Server.prototype.addService = function(service, implementation) { Server.prototype.addService = function(service, implementation) {
if (!_.isObjectLike(service) || !_.isObjectLike(implementation)) { if (!_.isObject(service) || !_.isObject(implementation)) {
throw new Error('addService requires two objects as arguments'); throw new Error('addService requires two objects as arguments');
} }
if (_.keys(service).length === 0) { if (_.keys(service).length === 0) {

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

Loading…
Cancel
Save