grpc 1.49.1 → 1.50.0.pre1

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of grpc might be problematic. Click here for more details.

Files changed (270) hide show
  1. checksums.yaml +4 -4
  2. data/Makefile +54 -153
  3. data/include/grpc/event_engine/endpoint_config.h +11 -5
  4. data/include/grpc/event_engine/event_engine.h +1 -1
  5. data/include/grpc/impl/codegen/atm_gcc_atomic.h +19 -28
  6. data/include/grpc/impl/codegen/atm_gcc_sync.h +0 -2
  7. data/include/grpc/impl/codegen/atm_windows.h +0 -2
  8. data/include/grpc/impl/codegen/grpc_types.h +6 -0
  9. data/src/core/ext/filters/channel_idle/channel_idle_filter.cc +3 -3
  10. data/src/core/ext/filters/client_channel/backup_poller.cc +4 -6
  11. data/src/core/ext/filters/client_channel/client_channel.cc +33 -22
  12. data/src/core/ext/filters/client_channel/client_channel.h +1 -1
  13. data/src/core/ext/filters/client_channel/client_channel_plugin.cc +0 -16
  14. data/src/core/ext/filters/client_channel/http_proxy.cc +12 -19
  15. data/src/core/ext/filters/client_channel/http_proxy.h +3 -2
  16. data/src/core/ext/filters/client_channel/lb_policy/child_policy_handler.cc +6 -4
  17. data/src/core/ext/filters/client_channel/lb_policy/child_policy_handler.h +5 -4
  18. data/src/core/ext/filters/client_channel/lb_policy/grpclb/client_load_reporting_filter.cc +0 -2
  19. data/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc +112 -96
  20. data/src/core/ext/filters/client_channel/lb_policy/oob_backend_metric.cc +20 -11
  21. data/src/core/ext/filters/client_channel/lb_policy/outlier_detection/outlier_detection.cc +106 -108
  22. data/src/core/ext/filters/client_channel/lb_policy/outlier_detection/outlier_detection.h +16 -0
  23. data/src/core/ext/filters/client_channel/lb_policy/pick_first/pick_first.cc +20 -13
  24. data/src/core/ext/filters/client_channel/lb_policy/priority/priority.cc +165 -257
  25. data/src/core/ext/filters/client_channel/lb_policy/ring_hash/ring_hash.cc +218 -231
  26. data/src/core/ext/filters/client_channel/lb_policy/ring_hash/ring_hash.h +10 -6
  27. data/src/core/ext/filters/client_channel/lb_policy/rls/rls.cc +389 -444
  28. data/src/core/ext/filters/client_channel/lb_policy/round_robin/round_robin.cc +16 -16
  29. data/src/core/ext/filters/client_channel/lb_policy/subchannel_list.h +8 -13
  30. data/src/core/ext/filters/client_channel/lb_policy/weighted_target/weighted_target.cc +84 -96
  31. data/src/core/ext/filters/client_channel/lb_policy/xds/cds.cc +38 -37
  32. data/src/core/ext/filters/client_channel/lb_policy/xds/xds_cluster_impl.cc +106 -186
  33. data/src/core/ext/filters/client_channel/lb_policy/xds/xds_cluster_manager.cc +106 -93
  34. data/src/core/ext/filters/client_channel/lb_policy/xds/xds_cluster_resolver.cc +170 -218
  35. data/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.cc +2 -2
  36. data/src/core/ext/filters/client_channel/resolver/dns/native/dns_resolver.cc +1 -1
  37. data/src/core/ext/filters/client_channel/resolver/google_c2p/google_c2p_resolver.cc +13 -15
  38. data/src/core/ext/filters/client_channel/resolver/polling_resolver.cc +84 -37
  39. data/src/core/ext/filters/client_channel/resolver/polling_resolver.h +11 -0
  40. data/src/core/ext/filters/client_channel/resolver/sockaddr/sockaddr_resolver.cc +1 -0
  41. data/src/core/ext/filters/client_channel/resolver/xds/xds_resolver.cc +5 -3
  42. data/src/core/ext/filters/client_channel/resolver_result_parsing.cc +5 -4
  43. data/src/core/ext/filters/client_channel/retry_filter.cc +25 -29
  44. data/src/core/ext/filters/client_channel/subchannel.cc +38 -33
  45. data/src/core/ext/filters/client_channel/subchannel.h +12 -3
  46. data/src/core/ext/filters/client_channel/subchannel_stream_client.cc +1 -2
  47. data/src/core/ext/filters/fault_injection/fault_injection_filter.cc +23 -16
  48. data/src/core/ext/filters/fault_injection/fault_injection_filter.h +8 -0
  49. data/src/core/ext/filters/http/client/http_client_filter.cc +1 -2
  50. data/src/core/ext/filters/http/message_compress/message_compress_filter.cc +2 -4
  51. data/src/core/ext/filters/http/message_compress/message_decompress_filter.cc +0 -2
  52. data/src/core/ext/filters/http/server/http_server_filter.cc +1 -2
  53. data/src/core/ext/transport/chttp2/client/chttp2_connector.cc +12 -8
  54. data/src/core/ext/transport/chttp2/server/chttp2_server.cc +32 -26
  55. data/src/core/ext/transport/chttp2/transport/bin_encoder.cc +1 -1
  56. data/src/core/ext/transport/chttp2/transport/chttp2_transport.cc +25 -130
  57. data/src/core/ext/transport/chttp2/transport/decode_huff.cc +287 -0
  58. data/src/core/ext/transport/chttp2/transport/decode_huff.h +1018 -0
  59. data/src/core/ext/transport/chttp2/transport/flow_control.cc +83 -51
  60. data/src/core/ext/transport/chttp2/transport/flow_control.h +11 -6
  61. data/src/core/ext/transport/chttp2/transport/frame_ping.cc +1 -2
  62. data/src/core/ext/transport/chttp2/transport/hpack_encoder.cc +2 -20
  63. data/src/core/ext/transport/chttp2/transport/hpack_parser.cc +28 -28
  64. data/src/core/ext/transport/chttp2/transport/hpack_parser_table.cc +1 -10
  65. data/src/core/ext/transport/chttp2/transport/hpack_parser_table.h +11 -6
  66. data/src/core/ext/transport/chttp2/transport/internal.h +2 -0
  67. data/src/core/ext/transport/chttp2/transport/parsing.cc +44 -0
  68. data/src/core/ext/transport/chttp2/transport/writing.cc +3 -14
  69. data/src/core/ext/transport/inproc/inproc_transport.cc +1 -3
  70. data/src/core/ext/xds/certificate_provider_store.cc +63 -3
  71. data/src/core/ext/xds/certificate_provider_store.h +9 -1
  72. data/src/core/ext/xds/file_watcher_certificate_provider_factory.cc +5 -5
  73. data/src/core/ext/xds/file_watcher_certificate_provider_factory.h +1 -1
  74. data/src/core/ext/xds/xds_api.cc +21 -17
  75. data/src/core/ext/xds/xds_api.h +7 -0
  76. data/src/core/ext/xds/xds_bootstrap.cc +5 -537
  77. data/src/core/ext/xds/xds_bootstrap.h +39 -111
  78. data/src/core/ext/xds/xds_bootstrap_grpc.cc +370 -0
  79. data/src/core/ext/xds/xds_bootstrap_grpc.h +169 -0
  80. data/src/core/ext/xds/xds_client.cc +219 -145
  81. data/src/core/ext/xds/xds_client.h +19 -17
  82. data/src/core/ext/xds/xds_client_grpc.cc +18 -80
  83. data/src/core/ext/xds/xds_client_grpc.h +2 -25
  84. data/src/core/ext/xds/xds_client_stats.cc +4 -4
  85. data/src/core/ext/xds/xds_cluster.cc +87 -79
  86. data/src/core/ext/xds/xds_cluster.h +5 -5
  87. data/src/core/ext/xds/xds_cluster_specifier_plugin.cc +3 -1
  88. data/src/core/ext/xds/xds_common_types.cc +13 -5
  89. data/src/core/ext/xds/xds_endpoint.cc +8 -6
  90. data/src/core/ext/xds/xds_endpoint.h +3 -4
  91. data/src/core/ext/xds/xds_lb_policy_registry.cc +4 -2
  92. data/src/core/ext/xds/xds_listener.cc +25 -20
  93. data/src/core/ext/xds/xds_listener.h +3 -4
  94. data/src/core/ext/xds/xds_resource_type.h +11 -8
  95. data/src/core/ext/xds/xds_route_config.cc +15 -16
  96. data/src/core/ext/xds/xds_route_config.h +3 -3
  97. data/src/core/ext/xds/xds_server_config_fetcher.cc +7 -5
  98. data/src/core/ext/xds/xds_transport_grpc.cc +15 -7
  99. data/src/core/lib/backoff/backoff.cc +2 -4
  100. data/src/core/lib/channel/call_finalization.h +1 -3
  101. data/src/core/lib/channel/channel_args.h +114 -14
  102. data/src/core/lib/channel/channel_trace.cc +3 -4
  103. data/src/core/lib/channel/promise_based_filter.cc +18 -19
  104. data/src/core/lib/channel/status_util.cc +27 -0
  105. data/src/core/lib/channel/status_util.h +10 -0
  106. data/src/core/lib/config/core_configuration.cc +5 -1
  107. data/src/core/lib/config/core_configuration.h +33 -0
  108. data/src/core/lib/debug/stats.cc +26 -30
  109. data/src/core/lib/debug/stats.h +2 -12
  110. data/src/core/lib/debug/stats_data.cc +118 -614
  111. data/src/core/lib/debug/stats_data.h +67 -465
  112. data/src/core/lib/debug/trace.cc +0 -2
  113. data/src/core/lib/event_engine/channel_args_endpoint_config.cc +12 -20
  114. data/src/core/lib/event_engine/channel_args_endpoint_config.h +13 -7
  115. data/src/core/lib/event_engine/forkable.cc +1 -1
  116. data/src/core/lib/event_engine/poller.h +14 -12
  117. data/src/core/lib/event_engine/posix_engine/timer_manager.cc +53 -32
  118. data/src/core/lib/event_engine/posix_engine/timer_manager.h +23 -1
  119. data/src/core/lib/event_engine/thread_pool.cc +131 -94
  120. data/src/core/lib/event_engine/thread_pool.h +56 -23
  121. data/src/core/lib/event_engine/time_util.cc +30 -0
  122. data/src/core/lib/event_engine/time_util.h +32 -0
  123. data/src/core/lib/event_engine/utils.cc +0 -5
  124. data/src/core/lib/event_engine/utils.h +0 -4
  125. data/src/core/lib/event_engine/windows/iocp.cc +13 -7
  126. data/src/core/lib/event_engine/windows/iocp.h +2 -1
  127. data/src/core/lib/event_engine/windows/win_socket.cc +1 -1
  128. data/src/core/lib/experiments/config.cc +146 -0
  129. data/src/core/lib/experiments/config.h +43 -0
  130. data/src/core/lib/experiments/experiments.cc +75 -0
  131. data/src/core/lib/experiments/experiments.h +56 -0
  132. data/src/core/lib/gpr/alloc.cc +1 -9
  133. data/src/core/lib/gpr/log_windows.cc +0 -1
  134. data/src/core/lib/gpr/string_util_windows.cc +3 -30
  135. data/src/core/lib/gpr/sync_abseil.cc +0 -14
  136. data/src/core/lib/gpr/sync_posix.cc +0 -14
  137. data/src/core/lib/gpr/time_posix.cc +0 -6
  138. data/src/core/lib/gpr/time_precise.h +1 -1
  139. data/src/core/lib/gpr/tmpfile_windows.cc +5 -7
  140. data/src/core/lib/gpr/useful.h +11 -0
  141. data/src/core/lib/{gpr → gprpp}/env.h +25 -12
  142. data/src/core/lib/{gpr → gprpp}/env_linux.cc +20 -15
  143. data/src/core/lib/{gpr → gprpp}/env_posix.cc +11 -10
  144. data/src/core/lib/gprpp/env_windows.cc +56 -0
  145. data/src/core/lib/gprpp/fork.cc +14 -22
  146. data/src/core/lib/gprpp/fork.h +0 -8
  147. data/src/core/lib/gprpp/global_config_env.cc +7 -6
  148. data/src/core/lib/gprpp/notification.h +67 -0
  149. data/src/core/lib/gprpp/packed_table.h +40 -0
  150. data/src/core/lib/gprpp/ref_counted_ptr.h +20 -33
  151. data/src/core/lib/gprpp/sorted_pack.h +98 -0
  152. data/src/core/lib/gprpp/status_helper.h +6 -0
  153. data/src/core/lib/gprpp/table.h +9 -1
  154. data/src/core/lib/gprpp/tchar.cc +49 -0
  155. data/src/core/lib/gprpp/tchar.h +33 -0
  156. data/src/core/lib/gprpp/time.cc +21 -0
  157. data/src/core/lib/gprpp/time.h +55 -0
  158. data/src/core/lib/gprpp/validation_errors.cc +61 -0
  159. data/src/core/lib/gprpp/validation_errors.h +110 -0
  160. data/src/core/{ext/filters/client_channel → lib/handshaker}/proxy_mapper.h +3 -3
  161. data/src/core/{ext/filters/client_channel → lib/handshaker}/proxy_mapper_registry.cc +14 -36
  162. data/src/core/lib/handshaker/proxy_mapper_registry.h +75 -0
  163. data/src/core/lib/iomgr/call_combiner.cc +0 -8
  164. data/src/core/lib/iomgr/closure.h +0 -1
  165. data/src/core/lib/iomgr/endpoint_pair_posix.cc +14 -10
  166. data/src/core/lib/iomgr/endpoint_pair_windows.cc +2 -2
  167. data/src/core/lib/iomgr/ev_epoll1_linux.cc +1 -38
  168. data/src/core/lib/iomgr/ev_poll_posix.cc +2 -17
  169. data/src/core/lib/iomgr/exec_ctx.cc +0 -10
  170. data/src/core/lib/iomgr/exec_ctx.h +7 -31
  171. data/src/core/lib/iomgr/iocp_windows.cc +1 -2
  172. data/src/core/lib/iomgr/iomgr.cc +6 -8
  173. data/src/core/lib/iomgr/iomgr_fwd.h +1 -0
  174. data/src/core/lib/iomgr/pollset.h +1 -1
  175. data/src/core/lib/iomgr/pollset_set.h +0 -1
  176. data/src/core/lib/iomgr/resolve_address.h +1 -0
  177. data/src/core/lib/iomgr/resolve_address_impl.h +1 -0
  178. data/src/core/lib/iomgr/resolve_address_posix.cc +1 -0
  179. data/src/core/lib/iomgr/resolve_address_windows.cc +1 -0
  180. data/src/core/lib/iomgr/sockaddr_utils_posix.cc +2 -1
  181. data/src/core/lib/iomgr/socket_utils_common_posix.cc +12 -34
  182. data/src/core/lib/iomgr/socket_utils_posix.cc +83 -1
  183. data/src/core/lib/iomgr/socket_utils_posix.h +98 -6
  184. data/src/core/lib/iomgr/tcp_client.cc +6 -7
  185. data/src/core/lib/iomgr/tcp_client.h +11 -11
  186. data/src/core/lib/iomgr/tcp_client_cfstream.cc +6 -6
  187. data/src/core/lib/iomgr/tcp_client_posix.cc +33 -29
  188. data/src/core/lib/iomgr/tcp_client_posix.h +12 -9
  189. data/src/core/lib/iomgr/tcp_client_windows.cc +6 -6
  190. data/src/core/lib/iomgr/tcp_posix.cc +131 -114
  191. data/src/core/lib/iomgr/tcp_posix.h +3 -1
  192. data/src/core/lib/iomgr/tcp_server.cc +5 -4
  193. data/src/core/lib/iomgr/tcp_server.h +9 -6
  194. data/src/core/lib/iomgr/tcp_server_posix.cc +17 -28
  195. data/src/core/lib/iomgr/tcp_server_utils_posix.h +2 -2
  196. data/src/core/lib/iomgr/tcp_server_utils_posix_common.cc +3 -3
  197. data/src/core/lib/iomgr/tcp_server_windows.cc +6 -7
  198. data/src/core/lib/iomgr/tcp_windows.cc +0 -1
  199. data/src/core/lib/iomgr/tcp_windows.h +0 -1
  200. data/src/core/lib/iomgr/timer_generic.cc +4 -4
  201. data/src/core/lib/iomgr/timer_manager.cc +1 -2
  202. data/src/core/lib/iomgr/wakeup_fd_eventfd.cc +0 -2
  203. data/src/core/lib/json/json_object_loader.cc +21 -52
  204. data/src/core/lib/json/json_object_loader.h +56 -76
  205. data/src/core/lib/json/json_util.cc +2 -1
  206. data/src/core/lib/load_balancing/lb_policy.h +5 -5
  207. data/src/core/lib/load_balancing/lb_policy_registry.cc +29 -55
  208. data/src/core/lib/load_balancing/lb_policy_registry.h +23 -11
  209. data/src/core/lib/promise/activity.h +2 -3
  210. data/src/core/lib/promise/context.h +1 -1
  211. data/src/core/lib/promise/sleep.cc +16 -4
  212. data/src/core/lib/promise/sleep.h +8 -2
  213. data/src/core/lib/resolver/resolver.h +13 -3
  214. data/src/core/lib/resource_quota/api.cc +9 -0
  215. data/src/core/lib/resource_quota/api.h +6 -0
  216. data/src/core/lib/resource_quota/arena.cc +1 -3
  217. data/src/core/lib/resource_quota/memory_quota.cc +8 -24
  218. data/src/core/lib/resource_quota/memory_quota.h +6 -19
  219. data/src/core/lib/resource_quota/periodic_update.cc +2 -3
  220. data/src/core/{ext/xds → lib/security/certificate_provider}/certificate_provider_factory.h +3 -3
  221. data/src/core/lib/security/certificate_provider/certificate_provider_registry.cc +60 -0
  222. data/src/core/lib/security/certificate_provider/certificate_provider_registry.h +70 -0
  223. data/src/core/lib/security/credentials/channel_creds_registry_init.cc +1 -0
  224. data/src/core/lib/security/credentials/external/aws_external_account_credentials.cc +15 -16
  225. data/src/core/lib/security/credentials/external/external_account_credentials.cc +2 -1
  226. data/src/core/lib/security/credentials/google_default/credentials_generic.cc +5 -8
  227. data/src/core/lib/security/credentials/google_default/google_default_credentials.cc +6 -6
  228. data/src/core/lib/security/credentials/jwt/jwt_verifier.cc +3 -2
  229. data/src/core/lib/security/credentials/jwt/jwt_verifier.h +1 -1
  230. data/src/core/lib/security/credentials/oauth2/oauth2_credentials.cc +1 -2
  231. data/src/core/lib/security/credentials/tls/grpc_tls_certificate_provider.cc +4 -3
  232. data/src/core/lib/security/credentials/tls/grpc_tls_certificate_provider.h +4 -2
  233. data/src/core/lib/security/credentials/tls/tls_utils.cc +3 -1
  234. data/src/core/lib/security/transport/client_auth_filter.cc +12 -1
  235. data/src/core/lib/security/transport/secure_endpoint.cc +0 -4
  236. data/src/core/lib/surface/call.cc +1 -11
  237. data/src/core/lib/surface/channel.cc +3 -2
  238. data/src/core/lib/surface/completion_queue.cc +16 -28
  239. data/src/core/lib/surface/completion_queue.h +1 -1
  240. data/src/core/lib/surface/completion_queue_factory.cc +5 -0
  241. data/src/core/lib/surface/init.cc +16 -11
  242. data/src/core/lib/surface/init_internally.cc +24 -0
  243. data/src/core/lib/surface/init_internally.h +28 -0
  244. data/src/core/lib/surface/server.cc +1 -7
  245. data/src/core/lib/surface/server.h +4 -6
  246. data/src/core/lib/surface/version.cc +2 -2
  247. data/src/core/lib/transport/bdp_estimator.cc +1 -3
  248. data/src/core/lib/transport/metadata_batch.cc +2 -3
  249. data/src/core/lib/transport/metadata_batch.h +9 -7
  250. data/src/core/lib/transport/parsed_metadata.h +4 -2
  251. data/src/core/lib/transport/status_conversion.cc +1 -3
  252. data/src/core/lib/transport/tcp_connect_handshaker.cc +9 -5
  253. data/src/core/lib/transport/transport.h +0 -1
  254. data/src/core/lib/transport/transport_impl.h +0 -1
  255. data/src/core/plugin_registry/grpc_plugin_registry.cc +23 -46
  256. data/src/core/plugin_registry/grpc_plugin_registry_extra.cc +13 -25
  257. data/src/ruby/lib/grpc/version.rb +1 -1
  258. data/src/ruby/spec/channel_spec.rb +5 -0
  259. data/src/ruby/spec/generic/server_interceptors_spec.rb +1 -1
  260. data/src/ruby/spec/user_agent_spec.rb +1 -1
  261. metadata +33 -19
  262. data/src/core/ext/filters/client_channel/proxy_mapper_registry.h +0 -56
  263. data/src/core/ext/xds/certificate_provider_registry.cc +0 -103
  264. data/src/core/ext/xds/certificate_provider_registry.h +0 -59
  265. data/src/core/lib/event_engine/promise.h +0 -78
  266. data/src/core/lib/gpr/env_windows.cc +0 -74
  267. data/src/core/lib/gpr/string_windows.h +0 -32
  268. data/src/core/lib/profiling/basic_timers.cc +0 -295
  269. data/src/core/lib/profiling/stap_timers.cc +0 -50
  270. data/src/core/lib/profiling/timers.h +0 -94
@@ -35,18 +35,13 @@
35
35
 
36
36
  #include <grpc/support/log.h>
37
37
 
38
+ #include "src/core/ext/transport/chttp2/transport/http2_settings.h"
39
+ #include "src/core/lib/experiments/experiments.h"
38
40
  #include "src/core/lib/gpr/useful.h"
39
- #include "src/core/lib/gprpp/global_config_env.h"
40
- #include "src/core/lib/iomgr/exec_ctx.h"
41
41
  #include "src/core/lib/resource_quota/memory_quota.h"
42
42
 
43
43
  grpc_core::TraceFlag grpc_flowctl_trace(false, "flowctl");
44
44
 
45
- GPR_GLOBAL_CONFIG_DEFINE_BOOL(
46
- grpc_experimental_broad_flow_control_range, false,
47
- "Use an enlarged memory pressure range for scaling flow control when using "
48
- "a resource quota.");
49
-
50
45
  namespace grpc_core {
51
46
  namespace chttp2 {
52
47
 
@@ -118,7 +113,7 @@ TransportFlowControl::TransportFlowControl(const char* name,
118
113
  .set_min_control_value(-1)
119
114
  .set_max_control_value(25)
120
115
  .set_integral_range(10)),
121
- last_pid_update_(ExecCtx::Get()->Now()) {}
116
+ last_pid_update_(Timestamp::Now()) {}
122
117
 
123
118
  uint32_t TransportFlowControl::MaybeSendUpdate(bool writing_anyway) {
124
119
  const uint32_t target_announced_window =
@@ -211,7 +206,7 @@ double TransportFlowControl::TargetLogBdp() {
211
206
  }
212
207
 
213
208
  double TransportFlowControl::SmoothLogBdp(double value) {
214
- Timestamp now = ExecCtx::Get()->Now();
209
+ Timestamp now = Timestamp::Now();
215
210
  double bdp_error = value - pid_controller_.last_control_value();
216
211
  const double dt = (now - last_pid_update_).seconds();
217
212
  last_pid_update_ = now;
@@ -274,56 +269,93 @@ TransportFlowControl::TargetInitialWindowSizeBasedOnMemoryPressureAndBdp()
274
269
  }
275
270
 
276
271
  void TransportFlowControl::UpdateSetting(
277
- int64_t* desired_value, int64_t new_desired_value,
278
- FlowControlAction* action,
272
+ grpc_chttp2_setting_id id, int64_t* desired_value,
273
+ uint32_t new_desired_value, FlowControlAction* action,
279
274
  FlowControlAction& (FlowControlAction::*set)(FlowControlAction::Urgency,
280
275
  uint32_t)) {
281
- int64_t delta = new_desired_value - *desired_value;
282
- // TODO(ncteisen): tune this
283
- if (delta != 0 &&
284
- (delta <= -*desired_value / 5 || delta >= *desired_value / 5)) {
285
- *desired_value = new_desired_value;
286
- (action->*set)(FlowControlAction::Urgency::QUEUE_UPDATE, *desired_value);
276
+ if (IsFlowControlFixesEnabled()) {
277
+ new_desired_value =
278
+ Clamp(new_desired_value, grpc_chttp2_settings_parameters[id].min_value,
279
+ grpc_chttp2_settings_parameters[id].max_value);
280
+ if (new_desired_value != *desired_value) {
281
+ *desired_value = new_desired_value;
282
+ (action->*set)(FlowControlAction::Urgency::QUEUE_UPDATE, *desired_value);
283
+ }
284
+ } else {
285
+ int64_t delta = new_desired_value - *desired_value;
286
+ // TODO(ncteisen): tune this
287
+ if (delta != 0 &&
288
+ (delta <= -*desired_value / 5 || delta >= *desired_value / 5)) {
289
+ *desired_value = new_desired_value;
290
+ (action->*set)(FlowControlAction::Urgency::QUEUE_UPDATE, *desired_value);
291
+ }
287
292
  }
288
293
  }
289
294
 
290
295
  FlowControlAction TransportFlowControl::PeriodicUpdate() {
291
- static const bool kSmoothMemoryPressure =
292
- GPR_GLOBAL_CONFIG_GET(grpc_experimental_smooth_memory_presure);
293
296
  FlowControlAction action;
294
297
  if (enable_bdp_probe_) {
295
- // get bdp estimate and update initial_window accordingly.
296
- // target might change based on how much memory pressure we are under
297
- // TODO(ncteisen): experiment with setting target to be huge under low
298
- // memory pressure.
299
- double target = kSmoothMemoryPressure
300
- ? TargetInitialWindowSizeBasedOnMemoryPressureAndBdp()
301
- : pow(2, SmoothLogBdp(TargetLogBdp()));
302
- if (g_test_only_transport_target_window_estimates_mocker != nullptr) {
303
- // Hook for simulating unusual flow control situations in tests.
304
- target = g_test_only_transport_target_window_estimates_mocker
305
- ->ComputeNextTargetInitialWindowSizeFromPeriodicUpdate(
306
- target_initial_window_size_ /* current target */);
298
+ if (IsFlowControlFixesEnabled()) {
299
+ // get bdp estimate and update initial_window accordingly.
300
+ // target might change based on how much memory pressure we are under
301
+ // TODO(ncteisen): experiment with setting target to be huge under low
302
+ // memory pressure.
303
+ uint32_t target = static_cast<uint32_t>(RoundUpToPowerOf2(
304
+ Clamp(IsMemoryPressureControllerEnabled()
305
+ ? TargetInitialWindowSizeBasedOnMemoryPressureAndBdp()
306
+ : pow(2, SmoothLogBdp(TargetLogBdp())),
307
+ 0.0, static_cast<double>(kMaxInitialWindowSize))));
308
+ if (target < kMinPositiveInitialWindowSize) target = 0;
309
+ if (g_test_only_transport_target_window_estimates_mocker != nullptr) {
310
+ // Hook for simulating unusual flow control situations in tests.
311
+ target = g_test_only_transport_target_window_estimates_mocker
312
+ ->ComputeNextTargetInitialWindowSizeFromPeriodicUpdate(
313
+ target_initial_window_size_ /* current target */);
314
+ }
315
+ // Though initial window 'could' drop to 0, we keep the floor at
316
+ // kMinInitialWindowSize
317
+ UpdateSetting(GRPC_CHTTP2_SETTINGS_INITIAL_WINDOW_SIZE,
318
+ &target_initial_window_size_, target, &action,
319
+ &FlowControlAction::set_send_initial_window_update);
320
+ // we target the max of BDP or bandwidth in microseconds.
321
+ UpdateSetting(GRPC_CHTTP2_SETTINGS_MAX_FRAME_SIZE, &target_frame_size_,
322
+ target, &action,
323
+ &FlowControlAction::set_send_max_frame_size_update);
324
+ } else {
325
+ // get bdp estimate and update initial_window accordingly.
326
+ // target might change based on how much memory pressure we are under
327
+ // TODO(ncteisen): experiment with setting target to be huge under low
328
+ // memory pressure.
329
+ double target = IsMemoryPressureControllerEnabled()
330
+ ? TargetInitialWindowSizeBasedOnMemoryPressureAndBdp()
331
+ : pow(2, SmoothLogBdp(TargetLogBdp()));
332
+ if (g_test_only_transport_target_window_estimates_mocker != nullptr) {
333
+ // Hook for simulating unusual flow control situations in tests.
334
+ target = g_test_only_transport_target_window_estimates_mocker
335
+ ->ComputeNextTargetInitialWindowSizeFromPeriodicUpdate(
336
+ target_initial_window_size_ /* current target */);
337
+ }
338
+ // Though initial window 'could' drop to 0, we keep the floor at
339
+ // kMinInitialWindowSize
340
+ UpdateSetting(
341
+ GRPC_CHTTP2_SETTINGS_INITIAL_WINDOW_SIZE,
342
+ &target_initial_window_size_,
343
+ static_cast<int32_t>(Clamp(target, double(kMinInitialWindowSize),
344
+ double(kMaxInitialWindowSize))),
345
+ &action, &FlowControlAction::set_send_initial_window_update);
346
+ // get bandwidth estimate and update max_frame accordingly.
347
+ double bw_dbl = bdp_estimator_.EstimateBandwidth();
348
+ // we target the max of BDP or bandwidth in microseconds.
349
+ UpdateSetting(
350
+ GRPC_CHTTP2_SETTINGS_MAX_FRAME_SIZE, &target_frame_size_,
351
+ static_cast<int32_t>(Clamp(
352
+ std::max(
353
+ static_cast<int32_t>(Clamp(bw_dbl, 0.0, double(INT_MAX))) /
354
+ 1000,
355
+ static_cast<int32_t>(target_initial_window_size_)),
356
+ 16384, 16777215)),
357
+ &action, &FlowControlAction::set_send_max_frame_size_update);
307
358
  }
308
- // Though initial window 'could' drop to 0, we keep the floor at
309
- // kMinInitialWindowSize
310
- UpdateSetting(
311
- &target_initial_window_size_,
312
- static_cast<int32_t>(Clamp(target, double(kMinInitialWindowSize),
313
- double(kMaxInitialWindowSize))),
314
- &action, &FlowControlAction::set_send_initial_window_update);
315
-
316
- // get bandwidth estimate and update max_frame accordingly.
317
- double bw_dbl = bdp_estimator_.EstimateBandwidth();
318
- // we target the max of BDP or bandwidth in microseconds.
319
- UpdateSetting(
320
- &target_frame_size_,
321
- static_cast<int32_t>(Clamp(
322
- std::max(static_cast<int32_t>(Clamp(bw_dbl, 0.0, double(INT_MAX))) /
323
- 1000,
324
- static_cast<int32_t>(target_initial_window_size_)),
325
- 16384, 16777215)),
326
- &action, &FlowControlAction::set_send_max_frame_size_update);
327
359
  }
328
360
  return UpdateAction(action);
329
361
  }
@@ -358,7 +390,7 @@ uint32_t StreamFlowControl::DesiredAnnounceSize() const {
358
390
  FlowControlAction StreamFlowControl::UpdateAction(FlowControlAction action) {
359
391
  const int64_t desired_announce_size = DesiredAnnounceSize();
360
392
  if (desired_announce_size > 0) {
361
- if ((min_progress_size_ > 0 && announced_window_delta_ < 0) ||
393
+ if ((min_progress_size_ > 0 && announced_window_delta_ <= 0) ||
362
394
  desired_announce_size >= 8192) {
363
395
  action.set_send_stream_update(
364
396
  FlowControlAction::Urgency::UPDATE_IMMEDIATELY);
@@ -25,14 +25,15 @@
25
25
 
26
26
  #include <iosfwd>
27
27
  #include <string>
28
+ #include <utility>
28
29
 
29
30
  #include "absl/functional/function_ref.h"
30
31
  #include "absl/status/status.h"
31
32
  #include "absl/types/optional.h"
32
- #include "absl/utility/utility.h"
33
33
 
34
34
  #include <grpc/support/log.h>
35
35
 
36
+ #include "src/core/ext/transport/chttp2/transport/http2_settings.h"
36
37
  #include "src/core/lib/debug/trace.h"
37
38
  #include "src/core/lib/gprpp/time.h"
38
39
  #include "src/core/lib/resource_quota/memory_quota.h"
@@ -53,13 +54,16 @@ namespace chttp2 {
53
54
  static constexpr uint32_t kDefaultWindow = 65535;
54
55
  static constexpr uint32_t kDefaultFrameSize = 16384;
55
56
  static constexpr int64_t kMaxWindow = static_cast<int64_t>((1u << 31) - 1);
56
- // TODO(ncteisen): Tune this
57
- static constexpr uint32_t kFrameSize = 1024 * 1024;
58
- static constexpr const uint32_t kMinInitialWindowSize = 128;
57
+ // If smaller than this, advertise zero window.
58
+ static constexpr uint32_t kMinPositiveInitialWindowSize = 1024;
59
59
  static constexpr const uint32_t kMaxInitialWindowSize = (1u << 30);
60
60
  // The maximum per-stream flow control window delta to advertise.
61
61
  static constexpr const int64_t kMaxWindowDelta = (1u << 20);
62
62
 
63
+ // TODO(ctiller): clean up when flow_control_fixes is enabled by default
64
+ static constexpr uint32_t kFrameSize = 1024 * 1024;
65
+ static constexpr const uint32_t kMinInitialWindowSize = 128;
66
+
63
67
  class TransportFlowControl;
64
68
  class StreamFlowControl;
65
69
 
@@ -170,7 +174,7 @@ class TransportFlowControl final {
170
174
  // Reads the flow control data and returns an actionable struct that will
171
175
  // tell chttp2 exactly what it needs to do
172
176
  FlowControlAction MakeAction() {
173
- return absl::exchange(tfc_, nullptr)->UpdateAction(FlowControlAction());
177
+ return std::exchange(tfc_, nullptr)->UpdateAction(FlowControlAction());
174
178
  }
175
179
 
176
180
  // Notify of data receipt. Returns OkStatus if the data was accepted,
@@ -253,7 +257,8 @@ class TransportFlowControl final {
253
257
  double TargetLogBdp();
254
258
  double SmoothLogBdp(double value);
255
259
  double TargetInitialWindowSizeBasedOnMemoryPressureAndBdp() const;
256
- static void UpdateSetting(int64_t* desired_value, int64_t new_desired_value,
260
+ static void UpdateSetting(grpc_chttp2_setting_id id, int64_t* desired_value,
261
+ uint32_t new_desired_value,
257
262
  FlowControlAction* action,
258
263
  FlowControlAction& (FlowControlAction::*set)(
259
264
  FlowControlAction::Urgency, uint32_t));
@@ -32,7 +32,6 @@
32
32
  #include "src/core/ext/transport/chttp2/transport/internal.h"
33
33
  #include "src/core/ext/transport/chttp2/transport/stream_map.h"
34
34
  #include "src/core/lib/gprpp/time.h"
35
- #include "src/core/lib/iomgr/exec_ctx.h"
36
35
 
37
36
  static bool g_disable_ping_ack = false;
38
37
 
@@ -95,7 +94,7 @@ grpc_error_handle grpc_chttp2_ping_parser_parse(void* parser,
95
94
  grpc_chttp2_ack_ping(t, p->opaque_8bytes);
96
95
  } else {
97
96
  if (!t->is_client) {
98
- grpc_core::Timestamp now = grpc_core::ExecCtx::Get()->Now();
97
+ grpc_core::Timestamp now = grpc_core::Timestamp::Now();
99
98
  grpc_core::Timestamp next_allowed_ping =
100
99
  t->ping_recv_state.last_ping_recv_time +
101
100
  t->ping_policy.min_recv_ping_interval_without_data;
@@ -24,8 +24,6 @@
24
24
  #include <cstdint>
25
25
  #include <memory>
26
26
 
27
- #include "absl/utility/utility.h"
28
-
29
27
  #include <grpc/slice.h>
30
28
  #include <grpc/slice_buffer.h>
31
29
  #include <grpc/support/log.h>
@@ -35,8 +33,6 @@
35
33
  #include "src/core/ext/transport/chttp2/transport/hpack_constants.h"
36
34
  #include "src/core/ext/transport/chttp2/transport/hpack_encoder_table.h"
37
35
  #include "src/core/ext/transport/chttp2/transport/varint.h"
38
- #include "src/core/lib/debug/stats.h"
39
- #include "src/core/lib/iomgr/exec_ctx.h"
40
36
  #include "src/core/lib/surface/validate_metadata.h"
41
37
  #include "src/core/lib/transport/timeout_encoding.h"
42
38
 
@@ -158,7 +154,6 @@ uint8_t* HPackCompressor::Framer::AddTiny(size_t len) {
158
154
  }
159
155
 
160
156
  void HPackCompressor::Framer::EmitIndexed(uint32_t elem_index) {
161
- GRPC_STATS_INC_HPACK_SEND_INDEXED();
162
157
  VarintWriter<1> w(elem_index);
163
158
  w.Write(0x80, AddTiny(w.length()));
164
159
  }
@@ -180,17 +175,14 @@ static WireValue GetWireValue(Slice value, bool true_binary_enabled,
180
175
  bool is_bin_hdr) {
181
176
  if (is_bin_hdr) {
182
177
  if (true_binary_enabled) {
183
- GRPC_STATS_INC_HPACK_SEND_BINARY();
184
178
  return WireValue(0x00, true, std::move(value));
185
179
  } else {
186
- GRPC_STATS_INC_HPACK_SEND_BINARY_BASE64();
187
180
  return WireValue(0x80, false,
188
181
  Slice(grpc_chttp2_base64_encode_and_huffman_compress(
189
182
  value.c_slice())));
190
183
  }
191
184
  } else {
192
185
  /* TODO(ctiller): opportunistically compress non-binary headers */
193
- GRPC_STATS_INC_HPACK_SEND_UNCOMPRESSED();
194
186
  return WireValue(0x00, false, std::move(value));
195
187
  }
196
188
  }
@@ -269,8 +261,6 @@ class StringKey {
269
261
 
270
262
  void HPackCompressor::Framer::EmitLitHdrWithNonBinaryStringKeyIncIdx(
271
263
  Slice key_slice, Slice value_slice) {
272
- GRPC_STATS_INC_HPACK_SEND_LITHDR_INCIDX_V();
273
- GRPC_STATS_INC_HPACK_SEND_UNCOMPRESSED();
274
264
  StringKey key(std::move(key_slice));
275
265
  key.WritePrefix(0x40, AddTiny(key.prefix_length()));
276
266
  Add(key.key());
@@ -281,8 +271,6 @@ void HPackCompressor::Framer::EmitLitHdrWithNonBinaryStringKeyIncIdx(
281
271
 
282
272
  void HPackCompressor::Framer::EmitLitHdrWithBinaryStringKeyNotIdx(
283
273
  Slice key_slice, Slice value_slice) {
284
- GRPC_STATS_INC_HPACK_SEND_LITHDR_NOTIDX_V();
285
- GRPC_STATS_INC_HPACK_SEND_UNCOMPRESSED();
286
274
  StringKey key(std::move(key_slice));
287
275
  key.WritePrefix(0x00, AddTiny(key.prefix_length()));
288
276
  Add(key.key());
@@ -293,8 +281,6 @@ void HPackCompressor::Framer::EmitLitHdrWithBinaryStringKeyNotIdx(
293
281
 
294
282
  void HPackCompressor::Framer::EmitLitHdrWithBinaryStringKeyIncIdx(
295
283
  Slice key_slice, Slice value_slice) {
296
- GRPC_STATS_INC_HPACK_SEND_LITHDR_INCIDX_V();
297
- GRPC_STATS_INC_HPACK_SEND_UNCOMPRESSED();
298
284
  StringKey key(std::move(key_slice));
299
285
  key.WritePrefix(0x40, AddTiny(key.prefix_length()));
300
286
  Add(key.key());
@@ -305,8 +291,6 @@ void HPackCompressor::Framer::EmitLitHdrWithBinaryStringKeyIncIdx(
305
291
 
306
292
  void HPackCompressor::Framer::EmitLitHdrWithBinaryStringKeyNotIdx(
307
293
  uint32_t key_index, Slice value_slice) {
308
- GRPC_STATS_INC_HPACK_SEND_LITHDR_NOTIDX();
309
- GRPC_STATS_INC_HPACK_SEND_UNCOMPRESSED();
310
294
  BinaryStringValue emit(std::move(value_slice), use_true_binary_metadata_);
311
295
  VarintWriter<4> key(key_index);
312
296
  uint8_t* data = AddTiny(key.length() + emit.prefix_length());
@@ -317,8 +301,6 @@ void HPackCompressor::Framer::EmitLitHdrWithBinaryStringKeyNotIdx(
317
301
 
318
302
  void HPackCompressor::Framer::EmitLitHdrWithNonBinaryStringKeyNotIdx(
319
303
  Slice key_slice, Slice value_slice) {
320
- GRPC_STATS_INC_HPACK_SEND_LITHDR_NOTIDX_V();
321
- GRPC_STATS_INC_HPACK_SEND_UNCOMPRESSED();
322
304
  StringKey key(std::move(key_slice));
323
305
  key.WritePrefix(0x00, AddTiny(key.prefix_length()));
324
306
  Add(key.key());
@@ -536,7 +518,7 @@ void HPackCompressor::Framer::EncodeRepeatingSliceValue(
536
518
  }
537
519
 
538
520
  void HPackCompressor::Framer::Encode(GrpcTimeoutMetadata, Timestamp deadline) {
539
- Timeout timeout = Timeout::FromDuration(deadline - ExecCtx::Get()->Now());
521
+ Timeout timeout = Timeout::FromDuration(deadline - Timestamp::Now());
540
522
  for (auto it = compressor_->previous_timeouts_.begin();
541
523
  it != compressor_->previous_timeouts_.end(); ++it) {
542
524
  double ratio = timeout.RatioVersus(it->timeout);
@@ -678,7 +660,7 @@ HPackCompressor::Framer::Framer(const EncodeHeaderOptions& options,
678
660
  stats_(options.stats),
679
661
  compressor_(compressor),
680
662
  prefix_(BeginFrame()) {
681
- if (absl::exchange(compressor_->advertise_table_size_change_, false)) {
663
+ if (std::exchange(compressor_->advertise_table_size_change_, false)) {
682
664
  AdvertiseTableSizeChange();
683
665
  }
684
666
  }
@@ -43,14 +43,14 @@
43
43
  #include <grpc/status.h>
44
44
  #include <grpc/support/log.h>
45
45
 
46
+ #include "src/core/ext/transport/chttp2/transport/decode_huff.h"
46
47
  #include "src/core/ext/transport/chttp2/transport/frame_rst_stream.h"
47
48
  #include "src/core/ext/transport/chttp2/transport/hpack_constants.h"
48
49
  #include "src/core/ext/transport/chttp2/transport/internal.h"
49
- #include "src/core/lib/debug/stats.h"
50
50
  #include "src/core/lib/debug/trace.h"
51
+ #include "src/core/lib/experiments/experiments.h"
51
52
  #include "src/core/lib/iomgr/closure.h"
52
53
  #include "src/core/lib/iomgr/combiner.h"
53
- #include "src/core/lib/profiling/timers.h"
54
54
  #include "src/core/lib/slice/slice.h"
55
55
  #include "src/core/lib/slice/slice_refcount_base.h"
56
56
  #include "src/core/lib/transport/http2_errors.h"
@@ -66,8 +66,9 @@ TraceFlag grpc_trace_chttp2_hpack_parser(false, "chttp2_hpack_parser");
66
66
  /* state table for huffman decoding: given a state, gives an index/16 into
67
67
  next_sub_tbl. Taking that index and adding the value of the nibble being
68
68
  considered returns the next state.
69
-
70
- generated by gen_hpack_tables.c */
69
+ generated by gen_hpack_tables.c
70
+ TODO(ctiller): remove once the new_hpack_huffman_decoder experiment is
71
+ complete. */
71
72
  static const uint8_t next_tbl[256] = {
72
73
  0, 1, 2, 3, 4, 1, 2, 5, 6, 1, 7, 8, 1, 3, 3, 9, 10, 11, 1, 1,
73
74
  1, 12, 1, 2, 13, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2,
@@ -143,7 +144,6 @@ static const int16_t next_sub_tbl[48 * 16] = {
143
144
 
144
145
  /* emission table: indexed like next_tbl, ultimately gives the byte to be
145
146
  emitted, or -1 for no byte, or 256 for end of stream
146
-
147
147
  generated by gen_hpack_tables.c */
148
148
  static const uint16_t emit_tbl[256] = {
149
149
  0, 1, 2, 3, 4, 5, 6, 7, 0, 8, 9, 10, 11, 12, 13,
@@ -766,22 +766,6 @@ class HPackParser::String {
766
766
  // decoded byte.
767
767
  template <typename Out>
768
768
  static bool ParseHuff(Input* input, uint32_t length, Out output) {
769
- GRPC_STATS_INC_HPACK_RECV_HUFFMAN();
770
- int16_t state = 0;
771
- // Parse one half byte... we leverage some lookup tables to keep the logic
772
- // here really simple.
773
- auto nibble = [&output, &state](uint8_t nibble) {
774
- int16_t emit = emit_sub_tbl[16 * emit_tbl[state] + nibble];
775
- int16_t next = next_sub_tbl[16 * next_tbl[state] + nibble];
776
- if (emit != -1) {
777
- if (emit >= 0 && emit < 256) {
778
- output(static_cast<uint8_t>(emit));
779
- } else {
780
- assert(emit == 256);
781
- }
782
- }
783
- state = next;
784
- };
785
769
  // If there's insufficient bytes remaining, return now.
786
770
  if (input->remaining() < length) {
787
771
  return input->UnexpectedEOF(false);
@@ -789,17 +773,35 @@ class HPackParser::String {
789
773
  // Grab the byte range, and iterate through it.
790
774
  const uint8_t* p = input->cur_ptr();
791
775
  input->Advance(length);
792
- for (uint32_t i = 0; i < length; i++) {
793
- nibble(p[i] >> 4);
794
- nibble(p[i] & 0xf);
776
+ if (IsNewHpackHuffmanDecoderEnabled()) {
777
+ return HuffDecoder<Out>(output, p, p + length).Run();
778
+ } else {
779
+ int16_t state = 0;
780
+ // Parse one half byte... we leverage some lookup tables to keep the logic
781
+ // here really simple.
782
+ auto nibble = [&output, &state](uint8_t nibble) {
783
+ int16_t emit = emit_sub_tbl[16 * emit_tbl[state] + nibble];
784
+ int16_t next = next_sub_tbl[16 * next_tbl[state] + nibble];
785
+ if (emit != -1) {
786
+ if (emit >= 0 && emit < 256) {
787
+ output(static_cast<uint8_t>(emit));
788
+ } else {
789
+ assert(emit == 256);
790
+ }
791
+ }
792
+ state = next;
793
+ };
794
+ for (uint32_t i = 0; i < length; i++) {
795
+ nibble(p[i] >> 4);
796
+ nibble(p[i] & 0xf);
797
+ }
798
+ return true;
795
799
  }
796
- return true;
797
800
  }
798
801
 
799
802
  // Parse some uncompressed string bytes.
800
803
  static absl::optional<String> ParseUncompressed(Input* input,
801
804
  uint32_t length) {
802
- GRPC_STATS_INC_HPACK_RECV_UNCOMPRESSED();
803
805
  // Check there's enough bytes
804
806
  if (input->remaining() < length) {
805
807
  return input->UnexpectedEOF(absl::optional<String>());
@@ -1161,7 +1163,6 @@ class HPackParser::Parser {
1161
1163
  if (GPR_UNLIKELY(elem == nullptr)) {
1162
1164
  return InvalidHPackIndexError(*index, false);
1163
1165
  }
1164
- GRPC_STATS_INC_HPACK_RECV_INDEXED();
1165
1166
  return FinishHeaderOmitFromTable(*elem);
1166
1167
  }
1167
1168
 
@@ -1347,7 +1348,6 @@ grpc_error_handle grpc_chttp2_header_parser_parse(void* hpack_parser,
1347
1348
  grpc_chttp2_stream* s,
1348
1349
  const grpc_slice& slice,
1349
1350
  int is_last) {
1350
- GPR_TIMER_SCOPE("grpc_chttp2_header_parser_parse", 0);
1351
1351
  auto* parser = static_cast<grpc_core::HPackParser*>(hpack_parser);
1352
1352
  if (s != nullptr) {
1353
1353
  s->stats.incoming.header_bytes += GRPC_SLICE_LENGTH(slice);
@@ -78,10 +78,6 @@ void HPackTable::MementoRingBuffer::Rebuild(uint32_t max_entries) {
78
78
  entries_.swap(entries);
79
79
  }
80
80
 
81
- HPackTable::HPackTable() : static_metadata_(GetStaticMementos()) {}
82
-
83
- HPackTable::~HPackTable() = default;
84
-
85
81
  /* Evict one element from the table */
86
82
  void HPackTable::EvictOne() {
87
83
  auto first_entry = entries_.PopOne();
@@ -229,7 +225,7 @@ const StaticTableEntry kStaticTable[hpack_constants::kLastStaticEntry] = {
229
225
  {"www-authenticate", ""},
230
226
  };
231
227
 
232
- GPR_ATTRIBUTE_NOINLINE HPackTable::Memento MakeMemento(size_t i) {
228
+ HPackTable::Memento MakeMemento(size_t i) {
233
229
  auto sm = kStaticTable[i];
234
230
  return grpc_metadata_batch::Parse(
235
231
  sm.key, Slice::FromStaticString(sm.value),
@@ -241,11 +237,6 @@ GPR_ATTRIBUTE_NOINLINE HPackTable::Memento MakeMemento(size_t i) {
241
237
 
242
238
  } // namespace
243
239
 
244
- auto HPackTable::GetStaticMementos() -> const StaticMementos& {
245
- static const StaticMementos* const static_mementos = new StaticMementos();
246
- return *static_mementos;
247
- }
248
-
249
240
  HPackTable::StaticMementos::StaticMementos() {
250
241
  for (uint32_t i = 0; i < hpack_constants::kLastStaticEntry; i++) {
251
242
  memento[i] = MakeMemento(i);
@@ -26,6 +26,7 @@
26
26
  #include <vector>
27
27
 
28
28
  #include "src/core/ext/transport/chttp2/transport/hpack_constants.h"
29
+ #include "src/core/lib/gprpp/no_destruct.h"
29
30
  #include "src/core/lib/iomgr/error.h"
30
31
  #include "src/core/lib/transport/metadata_batch.h"
31
32
  #include "src/core/lib/transport/parsed_metadata.h"
@@ -35,8 +36,8 @@ namespace grpc_core {
35
36
  // HPACK header table
36
37
  class HPackTable {
37
38
  public:
38
- HPackTable();
39
- ~HPackTable();
39
+ HPackTable() = default;
40
+ ~HPackTable() = default;
40
41
 
41
42
  HPackTable(const HPackTable&) = delete;
42
43
  HPackTable& operator=(const HPackTable&) = delete;
@@ -55,7 +56,7 @@ class HPackTable {
55
56
  // reading the core static metadata table here; at that point we'd need our
56
57
  // own singleton static metadata in the correct order.
57
58
  if (index <= hpack_constants::kLastStaticEntry) {
58
- return &static_metadata_.memento[index - 1];
59
+ return &static_mementos_->memento[index - 1];
59
60
  } else {
60
61
  return LookupDynamic(index);
61
62
  }
@@ -72,7 +73,6 @@ class HPackTable {
72
73
  StaticMementos();
73
74
  Memento memento[hpack_constants::kLastStaticEntry];
74
75
  };
75
- static const StaticMementos& GetStaticMementos() GPR_ATTRIBUTE_NOINLINE;
76
76
 
77
77
  class MementoRingBuffer {
78
78
  public:
@@ -114,6 +114,11 @@ class HPackTable {
114
114
 
115
115
  void EvictOne();
116
116
 
117
+ static const StaticMementos* GetStaticMementos() {
118
+ static const NoDestruct<StaticMementos> static_mementos;
119
+ return static_mementos.get();
120
+ }
121
+
117
122
  // The amount of memory used by the table, according to the hpack algorithm
118
123
  uint32_t mem_used_ = 0;
119
124
  // The max memory allowed to be used by the table, according to the hpack
@@ -123,8 +128,8 @@ class HPackTable {
123
128
  uint32_t current_table_bytes_ = hpack_constants::kInitialTableSize;
124
129
  // HPack table entries
125
130
  MementoRingBuffer entries_;
126
- // Mementos for static data
127
- const StaticMementos& static_metadata_;
131
+ // Static mementos
132
+ const StaticMementos* const static_mementos_ = GetStaticMementos();
128
133
  };
129
134
 
130
135
  } // namespace grpc_core
@@ -782,4 +782,6 @@ void grpc_chttp2_retry_initiate_ping(void* tp, grpc_error_handle error);
782
782
 
783
783
  void schedule_bdp_ping_locked(grpc_chttp2_transport* t);
784
784
 
785
+ uint32_t grpc_chttp2_min_read_progress_size(grpc_chttp2_transport* t);
786
+
785
787
  #endif /* GRPC_CORE_EXT_TRANSPORT_CHTTP2_TRANSPORT_INTERNAL_H */
@@ -79,6 +79,50 @@ static char get_utf8_safe_char(char c) {
79
79
  return static_cast<unsigned char>(c) < 128 ? c : 32;
80
80
  }
81
81
 
82
+ uint32_t grpc_chttp2_min_read_progress_size(grpc_chttp2_transport* t) {
83
+ switch (t->deframe_state) {
84
+ case GRPC_DTS_CLIENT_PREFIX_0:
85
+ case GRPC_DTS_CLIENT_PREFIX_1:
86
+ case GRPC_DTS_CLIENT_PREFIX_2:
87
+ case GRPC_DTS_CLIENT_PREFIX_3:
88
+ case GRPC_DTS_CLIENT_PREFIX_4:
89
+ case GRPC_DTS_CLIENT_PREFIX_5:
90
+ case GRPC_DTS_CLIENT_PREFIX_6:
91
+ case GRPC_DTS_CLIENT_PREFIX_7:
92
+ case GRPC_DTS_CLIENT_PREFIX_8:
93
+ case GRPC_DTS_CLIENT_PREFIX_9:
94
+ case GRPC_DTS_CLIENT_PREFIX_10:
95
+ case GRPC_DTS_CLIENT_PREFIX_11:
96
+ case GRPC_DTS_CLIENT_PREFIX_12:
97
+ case GRPC_DTS_CLIENT_PREFIX_13:
98
+ case GRPC_DTS_CLIENT_PREFIX_14:
99
+ case GRPC_DTS_CLIENT_PREFIX_15:
100
+ case GRPC_DTS_CLIENT_PREFIX_16:
101
+ case GRPC_DTS_CLIENT_PREFIX_17:
102
+ case GRPC_DTS_CLIENT_PREFIX_18:
103
+ case GRPC_DTS_CLIENT_PREFIX_19:
104
+ case GRPC_DTS_CLIENT_PREFIX_20:
105
+ case GRPC_DTS_CLIENT_PREFIX_21:
106
+ case GRPC_DTS_CLIENT_PREFIX_22:
107
+ case GRPC_DTS_CLIENT_PREFIX_23:
108
+ // Need the client prefix *and* the first fixed header to make progress.
109
+ return 9 + 24 - (t->deframe_state - GRPC_DTS_CLIENT_PREFIX_0);
110
+ case GRPC_DTS_FH_0:
111
+ case GRPC_DTS_FH_1:
112
+ case GRPC_DTS_FH_2:
113
+ case GRPC_DTS_FH_3:
114
+ case GRPC_DTS_FH_4:
115
+ case GRPC_DTS_FH_5:
116
+ case GRPC_DTS_FH_6:
117
+ case GRPC_DTS_FH_7:
118
+ case GRPC_DTS_FH_8:
119
+ return 9 - (t->deframe_state - GRPC_DTS_FH_0);
120
+ case GRPC_DTS_FRAME:
121
+ return t->incoming_frame_size;
122
+ }
123
+ GPR_UNREACHABLE_CODE(return 1);
124
+ }
125
+
82
126
  grpc_error_handle grpc_chttp2_perform_read(grpc_chttp2_transport* t,
83
127
  const grpc_slice& slice) {
84
128
  const uint8_t* beg = GRPC_SLICE_START_PTR(slice);