grpc 1.1.2 → 1.2.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 (255) hide show
  1. checksums.yaml +4 -4
  2. data/Makefile +1257 -404
  3. data/etc/roots.pem +189 -102
  4. data/include/grpc/census.h +7 -7
  5. data/include/grpc/compression.h +4 -4
  6. data/include/grpc/grpc.h +13 -7
  7. data/include/grpc/impl/codegen/atm_gcc_atomic.h +26 -9
  8. data/include/grpc/impl/codegen/grpc_types.h +39 -30
  9. data/include/grpc/impl/codegen/slice.h +24 -6
  10. data/include/grpc/impl/codegen/sync.h +8 -0
  11. data/include/grpc/load_reporting.h +63 -0
  12. data/include/grpc/slice.h +37 -1
  13. data/include/grpc/slice_buffer.h +7 -0
  14. data/include/grpc/support/alloc.h +3 -0
  15. data/include/grpc/support/useful.h +3 -0
  16. data/src/core/ext/census/gen/census.pb.h +1 -1
  17. data/src/core/ext/census/gen/trace_context.pb.c +9 -36
  18. data/src/core/ext/census/gen/trace_context.pb.h +20 -26
  19. data/src/core/ext/census/grpc_filter.c +3 -5
  20. data/src/core/ext/census/trace_context.c +1 -1
  21. data/src/core/ext/census/trace_context.h +3 -0
  22. data/src/core/ext/census/trace_label.h +61 -0
  23. data/src/core/ext/census/trace_propagation.h +63 -0
  24. data/src/core/ext/census/trace_status.h +45 -0
  25. data/src/core/ext/census/trace_string.h +50 -0
  26. data/src/core/ext/census/tracing.c +31 -11
  27. data/src/core/ext/census/tracing.h +124 -0
  28. data/src/core/ext/client_channel/client_channel.c +456 -368
  29. data/src/core/ext/client_channel/client_channel.h +4 -0
  30. data/src/core/ext/client_channel/client_channel_plugin.c +6 -1
  31. data/src/core/ext/client_channel/connector.c +3 -3
  32. data/src/core/ext/client_channel/connector.h +4 -3
  33. data/src/core/ext/client_channel/http_connect_handshaker.c +62 -72
  34. data/src/core/ext/client_channel/http_connect_handshaker.h +7 -10
  35. data/src/core/ext/client_channel/http_proxy.c +125 -0
  36. data/src/core/ext/client_channel/http_proxy.h +39 -0
  37. data/src/core/ext/client_channel/lb_policy.c +56 -35
  38. data/src/core/ext/client_channel/lb_policy.h +46 -39
  39. data/src/core/ext/client_channel/lb_policy_factory.h +1 -0
  40. data/src/core/ext/client_channel/parse_address.c +32 -6
  41. data/src/core/ext/client_channel/proxy_mapper.c +63 -0
  42. data/src/core/ext/client_channel/proxy_mapper.h +89 -0
  43. data/src/core/ext/client_channel/proxy_mapper_registry.c +133 -0
  44. data/src/core/ext/client_channel/proxy_mapper_registry.h +59 -0
  45. data/src/core/ext/client_channel/resolver.c +16 -9
  46. data/src/core/ext/client_channel/resolver.h +23 -12
  47. data/src/core/ext/client_channel/resolver_factory.h +1 -0
  48. data/src/core/ext/client_channel/resolver_registry.c +15 -11
  49. data/src/core/ext/client_channel/resolver_registry.h +5 -3
  50. data/src/core/ext/client_channel/subchannel.c +44 -27
  51. data/src/core/ext/client_channel/subchannel.h +6 -2
  52. data/src/core/ext/client_channel/uri_parser.c +26 -14
  53. data/src/core/ext/client_channel/uri_parser.h +3 -1
  54. data/src/core/ext/lb_policy/grpclb/grpclb.c +220 -209
  55. data/src/core/ext/lb_policy/grpclb/grpclb_channel.h +56 -0
  56. data/src/core/ext/lb_policy/grpclb/grpclb_channel_secure.c +107 -0
  57. data/src/core/ext/lb_policy/grpclb/load_balancer_api.c +3 -6
  58. data/src/core/ext/lb_policy/pick_first/pick_first.c +71 -116
  59. data/src/core/ext/lb_policy/round_robin/round_robin.c +52 -67
  60. data/src/core/ext/load_reporting/load_reporting.c +20 -0
  61. data/src/core/ext/load_reporting/load_reporting.h +1 -16
  62. data/src/core/ext/load_reporting/load_reporting_filter.c +28 -54
  63. data/src/core/ext/resolver/dns/native/dns_resolver.c +31 -45
  64. data/src/core/ext/resolver/sockaddr/sockaddr_resolver.c +20 -29
  65. data/src/core/ext/transport/chttp2/client/chttp2_connector.c +11 -8
  66. data/src/core/ext/transport/chttp2/client/insecure/channel_create.c +11 -2
  67. data/src/core/ext/transport/chttp2/client/secure/secure_channel_create.c +143 -46
  68. data/src/core/ext/transport/chttp2/server/chttp2_server.c +12 -50
  69. data/src/core/ext/transport/chttp2/server/insecure/server_chttp2.c +1 -1
  70. data/src/core/ext/transport/chttp2/server/secure/server_secure_chttp2.c +1 -1
  71. data/src/core/ext/transport/chttp2/transport/bin_decoder.c +7 -7
  72. data/src/core/ext/transport/chttp2/transport/bin_encoder.c +1 -2
  73. data/src/core/ext/transport/chttp2/transport/bin_encoder.h +1 -2
  74. data/src/core/ext/transport/chttp2/transport/chttp2_plugin.c +0 -3
  75. data/src/core/ext/transport/chttp2/transport/chttp2_transport.c +606 -374
  76. data/src/core/ext/transport/chttp2/transport/frame_ping.c +17 -5
  77. data/src/core/ext/transport/chttp2/transport/frame_ping.h +2 -2
  78. data/src/core/ext/transport/chttp2/transport/frame_rst_stream.c +9 -13
  79. data/src/core/ext/transport/chttp2/transport/frame_settings.c +12 -11
  80. data/src/core/ext/transport/chttp2/transport/frame_settings.h +1 -1
  81. data/src/core/ext/transport/chttp2/transport/frame_window_update.c +5 -6
  82. data/src/core/ext/transport/chttp2/transport/hpack_encoder.c +100 -53
  83. data/src/core/ext/transport/chttp2/transport/hpack_encoder.h +2 -2
  84. data/src/core/ext/transport/chttp2/transport/hpack_parser.c +126 -70
  85. data/src/core/ext/transport/chttp2/transport/hpack_parser.h +13 -7
  86. data/src/core/ext/transport/chttp2/transport/hpack_table.c +22 -19
  87. data/src/core/ext/transport/chttp2/transport/hpack_table.h +6 -6
  88. data/src/core/ext/transport/chttp2/transport/incoming_metadata.c +23 -11
  89. data/src/core/ext/transport/chttp2/transport/incoming_metadata.h +6 -2
  90. data/src/core/ext/transport/chttp2/transport/internal.h +169 -42
  91. data/src/core/ext/transport/chttp2/transport/parsing.c +98 -41
  92. data/src/core/ext/transport/chttp2/transport/stream_lists.c +29 -14
  93. data/src/core/ext/transport/chttp2/transport/writing.c +137 -15
  94. data/src/core/lib/channel/channel_stack.c +14 -44
  95. data/src/core/lib/channel/channel_stack.h +10 -17
  96. data/src/core/lib/channel/channel_stack_builder.c +2 -3
  97. data/src/core/lib/channel/compress_filter.c +54 -46
  98. data/src/core/lib/channel/connected_channel.c +4 -4
  99. data/src/core/lib/channel/connected_channel.h +5 -0
  100. data/src/core/lib/channel/context.h +3 -0
  101. data/src/core/lib/channel/deadline_filter.c +61 -61
  102. data/src/core/lib/channel/deadline_filter.h +8 -5
  103. data/src/core/lib/channel/handshaker.c +47 -7
  104. data/src/core/lib/channel/handshaker.h +21 -3
  105. data/src/core/lib/channel/http_client_filter.c +149 -99
  106. data/src/core/lib/channel/http_server_filter.c +163 -147
  107. data/src/core/lib/channel/message_size_filter.c +15 -10
  108. data/src/core/lib/compression/algorithm_metadata.h +4 -4
  109. data/src/core/lib/compression/compression.c +17 -23
  110. data/src/core/lib/http/httpcli.c +3 -2
  111. data/src/core/lib/http/httpcli.h +2 -1
  112. data/src/core/lib/http/httpcli_security_connector.c +2 -3
  113. data/src/core/lib/http/parser.c +2 -2
  114. data/src/core/lib/iomgr/closure.c +6 -3
  115. data/src/core/lib/iomgr/closure.h +4 -2
  116. data/src/core/lib/iomgr/combiner.c +35 -5
  117. data/src/core/lib/iomgr/combiner.h +21 -2
  118. data/src/core/lib/iomgr/endpoint.c +3 -2
  119. data/src/core/lib/iomgr/endpoint.h +3 -2
  120. data/src/core/lib/iomgr/error.c +60 -94
  121. data/src/core/lib/iomgr/error.h +7 -10
  122. data/src/core/lib/iomgr/error_internal.h +54 -0
  123. data/src/core/lib/iomgr/ev_epoll_linux.c +253 -109
  124. data/src/core/lib/iomgr/ev_poll_posix.c +61 -29
  125. data/src/core/lib/iomgr/ev_posix.c +7 -8
  126. data/src/core/lib/iomgr/ev_posix.h +4 -4
  127. data/src/core/lib/iomgr/exec_ctx.c +11 -6
  128. data/src/core/lib/iomgr/exec_ctx.h +11 -14
  129. data/src/core/lib/iomgr/executor.c +2 -2
  130. data/src/core/lib/iomgr/load_file.c +1 -1
  131. data/src/core/lib/iomgr/network_status_tracker.c +5 -81
  132. data/src/core/lib/iomgr/pollset.h +1 -3
  133. data/src/core/lib/iomgr/pollset_set.h +2 -1
  134. data/src/core/lib/iomgr/pollset_set_uv.c +2 -1
  135. data/src/core/lib/iomgr/pollset_set_windows.c +2 -1
  136. data/src/core/lib/iomgr/pollset_uv.c +25 -11
  137. data/src/core/lib/iomgr/pollset_windows.c +0 -11
  138. data/src/core/lib/iomgr/resolve_address_uv.c +50 -2
  139. data/src/core/lib/iomgr/resource_quota.c +41 -11
  140. data/src/core/lib/iomgr/resource_quota.h +6 -0
  141. data/src/core/lib/iomgr/sockaddr_utils.c +33 -17
  142. data/src/core/lib/iomgr/sockaddr_utils.h +4 -0
  143. data/src/core/lib/iomgr/tcp_client_posix.c +2 -3
  144. data/src/core/lib/iomgr/tcp_client_uv.c +1 -3
  145. data/src/core/lib/iomgr/tcp_client_windows.c +21 -6
  146. data/src/core/lib/iomgr/tcp_posix.c +4 -5
  147. data/src/core/lib/iomgr/tcp_server_posix.c +269 -94
  148. data/src/core/lib/iomgr/tcp_server_windows.c +1 -1
  149. data/src/core/lib/iomgr/tcp_uv.c +11 -5
  150. data/src/core/lib/iomgr/tcp_windows.c +20 -7
  151. data/src/core/lib/iomgr/timer_generic.c +15 -22
  152. data/src/core/lib/iomgr/timer_generic.h +1 -1
  153. data/src/core/lib/iomgr/timer_uv.c +10 -6
  154. data/src/core/lib/iomgr/timer_uv.h +1 -1
  155. data/src/core/lib/iomgr/udp_server.c +45 -6
  156. data/src/core/lib/iomgr/udp_server.h +7 -1
  157. data/src/core/lib/iomgr/unix_sockets_posix.c +11 -1
  158. data/src/core/lib/json/json.c +1 -2
  159. data/src/core/lib/profiling/basic_timers.c +17 -3
  160. data/src/core/lib/security/context/security_context.c +3 -10
  161. data/src/core/lib/security/credentials/composite/composite_credentials.c +4 -8
  162. data/src/core/lib/security/credentials/credentials.c +48 -2
  163. data/src/core/lib/security/credentials/credentials.h +13 -0
  164. data/src/core/lib/security/credentials/credentials_metadata.c +1 -2
  165. data/src/core/lib/security/credentials/fake/fake_credentials.c +6 -8
  166. data/src/core/lib/security/credentials/fake/fake_credentials.h +15 -0
  167. data/src/core/lib/security/credentials/google_default/google_default_credentials.c +3 -3
  168. data/src/core/lib/security/credentials/iam/iam_credentials.c +1 -2
  169. data/src/core/lib/security/credentials/jwt/jwt_credentials.c +1 -2
  170. data/src/core/lib/security/credentials/jwt/jwt_verifier.c +5 -8
  171. data/src/core/lib/security/credentials/jwt/jwt_verifier.h +2 -1
  172. data/src/core/lib/security/credentials/oauth2/oauth2_credentials.c +3 -5
  173. data/src/core/lib/security/credentials/plugin/plugin_credentials.c +15 -13
  174. data/src/core/lib/security/credentials/ssl/ssl_credentials.c +2 -4
  175. data/src/core/lib/security/transport/client_auth_filter.c +72 -47
  176. data/src/core/lib/security/transport/lb_targets_info.c +70 -0
  177. data/src/core/lib/security/transport/lb_targets_info.h +47 -0
  178. data/src/core/lib/security/transport/secure_endpoint.c +3 -3
  179. data/src/core/lib/security/transport/security_connector.c +125 -28
  180. data/src/core/lib/security/transport/security_connector.h +4 -3
  181. data/src/core/lib/security/transport/security_handshaker.c +13 -9
  182. data/src/core/lib/security/transport/server_auth_filter.c +31 -40
  183. data/src/core/lib/security/util/b64.c +1 -1
  184. data/src/core/lib/slice/slice.c +110 -20
  185. data/src/core/lib/slice/slice_buffer.c +92 -39
  186. data/src/core/lib/{transport/mdstr_hash_table.c → slice/slice_hash_table.c} +40 -33
  187. data/src/core/lib/{transport/mdstr_hash_table.h → slice/slice_hash_table.h} +21 -21
  188. data/src/core/lib/slice/slice_intern.c +346 -0
  189. data/src/core/lib/slice/slice_internal.h +15 -0
  190. data/src/core/lib/slice/slice_string_helpers.c +5 -0
  191. data/src/core/lib/slice/slice_string_helpers.h +5 -0
  192. data/src/core/lib/support/alloc.c +26 -1
  193. data/src/core/lib/support/cmdline.c +2 -4
  194. data/src/core/lib/support/cpu_posix.c +2 -7
  195. data/src/core/lib/support/histogram.c +1 -2
  196. data/src/core/lib/support/log_posix.c +8 -4
  197. data/src/core/lib/support/spinlock.h +52 -0
  198. data/src/core/lib/support/subprocess_posix.c +1 -2
  199. data/src/core/lib/support/sync.c +7 -1
  200. data/src/core/lib/support/sync_posix.c +9 -0
  201. data/src/core/lib/support/time_windows.c +7 -1
  202. data/src/core/lib/surface/call.c +647 -629
  203. data/src/core/lib/surface/call.h +4 -1
  204. data/src/core/lib/surface/call_details.c +8 -2
  205. data/src/core/lib/surface/call_log_batch.c +17 -6
  206. data/src/core/lib/surface/channel.c +49 -59
  207. data/src/core/lib/surface/channel.h +5 -6
  208. data/src/core/lib/surface/completion_queue.c +16 -45
  209. data/src/core/lib/surface/completion_queue.h +0 -3
  210. data/src/core/lib/surface/init.c +6 -2
  211. data/src/core/lib/surface/init_secure.c +1 -1
  212. data/src/core/lib/surface/lame_client.c +14 -4
  213. data/src/core/lib/surface/server.c +79 -82
  214. data/src/core/lib/surface/validate_metadata.c +46 -15
  215. data/src/core/lib/surface/validate_metadata.h +43 -0
  216. data/src/core/lib/surface/version.c +2 -2
  217. data/src/core/lib/transport/bdp_estimator.c +104 -0
  218. data/src/core/lib/transport/bdp_estimator.h +76 -0
  219. data/src/core/lib/transport/connectivity_state.c +33 -13
  220. data/src/core/lib/transport/connectivity_state.h +15 -5
  221. data/src/core/lib/transport/error_utils.c +124 -0
  222. data/src/core/lib/transport/error_utils.h +56 -0
  223. data/src/core/{ext/transport/chttp2 → lib}/transport/http2_errors.h +18 -18
  224. data/src/core/lib/transport/metadata.c +259 -503
  225. data/src/core/lib/transport/metadata.h +69 -68
  226. data/src/core/lib/transport/metadata_batch.c +183 -63
  227. data/src/core/lib/transport/metadata_batch.h +50 -26
  228. data/src/core/lib/transport/pid_controller.c +28 -8
  229. data/src/core/lib/transport/pid_controller.h +15 -2
  230. data/src/core/lib/transport/service_config.c +21 -18
  231. data/src/core/lib/transport/service_config.h +5 -5
  232. data/src/core/lib/transport/static_metadata.c +753 -112
  233. data/src/core/lib/transport/static_metadata.h +403 -264
  234. data/src/core/{ext/transport/chttp2 → lib}/transport/status_conversion.c +18 -20
  235. data/src/core/{ext/transport/chttp2 → lib}/transport/status_conversion.h +9 -10
  236. data/src/core/lib/transport/timeout_encoding.c +11 -9
  237. data/src/core/lib/transport/timeout_encoding.h +3 -1
  238. data/src/core/lib/transport/transport.c +47 -87
  239. data/src/core/lib/transport/transport.h +20 -25
  240. data/src/core/lib/transport/transport_op_string.c +7 -19
  241. data/src/core/lib/tsi/fake_transport_security.c +2 -4
  242. data/src/core/lib/tsi/ssl_transport_security.c +7 -16
  243. data/src/core/lib/tsi/transport_security.c +2 -4
  244. data/src/ruby/ext/grpc/extconf.rb +4 -1
  245. data/src/ruby/ext/grpc/rb_byte_buffer.c +7 -0
  246. data/src/ruby/ext/grpc/rb_byte_buffer.h +3 -0
  247. data/src/ruby/ext/grpc/rb_call.c +47 -46
  248. data/src/ruby/ext/grpc/rb_channel.c +21 -6
  249. data/src/ruby/ext/grpc/rb_compression_options.c +9 -6
  250. data/src/ruby/ext/grpc/rb_grpc_imports.generated.c +36 -2
  251. data/src/ruby/ext/grpc/rb_grpc_imports.generated.h +59 -8
  252. data/src/ruby/ext/grpc/rb_server.c +6 -4
  253. data/src/ruby/lib/grpc/generic/client_stub.rb +1 -1
  254. data/src/ruby/lib/grpc/version.rb +1 -1
  255. metadata +33 -9
@@ -39,10 +39,11 @@
39
39
  #include <grpc/support/log.h>
40
40
  #include <grpc/support/string_util.h>
41
41
 
42
- #include "src/core/ext/transport/chttp2/transport/http2_errors.h"
43
- #include "src/core/ext/transport/chttp2/transport/status_conversion.h"
44
42
  #include "src/core/lib/profiling/timers.h"
43
+ #include "src/core/lib/slice/slice_string_helpers.h"
44
+ #include "src/core/lib/transport/http2_errors.h"
45
45
  #include "src/core/lib/transport/static_metadata.h"
46
+ #include "src/core/lib/transport/status_conversion.h"
46
47
  #include "src/core/lib/transport/timeout_encoding.h"
47
48
 
48
49
  static grpc_error *init_frame_parser(grpc_exec_ctx *exec_ctx,
@@ -200,7 +201,7 @@ grpc_error *grpc_chttp2_perform_read(grpc_exec_ctx *exec_ctx,
200
201
  return err;
201
202
  }
202
203
  if (t->incoming_frame_size == 0) {
203
- err = parse_frame_slice(exec_ctx, t, gpr_empty_slice(), 1);
204
+ err = parse_frame_slice(exec_ctx, t, grpc_empty_slice(), 1);
204
205
  if (err != GRPC_ERROR_NONE) {
205
206
  return err;
206
207
  }
@@ -335,7 +336,7 @@ static grpc_error *skip_parser(grpc_exec_ctx *exec_ctx, void *parser,
335
336
  return GRPC_ERROR_NONE;
336
337
  }
337
338
 
338
- static void skip_header(grpc_exec_ctx *exec_ctx, void *tp, grpc_mdelem *md) {
339
+ static void skip_header(grpc_exec_ctx *exec_ctx, void *tp, grpc_mdelem md) {
339
340
  GRPC_MDELEM_UNREF(exec_ctx, md);
340
341
  }
341
342
 
@@ -375,25 +376,65 @@ static grpc_error *update_incoming_window(grpc_exec_ctx *exec_ctx,
375
376
  return err;
376
377
  }
377
378
 
378
- GRPC_CHTTP2_FLOW_DEBIT_TRANSPORT("parse", t, incoming_window,
379
- incoming_frame_size);
380
-
381
379
  if (s != NULL) {
382
- if (incoming_frame_size > s->incoming_window) {
383
- char *msg;
384
- gpr_asprintf(&msg,
385
- "frame of size %d overflows incoming window of %" PRId64,
386
- t->incoming_frame_size, s->incoming_window);
387
- grpc_error *err = GRPC_ERROR_CREATE(msg);
388
- gpr_free(msg);
389
- return err;
380
+ if (incoming_frame_size >
381
+ s->incoming_window_delta +
382
+ t->settings[GRPC_ACKED_SETTINGS]
383
+ [GRPC_CHTTP2_SETTINGS_INITIAL_WINDOW_SIZE]) {
384
+ if (incoming_frame_size <=
385
+ s->incoming_window_delta +
386
+ t->settings[GRPC_SENT_SETTINGS]
387
+ [GRPC_CHTTP2_SETTINGS_INITIAL_WINDOW_SIZE]) {
388
+ gpr_log(
389
+ GPR_ERROR,
390
+ "Incoming frame of size %d exceeds incoming window size of %" PRId64
391
+ ".\n"
392
+ "The (un-acked, future) window size would be %" PRId64
393
+ " which is not exceeded.\n"
394
+ "This would usually cause a disconnection, but allowing it due to "
395
+ "broken HTTP2 implementations in the wild.\n"
396
+ "See (for example) https://github.com/netty/netty/issues/6520.",
397
+ t->incoming_frame_size,
398
+ s->incoming_window_delta +
399
+ t->settings[GRPC_ACKED_SETTINGS]
400
+ [GRPC_CHTTP2_SETTINGS_INITIAL_WINDOW_SIZE],
401
+ s->incoming_window_delta +
402
+ t->settings[GRPC_SENT_SETTINGS]
403
+ [GRPC_CHTTP2_SETTINGS_INITIAL_WINDOW_SIZE]);
404
+ } else {
405
+ char *msg;
406
+ gpr_asprintf(&msg,
407
+ "frame of size %d overflows incoming window of %" PRId64,
408
+ t->incoming_frame_size,
409
+ s->incoming_window_delta +
410
+ t->settings[GRPC_ACKED_SETTINGS]
411
+ [GRPC_CHTTP2_SETTINGS_INITIAL_WINDOW_SIZE]);
412
+ grpc_error *err = GRPC_ERROR_CREATE(msg);
413
+ gpr_free(msg);
414
+ return err;
415
+ }
390
416
  }
391
417
 
392
- GRPC_CHTTP2_FLOW_DEBIT_STREAM("parse", t, s, incoming_window,
393
- incoming_frame_size);
418
+ GRPC_CHTTP2_FLOW_DEBIT_STREAM_INCOMING_WINDOW_DELTA("parse", t, s,
419
+ incoming_frame_size);
420
+ if ((int64_t)t->settings[GRPC_SENT_SETTINGS]
421
+ [GRPC_CHTTP2_SETTINGS_INITIAL_WINDOW_SIZE] +
422
+ (int64_t)s->incoming_window_delta - (int64_t)s->announce_window <=
423
+ (int64_t)t->settings[GRPC_SENT_SETTINGS]
424
+ [GRPC_CHTTP2_SETTINGS_INITIAL_WINDOW_SIZE] /
425
+ 2) {
426
+ grpc_chttp2_become_writable(exec_ctx, t, s,
427
+ GRPC_CHTTP2_STREAM_WRITE_INITIATE_UNCOVERED,
428
+ "window-update-required");
429
+ }
394
430
  s->received_bytes += incoming_frame_size;
395
- s->max_recv_bytes -=
396
- (uint32_t)GPR_MIN(s->max_recv_bytes, incoming_frame_size);
431
+ }
432
+
433
+ uint32_t target_incoming_window = grpc_chttp2_target_incoming_window(t);
434
+ GRPC_CHTTP2_FLOW_DEBIT_TRANSPORT("parse", t, incoming_window,
435
+ incoming_frame_size);
436
+ if (t->incoming_window <= target_incoming_window / 2) {
437
+ grpc_chttp2_initiate_write(exec_ctx, t, false, "flow_control");
397
438
  }
398
439
 
399
440
  return GRPC_ERROR_NONE;
@@ -432,7 +473,7 @@ error_handler:
432
473
  }
433
474
  grpc_slice_buffer_add(
434
475
  &t->qbuf, grpc_chttp2_rst_stream_create(t->incoming_stream_id,
435
- GRPC_CHTTP2_PROTOCOL_ERROR,
476
+ GRPC_HTTP2_PROTOCOL_ERROR,
436
477
  &s->stats.outgoing));
437
478
  return init_skip_frame_parser(exec_ctx, t, 0);
438
479
  } else {
@@ -443,7 +484,7 @@ error_handler:
443
484
  static void free_timeout(void *p) { gpr_free(p); }
444
485
 
445
486
  static void on_initial_header(grpc_exec_ctx *exec_ctx, void *tp,
446
- grpc_mdelem *md) {
487
+ grpc_mdelem md) {
447
488
  grpc_chttp2_transport *t = tp;
448
489
  grpc_chttp2_stream *s = t->incoming_stream;
449
490
 
@@ -451,32 +492,42 @@ static void on_initial_header(grpc_exec_ctx *exec_ctx, void *tp,
451
492
 
452
493
  GPR_ASSERT(s != NULL);
453
494
 
454
- GRPC_CHTTP2_IF_TRACING(gpr_log(
455
- GPR_INFO, "HTTP:%d:HDR:%s: %s: %s", s->id, t->is_client ? "CLI" : "SVR",
456
- grpc_mdstr_as_c_string(md->key), grpc_mdstr_as_c_string(md->value)));
495
+ if (grpc_http_trace) {
496
+ char *key = grpc_slice_to_c_string(GRPC_MDKEY(md));
497
+ char *value =
498
+ grpc_dump_slice(GRPC_MDVALUE(md), GPR_DUMP_HEX | GPR_DUMP_ASCII);
499
+ gpr_log(GPR_INFO, "HTTP:%d:HDR:%s: %s: %s", s->id,
500
+ t->is_client ? "CLI" : "SVR", key, value);
501
+ gpr_free(key);
502
+ gpr_free(value);
503
+ }
457
504
 
458
- if (md->key == GRPC_MDSTR_GRPC_STATUS && md != GRPC_MDELEM_GRPC_STATUS_0) {
505
+ if (grpc_slice_eq(GRPC_MDKEY(md), GRPC_MDSTR_GRPC_STATUS) &&
506
+ !grpc_mdelem_eq(md, GRPC_MDELEM_GRPC_STATUS_0)) {
459
507
  /* TODO(ctiller): check for a status like " 0" */
460
508
  s->seen_error = true;
461
509
  }
462
510
 
463
- if (md->key == GRPC_MDSTR_GRPC_TIMEOUT) {
511
+ if (grpc_slice_eq(GRPC_MDKEY(md), GRPC_MDSTR_GRPC_TIMEOUT)) {
464
512
  gpr_timespec *cached_timeout = grpc_mdelem_get_user_data(md, free_timeout);
465
- if (!cached_timeout) {
513
+ gpr_timespec timeout;
514
+ if (cached_timeout == NULL) {
466
515
  /* not already parsed: parse it now, and store the result away */
467
516
  cached_timeout = gpr_malloc(sizeof(gpr_timespec));
468
- if (!grpc_http2_decode_timeout(grpc_mdstr_as_c_string(md->value),
469
- cached_timeout)) {
470
- gpr_log(GPR_ERROR, "Ignoring bad timeout value '%s'",
471
- grpc_mdstr_as_c_string(md->value));
517
+ if (!grpc_http2_decode_timeout(GRPC_MDVALUE(md), cached_timeout)) {
518
+ char *val = grpc_slice_to_c_string(GRPC_MDVALUE(md));
519
+ gpr_log(GPR_ERROR, "Ignoring bad timeout value '%s'", val);
520
+ gpr_free(val);
472
521
  *cached_timeout = gpr_inf_future(GPR_TIMESPAN);
473
522
  }
474
- cached_timeout =
475
- grpc_mdelem_set_user_data(md, free_timeout, cached_timeout);
523
+ timeout = *cached_timeout;
524
+ grpc_mdelem_set_user_data(md, free_timeout, cached_timeout);
525
+ } else {
526
+ timeout = *cached_timeout;
476
527
  }
477
528
  grpc_chttp2_incoming_metadata_buffer_set_deadline(
478
529
  &s->metadata_buffer[0],
479
- gpr_time_add(gpr_now(GPR_CLOCK_MONOTONIC), *cached_timeout));
530
+ gpr_time_add(gpr_now(GPR_CLOCK_MONOTONIC), timeout));
480
531
  GRPC_MDELEM_UNREF(exec_ctx, md);
481
532
  } else {
482
533
  const size_t new_size = s->metadata_buffer[0].size + GRPC_MDELEM_LENGTH(md);
@@ -505,7 +556,7 @@ static void on_initial_header(grpc_exec_ctx *exec_ctx, void *tp,
505
556
  }
506
557
 
507
558
  static void on_trailing_header(grpc_exec_ctx *exec_ctx, void *tp,
508
- grpc_mdelem *md) {
559
+ grpc_mdelem md) {
509
560
  grpc_chttp2_transport *t = tp;
510
561
  grpc_chttp2_stream *s = t->incoming_stream;
511
562
 
@@ -513,11 +564,18 @@ static void on_trailing_header(grpc_exec_ctx *exec_ctx, void *tp,
513
564
 
514
565
  GPR_ASSERT(s != NULL);
515
566
 
516
- GRPC_CHTTP2_IF_TRACING(gpr_log(
517
- GPR_INFO, "HTTP:%d:TRL:%s: %s: %s", s->id, t->is_client ? "CLI" : "SVR",
518
- grpc_mdstr_as_c_string(md->key), grpc_mdstr_as_c_string(md->value)));
567
+ if (grpc_http_trace) {
568
+ char *key = grpc_slice_to_c_string(GRPC_MDKEY(md));
569
+ char *value =
570
+ grpc_dump_slice(GRPC_MDVALUE(md), GPR_DUMP_HEX | GPR_DUMP_ASCII);
571
+ gpr_log(GPR_INFO, "HTTP:%d:TRL:%s: %s: %s", s->id,
572
+ t->is_client ? "CLI" : "SVR", key, value);
573
+ gpr_free(key);
574
+ gpr_free(value);
575
+ }
519
576
 
520
- if (md->key == GRPC_MDSTR_GRPC_STATUS && md != GRPC_MDELEM_GRPC_STATUS_0) {
577
+ if (grpc_slice_eq(GRPC_MDKEY(md), GRPC_MDSTR_GRPC_STATUS) &&
578
+ !grpc_mdelem_eq(md, GRPC_MDELEM_GRPC_STATUS_0)) {
521
579
  /* TODO(ctiller): check for a status like " 0" */
522
580
  s->seen_error = true;
523
581
  }
@@ -733,14 +791,13 @@ static grpc_error *parse_frame_slice(grpc_exec_ctx *exec_ctx,
733
791
  if (grpc_http_trace) {
734
792
  const char *msg = grpc_error_string(err);
735
793
  gpr_log(GPR_ERROR, "%s", msg);
736
- grpc_error_free_string(msg);
737
794
  }
738
795
  grpc_chttp2_parsing_become_skip_parser(exec_ctx, t);
739
796
  if (s) {
740
797
  s->forced_close_error = err;
741
798
  grpc_slice_buffer_add(
742
799
  &t->qbuf, grpc_chttp2_rst_stream_create(t->incoming_stream_id,
743
- GRPC_CHTTP2_PROTOCOL_ERROR,
800
+ GRPC_HTTP2_PROTOCOL_ERROR,
744
801
  &s->stats.outgoing));
745
802
  } else {
746
803
  GRPC_ERROR_UNREF(err);
@@ -37,14 +37,14 @@
37
37
 
38
38
  /* core list management */
39
39
 
40
- static int stream_list_empty(grpc_chttp2_transport *t,
41
- grpc_chttp2_stream_list_id id) {
40
+ static bool stream_list_empty(grpc_chttp2_transport *t,
41
+ grpc_chttp2_stream_list_id id) {
42
42
  return t->lists[id].head == NULL;
43
43
  }
44
44
 
45
- static int stream_list_pop(grpc_chttp2_transport *t,
46
- grpc_chttp2_stream **stream,
47
- grpc_chttp2_stream_list_id id) {
45
+ static bool stream_list_pop(grpc_chttp2_transport *t,
46
+ grpc_chttp2_stream **stream,
47
+ grpc_chttp2_stream_list_id id) {
48
48
  grpc_chttp2_stream *s = t->lists[id].head;
49
49
  if (s) {
50
50
  grpc_chttp2_stream *new_head = s->links[id].next;
@@ -124,8 +124,8 @@ bool grpc_chttp2_list_add_writable_stream(grpc_chttp2_transport *t,
124
124
  return stream_list_add(t, s, GRPC_CHTTP2_LIST_WRITABLE);
125
125
  }
126
126
 
127
- int grpc_chttp2_list_pop_writable_stream(grpc_chttp2_transport *t,
128
- grpc_chttp2_stream **s) {
127
+ bool grpc_chttp2_list_pop_writable_stream(grpc_chttp2_transport *t,
128
+ grpc_chttp2_stream **s) {
129
129
  return stream_list_pop(t, s, GRPC_CHTTP2_LIST_WRITABLE);
130
130
  }
131
131
 
@@ -139,12 +139,12 @@ bool grpc_chttp2_list_add_writing_stream(grpc_chttp2_transport *t,
139
139
  return stream_list_add(t, s, GRPC_CHTTP2_LIST_WRITING);
140
140
  }
141
141
 
142
- int grpc_chttp2_list_have_writing_streams(grpc_chttp2_transport *t) {
142
+ bool grpc_chttp2_list_have_writing_streams(grpc_chttp2_transport *t) {
143
143
  return !stream_list_empty(t, GRPC_CHTTP2_LIST_WRITING);
144
144
  }
145
145
 
146
- int grpc_chttp2_list_pop_writing_stream(grpc_chttp2_transport *t,
147
- grpc_chttp2_stream **s) {
146
+ bool grpc_chttp2_list_pop_writing_stream(grpc_chttp2_transport *t,
147
+ grpc_chttp2_stream **s) {
148
148
  return stream_list_pop(t, s, GRPC_CHTTP2_LIST_WRITING);
149
149
  }
150
150
 
@@ -153,8 +153,8 @@ void grpc_chttp2_list_add_waiting_for_concurrency(grpc_chttp2_transport *t,
153
153
  stream_list_add(t, s, GRPC_CHTTP2_LIST_WAITING_FOR_CONCURRENCY);
154
154
  }
155
155
 
156
- int grpc_chttp2_list_pop_waiting_for_concurrency(grpc_chttp2_transport *t,
157
- grpc_chttp2_stream **s) {
156
+ bool grpc_chttp2_list_pop_waiting_for_concurrency(grpc_chttp2_transport *t,
157
+ grpc_chttp2_stream **s) {
158
158
  return stream_list_pop(t, s, GRPC_CHTTP2_LIST_WAITING_FOR_CONCURRENCY);
159
159
  }
160
160
 
@@ -168,8 +168,8 @@ void grpc_chttp2_list_add_stalled_by_transport(grpc_chttp2_transport *t,
168
168
  stream_list_add(t, s, GRPC_CHTTP2_LIST_STALLED_BY_TRANSPORT);
169
169
  }
170
170
 
171
- int grpc_chttp2_list_pop_stalled_by_transport(grpc_chttp2_transport *t,
172
- grpc_chttp2_stream **s) {
171
+ bool grpc_chttp2_list_pop_stalled_by_transport(grpc_chttp2_transport *t,
172
+ grpc_chttp2_stream **s) {
173
173
  return stream_list_pop(t, s, GRPC_CHTTP2_LIST_STALLED_BY_TRANSPORT);
174
174
  }
175
175
 
@@ -177,3 +177,18 @@ void grpc_chttp2_list_remove_stalled_by_transport(grpc_chttp2_transport *t,
177
177
  grpc_chttp2_stream *s) {
178
178
  stream_list_maybe_remove(t, s, GRPC_CHTTP2_LIST_STALLED_BY_TRANSPORT);
179
179
  }
180
+
181
+ void grpc_chttp2_list_add_stalled_by_stream(grpc_chttp2_transport *t,
182
+ grpc_chttp2_stream *s) {
183
+ stream_list_add(t, s, GRPC_CHTTP2_LIST_STALLED_BY_STREAM);
184
+ }
185
+
186
+ bool grpc_chttp2_list_pop_stalled_by_stream(grpc_chttp2_transport *t,
187
+ grpc_chttp2_stream **s) {
188
+ return stream_list_pop(t, s, GRPC_CHTTP2_LIST_STALLED_BY_STREAM);
189
+ }
190
+
191
+ bool grpc_chttp2_list_remove_stalled_by_stream(grpc_chttp2_transport *t,
192
+ grpc_chttp2_stream *s) {
193
+ return stream_list_maybe_remove(t, s, GRPC_CHTTP2_LIST_STALLED_BY_STREAM);
194
+ }
@@ -37,9 +37,9 @@
37
37
 
38
38
  #include <grpc/support/log.h>
39
39
 
40
- #include "src/core/ext/transport/chttp2/transport/http2_errors.h"
41
40
  #include "src/core/lib/profiling/timers.h"
42
41
  #include "src/core/lib/slice/slice_internal.h"
42
+ #include "src/core/lib/transport/http2_errors.h"
43
43
 
44
44
  static void add_to_write_list(grpc_chttp2_write_cb **list,
45
45
  grpc_chttp2_write_cb *cb) {
@@ -56,6 +56,75 @@ static void finish_write_cb(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t,
56
56
  t->write_cb_pool = cb;
57
57
  }
58
58
 
59
+ static void collapse_pings_from_into(grpc_chttp2_transport *t,
60
+ grpc_chttp2_ping_type ping_type,
61
+ grpc_chttp2_ping_queue *pq) {
62
+ for (size_t i = 0; i < GRPC_CHTTP2_PCL_COUNT; i++) {
63
+ grpc_closure_list_move(&t->ping_queues[ping_type].lists[i], &pq->lists[i]);
64
+ }
65
+ }
66
+
67
+ static void maybe_initiate_ping(grpc_exec_ctx *exec_ctx,
68
+ grpc_chttp2_transport *t,
69
+ grpc_chttp2_ping_type ping_type) {
70
+ grpc_chttp2_ping_queue *pq = &t->ping_queues[ping_type];
71
+ if (grpc_closure_list_empty(pq->lists[GRPC_CHTTP2_PCL_NEXT])) {
72
+ /* no ping needed: wait */
73
+ return;
74
+ }
75
+ if (!grpc_closure_list_empty(pq->lists[GRPC_CHTTP2_PCL_INFLIGHT])) {
76
+ /* ping already in-flight: wait */
77
+ if (grpc_http_trace || grpc_bdp_estimator_trace) {
78
+ gpr_log(GPR_DEBUG, "Ping delayed [%p]: already pinging", t->peer_string);
79
+ }
80
+ return;
81
+ }
82
+ if (t->ping_state.pings_before_data_required == 0 &&
83
+ t->ping_policy.max_pings_without_data != 0) {
84
+ /* need to send something of substance before sending a ping again */
85
+ if (grpc_http_trace || grpc_bdp_estimator_trace) {
86
+ gpr_log(GPR_DEBUG, "Ping delayed [%p]: too many recent pings: %d/%d",
87
+ t->peer_string, t->ping_state.pings_before_data_required,
88
+ t->ping_policy.max_pings_without_data);
89
+ }
90
+ return;
91
+ }
92
+ gpr_timespec now = gpr_now(GPR_CLOCK_MONOTONIC);
93
+ gpr_timespec elapsed = gpr_time_sub(now, t->ping_state.last_ping_sent_time);
94
+ /*gpr_log(GPR_DEBUG, "elapsed:%d.%09d min:%d.%09d", (int)elapsed.tv_sec,
95
+ elapsed.tv_nsec, (int)t->ping_policy.min_time_between_pings.tv_sec,
96
+ (int)t->ping_policy.min_time_between_pings.tv_nsec);*/
97
+ if (gpr_time_cmp(elapsed, t->ping_policy.min_time_between_pings) < 0) {
98
+ /* not enough elapsed time between successive pings */
99
+ if (grpc_http_trace || grpc_bdp_estimator_trace) {
100
+ gpr_log(GPR_DEBUG,
101
+ "Ping delayed [%p]: not enough time elapsed since last ping",
102
+ t->peer_string);
103
+ }
104
+ return;
105
+ }
106
+ /* coalesce equivalent pings into this one */
107
+ switch (ping_type) {
108
+ case GRPC_CHTTP2_PING_BEFORE_TRANSPORT_WINDOW_UPDATE:
109
+ collapse_pings_from_into(t, GRPC_CHTTP2_PING_ON_NEXT_WRITE, pq);
110
+ break;
111
+ case GRPC_CHTTP2_PING_ON_NEXT_WRITE:
112
+ break;
113
+ case GRPC_CHTTP2_PING_TYPE_COUNT:
114
+ GPR_UNREACHABLE_CODE(break);
115
+ }
116
+ pq->inflight_id = t->ping_ctr * GRPC_CHTTP2_PING_TYPE_COUNT + ping_type;
117
+ t->ping_ctr++;
118
+ grpc_closure_list_sched(exec_ctx, &pq->lists[GRPC_CHTTP2_PCL_INITIATE]);
119
+ grpc_closure_list_move(&pq->lists[GRPC_CHTTP2_PCL_NEXT],
120
+ &pq->lists[GRPC_CHTTP2_PCL_INFLIGHT]);
121
+ grpc_slice_buffer_add(&t->outbuf,
122
+ grpc_chttp2_ping_create(false, pq->inflight_id));
123
+ t->ping_state.last_ping_sent_time = now;
124
+ t->ping_state.pings_before_data_required -=
125
+ (t->ping_state.pings_before_data_required != 0);
126
+ }
127
+
59
128
  static void update_list(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t,
60
129
  grpc_chttp2_stream *s, int64_t send_bytes,
61
130
  grpc_chttp2_write_cb **list, grpc_error *error) {
@@ -74,6 +143,26 @@ static void update_list(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t,
74
143
  GRPC_ERROR_UNREF(error);
75
144
  }
76
145
 
146
+ static bool stream_ref_if_not_destroyed(gpr_refcount *r) {
147
+ gpr_atm count;
148
+ do {
149
+ count = gpr_atm_acq_load(&r->count);
150
+ if (count == 0) return false;
151
+ } while (!gpr_atm_rel_cas(&r->count, count, count + 1));
152
+ return true;
153
+ }
154
+
155
+ uint32_t grpc_chttp2_target_incoming_window(grpc_chttp2_transport *t) {
156
+ return (uint32_t)GPR_MAX(
157
+ (int64_t)((1u << 31) - 1),
158
+ t->stream_total_over_incoming_window +
159
+ (int64_t)GPR_MAX(
160
+ t->settings[GRPC_SENT_SETTINGS]
161
+ [GRPC_CHTTP2_SETTINGS_INITIAL_WINDOW_SIZE] -
162
+ t->stream_total_under_incoming_window,
163
+ 0));
164
+ }
165
+
77
166
  bool grpc_chttp2_begin_write(grpc_exec_ctx *exec_ctx,
78
167
  grpc_chttp2_transport *t) {
79
168
  grpc_chttp2_stream *s;
@@ -101,8 +190,11 @@ bool grpc_chttp2_begin_write(grpc_exec_ctx *exec_ctx,
101
190
 
102
191
  if (t->outgoing_window > 0) {
103
192
  while (grpc_chttp2_list_pop_stalled_by_transport(t, &s)) {
104
- grpc_chttp2_become_writable(exec_ctx, t, s, false,
105
- "transport.read_flow_control");
193
+ if (!t->closed && grpc_chttp2_list_add_writable_stream(t, s) &&
194
+ stream_ref_if_not_destroyed(&s->refcount->refs)) {
195
+ grpc_chttp2_initiate_write(exec_ctx, t, false,
196
+ "transport.read_flow_control");
197
+ }
106
198
  }
107
199
  }
108
200
 
@@ -127,6 +219,8 @@ bool grpc_chttp2_begin_write(grpc_exec_ctx *exec_ctx,
127
219
  s->sent_initial_metadata = true;
128
220
  sent_initial_metadata = true;
129
221
  now_writing = true;
222
+ t->ping_state.pings_before_data_required =
223
+ t->ping_policy.max_pings_without_data;
130
224
  }
131
225
  /* send any window updates */
132
226
  if (s->announce_window > 0) {
@@ -134,15 +228,22 @@ bool grpc_chttp2_begin_write(grpc_exec_ctx *exec_ctx,
134
228
  grpc_slice_buffer_add(&t->outbuf,
135
229
  grpc_chttp2_window_update_create(
136
230
  s->id, s->announce_window, &s->stats.outgoing));
231
+ t->ping_state.pings_before_data_required =
232
+ t->ping_policy.max_pings_without_data;
137
233
  GRPC_CHTTP2_FLOW_DEBIT_STREAM("write", t, s, announce_window, announce);
138
234
  }
139
235
  if (sent_initial_metadata) {
140
236
  /* send any body bytes, if allowed by flow control */
141
237
  if (s->flow_controlled_buffer.length > 0) {
142
- uint32_t max_outgoing =
143
- (uint32_t)GPR_MIN(t->settings[GRPC_ACKED_SETTINGS]
144
- [GRPC_CHTTP2_SETTINGS_MAX_FRAME_SIZE],
145
- GPR_MIN(s->outgoing_window, t->outgoing_window));
238
+ uint32_t stream_outgoing_window = (uint32_t)GPR_MAX(
239
+ 0,
240
+ s->outgoing_window_delta +
241
+ (int64_t)t->settings[GRPC_PEER_SETTINGS]
242
+ [GRPC_CHTTP2_SETTINGS_INITIAL_WINDOW_SIZE]);
243
+ uint32_t max_outgoing = (uint32_t)GPR_MIN(
244
+ t->settings[GRPC_ACKED_SETTINGS]
245
+ [GRPC_CHTTP2_SETTINGS_MAX_FRAME_SIZE],
246
+ GPR_MIN(stream_outgoing_window, t->outgoing_window));
146
247
  if (max_outgoing > 0) {
147
248
  uint32_t send_bytes =
148
249
  (uint32_t)GPR_MIN(max_outgoing, s->flow_controlled_buffer.length);
@@ -155,16 +256,18 @@ bool grpc_chttp2_begin_write(grpc_exec_ctx *exec_ctx,
155
256
  grpc_chttp2_encode_data(s->id, &s->flow_controlled_buffer, send_bytes,
156
257
  is_last_frame, &s->stats.outgoing,
157
258
  &t->outbuf);
158
- GRPC_CHTTP2_FLOW_DEBIT_STREAM("write", t, s, outgoing_window,
259
+ GRPC_CHTTP2_FLOW_DEBIT_STREAM("write", t, s, outgoing_window_delta,
159
260
  send_bytes);
160
261
  GRPC_CHTTP2_FLOW_DEBIT_TRANSPORT("write", t, outgoing_window,
161
262
  send_bytes);
263
+ t->ping_state.pings_before_data_required =
264
+ t->ping_policy.max_pings_without_data;
162
265
  if (is_last_frame) {
163
266
  s->send_trailing_metadata = NULL;
164
267
  s->sent_trailing_metadata = true;
165
268
  if (!t->is_client && !s->read_closed) {
166
269
  grpc_slice_buffer_add(&t->outbuf, grpc_chttp2_rst_stream_create(
167
- s->id, GRPC_CHTTP2_NO_ERROR,
270
+ s->id, GRPC_HTTP2_NO_ERROR,
168
271
  &s->stats.outgoing));
169
272
  }
170
273
  }
@@ -177,6 +280,9 @@ bool grpc_chttp2_begin_write(grpc_exec_ctx *exec_ctx,
177
280
  } else if (t->outgoing_window == 0) {
178
281
  grpc_chttp2_list_add_stalled_by_transport(t, s);
179
282
  now_writing = true;
283
+ } else if (stream_outgoing_window == 0) {
284
+ grpc_chttp2_list_add_stalled_by_stream(t, s);
285
+ now_writing = true;
180
286
  }
181
287
  }
182
288
  if (s->send_trailing_metadata != NULL &&
@@ -197,7 +303,7 @@ bool grpc_chttp2_begin_write(grpc_exec_ctx *exec_ctx,
197
303
  if (!t->is_client && !s->read_closed) {
198
304
  grpc_slice_buffer_add(
199
305
  &t->outbuf, grpc_chttp2_rst_stream_create(
200
- s->id, GRPC_CHTTP2_NO_ERROR, &s->stats.outgoing));
306
+ s->id, GRPC_HTTP2_NO_ERROR, &s->stats.outgoing));
201
307
  }
202
308
  now_writing = true;
203
309
  }
@@ -215,16 +321,32 @@ bool grpc_chttp2_begin_write(grpc_exec_ctx *exec_ctx,
215
321
 
216
322
  /* if the grpc_chttp2_transport is ready to send a window update, do so here
217
323
  also; 3/4 is a magic number that will likely get tuned soon */
218
- if (t->announce_incoming_window > 0) {
219
- uint32_t announced =
220
- (uint32_t)GPR_MIN(t->announce_incoming_window, UINT32_MAX);
221
- GRPC_CHTTP2_FLOW_DEBIT_TRANSPORT("write", t, announce_incoming_window,
222
- announced);
324
+ uint32_t target_incoming_window = grpc_chttp2_target_incoming_window(t);
325
+ uint32_t threshold_to_send_transport_window_update =
326
+ t->outbuf.count > 0 ? 3 * target_incoming_window / 4
327
+ : target_incoming_window / 2;
328
+ if (t->incoming_window <= threshold_to_send_transport_window_update &&
329
+ t->incoming_window != target_incoming_window) {
330
+ maybe_initiate_ping(exec_ctx, t,
331
+ GRPC_CHTTP2_PING_BEFORE_TRANSPORT_WINDOW_UPDATE);
332
+ uint32_t announced = (uint32_t)GPR_CLAMP(
333
+ target_incoming_window - t->incoming_window, 0, UINT32_MAX);
334
+ GRPC_CHTTP2_FLOW_CREDIT_TRANSPORT("write", t, incoming_window, announced);
223
335
  grpc_transport_one_way_stats throwaway_stats;
224
336
  grpc_slice_buffer_add(&t->outbuf, grpc_chttp2_window_update_create(
225
337
  0, announced, &throwaway_stats));
338
+ t->ping_state.pings_before_data_required =
339
+ t->ping_policy.max_pings_without_data;
226
340
  }
227
341
 
342
+ for (size_t i = 0; i < t->ping_ack_count; i++) {
343
+ grpc_slice_buffer_add(&t->outbuf,
344
+ grpc_chttp2_ping_create(1, t->ping_acks[i]));
345
+ }
346
+ t->ping_ack_count = 0;
347
+
348
+ maybe_initiate_ping(exec_ctx, t, GRPC_CHTTP2_PING_ON_NEXT_WRITE);
349
+
228
350
  GPR_TIMER_END("grpc_chttp2_begin_write", 0);
229
351
 
230
352
  return t->outbuf.count > 0;