Reland resource quota work (#28017)

* Check if memory owner available prior to polling it

The transport may drop the memory owner during its destruction sequence

* tcp_fix

* Revert "Revert "New resource quota integration (#27643)" (#28014)"

This reverts commit 0ea2c37263.

* clang-format

* fix-path

* fix
pull/28030/head
Craig Tiller 3 years ago committed by GitHub
parent 901e72edc0
commit a629c9a03e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 34
      BUILD
  2. 193
      CMakeLists.txt
  3. 18
      Makefile
  4. 214
      build_autogenerated.yaml
  5. 10
      config.m4
  6. 10
      config.w32
  7. 40
      gRPC-C++.podspec
  8. 51
      gRPC-Core.podspec
  9. 29
      grpc.gemspec
  10. 18
      grpc.gyp
  11. 32
      include/grpc/event_engine/internal/memory_allocator_impl.h
  12. 38
      include/grpc/event_engine/memory_allocator.h
  13. 57
      include/grpc/event_engine/memory_request.h
  14. 29
      package.xml
  15. 5
      src/core/ext/filters/client_channel/resolver/google_c2p/google_c2p_resolver.cc
  16. 9
      src/core/ext/transport/binder/client/channel_create_impl.cc
  17. 4
      src/core/ext/transport/binder/server/binder_server.cc
  18. 24
      src/core/ext/transport/chttp2/client/chttp2_connector.cc
  19. 2
      src/core/ext/transport/chttp2/client/chttp2_connector.h
  20. 7
      src/core/ext/transport/chttp2/client/insecure/channel_create.cc
  21. 22
      src/core/ext/transport/chttp2/client/insecure/channel_create_posix.cc
  22. 8
      src/core/ext/transport/chttp2/client/secure/secure_channel_create.cc
  23. 85
      src/core/ext/transport/chttp2/server/chttp2_server.cc
  24. 20
      src/core/ext/transport/chttp2/server/insecure/server_chttp2_posix.cc
  25. 92
      src/core/ext/transport/chttp2/transport/chttp2_transport.cc
  26. 3
      src/core/ext/transport/chttp2/transport/chttp2_transport.h
  27. 8
      src/core/ext/transport/chttp2/transport/flow_control.cc
  28. 10
      src/core/ext/transport/chttp2/transport/internal.h
  29. 5
      src/core/ext/transport/cronet/client/secure/cronet_channel_create.cc
  30. 8
      src/core/ext/transport/inproc/inproc_transport.cc
  31. 2
      src/core/lib/channel/channel_stack_builder.cc
  32. 6
      src/core/lib/gpr/tls.h
  33. 45
      src/core/lib/gprpp/cpp_impl_of.h
  34. 45
      src/core/lib/http/httpcli.cc
  35. 26
      src/core/lib/http/httpcli.h
  36. 1
      src/core/lib/iomgr/endpoint.h
  37. 27
      src/core/lib/iomgr/endpoint_cfstream.cc
  38. 6
      src/core/lib/iomgr/endpoint_cfstream.h
  39. 18
      src/core/lib/iomgr/endpoint_pair_posix.cc
  40. 19
      src/core/lib/iomgr/endpoint_pair_windows.cc
  41. 1106
      src/core/lib/iomgr/resource_quota.cc
  42. 226
      src/core/lib/iomgr/resource_quota.h
  43. 6
      src/core/lib/iomgr/tcp_client.cc
  44. 4
      src/core/lib/iomgr/tcp_client.h
  45. 10
      src/core/lib/iomgr/tcp_client_cfstream.cc
  46. 11
      src/core/lib/iomgr/tcp_client_custom.cc
  47. 29
      src/core/lib/iomgr/tcp_client_posix.cc
  48. 5
      src/core/lib/iomgr/tcp_client_posix.h
  49. 11
      src/core/lib/iomgr/tcp_client_windows.cc
  50. 45
      src/core/lib/iomgr/tcp_custom.cc
  51. 1
      src/core/lib/iomgr/tcp_custom.h
  52. 61
      src/core/lib/iomgr/tcp_posix.cc
  53. 4
      src/core/lib/iomgr/tcp_posix.h
  54. 8
      src/core/lib/iomgr/tcp_server.cc
  55. 10
      src/core/lib/iomgr/tcp_server.h
  56. 18
      src/core/lib/iomgr/tcp_server_custom.cc
  57. 36
      src/core/lib/iomgr/tcp_server_posix.cc
  58. 37
      src/core/lib/iomgr/tcp_server_utils_posix.h
  59. 15
      src/core/lib/iomgr/tcp_server_windows.cc
  60. 7
      src/core/lib/iomgr/tcp_windows.cc
  61. 3
      src/core/lib/iomgr/tcp_windows.h
  62. 3
      src/core/lib/promise/activity.cc
  63. 102
      src/core/lib/resource_quota/api.cc
  64. 52
      src/core/lib/resource_quota/api.h
  65. 69
      src/core/lib/resource_quota/memory_quota.cc
  66. 102
      src/core/lib/resource_quota/memory_quota.h
  67. 10
      src/core/lib/resource_quota/resource_quota.cc
  68. 22
      src/core/lib/resource_quota/resource_quota.h
  69. 2
      src/core/lib/resource_quota/thread_quota.h
  70. 19
      src/core/lib/resource_quota/trace.cc
  71. 16
      src/core/lib/resource_quota/trace.h
  72. 23
      src/core/lib/security/credentials/external/aws_external_account_credentials.cc
  73. 19
      src/core/lib/security/credentials/external/external_account_credentials.cc
  74. 7
      src/core/lib/security/credentials/external/url_external_account_credentials.cc
  75. 6
      src/core/lib/security/credentials/google_default/google_default_credentials.cc
  76. 10
      src/core/lib/security/credentials/jwt/jwt_verifier.cc
  77. 24
      src/core/lib/security/credentials/oauth2/oauth2_credentials.cc
  78. 33
      src/core/lib/surface/channel.cc
  79. 12
      src/core/lib/surface/channel.h
  80. 1
      src/core/lib/surface/init.cc
  81. 9
      src/core/lib/surface/lame_client.cc
  82. 15
      src/core/lib/surface/server.cc
  83. 5
      src/core/lib/surface/server.h
  84. 20
      src/cpp/server/health/default_health_check_service.cc
  85. 18
      src/cpp/thread_manager/thread_manager.cc
  86. 5
      src/cpp/thread_manager/thread_manager.h
  87. 8
      src/python/grpcio/grpc_core_dependencies.py
  88. 8
      test/core/bad_client/bad_client.cc
  89. 9
      test/core/bad_connection/close_fd_test.cc
  90. 29
      test/core/end2end/fixtures/h2_sockpair+trace.cc
  91. 29
      test/core/end2end/fixtures/h2_sockpair.cc
  92. 27
      test/core/end2end/fixtures/h2_sockpair_1byte.cc
  93. 17
      test/core/end2end/fixtures/http_proxy_fixture.cc
  94. 23
      test/core/end2end/fuzzers/api_fuzzer.cc
  95. 21
      test/core/end2end/fuzzers/client_fuzzer.cc
  96. 13
      test/core/end2end/fuzzers/server_fuzzer.cc
  97. 19
      test/core/end2end/generate_tests.bzl
  98. 5
      test/core/end2end/tests/binary_metadata.cc
  99. 12
      test/core/gprpp/BUILD
  100. 33
      test/core/gprpp/cpp_impl_of_test.cc
  101. Some files were not shown because too many files have changed in this diff Show More

34
BUILD

@ -191,6 +191,7 @@ GRPC_PUBLIC_EVENT_ENGINE_HDRS = [
"include/grpc/event_engine/event_engine.h",
"include/grpc/event_engine/port.h",
"include/grpc/event_engine/memory_allocator.h",
"include/grpc/event_engine/memory_request.h",
"include/grpc/event_engine/internal/memory_allocator_impl.h",
]
@ -901,6 +902,12 @@ grpc_cc_library(
public_hdrs = ["src/core/lib/gprpp/construct_destruct.h"],
)
grpc_cc_library(
name = "cpp_impl_of",
hdrs = ["src/core/lib/gprpp/cpp_impl_of.h"],
language = "c++",
)
grpc_cc_library(
name = "gpr_codegen",
language = "c++",
@ -1434,6 +1441,7 @@ grpc_cc_library(
hdrs = [
"include/grpc/event_engine/internal/memory_allocator_impl.h",
"include/grpc/event_engine/memory_allocator.h",
"include/grpc/event_engine/memory_request.h",
],
language = "c++",
deps = [
@ -1459,10 +1467,12 @@ grpc_cc_library(
"exec_ctx_wakeup_scheduler",
"gpr_base",
"loop",
"map",
"orphanable",
"poll",
"race",
"ref_counted_ptr",
"resource_quota_trace",
"seq",
"slice_refcount",
"useful",
@ -1483,6 +1493,20 @@ grpc_cc_library(
],
)
grpc_cc_library(
name = "resource_quota_trace",
srcs = [
"src/core/lib/resource_quota/trace.cc",
],
hdrs = [
"src/core/lib/resource_quota/trace.h",
],
deps = [
"gpr_platform",
"grpc_trace",
],
)
grpc_cc_library(
name = "resource_quota",
srcs = [
@ -1492,6 +1516,7 @@ grpc_cc_library(
"src/core/lib/resource_quota/resource_quota.h",
],
deps = [
"cpp_impl_of",
"gpr_base",
"memory_quota",
"ref_counted",
@ -1711,7 +1736,6 @@ grpc_cc_library(
"src/core/lib/iomgr/resolve_address_custom.cc",
"src/core/lib/iomgr/resolve_address_posix.cc",
"src/core/lib/iomgr/resolve_address_windows.cc",
"src/core/lib/iomgr/resource_quota.cc",
"src/core/lib/iomgr/socket_factory_posix.cc",
"src/core/lib/iomgr/socket_mutator.cc",
"src/core/lib/iomgr/socket_utils_common_posix.cc",
@ -1747,6 +1771,7 @@ grpc_cc_library(
"src/core/lib/iomgr/wakeup_fd_pipe.cc",
"src/core/lib/iomgr/wakeup_fd_posix.cc",
"src/core/lib/iomgr/work_serializer.cc",
"src/core/lib/resource_quota/api.cc",
"src/core/lib/slice/b64.cc",
"src/core/lib/slice/percent_encoding.cc",
"src/core/lib/slice/slice_api.cc",
@ -1817,6 +1842,7 @@ grpc_cc_library(
"src/core/lib/compression/algorithm_metadata.h",
"src/core/lib/compression/compression_args.h",
"src/core/lib/compression/compression_internal.h",
"src/core/lib/resource_quota/api.h",
"src/core/lib/compression/message_compress.h",
"src/core/lib/compression/stream_compression.h",
"src/core/lib/compression/stream_compression_gzip.h",
@ -1865,7 +1891,6 @@ grpc_cc_library(
"src/core/lib/iomgr/python_util.h",
"src/core/lib/iomgr/resolve_address.h",
"src/core/lib/iomgr/resolve_address_custom.h",
"src/core/lib/iomgr/resource_quota.h",
"src/core/lib/iomgr/sockaddr.h",
"src/core/lib/iomgr/sockaddr_posix.h",
"src/core/lib/iomgr/sockaddr_windows.h",
@ -1980,9 +2005,11 @@ grpc_cc_library(
"grpc_codegen",
"grpc_trace",
"json",
"memory_quota",
"orphanable",
"ref_counted",
"ref_counted_ptr",
"resource_quota",
"slice",
"slice_refcount",
"table",
@ -3571,7 +3598,9 @@ grpc_cc_library(
"hpack_encoder_index",
"hpack_encoder_table",
"match",
"memory_quota",
"popularity_count",
"resource_quota_trace",
"slice",
"slice_refcount",
"useful",
@ -3666,6 +3695,7 @@ grpc_cc_library(
"grpc_codegen",
"grpc_http_filters",
"grpc_transport_chttp2",
"memory_quota",
"ref_counted",
"ref_counted_ptr",
"slice",

193
CMakeLists.txt generated

@ -709,7 +709,6 @@ if(gRPC_BUILD_TESTS)
add_dependencies(buildtests_c tcp_server_posix_test)
endif()
add_dependencies(buildtests_c test_core_gpr_time_test)
add_dependencies(buildtests_c test_core_iomgr_resource_quota_test)
add_dependencies(buildtests_c test_core_security_credentials_test)
add_dependencies(buildtests_c test_core_slice_slice_test)
add_dependencies(buildtests_c thd_test)
@ -788,6 +787,7 @@ if(gRPC_BUILD_TESTS)
add_dependencies(buildtests_cxx context_list_test)
add_dependencies(buildtests_cxx context_test)
add_dependencies(buildtests_cxx core_configuration_test)
add_dependencies(buildtests_cxx cpp_impl_of_test)
add_dependencies(buildtests_cxx delegating_channel_test)
add_dependencies(buildtests_cxx destroy_grpclb_channel_with_active_connect_stress_test)
add_dependencies(buildtests_cxx dual_ref_counted_test)
@ -893,6 +893,7 @@ if(gRPC_BUILD_TESTS)
if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX)
add_dependencies(buildtests_cxx remove_stream_from_stalled_lists_test)
endif()
add_dependencies(buildtests_cxx resource_quota_test)
add_dependencies(buildtests_cxx retry_throttle_test)
add_dependencies(buildtests_cxx rls_end2end_test)
add_dependencies(buildtests_cxx rls_lb_config_parser_test)
@ -938,7 +939,6 @@ if(gRPC_BUILD_TESTS)
endif()
add_dependencies(buildtests_cxx string_ref_test)
add_dependencies(buildtests_cxx table_test)
add_dependencies(buildtests_cxx test_core_resource_quota_resource_quota_test)
add_dependencies(buildtests_cxx test_cpp_client_credentials_test)
add_dependencies(buildtests_cxx test_cpp_server_credentials_test)
add_dependencies(buildtests_cxx test_cpp_util_slice_test)
@ -1832,6 +1832,7 @@ add_library(grpc
src/core/lib/event_engine/channel_args_endpoint_config.cc
src/core/lib/event_engine/event_engine.cc
src/core/lib/event_engine/event_engine_factory.cc
src/core/lib/event_engine/memory_allocator.cc
src/core/lib/event_engine/sockaddr.cc
src/core/lib/http/format_request.cc
src/core/lib/http/httpcli.cc
@ -1896,7 +1897,6 @@ add_library(grpc
src/core/lib/iomgr/resolve_address_custom.cc
src/core/lib/iomgr/resolve_address_posix.cc
src/core/lib/iomgr/resolve_address_windows.cc
src/core/lib/iomgr/resource_quota.cc
src/core/lib/iomgr/socket_factory_posix.cc
src/core/lib/iomgr/socket_mutator.cc
src/core/lib/iomgr/socket_utils_common_posix.cc
@ -1936,6 +1936,12 @@ add_library(grpc
src/core/lib/json/json_util.cc
src/core/lib/json/json_writer.cc
src/core/lib/matchers/matchers.cc
src/core/lib/promise/activity.cc
src/core/lib/resource_quota/api.cc
src/core/lib/resource_quota/memory_quota.cc
src/core/lib/resource_quota/resource_quota.cc
src/core/lib/resource_quota/thread_quota.cc
src/core/lib/resource_quota/trace.cc
src/core/lib/security/authorization/authorization_policy_provider_vtable.cc
src/core/lib/security/authorization/evaluate_args.cc
src/core/lib/security/authorization/sdk_server_authz_filter.cc
@ -2128,6 +2134,7 @@ foreach(_hdr
include/grpc/event_engine/event_engine.h
include/grpc/event_engine/internal/memory_allocator_impl.h
include/grpc/event_engine/memory_allocator.h
include/grpc/event_engine/memory_request.h
include/grpc/event_engine/port.h
include/grpc/fork.h
include/grpc/grpc.h
@ -2214,7 +2221,6 @@ add_library(grpc_test_util
test/core/util/port_server_client.cc
test/core/util/reconnect_server.cc
test/core/util/resolve_localhost_ip46.cc
test/core/util/resource_user_util.cc
test/core/util/slice_splitter.cc
test/core/util/stack_tracer.cc
test/core/util/subprocess_posix.cc
@ -2283,7 +2289,6 @@ add_library(grpc_test_util_unsecure
test/core/util/port_server_client.cc
test/core/util/reconnect_server.cc
test/core/util/resolve_localhost_ip46.cc
test/core/util/resource_user_util.cc
test/core/util/slice_splitter.cc
test/core/util/stack_tracer.cc
test/core/util/subprocess_posix.cc
@ -2470,6 +2475,7 @@ add_library(grpc_unsecure
src/core/lib/event_engine/channel_args_endpoint_config.cc
src/core/lib/event_engine/event_engine.cc
src/core/lib/event_engine/event_engine_factory.cc
src/core/lib/event_engine/memory_allocator.cc
src/core/lib/event_engine/sockaddr.cc
src/core/lib/http/format_request.cc
src/core/lib/http/httpcli.cc
@ -2533,7 +2539,6 @@ add_library(grpc_unsecure
src/core/lib/iomgr/resolve_address_custom.cc
src/core/lib/iomgr/resolve_address_posix.cc
src/core/lib/iomgr/resolve_address_windows.cc
src/core/lib/iomgr/resource_quota.cc
src/core/lib/iomgr/socket_factory_posix.cc
src/core/lib/iomgr/socket_mutator.cc
src/core/lib/iomgr/socket_utils_common_posix.cc
@ -2572,6 +2577,12 @@ add_library(grpc_unsecure
src/core/lib/json/json_reader.cc
src/core/lib/json/json_util.cc
src/core/lib/json/json_writer.cc
src/core/lib/promise/activity.cc
src/core/lib/resource_quota/api.cc
src/core/lib/resource_quota/memory_quota.cc
src/core/lib/resource_quota/resource_quota.cc
src/core/lib/resource_quota/thread_quota.cc
src/core/lib/resource_quota/trace.cc
src/core/lib/security/authorization/authorization_policy_provider_null_vtable.cc
src/core/lib/slice/b64.cc
src/core/lib/slice/percent_encoding.cc
@ -2680,6 +2691,7 @@ foreach(_hdr
include/grpc/event_engine/event_engine.h
include/grpc/event_engine/internal/memory_allocator_impl.h
include/grpc/event_engine/memory_allocator.h
include/grpc/event_engine/memory_request.h
include/grpc/event_engine/port.h
include/grpc/fork.h
include/grpc/grpc.h
@ -5993,6 +6005,7 @@ if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_POSIX)
src/core/lib/iomgr/iomgr_internal.cc
src/core/lib/promise/activity.cc
src/core/lib/resource_quota/memory_quota.cc
src/core/lib/resource_quota/trace.cc
src/core/lib/slice/slice.cc
src/core/lib/slice/slice_refcount.cc
src/core/lib/slice/slice_string_helpers.cc
@ -7224,33 +7237,6 @@ target_link_libraries(test_core_gpr_time_test
)
endif()
if(gRPC_BUILD_TESTS)
add_executable(test_core_iomgr_resource_quota_test
test/core/iomgr/resource_quota_test.cc
)
target_include_directories(test_core_iomgr_resource_quota_test
PRIVATE
${CMAKE_CURRENT_SOURCE_DIR}
${CMAKE_CURRENT_SOURCE_DIR}/include
${_gRPC_ADDRESS_SORTING_INCLUDE_DIR}
${_gRPC_RE2_INCLUDE_DIR}
${_gRPC_SSL_INCLUDE_DIR}
${_gRPC_UPB_GENERATED_DIR}
${_gRPC_UPB_GRPC_GENERATED_DIR}
${_gRPC_UPB_INCLUDE_DIR}
${_gRPC_XXHASH_INCLUDE_DIR}
${_gRPC_ZLIB_INCLUDE_DIR}
)
target_link_libraries(test_core_iomgr_resource_quota_test
${_gRPC_ALLTARGETS_LIBRARIES}
grpc_test_util
)
endif()
if(gRPC_BUILD_TESTS)
@ -9861,6 +9847,40 @@ target_link_libraries(core_configuration_test
)
endif()
if(gRPC_BUILD_TESTS)
add_executable(cpp_impl_of_test
test/core/gprpp/cpp_impl_of_test.cc
third_party/googletest/googletest/src/gtest-all.cc
third_party/googletest/googlemock/src/gmock-all.cc
)
target_include_directories(cpp_impl_of_test
PRIVATE
${CMAKE_CURRENT_SOURCE_DIR}
${CMAKE_CURRENT_SOURCE_DIR}/include
${_gRPC_ADDRESS_SORTING_INCLUDE_DIR}
${_gRPC_RE2_INCLUDE_DIR}
${_gRPC_SSL_INCLUDE_DIR}
${_gRPC_UPB_GENERATED_DIR}
${_gRPC_UPB_GRPC_GENERATED_DIR}
${_gRPC_UPB_INCLUDE_DIR}
${_gRPC_XXHASH_INCLUDE_DIR}
${_gRPC_ZLIB_INCLUDE_DIR}
third_party/googletest/googletest/include
third_party/googletest/googletest
third_party/googletest/googlemock/include
third_party/googletest/googlemock
${_gRPC_PROTO_GENS_DIR}
)
target_link_libraries(cpp_impl_of_test
${_gRPC_PROTOBUF_LIBRARIES}
${_gRPC_ALLTARGETS_LIBRARIES}
)
endif()
if(gRPC_BUILD_TESTS)
@ -12912,6 +12932,7 @@ add_executable(memory_quota_test
src/core/lib/iomgr/iomgr_internal.cc
src/core/lib/promise/activity.cc
src/core/lib/resource_quota/memory_quota.cc
src/core/lib/resource_quota/trace.cc
src/core/lib/slice/slice.cc
src/core/lib/slice/slice_refcount.cc
src/core/lib/slice/slice_string_helpers.cc
@ -14308,6 +14329,59 @@ endif()
endif()
if(gRPC_BUILD_TESTS)
add_executable(resource_quota_test
src/core/lib/debug/trace.cc
src/core/lib/event_engine/memory_allocator.cc
src/core/lib/iomgr/combiner.cc
src/core/lib/iomgr/error.cc
src/core/lib/iomgr/exec_ctx.cc
src/core/lib/iomgr/executor.cc
src/core/lib/iomgr/iomgr_internal.cc
src/core/lib/promise/activity.cc
src/core/lib/resource_quota/memory_quota.cc
src/core/lib/resource_quota/resource_quota.cc
src/core/lib/resource_quota/thread_quota.cc
src/core/lib/resource_quota/trace.cc
src/core/lib/slice/slice.cc
src/core/lib/slice/slice_refcount.cc
src/core/lib/slice/slice_string_helpers.cc
src/core/lib/slice/static_slice.cc
test/core/resource_quota/resource_quota_test.cc
third_party/googletest/googletest/src/gtest-all.cc
third_party/googletest/googlemock/src/gmock-all.cc
)
target_include_directories(resource_quota_test
PRIVATE
${CMAKE_CURRENT_SOURCE_DIR}
${CMAKE_CURRENT_SOURCE_DIR}/include
${_gRPC_ADDRESS_SORTING_INCLUDE_DIR}
${_gRPC_RE2_INCLUDE_DIR}
${_gRPC_SSL_INCLUDE_DIR}
${_gRPC_UPB_GENERATED_DIR}
${_gRPC_UPB_GRPC_GENERATED_DIR}
${_gRPC_UPB_INCLUDE_DIR}
${_gRPC_XXHASH_INCLUDE_DIR}
${_gRPC_ZLIB_INCLUDE_DIR}
third_party/googletest/googletest/include
third_party/googletest/googletest
third_party/googletest/googlemock/include
third_party/googletest/googlemock
${_gRPC_PROTO_GENS_DIR}
)
target_link_libraries(resource_quota_test
${_gRPC_PROTOBUF_LIBRARIES}
${_gRPC_ALLTARGETS_LIBRARIES}
absl::statusor
absl::variant
gpr
)
endif()
if(gRPC_BUILD_TESTS)
add_executable(retry_throttle_test
test/core/client_channel/retry_throttle_test.cc
third_party/googletest/googletest/src/gtest-all.cc
@ -15654,58 +15728,6 @@ target_link_libraries(table_test
)
endif()
if(gRPC_BUILD_TESTS)
add_executable(test_core_resource_quota_resource_quota_test
src/core/lib/debug/trace.cc
src/core/lib/event_engine/memory_allocator.cc
src/core/lib/iomgr/combiner.cc
src/core/lib/iomgr/error.cc
src/core/lib/iomgr/exec_ctx.cc
src/core/lib/iomgr/executor.cc
src/core/lib/iomgr/iomgr_internal.cc
src/core/lib/promise/activity.cc
src/core/lib/resource_quota/memory_quota.cc
src/core/lib/resource_quota/resource_quota.cc
src/core/lib/resource_quota/thread_quota.cc
src/core/lib/slice/slice.cc
src/core/lib/slice/slice_refcount.cc
src/core/lib/slice/slice_string_helpers.cc
src/core/lib/slice/static_slice.cc
test/core/resource_quota/resource_quota_test.cc
third_party/googletest/googletest/src/gtest-all.cc
third_party/googletest/googlemock/src/gmock-all.cc
)
target_include_directories(test_core_resource_quota_resource_quota_test
PRIVATE
${CMAKE_CURRENT_SOURCE_DIR}
${CMAKE_CURRENT_SOURCE_DIR}/include
${_gRPC_ADDRESS_SORTING_INCLUDE_DIR}
${_gRPC_RE2_INCLUDE_DIR}
${_gRPC_SSL_INCLUDE_DIR}
${_gRPC_UPB_GENERATED_DIR}
${_gRPC_UPB_GRPC_GENERATED_DIR}
${_gRPC_UPB_INCLUDE_DIR}
${_gRPC_XXHASH_INCLUDE_DIR}
${_gRPC_ZLIB_INCLUDE_DIR}
third_party/googletest/googletest/include
third_party/googletest/googletest
third_party/googletest/googlemock/include
third_party/googletest/googlemock
${_gRPC_PROTO_GENS_DIR}
)
target_link_libraries(test_core_resource_quota_resource_quota_test
${_gRPC_PROTOBUF_LIBRARIES}
${_gRPC_ALLTARGETS_LIBRARIES}
absl::statusor
absl::variant
gpr
)
endif()
if(gRPC_BUILD_TESTS)
@ -16785,7 +16807,6 @@ if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX)
test/core/util/port_server_client.cc
test/core/util/reconnect_server.cc
test/core/util/resolve_localhost_ip46.cc
test/core/util/resource_user_util.cc
test/core/util/slice_splitter.cc
test/core/util/stack_tracer.cc
test/core/util/subprocess_posix.cc

18
Makefile generated

@ -1382,6 +1382,7 @@ LIBGRPC_SRC = \
src/core/lib/event_engine/channel_args_endpoint_config.cc \
src/core/lib/event_engine/event_engine.cc \
src/core/lib/event_engine/event_engine_factory.cc \
src/core/lib/event_engine/memory_allocator.cc \
src/core/lib/event_engine/sockaddr.cc \
src/core/lib/http/format_request.cc \
src/core/lib/http/httpcli.cc \
@ -1446,7 +1447,6 @@ LIBGRPC_SRC = \
src/core/lib/iomgr/resolve_address_custom.cc \
src/core/lib/iomgr/resolve_address_posix.cc \
src/core/lib/iomgr/resolve_address_windows.cc \
src/core/lib/iomgr/resource_quota.cc \
src/core/lib/iomgr/socket_factory_posix.cc \
src/core/lib/iomgr/socket_mutator.cc \
src/core/lib/iomgr/socket_utils_common_posix.cc \
@ -1486,6 +1486,12 @@ LIBGRPC_SRC = \
src/core/lib/json/json_util.cc \
src/core/lib/json/json_writer.cc \
src/core/lib/matchers/matchers.cc \
src/core/lib/promise/activity.cc \
src/core/lib/resource_quota/api.cc \
src/core/lib/resource_quota/memory_quota.cc \
src/core/lib/resource_quota/resource_quota.cc \
src/core/lib/resource_quota/thread_quota.cc \
src/core/lib/resource_quota/trace.cc \
src/core/lib/security/authorization/authorization_policy_provider_vtable.cc \
src/core/lib/security/authorization/evaluate_args.cc \
src/core/lib/security/authorization/sdk_server_authz_filter.cc \
@ -1625,6 +1631,7 @@ PUBLIC_HEADERS_C += \
include/grpc/event_engine/event_engine.h \
include/grpc/event_engine/internal/memory_allocator_impl.h \
include/grpc/event_engine/memory_allocator.h \
include/grpc/event_engine/memory_request.h \
include/grpc/event_engine/port.h \
include/grpc/fork.h \
include/grpc/grpc.h \
@ -1868,6 +1875,7 @@ LIBGRPC_UNSECURE_SRC = \
src/core/lib/event_engine/channel_args_endpoint_config.cc \
src/core/lib/event_engine/event_engine.cc \
src/core/lib/event_engine/event_engine_factory.cc \
src/core/lib/event_engine/memory_allocator.cc \
src/core/lib/event_engine/sockaddr.cc \
src/core/lib/http/format_request.cc \
src/core/lib/http/httpcli.cc \
@ -1931,7 +1939,6 @@ LIBGRPC_UNSECURE_SRC = \
src/core/lib/iomgr/resolve_address_custom.cc \
src/core/lib/iomgr/resolve_address_posix.cc \
src/core/lib/iomgr/resolve_address_windows.cc \
src/core/lib/iomgr/resource_quota.cc \
src/core/lib/iomgr/socket_factory_posix.cc \
src/core/lib/iomgr/socket_mutator.cc \
src/core/lib/iomgr/socket_utils_common_posix.cc \
@ -1970,6 +1977,12 @@ LIBGRPC_UNSECURE_SRC = \
src/core/lib/json/json_reader.cc \
src/core/lib/json/json_util.cc \
src/core/lib/json/json_writer.cc \
src/core/lib/promise/activity.cc \
src/core/lib/resource_quota/api.cc \
src/core/lib/resource_quota/memory_quota.cc \
src/core/lib/resource_quota/resource_quota.cc \
src/core/lib/resource_quota/thread_quota.cc \
src/core/lib/resource_quota/trace.cc \
src/core/lib/security/authorization/authorization_policy_provider_null_vtable.cc \
src/core/lib/slice/b64.cc \
src/core/lib/slice/percent_encoding.cc \
@ -2027,6 +2040,7 @@ PUBLIC_HEADERS_C += \
include/grpc/event_engine/event_engine.h \
include/grpc/event_engine/internal/memory_allocator_impl.h \
include/grpc/event_engine/memory_allocator.h \
include/grpc/event_engine/memory_request.h \
include/grpc/event_engine/port.h \
include/grpc/fork.h \
include/grpc/grpc.h \

@ -421,6 +421,7 @@ libs:
- include/grpc/event_engine/event_engine.h
- include/grpc/event_engine/internal/memory_allocator_impl.h
- include/grpc/event_engine/memory_allocator.h
- include/grpc/event_engine/memory_request.h
- include/grpc/event_engine/port.h
- include/grpc/fork.h
- include/grpc/grpc.h
@ -756,6 +757,7 @@ libs:
- src/core/lib/gprpp/atomic_utils.h
- src/core/lib/gprpp/bitset.h
- src/core/lib/gprpp/chunked_vector.h
- src/core/lib/gprpp/cpp_impl_of.h
- src/core/lib/gprpp/dual_ref_counted.h
- src/core/lib/gprpp/match.h
- src/core/lib/gprpp/orphanable.h
@ -815,7 +817,6 @@ libs:
- src/core/lib/iomgr/python_util.h
- src/core/lib/iomgr/resolve_address.h
- src/core/lib/iomgr/resolve_address_custom.h
- src/core/lib/iomgr/resource_quota.h
- src/core/lib/iomgr/sockaddr.h
- src/core/lib/iomgr/sockaddr_posix.h
- src/core/lib/iomgr/sockaddr_windows.h
@ -845,6 +846,24 @@ libs:
- src/core/lib/json/json.h
- src/core/lib/json/json_util.h
- src/core/lib/matchers/matchers.h
- src/core/lib/promise/activity.h
- src/core/lib/promise/context.h
- src/core/lib/promise/detail/basic_seq.h
- src/core/lib/promise/detail/promise_factory.h
- src/core/lib/promise/detail/promise_like.h
- src/core/lib/promise/detail/status.h
- src/core/lib/promise/detail/switch.h
- src/core/lib/promise/exec_ctx_wakeup_scheduler.h
- src/core/lib/promise/loop.h
- src/core/lib/promise/map.h
- src/core/lib/promise/poll.h
- src/core/lib/promise/race.h
- src/core/lib/promise/seq.h
- src/core/lib/resource_quota/api.h
- src/core/lib/resource_quota/memory_quota.h
- src/core/lib/resource_quota/resource_quota.h
- src/core/lib/resource_quota/thread_quota.h
- src/core/lib/resource_quota/trace.h
- src/core/lib/security/authorization/authorization_engine.h
- src/core/lib/security/authorization/authorization_policy_provider.h
- src/core/lib/security/authorization/evaluate_args.h
@ -1298,6 +1317,7 @@ libs:
- src/core/lib/event_engine/channel_args_endpoint_config.cc
- src/core/lib/event_engine/event_engine.cc
- src/core/lib/event_engine/event_engine_factory.cc
- src/core/lib/event_engine/memory_allocator.cc
- src/core/lib/event_engine/sockaddr.cc
- src/core/lib/http/format_request.cc
- src/core/lib/http/httpcli.cc
@ -1362,7 +1382,6 @@ libs:
- src/core/lib/iomgr/resolve_address_custom.cc
- src/core/lib/iomgr/resolve_address_posix.cc
- src/core/lib/iomgr/resolve_address_windows.cc
- src/core/lib/iomgr/resource_quota.cc
- src/core/lib/iomgr/socket_factory_posix.cc
- src/core/lib/iomgr/socket_mutator.cc
- src/core/lib/iomgr/socket_utils_common_posix.cc
@ -1402,6 +1421,12 @@ libs:
- src/core/lib/json/json_util.cc
- src/core/lib/json/json_writer.cc
- src/core/lib/matchers/matchers.cc
- src/core/lib/promise/activity.cc
- src/core/lib/resource_quota/api.cc
- src/core/lib/resource_quota/memory_quota.cc
- src/core/lib/resource_quota/resource_quota.cc
- src/core/lib/resource_quota/thread_quota.cc
- src/core/lib/resource_quota/trace.cc
- src/core/lib/security/authorization/authorization_policy_provider_vtable.cc
- src/core/lib/security/authorization/evaluate_args.cc
- src/core/lib/security/authorization/sdk_server_authz_filter.cc
@ -1572,7 +1597,6 @@ libs:
- test/core/util/port_server_client.h
- test/core/util/reconnect_server.h
- test/core/util/resolve_localhost_ip46.h
- test/core/util/resource_user_util.h
- test/core/util/slice_splitter.h
- test/core/util/stack_tracer.h
- test/core/util/subprocess.h
@ -1594,7 +1618,6 @@ libs:
- test/core/util/port_server_client.cc
- test/core/util/reconnect_server.cc
- test/core/util/resolve_localhost_ip46.cc
- test/core/util/resource_user_util.cc
- test/core/util/slice_splitter.cc
- test/core/util/stack_tracer.cc
- test/core/util/subprocess_posix.cc
@ -1627,7 +1650,6 @@ libs:
- test/core/util/port_server_client.h
- test/core/util/reconnect_server.h
- test/core/util/resolve_localhost_ip46.h
- test/core/util/resource_user_util.h
- test/core/util/slice_splitter.h
- test/core/util/stack_tracer.h
- test/core/util/subprocess.h
@ -1648,7 +1670,6 @@ libs:
- test/core/util/port_server_client.cc
- test/core/util/reconnect_server.cc
- test/core/util/resolve_localhost_ip46.cc
- test/core/util/resource_user_util.cc
- test/core/util/slice_splitter.cc
- test/core/util/stack_tracer.cc
- test/core/util/subprocess_posix.cc
@ -1673,6 +1694,7 @@ libs:
- include/grpc/event_engine/event_engine.h
- include/grpc/event_engine/internal/memory_allocator_impl.h
- include/grpc/event_engine/memory_allocator.h
- include/grpc/event_engine/memory_request.h
- include/grpc/event_engine/port.h
- include/grpc/fork.h
- include/grpc/grpc.h
@ -1808,6 +1830,7 @@ libs:
- src/core/lib/gprpp/atomic_utils.h
- src/core/lib/gprpp/bitset.h
- src/core/lib/gprpp/chunked_vector.h
- src/core/lib/gprpp/cpp_impl_of.h
- src/core/lib/gprpp/dual_ref_counted.h
- src/core/lib/gprpp/match.h
- src/core/lib/gprpp/orphanable.h
@ -1867,7 +1890,6 @@ libs:
- src/core/lib/iomgr/python_util.h
- src/core/lib/iomgr/resolve_address.h
- src/core/lib/iomgr/resolve_address_custom.h
- src/core/lib/iomgr/resource_quota.h
- src/core/lib/iomgr/sockaddr.h
- src/core/lib/iomgr/sockaddr_posix.h
- src/core/lib/iomgr/sockaddr_windows.h
@ -1896,6 +1918,24 @@ libs:
- src/core/lib/iomgr/work_serializer.h
- src/core/lib/json/json.h
- src/core/lib/json/json_util.h
- src/core/lib/promise/activity.h
- src/core/lib/promise/context.h
- src/core/lib/promise/detail/basic_seq.h
- src/core/lib/promise/detail/promise_factory.h
- src/core/lib/promise/detail/promise_like.h
- src/core/lib/promise/detail/status.h
- src/core/lib/promise/detail/switch.h
- src/core/lib/promise/exec_ctx_wakeup_scheduler.h
- src/core/lib/promise/loop.h
- src/core/lib/promise/map.h
- src/core/lib/promise/poll.h
- src/core/lib/promise/race.h
- src/core/lib/promise/seq.h
- src/core/lib/resource_quota/api.h
- src/core/lib/resource_quota/memory_quota.h
- src/core/lib/resource_quota/resource_quota.h
- src/core/lib/resource_quota/thread_quota.h
- src/core/lib/resource_quota/trace.h
- src/core/lib/slice/b64.h
- src/core/lib/slice/percent_encoding.h
- src/core/lib/slice/slice_internal.h
@ -2070,6 +2110,7 @@ libs:
- src/core/lib/event_engine/channel_args_endpoint_config.cc
- src/core/lib/event_engine/event_engine.cc
- src/core/lib/event_engine/event_engine_factory.cc
- src/core/lib/event_engine/memory_allocator.cc
- src/core/lib/event_engine/sockaddr.cc
- src/core/lib/http/format_request.cc
- src/core/lib/http/httpcli.cc
@ -2133,7 +2174,6 @@ libs:
- src/core/lib/iomgr/resolve_address_custom.cc
- src/core/lib/iomgr/resolve_address_posix.cc
- src/core/lib/iomgr/resolve_address_windows.cc
- src/core/lib/iomgr/resource_quota.cc
- src/core/lib/iomgr/socket_factory_posix.cc
- src/core/lib/iomgr/socket_mutator.cc
- src/core/lib/iomgr/socket_utils_common_posix.cc
@ -2172,6 +2212,12 @@ libs:
- src/core/lib/json/json_reader.cc
- src/core/lib/json/json_util.cc
- src/core/lib/json/json_writer.cc
- src/core/lib/promise/activity.cc
- src/core/lib/resource_quota/api.cc
- src/core/lib/resource_quota/memory_quota.cc
- src/core/lib/resource_quota/resource_quota.cc
- src/core/lib/resource_quota/thread_quota.cc
- src/core/lib/resource_quota/trace.cc
- src/core/lib/security/authorization/authorization_policy_provider_null_vtable.cc
- src/core/lib/slice/b64.cc
- src/core/lib/slice/percent_encoding.cc
@ -3680,10 +3726,12 @@ targets:
- src/core/lib/promise/detail/switch.h
- src/core/lib/promise/exec_ctx_wakeup_scheduler.h
- src/core/lib/promise/loop.h
- src/core/lib/promise/map.h
- src/core/lib/promise/poll.h
- src/core/lib/promise/race.h
- src/core/lib/promise/seq.h
- src/core/lib/resource_quota/memory_quota.h
- src/core/lib/resource_quota/trace.h
- src/core/lib/slice/slice_internal.h
- src/core/lib/slice/slice_refcount.h
- src/core/lib/slice/slice_refcount_base.h
@ -3700,6 +3748,7 @@ targets:
- src/core/lib/iomgr/iomgr_internal.cc
- src/core/lib/promise/activity.cc
- src/core/lib/resource_quota/memory_quota.cc
- src/core/lib/resource_quota/trace.cc
- src/core/lib/slice/slice.cc
- src/core/lib/slice/slice_refcount.cc
- src/core/lib/slice/slice_string_helpers.cc
@ -4166,14 +4215,6 @@ targets:
deps:
- grpc_test_util
uses_polling: false
- name: test_core_iomgr_resource_quota_test
build: test
language: c
headers: []
src:
- test/core/iomgr/resource_quota_test.cc
deps:
- grpc_test_util
- name: test_core_security_credentials_test
build: test
language: c
@ -5396,6 +5437,16 @@ targets:
- absl/types:optional
- upb
uses_polling: false
- name: cpp_impl_of_test
gtest: true
build: test
language: c++
headers:
- src/core/lib/gprpp/cpp_impl_of.h
src:
- test/core/gprpp/cpp_impl_of_test.cc
deps: []
uses_polling: false
- name: delegating_channel_test
gtest: true
build: test
@ -6750,10 +6801,12 @@ targets:
- src/core/lib/promise/detail/switch.h
- src/core/lib/promise/exec_ctx_wakeup_scheduler.h
- src/core/lib/promise/loop.h
- src/core/lib/promise/map.h
- src/core/lib/promise/poll.h
- src/core/lib/promise/race.h
- src/core/lib/promise/seq.h
- src/core/lib/resource_quota/memory_quota.h
- src/core/lib/resource_quota/trace.h
- src/core/lib/slice/slice_internal.h
- src/core/lib/slice/slice_refcount.h
- src/core/lib/slice/slice_refcount_base.h
@ -6771,6 +6824,7 @@ targets:
- src/core/lib/iomgr/iomgr_internal.cc
- src/core/lib/promise/activity.cc
- src/core/lib/resource_quota/memory_quota.cc
- src/core/lib/resource_quota/trace.cc
- src/core/lib/slice/slice.cc
- src/core/lib/slice/slice_refcount.cc
- src/core/lib/slice/slice_string_helpers.cc
@ -7440,6 +7494,71 @@ targets:
- linux
- posix
- mac
- name: resource_quota_test
gtest: true
build: test
language: c++
headers:
- src/core/lib/debug/trace.h
- src/core/lib/gprpp/atomic_utils.h
- src/core/lib/gprpp/cpp_impl_of.h
- src/core/lib/gprpp/dual_ref_counted.h
- src/core/lib/gprpp/orphanable.h
- src/core/lib/gprpp/ref_counted.h
- src/core/lib/gprpp/ref_counted_ptr.h
- src/core/lib/iomgr/closure.h
- src/core/lib/iomgr/combiner.h
- src/core/lib/iomgr/error.h
- src/core/lib/iomgr/error_internal.h
- src/core/lib/iomgr/exec_ctx.h
- src/core/lib/iomgr/executor.h
- src/core/lib/iomgr/iomgr_internal.h
- src/core/lib/promise/activity.h
- src/core/lib/promise/context.h
- src/core/lib/promise/detail/basic_seq.h
- src/core/lib/promise/detail/promise_factory.h
- src/core/lib/promise/detail/promise_like.h
- src/core/lib/promise/detail/status.h
- src/core/lib/promise/detail/switch.h
- src/core/lib/promise/exec_ctx_wakeup_scheduler.h
- src/core/lib/promise/loop.h
- src/core/lib/promise/map.h
- src/core/lib/promise/poll.h
- src/core/lib/promise/race.h
- src/core/lib/promise/seq.h
- src/core/lib/resource_quota/memory_quota.h
- src/core/lib/resource_quota/resource_quota.h
- src/core/lib/resource_quota/thread_quota.h
- src/core/lib/resource_quota/trace.h
- src/core/lib/slice/slice_internal.h
- src/core/lib/slice/slice_refcount.h
- src/core/lib/slice/slice_refcount_base.h
- src/core/lib/slice/slice_string_helpers.h
- src/core/lib/slice/slice_utils.h
- src/core/lib/slice/static_slice.h
src:
- src/core/lib/debug/trace.cc
- src/core/lib/event_engine/memory_allocator.cc
- src/core/lib/iomgr/combiner.cc
- src/core/lib/iomgr/error.cc
- src/core/lib/iomgr/exec_ctx.cc
- src/core/lib/iomgr/executor.cc
- src/core/lib/iomgr/iomgr_internal.cc
- src/core/lib/promise/activity.cc
- src/core/lib/resource_quota/memory_quota.cc
- src/core/lib/resource_quota/resource_quota.cc
- src/core/lib/resource_quota/thread_quota.cc
- src/core/lib/resource_quota/trace.cc
- src/core/lib/slice/slice.cc
- src/core/lib/slice/slice_refcount.cc
- src/core/lib/slice/slice_string_helpers.cc
- src/core/lib/slice/static_slice.cc
- test/core/resource_quota/resource_quota_test.cc
deps:
- absl/status:statusor
- absl/types:variant
- gpr
uses_polling: false
- name: retry_throttle_test
gtest: true
build: test
@ -7867,67 +7986,6 @@ targets:
- absl/types:optional
- absl/utility:utility
uses_polling: false
- name: test_core_resource_quota_resource_quota_test
gtest: true
build: test
language: c++
headers:
- src/core/lib/debug/trace.h
- src/core/lib/gprpp/atomic_utils.h
- src/core/lib/gprpp/dual_ref_counted.h
- src/core/lib/gprpp/orphanable.h
- src/core/lib/gprpp/ref_counted.h
- src/core/lib/gprpp/ref_counted_ptr.h
- src/core/lib/iomgr/closure.h
- src/core/lib/iomgr/combiner.h
- src/core/lib/iomgr/error.h
- src/core/lib/iomgr/error_internal.h
- src/core/lib/iomgr/exec_ctx.h
- src/core/lib/iomgr/executor.h
- src/core/lib/iomgr/iomgr_internal.h
- src/core/lib/promise/activity.h
- src/core/lib/promise/context.h
- src/core/lib/promise/detail/basic_seq.h
- src/core/lib/promise/detail/promise_factory.h
- src/core/lib/promise/detail/promise_like.h
- src/core/lib/promise/detail/status.h
- src/core/lib/promise/detail/switch.h
- src/core/lib/promise/exec_ctx_wakeup_scheduler.h
- src/core/lib/promise/loop.h
- src/core/lib/promise/poll.h
- src/core/lib/promise/race.h
- src/core/lib/promise/seq.h
- src/core/lib/resource_quota/memory_quota.h
- src/core/lib/resource_quota/resource_quota.h
- src/core/lib/resource_quota/thread_quota.h
- src/core/lib/slice/slice_internal.h
- src/core/lib/slice/slice_refcount.h
- src/core/lib/slice/slice_refcount_base.h
- src/core/lib/slice/slice_string_helpers.h
- src/core/lib/slice/slice_utils.h
- src/core/lib/slice/static_slice.h
src:
- src/core/lib/debug/trace.cc
- src/core/lib/event_engine/memory_allocator.cc
- src/core/lib/iomgr/combiner.cc
- src/core/lib/iomgr/error.cc
- src/core/lib/iomgr/exec_ctx.cc
- src/core/lib/iomgr/executor.cc
- src/core/lib/iomgr/iomgr_internal.cc
- src/core/lib/promise/activity.cc
- src/core/lib/resource_quota/memory_quota.cc
- src/core/lib/resource_quota/resource_quota.cc
- src/core/lib/resource_quota/thread_quota.cc
- src/core/lib/slice/slice.cc
- src/core/lib/slice/slice_refcount.cc
- src/core/lib/slice/slice_string_helpers.cc
- src/core/lib/slice/static_slice.cc
- test/core/resource_quota/resource_quota_test.cc
deps:
- absl/status:statusor
- absl/types:variant
- gpr
uses_polling: false
- name: test_cpp_client_credentials_test
gtest: true
build: test
@ -8492,7 +8550,6 @@ targets:
- test/core/util/port_server_client.h
- test/core/util/reconnect_server.h
- test/core/util/resolve_localhost_ip46.h
- test/core/util/resource_user_util.h
- test/core/util/slice_splitter.h
- test/core/util/stack_tracer.h
- test/core/util/subprocess.h
@ -8516,7 +8573,6 @@ targets:
- test/core/util/port_server_client.cc
- test/core/util/reconnect_server.cc
- test/core/util/resolve_localhost_ip46.cc
- test/core/util/resource_user_util.cc
- test/core/util/slice_splitter.cc
- test/core/util/stack_tracer.cc
- test/core/util/subprocess_posix.cc

10
config.m4 generated

@ -390,6 +390,7 @@ if test "$PHP_GRPC" != "no"; then
src/core/lib/event_engine/channel_args_endpoint_config.cc \
src/core/lib/event_engine/event_engine.cc \
src/core/lib/event_engine/event_engine_factory.cc \
src/core/lib/event_engine/memory_allocator.cc \
src/core/lib/event_engine/sockaddr.cc \
src/core/lib/gpr/alloc.cc \
src/core/lib/gpr/atm.cc \
@ -497,7 +498,6 @@ if test "$PHP_GRPC" != "no"; then
src/core/lib/iomgr/resolve_address_custom.cc \
src/core/lib/iomgr/resolve_address_posix.cc \
src/core/lib/iomgr/resolve_address_windows.cc \
src/core/lib/iomgr/resource_quota.cc \
src/core/lib/iomgr/socket_factory_posix.cc \
src/core/lib/iomgr/socket_mutator.cc \
src/core/lib/iomgr/socket_utils_common_posix.cc \
@ -539,6 +539,12 @@ if test "$PHP_GRPC" != "no"; then
src/core/lib/matchers/matchers.cc \
src/core/lib/profiling/basic_timers.cc \
src/core/lib/profiling/stap_timers.cc \
src/core/lib/promise/activity.cc \
src/core/lib/resource_quota/api.cc \
src/core/lib/resource_quota/memory_quota.cc \
src/core/lib/resource_quota/resource_quota.cc \
src/core/lib/resource_quota/thread_quota.cc \
src/core/lib/resource_quota/trace.cc \
src/core/lib/security/authorization/authorization_policy_provider_vtable.cc \
src/core/lib/security/authorization/evaluate_args.cc \
src/core/lib/security/authorization/sdk_server_authz_filter.cc \
@ -1204,6 +1210,8 @@ if test "$PHP_GRPC" != "no"; then
PHP_ADD_BUILD_DIR($ext_builddir/src/core/lib/json)
PHP_ADD_BUILD_DIR($ext_builddir/src/core/lib/matchers)
PHP_ADD_BUILD_DIR($ext_builddir/src/core/lib/profiling)
PHP_ADD_BUILD_DIR($ext_builddir/src/core/lib/promise)
PHP_ADD_BUILD_DIR($ext_builddir/src/core/lib/resource_quota)
PHP_ADD_BUILD_DIR($ext_builddir/src/core/lib/security/authorization)
PHP_ADD_BUILD_DIR($ext_builddir/src/core/lib/security/context)
PHP_ADD_BUILD_DIR($ext_builddir/src/core/lib/security/credentials)

10
config.w32 generated

@ -356,6 +356,7 @@ if (PHP_GRPC != "no") {
"src\\core\\lib\\event_engine\\channel_args_endpoint_config.cc " +
"src\\core\\lib\\event_engine\\event_engine.cc " +
"src\\core\\lib\\event_engine\\event_engine_factory.cc " +
"src\\core\\lib\\event_engine\\memory_allocator.cc " +
"src\\core\\lib\\event_engine\\sockaddr.cc " +
"src\\core\\lib\\gpr\\alloc.cc " +
"src\\core\\lib\\gpr\\atm.cc " +
@ -463,7 +464,6 @@ if (PHP_GRPC != "no") {
"src\\core\\lib\\iomgr\\resolve_address_custom.cc " +
"src\\core\\lib\\iomgr\\resolve_address_posix.cc " +
"src\\core\\lib\\iomgr\\resolve_address_windows.cc " +
"src\\core\\lib\\iomgr\\resource_quota.cc " +
"src\\core\\lib\\iomgr\\socket_factory_posix.cc " +
"src\\core\\lib\\iomgr\\socket_mutator.cc " +
"src\\core\\lib\\iomgr\\socket_utils_common_posix.cc " +
@ -505,6 +505,12 @@ if (PHP_GRPC != "no") {
"src\\core\\lib\\matchers\\matchers.cc " +
"src\\core\\lib\\profiling\\basic_timers.cc " +
"src\\core\\lib\\profiling\\stap_timers.cc " +
"src\\core\\lib\\promise\\activity.cc " +
"src\\core\\lib\\resource_quota\\api.cc " +
"src\\core\\lib\\resource_quota\\memory_quota.cc " +
"src\\core\\lib\\resource_quota\\resource_quota.cc " +
"src\\core\\lib\\resource_quota\\thread_quota.cc " +
"src\\core\\lib\\resource_quota\\trace.cc " +
"src\\core\\lib\\security\\authorization\\authorization_policy_provider_vtable.cc " +
"src\\core\\lib\\security\\authorization\\evaluate_args.cc " +
"src\\core\\lib\\security\\authorization\\sdk_server_authz_filter.cc " +
@ -1308,6 +1314,8 @@ if (PHP_GRPC != "no") {
FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\lib\\json");
FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\lib\\matchers");
FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\lib\\profiling");
FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\lib\\promise");
FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\lib\\resource_quota");
FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\lib\\security");
FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\lib\\security\\authorization");
FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\lib\\security\\context");

40
gRPC-C++.podspec generated

@ -599,6 +599,7 @@ Pod::Spec.new do |s|
'src/core/lib/gprpp/bitset.h',
'src/core/lib/gprpp/chunked_vector.h',
'src/core/lib/gprpp/construct_destruct.h',
'src/core/lib/gprpp/cpp_impl_of.h',
'src/core/lib/gprpp/debug_location.h',
'src/core/lib/gprpp/dual_ref_counted.h',
'src/core/lib/gprpp/examine_stack.h',
@ -674,7 +675,6 @@ Pod::Spec.new do |s|
'src/core/lib/iomgr/python_util.h',
'src/core/lib/iomgr/resolve_address.h',
'src/core/lib/iomgr/resolve_address_custom.h',
'src/core/lib/iomgr/resource_quota.h',
'src/core/lib/iomgr/sockaddr.h',
'src/core/lib/iomgr/sockaddr_posix.h',
'src/core/lib/iomgr/sockaddr_windows.h',
@ -705,6 +705,24 @@ Pod::Spec.new do |s|
'src/core/lib/json/json_util.h',
'src/core/lib/matchers/matchers.h',
'src/core/lib/profiling/timers.h',
'src/core/lib/promise/activity.h',
'src/core/lib/promise/context.h',
'src/core/lib/promise/detail/basic_seq.h',
'src/core/lib/promise/detail/promise_factory.h',
'src/core/lib/promise/detail/promise_like.h',
'src/core/lib/promise/detail/status.h',
'src/core/lib/promise/detail/switch.h',
'src/core/lib/promise/exec_ctx_wakeup_scheduler.h',
'src/core/lib/promise/loop.h',
'src/core/lib/promise/map.h',
'src/core/lib/promise/poll.h',
'src/core/lib/promise/race.h',
'src/core/lib/promise/seq.h',
'src/core/lib/resource_quota/api.h',
'src/core/lib/resource_quota/memory_quota.h',
'src/core/lib/resource_quota/resource_quota.h',
'src/core/lib/resource_quota/thread_quota.h',
'src/core/lib/resource_quota/trace.h',
'src/core/lib/security/authorization/authorization_engine.h',
'src/core/lib/security/authorization/authorization_policy_provider.h',
'src/core/lib/security/authorization/evaluate_args.h',
@ -1292,6 +1310,7 @@ Pod::Spec.new do |s|
'src/core/lib/gprpp/bitset.h',
'src/core/lib/gprpp/chunked_vector.h',
'src/core/lib/gprpp/construct_destruct.h',
'src/core/lib/gprpp/cpp_impl_of.h',
'src/core/lib/gprpp/debug_location.h',
'src/core/lib/gprpp/dual_ref_counted.h',
'src/core/lib/gprpp/examine_stack.h',
@ -1367,7 +1386,6 @@ Pod::Spec.new do |s|
'src/core/lib/iomgr/python_util.h',
'src/core/lib/iomgr/resolve_address.h',
'src/core/lib/iomgr/resolve_address_custom.h',
'src/core/lib/iomgr/resource_quota.h',
'src/core/lib/iomgr/sockaddr.h',
'src/core/lib/iomgr/sockaddr_posix.h',
'src/core/lib/iomgr/sockaddr_windows.h',
@ -1398,6 +1416,24 @@ Pod::Spec.new do |s|
'src/core/lib/json/json_util.h',
'src/core/lib/matchers/matchers.h',
'src/core/lib/profiling/timers.h',
'src/core/lib/promise/activity.h',
'src/core/lib/promise/context.h',
'src/core/lib/promise/detail/basic_seq.h',
'src/core/lib/promise/detail/promise_factory.h',
'src/core/lib/promise/detail/promise_like.h',
'src/core/lib/promise/detail/status.h',
'src/core/lib/promise/detail/switch.h',
'src/core/lib/promise/exec_ctx_wakeup_scheduler.h',
'src/core/lib/promise/loop.h',
'src/core/lib/promise/map.h',
'src/core/lib/promise/poll.h',
'src/core/lib/promise/race.h',
'src/core/lib/promise/seq.h',
'src/core/lib/resource_quota/api.h',
'src/core/lib/resource_quota/memory_quota.h',
'src/core/lib/resource_quota/resource_quota.h',
'src/core/lib/resource_quota/thread_quota.h',
'src/core/lib/resource_quota/trace.h',
'src/core/lib/security/authorization/authorization_engine.h',
'src/core/lib/security/authorization/authorization_policy_provider.h',
'src/core/lib/security/authorization/evaluate_args.h',

51
gRPC-Core.podspec generated

@ -111,6 +111,7 @@ Pod::Spec.new do |s|
'include/grpc/event_engine/event_engine.h',
'include/grpc/event_engine/internal/memory_allocator_impl.h',
'include/grpc/event_engine/memory_allocator.h',
'include/grpc/event_engine/memory_request.h',
'include/grpc/event_engine/port.h',
'include/grpc/fork.h',
'include/grpc/grpc.h',
@ -871,6 +872,7 @@ Pod::Spec.new do |s|
'src/core/lib/event_engine/event_engine.cc',
'src/core/lib/event_engine/event_engine_factory.cc',
'src/core/lib/event_engine/event_engine_factory.h',
'src/core/lib/event_engine/memory_allocator.cc',
'src/core/lib/event_engine/sockaddr.cc',
'src/core/lib/event_engine/sockaddr.h',
'src/core/lib/gpr/alloc.cc',
@ -920,6 +922,7 @@ Pod::Spec.new do |s|
'src/core/lib/gprpp/bitset.h',
'src/core/lib/gprpp/chunked_vector.h',
'src/core/lib/gprpp/construct_destruct.h',
'src/core/lib/gprpp/cpp_impl_of.h',
'src/core/lib/gprpp/debug_location.h',
'src/core/lib/gprpp/dual_ref_counted.h',
'src/core/lib/gprpp/examine_stack.cc',
@ -1069,8 +1072,6 @@ Pod::Spec.new do |s|
'src/core/lib/iomgr/resolve_address_custom.h',
'src/core/lib/iomgr/resolve_address_posix.cc',
'src/core/lib/iomgr/resolve_address_windows.cc',
'src/core/lib/iomgr/resource_quota.cc',
'src/core/lib/iomgr/resource_quota.h',
'src/core/lib/iomgr/sockaddr.h',
'src/core/lib/iomgr/sockaddr_posix.h',
'src/core/lib/iomgr/sockaddr_windows.h',
@ -1142,6 +1143,30 @@ Pod::Spec.new do |s|
'src/core/lib/profiling/basic_timers.cc',
'src/core/lib/profiling/stap_timers.cc',
'src/core/lib/profiling/timers.h',
'src/core/lib/promise/activity.cc',
'src/core/lib/promise/activity.h',
'src/core/lib/promise/context.h',
'src/core/lib/promise/detail/basic_seq.h',
'src/core/lib/promise/detail/promise_factory.h',
'src/core/lib/promise/detail/promise_like.h',
'src/core/lib/promise/detail/status.h',
'src/core/lib/promise/detail/switch.h',
'src/core/lib/promise/exec_ctx_wakeup_scheduler.h',
'src/core/lib/promise/loop.h',
'src/core/lib/promise/map.h',
'src/core/lib/promise/poll.h',
'src/core/lib/promise/race.h',
'src/core/lib/promise/seq.h',
'src/core/lib/resource_quota/api.cc',
'src/core/lib/resource_quota/api.h',
'src/core/lib/resource_quota/memory_quota.cc',
'src/core/lib/resource_quota/memory_quota.h',
'src/core/lib/resource_quota/resource_quota.cc',
'src/core/lib/resource_quota/resource_quota.h',
'src/core/lib/resource_quota/thread_quota.cc',
'src/core/lib/resource_quota/thread_quota.h',
'src/core/lib/resource_quota/trace.cc',
'src/core/lib/resource_quota/trace.h',
'src/core/lib/security/authorization/authorization_engine.h',
'src/core/lib/security/authorization/authorization_policy_provider.h',
'src/core/lib/security/authorization/authorization_policy_provider_vtable.cc',
@ -1809,6 +1834,7 @@ Pod::Spec.new do |s|
'src/core/lib/gprpp/bitset.h',
'src/core/lib/gprpp/chunked_vector.h',
'src/core/lib/gprpp/construct_destruct.h',
'src/core/lib/gprpp/cpp_impl_of.h',
'src/core/lib/gprpp/debug_location.h',
'src/core/lib/gprpp/dual_ref_counted.h',
'src/core/lib/gprpp/examine_stack.h',
@ -1884,7 +1910,6 @@ Pod::Spec.new do |s|
'src/core/lib/iomgr/python_util.h',
'src/core/lib/iomgr/resolve_address.h',
'src/core/lib/iomgr/resolve_address_custom.h',
'src/core/lib/iomgr/resource_quota.h',
'src/core/lib/iomgr/sockaddr.h',
'src/core/lib/iomgr/sockaddr_posix.h',
'src/core/lib/iomgr/sockaddr_windows.h',
@ -1915,6 +1940,24 @@ Pod::Spec.new do |s|
'src/core/lib/json/json_util.h',
'src/core/lib/matchers/matchers.h',
'src/core/lib/profiling/timers.h',
'src/core/lib/promise/activity.h',
'src/core/lib/promise/context.h',
'src/core/lib/promise/detail/basic_seq.h',
'src/core/lib/promise/detail/promise_factory.h',
'src/core/lib/promise/detail/promise_like.h',
'src/core/lib/promise/detail/status.h',
'src/core/lib/promise/detail/switch.h',
'src/core/lib/promise/exec_ctx_wakeup_scheduler.h',
'src/core/lib/promise/loop.h',
'src/core/lib/promise/map.h',
'src/core/lib/promise/poll.h',
'src/core/lib/promise/race.h',
'src/core/lib/promise/seq.h',
'src/core/lib/resource_quota/api.h',
'src/core/lib/resource_quota/memory_quota.h',
'src/core/lib/resource_quota/resource_quota.h',
'src/core/lib/resource_quota/thread_quota.h',
'src/core/lib/resource_quota/trace.h',
'src/core/lib/security/authorization/authorization_engine.h',
'src/core/lib/security/authorization/authorization_policy_provider.h',
'src/core/lib/security/authorization/evaluate_args.h',
@ -2254,8 +2297,6 @@ Pod::Spec.new do |s|
'test/core/util/reconnect_server.h',
'test/core/util/resolve_localhost_ip46.cc',
'test/core/util/resolve_localhost_ip46.h',
'test/core/util/resource_user_util.cc',
'test/core/util/resource_user_util.h',
'test/core/util/slice_splitter.cc',
'test/core/util/slice_splitter.h',
'test/core/util/stack_tracer.cc',

29
grpc.gemspec generated

@ -57,6 +57,7 @@ Gem::Specification.new do |s|
s.files += %w( include/grpc/event_engine/event_engine.h )
s.files += %w( include/grpc/event_engine/internal/memory_allocator_impl.h )
s.files += %w( include/grpc/event_engine/memory_allocator.h )
s.files += %w( include/grpc/event_engine/memory_request.h )
s.files += %w( include/grpc/event_engine/port.h )
s.files += %w( include/grpc/fork.h )
s.files += %w( include/grpc/grpc.h )
@ -791,6 +792,7 @@ Gem::Specification.new do |s|
s.files += %w( src/core/lib/event_engine/event_engine.cc )
s.files += %w( src/core/lib/event_engine/event_engine_factory.cc )
s.files += %w( src/core/lib/event_engine/event_engine_factory.h )
s.files += %w( src/core/lib/event_engine/memory_allocator.cc )
s.files += %w( src/core/lib/event_engine/sockaddr.cc )
s.files += %w( src/core/lib/event_engine/sockaddr.h )
s.files += %w( src/core/lib/gpr/alloc.cc )
@ -840,6 +842,7 @@ Gem::Specification.new do |s|
s.files += %w( src/core/lib/gprpp/bitset.h )
s.files += %w( src/core/lib/gprpp/chunked_vector.h )
s.files += %w( src/core/lib/gprpp/construct_destruct.h )
s.files += %w( src/core/lib/gprpp/cpp_impl_of.h )
s.files += %w( src/core/lib/gprpp/debug_location.h )
s.files += %w( src/core/lib/gprpp/dual_ref_counted.h )
s.files += %w( src/core/lib/gprpp/examine_stack.cc )
@ -989,8 +992,6 @@ Gem::Specification.new do |s|
s.files += %w( src/core/lib/iomgr/resolve_address_custom.h )
s.files += %w( src/core/lib/iomgr/resolve_address_posix.cc )
s.files += %w( src/core/lib/iomgr/resolve_address_windows.cc )
s.files += %w( src/core/lib/iomgr/resource_quota.cc )
s.files += %w( src/core/lib/iomgr/resource_quota.h )
s.files += %w( src/core/lib/iomgr/sockaddr.h )
s.files += %w( src/core/lib/iomgr/sockaddr_posix.h )
s.files += %w( src/core/lib/iomgr/sockaddr_windows.h )
@ -1062,6 +1063,30 @@ Gem::Specification.new do |s|
s.files += %w( src/core/lib/profiling/basic_timers.cc )
s.files += %w( src/core/lib/profiling/stap_timers.cc )
s.files += %w( src/core/lib/profiling/timers.h )
s.files += %w( src/core/lib/promise/activity.cc )
s.files += %w( src/core/lib/promise/activity.h )
s.files += %w( src/core/lib/promise/context.h )
s.files += %w( src/core/lib/promise/detail/basic_seq.h )
s.files += %w( src/core/lib/promise/detail/promise_factory.h )
s.files += %w( src/core/lib/promise/detail/promise_like.h )
s.files += %w( src/core/lib/promise/detail/status.h )
s.files += %w( src/core/lib/promise/detail/switch.h )
s.files += %w( src/core/lib/promise/exec_ctx_wakeup_scheduler.h )
s.files += %w( src/core/lib/promise/loop.h )
s.files += %w( src/core/lib/promise/map.h )
s.files += %w( src/core/lib/promise/poll.h )
s.files += %w( src/core/lib/promise/race.h )
s.files += %w( src/core/lib/promise/seq.h )
s.files += %w( src/core/lib/resource_quota/api.cc )
s.files += %w( src/core/lib/resource_quota/api.h )
s.files += %w( src/core/lib/resource_quota/memory_quota.cc )
s.files += %w( src/core/lib/resource_quota/memory_quota.h )
s.files += %w( src/core/lib/resource_quota/resource_quota.cc )
s.files += %w( src/core/lib/resource_quota/resource_quota.h )
s.files += %w( src/core/lib/resource_quota/thread_quota.cc )
s.files += %w( src/core/lib/resource_quota/thread_quota.h )
s.files += %w( src/core/lib/resource_quota/trace.cc )
s.files += %w( src/core/lib/resource_quota/trace.h )
s.files += %w( src/core/lib/security/authorization/authorization_engine.h )
s.files += %w( src/core/lib/security/authorization/authorization_policy_provider.h )
s.files += %w( src/core/lib/security/authorization/authorization_policy_provider_vtable.cc )

18
grpc.gyp generated

@ -823,6 +823,7 @@
'src/core/lib/event_engine/channel_args_endpoint_config.cc',
'src/core/lib/event_engine/event_engine.cc',
'src/core/lib/event_engine/event_engine_factory.cc',
'src/core/lib/event_engine/memory_allocator.cc',
'src/core/lib/event_engine/sockaddr.cc',
'src/core/lib/http/format_request.cc',
'src/core/lib/http/httpcli.cc',
@ -887,7 +888,6 @@
'src/core/lib/iomgr/resolve_address_custom.cc',
'src/core/lib/iomgr/resolve_address_posix.cc',
'src/core/lib/iomgr/resolve_address_windows.cc',
'src/core/lib/iomgr/resource_quota.cc',
'src/core/lib/iomgr/socket_factory_posix.cc',
'src/core/lib/iomgr/socket_mutator.cc',
'src/core/lib/iomgr/socket_utils_common_posix.cc',
@ -927,6 +927,12 @@
'src/core/lib/json/json_util.cc',
'src/core/lib/json/json_writer.cc',
'src/core/lib/matchers/matchers.cc',
'src/core/lib/promise/activity.cc',
'src/core/lib/resource_quota/api.cc',
'src/core/lib/resource_quota/memory_quota.cc',
'src/core/lib/resource_quota/resource_quota.cc',
'src/core/lib/resource_quota/thread_quota.cc',
'src/core/lib/resource_quota/trace.cc',
'src/core/lib/security/authorization/authorization_policy_provider_vtable.cc',
'src/core/lib/security/authorization/evaluate_args.cc',
'src/core/lib/security/authorization/sdk_server_authz_filter.cc',
@ -1091,7 +1097,6 @@
'test/core/util/port_server_client.cc',
'test/core/util/reconnect_server.cc',
'test/core/util/resolve_localhost_ip46.cc',
'test/core/util/resource_user_util.cc',
'test/core/util/slice_splitter.cc',
'test/core/util/stack_tracer.cc',
'test/core/util/subprocess_posix.cc',
@ -1125,7 +1130,6 @@
'test/core/util/port_server_client.cc',
'test/core/util/reconnect_server.cc',
'test/core/util/resolve_localhost_ip46.cc',
'test/core/util/resource_user_util.cc',
'test/core/util/slice_splitter.cc',
'test/core/util/stack_tracer.cc',
'test/core/util/subprocess_posix.cc',
@ -1282,6 +1286,7 @@
'src/core/lib/event_engine/channel_args_endpoint_config.cc',
'src/core/lib/event_engine/event_engine.cc',
'src/core/lib/event_engine/event_engine_factory.cc',
'src/core/lib/event_engine/memory_allocator.cc',
'src/core/lib/event_engine/sockaddr.cc',
'src/core/lib/http/format_request.cc',
'src/core/lib/http/httpcli.cc',
@ -1345,7 +1350,6 @@
'src/core/lib/iomgr/resolve_address_custom.cc',
'src/core/lib/iomgr/resolve_address_posix.cc',
'src/core/lib/iomgr/resolve_address_windows.cc',
'src/core/lib/iomgr/resource_quota.cc',
'src/core/lib/iomgr/socket_factory_posix.cc',
'src/core/lib/iomgr/socket_mutator.cc',
'src/core/lib/iomgr/socket_utils_common_posix.cc',
@ -1384,6 +1388,12 @@
'src/core/lib/json/json_reader.cc',
'src/core/lib/json/json_util.cc',
'src/core/lib/json/json_writer.cc',
'src/core/lib/promise/activity.cc',
'src/core/lib/resource_quota/api.cc',
'src/core/lib/resource_quota/memory_quota.cc',
'src/core/lib/resource_quota/resource_quota.cc',
'src/core/lib/resource_quota/thread_quota.cc',
'src/core/lib/resource_quota/trace.cc',
'src/core/lib/security/authorization/authorization_policy_provider_null_vtable.cc',
'src/core/lib/slice/b64.cc',
'src/core/lib/slice/percent_encoding.cc',

@ -21,42 +21,12 @@
#include <type_traits>
#include <vector>
#include <grpc/event_engine/memory_request.h>
#include <grpc/slice.h>
// forward-declaring an internal struct, not used publicly.
struct grpc_slice_buffer;
namespace grpc_event_engine {
namespace experimental {
/// Reservation request - how much memory do we want to allocate?
class MemoryRequest {
public:
/// Request a fixed amount of memory.
// NOLINTNEXTLINE(google-explicit-constructor)
MemoryRequest(size_t n) : min_(n), max_(n) {}
/// Request a range of memory.
/// Requires: \a min <= \a max.
/// Requires: \a max <= max_size()
MemoryRequest(size_t min, size_t max) : min_(min), max_(max) {}
/// Maximum allowable request size - hard coded to 1GB.
static constexpr size_t max_allowed_size() { return 1024 * 1024 * 1024; }
/// Increase the size by \a amount.
/// Undefined behavior if min() + amount or max() + amount overflows.
MemoryRequest Increase(size_t amount) const {
return MemoryRequest(min_ + amount, max_ + amount);
}
size_t min() const { return min_; }
size_t max() const { return max_; }
private:
size_t min_;
size_t max_;
};
namespace internal {
/// Underlying memory allocation interface.

@ -16,6 +16,8 @@
#include <grpc/impl/codegen/port_platform.h>
#include <stdlib.h> // for abort()
#include <algorithm>
#include <memory>
#include <type_traits>
@ -42,6 +44,9 @@ class SliceBuffer {
grpc_slice_buffer* slice_buffer_;
};
// Tracks memory allocated by one system.
// Is effectively a thin wrapper/smart pointer for a MemoryAllocatorImpl,
// providing a convenient and stable API.
class MemoryAllocator {
public:
/// Construct a MemoryAllocator given an internal::MemoryAllocatorImpl
@ -50,6 +55,8 @@ class MemoryAllocator {
explicit MemoryAllocator(
std::shared_ptr<internal::MemoryAllocatorImpl> allocator)
: allocator_(std::move(allocator)) {}
// Construct an invalid MemoryAllocator.
MemoryAllocator() : allocator_(nullptr) {}
~MemoryAllocator() {
if (allocator_ != nullptr) allocator_->Shutdown();
}
@ -60,6 +67,14 @@ class MemoryAllocator {
MemoryAllocator(MemoryAllocator&&) = default;
MemoryAllocator& operator=(MemoryAllocator&&) = default;
/// Drop the underlying allocator and make this an empty object.
/// The object will not be usable after this call unless it's a valid
/// allocator is moved into it.
void Reset() {
if (allocator_ != nullptr) allocator_->Shutdown();
allocator_.reset();
}
/// Reserve bytes from the quota.
/// If we enter overcommit, reclamation will begin concurrently.
/// Returns the number of bytes reserved.
@ -68,13 +83,6 @@ class MemoryAllocator {
/// Release some bytes that were previously reserved.
void Release(size_t n) { return allocator_->Release(n); }
/// Return a pointer to the underlying implementation.
/// Note that the interface of said implementatoin is unstable and likely to
/// change at any time.
internal::MemoryAllocatorImpl* get_internal_impl_ptr() {
return allocator_.get();
}
//
// The remainder of this type are helper functions implemented in terms of
// Reserve/Release.
@ -175,8 +183,15 @@ class MemoryAllocator {
};
protected:
const std::shared_ptr<internal::MemoryAllocatorImpl>& allocator() {
return allocator_;
/// Return a pointer to the underlying implementation.
/// Note that the interface of said implementation is unstable and likely to
/// change at any time.
internal::MemoryAllocatorImpl* get_internal_impl_ptr() {
return allocator_.get();
}
const internal::MemoryAllocatorImpl* get_internal_impl_ptr() const {
return allocator_.get();
}
private:
@ -198,10 +213,11 @@ class MemoryAllocatorFactory {
virtual ~MemoryAllocatorFactory() = default;
/// On Endpoint creation, call \a CreateMemoryAllocator to create a new
/// allocator for the endpoint.
/// \a name is used to label the memory allocator in debug logs.
/// Typically we'll want to:
/// auto allocator = factory->CreateMemoryAllocator();
/// auto allocator = factory->CreateMemoryAllocator(peer_address_string);
/// auto* endpoint = allocator->New<MyEndpoint>(std::move(allocator), ...);
virtual MemoryAllocator CreateMemoryAllocator() = 0;
virtual MemoryAllocator CreateMemoryAllocator(absl::string_view name) = 0;
};
} // namespace experimental

@ -0,0 +1,57 @@
// Copyright 2021 The gRPC Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef GRPC_EVENT_ENGINE_MEMORY_REQUEST_H
#define GRPC_EVENT_ENGINE_MEMORY_REQUEST_H
#include <grpc/support/port_platform.h>
#include <stddef.h>
#include "absl/strings/string_view.h"
namespace grpc_event_engine {
namespace experimental {
/// Reservation request - how much memory do we want to allocate?
class MemoryRequest {
public:
/// Request a fixed amount of memory.
// NOLINTNEXTLINE(google-explicit-constructor)
MemoryRequest(size_t n) : min_(n), max_(n) {}
/// Request a range of memory.
/// Requires: \a min <= \a max.
/// Requires: \a max <= max_size()
MemoryRequest(size_t min, size_t max) : min_(min), max_(max) {}
/// Maximum allowable request size - hard coded to 1GB.
static constexpr size_t max_allowed_size() { return 1024 * 1024 * 1024; }
/// Increase the size by \a amount.
/// Undefined behavior if min() + amount or max() + amount overflows.
MemoryRequest Increase(size_t amount) const {
return MemoryRequest(min_ + amount, max_ + amount);
}
size_t min() const { return min_; }
size_t max() const { return max_; }
private:
size_t min_;
size_t max_;
};
} // namespace experimental
} // namespace grpc_event_engine
#endif // GRPC_EVENT_ENGINE_MEMORY_REQUEST_H

29
package.xml generated

@ -37,6 +37,7 @@
<file baseinstalldir="/" name="include/grpc/event_engine/event_engine.h" role="src" />
<file baseinstalldir="/" name="include/grpc/event_engine/internal/memory_allocator_impl.h" role="src" />
<file baseinstalldir="/" name="include/grpc/event_engine/memory_allocator.h" role="src" />
<file baseinstalldir="/" name="include/grpc/event_engine/memory_request.h" role="src" />
<file baseinstalldir="/" name="include/grpc/event_engine/port.h" role="src" />
<file baseinstalldir="/" name="include/grpc/fork.h" role="src" />
<file baseinstalldir="/" name="include/grpc/grpc.h" role="src" />
@ -771,6 +772,7 @@
<file baseinstalldir="/" name="src/core/lib/event_engine/event_engine.cc" role="src" />
<file baseinstalldir="/" name="src/core/lib/event_engine/event_engine_factory.cc" role="src" />
<file baseinstalldir="/" name="src/core/lib/event_engine/event_engine_factory.h" role="src" />
<file baseinstalldir="/" name="src/core/lib/event_engine/memory_allocator.cc" role="src" />
<file baseinstalldir="/" name="src/core/lib/event_engine/sockaddr.cc" role="src" />
<file baseinstalldir="/" name="src/core/lib/event_engine/sockaddr.h" role="src" />
<file baseinstalldir="/" name="src/core/lib/gpr/alloc.cc" role="src" />
@ -820,6 +822,7 @@
<file baseinstalldir="/" name="src/core/lib/gprpp/bitset.h" role="src" />
<file baseinstalldir="/" name="src/core/lib/gprpp/chunked_vector.h" role="src" />
<file baseinstalldir="/" name="src/core/lib/gprpp/construct_destruct.h" role="src" />
<file baseinstalldir="/" name="src/core/lib/gprpp/cpp_impl_of.h" role="src" />
<file baseinstalldir="/" name="src/core/lib/gprpp/debug_location.h" role="src" />
<file baseinstalldir="/" name="src/core/lib/gprpp/dual_ref_counted.h" role="src" />
<file baseinstalldir="/" name="src/core/lib/gprpp/examine_stack.cc" role="src" />
@ -969,8 +972,6 @@
<file baseinstalldir="/" name="src/core/lib/iomgr/resolve_address_custom.h" role="src" />
<file baseinstalldir="/" name="src/core/lib/iomgr/resolve_address_posix.cc" role="src" />
<file baseinstalldir="/" name="src/core/lib/iomgr/resolve_address_windows.cc" role="src" />
<file baseinstalldir="/" name="src/core/lib/iomgr/resource_quota.cc" role="src" />
<file baseinstalldir="/" name="src/core/lib/iomgr/resource_quota.h" role="src" />
<file baseinstalldir="/" name="src/core/lib/iomgr/sockaddr.h" role="src" />
<file baseinstalldir="/" name="src/core/lib/iomgr/sockaddr_posix.h" role="src" />
<file baseinstalldir="/" name="src/core/lib/iomgr/sockaddr_windows.h" role="src" />
@ -1042,6 +1043,30 @@
<file baseinstalldir="/" name="src/core/lib/profiling/basic_timers.cc" role="src" />
<file baseinstalldir="/" name="src/core/lib/profiling/stap_timers.cc" role="src" />
<file baseinstalldir="/" name="src/core/lib/profiling/timers.h" role="src" />
<file baseinstalldir="/" name="src/core/lib/promise/activity.cc" role="src" />
<file baseinstalldir="/" name="src/core/lib/promise/activity.h" role="src" />
<file baseinstalldir="/" name="src/core/lib/promise/context.h" role="src" />
<file baseinstalldir="/" name="src/core/lib/promise/detail/basic_seq.h" role="src" />
<file baseinstalldir="/" name="src/core/lib/promise/detail/promise_factory.h" role="src" />
<file baseinstalldir="/" name="src/core/lib/promise/detail/promise_like.h" role="src" />
<file baseinstalldir="/" name="src/core/lib/promise/detail/status.h" role="src" />
<file baseinstalldir="/" name="src/core/lib/promise/detail/switch.h" role="src" />
<file baseinstalldir="/" name="src/core/lib/promise/exec_ctx_wakeup_scheduler.h" role="src" />
<file baseinstalldir="/" name="src/core/lib/promise/loop.h" role="src" />
<file baseinstalldir="/" name="src/core/lib/promise/map.h" role="src" />
<file baseinstalldir="/" name="src/core/lib/promise/poll.h" role="src" />
<file baseinstalldir="/" name="src/core/lib/promise/race.h" role="src" />
<file baseinstalldir="/" name="src/core/lib/promise/seq.h" role="src" />
<file baseinstalldir="/" name="src/core/lib/resource_quota/api.cc" role="src" />
<file baseinstalldir="/" name="src/core/lib/resource_quota/api.h" role="src" />
<file baseinstalldir="/" name="src/core/lib/resource_quota/memory_quota.cc" role="src" />
<file baseinstalldir="/" name="src/core/lib/resource_quota/memory_quota.h" role="src" />
<file baseinstalldir="/" name="src/core/lib/resource_quota/resource_quota.cc" role="src" />
<file baseinstalldir="/" name="src/core/lib/resource_quota/resource_quota.h" role="src" />
<file baseinstalldir="/" name="src/core/lib/resource_quota/thread_quota.cc" role="src" />
<file baseinstalldir="/" name="src/core/lib/resource_quota/thread_quota.h" role="src" />
<file baseinstalldir="/" name="src/core/lib/resource_quota/trace.cc" role="src" />
<file baseinstalldir="/" name="src/core/lib/resource_quota/trace.h" role="src" />
<file baseinstalldir="/" name="src/core/lib/security/authorization/authorization_engine.h" role="src" />
<file baseinstalldir="/" name="src/core/lib/security/authorization/authorization_policy_provider.h" role="src" />
<file baseinstalldir="/" name="src/core/lib/security/authorization/authorization_policy_provider_vtable.cc" role="src" />

@ -127,9 +127,8 @@ GoogleCloud2ProdResolver::MetadataQuery::MetadataQuery(
request.http.path = const_cast<char*>(path);
request.http.hdr_count = 1;
request.http.hdrs = &header;
grpc_resource_quota* resource_quota =
grpc_resource_quota_create("c2p_resolver");
grpc_httpcli_get(&context_, pollent, resource_quota, &request,
// TODO(ctiller): share the quota from whomever instantiates this!
grpc_httpcli_get(&context_, pollent, ResourceQuota::Default(), &request,
ExecCtx::Get()->Now() + 10000, // 10s timeout
&on_done_, &response_);
}

@ -56,9 +56,10 @@ grpc_channel* CreateDirectBinderChannelImplForTesting(
grpc_channel_args* final_args =
grpc_channel_args_copy_and_add(args, &default_authority_arg, 1);
grpc_error_handle error = GRPC_ERROR_NONE;
grpc_channel* channel = grpc_channel_create(
"binder_target_placeholder", final_args, GRPC_CLIENT_DIRECT_CHANNEL,
transport, nullptr, 0, &error);
grpc_channel* channel =
grpc_channel_create("binder_target_placeholder", final_args,
GRPC_CLIENT_DIRECT_CHANNEL, transport, &error);
// TODO(mingcl): Handle error properly
GPR_ASSERT(error == GRPC_ERROR_NONE);
grpc_channel_args_destroy(final_args);
return channel;
@ -80,7 +81,7 @@ grpc_channel* CreateClientBinderChannelImpl(const grpc_channel_args* args) {
grpc_channel* channel =
grpc_channel_create("binder_channel_target_placeholder", new_args,
GRPC_CLIENT_CHANNEL, nullptr, nullptr, 0, &error);
GRPC_CLIENT_CHANNEL, nullptr, &error);
// Clean up.
grpc_channel_args_destroy(new_args);

@ -214,8 +214,8 @@ class BinderServerListener : public Server::ListenerInterface {
std::move(client_binder), security_policy_);
GPR_ASSERT(server_transport);
grpc_channel_args* args = grpc_channel_args_copy(server_->channel_args());
grpc_error_handle error = server_->SetupTransport(server_transport, nullptr,
args, nullptr, nullptr);
grpc_error_handle error =
server_->SetupTransport(server_transport, nullptr, args, nullptr);
grpc_channel_args_destroy(args);
return grpc_error_to_absl_status(error);
}

@ -43,9 +43,6 @@ Chttp2Connector::Chttp2Connector() {
}
Chttp2Connector::~Chttp2Connector() {
if (resource_quota_ != nullptr) {
grpc_resource_quota_unref_internal(resource_quota_);
}
if (endpoint_ != nullptr) {
grpc_endpoint_destroy(endpoint_);
}
@ -64,11 +61,6 @@ void Chttp2Connector::Connect(const Args& args, Result* result,
connecting_ = true;
GPR_ASSERT(endpoint_ == nullptr);
ep = &endpoint_;
if (resource_quota_ != nullptr) {
grpc_resource_quota_unref_internal(resource_quota_);
}
resource_quota_ =
grpc_resource_quota_from_channel_args(args.channel_args, true);
}
// In some implementations, the closure can be flushed before
// grpc_tcp_client_connect() returns, and since the closure requires access
@ -77,12 +69,8 @@ void Chttp2Connector::Connect(const Args& args, Result* result,
// grpc_tcp_client_connect() will fill endpoint_ with proper contents, and we
// make sure that we still exist at that point by taking a ref.
Ref().release(); // Ref held by callback.
grpc_tcp_client_connect(
&connected_, ep,
grpc_slice_allocator_create(resource_quota_,
grpc_sockaddr_to_string(args.address, false),
args.channel_args),
args.interested_parties, args.channel_args, args.address, args.deadline);
grpc_tcp_client_connect(&connected_, ep, args.interested_parties,
args.channel_args, args.address, args.deadline);
}
void Chttp2Connector::Shutdown(grpc_error_handle error) {
@ -175,12 +163,8 @@ void Chttp2Connector::OnHandshakeDone(void* arg, grpc_error_handle error) {
self->result_->Reset();
NullThenSchedClosure(DEBUG_LOCATION, &self->notify_, error);
} else if (args->endpoint != nullptr) {
self->result_->transport = grpc_create_chttp2_transport(
args->args, args->endpoint, true,
grpc_resource_user_create(
self->resource_quota_,
absl::StrCat(grpc_endpoint_get_peer(args->endpoint),
":connector_transport")));
self->result_->transport =
grpc_create_chttp2_transport(args->args, args->endpoint, true);
self->result_->socket_node =
grpc_chttp2_transport_get_socket_node(self->result_->transport);
self->result_->channel_args = args->args;

@ -24,7 +24,6 @@
#include "src/core/ext/filters/client_channel/connector.h"
#include "src/core/lib/channel/handshaker.h"
#include "src/core/lib/channel/handshaker_registry.h"
#include "src/core/lib/iomgr/resource_quota.h"
namespace grpc_core {
@ -69,7 +68,6 @@ class Chttp2Connector : public SubchannelConnector {
grpc_closure on_timeout_;
absl::optional<grpc_error_handle> notify_error_;
RefCountedPtr<HandshakeManager> handshake_mgr_;
grpc_resource_quota* resource_quota_ = nullptr;
};
} // namespace grpc_core

@ -26,6 +26,7 @@
#include "src/core/ext/filters/client_channel/resolver_registry.h"
#include "src/core/ext/transport/chttp2/client/chttp2_connector.h"
#include "src/core/lib/channel/channel_args.h"
#include "src/core/lib/resource_quota/api.h"
#include "src/core/lib/surface/api_trace.h"
#include "src/core/lib/surface/channel.h"
@ -57,10 +58,12 @@ grpc_channel* CreateChannel(const char* target, const grpc_channel_args* args,
grpc_arg arg = grpc_channel_arg_string_create(
const_cast<char*>(GRPC_ARG_SERVER_URI), canonical_target.get());
const char* to_remove[] = {GRPC_ARG_SERVER_URI};
grpc_channel_args* new_args =
grpc_channel_args* new_args0 =
grpc_channel_args_copy_and_add_and_remove(args, to_remove, 1, &arg, 1);
grpc_channel_args* new_args = EnsureResourceQuotaInChannelArgs(new_args0);
grpc_channel_args_destroy(new_args0);
grpc_channel* channel = grpc_channel_create(
target, new_args, GRPC_CLIENT_CHANNEL, nullptr, nullptr, 0, error);
target, new_args, GRPC_CLIENT_CHANNEL, nullptr, error);
grpc_channel_args_destroy(new_args);
return channel;
}

@ -31,6 +31,7 @@
#include "src/core/lib/iomgr/endpoint.h"
#include "src/core/lib/iomgr/tcp_client_posix.h"
#include "src/core/lib/iomgr/tcp_posix.h"
#include "src/core/lib/resource_quota/api.h"
#include "src/core/lib/surface/api_trace.h"
#include "src/core/lib/surface/channel.h"
#include "src/core/lib/transport/transport.h"
@ -44,26 +45,21 @@ grpc_channel* grpc_insecure_channel_create_from_fd(
grpc_arg default_authority_arg = grpc_channel_arg_string_create(
const_cast<char*>(GRPC_ARG_DEFAULT_AUTHORITY),
const_cast<char*>("test.authority"));
args = grpc_channel_args_copy_and_add(args, &default_authority_arg, 1);
grpc_channel_args* final_args =
grpc_channel_args_copy_and_add(args, &default_authority_arg, 1);
grpc_core::EnsureResourceQuotaInChannelArgs(args);
grpc_channel_args_destroy(args);
int flags = fcntl(fd, F_GETFL, 0);
GPR_ASSERT(fcntl(fd, F_SETFL, flags | O_NONBLOCK) == 0);
grpc_resource_quota* resource_quota =
grpc_resource_quota_from_channel_args(args, true);
grpc_slice_allocator* allocator = grpc_slice_allocator_create(
resource_quota, "fd-client:endpoint", final_args);
grpc_endpoint* client = grpc_tcp_client_create_from_fd(
grpc_fd_create(fd, "client", true), args, "fd-client", allocator);
grpc_transport* transport = grpc_create_chttp2_transport(
final_args, client, true,
grpc_resource_user_create(resource_quota, "fd-client:transport"));
grpc_resource_quota_unref_internal(resource_quota);
grpc_fd_create(fd, "client", true), final_args, "fd-client");
grpc_transport* transport =
grpc_create_chttp2_transport(final_args, client, true);
GPR_ASSERT(transport);
grpc_error_handle error = GRPC_ERROR_NONE;
grpc_channel* channel =
grpc_channel_create(target, final_args, GRPC_CLIENT_DIRECT_CHANNEL,
transport, nullptr, 0, &error);
grpc_channel* channel = grpc_channel_create(
target, final_args, GRPC_CLIENT_DIRECT_CHANNEL, transport, &error);
grpc_channel_args_destroy(final_args);
if (channel != nullptr) {
grpc_chttp2_transport_start_reading(transport, nullptr, nullptr, nullptr);

@ -28,6 +28,7 @@
#include "src/core/lib/address_utils/sockaddr_utils.h"
#include "src/core/lib/channel/channel_args.h"
#include "src/core/lib/gprpp/memory.h"
#include "src/core/lib/resource_quota/api.h"
#include "src/core/lib/security/credentials/credentials.h"
#include "src/core/lib/security/security_connector/security_connector.h"
#include "src/core/lib/slice/slice_internal.h"
@ -120,7 +121,7 @@ grpc_channel* CreateChannel(const char* target, const grpc_channel_args* args,
grpc_channel_args* new_args =
grpc_channel_args_copy_and_add_and_remove(args, to_remove, 1, &arg, 1);
grpc_channel* channel = grpc_channel_create(
target, new_args, GRPC_CLIENT_CHANNEL, nullptr, nullptr, 0, error);
target, new_args, GRPC_CLIENT_CHANNEL, nullptr, error);
grpc_channel_args_destroy(new_args);
return channel;
}
@ -166,8 +167,11 @@ grpc_channel* grpc_secure_channel_create(grpc_channel_credentials* creds,
grpc_arg args_to_add[] = {channel_factory_arg,
grpc_channel_credentials_to_arg(creds)};
const char* arg_to_remove = channel_factory_arg.key;
grpc_channel_args* new_args = grpc_channel_args_copy_and_add_and_remove(
grpc_channel_args* updated_args = grpc_channel_args_copy_and_add_and_remove(
args, &arg_to_remove, 1, args_to_add, GPR_ARRAY_SIZE(args_to_add));
grpc_channel_args* new_args =
grpc_core::EnsureResourceQuotaInChannelArgs(updated_args);
grpc_channel_args_destroy(updated_args);
new_args = creds->update_arguments(new_args);
// Create channel.
channel = grpc_core::CreateChannel(target, new_args, &error);

@ -48,9 +48,10 @@
#include "src/core/lib/gprpp/ref_counted_ptr.h"
#include "src/core/lib/iomgr/endpoint.h"
#include "src/core/lib/iomgr/resolve_address.h"
#include "src/core/lib/iomgr/resource_quota.h"
#include "src/core/lib/iomgr/tcp_server.h"
#include "src/core/lib/iomgr/unix_sockets_posix.h"
#include "src/core/lib/resource_quota/api.h"
#include "src/core/lib/resource_quota/memory_quota.h"
#include "src/core/lib/slice/slice_internal.h"
#include "src/core/lib/surface/api_trace.h"
#include "src/core/lib/surface/server.h"
@ -75,8 +76,7 @@ class Chttp2ServerListener : public Server::ListenerInterface {
// Do not instantiate directly. Use one of the factory methods above.
Chttp2ServerListener(Server* server, grpc_channel_args* args,
Chttp2ServerArgsModifier args_modifier,
grpc_resource_quota* resource_quota);
Chttp2ServerArgsModifier args_modifier);
~Chttp2ServerListener() override;
void Start(Server* server,
@ -114,8 +114,7 @@ class Chttp2ServerListener : public Server::ListenerInterface {
HandshakingState(RefCountedPtr<ActiveConnection> connection_ref,
grpc_pollset* accepting_pollset,
grpc_tcp_server_acceptor* acceptor,
grpc_channel_args* args,
grpc_resource_user* channel_resource_user);
grpc_channel_args* args);
~HandshakingState() override;
@ -141,13 +140,11 @@ class Chttp2ServerListener : public Server::ListenerInterface {
grpc_closure on_timeout_ ABSL_GUARDED_BY(&connection_->mu_);
grpc_closure on_receive_settings_ ABSL_GUARDED_BY(&connection_->mu_);
grpc_pollset_set* const interested_parties_;
grpc_resource_user* channel_resource_user_;
};
ActiveConnection(grpc_pollset* accepting_pollset,
grpc_tcp_server_acceptor* acceptor,
grpc_channel_args* args,
grpc_resource_user* channel_resource_user);
grpc_channel_args* args, MemoryOwner memory_owner);
~ActiveConnection() override;
void Orphan() override;
@ -241,7 +238,7 @@ class Chttp2ServerListener : public Server::ListenerInterface {
grpc_closure tcp_server_shutdown_complete_ ABSL_GUARDED_BY(mu_);
grpc_closure* on_destroy_done_ ABSL_GUARDED_BY(mu_) = nullptr;
RefCountedPtr<channelz::ListenSocketNode> channelz_listen_socket_;
grpc_resource_quota* resource_quota_;
MemoryQuotaRefPtr memory_quota_;
};
//
@ -313,14 +310,13 @@ grpc_millis GetConnectionDeadline(const grpc_channel_args* args) {
Chttp2ServerListener::ActiveConnection::HandshakingState::HandshakingState(
RefCountedPtr<ActiveConnection> connection_ref,
grpc_pollset* accepting_pollset, grpc_tcp_server_acceptor* acceptor,
grpc_channel_args* args, grpc_resource_user* channel_resource_user)
grpc_channel_args* args)
: connection_(std::move(connection_ref)),
accepting_pollset_(accepting_pollset),
acceptor_(acceptor),
handshake_mgr_(MakeRefCounted<HandshakeManager>()),
deadline_(GetConnectionDeadline(args)),
interested_parties_(grpc_pollset_set_create()),
channel_resource_user_(channel_resource_user) {
interested_parties_(grpc_pollset_set_create()) {
grpc_pollset_set_add_pollset(interested_parties_, accepting_pollset_);
CoreConfiguration::Get().handshaker_registry().AddHandshakers(
HANDSHAKER_SERVER, args, interested_parties_, handshake_mgr_.get());
@ -329,9 +325,6 @@ Chttp2ServerListener::ActiveConnection::HandshakingState::HandshakingState(
Chttp2ServerListener::ActiveConnection::HandshakingState::~HandshakingState() {
grpc_pollset_set_del_pollset(interested_parties_, accepting_pollset_);
grpc_pollset_set_destroy(interested_parties_);
if (channel_resource_user_ != nullptr) {
grpc_resource_user_unref(channel_resource_user_);
}
gpr_free(acceptor_);
}
@ -416,18 +409,12 @@ void Chttp2ServerListener::ActiveConnection::HandshakingState::OnHandshakeDone(
// handshaker may have handed off the connection to some external
// code, so we can just clean up here without creating a transport.
if (args->endpoint != nullptr) {
grpc_transport* transport = grpc_create_chttp2_transport(
args->args, args->endpoint, false,
grpc_resource_user_create(
self->connection_->listener_->resource_quota_,
absl::StrCat(grpc_endpoint_get_peer(args->endpoint),
":chttp2_server_transport")));
grpc_transport* transport =
grpc_create_chttp2_transport(args->args, args->endpoint, false);
grpc_error_handle channel_init_err =
self->connection_->listener_->server_->SetupTransport(
transport, self->accepting_pollset_, args->args,
grpc_chttp2_transport_get_socket_node(transport),
self->channel_resource_user_, GRPC_RESOURCE_QUOTA_CHANNEL_SIZE);
self->channel_resource_user_ = nullptr;
grpc_chttp2_transport_get_socket_node(transport));
if (channel_init_err == GRPC_ERROR_NONE) {
// Use notify_on_receive_settings callback to enforce the
// handshake deadline.
@ -491,10 +478,6 @@ void Chttp2ServerListener::ActiveConnection::HandshakingState::OnHandshakeDone(
gpr_free(self->acceptor_);
self->acceptor_ = nullptr;
OrphanablePtr<ActiveConnection> connection;
if (self->channel_resource_user_ != nullptr) {
grpc_resource_user_free(self->channel_resource_user_,
GRPC_RESOURCE_QUOTA_CHANNEL_SIZE);
}
if (cleanup_connection) {
MutexLock listener_lock(&self->connection_->listener_->mu_);
auto it = self->connection_->listener_->connections_.find(
@ -513,9 +496,9 @@ void Chttp2ServerListener::ActiveConnection::HandshakingState::OnHandshakeDone(
Chttp2ServerListener::ActiveConnection::ActiveConnection(
grpc_pollset* accepting_pollset, grpc_tcp_server_acceptor* acceptor,
grpc_channel_args* args, grpc_resource_user* channel_resource_user)
: handshaking_state_(MakeOrphanable<HandshakingState>(
Ref(), accepting_pollset, acceptor, args, channel_resource_user)) {
grpc_channel_args* args, MemoryOwner memory_owner)
: handshaking_state_(memory_owner.MakeOrphanable<HandshakingState>(
Ref(), accepting_pollset, acceptor, args)) {
GRPC_CLOSURE_INIT(&on_close_, ActiveConnection::OnClose, this,
grpc_schedule_on_exec_ctx);
}
@ -600,14 +583,9 @@ grpc_error_handle Chttp2ServerListener::Create(
grpc_error_handle error = [&]() {
grpc_error_handle error = GRPC_ERROR_NONE;
// Create Chttp2ServerListener.
listener = new Chttp2ServerListener(
server, args, args_modifier,
grpc_resource_quota_from_channel_args(args, true));
grpc_resource_quota_ref_internal(listener->resource_quota_);
error = grpc_tcp_server_create(
&listener->tcp_server_shutdown_complete_, args,
grpc_slice_allocator_factory_create(listener->resource_quota_),
&listener->tcp_server_);
listener = new Chttp2ServerListener(server, args, args_modifier);
error = grpc_tcp_server_create(&listener->tcp_server_shutdown_complete_,
args, &listener->tcp_server_);
if (error != GRPC_ERROR_NONE) return error;
if (server->config_fetcher() != nullptr) {
listener->resolved_address_ = *addr;
@ -648,14 +626,10 @@ grpc_error_handle Chttp2ServerListener::Create(
grpc_error_handle Chttp2ServerListener::CreateWithAcceptor(
Server* server, const char* name, grpc_channel_args* args,
Chttp2ServerArgsModifier args_modifier) {
Chttp2ServerListener* listener = new Chttp2ServerListener(
server, args, args_modifier,
grpc_resource_quota_from_channel_args(args, true));
grpc_resource_quota_ref_internal(listener->resource_quota_);
Chttp2ServerListener* listener =
new Chttp2ServerListener(server, args, args_modifier);
grpc_error_handle error = grpc_tcp_server_create(
&listener->tcp_server_shutdown_complete_, args,
grpc_slice_allocator_factory_create(listener->resource_quota_),
&listener->tcp_server_);
&listener->tcp_server_shutdown_complete_, args, &listener->tcp_server_);
if (error != GRPC_ERROR_NONE) {
delete listener;
return error;
@ -670,11 +644,11 @@ grpc_error_handle Chttp2ServerListener::CreateWithAcceptor(
Chttp2ServerListener::Chttp2ServerListener(
Server* server, grpc_channel_args* args,
Chttp2ServerArgsModifier args_modifier, grpc_resource_quota* resource_quota)
Chttp2ServerArgsModifier args_modifier)
: server_(server),
args_modifier_(args_modifier),
args_(args),
resource_quota_(resource_quota) {
memory_quota_(ResourceQuotaFromChannelArgs(args)->memory_quota()) {
GRPC_CLOSURE_INIT(&tcp_server_shutdown_complete_, TcpServerShutdownComplete,
this, grpc_schedule_on_exec_ctx);
}
@ -687,7 +661,6 @@ Chttp2ServerListener::~Chttp2ServerListener() {
ExecCtx::Run(DEBUG_LOCATION, on_destroy_done_, GRPC_ERROR_NONE);
ExecCtx::Get()->Flush();
}
grpc_resource_quota_unref_internal(resource_quota_);
grpc_channel_args_destroy(args_);
}
@ -766,11 +739,10 @@ void Chttp2ServerListener::OnAccept(void* arg, grpc_endpoint* tcp,
}
args_to_destroy = args;
}
grpc_resource_user* channel_resource_user = grpc_resource_user_create(
self->resource_quota_,
auto memory_owner = self->memory_quota_->CreateMemoryOwner(
absl::StrCat(grpc_endpoint_get_peer(tcp), ":server_channel"));
auto connection = MakeOrphanable<ActiveConnection>(
accepting_pollset, acceptor, args, channel_resource_user);
auto connection = memory_owner.MakeOrphanable<ActiveConnection>(
accepting_pollset, acceptor, args, std::move(memory_owner));
// We no longer own acceptor
acceptor = nullptr;
// Hold a ref to connection to allow starting handshake outside the
@ -781,12 +753,6 @@ void Chttp2ServerListener::OnAccept(void* arg, grpc_endpoint* tcp,
MutexLock lock(&self->mu_);
// Shutdown the the connection if listener's stopped serving.
if (!self->shutdown_ && self->is_serving_) {
if (!grpc_resource_user_safe_alloc(channel_resource_user,
GRPC_RESOURCE_QUOTA_CHANNEL_SIZE)) {
gpr_log(
GPR_INFO,
"Memory quota exhausted, rejecting connection, no handshaking.");
} else {
// This ref needs to be taken in the critical region after having made
// sure that the listener has not been Orphaned, so as to avoid
// heap-use-after-free issues where `Ref()` is invoked when the ref of
@ -796,7 +762,6 @@ void Chttp2ServerListener::OnAccept(void* arg, grpc_endpoint* tcp,
self->connections_.emplace(connection.get(), std::move(connection));
}
}
}
if (connection != nullptr) {
endpoint_cleanup(GRPC_ERROR_NONE);
} else {

@ -33,6 +33,7 @@
#include "src/core/lib/iomgr/endpoint.h"
#include "src/core/lib/iomgr/exec_ctx.h"
#include "src/core/lib/iomgr/tcp_posix.h"
#include "src/core/lib/resource_quota/api.h"
#include "src/core/lib/surface/completion_queue.h"
#include "src/core/lib/surface/server.h"
@ -45,20 +46,15 @@ void grpc_server_add_insecure_channel_from_fd(grpc_server* server,
const grpc_channel_args* server_args = core_server->channel_args();
std::string name = absl::StrCat("fd:", fd);
grpc_resource_quota* resource_quota =
grpc_resource_quota_create(name.c_str());
auto memory_quota =
grpc_core::ResourceQuotaFromChannelArgs(server_args)->memory_quota();
grpc_endpoint* server_endpoint = grpc_tcp_create(
grpc_fd_create(fd, name.c_str(), true), server_args, name,
grpc_slice_allocator_create(resource_quota, name, server_args));
grpc_fd_create(fd, name.c_str(), true), server_args, name);
grpc_transport* transport = grpc_create_chttp2_transport(
server_args, server_endpoint, false /* is_client */,
grpc_resource_user_create(resource_quota,
absl::StrCat(name, ":transport")));
grpc_error_handle error = core_server->SetupTransport(
transport, nullptr, server_args, nullptr,
grpc_resource_user_create(resource_quota,
absl::StrCat(name, ":channel")));
grpc_resource_quota_unref_internal(resource_quota);
server_args, server_endpoint, false /* is_client */
);
grpc_error_handle error =
core_server->SetupTransport(transport, nullptr, server_args, nullptr);
if (error == GRPC_ERROR_NONE) {
for (grpc_pollset* pollset : core_server->pollsets()) {
grpc_endpoint_add_to_pollset(server_endpoint, pollset);

@ -46,6 +46,8 @@
#include "src/core/lib/iomgr/iomgr.h"
#include "src/core/lib/iomgr/timer.h"
#include "src/core/lib/profiling/timers.h"
#include "src/core/lib/resource_quota/api.h"
#include "src/core/lib/resource_quota/trace.h"
#include "src/core/lib/slice/slice_internal.h"
#include "src/core/lib/slice/slice_string_helpers.h"
#include "src/core/lib/transport/error_utils.h"
@ -126,8 +128,6 @@ static void connectivity_state_set(grpc_chttp2_transport* t,
const absl::Status& status,
const char* reason);
static void benign_reclaimer(void* arg, grpc_error_handle error);
static void destructive_reclaimer(void* arg, grpc_error_handle error);
static void benign_reclaimer_locked(void* arg, grpc_error_handle error);
static void destructive_reclaimer_locked(void* arg, grpc_error_handle error);
@ -442,14 +442,18 @@ static void init_keepalive_pings_if_enabled(grpc_chttp2_transport* t) {
}
grpc_chttp2_transport::grpc_chttp2_transport(
const grpc_channel_args* channel_args, grpc_endpoint* ep, bool is_client,
grpc_resource_user* resource_user)
const grpc_channel_args* channel_args, grpc_endpoint* ep, bool is_client)
: refs(1, GRPC_TRACE_FLAG_ENABLED(grpc_trace_chttp2_refcount)
? "chttp2_refcount"
: nullptr),
ep(ep),
peer_string(grpc_endpoint_get_peer(ep)),
resource_user(resource_user),
memory_owner(grpc_core::ResourceQuotaFromChannelArgs(channel_args)
->memory_quota()
->CreateMemoryOwner(absl::StrCat(
grpc_endpoint_get_peer(ep), ":client_transport"))),
self_reservation(
memory_owner.MakeReservation(sizeof(grpc_chttp2_transport))),
combiner(grpc_combiner_create()),
state_tracker(is_client ? "client_transport" : "server_transport",
GRPC_CHANNEL_READY),
@ -535,12 +539,11 @@ grpc_chttp2_transport::grpc_chttp2_transport(
static void destroy_transport_locked(void* tp, grpc_error_handle /*error*/) {
grpc_chttp2_transport* t = static_cast<grpc_chttp2_transport*>(tp);
t->destroying = 1;
grpc_resource_user_shutdown(t->resource_user);
grpc_resource_user_unref(t->resource_user);
close_transport_locked(
t, grpc_error_set_int(
GRPC_ERROR_CREATE_FROM_STATIC_STRING("Transport destroyed"),
GRPC_ERROR_INT_OCCURRED_DURING_WRITE, t->write_state));
t->memory_owner.Reset();
// Must be the last line.
GRPC_CHTTP2_UNREF_TRANSPORT(t, "destroy");
}
@ -646,6 +649,10 @@ grpc_chttp2_stream::grpc_chttp2_stream(grpc_chttp2_transport* t,
: t(t),
refcount(refcount),
reffer(this),
stream_reservation(t->memory_owner.MakeReservation(
grpc_core::kResourceQuotaCallSize)), // TODO(ctiller): sizeof(*this),
// or better, move allocation to
// memory quota.
initial_metadata_buffer(arena),
trailing_metadata_buffer(arena) {
if (server_data) {
@ -712,9 +719,6 @@ grpc_chttp2_stream::~grpc_chttp2_stream() {
GRPC_ERROR_UNREF(write_closed_error);
GRPC_ERROR_UNREF(byte_stream_error);
flow_control.Destroy();
if (!t->is_client) {
grpc_resource_user_free(t->resource_user, GRPC_RESOURCE_QUOTA_CALL_SIZE);
}
GRPC_CHTTP2_UNREF_TRANSPORT(t, "stream");
grpc_core::ExecCtx::Run(DEBUG_LOCATION, destroy_stream_arg, GRPC_ERROR_NONE);
}
@ -763,18 +767,6 @@ grpc_chttp2_stream* grpc_chttp2_parsing_accept_stream(grpc_chttp2_transport* t,
if (t->accept_stream_cb == nullptr) {
return nullptr;
}
// Don't accept the stream if memory quota doesn't allow. Note that we should
// simply refuse the stream here instead of canceling the stream after it's
// accepted since the latter will create the call which costs much memory.
GPR_ASSERT(t->resource_user != nullptr);
if (!grpc_resource_user_safe_alloc(t->resource_user,
GRPC_RESOURCE_QUOTA_CALL_SIZE)) {
gpr_log(GPR_INFO, "Memory exhausted, rejecting the stream.");
grpc_chttp2_add_rst_stream_to_next_write(t, id, GRPC_HTTP2_REFUSED_STREAM,
nullptr);
grpc_chttp2_initiate_write(t, GRPC_CHTTP2_INITIATE_WRITE_RST_STREAM);
return nullptr;
}
grpc_chttp2_stream* accepting = nullptr;
GPR_ASSERT(t->accepting_stream == nullptr);
t->accepting_stream = &accepting;
@ -3156,10 +3148,19 @@ static void post_benign_reclaimer(grpc_chttp2_transport* t) {
if (!t->benign_reclaimer_registered) {
t->benign_reclaimer_registered = true;
GRPC_CHTTP2_REF_TRANSPORT(t, "benign_reclaimer");
GRPC_CLOSURE_INIT(&t->benign_reclaimer_locked, benign_reclaimer, t,
t->memory_owner.PostReclaimer(
grpc_core::ReclamationPass::kBenign,
[t](absl::optional<grpc_core::ReclamationSweep> sweep) {
if (sweep.has_value()) {
GRPC_CLOSURE_INIT(&t->benign_reclaimer_locked,
benign_reclaimer_locked, t,
grpc_schedule_on_exec_ctx);
grpc_resource_user_post_reclaimer(t->resource_user, false,
&t->benign_reclaimer_locked);
t->active_reclamation = std::move(*sweep);
t->combiner->Run(&t->benign_reclaimer_locked, GRPC_ERROR_NONE);
} else {
GRPC_CHTTP2_UNREF_TRANSPORT(t, "benign_reclaimer");
}
});
}
}
@ -3167,18 +3168,20 @@ static void post_destructive_reclaimer(grpc_chttp2_transport* t) {
if (!t->destructive_reclaimer_registered) {
t->destructive_reclaimer_registered = true;
GRPC_CHTTP2_REF_TRANSPORT(t, "destructive_reclaimer");
GRPC_CLOSURE_INIT(&t->destructive_reclaimer_locked, destructive_reclaimer,
t, grpc_schedule_on_exec_ctx);
grpc_resource_user_post_reclaimer(t->resource_user, true,
&t->destructive_reclaimer_locked);
t->memory_owner.PostReclaimer(
grpc_core::ReclamationPass::kDestructive,
[t](absl::optional<grpc_core::ReclamationSweep> sweep) {
if (sweep.has_value()) {
GRPC_CLOSURE_INIT(&t->destructive_reclaimer_locked,
destructive_reclaimer_locked, t,
grpc_schedule_on_exec_ctx);
t->active_reclamation = std::move(*sweep);
t->combiner->Run(&t->destructive_reclaimer_locked, GRPC_ERROR_NONE);
} else {
GRPC_CHTTP2_UNREF_TRANSPORT(t, "benign_reclaimer");
}
});
}
}
static void benign_reclaimer(void* arg, grpc_error_handle error) {
grpc_chttp2_transport* t = static_cast<grpc_chttp2_transport*>(arg);
t->combiner->Run(GRPC_CLOSURE_INIT(&t->benign_reclaimer_locked,
benign_reclaimer_locked, t, nullptr),
GRPC_ERROR_REF(error));
}
static void benign_reclaimer_locked(void* arg, grpc_error_handle error) {
@ -3205,18 +3208,11 @@ static void benign_reclaimer_locked(void* arg, grpc_error_handle error) {
}
t->benign_reclaimer_registered = false;
if (error != GRPC_ERROR_CANCELLED) {
grpc_resource_user_finish_reclamation(t->resource_user);
t->active_reclamation.Finish();
}
GRPC_CHTTP2_UNREF_TRANSPORT(t, "benign_reclaimer");
}
static void destructive_reclaimer(void* arg, grpc_error_handle error) {
grpc_chttp2_transport* t = static_cast<grpc_chttp2_transport*>(arg);
t->combiner->Run(GRPC_CLOSURE_INIT(&t->destructive_reclaimer_locked,
destructive_reclaimer_locked, t, nullptr),
GRPC_ERROR_REF(error));
}
static void destructive_reclaimer_locked(void* arg, grpc_error_handle error) {
grpc_chttp2_transport* t = static_cast<grpc_chttp2_transport*>(arg);
size_t n = grpc_chttp2_stream_map_size(&t->stream_map);
@ -3242,7 +3238,7 @@ static void destructive_reclaimer_locked(void* arg, grpc_error_handle error) {
}
}
if (error != GRPC_ERROR_CANCELLED) {
grpc_resource_user_finish_reclamation(t->resource_user);
t->active_reclamation.Finish();
}
GRPC_CHTTP2_UNREF_TRANSPORT(t, "destructive_reclaimer");
}
@ -3325,10 +3321,8 @@ grpc_chttp2_transport_get_socket_node(grpc_transport* transport) {
}
grpc_transport* grpc_create_chttp2_transport(
const grpc_channel_args* channel_args, grpc_endpoint* ep, bool is_client,
grpc_resource_user* resource_user) {
auto t =
new grpc_chttp2_transport(channel_args, ep, is_client, resource_user);
const grpc_channel_args* channel_args, grpc_endpoint* ep, bool is_client) {
auto t = new grpc_chttp2_transport(channel_args, ep, is_client);
return &t->base;
}

@ -38,8 +38,7 @@ extern bool g_flow_control_enabled;
/// from the caller; if the caller still needs the resource_user after creating
/// a transport, the caller must take another ref.
grpc_transport* grpc_create_chttp2_transport(
const grpc_channel_args* channel_args, grpc_endpoint* ep, bool is_client,
grpc_resource_user* resource_user);
const grpc_channel_args* channel_args, grpc_endpoint* ep, bool is_client);
grpc_core::RefCountedPtr<grpc_core::channelz::SocketNode>
grpc_chttp2_transport_get_socket_node(grpc_transport* transport);

@ -324,10 +324,8 @@ void StreamFlowControl::IncomingByteStreamUpdate(size_t max_size_hint,
}
// Take in a target and modifies it based on the memory pressure of the system
static double AdjustForMemoryPressure(grpc_resource_quota* quota,
double target) {
static double AdjustForMemoryPressure(double memory_pressure, double target) {
// do not increase window under heavy memory pressure.
double memory_pressure = grpc_resource_quota_get_memory_pressure(quota);
static const double kLowMemPressure = 0.1;
static const double kZeroTarget = 22;
static const double kHighMemPressure = 0.8;
@ -343,7 +341,9 @@ static double AdjustForMemoryPressure(grpc_resource_quota* quota,
}
double TransportFlowControl::TargetLogBdp() {
return AdjustForMemoryPressure(grpc_resource_user_quota(t_->resource_user),
return AdjustForMemoryPressure(t_->memory_owner.is_valid()
? t_->memory_owner.InstantaneousPressure()
: 0.0,
1 + log2(bdp_estimator_.EstimateBdp()));
}

@ -41,6 +41,7 @@
#include "src/core/lib/iomgr/combiner.h"
#include "src/core/lib/iomgr/endpoint.h"
#include "src/core/lib/iomgr/timer.h"
#include "src/core/lib/resource_quota/memory_quota.h"
#include "src/core/lib/transport/connectivity_state.h"
#include "src/core/lib/transport/metadata_batch.h"
#include "src/core/lib/transport/transport_impl.h"
@ -287,8 +288,7 @@ typedef enum {
struct grpc_chttp2_transport {
grpc_chttp2_transport(const grpc_channel_args* channel_args,
grpc_endpoint* ep, bool is_client,
grpc_resource_user* resource_user);
grpc_endpoint* ep, bool is_client);
~grpc_chttp2_transport();
grpc_transport base; /* must be first */
@ -296,7 +296,9 @@ struct grpc_chttp2_transport {
grpc_endpoint* ep;
std::string peer_string;
grpc_resource_user* resource_user;
grpc_core::MemoryOwner memory_owner;
const grpc_core::MemoryAllocator::Reservation self_reservation;
grpc_core::ReclamationSweep active_reclamation;
grpc_core::Combiner* combiner;
@ -521,6 +523,8 @@ struct grpc_chttp2_stream {
explicit Reffer(grpc_chttp2_stream* s);
} reffer;
grpc_core::MemoryAllocator::Reservation stream_reservation;
grpc_closure destroy_stream;
grpc_closure* destroy_stream_arg;

@ -27,6 +27,7 @@
#include <grpc/support/log.h>
#include "src/core/ext/transport/cronet/transport/cronet_transport.h"
#include "src/core/lib/resource_quota/api.h"
#include "src/core/lib/surface/channel.h"
#include "src/core/lib/transport/transport_impl.h"
@ -52,6 +53,7 @@ GRPCAPI grpc_channel* grpc_cronet_secure_channel_create(
const_cast<char*>(GRPC_ARG_DISABLE_CLIENT_AUTHORITY_FILTER);
disable_client_authority_filter_arg.type = GRPC_ARG_INTEGER;
disable_client_authority_filter_arg.value.integer = 1;
args = grpc_core::EnsureResourceQuotaInChannelArgs(args);
grpc_channel_args* new_args = grpc_channel_args_copy_and_add(
args, &disable_client_authority_filter_arg, 1);
@ -60,7 +62,8 @@ GRPCAPI grpc_channel* grpc_cronet_secure_channel_create(
grpc_core::ExecCtx exec_ctx;
grpc_channel* channel = grpc_channel_create(
target, new_args, GRPC_CLIENT_DIRECT_CHANNEL, ct, nullptr, 0, nullptr);
target, new_args, GRPC_CLIENT_DIRECT_CHANNEL, ct, nullptr);
grpc_channel_args_destroy(new_args);
grpc_channel_args_destroy(args);
return channel;
}

@ -29,6 +29,7 @@
#include "src/core/lib/channel/channel_args.h"
#include "src/core/lib/gprpp/manual_constructor.h"
#include "src/core/lib/resource_quota/api.h"
#include "src/core/lib/slice/slice_internal.h"
#include "src/core/lib/surface/api_trace.h"
#include "src/core/lib/surface/channel.h"
@ -1294,9 +1295,10 @@ grpc_channel* grpc_inproc_channel_create(grpc_server* server,
default_authority_arg.type = GRPC_ARG_STRING;
default_authority_arg.key = const_cast<char*>(GRPC_ARG_DEFAULT_AUTHORITY);
default_authority_arg.value.string = const_cast<char*>("inproc.authority");
args = grpc_channel_args_copy_and_add(args, &default_authority_arg, 1);
grpc_channel_args* client_args =
grpc_channel_args_copy_and_add(args, &default_authority_arg, 1);
grpc_core::EnsureResourceQuotaInChannelArgs(args);
grpc_channel_args_destroy(args);
grpc_transport* server_transport;
grpc_transport* client_transport;
inproc_transports_create(&server_transport, server_args, &client_transport,
@ -1309,7 +1311,7 @@ grpc_channel* grpc_inproc_channel_create(grpc_server* server,
if (error == GRPC_ERROR_NONE) {
channel =
grpc_channel_create("inproc", client_args, GRPC_CLIENT_DIRECT_CHANNEL,
client_transport, nullptr, 0, &error);
client_transport, &error);
if (error != GRPC_ERROR_NONE) {
GPR_ASSERT(!channel);
gpr_log(GPR_ERROR, "Failed to create client channel: %s",

@ -42,8 +42,6 @@ struct grpc_channel_stack_builder {
// various set/get-able parameters
grpc_channel_args* args;
grpc_transport* transport;
grpc_resource_user* resource_user;
size_t preallocated_bytes;
char* target;
const char* name;
};

@ -118,6 +118,12 @@ class PthreadTlsImpl : TlsTypeConstrainer<T> {
return t;
}
T operator->() const {
static_assert(std::is_pointer<T>::value,
"operator-> only usable on pointers");
return this->operator T();
}
T operator=(T t) {
char* src = reinterpret_cast<char*>(&t);
for (pthread_key_t key : keys_) {

@ -0,0 +1,45 @@
// Copyright 2021 gRPC authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef GRPC_CORE_LIB_GPRPP_CPP_IMPL_OF_H
#define GRPC_CORE_LIB_GPRPP_CPP_IMPL_OF_H
namespace grpc_core {
// Declares CppType to be the backing implementation of CType.
// Use via the curiously recursive template:
// class Foo : public CppImplOf<Foo, grpc_foo> {};
// Provides casting methods each way.
// grpc_foo should be `typedef struct grpc_foo grpc_foo` and otherwise
// not defined.
template <typename CppType, typename CType>
class CppImplOf {
public:
// Convert the C struct to C++
static CppType* FromC(CType* c_type) {
return reinterpret_cast<CppType*>(c_type);
}
// Retrieve a c pointer (of the same ownership as this)
CType* c_ptr() {
return reinterpret_cast<CType*>(static_cast<CppType*>(this));
}
protected:
~CppImplOf() = default;
};
} // namespace grpc_core
#endif // GRPC_CORE_LIB_GPRPP_CPP_IMPL_OF_H

@ -32,6 +32,7 @@
#include <grpc/support/string_util.h>
#include "src/core/lib/address_utils/sockaddr_utils.h"
#include "src/core/lib/channel/channel_args.h"
#include "src/core/lib/gpr/string.h"
#include "src/core/lib/gprpp/memory.h"
#include "src/core/lib/http/format_request.h"
@ -40,6 +41,7 @@
#include "src/core/lib/iomgr/iomgr_internal.h"
#include "src/core/lib/iomgr/resolve_address.h"
#include "src/core/lib/iomgr/tcp_client.h"
#include "src/core/lib/resource_quota/api.h"
#include "src/core/lib/slice/slice_internal.h"
namespace grpc_core {
@ -49,13 +51,13 @@ class InternalRequest {
public:
InternalRequest(const grpc_slice& request_text,
grpc_httpcli_response* response,
grpc_resource_quota* resource_quota, absl::string_view host,
ResourceQuotaRefPtr resource_quota, absl::string_view host,
absl::string_view ssl_host_override, grpc_millis deadline,
const grpc_httpcli_handshaker* handshaker,
grpc_closure* on_done, grpc_httpcli_context* context,
grpc_polling_entity* pollent, const char* name)
: request_text_(request_text),
resource_quota_(resource_quota),
resource_quota_(std::move(resource_quota)),
host_(host),
ssl_host_override_(ssl_host_override),
deadline_(deadline),
@ -91,7 +93,6 @@ class InternalRequest {
grpc_slice_buffer_destroy_internal(&incoming_);
grpc_slice_buffer_destroy_internal(&outgoing_);
GRPC_ERROR_UNREF(overall_error_);
grpc_resource_quota_unref_internal(resource_quota_);
}
private:
@ -203,10 +204,10 @@ class InternalRequest {
addr = &addresses_->addrs[next_address_++];
GRPC_CLOSURE_INIT(&connected_, OnConnected, this,
grpc_schedule_on_exec_ctx);
grpc_tcp_client_connect(&connected_, &ep_,
grpc_slice_allocator_create(
resource_quota_, grpc_sockaddr_to_uri(addr)),
context_->pollset_set, nullptr, addr, deadline_);
grpc_channel_args* args = ChannelArgsWrappingResourceQuota(resource_quota_);
grpc_tcp_client_connect(&connected_, &ep_, context_->pollset_set, args,
addr, deadline_);
grpc_channel_args_destroy(args);
}
static void OnResolved(void* arg, grpc_error_handle error) {
@ -224,7 +225,7 @@ class InternalRequest {
grpc_resolved_addresses* addresses_ = nullptr;
size_t next_address_ = 0;
grpc_endpoint* ep_ = nullptr;
grpc_resource_quota* resource_quota_;
ResourceQuotaRefPtr resource_quota_;
std::string host_;
std::string ssl_host_override_;
grpc_millis deadline_;
@ -266,16 +267,14 @@ void grpc_httpcli_context_destroy(grpc_httpcli_context* context) {
grpc_pollset_set_destroy(context->pollset_set);
}
static void internal_request_begin(grpc_httpcli_context* context,
grpc_polling_entity* pollent,
grpc_resource_quota* resource_quota,
const grpc_httpcli_request* request,
grpc_millis deadline, grpc_closure* on_done,
grpc_httpcli_response* response,
const char* name,
static void internal_request_begin(
grpc_httpcli_context* context, grpc_polling_entity* pollent,
grpc_core::ResourceQuotaRefPtr resource_quota,
const grpc_httpcli_request* request, grpc_millis deadline,
grpc_closure* on_done, grpc_httpcli_response* response, const char* name,
const grpc_slice& request_text) {
new grpc_core::InternalRequest(
request_text, response, resource_quota, request->host,
request_text, response, std::move(resource_quota), request->host,
request->ssl_host_override, deadline,
request->handshaker ? request->handshaker : &grpc_httpcli_plaintext,
on_done, context, pollent, name);
@ -283,37 +282,35 @@ static void internal_request_begin(grpc_httpcli_context* context,
void grpc_httpcli_get(grpc_httpcli_context* context,
grpc_polling_entity* pollent,
grpc_resource_quota* resource_quota,
grpc_core::ResourceQuotaRefPtr resource_quota,
const grpc_httpcli_request* request, grpc_millis deadline,
grpc_closure* on_done, grpc_httpcli_response* response) {
if (g_get_override && g_get_override(request, deadline, on_done, response)) {
grpc_resource_quota_unref_internal(resource_quota);
return;
}
std::string name =
absl::StrFormat("HTTP:GET:%s:%s", request->host, request->http.path);
internal_request_begin(context, pollent, resource_quota, request, deadline,
on_done, response, name.c_str(),
internal_request_begin(context, pollent, std::move(resource_quota), request,
deadline, on_done, response, name.c_str(),
grpc_httpcli_format_get_request(request));
}
void grpc_httpcli_post(grpc_httpcli_context* context,
grpc_polling_entity* pollent,
grpc_resource_quota* resource_quota,
grpc_core::ResourceQuotaRefPtr resource_quota,
const grpc_httpcli_request* request,
const char* body_bytes, size_t body_size,
grpc_millis deadline, grpc_closure* on_done,
grpc_httpcli_response* response) {
if (g_post_override && g_post_override(request, body_bytes, body_size,
deadline, on_done, response)) {
grpc_resource_quota_unref_internal(resource_quota);
return;
}
std::string name =
absl::StrFormat("HTTP:POST:%s:%s", request->host, request->http.path);
internal_request_begin(
context, pollent, resource_quota, request, deadline, on_done, response,
name.c_str(),
context, pollent, std::move(resource_quota), request, deadline, on_done,
response, name.c_str(),
grpc_httpcli_format_post_request(request, body_bytes, body_size));
}

@ -30,7 +30,7 @@
#include "src/core/lib/iomgr/iomgr_internal.h"
#include "src/core/lib/iomgr/polling_entity.h"
#include "src/core/lib/iomgr/pollset_set.h"
#include "src/core/lib/iomgr/resource_quota.h"
#include "src/core/lib/resource_quota/resource_quota.h"
/* User agent this library reports */
#define GRPC_HTTPCLI_USER_AGENT "grpc-httpcli/0.0"
@ -73,26 +73,28 @@ void grpc_httpcli_context_destroy(grpc_httpcli_context* context);
/* Asynchronously perform a HTTP GET.
'context' specifies the http context under which to do the get
'pollset' indicates a grpc_pollset that is interested in the result
of the get - work on this pollset may be used to progress the get
'pollent' indicates a grpc_polling_entity that is interested in the result
of the get - work on this entity may be used to progress the get
operation
'resource_quota: this function takes ownership of a ref from the caller
'request' contains request parameters - these are caller owned and can be
destroyed once the call returns
'deadline' contains a deadline for the request (or gpr_inf_future)
'resource_quota' allows the caller to specify the quota against which to
allocate
'request' contains request parameters - these are caller owned and
can be destroyed once the call returns 'deadline' contains a deadline for the
request (or gpr_inf_future)
'on_response' is a callback to report results to */
void grpc_httpcli_get(grpc_httpcli_context* context,
grpc_polling_entity* pollent,
grpc_resource_quota* resource_quota,
grpc_core::ResourceQuotaRefPtr resource_quota,
const grpc_httpcli_request* request, grpc_millis deadline,
grpc_closure* on_done, grpc_httpcli_response* response);
/* Asynchronously perform a HTTP POST.
'context' specifies the http context under which to do the post
'pollset' indicates a grpc_pollset that is interested in the result
of the post - work on this pollset may be used to progress the post
'pollent' indicates a grpc_polling_entity that is interested in the result
of the post - work on this entity may be used to progress the post
operation
'resource_quota' - this function takes ownership of a ref from the caller.
'resource_quota' allows the caller to specify the quota against which to
allocate
'request' contains request parameters - these are caller owned and can be
destroyed once the call returns
'body_bytes' and 'body_size' specify the payload for the post.
@ -104,7 +106,7 @@ void grpc_httpcli_get(grpc_httpcli_context* context,
Does not support ?var1=val1&var2=val2 in the path. */
void grpc_httpcli_post(grpc_httpcli_context* context,
grpc_polling_entity* pollent,
grpc_resource_quota* resource_quota,
grpc_core::ResourceQuotaRefPtr resource_quota,
const grpc_httpcli_request* request,
const char* body_bytes, size_t body_size,
grpc_millis deadline, grpc_closure* on_done,

@ -29,7 +29,6 @@
#include "src/core/lib/iomgr/pollset.h"
#include "src/core/lib/iomgr/pollset_set.h"
#include "src/core/lib/iomgr/resource_quota.h"
/* An endpoint caps a streaming channel between two communicating processes.
Examples may be: a tcp socket, <stdin+stdout>, or some shared memory. */

@ -59,10 +59,8 @@ struct CFStreamEndpoint {
std::string peer_string;
std::string local_address;
grpc_slice_allocator* slice_allocator;
};
static void CFStreamFree(CFStreamEndpoint* ep) {
grpc_slice_allocator_destroy(ep->slice_allocator);
CFRelease(ep->read_stream);
CFRelease(ep->write_stream);
CFSTREAM_HANDLE_UNREF(ep->stream_sync, "free");
@ -238,17 +236,6 @@ static void WriteAction(void* arg, grpc_error_handle error) {
grpc_slice_unref_internal(slice);
}
static void CFStreamReadAllocationDone(void* arg, grpc_error_handle error) {
CFStreamEndpoint* ep = static_cast<CFStreamEndpoint*>(arg);
if (error == GRPC_ERROR_NONE) {
ep->stream_sync->NotifyOnRead(&ep->read_action);
} else {
grpc_slice_buffer_reset_and_unref_internal(ep->read_slices);
CallReadCb(ep, error);
EP_UNREF(ep, "read");
}
}
static void CFStreamRead(grpc_endpoint* ep, grpc_slice_buffer* slices,
grpc_closure* cb, bool urgent) {
CFStreamEndpoint* ep_impl = reinterpret_cast<CFStreamEndpoint*>(ep);
@ -260,13 +247,10 @@ static void CFStreamRead(grpc_endpoint* ep, grpc_slice_buffer* slices,
ep_impl->read_cb = cb;
ep_impl->read_slices = slices;
grpc_slice_buffer_reset_and_unref_internal(slices);
grpc_slice_buffer_add_indexed(
slices, GRPC_SLICE_MALLOC(GRPC_TCP_DEFAULT_READ_SLICE_SIZE));
EP_REF(ep_impl, "read");
if (grpc_slice_allocator_allocate(
ep_impl->slice_allocator, GRPC_TCP_DEFAULT_READ_SLICE_SIZE, 1,
grpc_slice_allocator_intent::kReadBuffer, ep_impl->read_slices,
CFStreamReadAllocationDone, ep_impl)) {
ep_impl->stream_sync->NotifyOnRead(&ep_impl->read_action);
}
}
static void CFStreamWrite(grpc_endpoint* ep, grpc_slice_buffer* slices,
@ -337,9 +321,9 @@ static const grpc_endpoint_vtable vtable = {CFStreamRead,
CFStreamGetFD,
CFStreamCanTrackErr};
grpc_endpoint* grpc_cfstream_endpoint_create(
CFReadStreamRef read_stream, CFWriteStreamRef write_stream,
const char* peer_string, grpc_slice_allocator* slice_allocator,
grpc_endpoint* grpc_cfstream_endpoint_create(CFReadStreamRef read_stream,
CFWriteStreamRef write_stream,
const char* peer_string,
CFStreamHandle* stream_sync) {
CFStreamEndpoint* ep_impl = new CFStreamEndpoint;
if (grpc_tcp_trace.enabled()) {
@ -381,7 +365,6 @@ grpc_endpoint* grpc_cfstream_endpoint_create(
static_cast<void*>(ep_impl), grpc_schedule_on_exec_ctx);
GRPC_CLOSURE_INIT(&ep_impl->write_action, WriteAction,
static_cast<void*>(ep_impl), grpc_schedule_on_exec_ctx);
ep_impl->slice_allocator = slice_allocator;
return &ep_impl->base;
}

@ -39,9 +39,9 @@
#include "src/core/lib/iomgr/cfstream_handle.h"
#include "src/core/lib/iomgr/endpoint.h"
grpc_endpoint* grpc_cfstream_endpoint_create(
CFReadStreamRef read_stream, CFWriteStreamRef write_stream,
const char* peer_string, grpc_slice_allocator* slice_allocator,
grpc_endpoint* grpc_cfstream_endpoint_create(CFReadStreamRef read_stream,
CFWriteStreamRef write_stream,
const char* peer_string,
CFStreamHandle* stream_sync);
#endif /* GRPC_CFSTREAM */

@ -40,6 +40,7 @@
#include "src/core/lib/iomgr/socket_utils_posix.h"
#include "src/core/lib/iomgr/tcp_posix.h"
#include "src/core/lib/iomgr/unix_sockets_posix.h"
#include "src/core/lib/resource_quota/api.h"
static void create_sockets(int sv[2]) {
int flags;
@ -59,18 +60,13 @@ grpc_endpoint_pair grpc_iomgr_create_endpoint_pair(const char* name,
create_sockets(sv);
grpc_core::ExecCtx exec_ctx;
std::string final_name = absl::StrCat(name, ":client");
grpc_resource_quota* resource_quota =
grpc_resource_quota_from_channel_args(args, true);
p.client = grpc_tcp_create(
grpc_fd_create(sv[1], final_name.c_str(), false), args,
"socketpair-server",
grpc_slice_allocator_create(resource_quota, "server_endpoint", args));
args = grpc_core::EnsureResourceQuotaInChannelArgs(args);
p.client = grpc_tcp_create(grpc_fd_create(sv[1], final_name.c_str(), false),
args, "socketpair-server");
final_name = absl::StrCat(name, ":server");
p.server = grpc_tcp_create(
grpc_fd_create(sv[0], final_name.c_str(), false), args,
"socketpair-client",
grpc_slice_allocator_create(resource_quota, "client_endpoint", args));
grpc_resource_quota_unref_internal(resource_quota);
p.server = grpc_tcp_create(grpc_fd_create(sv[0], final_name.c_str(), false),
args, "socketpair-client");
grpc_channel_args_destroy(args);
return p;
}

@ -71,24 +71,15 @@ static void create_sockets(SOCKET sv[2]) {
}
grpc_endpoint_pair grpc_iomgr_create_endpoint_pair(
const char* name, grpc_channel_args* channel_args) {
const char*, grpc_channel_args* channel_args) {
SOCKET sv[2];
grpc_endpoint_pair p;
create_sockets(sv);
grpc_core::ExecCtx exec_ctx;
grpc_resource_quota* resource_quota =
grpc_resource_quota_from_channel_args(channel_args, true);
p.client =
grpc_tcp_create(grpc_winsocket_create(sv[1], "endpoint:client"),
channel_args, "endpoint:server",
grpc_slice_allocator_create(
resource_quota, "endpoint:server", channel_args));
p.server =
grpc_tcp_create(grpc_winsocket_create(sv[0], "endpoint:server"),
channel_args, "endpoint:client",
grpc_slice_allocator_create(
resource_quota, "endpoint:client", channel_args));
grpc_resource_quota_unref_internal(resource_quota);
p.client = grpc_tcp_create(grpc_winsocket_create(sv[1], "endpoint:client"),
channel_args, "endpoint:server");
p.server = grpc_tcp_create(grpc_winsocket_create(sv[0], "endpoint:server"),
channel_args, "endpoint:client");
return p;
}

File diff suppressed because it is too large Load Diff

@ -1,226 +0,0 @@
/*
*
* Copyright 2016 gRPC authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
#ifndef GRPC_CORE_LIB_IOMGR_RESOURCE_QUOTA_H
#define GRPC_CORE_LIB_IOMGR_RESOURCE_QUOTA_H
#include <grpc/support/port_platform.h>
#include <grpc/grpc.h>
#include "src/core/lib/debug/trace.h"
#include "src/core/lib/iomgr/closure.h"
/** \file Tracks resource usage against a pool.
The current implementation tracks only memory usage, but in the future
this may be extended to (for example) threads and file descriptors.
A grpc_resource_quota represents the pooled resources, and
grpc_resource_user instances attach to the quota and consume those
resources. They also offer a vector for reclamation: if we become
resource constrained, grpc_resource_user instances are asked (in turn) to
free up whatever they can so that the system as a whole can make progress.
There are three kinds of reclamation that take place, in order of increasing
invasiveness:
- an internal reclamation, where cached resource at the resource user level
is returned to the quota
- a benign reclamation phase, whereby resources that are in use but are not
helping anything make progress are reclaimed
- a destructive reclamation, whereby resources that are helping something
make progress may be enacted so that at least one part of the system can
complete.
Only one reclamation will be outstanding for a given quota at a given time.
On each reclamation attempt, the kinds of reclamation are tried in order of
increasing invasiveness, stopping at the first one that succeeds. Thus, on a
given reclamation attempt, if internal and benign reclamation both fail, it
will wind up doing a destructive reclamation. However, the next reclamation
attempt may then be able to get what it needs via internal or benign
reclamation, due to resources that may have been freed up by the destructive
reclamation in the previous attempt.
Future work will be to expose the current resource pressure so that back
pressure can be applied to avoid reclamation phases starting.
Resource users own references to resource quotas, and resource quotas
maintain lists of users (which users arrange to leave before they are
destroyed) */
extern grpc_core::TraceFlag grpc_resource_quota_trace;
// TODO(juanlishen): This is a hack. We need to do real accounting instead of
// hard coding.
constexpr size_t GRPC_RESOURCE_QUOTA_CALL_SIZE = 15 * 1024;
constexpr size_t GRPC_RESOURCE_QUOTA_CHANNEL_SIZE = 50 * 1024;
constexpr size_t GRPC_SLICE_ALLOCATOR_MIN_ALLOCATE_SIZE = 256;
constexpr size_t GRPC_SLICE_ALLOCATOR_MAX_ALLOCATE_SIZE = 4 * 1024 * 1024;
grpc_resource_quota* grpc_resource_quota_ref_internal(
grpc_resource_quota* resource_quota);
void grpc_resource_quota_unref_internal(grpc_resource_quota* resource_quota);
grpc_resource_quota* grpc_resource_quota_from_channel_args(
const grpc_channel_args* channel_args, bool create = true);
/* Return a number indicating current memory pressure:
0.0 ==> no memory usage
1.0 ==> maximum memory usage */
double grpc_resource_quota_get_memory_pressure(
grpc_resource_quota* resource_quota);
size_t grpc_resource_quota_peek_size(grpc_resource_quota* resource_quota);
typedef struct grpc_resource_user grpc_resource_user;
grpc_resource_user* grpc_resource_user_create(
grpc_resource_quota* resource_quota, absl::string_view name);
/* Returns a borrowed reference to the underlying resource quota for this
resource user. */
grpc_resource_quota* grpc_resource_user_quota(
grpc_resource_user* resource_user);
void grpc_resource_user_ref(grpc_resource_user* resource_user);
void grpc_resource_user_unref(grpc_resource_user* resource_user);
void grpc_resource_user_shutdown(grpc_resource_user* resource_user);
/* Attempts to get quota from the resource_user to create 'thread_count' number
* of threads. Returns true if successful (i.e the caller is now free to create
* 'thread_count' number of threads) or false if quota is not available */
bool grpc_resource_user_allocate_threads(grpc_resource_user* resource_user,
int thread_count);
/* Releases 'thread_count' worth of quota back to the resource user. The quota
* should have been previously obtained successfully by calling
* grpc_resource_user_allocate_threads().
*
* Note: There need not be an exact one-to-one correspondence between
* grpc_resource_user_allocate_threads() and grpc_resource_user_free_threads()
* calls. The only requirement is that the number of threads allocated should
* all be eventually released */
void grpc_resource_user_free_threads(grpc_resource_user* resource_user,
int thread_count);
/* Allocates from the resource user 'size' worth of memory if this won't exceed
* the resource quota's total size. Returns whether the allocation is done
* successfully. If allocated successfully, the memory should be freed by the
* caller eventually. */
bool grpc_resource_user_safe_alloc(grpc_resource_user* resource_user,
size_t size);
/* Allocates from the resource user 'size' worth of memory.
* If optional_on_done is NULL, then allocate immediately. This may push the
* quota over-limit, at which point reclamation will kick in. The caller is
* always responsible to free the memory eventually.
* Returns true if the allocation was successful. Otherwise, if optional_on_done
* is non-NULL, it will be scheduled without error when the allocation has been
* granted by the quota, and the caller is responsible to free the memory
* eventually. Or it may be scheduled with an error, in which case the caller
* fails to allocate the memory and shouldn't free the memory.
*/
bool grpc_resource_user_alloc(grpc_resource_user* resource_user, size_t size,
grpc_closure* optional_on_done)
GRPC_MUST_USE_RESULT;
/* Release memory back to the quota */
void grpc_resource_user_free(grpc_resource_user* resource_user, size_t size);
/* Post a memory reclaimer to the resource user. Only one benign and one
destructive reclaimer can be posted at once. When executed, the reclaimer
MUST call grpc_resource_user_finish_reclamation before it completes, to
return control to the resource quota. */
void grpc_resource_user_post_reclaimer(grpc_resource_user* resource_user,
bool destructive, grpc_closure* closure);
/* Finish a reclamation step */
void grpc_resource_user_finish_reclamation(grpc_resource_user* resource_user);
/* Helper to allocate slices from a resource user */
typedef struct grpc_slice_allocator {
/* Closure for when a resource user allocation completes */
grpc_closure on_allocated;
/* Closure to call when slices have been allocated */
grpc_closure on_done;
/* Length of slices to allocate on the current request */
size_t length;
/* Number of slices to allocate on the current request */
size_t count;
/* Minimum size to allocate under memory pressure. */
size_t min_length;
/* Maximum size that can be allocated. */
size_t max_length;
/* Destination for slices to allocate on the current request */
grpc_slice_buffer* dest;
/* Parent resource user */
grpc_resource_user* resource_user;
} grpc_slice_allocator;
/// Constructs a slice allocator using configuration from \a args.
///
/// Minimum and maximum limits for memory allocation size can be defined in
/// \a args, and used to configure an allocator. See
/// \a grpc_slice_allocator_allocate for details on how those values are used.
///
/// Caller is responsible for calling \a grpc_slice_allocator_destroy.
grpc_slice_allocator* grpc_slice_allocator_create(
grpc_resource_quota* resource_quota, absl::string_view name,
const grpc_channel_args* args = nullptr);
/* Cleans up after a slice_allocator. */
void grpc_slice_allocator_destroy(grpc_slice_allocator* slice_allocator);
enum class grpc_slice_allocator_intent {
kDefault, // Default intent allocates exactly the memory required.
kReadBuffer // ReadBuffer intent may return a smaller slice than requested if
// memory pressure is high.
};
/** Allocate \a count slices of length \a length into \a dest. Only one request
can be outstanding at a time. When an allocation is completed, calls \a cb
with arg \a p. Returns whether the slice was allocated inline in the
function. If true, the \a cb will not be called. The \a intent argument
allows allocation of smaller slices if memory pressure is high; the size is
implementation-dependent. */
bool grpc_slice_allocator_allocate(grpc_slice_allocator* slice_allocator,
size_t length, size_t count,
grpc_slice_allocator_intent intent,
grpc_slice_buffer* dest,
grpc_iomgr_cb_func cb,
void* p) GRPC_MUST_USE_RESULT;
/* Allows creation of slice_allocators (thus resource_users) without calling
* code having to understand resource_user concepts. */
typedef struct grpc_slice_allocator_factory {
/* Parent resource quota */
grpc_resource_quota* resource_quota;
} grpc_slice_allocator_factory;
/* Constructs a slice allocator factory. Takes ownership of a ref on
* \a resource_quota from the caller. Caller is responsible for calling \a
* grpc_slice_allocator_factory_destroy. */
grpc_slice_allocator_factory* grpc_slice_allocator_factory_create(
grpc_resource_quota* resource_quota);
/* Cleans up after a slice_allocator. */
void grpc_slice_allocator_factory_destroy(
grpc_slice_allocator_factory* slice_allocator_factory);
/** A factory method to create and initialize a slice_allocator using the
factory's resource quota. \a name is the resulting resource_user name. \a args
are used to configure the \a slice_allocator */
grpc_slice_allocator* grpc_slice_allocator_factory_create_slice_allocator(
grpc_slice_allocator_factory* slice_allocator_factory,
absl::string_view name, grpc_channel_args* args = nullptr);
#endif /* GRPC_CORE_LIB_IOMGR_RESOURCE_QUOTA_H */

@ -23,14 +23,12 @@
grpc_tcp_client_vtable* grpc_tcp_client_impl;
void grpc_tcp_client_connect(grpc_closure* on_connect, grpc_endpoint** endpoint,
grpc_slice_allocator* slice_allocator,
grpc_pollset_set* interested_parties,
const grpc_channel_args* channel_args,
const grpc_resolved_address* addr,
grpc_millis deadline) {
grpc_tcp_client_impl->connect(on_connect, endpoint, slice_allocator,
interested_parties, channel_args, addr,
deadline);
grpc_tcp_client_impl->connect(on_connect, endpoint, interested_parties,
channel_args, addr, deadline);
}
void grpc_set_tcp_client_impl(grpc_tcp_client_vtable* impl) {

@ -27,11 +27,10 @@
#include "src/core/lib/iomgr/endpoint.h"
#include "src/core/lib/iomgr/pollset_set.h"
#include "src/core/lib/iomgr/resolve_address.h"
#include "src/core/lib/iomgr/resource_quota.h"
#include "src/core/lib/resource_quota/memory_quota.h"
typedef struct grpc_tcp_client_vtable {
void (*connect)(grpc_closure* on_connect, grpc_endpoint** endpoint,
grpc_slice_allocator* slice_allocator,
grpc_pollset_set* interested_parties,
const grpc_channel_args* channel_args,
const grpc_resolved_address* addr, grpc_millis deadline);
@ -43,7 +42,6 @@ typedef struct grpc_tcp_client_vtable {
interested_parties points to a set of pollsets that would be interested
in this connection being established (in order to continue their work) */
void grpc_tcp_client_connect(grpc_closure* on_connect, grpc_endpoint** endpoint,
grpc_slice_allocator* slice_allocator,
grpc_pollset_set* interested_parties,
const grpc_channel_args* channel_args,
const grpc_resolved_address* addr,

@ -64,16 +64,12 @@ struct CFStreamConnect {
grpc_endpoint** endpoint;
int refs;
std::string addr_name;
grpc_slice_allocator* slice_allocator;
};
static void CFStreamConnectCleanup(CFStreamConnect* connect) {
CFSTREAM_HANDLE_UNREF(connect->stream_handle, "async connect clean up");
CFRelease(connect->read_stream);
CFRelease(connect->write_stream);
if (connect->slice_allocator != nullptr) {
grpc_slice_allocator_destroy(connect->slice_allocator);
}
gpr_mu_destroy(&connect->mu);
delete connect;
}
@ -132,9 +128,7 @@ static void OnOpen(void* arg, grpc_error_handle error) {
if (error == GRPC_ERROR_NONE) {
*endpoint = grpc_cfstream_endpoint_create(
connect->read_stream, connect->write_stream,
connect->addr_name.c_str(), connect->slice_allocator,
connect->stream_handle);
connect->slice_allocator = nullptr;
connect->addr_name.c_str(), connect->stream_handle);
}
} else {
(void)GRPC_ERROR_REF(error);
@ -156,7 +150,6 @@ static void ParseResolvedAddress(const grpc_resolved_address* addr,
}
static void CFStreamClientConnect(grpc_closure* closure, grpc_endpoint** ep,
grpc_slice_allocator* slice_allocator,
grpc_pollset_set* interested_parties,
const grpc_channel_args* channel_args,
const grpc_resolved_address* resolved_addr,
@ -173,7 +166,6 @@ static void CFStreamClientConnect(grpc_closure* closure, grpc_endpoint** ep,
gpr_log(GPR_DEBUG, "CLIENT_CONNECT: %p, %s: asynchronously connecting",
connect, connect->addr_name.c_str());
}
connect->slice_allocator = slice_allocator;
CFReadStreamRef read_stream;
CFWriteStreamRef write_stream;

@ -42,13 +42,9 @@ struct grpc_custom_tcp_connect {
grpc_endpoint** endpoint;
int refs;
std::string addr_name;
grpc_slice_allocator* slice_allocator;
};
static void custom_tcp_connect_cleanup(grpc_custom_tcp_connect* connect) {
if (connect->slice_allocator != nullptr) {
grpc_slice_allocator_destroy(connect->slice_allocator);
}
grpc_custom_socket* socket = connect->socket;
delete connect;
if (socket->refs == 0) {
@ -87,9 +83,8 @@ static void custom_connect_callback_internal(grpc_custom_socket* socket,
grpc_closure* closure = connect->closure;
grpc_timer_cancel(&connect->alarm);
if (error == GRPC_ERROR_NONE) {
*connect->endpoint = custom_tcp_endpoint_create(
socket, connect->slice_allocator, connect->addr_name.c_str());
connect->slice_allocator = nullptr;
*connect->endpoint =
custom_tcp_endpoint_create(socket, connect->addr_name.c_str());
}
done = (--connect->refs == 0);
socket->refs--;
@ -114,7 +109,6 @@ static void custom_connect_callback(grpc_custom_socket* socket,
}
static void tcp_connect(grpc_closure* closure, grpc_endpoint** ep,
grpc_slice_allocator* slice_allocator,
grpc_pollset_set* interested_parties,
const grpc_channel_args* channel_args,
const grpc_resolved_address* resolved_addr,
@ -130,7 +124,6 @@ static void tcp_connect(grpc_closure* closure, grpc_endpoint** ep,
connect->closure = closure;
connect->endpoint = ep;
connect->addr_name = grpc_sockaddr_to_uri(resolved_addr);
connect->slice_allocator = slice_allocator;
connect->socket = socket;
socket->connector = connect;
socket->endpoint = nullptr;

@ -62,7 +62,6 @@ struct async_connect {
grpc_endpoint** ep;
grpc_closure* closure;
grpc_channel_args* channel_args;
grpc_slice_allocator* slice_allocator;
};
static grpc_error_handle prepare_socket(const grpc_resolved_address* addr,
@ -118,9 +117,6 @@ static void tc_on_alarm(void* acp, grpc_error_handle error) {
gpr_mu_unlock(&ac->mu);
if (done) {
gpr_mu_destroy(&ac->mu);
if (ac->slice_allocator != nullptr) {
grpc_slice_allocator_destroy(ac->slice_allocator);
}
grpc_channel_args_destroy(ac->channel_args);
delete ac;
}
@ -128,8 +124,8 @@ static void tc_on_alarm(void* acp, grpc_error_handle error) {
grpc_endpoint* grpc_tcp_client_create_from_fd(
grpc_fd* fd, const grpc_channel_args* channel_args,
absl::string_view addr_str, grpc_slice_allocator* slice_allocator) {
return grpc_tcp_create(fd, channel_args, addr_str, slice_allocator);
absl::string_view addr_str) {
return grpc_tcp_create(fd, channel_args, addr_str);
}
static void on_writable(void* acp, grpc_error_handle error) {
@ -177,9 +173,7 @@ static void on_writable(void* acp, grpc_error_handle error) {
switch (so_error) {
case 0:
grpc_pollset_set_del_fd(ac->interested_parties, fd);
*ep = grpc_tcp_client_create_from_fd(fd, ac->channel_args, ac->addr_str,
ac->slice_allocator);
ac->slice_allocator = nullptr;
*ep = grpc_tcp_client_create_from_fd(fd, ac->channel_args, ac->addr_str);
fd = nullptr;
break;
case ENOBUFS:
@ -234,10 +228,6 @@ finish:
// This is safe even outside the lock, because "done", the sentinel, is
// populated *inside* the lock.
gpr_mu_destroy(&ac->mu);
if (ac->slice_allocator != nullptr) {
grpc_slice_allocator_destroy(ac->slice_allocator);
ac->slice_allocator = nullptr;
}
grpc_channel_args_destroy(ac->channel_args);
delete ac;
}
@ -280,8 +270,7 @@ grpc_error_handle grpc_tcp_client_prepare_fd(
void grpc_tcp_client_create_from_prepared_fd(
grpc_pollset_set* interested_parties, grpc_closure* closure, const int fd,
const grpc_channel_args* channel_args, const grpc_resolved_address* addr,
grpc_millis deadline, grpc_endpoint** ep,
grpc_slice_allocator* slice_allocator) {
grpc_millis deadline, grpc_endpoint** ep) {
int err;
do {
err = connect(fd, reinterpret_cast<const grpc_sockaddr*>(addr->addr),
@ -292,13 +281,12 @@ void grpc_tcp_client_create_from_prepared_fd(
grpc_fd* fdobj = grpc_fd_create(fd, name.c_str(), true);
if (err >= 0) {
*ep = grpc_tcp_client_create_from_fd(
fdobj, channel_args, grpc_sockaddr_to_uri(addr), slice_allocator);
*ep = grpc_tcp_client_create_from_fd(fdobj, channel_args,
grpc_sockaddr_to_uri(addr));
grpc_core::ExecCtx::Run(DEBUG_LOCATION, closure, GRPC_ERROR_NONE);
return;
}
if (errno != EWOULDBLOCK && errno != EINPROGRESS) {
grpc_slice_allocator_destroy(slice_allocator);
grpc_error_handle error = GRPC_OS_ERROR(errno, "connect");
error = grpc_error_set_str(error, GRPC_ERROR_STR_TARGET_ADDRESS,
grpc_sockaddr_to_uri(addr));
@ -317,7 +305,6 @@ void grpc_tcp_client_create_from_prepared_fd(
ac->addr_str = grpc_sockaddr_to_uri(addr);
gpr_mu_init(&ac->mu);
ac->refs = 2;
ac->slice_allocator = slice_allocator;
GRPC_CLOSURE_INIT(&ac->write_closure, on_writable, ac,
grpc_schedule_on_exec_ctx);
ac->channel_args = grpc_channel_args_copy(channel_args);
@ -335,7 +322,6 @@ void grpc_tcp_client_create_from_prepared_fd(
}
static void tcp_connect(grpc_closure* closure, grpc_endpoint** ep,
grpc_slice_allocator* slice_allocator,
grpc_pollset_set* interested_parties,
const grpc_channel_args* channel_args,
const grpc_resolved_address* addr,
@ -346,13 +332,12 @@ static void tcp_connect(grpc_closure* closure, grpc_endpoint** ep,
*ep = nullptr;
if ((error = grpc_tcp_client_prepare_fd(channel_args, addr, &mapped_addr,
&fd)) != GRPC_ERROR_NONE) {
grpc_slice_allocator_destroy(slice_allocator);
grpc_core::ExecCtx::Run(DEBUG_LOCATION, closure, error);
return;
}
grpc_tcp_client_create_from_prepared_fd(interested_parties, closure, fd,
channel_args, &mapped_addr, deadline,
ep, slice_allocator);
ep);
}
grpc_tcp_client_vtable grpc_posix_tcp_client_vtable = {tcp_connect};

@ -35,7 +35,7 @@
*/
grpc_endpoint* grpc_tcp_client_create_from_fd(
grpc_fd* fd, const grpc_channel_args* channel_args,
absl::string_view addr_str, grpc_slice_allocator* slice_allocator);
absl::string_view addr_str);
/* Return a configured, unbound, unconnected TCP client fd.
@ -64,7 +64,6 @@ grpc_error_handle grpc_tcp_client_prepare_fd(
void grpc_tcp_client_create_from_prepared_fd(
grpc_pollset_set* interested_parties, grpc_closure* closure, const int fd,
const grpc_channel_args* channel_args, const grpc_resolved_address* addr,
grpc_millis deadline, grpc_endpoint** ep,
grpc_slice_allocator* slice_allocator);
grpc_millis deadline, grpc_endpoint** ep);
#endif /* GRPC_CORE_LIB_IOMGR_TCP_CLIENT_POSIX_H */

@ -51,7 +51,6 @@ struct async_connect {
grpc_closure on_connect;
grpc_endpoint** endpoint;
grpc_channel_args* channel_args;
grpc_slice_allocator* slice_allocator;
};
static void async_connect_unlock_and_cleanup(async_connect* ac,
@ -61,9 +60,6 @@ static void async_connect_unlock_and_cleanup(async_connect* ac,
if (done) {
grpc_channel_args_destroy(ac->channel_args);
gpr_mu_destroy(&ac->mu);
if (ac->slice_allocator != nullptr) {
grpc_slice_allocator_destroy(ac->slice_allocator);
}
delete ac;
}
if (socket != NULL) grpc_winsocket_destroy(socket);
@ -109,9 +105,7 @@ static void on_connect(void* acp, grpc_error_handle error) {
error = GRPC_WSA_ERROR(WSAGetLastError(), "ConnectEx");
closesocket(socket->socket);
} else {
*ep = grpc_tcp_create(socket, ac->channel_args, ac->addr_name,
ac->slice_allocator);
ac->slice_allocator = nullptr;
*ep = grpc_tcp_create(socket, ac->channel_args, ac->addr_name);
socket = nullptr;
}
} else {
@ -128,7 +122,6 @@ static void on_connect(void* acp, grpc_error_handle error) {
/* Tries to issue one async connection, then schedules both an IOCP
notification request for the connection, and one timeout alert. */
static void tcp_connect(grpc_closure* on_done, grpc_endpoint** endpoint,
grpc_slice_allocator* slice_allocator,
grpc_pollset_set* interested_parties,
const grpc_channel_args* channel_args,
const grpc_resolved_address* addr,
@ -208,7 +201,6 @@ static void tcp_connect(grpc_closure* on_done, grpc_endpoint** endpoint,
ac->refs = 2;
ac->addr_name = grpc_sockaddr_to_uri(addr);
ac->endpoint = endpoint;
ac->slice_allocator = slice_allocator;
ac->channel_args = grpc_channel_args_copy(channel_args);
GRPC_CLOSURE_INIT(&ac->on_connect, on_connect, ac, grpc_schedule_on_exec_ctx);
@ -227,7 +219,6 @@ failure:
"Failed to connect", &error, 1),
GRPC_ERROR_STR_TARGET_ADDRESS, target_uri);
GRPC_ERROR_UNREF(error);
grpc_slice_allocator_destroy(slice_allocator);
if (socket != NULL) {
grpc_winsocket_destroy(socket);
} else if (sock != INVALID_SOCKET) {

@ -32,7 +32,6 @@
#include "src/core/lib/iomgr/error.h"
#include "src/core/lib/iomgr/iomgr_custom.h"
#include "src/core/lib/iomgr/port.h"
#include "src/core/lib/iomgr/resource_quota.h"
#include "src/core/lib/iomgr/tcp_client.h"
#include "src/core/lib/iomgr/tcp_server.h"
#include "src/core/lib/slice/slice_internal.h"
@ -63,8 +62,6 @@ struct custom_tcp_endpoint {
grpc_slice_buffer* read_slices = nullptr;
grpc_slice_buffer* write_slices = nullptr;
grpc_slice_allocator* slice_allocator;
bool shutting_down;
std::string peer_string;
@ -73,7 +70,6 @@ struct custom_tcp_endpoint {
static void tcp_free(grpc_custom_socket* s) {
custom_tcp_endpoint* tcp =
reinterpret_cast<custom_tcp_endpoint*>(s->endpoint);
grpc_slice_allocator_destroy(tcp->slice_allocator);
delete tcp;
s->refs--;
if (s->refs == 0) {
@ -167,31 +163,6 @@ static void custom_read_callback(grpc_custom_socket* socket, size_t nread,
call_read_cb(tcp, error);
}
static void tcp_read_allocation_done(void* tcpp, grpc_error_handle error) {
custom_tcp_endpoint* tcp = static_cast<custom_tcp_endpoint*>(tcpp);
if (GRPC_TRACE_FLAG_ENABLED(grpc_tcp_trace)) {
gpr_log(GPR_INFO, "TCP:%p read_allocation_done: %s", tcp->socket,
grpc_error_std_string(error).c_str());
}
if (error == GRPC_ERROR_NONE) {
/* Before calling read, we allocate a buffer with exactly one slice
* to tcp->read_slices and wait for the callback indicating that the
* allocation was successful. So slices[0] should always exist here */
char* buffer = reinterpret_cast<char*>(
GRPC_SLICE_START_PTR(tcp->read_slices->slices[0]));
size_t len = GRPC_SLICE_LENGTH(tcp->read_slices->slices[0]);
grpc_custom_socket_vtable->read(tcp->socket, buffer, len,
custom_read_callback);
} else {
grpc_slice_buffer_reset_and_unref_internal(tcp->read_slices);
call_read_cb(tcp, GRPC_ERROR_REF(error));
}
if (GRPC_TRACE_FLAG_ENABLED(grpc_tcp_trace)) {
gpr_log(GPR_INFO, "Initiating read on %p: error=%s", tcp->socket,
grpc_error_std_string(error).c_str());
}
}
static void endpoint_read(grpc_endpoint* ep, grpc_slice_buffer* read_slices,
grpc_closure* cb, bool /*urgent*/) {
custom_tcp_endpoint* tcp = reinterpret_cast<custom_tcp_endpoint*>(ep);
@ -201,12 +172,16 @@ static void endpoint_read(grpc_endpoint* ep, grpc_slice_buffer* read_slices,
tcp->read_slices = read_slices;
grpc_slice_buffer_reset_and_unref_internal(read_slices);
TCP_REF(tcp, "read");
if (grpc_slice_allocator_allocate(
tcp->slice_allocator, GRPC_TCP_DEFAULT_READ_SLICE_SIZE, 1,
grpc_slice_allocator_intent::kReadBuffer, tcp->read_slices,
tcp_read_allocation_done, tcp)) {
tcp_read_allocation_done(tcp, GRPC_ERROR_NONE);
if (tcp->read_slices->length < GRPC_TCP_DEFAULT_READ_SLICE_SIZE) {
grpc_slice_buffer_add_indexed(
tcp->read_slices, GRPC_SLICE_MALLOC(GRPC_TCP_DEFAULT_READ_SLICE_SIZE));
}
/* slices[0] should always exist here since we just added it if it did not */
char* buffer = reinterpret_cast<char*>(
GRPC_SLICE_START_PTR(tcp->read_slices->slices[0]));
size_t len = GRPC_SLICE_LENGTH(tcp->read_slices->slices[0]);
grpc_custom_socket_vtable->read(tcp->socket, buffer, len,
custom_read_callback);
}
static void custom_write_callback(grpc_custom_socket* socket,
@ -346,7 +321,6 @@ static grpc_endpoint_vtable vtable = {endpoint_read,
endpoint_can_track_err};
grpc_endpoint* custom_tcp_endpoint_create(grpc_custom_socket* socket,
grpc_slice_allocator* slice_allocator,
const char* peer_string) {
custom_tcp_endpoint* tcp = new custom_tcp_endpoint;
grpc_core::ApplicationCallbackExecCtx callback_exec_ctx;
@ -372,6 +346,5 @@ grpc_endpoint* custom_tcp_endpoint_create(grpc_custom_socket* socket,
tcp->local_address = grpc_sockaddr_to_uri(&resolved_local_addr);
}
tcp->shutting_down = false;
tcp->slice_allocator = slice_allocator;
return &tcp->base;
}

@ -80,7 +80,6 @@ void grpc_custom_close_server_callback(grpc_tcp_listener* listener);
/// Takes ownership of \a slice_allocator.
grpc_endpoint* custom_tcp_endpoint_create(grpc_custom_socket* socket,
grpc_slice_allocator* slice_allocator,
const char* peer_string);
#endif /* GRPC_CORE_LIB_IOMGR_TCP_CUSTOM_H */

@ -18,6 +18,8 @@
#include <grpc/support/port_platform.h>
#include <grpc/impl/codegen/grpc_types.h>
#include "src/core/lib/iomgr/port.h"
#ifdef GRPC_POSIX_SOCKET_TCP
@ -54,10 +56,11 @@
#include "src/core/lib/iomgr/buffer_list.h"
#include "src/core/lib/iomgr/ev_posix.h"
#include "src/core/lib/iomgr/executor.h"
#include "src/core/lib/iomgr/resource_quota.h"
#include "src/core/lib/iomgr/socket_utils_posix.h"
#include "src/core/lib/iomgr/tcp_posix.h"
#include "src/core/lib/profiling/timers.h"
#include "src/core/lib/resource_quota/api.h"
#include "src/core/lib/resource_quota/memory_quota.h"
#include "src/core/lib/slice/slice_internal.h"
#include "src/core/lib/slice/slice_string_helpers.h"
@ -393,7 +396,8 @@ struct grpc_tcp {
std::string peer_string;
std::string local_address;
grpc_slice_allocator* slice_allocator;
grpc_core::MemoryOwner memory_owner;
grpc_core::MemoryAllocator::Reservation self_reservation;
grpc_core::TracedBuffer* tb_head; /* List of traced buffers */
gpr_mu tb_mu; /* Lock for access to list of traced buffers */
@ -608,7 +612,6 @@ static void tcp_free(grpc_tcp* tcp) {
grpc_fd_orphan(tcp->em_fd, tcp->release_fd_cb, tcp->release_fd,
"tcp_unref_orphan");
grpc_slice_buffer_destroy_internal(&tcp->last_read_buffer);
grpc_slice_allocator_destroy(tcp->slice_allocator);
/* The lock is not really necessary here, since all refs have been released */
gpr_mu_lock(&tcp->tb_mu);
grpc_core::TracedBuffer::Shutdown(
@ -701,6 +704,8 @@ static void tcp_do_read(grpc_tcp* tcp) {
iov[i].iov_len = GRPC_SLICE_LENGTH(tcp->incoming_buffer->slices[i]);
}
GPR_ASSERT(tcp->incoming_buffer->length != 0);
do {
/* Assume there is something on the queue. If we receive TCP_INQ from
* kernel, we will update this value, otherwise, we have to assume there is
@ -787,7 +792,6 @@ static void tcp_do_read(grpc_tcp* tcp) {
total_read_bytes += read_bytes;
if (tcp->inq == 0 || total_read_bytes == tcp->incoming_buffer->length) {
/* We have filled incoming_buffer, and we cannot read any more. */
break;
}
@ -827,36 +831,25 @@ static void tcp_do_read(grpc_tcp* tcp) {
TCP_UNREF(tcp, "read");
}
static void tcp_read_allocation_done(void* tcpp, grpc_error_handle error) {
grpc_tcp* tcp = static_cast<grpc_tcp*>(tcpp);
if (GRPC_TRACE_FLAG_ENABLED(grpc_tcp_trace)) {
gpr_log(GPR_INFO, "TCP:%p read_allocation_done: %s", tcp,
grpc_error_std_string(error).c_str());
}
if (GPR_UNLIKELY(error != GRPC_ERROR_NONE)) {
grpc_slice_buffer_reset_and_unref_internal(tcp->incoming_buffer);
grpc_slice_buffer_reset_and_unref_internal(&tcp->last_read_buffer);
call_read_cb(tcp, GRPC_ERROR_REF(error));
TCP_UNREF(tcp, "read");
} else {
tcp_do_read(tcp);
}
}
static void tcp_continue_read(grpc_tcp* tcp) {
/* Wait for allocation only when there is no buffer left. */
if (tcp->incoming_buffer->length == 0 &&
tcp->incoming_buffer->count < MAX_READ_IOVEC) {
if (GRPC_TRACE_FLAG_ENABLED(grpc_tcp_trace)) {
gpr_log(GPR_INFO, "TCP:%p alloc_slices", tcp);
}
if (GPR_UNLIKELY(!grpc_slice_allocator_allocate(
tcp->slice_allocator, tcp->target_length, 1,
grpc_slice_allocator_intent::kReadBuffer, tcp->incoming_buffer,
tcp_read_allocation_done, tcp))) {
// Wait for allocation.
return;
}
gpr_log(GPR_INFO,
"TCP:%p alloc_slices; min_chunk=%d max_chunk=%d target=%lf "
"buf_len=%" PRIdPTR,
tcp, tcp->min_read_chunk_size, tcp->max_read_chunk_size,
tcp->target_length, tcp->incoming_buffer->length);
}
int target_length = static_cast<int>(tcp->target_length);
int extra_wanted =
target_length - static_cast<int>(tcp->incoming_buffer->length);
grpc_slice_buffer_add_indexed(
tcp->incoming_buffer,
tcp->memory_owner.MakeSlice(grpc_core::MemoryRequest(
tcp->min_read_chunk_size,
grpc_core::Clamp(extra_wanted, tcp->min_read_chunk_size,
tcp->max_read_chunk_size))));
}
if (GRPC_TRACE_FLAG_ENABLED(grpc_tcp_trace)) {
gpr_log(GPR_INFO, "TCP:%p do_read", tcp);
@ -1669,8 +1662,7 @@ static const grpc_endpoint_vtable vtable = {tcp_read,
grpc_endpoint* grpc_tcp_create(grpc_fd* em_fd,
const grpc_channel_args* channel_args,
absl::string_view peer_string,
grpc_slice_allocator* slice_allocator) {
absl::string_view peer_string) {
static constexpr bool kZerocpTxEnabledDefault = false;
int tcp_read_chunk_size = GRPC_TCP_DEFAULT_READ_SLICE_SIZE;
int tcp_max_read_chunk_size = 4 * 1024 * 1024;
@ -1729,7 +1721,10 @@ grpc_endpoint* grpc_tcp_create(grpc_fd* em_fd,
tcp->base.vtable = &vtable;
tcp->peer_string = std::string(peer_string);
tcp->fd = grpc_fd_wrapped_fd(em_fd);
tcp->slice_allocator = slice_allocator;
tcp->memory_owner = grpc_core::ResourceQuotaFromChannelArgs(channel_args)
->memory_quota()
->CreateMemoryOwner(peer_string);
tcp->self_reservation = tcp->memory_owner.MakeReservation(sizeof(grpc_tcp));
grpc_resolved_address resolved_local_addr;
memset(&resolved_local_addr, 0, sizeof(resolved_local_addr));
resolved_local_addr.len = sizeof(resolved_local_addr.addr);

@ -36,15 +36,13 @@
#include "src/core/lib/iomgr/endpoint.h"
#include "src/core/lib/iomgr/ev_posix.h"
#include "src/core/lib/iomgr/port.h"
#include "src/core/lib/iomgr/resource_quota.h"
extern grpc_core::TraceFlag grpc_tcp_trace;
/// Create a tcp endpoint given a file desciptor and a read slice size.
/// Takes ownership of \a fd. Takes ownership of the \a slice_allocator.
grpc_endpoint* grpc_tcp_create(grpc_fd* fd, const grpc_channel_args* args,
absl::string_view peer_string,
grpc_slice_allocator* slice_allocator);
absl::string_view peer_string);
/// Return the tcp endpoint's fd, or -1 if this is not available. Does not
/// release the fd. Requires: \a ep must be a tcp endpoint.

@ -22,12 +22,10 @@
grpc_tcp_server_vtable* grpc_tcp_server_impl;
grpc_error_handle grpc_tcp_server_create(
grpc_closure* shutdown_complete, const grpc_channel_args* args,
grpc_slice_allocator_factory* slice_allocator_factory,
grpc_error_handle grpc_tcp_server_create(grpc_closure* shutdown_complete,
const grpc_channel_args* args,
grpc_tcp_server** server) {
return grpc_tcp_server_impl->create(shutdown_complete, args,
slice_allocator_factory, server);
return grpc_tcp_server_impl->create(shutdown_complete, args, server);
}
void grpc_tcp_server_start(grpc_tcp_server* server,

@ -63,9 +63,8 @@ class TcpServerFdHandler {
} // namespace grpc_core
typedef struct grpc_tcp_server_vtable {
grpc_error_handle (*create)(
grpc_closure* shutdown_complete, const grpc_channel_args* args,
grpc_slice_allocator_factory* slice_allocator_factory,
grpc_error_handle (*create)(grpc_closure* shutdown_complete,
const grpc_channel_args* args,
grpc_tcp_server** server);
void (*start)(grpc_tcp_server* server,
const std::vector<grpc_pollset*>* pollsets,
@ -87,9 +86,8 @@ typedef struct grpc_tcp_server_vtable {
If shutdown_complete is not NULL, it will be used by
grpc_tcp_server_unref() when the ref count reaches zero.
Takes ownership of the slice_allocator_factory. */
grpc_error_handle grpc_tcp_server_create(
grpc_closure* shutdown_complete, const grpc_channel_args* args,
grpc_slice_allocator_factory* slice_allocator_factory,
grpc_error_handle grpc_tcp_server_create(grpc_closure* shutdown_complete,
const grpc_channel_args* args,
grpc_tcp_server** server);
/* Start listening to bound ports */

@ -76,16 +76,12 @@ struct grpc_tcp_server {
bool shutdown;
bool so_reuseport;
grpc_slice_allocator_factory* slice_allocator_factory;
};
static grpc_error_handle tcp_server_create(
grpc_closure* shutdown_complete, const grpc_channel_args* args,
grpc_slice_allocator_factory* slice_allocator_factory,
static grpc_error_handle tcp_server_create(grpc_closure* shutdown_complete,
const grpc_channel_args* args,
grpc_tcp_server** server) {
grpc_tcp_server* s =
static_cast<grpc_tcp_server*>(gpr_malloc(sizeof(grpc_tcp_server)));
grpc_tcp_server* s = new grpc_tcp_server();
s->so_reuseport =
grpc_channel_args_find_bool(args, GRPC_ARG_ALLOW_REUSEPORT, true);
gpr_ref_init(&s->refs, 1);
@ -98,7 +94,6 @@ static grpc_error_handle tcp_server_create(
s->shutdown_starting.tail = nullptr;
s->shutdown_complete = shutdown_complete;
s->shutdown = false;
s->slice_allocator_factory = slice_allocator_factory;
*server = s;
return GRPC_ERROR_NONE;
}
@ -128,7 +123,6 @@ static void finish_shutdown(grpc_tcp_server* s) {
sp->next = nullptr;
gpr_free(sp);
}
grpc_slice_allocator_factory_destroy(s->slice_allocator_factory);
gpr_free(s);
}
@ -219,11 +213,7 @@ static void finish_accept(grpc_tcp_listener* sp, grpc_custom_socket* socket) {
gpr_log(GPR_INFO, "SERVER_CONNECT: %p accepted connection: %s", sp->server,
peer_name_string.c_str());
}
ep = custom_tcp_endpoint_create(
socket,
grpc_slice_allocator_factory_create_slice_allocator(
sp->server->slice_allocator_factory, peer_name_string),
peer_name_string.c_str());
ep = custom_tcp_endpoint_create(socket, peer_name_string.c_str());
acceptor->from_server = sp->server;
acceptor->port_index = sp->port_index;
acceptor->fd_index = 0;

@ -59,12 +59,12 @@
#include "src/core/lib/iomgr/tcp_server.h"
#include "src/core/lib/iomgr/tcp_server_utils_posix.h"
#include "src/core/lib/iomgr/unix_sockets_posix.h"
#include "src/core/lib/resource_quota/api.h"
static grpc_error_handle tcp_server_create(
grpc_closure* shutdown_complete, const grpc_channel_args* args,
grpc_slice_allocator_factory* slice_allocator_factory,
static grpc_error_handle tcp_server_create(grpc_closure* shutdown_complete,
const grpc_channel_args* args,
grpc_tcp_server** server) {
grpc_tcp_server* s = grpc_core::Zalloc<grpc_tcp_server>();
grpc_tcp_server* s = new grpc_tcp_server;
s->so_reuseport = grpc_is_socket_reuse_port_supported();
s->expand_wildcard_addrs = false;
for (size_t i = 0; i < (args == nullptr ? 0 : args->num_args); i++) {
@ -74,7 +74,6 @@ static grpc_error_handle tcp_server_create(
(args->args[i].value.integer != 0);
} else {
gpr_free(s);
grpc_slice_allocator_factory_destroy(slice_allocator_factory);
return GRPC_ERROR_CREATE_FROM_STATIC_STRING(GRPC_ARG_ALLOW_REUSEPORT
" must be an integer");
}
@ -83,7 +82,6 @@ static grpc_error_handle tcp_server_create(
s->expand_wildcard_addrs = (args->args[i].value.integer != 0);
} else {
gpr_free(s);
grpc_slice_allocator_factory_destroy(slice_allocator_factory);
return GRPC_ERROR_CREATE_FROM_STATIC_STRING(
GRPC_ARG_EXPAND_WILDCARD_ADDRS " must be an integer");
}
@ -104,7 +102,8 @@ static grpc_error_handle tcp_server_create(
s->nports = 0;
s->channel_args = grpc_channel_args_copy(args);
s->fd_handler = nullptr;
s->slice_allocator_factory = slice_allocator_factory;
s->memory_quota =
grpc_core::ResourceQuotaFromChannelArgs(args)->memory_quota();
gpr_atm_no_barrier_store(&s->next_pollset_to_assign, 0);
*server = s;
return GRPC_ERROR_NONE;
@ -124,10 +123,9 @@ static void finish_shutdown(grpc_tcp_server* s) {
s->head = sp->next;
gpr_free(sp);
}
grpc_slice_allocator_factory_destroy(s->slice_allocator_factory);
grpc_channel_args_destroy(s->channel_args);
delete s->fd_handler;
gpr_free(s);
delete s;
}
static void destroyed_port(void* server, grpc_error_handle /*error*/) {
@ -222,6 +220,12 @@ static void on_read(void* arg, grpc_error_handle err) {
}
}
if (sp->server->memory_quota->IsMemoryPressureHigh()) {
gpr_log(GPR_INFO, "Drop incoming connection: high memory pressure");
close(fd);
continue;
}
/* For UNIX sockets, the accept call might not fill up the member sun_path
* of sockaddr_un, so explicitly call getsockname to get it. */
if (grpc_is_unix_socket(&addr)) {
@ -268,11 +272,7 @@ static void on_read(void* arg, grpc_error_handle err) {
acceptor->external_connection = false;
sp->server->on_accept_cb(
sp->server->on_accept_cb_arg,
grpc_tcp_create(fdobj, sp->server->channel_args, addr_str,
grpc_slice_allocator_factory_create_slice_allocator(
sp->server->slice_allocator_factory,
absl::StrCat("tcp_server_posix:", addr_str),
sp->server->channel_args)),
grpc_tcp_create(fdobj, sp->server->channel_args, addr_str),
read_notifier_pollset, acceptor);
}
@ -615,12 +615,8 @@ class ExternalConnectionHandler : public grpc_core::TcpServerFdHandler {
acceptor->external_connection = true;
acceptor->listener_fd = listener_fd;
acceptor->pending_data = buf;
s_->on_accept_cb(
s_->on_accept_cb_arg,
grpc_tcp_create(
fdobj, s_->channel_args, addr_str,
grpc_slice_allocator_factory_create_slice_allocator(
s_->slice_allocator_factory, addr_str, s_->channel_args)),
s_->on_accept_cb(s_->on_accept_cb_arg,
grpc_tcp_create(fdobj, s_->channel_args, addr_str),
read_notifier_pollset, acceptor);
}

@ -25,6 +25,7 @@
#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"
#include "src/core/lib/resource_quota/memory_quota.h"
/* one listening port */
typedef struct grpc_tcp_listener {
@ -52,51 +53,51 @@ typedef struct grpc_tcp_listener {
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;
grpc_tcp_server_cb on_accept_cb = nullptr;
void* on_accept_cb_arg = nullptr;
gpr_mu mu;
/* active port count: how many ports are actually still listening */
size_t active_ports;
size_t active_ports = 0;
/* destroyed port count: how many ports are completely destroyed */
size_t destroyed_ports;
size_t destroyed_ports = 0;
/* is this server shutting down? */
bool shutdown;
bool shutdown = false;
/* have listeners been shutdown? */
bool shutdown_listeners;
bool shutdown_listeners = false;
/* use SO_REUSEPORT */
bool so_reuseport;
bool so_reuseport = false;
/* expand wildcard addresses to a list of all local addresses */
bool expand_wildcard_addrs;
bool expand_wildcard_addrs = false;
/* linked list of server ports */
grpc_tcp_listener* head;
grpc_tcp_listener* tail;
unsigned nports;
grpc_tcp_listener* head = nullptr;
grpc_tcp_listener* tail = nullptr;
unsigned nports = 0;
/* List of closures passed to shutdown_starting_add(). */
grpc_closure_list shutdown_starting;
grpc_closure_list shutdown_starting{nullptr, nullptr};
/* shutdown callback */
grpc_closure* shutdown_complete;
grpc_closure* shutdown_complete = nullptr;
/* all pollsets interested in new connections. The object pointed at is not
* owned by this struct */
const std::vector<grpc_pollset*>* pollsets;
const std::vector<grpc_pollset*>* pollsets = nullptr;
/* next pollset to assign a channel to */
gpr_atm next_pollset_to_assign;
gpr_atm next_pollset_to_assign = 0;
/* channel args for this server */
grpc_channel_args* channel_args;
grpc_channel_args* channel_args = nullptr;
/* a handler for external connections, owned */
grpc_core::TcpServerFdHandler* fd_handler;
grpc_core::TcpServerFdHandler* fd_handler = nullptr;
/* used to create slice allocators for endpoints, owned */
grpc_slice_allocator_factory* slice_allocator_factory;
grpc_core::MemoryQuotaRefPtr memory_quota;
};
/* If successful, add a listener to \a s for \a addr, set \a dsmode for the

@ -96,14 +96,12 @@ struct grpc_tcp_server {
grpc_closure* shutdown_complete;
grpc_channel_args* channel_args;
grpc_slice_allocator_factory* slice_allocator_factory;
};
/* Public function. Allocates the proper data structures to hold a
grpc_tcp_server. */
static grpc_error_handle tcp_server_create(
grpc_closure* shutdown_complete, const grpc_channel_args* args,
grpc_slice_allocator_factory* slice_allocator_factory,
static grpc_error_handle tcp_server_create(grpc_closure* shutdown_complete,
const grpc_channel_args* args,
grpc_tcp_server** server) {
grpc_tcp_server* s = (grpc_tcp_server*)gpr_malloc(sizeof(grpc_tcp_server));
s->channel_args = grpc_channel_args_copy(args);
@ -117,7 +115,6 @@ static grpc_error_handle tcp_server_create(
s->shutdown_starting.head = NULL;
s->shutdown_starting.tail = NULL;
s->shutdown_complete = shutdown_complete;
s->slice_allocator_factory = slice_allocator_factory;
*server = s;
return GRPC_ERROR_NONE;
}
@ -168,7 +165,6 @@ static void tcp_server_shutdown_starting_add(grpc_tcp_server* s,
static void tcp_server_destroy(grpc_tcp_server* s) {
grpc_tcp_listener* sp;
gpr_mu_lock(&s->mu);
grpc_slice_allocator_factory_destroy(s->slice_allocator_factory);
/* First, shutdown all fd's. This will queue abortion calls for all
of the pending accepts due to the normal operation mechanism. */
if (s->active_ports == 0) {
@ -358,11 +354,8 @@ static void on_accept(void* arg, grpc_error_handle error) {
gpr_free(utf8_message);
}
std::string fd_name = absl::StrCat("tcp_server:", peer_name_string);
ep = grpc_tcp_create(
grpc_winsocket_create(sock, fd_name.c_str()),
sp->server->channel_args, peer_name_string,
grpc_slice_allocator_factory_create_slice_allocator(
sp->server->slice_allocator_factory, peer_name_string));
ep = grpc_tcp_create(grpc_winsocket_create(sock, fd_name.c_str()),
sp->server->channel_args, peer_name_string);
} else {
closesocket(sock);
}

@ -116,8 +116,6 @@ typedef struct grpc_tcp {
grpc_slice_buffer* write_slices;
grpc_slice_buffer* read_slices;
grpc_slice_allocator* slice_allocator;
/* The IO Completion Port runs from another thread. We need some mechanism
to protect ourselves when requesting a shutdown. */
gpr_mu mu;
@ -132,7 +130,6 @@ static void tcp_free(grpc_tcp* tcp) {
grpc_winsocket_destroy(tcp->socket);
gpr_mu_destroy(&tcp->mu);
grpc_slice_buffer_destroy_internal(&tcp->last_read_buffer);
grpc_slice_allocator_destroy(tcp->slice_allocator);
if (tcp->shutting_down) GRPC_ERROR_UNREF(tcp->shutdown_error);
delete tcp;
}
@ -502,8 +499,7 @@ static grpc_endpoint_vtable vtable = {win_read,
grpc_endpoint* grpc_tcp_create(grpc_winsocket* socket,
grpc_channel_args* channel_args,
absl::string_view peer_string,
grpc_slice_allocator* slice_allocator) {
absl::string_view peer_string) {
grpc_tcp* tcp = new grpc_tcp;
memset(tcp, 0, sizeof(grpc_tcp));
tcp->base.vtable = &vtable;
@ -523,7 +519,6 @@ grpc_endpoint* grpc_tcp_create(grpc_winsocket* socket,
}
tcp->peer_string = std::string(peer_string);
grpc_slice_buffer_init(&tcp->last_read_buffer);
tcp->slice_allocator = slice_allocator;
return &tcp->base;
}

@ -42,8 +42,7 @@
*/
grpc_endpoint* grpc_tcp_create(grpc_winsocket* socket,
grpc_channel_args* channel_args,
absl::string_view peer_string,
grpc_slice_allocator* slice_allocator);
absl::string_view peer_string);
grpc_error_handle grpc_tcp_prepare_socket(SOCKET sock);

@ -25,8 +25,7 @@ namespace grpc_core {
///////////////////////////////////////////////////////////////////////////////
// GLOBALS
ABSL_CONST_INIT GPR_THREAD_LOCAL(Activity*) Activity::g_current_activity_ =
nullptr;
GPR_THREAD_LOCAL(Activity*) Activity::g_current_activity_{nullptr};
Waker::Unwakeable Waker::unwakeable_;
///////////////////////////////////////////////////////////////////////////////

@ -0,0 +1,102 @@
// Copyright 2021 gRPC authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include <grpc/support/port_platform.h>
#include "src/core/lib/resource_quota/api.h"
#include <grpc/grpc.h>
#include "src/core/lib/gpr/useful.h"
namespace grpc_core {
ResourceQuotaRefPtr ResourceQuotaFromChannelArgs(
const grpc_channel_args* args) {
return grpc_channel_args_find_pointer<ResourceQuota>(args,
GRPC_ARG_RESOURCE_QUOTA)
->Ref();
}
namespace {
grpc_arg MakeArg(ResourceQuota* quota) {
return grpc_channel_arg_pointer_create(
const_cast<char*>(GRPC_ARG_RESOURCE_QUOTA), quota,
grpc_resource_quota_arg_vtable());
}
} // namespace
grpc_channel_args* EnsureResourceQuotaInChannelArgs(
const grpc_channel_args* args) {
if (grpc_channel_args_find(args, GRPC_ARG_RESOURCE_QUOTA) != nullptr) {
return grpc_channel_args_copy(args);
}
// If there's no existing quota, add it to the default one - shared between
// all channel args declared thusly. This prevents us from accidentally not
// sharing subchannels due to their channel args not specifying a quota.
auto new_arg = MakeArg(ResourceQuota::Default().get());
return grpc_channel_args_copy_and_add(args, &new_arg, 1);
}
grpc_channel_args* ChannelArgsWrappingResourceQuota(
ResourceQuotaRefPtr resource_quota) {
auto new_arg = MakeArg(resource_quota.get());
return grpc_channel_args_copy_and_add(nullptr, &new_arg, 1);
}
} // namespace grpc_core
extern "C" const grpc_arg_pointer_vtable* grpc_resource_quota_arg_vtable() {
static const grpc_arg_pointer_vtable vtable = {
// copy
[](void* p) -> void* {
return static_cast<grpc_core::ResourceQuota*>(p)->Ref().release();
},
// destroy
[](void* p) { static_cast<grpc_core::ResourceQuota*>(p)->Unref(); },
// compare
[](void* p, void* q) { return grpc_core::QsortCompare(p, q); }};
return &vtable;
}
extern "C" grpc_resource_quota* grpc_resource_quota_create(const char* name) {
static std::atomic<uintptr_t> anonymous_counter{0};
std::string quota_name =
name == nullptr
? absl::StrCat("anonymous-quota-", anonymous_counter.fetch_add(1))
: name;
return (new grpc_core::ResourceQuota(std::move(quota_name)))->c_ptr();
}
extern "C" void grpc_resource_quota_ref(grpc_resource_quota* resource_quota) {
grpc_core::ResourceQuota::FromC(resource_quota)->Ref().release();
}
extern "C" void grpc_resource_quota_unref(grpc_resource_quota* resource_quota) {
grpc_core::ResourceQuota::FromC(resource_quota)->Unref();
}
extern "C" void grpc_resource_quota_resize(grpc_resource_quota* resource_quota,
size_t new_size) {
grpc_core::ResourceQuota::FromC(resource_quota)
->memory_quota()
->SetSize(new_size);
}
extern "C" void grpc_resource_quota_set_max_threads(
grpc_resource_quota* resource_quota, int new_max_threads) {
grpc_core::ResourceQuota::FromC(resource_quota)
->thread_quota()
->SetMax(new_max_threads);
}

@ -0,0 +1,52 @@
// Copyright 2021 gRPC authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef GRPC_CORE_LIB_RESOURCE_QUOTA_API_H
#define GRPC_CORE_LIB_RESOURCE_QUOTA_API_H
#include <grpc/support/port_platform.h>
#include "src/core/lib/channel/channel_args.h"
#include "src/core/lib/resource_quota/resource_quota.h"
typedef struct grpc_resource_quota grpc_resource_quota;
namespace grpc_core {
// TODO(ctiller): This is a hack. We need to do real accounting instead of
// hard coding.
constexpr size_t kResourceQuotaCallSize = 15 * 1024;
constexpr size_t kResourceQuotaChannelSize = 50 * 1024;
// Retrieve the resource quota from the channel args.
// UB if not set.
ResourceQuotaRefPtr ResourceQuotaFromChannelArgs(const grpc_channel_args* args);
// Take some channel args:
// If there is a resource quota set, copy args and return that.
// If there is no resource quota set, set a default, and return new
// channel args. Call grpc_channel_args_destroy on the input args.
grpc_channel_args* EnsureResourceQuotaInChannelArgs(
const grpc_channel_args* args);
// Create channel args with just the passed in resource quota
grpc_channel_args* ChannelArgsWrappingResourceQuota(ResourceQuotaRefPtr);
inline ResourceQuota* ResourceQuotaFromC(grpc_resource_quota* quota) {
return reinterpret_cast<ResourceQuota*>(quota);
}
} // namespace grpc_core
#endif // GRPC_CORE_LIB_RESOURCE_QUOTA_API_H

@ -19,8 +19,10 @@
#include "src/core/lib/gpr/useful.h"
#include "src/core/lib/promise/exec_ctx_wakeup_scheduler.h"
#include "src/core/lib/promise/loop.h"
#include "src/core/lib/promise/map.h"
#include "src/core/lib/promise/race.h"
#include "src/core/lib/promise/seq.h"
#include "src/core/lib/resource_quota/trace.h"
namespace grpc_core {
@ -104,8 +106,8 @@ Poll<ReclamationFunction> ReclaimerQueue::PollNext() {
//
GrpcMemoryAllocatorImpl::GrpcMemoryAllocatorImpl(
std::shared_ptr<BasicMemoryQuota> memory_quota)
: memory_quota_(memory_quota) {
std::shared_ptr<BasicMemoryQuota> memory_quota, std::string name)
: memory_quota_(memory_quota), name_(std::move(name)) {
memory_quota_->Take(taken_bytes_);
}
@ -157,9 +159,14 @@ absl::optional<size_t> GrpcMemoryAllocatorImpl::TryReserve(
// flexibility.
if (scaled_size_over_min != 0) {
double pressure;
size_t max_recommended_allocation_size;
{
MutexLock lock(&memory_quota_mu_);
pressure = memory_quota_->InstantaneousPressure();
const auto pressure_and_max_recommended_allocation_size =
memory_quota_->InstantaneousPressureAndMaxRecommendedAllocationSize();
pressure = pressure_and_max_recommended_allocation_size.first;
max_recommended_allocation_size =
pressure_and_max_recommended_allocation_size.second;
}
// Reduce allocation size proportional to the pressure > 80% usage.
if (pressure > 0.8) {
@ -168,6 +175,12 @@ absl::optional<size_t> GrpcMemoryAllocatorImpl::TryReserve(
static_cast<size_t>((request.max() - request.min()) *
(1.0 - pressure) / 0.2));
}
if (max_recommended_allocation_size < request.min()) {
scaled_size_over_min = 0;
} else if (request.min() + scaled_size_over_min >
max_recommended_allocation_size) {
scaled_size_over_min = max_recommended_allocation_size - request.min();
}
}
// How much do we want to reserve?
@ -279,8 +292,7 @@ void GrpcMemoryAllocatorImpl::PostReclaimer(ReclamationPass pass,
//
void MemoryOwner::Rebind(MemoryQuota* quota) {
static_cast<GrpcMemoryAllocatorImpl*>(allocator_.get_internal_impl_ptr())
->Rebind(quota->memory_quota_);
impl()->Rebind(quota->memory_quota_);
}
//
@ -327,10 +339,22 @@ void BasicMemoryQuota::Start() {
// Race biases to the first thing that completes... so this will
// choose the highest priority/least destructive thing to do that's
// available.
return Race(self->reclaimers_[0].Next(), self->reclaimers_[1].Next(),
self->reclaimers_[2].Next(), self->reclaimers_[3].Next());
auto annotate = [](const char* name) {
return [name](ReclamationFunction f) {
return std::make_tuple(name, std::move(f));
};
};
return Race(Map(self->reclaimers_[0].Next(), annotate("compact")),
Map(self->reclaimers_[1].Next(), annotate("benign")),
Map(self->reclaimers_[2].Next(), annotate("idle")),
Map(self->reclaimers_[3].Next(), annotate("destructive")));
},
[self](ReclamationFunction reclaimer) {
[self](std::tuple<const char*, ReclamationFunction> arg) {
auto reclaimer = std::move(std::get<1>(arg));
if (GRPC_TRACE_FLAG_ENABLED(grpc_resource_quota_trace)) {
gpr_log(GPR_INFO, "RQ: %s perform %s reclamation",
self->name_.c_str(), std::get<0>(arg));
}
// One of the reclaimer queues gave us a way to get back memory.
// Call the reclaimer with a token that contains enough to wake us
// up again.
@ -386,6 +410,9 @@ void BasicMemoryQuota::FinishReclamation(uint64_t token) {
if (reclamation_counter_.compare_exchange_strong(current, current + 1,
std::memory_order_relaxed,
std::memory_order_relaxed)) {
if (GRPC_TRACE_FLAG_ENABLED(grpc_resource_quota_trace)) {
gpr_log(GPR_INFO, "RQ: %s reclamation complete", name_.c_str());
}
if (reclaimer_activity_ != nullptr) reclaimer_activity_->ForceWakeup();
}
}
@ -394,15 +421,33 @@ void BasicMemoryQuota::Return(size_t amount) {
free_bytes_.fetch_add(amount, std::memory_order_relaxed);
}
size_t BasicMemoryQuota::InstantaneousPressure() const {
std::pair<double, size_t>
BasicMemoryQuota::InstantaneousPressureAndMaxRecommendedAllocationSize() const {
double free = free_bytes_.load();
if (free < 0) free = 0;
double size = quota_size_.load();
if (size < 1) return 1.0;
size_t quota_size = quota_size_.load();
double size = quota_size;
if (size < 1) return std::make_pair(1.0, 1);
double pressure = (size - free) / size;
if (pressure < 0.0) pressure = 0.0;
if (pressure > 1.0) pressure = 1.0;
return pressure;
return std::make_pair(pressure, quota_size / 16);
}
//
// MemoryQuota
//
MemoryAllocator MemoryQuota::CreateMemoryAllocator(absl::string_view name) {
auto impl = std::make_shared<GrpcMemoryAllocatorImpl>(
memory_quota_, absl::StrCat(memory_quota_->name(), "/allocator/", name));
return MemoryAllocator(std::move(impl));
}
MemoryOwner MemoryQuota::CreateMemoryOwner(absl::string_view name) {
auto impl = std::make_shared<GrpcMemoryAllocatorImpl>(
memory_quota_, absl::StrCat(memory_quota_->name(), "/owner/", name));
return MemoryOwner(std::move(impl));
}
} // namespace grpc_core

@ -27,6 +27,7 @@
#include <grpc/event_engine/memory_allocator.h>
#include <grpc/slice.h>
#include "src/core/lib/gprpp/orphanable.h"
#include "src/core/lib/gprpp/sync.h"
#include "src/core/lib/promise/activity.h"
#include "src/core/lib/promise/poll.h"
@ -77,6 +78,7 @@ static constexpr size_t kNumReclamationPasses = 4;
// then that reclamation is complete and we may continue the reclamation loop.
class ReclamationSweep {
public:
ReclamationSweep() = default;
ReclamationSweep(std::shared_ptr<BasicMemoryQuota> memory_quota,
uint64_t sweep_token)
: memory_quota_(std::move(memory_quota)), sweep_token_(sweep_token) {}
@ -94,6 +96,13 @@ class ReclamationSweep {
// work item.
bool IsSufficient() const;
// Explicit finish for users that wish to write it.
// Just destroying the object is enough, but sometimes the additional
// explicitness is warranted.
void Finish() {
[](ReclamationSweep) {}(std::move(*this));
}
private:
std::shared_ptr<BasicMemoryQuota> memory_quota_;
uint64_t sweep_token_;
@ -170,6 +179,8 @@ class ReclaimerQueue {
class BasicMemoryQuota final
: public std::enable_shared_from_this<BasicMemoryQuota> {
public:
explicit BasicMemoryQuota(std::string name) : name_(std::move(name)) {}
// Start the reclamation activity.
void Start();
// Stop the reclamation activity.
@ -188,7 +199,8 @@ class BasicMemoryQuota final
// Return some memory to the quota.
void Return(size_t amount);
// Instantaneous memory pressure approximation.
size_t InstantaneousPressure() const;
std::pair<double, size_t>
InstantaneousPressureAndMaxRecommendedAllocationSize() const;
// Cancel a reclaimer
ReclamationFunction CancelReclaimer(
size_t reclaimer, typename ReclaimerQueue::Index index,
@ -203,6 +215,9 @@ class BasicMemoryQuota final
reclaimers_[reclaimer].Insert(std::move(allocator), std::move(fn), index);
}
// The name of this quota
absl::string_view name() const { return name_; }
private:
friend class ReclamationSweep;
class WaitForSweepPromise;
@ -228,6 +243,8 @@ class BasicMemoryQuota final
// We also increment this counter on completion of a sweep, as an indicator
// that the wait has ended.
std::atomic<uint64_t> reclamation_counter_{0};
// The name of this quota - used for debugging/tracing/etc..
std::string name_;
};
// MemoryAllocatorImpl grants the owner the ability to allocate memory from an
@ -235,7 +252,7 @@ class BasicMemoryQuota final
class GrpcMemoryAllocatorImpl final : public EventEngineMemoryAllocatorImpl {
public:
explicit GrpcMemoryAllocatorImpl(
std::shared_ptr<BasicMemoryQuota> memory_quota);
std::shared_ptr<BasicMemoryQuota> memory_quota, std::string name);
~GrpcMemoryAllocatorImpl() override;
// Rebind - Swaps the underlying quota for this allocator, taking care to
@ -263,6 +280,16 @@ class GrpcMemoryAllocatorImpl final : public EventEngineMemoryAllocatorImpl {
// Shutdown the allocator.
void Shutdown() override;
// Read the instantaneous memory pressure
double InstantaneousPressure() const {
MutexLock lock(&memory_quota_mu_);
return memory_quota_->InstantaneousPressureAndMaxRecommendedAllocationSize()
.first;
}
// Name of this allocator
absl::string_view name() const { return name_; }
private:
// Primitive reservation function.
absl::optional<size_t> TryReserve(MemoryRequest request) GRPC_MUST_USE_RESULT;
@ -281,7 +308,7 @@ class GrpcMemoryAllocatorImpl final : public EventEngineMemoryAllocatorImpl {
// pressure.
std::atomic<size_t> free_bytes_{0};
// Mutex guarding the backing resource quota.
Mutex memory_quota_mu_;
mutable Mutex memory_quota_mu_;
// Backing resource quota.
std::shared_ptr<BasicMemoryQuota> memory_quota_
ABSL_GUARDED_BY(memory_quota_mu_);
@ -296,35 +323,65 @@ class GrpcMemoryAllocatorImpl final : public EventEngineMemoryAllocatorImpl {
memory_quota_mu_) = {
ReclaimerQueue::kInvalidIndex, ReclaimerQueue::kInvalidIndex,
ReclaimerQueue::kInvalidIndex, ReclaimerQueue::kInvalidIndex};
// Name of this allocator.
std::string name_;
};
// MemoryOwner is an enhanced MemoryAllocator that can also reclaim memory, and
// be rebound to a different memory quota.
class MemoryOwner {
// Different modules should not share a MemoryOwner between themselves, instead
// each module that requires a MemoryOwner should create one from a resource
// quota. This is because the MemoryOwner reclaimers are tied to the
// MemoryOwner's lifetime, and are not queryable, so passing a MemoryOwner to a
// new owning module means that module cannot reason about which reclaimers are
// active, nor what they might do.
class MemoryOwner final : public MemoryAllocator {
public:
explicit MemoryOwner(std::shared_ptr<GrpcMemoryAllocatorImpl> allocator)
: allocator_(std::move(allocator)) {}
MemoryOwner() = default;
MemoryAllocator* allocator() { return &allocator_; }
explicit MemoryOwner(std::shared_ptr<GrpcMemoryAllocatorImpl> allocator)
: MemoryAllocator(std::move(allocator)) {}
// Post a reclaimer for some reclamation pass.
void PostReclaimer(ReclamationPass pass, ReclamationFunction fn) {
static_cast<GrpcMemoryAllocatorImpl*>(allocator_.get_internal_impl_ptr())
->PostReclaimer(pass, std::move(fn));
impl()->PostReclaimer(pass, std::move(fn));
}
// Rebind to a different quota.
void Rebind(MemoryQuota* quota);
// Instantaneous memory pressure in the underlying quota.
double InstantaneousPressure() const {
return impl()->InstantaneousPressure();
}
template <typename T, typename... Args>
OrphanablePtr<T> MakeOrphanable(Args&&... args) {
return OrphanablePtr<T>(New<T>(std::forward<Args>(args)...));
}
// Name of this object
absl::string_view name() const { return impl()->name(); }
// Is this object valid (ie has not been moved out of or reset)
bool is_valid() const { return impl() != nullptr; }
private:
MemoryAllocator allocator_;
const GrpcMemoryAllocatorImpl* impl() const {
return static_cast<const GrpcMemoryAllocatorImpl*>(get_internal_impl_ptr());
}
GrpcMemoryAllocatorImpl* impl() {
return static_cast<GrpcMemoryAllocatorImpl*>(get_internal_impl_ptr());
}
};
// MemoryQuota tracks the amount of memory available as part of a ResourceQuota.
class MemoryQuota final
: public grpc_event_engine::experimental::MemoryAllocatorFactory {
public:
MemoryQuota() : memory_quota_(std::make_shared<BasicMemoryQuota>()) {
explicit MemoryQuota(std::string name)
: memory_quota_(std::make_shared<BasicMemoryQuota>(std::move(name))) {
memory_quota_->Start();
}
~MemoryQuota() override {
@ -336,24 +393,29 @@ class MemoryQuota final
MemoryQuota(MemoryQuota&&) = default;
MemoryQuota& operator=(MemoryQuota&&) = default;
MemoryAllocator CreateMemoryAllocator() override {
auto impl = std::make_shared<GrpcMemoryAllocatorImpl>(memory_quota_);
return MemoryAllocator(std::move(impl));
}
MemoryOwner CreateMemoryOwner() {
auto impl = std::make_shared<GrpcMemoryAllocatorImpl>(memory_quota_);
return MemoryOwner(std::move(impl));
}
MemoryAllocator CreateMemoryAllocator(absl::string_view name) override;
MemoryOwner CreateMemoryOwner(absl::string_view name);
// Resize the quota to new_size.
void SetSize(size_t new_size) { memory_quota_->SetSize(new_size); }
// Return true if the instantaneous memory pressure is high.
bool IsMemoryPressureHigh() const {
static constexpr double kMemoryPressureHighThreshold = 0.9;
return memory_quota_->InstantaneousPressureAndMaxRecommendedAllocationSize()
.first > kMemoryPressureHighThreshold;
}
private:
friend class MemoryOwner;
std::shared_ptr<BasicMemoryQuota> memory_quota_;
};
using MemoryQuotaRefPtr = std::shared_ptr<MemoryQuota>;
inline MemoryQuotaRefPtr MakeMemoryQuota(std::string name) {
return std::make_shared<MemoryQuota>(std::move(name));
}
} // namespace grpc_core
#endif // GRPC_CORE_LIB_RESOURCE_QUOTA_MEMORY_QUOTA_H

@ -18,10 +18,16 @@
namespace grpc_core {
ResourceQuota::ResourceQuota()
: memory_quota_(std::make_shared<MemoryQuota>()),
ResourceQuota::ResourceQuota(std::string name)
: memory_quota_(MakeMemoryQuota(std::move(name))),
thread_quota_(MakeRefCounted<ThreadQuota>()) {}
ResourceQuota::~ResourceQuota() = default;
ResourceQuotaRefPtr ResourceQuota::Default() {
static auto default_resource_quota =
MakeResourceQuota("default_resource_quota").release();
return default_resource_quota->Ref();
}
} // namespace grpc_core

@ -17,28 +17,42 @@
#include <grpc/support/port_platform.h>
#include <grpc/impl/codegen/grpc_types.h>
#include "src/core/lib/gprpp/cpp_impl_of.h"
#include "src/core/lib/resource_quota/memory_quota.h"
#include "src/core/lib/resource_quota/thread_quota.h"
namespace grpc_core {
class ResourceQuota : public RefCounted<ResourceQuota> {
class ResourceQuota;
using ResourceQuotaRefPtr = RefCountedPtr<ResourceQuota>;
class ResourceQuota : public RefCounted<ResourceQuota>,
public CppImplOf<ResourceQuota, grpc_resource_quota> {
public:
ResourceQuota();
explicit ResourceQuota(std::string name);
~ResourceQuota() override;
ResourceQuota(const ResourceQuota&) = delete;
ResourceQuota& operator=(const ResourceQuota&) = delete;
std::shared_ptr<MemoryQuota> memory_quota() { return memory_quota_; }
MemoryQuotaRefPtr memory_quota() { return memory_quota_; }
const RefCountedPtr<ThreadQuota>& thread_quota() { return thread_quota_; }
// The default global resource quota
static ResourceQuotaRefPtr Default();
private:
std::shared_ptr<MemoryQuota> memory_quota_;
MemoryQuotaRefPtr memory_quota_;
RefCountedPtr<ThreadQuota> thread_quota_;
};
inline ResourceQuotaRefPtr MakeResourceQuota(std::string name) {
return MakeRefCounted<ResourceQuota>(std::move(name));
}
} // namespace grpc_core
#endif // GRPC_CORE_LIB_RESOURCE_QUOTA_RESOURCE_QUOTA_H

@ -50,6 +50,8 @@ class ThreadQuota : public RefCounted<ThreadQuota> {
size_t max_ ABSL_GUARDED_BY(mu_) = std::numeric_limits<size_t>::max();
};
using ThreadQuotaPtr = RefCountedPtr<ThreadQuota>;
} // namespace grpc_core
#endif // GRPC_CORE_LIB_RESOURCE_QUOTA_THREAD_QUOTA_H

@ -0,0 +1,19 @@
// Copyright 2021 gRPC authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include <grpc/support/port_platform.h>
#include "src/core/lib/resource_quota/trace.h"
grpc_core::TraceFlag grpc_resource_quota_trace(false, "resource_quota");

@ -1,4 +1,4 @@
// Copyright 2021 The gRPC Authors
// Copyright 2021 gRPC authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
@ -11,14 +11,14 @@
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef GRPC_TEST_CORE_UTIL_RESOURCE_USER_UTIL_H
#define GRPC_TEST_CORE_UTIL_RESOURCE_USER_UTIL_H
#include "src/core/lib/iomgr/resource_quota.h"
#ifndef GRPC_CORE_LIB_RESOURCE_QUOTA_TRACE_H
#define GRPC_CORE_LIB_RESOURCE_QUOTA_TRACE_H
grpc_resource_user* grpc_resource_user_create_unlimited(
grpc_resource_quota* resource_quota = nullptr);
#include <grpc/support/port_platform.h>
grpc_slice_allocator* grpc_slice_allocator_create_unlimited();
#include "src/core/lib/debug/trace.h"
#endif // GRPC_TEST_CORE_UTIL_RESOURCE_USER_UTIL_H
extern grpc_core::TraceFlag grpc_resource_quota_trace;
#endif // GRPC_CORE_LIB_RESOURCE_QUOTA_TRACE_H

@ -166,13 +166,12 @@ void AwsExternalAccountCredentials::RetrieveRegion() {
request.http.path = gpr_strdup(uri->path().c_str());
request.handshaker =
uri->scheme() == "https" ? &grpc_httpcli_ssl : &grpc_httpcli_plaintext;
grpc_resource_quota* resource_quota =
grpc_resource_quota_create("external_account_credentials");
grpc_http_response_destroy(&ctx_->response);
ctx_->response = {};
GRPC_CLOSURE_INIT(&ctx_->closure, OnRetrieveRegion, this, nullptr);
grpc_httpcli_get(ctx_->httpcli_context, ctx_->pollent, resource_quota,
&request, ctx_->deadline, &ctx_->closure, &ctx_->response);
grpc_httpcli_get(ctx_->httpcli_context, ctx_->pollent,
ResourceQuota::Default(), &request, ctx_->deadline,
&ctx_->closure, &ctx_->response);
grpc_http_request_destroy(&request.http);
}
@ -214,13 +213,13 @@ void AwsExternalAccountCredentials::RetrieveRoleName() {
request.http.path = gpr_strdup(uri->path().c_str());
request.handshaker =
uri->scheme() == "https" ? &grpc_httpcli_ssl : &grpc_httpcli_plaintext;
grpc_resource_quota* resource_quota =
grpc_resource_quota_create("external_account_credentials");
grpc_http_response_destroy(&ctx_->response);
ctx_->response = {};
GRPC_CLOSURE_INIT(&ctx_->closure, OnRetrieveRoleName, this, nullptr);
grpc_httpcli_get(ctx_->httpcli_context, ctx_->pollent, resource_quota,
&request, ctx_->deadline, &ctx_->closure, &ctx_->response);
// TODO(ctiller): use the caller's resource quota.
grpc_httpcli_get(ctx_->httpcli_context, ctx_->pollent,
ResourceQuota::Default(), &request, ctx_->deadline,
&ctx_->closure, &ctx_->response);
grpc_http_request_destroy(&request.http);
}
@ -274,13 +273,13 @@ void AwsExternalAccountCredentials::RetrieveSigningKeys() {
request.http.path = gpr_strdup(uri->path().c_str());
request.handshaker =
uri->scheme() == "https" ? &grpc_httpcli_ssl : &grpc_httpcli_plaintext;
grpc_resource_quota* resource_quota =
grpc_resource_quota_create("external_account_credentials");
grpc_http_response_destroy(&ctx_->response);
ctx_->response = {};
GRPC_CLOSURE_INIT(&ctx_->closure, OnRetrieveSigningKeys, this, nullptr);
grpc_httpcli_get(ctx_->httpcli_context, ctx_->pollent, resource_quota,
&request, ctx_->deadline, &ctx_->closure, &ctx_->response);
// TODO(ctiller): use the caller's resource quota.
grpc_httpcli_get(ctx_->httpcli_context, ctx_->pollent,
ResourceQuota::Default(), &request, ctx_->deadline,
&ctx_->closure, &ctx_->response);
grpc_http_request_destroy(&request.http);
}

@ -323,14 +323,13 @@ void ExternalAccountCredentials::ExchangeToken(
body_parts.push_back(absl::StrFormat(
"options=%s", UrlEncode(addtional_options_json.Dump()).c_str()));
std::string body = absl::StrJoin(body_parts, "&");
grpc_resource_quota* resource_quota =
grpc_resource_quota_create("external_account_credentials");
grpc_http_response_destroy(&ctx_->response);
ctx_->response = {};
GRPC_CLOSURE_INIT(&ctx_->closure, OnExchangeToken, this, nullptr);
grpc_httpcli_post(ctx_->httpcli_context, ctx_->pollent, resource_quota,
&request, body.c_str(), body.size(), ctx_->deadline,
&ctx_->closure, &ctx_->response);
grpc_httpcli_post(ctx_->httpcli_context, ctx_->pollent,
ResourceQuota::Default(), &request, body.c_str(),
body.size(), ctx_->deadline, &ctx_->closure,
&ctx_->response);
grpc_http_request_destroy(&request.http);
}
@ -409,14 +408,14 @@ void ExternalAccountCredentials::ImpersenateServiceAccount() {
uri->scheme() == "https" ? &grpc_httpcli_ssl : &grpc_httpcli_plaintext;
std::string scope = absl::StrJoin(scopes_, " ");
std::string body = absl::StrFormat("scope=%s", scope);
grpc_resource_quota* resource_quota =
grpc_resource_quota_create("external_account_credentials");
grpc_http_response_destroy(&ctx_->response);
ctx_->response = {};
GRPC_CLOSURE_INIT(&ctx_->closure, OnImpersenateServiceAccount, this, nullptr);
grpc_httpcli_post(ctx_->httpcli_context, ctx_->pollent, resource_quota,
&request, body.c_str(), body.size(), ctx_->deadline,
&ctx_->closure, &ctx_->response);
// TODO(ctiller): Use the callers resource quota.
grpc_httpcli_post(ctx_->httpcli_context, ctx_->pollent,
ResourceQuota::Default(), &request, body.c_str(),
body.size(), ctx_->deadline, &ctx_->closure,
&ctx_->response);
grpc_http_request_destroy(&request.http);
}

@ -139,13 +139,12 @@ void UrlExternalAccountCredentials::RetrieveSubjectToken(
request.http.hdrs = headers;
request.handshaker =
url_.scheme() == "https" ? &grpc_httpcli_ssl : &grpc_httpcli_plaintext;
grpc_resource_quota* resource_quota =
grpc_resource_quota_create("external_account_credentials");
grpc_http_response_destroy(&ctx_->response);
ctx_->response = {};
GRPC_CLOSURE_INIT(&ctx_->closure, OnRetrieveSubjectToken, this, nullptr);
grpc_httpcli_get(ctx_->httpcli_context, ctx_->pollent, resource_quota,
&request, ctx_->deadline, &ctx_->closure, &ctx_->response);
grpc_httpcli_get(ctx_->httpcli_context, ctx_->pollent,
ResourceQuota::Default(), &request, ctx_->deadline,
&ctx_->closure, &ctx_->response);
grpc_http_request_destroy(&request.http);
}

@ -187,11 +187,9 @@ static int is_metadata_server_reachable() {
request.host = const_cast<char*>(GRPC_COMPUTE_ENGINE_DETECTION_HOST);
request.http.path = const_cast<char*>("/");
grpc_httpcli_context_init(&context);
grpc_resource_quota* resource_quota =
grpc_resource_quota_create("google_default_credentials");
grpc_httpcli_get(
&context, &detector.pollent, resource_quota, &request,
grpc_core::ExecCtx::Get()->Now() + max_detection_delay,
&context, &detector.pollent, grpc_core::ResourceQuota::Default(),
&request, grpc_core::ExecCtx::Get()->Now() + max_detection_delay,
GRPC_CLOSURE_CREATE(on_metadata_server_detection_http_response, &detector,
grpc_schedule_on_exec_ctx),
&detector.response);

@ -671,7 +671,6 @@ static void on_openid_config_retrieved(void* user_data,
Json json = json_from_http(response);
grpc_httpcli_request req;
const char* jwks_uri;
grpc_resource_quota* resource_quota = nullptr;
const Json* cur;
/* TODO(jboeuf): Cache the jwks_uri in order to avoid this hop next time. */
@ -700,9 +699,9 @@ static void on_openid_config_retrieved(void* user_data,
/* TODO(ctiller): Carry the resource_quota in ctx and share it with the host
channel. This would allow us to cancel an authentication query when under
extreme memory pressure. */
resource_quota = grpc_resource_quota_create("jwt_verifier");
grpc_httpcli_get(
&ctx->verifier->http_ctx, &ctx->pollent, resource_quota, &req,
&ctx->verifier->http_ctx, &ctx->pollent,
grpc_core::ResourceQuota::Default(), &req,
grpc_core::ExecCtx::Get()->Now() + grpc_jwt_verifier_max_delay,
GRPC_CLOSURE_CREATE(on_keys_retrieved, ctx, grpc_schedule_on_exec_ctx),
&ctx->responses[HTTP_RESPONSE_KEYS]);
@ -765,7 +764,6 @@ static void retrieve_key_and_verify(verifier_cb_ctx* ctx) {
char* path_prefix = nullptr;
const char* iss;
grpc_httpcli_request req;
grpc_resource_quota* resource_quota = nullptr;
memset(&req, 0, sizeof(grpc_httpcli_request));
req.handshaker = &grpc_httpcli_ssl;
http_response_index rsp_idx;
@ -825,9 +823,9 @@ static void retrieve_key_and_verify(verifier_cb_ctx* ctx) {
/* TODO(ctiller): Carry the resource_quota in ctx and share it with the host
channel. This would allow us to cancel an authentication query when under
extreme memory pressure. */
resource_quota = grpc_resource_quota_create("jwt_verifier");
grpc_httpcli_get(
&ctx->verifier->http_ctx, &ctx->pollent, resource_quota, &req,
&ctx->verifier->http_ctx, &ctx->pollent,
grpc_core::ResourceQuota::Default(), &req,
grpc_core::ExecCtx::Get()->Now() + grpc_jwt_verifier_max_delay, http_cb,
&ctx->responses[rsp_idx]);
gpr_free(req.host);

@ -392,12 +392,11 @@ class grpc_compute_engine_token_fetcher_credentials
const_cast<char*>(GRPC_COMPUTE_ENGINE_METADATA_TOKEN_PATH);
request.http.hdr_count = 1;
request.http.hdrs = &header;
/* TODO(ctiller): Carry the resource_quota in ctx and share it with the host
/* TODO(ctiller): Carry the memory quota in ctx and share it with the host
channel. This would allow us to cancel an authentication query when under
extreme memory pressure. */
grpc_resource_quota* resource_quota =
grpc_resource_quota_create("oauth2_credentials");
grpc_httpcli_get(http_context, pollent, resource_quota, &request, deadline,
grpc_httpcli_get(http_context, pollent, grpc_core::ResourceQuota::Default(),
&request, deadline,
GRPC_CLOSURE_INIT(&http_get_cb_closure_, response_cb,
metadata_req, grpc_schedule_on_exec_ctx),
&metadata_req->response);
@ -451,13 +450,12 @@ void grpc_google_refresh_token_credentials::fetch_oauth2(
request.http.hdr_count = 1;
request.http.hdrs = &header;
request.handshaker = &grpc_httpcli_ssl;
/* TODO(ctiller): Carry the resource_quota in ctx and share it with the host
/* TODO(ctiller): Carry the memory quota in ctx and share it with the host
channel. This would allow us to cancel an authentication query when under
extreme memory pressure. */
grpc_resource_quota* resource_quota =
grpc_resource_quota_create("oauth2_credentials_refresh");
grpc_httpcli_post(httpcli_context, pollent, resource_quota, &request,
body.c_str(), body.size(), deadline,
grpc_httpcli_post(httpcli_context, pollent,
grpc_core::ResourceQuota::Default(), &request, body.c_str(),
body.size(), deadline,
GRPC_CLOSURE_INIT(&http_post_cb_closure_, response_cb,
metadata_req, grpc_schedule_on_exec_ctx),
&metadata_req->response);
@ -582,14 +580,12 @@ class StsTokenFetcherCredentials
request.handshaker = (sts_url_.scheme() == "https")
? &grpc_httpcli_ssl
: &grpc_httpcli_plaintext;
/* TODO(ctiller): Carry the resource_quota in ctx and share it with the host
/* TODO(ctiller): Carry the memory quota in ctx and share it with the host
channel. This would allow us to cancel an authentication query when under
extreme memory pressure. */
grpc_resource_quota* resource_quota =
grpc_resource_quota_create("oauth2_credentials_refresh");
grpc_httpcli_post(
http_context, pollent, resource_quota, &request, body, body_length,
deadline,
http_context, pollent, grpc_core::ResourceQuota::Default(), &request,
body, body_length, deadline,
GRPC_CLOSURE_INIT(&http_post_cb_closure_, response_cb, metadata_req,
grpc_schedule_on_exec_ctx),
&metadata_req->response);

@ -41,7 +41,7 @@
#include "src/core/lib/gprpp/memory.h"
#include "src/core/lib/gprpp/ref_counted_ptr.h"
#include "src/core/lib/iomgr/iomgr.h"
#include "src/core/lib/iomgr/resource_quota.h"
#include "src/core/lib/resource_quota/memory_quota.h"
#include "src/core/lib/slice/slice_internal.h"
#include "src/core/lib/surface/api_trace.h"
#include "src/core/lib/surface/call.h"
@ -58,9 +58,7 @@ static void destroy_channel(void* arg, grpc_error_handle error);
grpc_channel* grpc_channel_create_with_builder(
grpc_channel_stack_builder* builder,
grpc_channel_stack_type channel_stack_type,
grpc_resource_user* resource_user, size_t preallocated_bytes,
grpc_error_handle* error) {
grpc_channel_stack_type channel_stack_type, grpc_error_handle* error) {
char* target = gpr_strdup(grpc_channel_stack_builder_get_target(builder));
grpc_channel_args* args = grpc_channel_args_copy(
grpc_channel_stack_builder_get_channel_arguments(builder));
@ -84,17 +82,9 @@ grpc_channel* grpc_channel_create_with_builder(
}
gpr_free(target);
grpc_channel_args_destroy(args);
if (resource_user != nullptr) {
if (preallocated_bytes > 0) {
grpc_resource_user_free(resource_user, preallocated_bytes);
}
grpc_resource_user_unref(resource_user);
}
return nullptr;
}
channel->target = target;
channel->resource_user = resource_user;
channel->preallocated_bytes = preallocated_bytes;
channel->is_client = grpc_channel_stack_type_is_client(channel_stack_type);
channel->registration_table.Init();
@ -233,8 +223,6 @@ grpc_channel* grpc_channel_create(const char* target,
const grpc_channel_args* input_args,
grpc_channel_stack_type channel_stack_type,
grpc_transport* optional_transport,
grpc_resource_user* resource_user,
size_t preallocated_bytes,
grpc_error_handle* error) {
// We need to make sure that grpc_shutdown() does not shut things down
// until after the channel is destroyed. However, the channel may not
@ -272,12 +260,6 @@ grpc_channel* grpc_channel_create(const char* target,
if (!grpc_core::CoreConfiguration::Get().channel_init().CreateStack(
builder, channel_stack_type)) {
grpc_channel_stack_builder_destroy(builder);
if (resource_user != nullptr) {
if (preallocated_bytes > 0) {
grpc_resource_user_free(resource_user, preallocated_bytes);
}
grpc_resource_user_unref(resource_user);
}
grpc_shutdown(); // Since we won't call destroy_channel().
return nullptr;
}
@ -286,8 +268,8 @@ grpc_channel* grpc_channel_create(const char* target,
if (grpc_channel_stack_type_is_client(channel_stack_type)) {
CreateChannelzNode(builder);
}
grpc_channel* channel = grpc_channel_create_with_builder(
builder, channel_stack_type, resource_user, preallocated_bytes, error);
grpc_channel* channel =
grpc_channel_create_with_builder(builder, channel_stack_type, error);
if (channel == nullptr) {
grpc_shutdown(); // Since we won't call destroy_channel().
}
@ -504,13 +486,6 @@ static void destroy_channel(void* arg, grpc_error_handle /*error*/) {
}
grpc_channel_stack_destroy(CHANNEL_STACK_FROM_CHANNEL(channel));
channel->registration_table.Destroy();
if (channel->resource_user != nullptr) {
if (channel->preallocated_bytes > 0) {
grpc_resource_user_free(channel->resource_user,
channel->preallocated_bytes);
}
grpc_resource_user_unref(channel->resource_user);
}
gpr_free(channel->target);
gpr_free(channel);
// See comment in grpc_channel_create() for why we do this.

@ -27,22 +27,15 @@
#include "src/core/lib/channel/channel_stack_builder.h"
#include "src/core/lib/channel/channelz.h"
#include "src/core/lib/gprpp/manual_constructor.h"
#include "src/core/lib/resource_quota/memory_quota.h"
#include "src/core/lib/surface/channel_stack_type.h"
#include "src/core/lib/transport/metadata.h"
/// Creates a grpc_channel.
///
/// If the \a resource_user is not null, \a preallocated_bytes may have been
/// allocated on that resource_user for use by the channel. These bytes will be
/// freed from the resource_user upon channel destruction.
///
/// Takes ownership of a \a resource_user ref.
grpc_channel* grpc_channel_create(const char* target,
const grpc_channel_args* args,
grpc_channel_stack_type channel_stack_type,
grpc_transport* optional_transport,
grpc_resource_user* resource_user,
size_t preallocated_bytes,
grpc_error_handle* error);
/** The same as grpc_channel_destroy, but doesn't create an ExecCtx, and so
@ -54,7 +47,6 @@ void grpc_channel_destroy_internal(grpc_channel* channel);
grpc_channel* grpc_channel_create_with_builder(
grpc_channel_stack_builder* builder,
grpc_channel_stack_type channel_stack_type,
grpc_resource_user* resource_user, size_t preallocated_bytes,
grpc_error_handle* error = nullptr);
/** Create a call given a grpc_channel, in order to call \a method.
@ -109,8 +101,6 @@ struct grpc_channel {
grpc_compression_options compression_options;
gpr_atm call_size_estimate;
grpc_resource_user* resource_user;
size_t preallocated_bytes;
// TODO(vjpai): Once the grpc_channel is allocated via new rather than malloc,
// expand the members of the CallRegistrationTable directly into

@ -42,7 +42,6 @@
#include "src/core/lib/iomgr/exec_ctx.h"
#include "src/core/lib/iomgr/executor.h"
#include "src/core/lib/iomgr/iomgr.h"
#include "src/core/lib/iomgr/resource_quota.h"
#include "src/core/lib/iomgr/timer_manager.h"
#include "src/core/lib/profiling/timers.h"
#include "src/core/lib/slice/slice_internal.h"

@ -30,6 +30,7 @@
#include "src/core/lib/channel/channel_stack.h"
#include "src/core/lib/gpr/string.h"
#include "src/core/lib/resource_quota/api.h"
#include "src/core/lib/surface/api_trace.h"
#include "src/core/lib/surface/call.h"
#include "src/core/lib/surface/channel.h"
@ -184,9 +185,13 @@ grpc_channel* grpc_lame_client_channel_create(const char* target,
GRPC_ERROR_INT_GRPC_STATUS, error_code),
GRPC_ERROR_STR_GRPC_MESSAGE, error_message);
grpc_arg error_arg = grpc_core::MakeLameClientErrorArg(&error);
grpc_channel_args args = {1, &error_arg};
grpc_channel_args* args0 =
grpc_channel_args_copy_and_add(nullptr, &error_arg, 1);
grpc_channel_args* args = grpc_core::EnsureResourceQuotaInChannelArgs(args0);
grpc_channel_args_destroy(args0);
grpc_channel* channel = grpc_channel_create(
target, &args, GRPC_CLIENT_LAME_CHANNEL, nullptr, nullptr, 0, nullptr);
target, args, GRPC_CLIENT_LAME_CHANNEL, nullptr, nullptr);
grpc_channel_args_destroy(args);
GRPC_ERROR_UNREF(error);
return channel;
}

@ -46,6 +46,7 @@
#include "src/core/lib/gprpp/mpscq.h"
#include "src/core/lib/iomgr/executor.h"
#include "src/core/lib/iomgr/iomgr.h"
#include "src/core/lib/resource_quota/api.h"
#include "src/core/lib/slice/slice_internal.h"
#include "src/core/lib/surface/api_trace.h"
#include "src/core/lib/surface/call.h"
@ -600,13 +601,11 @@ void Server::Start() {
grpc_error_handle Server::SetupTransport(
grpc_transport* transport, grpc_pollset* accepting_pollset,
const grpc_channel_args* args,
const RefCountedPtr<grpc_core::channelz::SocketNode>& socket_node,
grpc_resource_user* resource_user, size_t preallocated_bytes) {
const RefCountedPtr<grpc_core::channelz::SocketNode>& socket_node) {
// Create channel.
grpc_error_handle error = GRPC_ERROR_NONE;
grpc_channel* channel =
grpc_channel_create(nullptr, args, GRPC_SERVER_CHANNEL, transport,
resource_user, preallocated_bytes, &error);
grpc_channel* channel = grpc_channel_create(
nullptr, args, GRPC_SERVER_CHANNEL, transport, &error);
if (channel == nullptr) {
return error;
}
@ -1477,8 +1476,12 @@ grpc_server* grpc_server_create(const grpc_channel_args* args, void* reserved) {
grpc_core::ExecCtx exec_ctx;
args = grpc_channel_args_remove_grpc_internal(args);
GRPC_API_TRACE("grpc_server_create(%p, %p)", 2, (args, reserved));
grpc_channel_args* new_args =
grpc_core::EnsureResourceQuotaInChannelArgs(args);
grpc_server* c_server = new grpc_server;
c_server->core_server = grpc_core::MakeOrphanable<grpc_core::Server>(args);
c_server->core_server =
grpc_core::MakeOrphanable<grpc_core::Server>(new_args);
grpc_channel_args_destroy(new_args);
grpc_channel_args_destroy(args);
return c_server;
}

@ -34,6 +34,7 @@
#include "src/core/lib/channel/channelz.h"
#include "src/core/lib/debug/trace.h"
#include "src/core/lib/iomgr/resolve_address.h"
#include "src/core/lib/resource_quota/memory_quota.h"
#include "src/core/lib/surface/completion_queue.h"
#include "src/core/lib/transport/transport.h"
@ -130,9 +131,7 @@ class Server : public InternallyRefCounted<Server> {
grpc_error_handle SetupTransport(
grpc_transport* transport, grpc_pollset* accepting_pollset,
const grpc_channel_args* args,
const RefCountedPtr<channelz::SocketNode>& socket_node,
grpc_resource_user* resource_user = nullptr,
size_t preallocated_bytes = 0);
const RefCountedPtr<channelz::SocketNode>& socket_node);
void RegisterCompletionQueue(grpc_completion_queue* cq);

@ -202,28 +202,16 @@ void DefaultHealthCheckService::HealthCheckServiceImpl::Serve(void* arg) {
bool DefaultHealthCheckService::HealthCheckServiceImpl::DecodeRequest(
const ByteBuffer& request, std::string* service_name) {
std::vector<Slice> slices;
if (!request.Dump(&slices).ok()) return false;
Slice slice;
if (!request.DumpToSingleSlice(&slice).ok()) return false;
uint8_t* request_bytes = nullptr;
size_t request_size = 0;
if (slices.size() == 1) {
request_bytes = const_cast<uint8_t*>(slices[0].begin());
request_size = slices[0].size();
} else if (slices.size() > 1) {
request_bytes = static_cast<uint8_t*>(gpr_malloc(request.Length()));
uint8_t* copy_to = request_bytes;
for (size_t i = 0; i < slices.size(); i++) {
memcpy(copy_to, slices[i].begin(), slices[i].size());
copy_to += slices[i].size();
}
}
request_bytes = const_cast<uint8_t*>(slice.begin());
request_size = slice.size();
upb::Arena arena;
grpc_health_v1_HealthCheckRequest* request_struct =
grpc_health_v1_HealthCheckRequest_parse(
reinterpret_cast<char*>(request_bytes), request_size, arena.ptr());
if (slices.size() > 1) {
gpr_free(request_bytes);
}
if (request_struct == nullptr) {
return false;
}

@ -50,18 +50,16 @@ ThreadManager::WorkerThread::~WorkerThread() {
thd_.Join();
}
ThreadManager::ThreadManager(const char* name,
grpc_resource_quota* resource_quota,
ThreadManager::ThreadManager(const char*, grpc_resource_quota* resource_quota,
int min_pollers, int max_pollers)
: shutdown_(false),
thread_quota_(
grpc_core::ResourceQuotaFromC(resource_quota)->thread_quota()),
num_pollers_(0),
min_pollers_(min_pollers),
max_pollers_(max_pollers == -1 ? INT_MAX : max_pollers),
num_threads_(0),
max_active_threads_sofar_(0) {
resource_user_ =
grpc_resource_user_create(resource_quota, name != nullptr ? name : "");
}
max_active_threads_sofar_(0) {}
ThreadManager::~ThreadManager() {
{
@ -69,8 +67,6 @@ ThreadManager::~ThreadManager() {
GPR_ASSERT(num_threads_ == 0);
}
grpc_core::ExecCtx exec_ctx; // grpc_resource_user_unref needs an exec_ctx
grpc_resource_user_unref(resource_user_);
CleanupCompletedThreads();
}
@ -111,7 +107,7 @@ void ThreadManager::MarkAsCompleted(WorkerThread* thd) {
}
// Give a thread back to the resource quota
grpc_resource_user_free_threads(resource_user_, 1);
thread_quota_->Release(1);
}
void ThreadManager::CleanupCompletedThreads() {
@ -126,7 +122,7 @@ void ThreadManager::CleanupCompletedThreads() {
}
void ThreadManager::Initialize() {
if (!grpc_resource_user_allocate_threads(resource_user_, min_pollers_)) {
if (!thread_quota_->Reserve(min_pollers_)) {
gpr_log(GPR_ERROR,
"No thread quota available to even create the minimum required "
"polling threads (i.e %d). Unable to start the thread manager",
@ -173,7 +169,7 @@ void ThreadManager::MainWorkLoop() {
// quota available to create a new thread, start a new poller thread
bool resource_exhausted = false;
if (!shutdown_ && num_pollers_ < min_pollers_) {
if (grpc_resource_user_allocate_threads(resource_user_, 1)) {
if (thread_quota_->Reserve(1)) {
// We can allocate a new poller thread
num_pollers_++;
num_threads_++;

@ -22,11 +22,12 @@
#include <list>
#include <memory>
#include <grpc/grpc.h>
#include <grpcpp/support/config.h>
#include "src/core/lib/gprpp/sync.h"
#include "src/core/lib/gprpp/thd.h"
#include "src/core/lib/iomgr/resource_quota.h"
#include "src/core/lib/resource_quota/api.h"
namespace grpc {
@ -154,7 +155,7 @@ class ThreadManager {
// object (that contains the actual max thread quota) and a grpc_resource_user
// object through which quota is requested whenever new threads need to be
// created
grpc_resource_user* resource_user_;
grpc_core::ThreadQuotaPtr thread_quota_;
// Number of threads doing polling
int num_pollers_;

@ -365,6 +365,7 @@ CORE_SOURCE_FILES = [
'src/core/lib/event_engine/channel_args_endpoint_config.cc',
'src/core/lib/event_engine/event_engine.cc',
'src/core/lib/event_engine/event_engine_factory.cc',
'src/core/lib/event_engine/memory_allocator.cc',
'src/core/lib/event_engine/sockaddr.cc',
'src/core/lib/gpr/alloc.cc',
'src/core/lib/gpr/atm.cc',
@ -472,7 +473,6 @@ CORE_SOURCE_FILES = [
'src/core/lib/iomgr/resolve_address_custom.cc',
'src/core/lib/iomgr/resolve_address_posix.cc',
'src/core/lib/iomgr/resolve_address_windows.cc',
'src/core/lib/iomgr/resource_quota.cc',
'src/core/lib/iomgr/socket_factory_posix.cc',
'src/core/lib/iomgr/socket_mutator.cc',
'src/core/lib/iomgr/socket_utils_common_posix.cc',
@ -514,6 +514,12 @@ CORE_SOURCE_FILES = [
'src/core/lib/matchers/matchers.cc',
'src/core/lib/profiling/basic_timers.cc',
'src/core/lib/profiling/stap_timers.cc',
'src/core/lib/promise/activity.cc',
'src/core/lib/resource_quota/api.cc',
'src/core/lib/resource_quota/memory_quota.cc',
'src/core/lib/resource_quota/resource_quota.cc',
'src/core/lib/resource_quota/thread_quota.cc',
'src/core/lib/resource_quota/trace.cc',
'src/core/lib/security/authorization/authorization_policy_provider_vtable.cc',
'src/core/lib/security/authorization/evaluate_args.cc',
'src/core/lib/security/authorization/sdk_server_authz_filter.cc',

@ -31,11 +31,11 @@
#include "src/core/lib/gpr/string.h"
#include "src/core/lib/gprpp/thd.h"
#include "src/core/lib/iomgr/endpoint_pair.h"
#include "src/core/lib/resource_quota/api.h"
#include "src/core/lib/slice/slice_internal.h"
#include "src/core/lib/surface/completion_queue.h"
#include "src/core/lib/surface/server.h"
#include "test/core/end2end/cq_verifier.h"
#include "test/core/util/resource_user_util.h"
#define MIN_HTTP2_FRAME_SIZE 9
@ -212,8 +212,10 @@ void grpc_run_bad_client_test(
GRPC_BAD_CLIENT_REGISTERED_HOST,
GRPC_SRM_PAYLOAD_READ_INITIAL_BYTE_BUFFER, 0);
grpc_server_start(a.server);
transport = grpc_create_chttp2_transport(
nullptr, sfd.server, false, grpc_resource_user_create_unlimited());
grpc_channel_args* channel_args =
grpc_core::EnsureResourceQuotaInChannelArgs(nullptr);
transport = grpc_create_chttp2_transport(channel_args, sfd.server, false);
grpc_channel_args_destroy(channel_args);
server_setup_transport(&a, transport);
grpc_chttp2_transport_start_reading(transport, nullptr, nullptr, nullptr);

@ -42,7 +42,6 @@
#include "src/core/lib/surface/channel.h"
#include "src/core/lib/surface/completion_queue.h"
#include "src/core/lib/surface/server.h"
#include "test/core/util/resource_user_util.h"
#include "test/core/util/test_config.h"
static void* tag(intptr_t t) { return reinterpret_cast<void*>(t); }
@ -94,15 +93,14 @@ static void client_setup_transport(grpc_transport* transport) {
* GRPC_CLIENT_DIRECT_CHANNEL */
g_ctx.client =
grpc_channel_create("socketpair-target", args, GRPC_CLIENT_DIRECT_CHANNEL,
transport, nullptr, 0, nullptr);
transport, nullptr);
grpc_channel_args_destroy(args);
}
static void init_client() {
grpc_core::ExecCtx exec_ctx;
grpc_transport* transport;
transport = grpc_create_chttp2_transport(
nullptr, g_ctx.ep->client, true, grpc_resource_user_create_unlimited());
transport = grpc_create_chttp2_transport(nullptr, g_ctx.ep->client, true);
client_setup_transport(transport);
GPR_ASSERT(g_ctx.client);
grpc_chttp2_transport_start_reading(transport, nullptr, nullptr, nullptr);
@ -115,8 +113,7 @@ static void init_server() {
g_ctx.server = grpc_server_create(nullptr, nullptr);
grpc_server_register_completion_queue(g_ctx.server, g_ctx.cq, nullptr);
grpc_server_start(g_ctx.server);
transport = grpc_create_chttp2_transport(
nullptr, g_ctx.ep->server, false, grpc_resource_user_create_unlimited());
transport = grpc_create_chttp2_transport(nullptr, g_ctx.ep->server, false);
server_setup_transport(transport);
grpc_chttp2_transport_start_reading(transport, nullptr, nullptr, nullptr);
}

@ -35,6 +35,7 @@
#include "src/core/lib/iomgr/endpoint_pair.h"
#include "src/core/lib/iomgr/iomgr.h"
#include "src/core/lib/iomgr/port.h"
#include "src/core/lib/resource_quota/api.h"
#include "src/core/lib/surface/channel.h"
#include "src/core/lib/surface/completion_queue.h"
#include "src/core/lib/surface/server.h"
@ -47,7 +48,6 @@
struct custom_fixture_data {
grpc_endpoint_pair ep;
grpc_resource_quota* resource_quota;
};
static void server_setup_transport(void* ts, grpc_transport* transport) {
@ -79,9 +79,8 @@ static void client_setup_transport(void* ts, grpc_transport* transport) {
grpc_channel_args* args =
grpc_channel_args_copy_and_add(cs->client_args, &authority_arg, 1);
grpc_error_handle error = GRPC_ERROR_NONE;
cs->f->client =
grpc_channel_create("socketpair-target", args, GRPC_CLIENT_DIRECT_CHANNEL,
transport, nullptr, 0, &error);
cs->f->client = grpc_channel_create(
"socketpair-target", args, GRPC_CLIENT_DIRECT_CHANNEL, transport, &error);
grpc_channel_args_destroy(args);
if (cs->f->client != nullptr) {
grpc_chttp2_transport_start_reading(transport, nullptr, nullptr, nullptr);
@ -99,7 +98,7 @@ static void client_setup_transport(void* ts, grpc_transport* transport) {
}
static grpc_end2end_test_fixture chttp2_create_fixture_socketpair(
grpc_channel_args* client_args, grpc_channel_args* /*server_args*/) {
grpc_channel_args* /*client_args*/, grpc_channel_args* /*server_args*/) {
custom_fixture_data* fixture_data = static_cast<custom_fixture_data*>(
gpr_malloc(sizeof(custom_fixture_data)));
grpc_end2end_test_fixture f;
@ -107,8 +106,6 @@ static grpc_end2end_test_fixture chttp2_create_fixture_socketpair(
f.fixture_data = fixture_data;
f.cq = grpc_completion_queue_create_for_next(nullptr);
f.shutdown_cq = grpc_completion_queue_create_for_pluck(nullptr);
fixture_data->resource_quota =
grpc_resource_quota_from_channel_args(client_args, true);
fixture_data->ep = grpc_iomgr_create_endpoint_pair("fixture", nullptr);
return f;
}
@ -121,10 +118,10 @@ static void chttp2_init_client_socketpair(grpc_end2end_test_fixture* f,
sp_client_setup cs;
cs.client_args = client_args;
cs.f = f;
transport = grpc_create_chttp2_transport(
client_args, fixture_data->ep.client, true,
grpc_resource_user_create(fixture_data->resource_quota,
"client_transport"));
client_args = grpc_core::EnsureResourceQuotaInChannelArgs(client_args);
transport =
grpc_create_chttp2_transport(client_args, fixture_data->ep.client, true);
grpc_channel_args_destroy(client_args);
client_setup_transport(&cs, transport);
GPR_ASSERT(f->client);
}
@ -138,17 +135,15 @@ static void chttp2_init_server_socketpair(grpc_end2end_test_fixture* f,
f->server = grpc_server_create(server_args, nullptr);
grpc_server_register_completion_queue(f->server, f->cq, nullptr);
grpc_server_start(f->server);
transport = grpc_create_chttp2_transport(
server_args, fixture_data->ep.server, false,
grpc_resource_user_create(fixture_data->resource_quota,
"server_transport"));
server_args = grpc_core::EnsureResourceQuotaInChannelArgs(server_args);
transport =
grpc_create_chttp2_transport(server_args, fixture_data->ep.server, false);
grpc_channel_args_destroy(server_args);
server_setup_transport(f, transport);
}
static void chttp2_tear_down_socketpair(grpc_end2end_test_fixture* f) {
grpc_core::ExecCtx exec_ctx;
auto* fixture_data = static_cast<custom_fixture_data*>(f->fixture_data);
grpc_resource_quota_unref(fixture_data->resource_quota);
gpr_free(f->fixture_data);
}

@ -30,6 +30,7 @@
#include "src/core/lib/channel/connected_channel.h"
#include "src/core/lib/iomgr/endpoint_pair.h"
#include "src/core/lib/iomgr/iomgr.h"
#include "src/core/lib/resource_quota/api.h"
#include "src/core/lib/surface/channel.h"
#include "src/core/lib/surface/completion_queue.h"
#include "src/core/lib/surface/server.h"
@ -42,7 +43,6 @@
struct custom_fixture_data {
grpc_endpoint_pair ep;
grpc_resource_quota* resource_quota;
};
static void server_setup_transport(void* ts, grpc_transport* transport) {
@ -75,9 +75,8 @@ static void client_setup_transport(void* ts, grpc_transport* transport) {
grpc_channel_args* args =
grpc_channel_args_copy_and_add(cs->client_args, &authority_arg, 1);
grpc_error_handle error = GRPC_ERROR_NONE;
cs->f->client =
grpc_channel_create("socketpair-target", args, GRPC_CLIENT_DIRECT_CHANNEL,
transport, nullptr, 0, &error);
cs->f->client = grpc_channel_create(
"socketpair-target", args, GRPC_CLIENT_DIRECT_CHANNEL, transport, &error);
grpc_channel_args_destroy(args);
if (cs->f->client != nullptr) {
grpc_chttp2_transport_start_reading(transport, nullptr, nullptr, nullptr);
@ -95,7 +94,7 @@ static void client_setup_transport(void* ts, grpc_transport* transport) {
}
static grpc_end2end_test_fixture chttp2_create_fixture_socketpair(
grpc_channel_args* client_args, grpc_channel_args* /*server_args*/) {
grpc_channel_args* /*client_args*/, grpc_channel_args* /*server_args*/) {
custom_fixture_data* fixture_data = static_cast<custom_fixture_data*>(
gpr_malloc(sizeof(custom_fixture_data)));
grpc_end2end_test_fixture f;
@ -103,8 +102,6 @@ static grpc_end2end_test_fixture chttp2_create_fixture_socketpair(
f.fixture_data = fixture_data;
f.cq = grpc_completion_queue_create_for_next(nullptr);
f.shutdown_cq = grpc_completion_queue_create_for_pluck(nullptr);
fixture_data->resource_quota =
grpc_resource_quota_from_channel_args(client_args, true);
fixture_data->ep = grpc_iomgr_create_endpoint_pair("fixture", nullptr);
return f;
}
@ -117,10 +114,10 @@ static void chttp2_init_client_socketpair(grpc_end2end_test_fixture* f,
sp_client_setup cs;
cs.client_args = client_args;
cs.f = f;
transport = grpc_create_chttp2_transport(
client_args, fixture_data->ep.client, true,
grpc_resource_user_create(fixture_data->resource_quota,
"client_transport"));
client_args = grpc_core::EnsureResourceQuotaInChannelArgs(client_args);
transport =
grpc_create_chttp2_transport(client_args, fixture_data->ep.client, true);
grpc_channel_args_destroy(client_args);
client_setup_transport(&cs, transport);
GPR_ASSERT(f->client);
}
@ -134,17 +131,15 @@ static void chttp2_init_server_socketpair(grpc_end2end_test_fixture* f,
f->server = grpc_server_create(server_args, nullptr);
grpc_server_register_completion_queue(f->server, f->cq, nullptr);
grpc_server_start(f->server);
transport = grpc_create_chttp2_transport(
server_args, fixture_data->ep.server, false,
grpc_resource_user_create(fixture_data->resource_quota,
"server_transport"));
server_args = grpc_core::EnsureResourceQuotaInChannelArgs(server_args);
transport =
grpc_create_chttp2_transport(server_args, fixture_data->ep.server, false);
grpc_channel_args_destroy(server_args);
server_setup_transport(f, transport);
}
static void chttp2_tear_down_socketpair(grpc_end2end_test_fixture* f) {
grpc_core::ExecCtx exec_ctx;
auto* fixture_data = static_cast<custom_fixture_data*>(f->fixture_data);
grpc_resource_quota_unref(fixture_data->resource_quota);
gpr_free(f->fixture_data);
}

@ -30,6 +30,7 @@
#include "src/core/lib/channel/connected_channel.h"
#include "src/core/lib/iomgr/endpoint_pair.h"
#include "src/core/lib/iomgr/iomgr.h"
#include "src/core/lib/resource_quota/api.h"
#include "src/core/lib/surface/channel.h"
#include "src/core/lib/surface/completion_queue.h"
#include "src/core/lib/surface/server.h"
@ -42,7 +43,6 @@
struct custom_fixture_data {
grpc_endpoint_pair ep;
grpc_resource_quota* resource_quota;
};
static void server_setup_transport(void* ts, grpc_transport* transport) {
@ -75,9 +75,8 @@ static void client_setup_transport(void* ts, grpc_transport* transport) {
grpc_channel_args* args =
grpc_channel_args_copy_and_add(cs->client_args, &authority_arg, 1);
grpc_error_handle error = GRPC_ERROR_NONE;
cs->f->client =
grpc_channel_create("socketpair-target", args, GRPC_CLIENT_DIRECT_CHANNEL,
transport, nullptr, 0, &error);
cs->f->client = grpc_channel_create(
"socketpair-target", args, GRPC_CLIENT_DIRECT_CHANNEL, transport, &error);
grpc_channel_args_destroy(args);
if (cs->f->client != nullptr) {
grpc_chttp2_transport_start_reading(transport, nullptr, nullptr, nullptr);
@ -114,8 +113,6 @@ static grpc_end2end_test_fixture chttp2_create_fixture_socketpair(
a[2].type = GRPC_ARG_INTEGER;
a[2].value.integer = 1;
grpc_channel_args args = {GPR_ARRAY_SIZE(a), a};
fixture_data->resource_quota =
grpc_resource_quota_from_channel_args(&args, true);
fixture_data->ep = grpc_iomgr_create_endpoint_pair("fixture", &args);
return f;
}
@ -128,10 +125,10 @@ static void chttp2_init_client_socketpair(grpc_end2end_test_fixture* f,
sp_client_setup cs;
cs.client_args = client_args;
cs.f = f;
transport = grpc_create_chttp2_transport(
client_args, fixture_data->ep.client, true,
grpc_resource_user_create(fixture_data->resource_quota,
"client_transport"));
client_args = grpc_core::EnsureResourceQuotaInChannelArgs(client_args);
transport =
grpc_create_chttp2_transport(client_args, fixture_data->ep.client, true);
grpc_channel_args_destroy(client_args);
client_setup_transport(&cs, transport);
GPR_ASSERT(f->client);
}
@ -145,17 +142,15 @@ static void chttp2_init_server_socketpair(grpc_end2end_test_fixture* f,
f->server = grpc_server_create(server_args, nullptr);
grpc_server_register_completion_queue(f->server, f->cq, nullptr);
grpc_server_start(f->server);
transport = grpc_create_chttp2_transport(
server_args, fixture_data->ep.server, false,
grpc_resource_user_create(fixture_data->resource_quota,
"server_transport"));
server_args = grpc_core::EnsureResourceQuotaInChannelArgs(server_args);
transport =
grpc_create_chttp2_transport(server_args, fixture_data->ep.server, false);
grpc_channel_args_destroy(server_args);
server_setup_transport(f, transport);
}
static void chttp2_tear_down_socketpair(grpc_end2end_test_fixture* f) {
grpc_core::ExecCtx exec_ctx;
auto* fixture_data = static_cast<custom_fixture_data*>(f->fixture_data);
grpc_resource_quota_unref(fixture_data->resource_quota);
gpr_free(f->fixture_data);
}

@ -48,10 +48,10 @@
#include "src/core/lib/iomgr/tcp_client.h"
#include "src/core/lib/iomgr/tcp_server.h"
#include "src/core/lib/iomgr/timer.h"
#include "src/core/lib/resource_quota/api.h"
#include "src/core/lib/slice/b64.h"
#include "src/core/lib/slice/slice_internal.h"
#include "test/core/util/port.h"
#include "test/core/util/resource_user_util.h"
struct grpc_end2end_http_proxy {
grpc_end2end_http_proxy()
@ -536,10 +536,12 @@ static void on_read_request_done_locked(void* arg, grpc_error_handle error) {
grpc_core::ExecCtx::Get()->Now() + 10 * GPR_MS_PER_SEC;
GRPC_CLOSURE_INIT(&conn->on_server_connect_done, on_server_connect_done, conn,
grpc_schedule_on_exec_ctx);
grpc_channel_args* args =
grpc_core::EnsureResourceQuotaInChannelArgs(nullptr);
grpc_tcp_client_connect(&conn->on_server_connect_done, &conn->server_endpoint,
grpc_slice_allocator_create_unlimited(),
conn->pollset_set, nullptr,
conn->pollset_set, args,
&resolved_addresses->addrs[0], deadline);
grpc_channel_args_destroy(args);
grpc_resolved_addresses_destroy(resolved_addresses);
}
@ -610,12 +612,9 @@ grpc_end2end_http_proxy* grpc_end2end_http_proxy_create(
proxy->proxy_name = grpc_core::JoinHostPort("localhost", proxy_port);
gpr_log(GPR_INFO, "Proxy address: %s", proxy->proxy_name.c_str());
// Create TCP server.
proxy->channel_args = grpc_channel_args_copy(args);
grpc_error_handle error = grpc_tcp_server_create(
nullptr, proxy->channel_args,
grpc_slice_allocator_factory_create(
grpc_resource_quota_from_channel_args(args, true)),
&proxy->server);
proxy->channel_args = grpc_core::EnsureResourceQuotaInChannelArgs(args);
grpc_error_handle error =
grpc_tcp_server_create(nullptr, proxy->channel_args, &proxy->server);
GPR_ASSERT(error == GRPC_ERROR_NONE);
// Bind to port.
grpc_resolved_address resolved_addr;

@ -150,34 +150,29 @@ static void my_cancel_ares_request_locked(grpc_ares_request* request) {
////////////////////////////////////////////////////////////////////////////////
// client connection
static void sched_connect(grpc_closure* closure,
grpc_slice_allocator* slice_allocator,
grpc_endpoint** ep, gpr_timespec deadline);
static void sched_connect(grpc_closure* closure, grpc_endpoint** ep,
gpr_timespec deadline);
typedef struct {
grpc_timer timer;
grpc_closure* closure;
grpc_endpoint** ep;
gpr_timespec deadline;
grpc_slice_allocator* slice_allocator;
} future_connect;
static void do_connect(void* arg, grpc_error_handle error) {
future_connect* fc = static_cast<future_connect*>(arg);
if (error != GRPC_ERROR_NONE) {
grpc_slice_allocator_destroy(fc->slice_allocator);
*fc->ep = nullptr;
grpc_core::ExecCtx::Run(DEBUG_LOCATION, fc->closure, GRPC_ERROR_REF(error));
} else if (g_server != nullptr) {
grpc_slice_allocator_destroy(fc->slice_allocator);
grpc_endpoint* client;
grpc_endpoint* server;
grpc_passthru_endpoint_create(&client, &server, nullptr);
*fc->ep = client;
grpc_transport* transport = grpc_create_chttp2_transport(
nullptr, server, false,
grpc_resource_user_create(g_resource_quota, "transport-user"));
g_server->core_server->channel_args(), server, false);
GPR_ASSERT(GRPC_LOG_IF_ERROR("SetupTransport",
g_server->core_server->SetupTransport(
transport, nullptr, nullptr, nullptr)));
@ -185,17 +180,15 @@ static void do_connect(void* arg, grpc_error_handle error) {
grpc_core::ExecCtx::Run(DEBUG_LOCATION, fc->closure, GRPC_ERROR_NONE);
} else {
sched_connect(fc->closure, fc->slice_allocator, fc->ep, fc->deadline);
sched_connect(fc->closure, fc->ep, fc->deadline);
}
gpr_free(fc);
}
static void sched_connect(grpc_closure* closure,
grpc_slice_allocator* slice_allocator,
grpc_endpoint** ep, gpr_timespec deadline) {
static void sched_connect(grpc_closure* closure, grpc_endpoint** ep,
gpr_timespec deadline) {
if (gpr_time_cmp(deadline, gpr_now(deadline.clock_type)) < 0) {
*ep = nullptr;
grpc_slice_allocator_destroy(slice_allocator);
grpc_core::ExecCtx::Run(
DEBUG_LOCATION, closure,
GRPC_ERROR_CREATE_FROM_STATIC_STRING("Connect deadline exceeded"));
@ -206,19 +199,17 @@ static void sched_connect(grpc_closure* closure,
fc->closure = closure;
fc->ep = ep;
fc->deadline = deadline;
fc->slice_allocator = slice_allocator;
grpc_timer_init(
&fc->timer, GPR_MS_PER_SEC + grpc_core::ExecCtx::Get()->Now(),
GRPC_CLOSURE_CREATE(do_connect, fc, grpc_schedule_on_exec_ctx));
}
static void my_tcp_client_connect(grpc_closure* closure, grpc_endpoint** ep,
grpc_slice_allocator* slice_allocator,
grpc_pollset_set* /*interested_parties*/,
const grpc_channel_args* /*channel_args*/,
const grpc_resolved_address* /*addr*/,
grpc_millis deadline) {
sched_connect(closure, slice_allocator, ep,
sched_connect(closure, ep,
grpc_millis_to_timespec(deadline, GPR_CLOCK_MONOTONIC));
}

@ -24,6 +24,7 @@
#include "src/core/ext/transport/chttp2/transport/chttp2_transport.h"
#include "src/core/lib/iomgr/executor.h"
#include "src/core/lib/resource_quota/api.h"
#include "src/core/lib/slice/slice_internal.h"
#include "src/core/lib/surface/channel.h"
#include "test/core/util/mock_endpoint.h"
@ -47,23 +48,21 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
grpc_resource_quota* resource_quota =
grpc_resource_quota_create("context_list_test");
grpc_endpoint* mock_endpoint = grpc_mock_endpoint_create(
discard_write,
grpc_slice_allocator_create(resource_quota, "mock_endpoint"));
grpc_endpoint* mock_endpoint = grpc_mock_endpoint_create(discard_write);
grpc_completion_queue* cq = grpc_completion_queue_create_for_next(nullptr);
grpc_transport* transport = grpc_create_chttp2_transport(
nullptr, mock_endpoint, true,
grpc_resource_user_create(resource_quota, "mock_transport"));
grpc_channel_args* args =
grpc_core::EnsureResourceQuotaInChannelArgs(nullptr);
grpc_transport* transport =
grpc_create_chttp2_transport(args, mock_endpoint, true);
grpc_channel_args_destroy(args);
grpc_resource_quota_unref(resource_quota);
grpc_chttp2_transport_start_reading(transport, nullptr, nullptr, nullptr);
grpc_arg authority_arg = grpc_channel_arg_string_create(
const_cast<char*>(GRPC_ARG_DEFAULT_AUTHORITY),
const_cast<char*>("test-authority"));
grpc_channel_args* args =
grpc_channel_args_copy_and_add(nullptr, &authority_arg, 1);
grpc_channel* channel =
grpc_channel_create("test-target", args, GRPC_CLIENT_DIRECT_CHANNEL,
transport, nullptr, 0, nullptr);
args = grpc_channel_args_copy_and_add(nullptr, &authority_arg, 1);
grpc_channel* channel = grpc_channel_create(
"test-target", args, GRPC_CLIENT_DIRECT_CHANNEL, transport, nullptr);
grpc_channel_args_destroy(args);
grpc_slice host = grpc_slice_from_static_string("localhost");
grpc_call* call = grpc_channel_create_call(

@ -20,6 +20,7 @@
#include "src/core/ext/transport/chttp2/transport/chttp2_transport.h"
#include "src/core/lib/iomgr/executor.h"
#include "src/core/lib/resource_quota/api.h"
#include "src/core/lib/slice/slice_internal.h"
#include "src/core/lib/surface/server.h"
#include "test/core/util/mock_endpoint.h"
@ -42,9 +43,7 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
grpc_core::Executor::SetThreadingAll(false);
grpc_resource_quota* resource_quota =
grpc_resource_quota_create("context_list_test");
grpc_endpoint* mock_endpoint = grpc_mock_endpoint_create(
discard_write,
grpc_slice_allocator_create(resource_quota, "mock_endpoint"));
grpc_endpoint* mock_endpoint = grpc_mock_endpoint_create(discard_write);
grpc_mock_endpoint_put_read(
mock_endpoint, grpc_slice_from_copied_buffer((const char*)data, size));
grpc_server* server = grpc_server_create(nullptr, nullptr);
@ -53,9 +52,11 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
// TODO(ctiller): add more registered methods (one for POST, one for PUT)
grpc_server_register_method(server, "/reg", nullptr, {}, 0);
grpc_server_start(server);
grpc_transport* transport = grpc_create_chttp2_transport(
nullptr, mock_endpoint, false,
grpc_resource_user_create(resource_quota, "mock_transport"));
grpc_channel_args* channel_args =
grpc_core::EnsureResourceQuotaInChannelArgs(nullptr);
grpc_transport* transport =
grpc_create_chttp2_transport(channel_args, mock_endpoint, false);
grpc_channel_args_destroy(channel_args);
grpc_resource_quota_unref(resource_quota);
GPR_ASSERT(GRPC_LOG_IF_ERROR("SetupTransport",
server->core_server->SetupTransport(

@ -28,6 +28,7 @@ def _fixture_options(
tracing = False,
_platforms = ["windows", "linux", "mac", "posix"],
is_inproc = False,
is_1byte = False,
is_http2 = True,
supports_proxy_auth = False,
supports_write_buffering = True,
@ -42,6 +43,7 @@ def _fixture_options(
secure = secure,
tracing = tracing,
is_inproc = is_inproc,
is_1byte = is_1byte,
is_http2 = is_http2,
supports_proxy_auth = supports_proxy_auth,
supports_write_buffering = supports_write_buffering,
@ -76,6 +78,7 @@ END2END_FIXTURES = {
fullstack = False,
dns_resolver = False,
client_channel = False,
is_1byte = True,
),
"h2_sockpair": _fixture_options(
fullstack = False,
@ -151,6 +154,7 @@ END2END_NOSEC_FIXTURES = {
dns_resolver = False,
client_channel = False,
secure = False,
is_1byte = True,
),
"h2_sockpair": _fixture_options(
fullstack = False,
@ -184,6 +188,7 @@ def _test_options(
secure = False,
traceable = False,
exclude_inproc = False,
exclude_1byte = False,
needs_http2 = False,
needs_proxy_auth = False,
needs_write_buffering = False,
@ -198,6 +203,7 @@ def _test_options(
secure = secure,
traceable = traceable,
exclude_inproc = exclude_inproc,
exclude_1byte = exclude_1byte,
needs_http2 = needs_http2,
needs_proxy_auth = needs_proxy_auth,
needs_write_buffering = needs_write_buffering,
@ -215,6 +221,7 @@ END2END_TESTS = {
proxyable = False,
# TODO(b/151212019): Test case known to be flaky under epoll1.
exclude_pollers = ["epoll1"],
exclude_1byte = True,
),
"call_creds": _test_options(secure = True),
"call_host_override": _test_options(
@ -255,9 +262,9 @@ END2END_TESTS = {
),
"high_initial_seqno": _test_options(),
"idempotent_request": _test_options(),
"invoke_large_request": _test_options(),
"invoke_large_request": _test_options(exclude_1byte = True),
"keepalive_timeout": _test_options(proxyable = False, needs_http2 = True),
"large_metadata": _test_options(),
"large_metadata": _test_options(exclude_1byte = True),
"max_concurrent_streams": _test_options(
proxyable = False,
exclude_inproc = True,
@ -269,7 +276,7 @@ END2END_TESTS = {
"no_error_on_hotpath": _test_options(proxyable = False),
"no_logging": _test_options(traceable = False),
"no_op": _test_options(),
"payload": _test_options(),
"payload": _test_options(exclude_1byte = True),
# TODO(juanlishen): This is disabled for now because it depends on some generated functions in
# end2end_tests.cc, which are not generated because they would depend on OpenCensus while
# OpenCensus can only be built via Bazel so far.
@ -357,8 +364,9 @@ END2END_TESTS = {
"stream_compression_compressed_payload": _test_options(
proxyable = False,
exclude_inproc = True,
exclude_1byte = True,
),
"stream_compression_payload": _test_options(exclude_inproc = True),
"stream_compression_payload": _test_options(exclude_inproc = True, exclude_1byte = True),
"stream_compression_ping_pong_streaming": _test_options(exclude_inproc = True),
"trailing_metadata": _test_options(),
"authority_not_supported": _test_options(),
@ -387,6 +395,9 @@ def _compatible(fopt, topt):
if topt.exclude_inproc:
if fopt.is_inproc:
return False
if topt.exclude_1byte:
if fopt.is_1byte:
return False
if topt.needs_http2:
if not fopt.is_http2:
return False

@ -24,6 +24,7 @@
#include <grpc/support/log.h>
#include <grpc/support/time.h>
#include "src/core/lib/resource_quota/api.h"
#include "test/core/end2end/cq_verifier.h"
#include "test/core/end2end/end2end_tests.h"
@ -35,9 +36,13 @@ static grpc_end2end_test_fixture begin_test(grpc_end2end_test_config config,
grpc_channel_args* server_args) {
grpc_end2end_test_fixture f;
gpr_log(GPR_INFO, "Running test: %s/%s", test_name, config.name);
client_args = grpc_core::EnsureResourceQuotaInChannelArgs(client_args);
server_args = grpc_core::EnsureResourceQuotaInChannelArgs(server_args);
f = config.create_fixture(client_args, server_args);
config.init_server(&f, server_args);
config.init_client(&f, client_args);
grpc_channel_args_destroy(client_args);
grpc_channel_args_destroy(server_args);
return f;
}

@ -285,6 +285,18 @@ grpc_cc_test(
],
)
grpc_cc_test(
name = "cpp_impl_of_test",
srcs = ["cpp_impl_of_test.cc"],
external_deps = ["gtest"],
language = "c++",
uses_polling = False,
deps = [
"//:cpp_impl_of",
"//test/core/util:grpc_suppressions",
],
)
grpc_cc_test(
name = "chunked_vector_test",
srcs = ["chunked_vector_test.cc"],

@ -0,0 +1,33 @@
// Copyright 2021 gRPC authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include "src/core/lib/gprpp/cpp_impl_of.h"
#include <gtest/gtest.h>
typedef struct grpc_foo grpc_foo;
namespace grpc_core {
namespace {
class Foo : public CppImplOf<Foo, grpc_foo> {};
} // namespace
TEST(CppImplOfTest, CreateDestroy) { delete Foo::FromC((new Foo())->c_ptr()); }
} // namespace grpc_core
int main(int argc, char** argv) {
::testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
}

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

Loading…
Cancel
Save