grpc 1.3.4 → 1.4.0

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 (286) hide show
  1. checksums.yaml +4 -4
  2. data/Makefile +581 -450
  3. data/include/grpc/census.h +49 -49
  4. data/include/grpc/grpc.h +16 -70
  5. data/include/grpc/grpc_security.h +59 -59
  6. data/include/grpc/grpc_security_constants.h +9 -9
  7. data/include/grpc/impl/codegen/atm.h +1 -1
  8. data/include/grpc/impl/codegen/atm_windows.h +4 -4
  9. data/include/grpc/impl/codegen/byte_buffer_reader.h +2 -2
  10. data/include/grpc/impl/codegen/compression_types.h +4 -5
  11. data/include/grpc/impl/codegen/gpr_slice.h +5 -5
  12. data/include/grpc/impl/codegen/gpr_types.h +6 -7
  13. data/include/grpc/impl/codegen/grpc_types.h +128 -59
  14. data/include/grpc/impl/codegen/port_platform.h +6 -0
  15. data/include/grpc/impl/codegen/propagation_bits.h +2 -2
  16. data/include/grpc/impl/codegen/slice.h +13 -12
  17. data/include/grpc/impl/codegen/status.h +23 -18
  18. data/include/grpc/impl/codegen/sync.h +1 -1
  19. data/include/grpc/load_reporting.h +6 -6
  20. data/include/grpc/slice.h +47 -25
  21. data/include/grpc/slice_buffer.h +18 -14
  22. data/include/grpc/support/alloc.h +7 -7
  23. data/include/grpc/support/cmdline.h +10 -10
  24. data/include/grpc/support/cpu.h +3 -3
  25. data/include/grpc/support/histogram.h +1 -1
  26. data/include/grpc/support/host_port.h +2 -2
  27. data/include/grpc/support/log.h +9 -9
  28. data/include/grpc/support/log_windows.h +1 -1
  29. data/include/grpc/support/string_util.h +3 -3
  30. data/include/grpc/support/subprocess.h +3 -3
  31. data/include/grpc/support/sync.h +31 -31
  32. data/include/grpc/support/thd.h +11 -11
  33. data/include/grpc/support/time.h +12 -12
  34. data/include/grpc/support/tls.h +1 -1
  35. data/include/grpc/support/tls_gcc.h +2 -2
  36. data/include/grpc/support/tls_msvc.h +1 -1
  37. data/include/grpc/support/tls_pthread.h +1 -1
  38. data/include/grpc/support/useful.h +2 -2
  39. data/include/grpc/support/workaround_list.h +46 -0
  40. data/src/core/ext/census/context.c +1 -1
  41. data/src/core/ext/census/intrusive_hash_map.c +319 -0
  42. data/src/core/ext/census/intrusive_hash_map.h +167 -0
  43. data/src/core/ext/census/intrusive_hash_map_internal.h +63 -0
  44. data/src/core/ext/census/resource.c +3 -1
  45. data/src/core/ext/filters/client_channel/channel_connectivity.c +1 -1
  46. data/src/core/ext/filters/client_channel/client_channel.c +173 -103
  47. data/src/core/ext/filters/client_channel/client_channel_plugin.c +3 -2
  48. data/src/core/ext/filters/client_channel/lb_policy.c +2 -1
  49. data/src/core/ext/filters/client_channel/lb_policy.h +8 -7
  50. data/src/core/ext/filters/client_channel/lb_policy/grpclb/client_load_reporting_filter.c +153 -0
  51. data/src/core/ext/filters/client_channel/lb_policy/grpclb/client_load_reporting_filter.h +42 -0
  52. data/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.c +405 -102
  53. data/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_client_stats.c +133 -0
  54. data/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_client_stats.h +65 -0
  55. data/src/core/ext/filters/client_channel/lb_policy/grpclb/load_balancer_api.c +90 -51
  56. data/src/core/ext/filters/client_channel/lb_policy/grpclb/load_balancer_api.h +7 -1
  57. data/src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.c +19 -8
  58. data/src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.h +63 -34
  59. data/src/core/ext/filters/client_channel/lb_policy/pick_first/pick_first.c +2 -1
  60. data/src/core/ext/filters/client_channel/lb_policy/round_robin/round_robin.c +188 -294
  61. data/src/core/ext/filters/client_channel/lb_policy_factory.c +28 -5
  62. data/src/core/ext/filters/client_channel/lb_policy_factory.h +18 -4
  63. data/src/core/ext/filters/client_channel/parse_address.c +90 -59
  64. data/src/core/ext/filters/client_channel/parse_address.h +17 -8
  65. data/src/core/ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.c +11 -7
  66. data/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.c +59 -14
  67. data/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.h +6 -0
  68. data/src/core/ext/filters/client_channel/resolver/sockaddr/sockaddr_resolver.c +3 -3
  69. data/src/core/ext/filters/client_channel/subchannel.c +20 -17
  70. data/src/core/ext/filters/client_channel/subchannel.h +1 -0
  71. data/src/core/ext/filters/client_channel/subchannel_index.c +11 -1
  72. data/src/core/ext/filters/client_channel/uri_parser.c +36 -22
  73. data/src/core/ext/filters/client_channel/uri_parser.h +1 -1
  74. data/src/core/{lib/channel → ext/filters/deadline}/deadline_filter.c +42 -17
  75. data/src/core/{lib/channel → ext/filters/deadline}/deadline_filter.h +8 -9
  76. data/src/core/{lib/channel → ext/filters/http/client}/http_client_filter.c +19 -11
  77. data/src/core/{lib/channel → ext/filters/http/client}/http_client_filter.h +3 -6
  78. data/src/core/ext/filters/http/http_filters_plugin.c +104 -0
  79. data/src/core/{lib/channel/compress_filter.c → ext/filters/http/message_compress/message_compress_filter.c} +124 -23
  80. data/src/core/{lib/channel/compress_filter.h → ext/filters/http/message_compress/message_compress_filter.h} +5 -6
  81. data/src/core/{lib/channel → ext/filters/http/server}/http_server_filter.c +4 -6
  82. data/src/core/{lib/channel → ext/filters/http/server}/http_server_filter.h +3 -3
  83. data/src/core/ext/filters/load_reporting/load_reporting.c +2 -25
  84. data/src/core/ext/filters/load_reporting/load_reporting_filter.c +26 -1
  85. data/src/core/ext/filters/max_age/max_age_filter.c +14 -14
  86. data/src/core/{lib/channel → ext/filters/message_size}/message_size_filter.c +91 -47
  87. data/src/core/{lib/channel → ext/filters/message_size}/message_size_filter.h +3 -3
  88. data/src/core/ext/filters/workarounds/workaround_cronet_compression_filter.c +223 -0
  89. data/src/core/ext/filters/workarounds/workaround_cronet_compression_filter.h +40 -0
  90. data/src/core/ext/filters/workarounds/workaround_utils.c +65 -0
  91. data/src/core/ext/filters/workarounds/workaround_utils.h +52 -0
  92. data/src/core/ext/transport/chttp2/client/insecure/channel_create.c +1 -1
  93. data/src/core/ext/transport/chttp2/server/chttp2_server.c +3 -2
  94. data/src/core/ext/transport/chttp2/transport/bin_decoder.c +2 -2
  95. data/src/core/ext/transport/chttp2/transport/bin_encoder.c +3 -3
  96. data/src/core/ext/transport/chttp2/transport/chttp2_transport.c +319 -175
  97. data/src/core/ext/transport/chttp2/transport/chttp2_transport.h +3 -2
  98. data/src/core/ext/transport/chttp2/transport/frame_data.c +203 -164
  99. data/src/core/ext/transport/chttp2/transport/frame_data.h +8 -14
  100. data/src/core/ext/transport/chttp2/transport/frame_goaway.c +1 -1
  101. data/src/core/ext/transport/chttp2/transport/frame_ping.c +1 -1
  102. data/src/core/ext/transport/chttp2/transport/frame_rst_stream.c +1 -1
  103. data/src/core/ext/transport/chttp2/transport/frame_settings.c +5 -5
  104. data/src/core/ext/transport/chttp2/transport/frame_window_update.c +1 -1
  105. data/src/core/ext/transport/chttp2/transport/hpack_encoder.c +4 -4
  106. data/src/core/ext/transport/chttp2/transport/hpack_parser.c +2 -4
  107. data/src/core/ext/transport/chttp2/transport/hpack_table.c +4 -3
  108. data/src/core/ext/transport/chttp2/transport/internal.h +50 -33
  109. data/src/core/ext/transport/chttp2/transport/parsing.c +10 -11
  110. data/src/core/ext/transport/chttp2/transport/writing.c +32 -13
  111. data/src/core/lib/channel/channel_args.c +30 -9
  112. data/src/core/lib/channel/channel_args.h +5 -1
  113. data/src/core/lib/channel/channel_stack.c +1 -1
  114. data/src/core/lib/channel/channel_stack.h +2 -2
  115. data/src/core/lib/channel/channel_stack_builder.c +13 -1
  116. data/src/core/lib/channel/channel_stack_builder.h +5 -1
  117. data/src/core/lib/channel/connected_channel.c +3 -1
  118. data/src/core/lib/channel/context.h +2 -2
  119. data/src/core/lib/compression/message_compress.c +2 -2
  120. data/src/core/lib/debug/trace.c +13 -6
  121. data/src/core/lib/debug/trace.h +27 -1
  122. data/src/core/lib/http/httpcli.c +1 -1
  123. data/src/core/lib/http/httpcli_security_connector.c +9 -11
  124. data/src/core/lib/http/parser.c +2 -2
  125. data/src/core/lib/http/parser.h +2 -1
  126. data/src/core/lib/iomgr/combiner.c +6 -6
  127. data/src/core/lib/iomgr/combiner.h +2 -1
  128. data/src/core/lib/iomgr/error.c +12 -5
  129. data/src/core/lib/iomgr/error.h +13 -13
  130. data/src/core/lib/iomgr/ev_epoll1_linux.c +984 -0
  131. data/src/core/lib/iomgr/ev_epoll1_linux.h +44 -0
  132. data/src/core/lib/iomgr/ev_epoll_limited_pollers_linux.c +2146 -0
  133. data/src/core/lib/iomgr/ev_epoll_limited_pollers_linux.h +43 -0
  134. data/src/core/lib/iomgr/ev_epoll_thread_pool_linux.c +1337 -0
  135. data/src/core/lib/iomgr/ev_epoll_thread_pool_linux.h +43 -0
  136. data/src/core/lib/iomgr/ev_epollex_linux.c +1511 -0
  137. data/src/core/lib/iomgr/ev_epollex_linux.h +43 -0
  138. data/src/core/lib/iomgr/{ev_epoll_linux.c → ev_epollsig_linux.c} +41 -33
  139. data/src/core/lib/iomgr/{ev_epoll_linux.h → ev_epollsig_linux.h} +4 -4
  140. data/src/core/lib/iomgr/ev_poll_posix.c +12 -27
  141. data/src/core/lib/iomgr/ev_poll_posix.h +2 -2
  142. data/src/core/lib/iomgr/ev_posix.c +22 -8
  143. data/src/core/lib/iomgr/ev_posix.h +4 -3
  144. data/src/core/lib/iomgr/ev_windows.c +43 -0
  145. data/src/core/lib/iomgr/exec_ctx.c +5 -0
  146. data/src/core/lib/iomgr/exec_ctx.h +2 -0
  147. data/src/core/lib/iomgr/iomgr.c +4 -0
  148. data/src/core/lib/iomgr/iomgr.h +3 -0
  149. data/src/core/lib/iomgr/is_epollexclusive_available.c +116 -0
  150. data/src/core/lib/iomgr/is_epollexclusive_available.h +41 -0
  151. data/src/core/lib/iomgr/lockfree_event.c +16 -0
  152. data/src/core/lib/iomgr/pollset.h +2 -5
  153. data/src/core/lib/iomgr/pollset_uv.c +1 -1
  154. data/src/core/lib/iomgr/pollset_windows.c +3 -3
  155. data/src/core/lib/iomgr/resource_quota.c +9 -8
  156. data/src/core/lib/iomgr/resource_quota.h +2 -1
  157. data/src/core/lib/iomgr/sockaddr_utils.h +1 -1
  158. data/src/core/lib/iomgr/socket_mutator.h +2 -0
  159. data/src/core/lib/iomgr/sys_epoll_wrapper.h +43 -0
  160. data/src/core/lib/iomgr/tcp_client_posix.c +6 -6
  161. data/src/core/lib/iomgr/tcp_client_uv.c +3 -3
  162. data/src/core/lib/iomgr/tcp_posix.c +7 -7
  163. data/src/core/lib/iomgr/tcp_posix.h +2 -1
  164. data/src/core/lib/iomgr/tcp_server_posix.c +1 -1
  165. data/src/core/lib/iomgr/tcp_uv.c +6 -6
  166. data/src/core/lib/iomgr/tcp_uv.h +2 -1
  167. data/src/core/lib/iomgr/tcp_windows.c +1 -1
  168. data/src/core/lib/iomgr/timer_generic.c +24 -25
  169. data/src/core/lib/iomgr/timer_manager.c +276 -0
  170. data/src/core/lib/iomgr/timer_manager.h +52 -0
  171. data/src/core/lib/iomgr/timer_uv.c +6 -0
  172. data/src/core/lib/iomgr/udp_server.c +42 -9
  173. data/src/core/lib/iomgr/udp_server.h +3 -1
  174. data/src/core/lib/security/credentials/credentials.c +0 -1
  175. data/src/core/lib/security/credentials/fake/fake_credentials.c +23 -0
  176. data/src/core/lib/security/credentials/fake/fake_credentials.h +12 -9
  177. data/src/core/lib/security/credentials/google_default/google_default_credentials.c +1 -1
  178. data/src/core/lib/security/credentials/jwt/jwt_credentials.c +1 -1
  179. data/src/core/lib/security/credentials/oauth2/oauth2_credentials.c +1 -1
  180. data/src/core/lib/security/credentials/ssl/ssl_credentials.c +24 -53
  181. data/src/core/lib/security/transport/client_auth_filter.c +9 -3
  182. data/src/core/lib/security/transport/secure_endpoint.c +7 -7
  183. data/src/core/lib/security/transport/secure_endpoint.h +1 -1
  184. data/src/core/lib/security/transport/security_connector.c +45 -57
  185. data/src/core/lib/security/transport/security_connector.h +10 -14
  186. data/src/core/lib/security/transport/security_handshaker.c +123 -97
  187. data/src/core/lib/slice/b64.c +1 -1
  188. data/src/core/lib/slice/percent_encoding.c +3 -3
  189. data/src/core/lib/slice/slice.c +66 -33
  190. data/src/core/lib/slice/slice_buffer.c +25 -6
  191. data/src/core/lib/slice/slice_hash_table.c +33 -35
  192. data/src/core/lib/slice/slice_hash_table.h +7 -12
  193. data/src/core/lib/support/atomic.h +45 -0
  194. data/src/core/lib/support/atomic_with_atm.h +70 -0
  195. data/src/core/lib/support/atomic_with_std.h +48 -0
  196. data/src/core/lib/support/avl.c +14 -14
  197. data/src/core/lib/support/cmdline.c +3 -3
  198. data/src/core/lib/support/histogram.c +2 -2
  199. data/src/core/lib/support/host_port.c +1 -1
  200. data/src/core/lib/support/memory.h +74 -0
  201. data/src/core/lib/support/mpscq.c +36 -2
  202. data/src/core/lib/support/mpscq.h +28 -1
  203. data/src/core/lib/support/stack_lockfree.c +3 -36
  204. data/src/core/lib/support/string.c +12 -12
  205. data/src/core/lib/support/string_posix.c +1 -1
  206. data/src/core/lib/support/subprocess_posix.c +2 -2
  207. data/src/core/lib/support/thd_posix.c +1 -1
  208. data/src/core/lib/support/time_posix.c +8 -0
  209. data/src/core/lib/support/tmpfile_posix.c +10 -10
  210. data/src/core/lib/surface/alarm.c +3 -1
  211. data/src/core/lib/surface/api_trace.c +2 -1
  212. data/src/core/lib/surface/api_trace.h +2 -2
  213. data/src/core/lib/surface/byte_buffer_reader.c +1 -1
  214. data/src/core/lib/surface/call.c +65 -22
  215. data/src/core/lib/surface/call.h +4 -2
  216. data/src/core/lib/surface/channel_init.c +2 -19
  217. data/src/core/lib/surface/channel_stack_type.c +18 -0
  218. data/src/core/lib/surface/channel_stack_type.h +2 -0
  219. data/src/core/lib/surface/completion_queue.c +694 -247
  220. data/src/core/lib/surface/completion_queue.h +30 -13
  221. data/src/core/lib/surface/completion_queue_factory.c +24 -9
  222. data/src/core/lib/surface/init.c +1 -52
  223. data/src/core/lib/surface/{lame_client.c → lame_client.cc} +37 -26
  224. data/src/core/lib/surface/server.c +79 -110
  225. data/src/core/lib/surface/server.h +2 -1
  226. data/src/core/lib/surface/version.c +2 -2
  227. data/src/core/lib/transport/bdp_estimator.c +25 -9
  228. data/src/core/lib/transport/bdp_estimator.h +7 -1
  229. data/src/core/lib/transport/byte_stream.c +23 -9
  230. data/src/core/lib/transport/byte_stream.h +15 -6
  231. data/src/core/lib/transport/connectivity_state.c +6 -6
  232. data/src/core/lib/transport/connectivity_state.h +2 -1
  233. data/src/core/lib/transport/service_config.c +6 -13
  234. data/src/core/lib/transport/service_config.h +2 -2
  235. data/src/core/lib/transport/static_metadata.c +403 -389
  236. data/src/core/lib/transport/static_metadata.h +127 -114
  237. data/src/core/plugin_registry/grpc_plugin_registry.c +16 -0
  238. data/src/core/tsi/fake_transport_security.c +5 -4
  239. data/src/core/tsi/ssl_transport_security.c +71 -82
  240. data/src/core/tsi/ssl_transport_security.h +39 -61
  241. data/src/core/tsi/transport_security.c +83 -2
  242. data/src/core/tsi/transport_security.h +27 -2
  243. data/src/core/tsi/transport_security_adapter.c +236 -0
  244. data/src/core/tsi/transport_security_adapter.h +62 -0
  245. data/src/core/tsi/transport_security_interface.h +179 -66
  246. data/src/ruby/ext/grpc/extconf.rb +2 -1
  247. data/src/ruby/ext/grpc/rb_byte_buffer.c +8 -6
  248. data/src/ruby/ext/grpc/rb_call.c +56 -48
  249. data/src/ruby/ext/grpc/rb_call.h +3 -4
  250. data/src/ruby/ext/grpc/rb_call_credentials.c +23 -22
  251. data/src/ruby/ext/grpc/rb_channel.c +2 -3
  252. data/src/ruby/ext/grpc/rb_channel_args.c +11 -9
  253. data/src/ruby/ext/grpc/rb_channel_credentials.c +16 -12
  254. data/src/ruby/ext/grpc/rb_completion_queue.c +7 -9
  255. data/src/ruby/ext/grpc/rb_compression_options.c +7 -6
  256. data/src/ruby/ext/grpc/rb_event_thread.c +10 -12
  257. data/src/ruby/ext/grpc/rb_event_thread.h +1 -2
  258. data/src/ruby/ext/grpc/rb_grpc.c +11 -15
  259. data/src/ruby/ext/grpc/rb_grpc.h +2 -2
  260. data/src/ruby/ext/grpc/rb_grpc_imports.generated.c +16 -6
  261. data/src/ruby/ext/grpc/rb_grpc_imports.generated.h +25 -10
  262. data/src/ruby/ext/grpc/rb_server.c +26 -28
  263. data/src/ruby/lib/grpc/grpc.rb +1 -1
  264. data/src/ruby/lib/grpc/version.rb +1 -1
  265. data/third_party/cares/config_linux/ares_config.h +36 -2
  266. data/third_party/zlib/adler32.c +14 -7
  267. data/third_party/zlib/compress.c +24 -18
  268. data/third_party/zlib/crc32.c +29 -12
  269. data/third_party/zlib/deflate.c +499 -303
  270. data/third_party/zlib/deflate.h +19 -16
  271. data/third_party/zlib/gzguts.h +16 -7
  272. data/third_party/zlib/gzlib.c +17 -14
  273. data/third_party/zlib/gzread.c +108 -48
  274. data/third_party/zlib/gzwrite.c +210 -122
  275. data/third_party/zlib/infback.c +2 -2
  276. data/third_party/zlib/inffast.c +34 -51
  277. data/third_party/zlib/inflate.c +86 -37
  278. data/third_party/zlib/inflate.h +7 -4
  279. data/third_party/zlib/inftrees.c +12 -14
  280. data/third_party/zlib/trees.c +38 -61
  281. data/third_party/zlib/uncompr.c +66 -32
  282. data/third_party/zlib/zconf.h +32 -9
  283. data/third_party/zlib/zlib.h +298 -154
  284. data/third_party/zlib/zutil.c +25 -24
  285. data/third_party/zlib/zutil.h +35 -17
  286. metadata +63 -30
@@ -0,0 +1,40 @@
1
+ //
2
+ // Copyright 2017, Google Inc.
3
+ // All rights reserved.
4
+ //
5
+ // Redistribution and use in source and binary forms, with or without
6
+ // modification, are permitted provided that the following conditions are
7
+ // met:
8
+ //
9
+ // * Redistributions of source code must retain the above copyright
10
+ // notice, this list of conditions and the following disclaimer.
11
+ // * Redistributions in binary form must reproduce the above
12
+ // copyright notice, this list of conditions and the following disclaimer
13
+ // in the documentation and/or other materials provided with the
14
+ // distribution.
15
+ // * Neither the name of Google Inc. nor the names of its
16
+ // contributors may be used to endorse or promote products derived from
17
+ // this software without specific prior written permission.
18
+ //
19
+ // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20
+ // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21
+ // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22
+ // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
23
+ // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24
+ // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
25
+ // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26
+ // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27
+ // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28
+ // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29
+ // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30
+ //
31
+
32
+ #ifndef GRPC_CORE_EXT_FILTERS_WORKAROUNDS_WORKAROUND_CRONET_COMPRESSION_FILTER_H
33
+ #define GRPC_CORE_EXT_FILTERS_WORKAROUNDS_WORKAROUND_CRONET_COMPRESSION_FILTER_H
34
+
35
+ #include "src/core/lib/channel/channel_stack.h"
36
+
37
+ extern const grpc_channel_filter grpc_workaround_cronet_compression_filter;
38
+
39
+ #endif /* GRPC_CORE_EXT_FILTERS_WORKAROUNDS_WORKAROUND_CRONET_COMPRESSION_FILTER_H \
40
+ */
@@ -0,0 +1,65 @@
1
+ //
2
+ // Copyright 2017, Google Inc.
3
+ // All rights reserved.
4
+ //
5
+ // Redistribution and use in source and binary forms, with or without
6
+ // modification, are permitted provided that the following conditions are
7
+ // met:
8
+ //
9
+ // * Redistributions of source code must retain the above copyright
10
+ // notice, this list of conditions and the following disclaimer.
11
+ // * Redistributions in binary form must reproduce the above
12
+ // copyright notice, this list of conditions and the following disclaimer
13
+ // in the documentation and/or other materials provided with the
14
+ // distribution.
15
+ // * Neither the name of Google Inc. nor the names of its
16
+ // contributors may be used to endorse or promote products derived from
17
+ // this software without specific prior written permission.
18
+ //
19
+ // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20
+ // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21
+ // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22
+ // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
23
+ // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24
+ // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
25
+ // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26
+ // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27
+ // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28
+ // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29
+ // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30
+ //
31
+
32
+ #include "src/core/ext/filters/workarounds/workaround_utils.h"
33
+
34
+ #include <grpc/support/alloc.h>
35
+ #include <grpc/support/log.h>
36
+
37
+ user_agent_parser ua_parser[GRPC_MAX_WORKAROUND_ID];
38
+
39
+ static void destroy_user_agent_md(void *user_agent_md) {
40
+ gpr_free(user_agent_md);
41
+ }
42
+
43
+ grpc_workaround_user_agent_md *grpc_parse_user_agent(grpc_mdelem md) {
44
+ grpc_workaround_user_agent_md *user_agent_md =
45
+ (grpc_workaround_user_agent_md *)grpc_mdelem_get_user_data(
46
+ md, destroy_user_agent_md);
47
+
48
+ if (NULL != user_agent_md) {
49
+ return user_agent_md;
50
+ }
51
+ user_agent_md = gpr_malloc(sizeof(grpc_workaround_user_agent_md));
52
+ for (int i = 0; i < GRPC_MAX_WORKAROUND_ID; i++) {
53
+ if (ua_parser[i]) {
54
+ user_agent_md->workaround_active[i] = ua_parser[i](md);
55
+ }
56
+ }
57
+ grpc_mdelem_set_user_data(md, destroy_user_agent_md, (void *)user_agent_md);
58
+
59
+ return user_agent_md;
60
+ }
61
+
62
+ void grpc_register_workaround(uint32_t id, user_agent_parser parser) {
63
+ GPR_ASSERT(id < GRPC_MAX_WORKAROUND_ID);
64
+ ua_parser[id] = parser;
65
+ }
@@ -0,0 +1,52 @@
1
+ //
2
+ // Copyright 2017, Google Inc.
3
+ // All rights reserved.
4
+ //
5
+ // Redistribution and use in source and binary forms, with or without
6
+ // modification, are permitted provided that the following conditions are
7
+ // met:
8
+ //
9
+ // * Redistributions of source code must retain the above copyright
10
+ // notice, this list of conditions and the following disclaimer.
11
+ // * Redistributions in binary form must reproduce the above
12
+ // copyright notice, this list of conditions and the following disclaimer
13
+ // in the documentation and/or other materials provided with the
14
+ // distribution.
15
+ // * Neither the name of Google Inc. nor the names of its
16
+ // contributors may be used to endorse or promote products derived from
17
+ // this software without specific prior written permission.
18
+ //
19
+ // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20
+ // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21
+ // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22
+ // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
23
+ // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24
+ // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
25
+ // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26
+ // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27
+ // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28
+ // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29
+ // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30
+ //
31
+
32
+ #ifndef GRPC_CORE_EXT_FILTERS_WORKAROUNDS_WORKAROUND_UTILS_H
33
+ #define GRPC_CORE_EXT_FILTERS_WORKAROUNDS_WORKAROUND_UTILS_H
34
+
35
+ #include <grpc/support/workaround_list.h>
36
+
37
+ #include "src/core/lib/transport/metadata.h"
38
+
39
+ #define GRPC_WORKAROUND_PRIORITY_HIGH 10001
40
+ #define GRPC_WORKAROUND_PROIRITY_LOW 9999
41
+
42
+ typedef struct grpc_workaround_user_agent_md {
43
+ bool workaround_active[GRPC_MAX_WORKAROUND_ID];
44
+ } grpc_workaround_user_agent_md;
45
+
46
+ grpc_workaround_user_agent_md *grpc_parse_user_agent(grpc_mdelem md);
47
+
48
+ typedef bool (*user_agent_parser)(grpc_mdelem);
49
+
50
+ void grpc_register_workaround(uint32_t id, user_agent_parser parser);
51
+
52
+ #endif
@@ -101,7 +101,7 @@ grpc_channel *grpc_insecure_channel_create(const char *target,
101
101
  void *reserved) {
102
102
  grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
103
103
  GRPC_API_TRACE(
104
- "grpc_insecure_channel_create(target=%p, args=%p, reserved=%p)", 3,
104
+ "grpc_insecure_channel_create(target=%s, args=%p, reserved=%p)", 3,
105
105
  (target, args, reserved));
106
106
  GPR_ASSERT(reserved == NULL);
107
107
  // Add channel arg containing the client channel factory.
@@ -43,11 +43,11 @@
43
43
  #include <grpc/support/sync.h>
44
44
  #include <grpc/support/useful.h>
45
45
 
46
+ #include "src/core/ext/filters/http/server/http_server_filter.h"
46
47
  #include "src/core/ext/transport/chttp2/transport/chttp2_transport.h"
47
48
  #include "src/core/lib/channel/channel_args.h"
48
49
  #include "src/core/lib/channel/handshaker.h"
49
50
  #include "src/core/lib/channel/handshaker_registry.h"
50
- #include "src/core/lib/channel/http_server_filter.h"
51
51
  #include "src/core/lib/iomgr/endpoint.h"
52
52
  #include "src/core/lib/iomgr/resolve_address.h"
53
53
  #include "src/core/lib/iomgr/tcp_server.h"
@@ -80,7 +80,7 @@ static void on_handshake_done(grpc_exec_ctx *exec_ctx, void *arg,
80
80
  gpr_mu_lock(&connection_state->server_state->mu);
81
81
  if (error != GRPC_ERROR_NONE || connection_state->server_state->shutdown) {
82
82
  const char *error_str = grpc_error_string(error);
83
- gpr_log(GPR_ERROR, "Handshaking failed: %s", error_str);
83
+ gpr_log(GPR_DEBUG, "Handshaking failed: %s", error_str);
84
84
 
85
85
  if (error == GRPC_ERROR_NONE && args->endpoint != NULL) {
86
86
  // We were shut down after handshaking completed successfully, so
@@ -127,6 +127,7 @@ static void on_accept(grpc_exec_ctx *exec_ctx, void *arg, grpc_endpoint *tcp,
127
127
  gpr_mu_lock(&state->mu);
128
128
  if (state->shutdown) {
129
129
  gpr_mu_unlock(&state->mu);
130
+ grpc_endpoint_shutdown(exec_ctx, tcp, GRPC_ERROR_NONE);
130
131
  grpc_endpoint_destroy(exec_ctx, tcp);
131
132
  gpr_free(acceptor);
132
133
  return;
@@ -169,7 +169,7 @@ grpc_slice grpc_chttp2_base64_decode(grpc_exec_ctx *exec_ctx,
169
169
  }
170
170
  }
171
171
  }
172
- output = grpc_slice_malloc(output_length);
172
+ output = GRPC_SLICE_MALLOC(output_length);
173
173
 
174
174
  ctx.input_cur = GRPC_SLICE_START_PTR(input);
175
175
  ctx.input_end = GRPC_SLICE_END_PTR(input);
@@ -193,7 +193,7 @@ grpc_slice grpc_chttp2_base64_decode_with_length(grpc_exec_ctx *exec_ctx,
193
193
  grpc_slice input,
194
194
  size_t output_length) {
195
195
  size_t input_length = GRPC_SLICE_LENGTH(input);
196
- grpc_slice output = grpc_slice_malloc(output_length);
196
+ grpc_slice output = GRPC_SLICE_MALLOC(output_length);
197
197
  struct grpc_base64_decode_context ctx;
198
198
 
199
199
  // The length of a base64 string cannot be 4 * n + 1
@@ -66,7 +66,7 @@ grpc_slice grpc_chttp2_base64_encode(grpc_slice input) {
66
66
  size_t input_triplets = input_length / 3;
67
67
  size_t tail_case = input_length % 3;
68
68
  size_t output_length = input_triplets * 4 + tail_xtra[tail_case];
69
- grpc_slice output = grpc_slice_malloc(output_length);
69
+ grpc_slice output = GRPC_SLICE_MALLOC(output_length);
70
70
  uint8_t *in = GRPC_SLICE_START_PTR(input);
71
71
  char *out = (char *)GRPC_SLICE_START_PTR(output);
72
72
  size_t i;
@@ -119,7 +119,7 @@ grpc_slice grpc_chttp2_huffman_compress(grpc_slice input) {
119
119
  nbits += grpc_chttp2_huffsyms[*in].length;
120
120
  }
121
121
 
122
- output = grpc_slice_malloc(nbits / 8 + (nbits % 8 != 0));
122
+ output = GRPC_SLICE_MALLOC(nbits / 8 + (nbits % 8 != 0));
123
123
  out = GRPC_SLICE_START_PTR(output);
124
124
  for (in = GRPC_SLICE_START_PTR(input); in != GRPC_SLICE_END_PTR(input);
125
125
  ++in) {
@@ -184,7 +184,7 @@ grpc_slice grpc_chttp2_base64_encode_and_huffman_compress(grpc_slice input) {
184
184
  size_t output_syms = input_triplets * 4 + tail_xtra[tail_case];
185
185
  size_t max_output_bits = 11 * output_syms;
186
186
  size_t max_output_length = max_output_bits / 8 + (max_output_bits % 8 != 0);
187
- grpc_slice output = grpc_slice_malloc(max_output_length);
187
+ grpc_slice output = GRPC_SLICE_MALLOC(max_output_length);
188
188
  uint8_t *in = GRPC_SLICE_START_PTR(input);
189
189
  uint8_t *start_out = GRPC_SLICE_START_PTR(output);
190
190
  huff_out out;
@@ -44,6 +44,7 @@
44
44
  #include <grpc/support/string_util.h>
45
45
  #include <grpc/support/useful.h>
46
46
 
47
+ #include "src/core/ext/transport/chttp2/transport/frame_data.h"
47
48
  #include "src/core/ext/transport/chttp2/transport/internal.h"
48
49
  #include "src/core/ext/transport/chttp2/transport/varint.h"
49
50
  #include "src/core/lib/channel/channel_args.h"
@@ -88,8 +89,8 @@ static bool g_default_keepalive_permit_without_calls =
88
89
  DEFAULT_KEEPALIVE_PERMIT_WITHOUT_CALLS;
89
90
 
90
91
  #define MAX_CLIENT_STREAM_ID 0x7fffffffu
91
- int grpc_http_trace = 0;
92
- int grpc_flowctl_trace = 0;
92
+ grpc_tracer_flag grpc_http_trace = GRPC_TRACER_INITIALIZER(false);
93
+ grpc_tracer_flag grpc_flowctl_trace = GRPC_TRACER_INITIALIZER(false);
93
94
 
94
95
  static const grpc_transport_vtable vtable;
95
96
 
@@ -129,6 +130,11 @@ static void incoming_byte_stream_update_flow_control(grpc_exec_ctx *exec_ctx,
129
130
  static void incoming_byte_stream_destroy_locked(grpc_exec_ctx *exec_ctx,
130
131
  void *byte_stream,
131
132
  grpc_error *error_ignored);
133
+ static void incoming_byte_stream_publish_error(
134
+ grpc_exec_ctx *exec_ctx, grpc_chttp2_incoming_byte_stream *bs,
135
+ grpc_error *error);
136
+ static void incoming_byte_stream_unref(grpc_exec_ctx *exec_ctx,
137
+ grpc_chttp2_incoming_byte_stream *bs);
132
138
 
133
139
  static void benign_reclaimer_locked(grpc_exec_ctx *exec_ctx, void *t,
134
140
  grpc_error *error);
@@ -174,6 +180,9 @@ static void finish_keepalive_ping_locked(grpc_exec_ctx *exec_ctx, void *arg,
174
180
  static void keepalive_watchdog_fired_locked(grpc_exec_ctx *exec_ctx, void *arg,
175
181
  grpc_error *error);
176
182
 
183
+ static void reset_byte_stream(grpc_exec_ctx *exec_ctx, void *arg,
184
+ grpc_error *error);
185
+
177
186
  /*******************************************************************************
178
187
  * CONSTRUCTION/DESTRUCTION/REFCOUNTING
179
188
  */
@@ -550,6 +559,10 @@ static void init_transport(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t,
550
559
  exec_ctx, &t->keepalive_ping_timer,
551
560
  gpr_time_add(gpr_now(GPR_CLOCK_MONOTONIC), t->keepalive_time),
552
561
  &t->init_keepalive_ping_locked, gpr_now(GPR_CLOCK_MONOTONIC));
562
+ } else {
563
+ /* Use GRPC_CHTTP2_KEEPALIVE_STATE_DISABLED to indicate there are no
564
+ inflight keeaplive timers */
565
+ t->keepalive_state = GRPC_CHTTP2_KEEPALIVE_STATE_DISABLED;
553
566
  }
554
567
 
555
568
  grpc_chttp2_initiate_write(exec_ctx, t, false, "init");
@@ -598,21 +611,18 @@ static void close_transport_locked(grpc_exec_ctx *exec_ctx,
598
611
  connectivity_state_set(exec_ctx, t, GRPC_CHANNEL_SHUTDOWN,
599
612
  GRPC_ERROR_REF(error), "close_transport");
600
613
  grpc_endpoint_shutdown(exec_ctx, t->ep, GRPC_ERROR_REF(error));
601
- if (t->is_client) {
602
- switch (t->keepalive_state) {
603
- case GRPC_CHTTP2_KEEPALIVE_STATE_WAITING: {
604
- grpc_timer_cancel(exec_ctx, &t->keepalive_ping_timer);
605
- break;
606
- }
607
- case GRPC_CHTTP2_KEEPALIVE_STATE_PINGING: {
608
- grpc_timer_cancel(exec_ctx, &t->keepalive_ping_timer);
609
- grpc_timer_cancel(exec_ctx, &t->keepalive_watchdog_timer);
610
- break;
611
- }
612
- case GRPC_CHTTP2_KEEPALIVE_STATE_DYING: {
613
- break;
614
- }
615
- }
614
+ switch (t->keepalive_state) {
615
+ case GRPC_CHTTP2_KEEPALIVE_STATE_WAITING:
616
+ grpc_timer_cancel(exec_ctx, &t->keepalive_ping_timer);
617
+ break;
618
+ case GRPC_CHTTP2_KEEPALIVE_STATE_PINGING:
619
+ grpc_timer_cancel(exec_ctx, &t->keepalive_ping_timer);
620
+ grpc_timer_cancel(exec_ctx, &t->keepalive_watchdog_timer);
621
+ break;
622
+ case GRPC_CHTTP2_KEEPALIVE_STATE_DYING:
623
+ case GRPC_CHTTP2_KEEPALIVE_STATE_DISABLED:
624
+ /* keepalive timers are not set in these two states */
625
+ break;
616
626
  }
617
627
 
618
628
  /* flush writable stream list to avoid dangling references */
@@ -655,7 +665,6 @@ static int init_stream(grpc_exec_ctx *exec_ctx, grpc_transport *gt,
655
665
  /* We reserve one 'active stream' that's dropped when the stream is
656
666
  read-closed. The others are for incoming_byte_streams that are actively
657
667
  reading */
658
- gpr_ref_init(&s->active_streams, 1);
659
668
  GRPC_CHTTP2_STREAM_REF(s, "chttp2");
660
669
 
661
670
  grpc_chttp2_incoming_metadata_buffer_init(&s->metadata_buffer[0], arena);
@@ -665,6 +674,11 @@ static int init_stream(grpc_exec_ctx *exec_ctx, grpc_transport *gt,
665
674
  s->deadline = gpr_inf_future(GPR_CLOCK_MONOTONIC);
666
675
  grpc_closure_init(&s->complete_fetch_locked, complete_fetch_locked, s,
667
676
  grpc_schedule_on_exec_ctx);
677
+ grpc_slice_buffer_init(&s->unprocessed_incoming_frames_buffer);
678
+ grpc_slice_buffer_init(&s->frame_storage);
679
+ s->pending_byte_stream = false;
680
+ grpc_closure_init(&s->reset_byte_stream, reset_byte_stream, s,
681
+ grpc_combiner_scheduler(t->combiner, false));
668
682
 
669
683
  GRPC_CHTTP2_REF_TRANSPORT(t, "stream");
670
684
 
@@ -682,7 +696,6 @@ static int init_stream(grpc_exec_ctx *exec_ctx, grpc_transport *gt,
682
696
 
683
697
  static void destroy_stream_locked(grpc_exec_ctx *exec_ctx, void *sp,
684
698
  grpc_error *error) {
685
- grpc_byte_stream *bs;
686
699
  grpc_chttp2_stream *s = sp;
687
700
  grpc_chttp2_transport *t = s->t;
688
701
 
@@ -693,9 +706,9 @@ static void destroy_stream_locked(grpc_exec_ctx *exec_ctx, void *sp,
693
706
  GPR_ASSERT(grpc_chttp2_stream_map_find(&t->stream_map, s->id) == NULL);
694
707
  }
695
708
 
696
- while ((bs = grpc_chttp2_incoming_frame_queue_pop(&s->incoming_frames))) {
697
- incoming_byte_stream_destroy_locked(exec_ctx, bs, GRPC_ERROR_NONE);
698
- }
709
+ grpc_slice_buffer_destroy_internal(exec_ctx,
710
+ &s->unprocessed_incoming_frames_buffer);
711
+ grpc_slice_buffer_destroy_internal(exec_ctx, &s->frame_storage);
699
712
 
700
713
  grpc_chttp2_list_remove_stalled_by_transport(t, s);
701
714
  grpc_chttp2_list_remove_stalled_by_stream(t, s);
@@ -722,6 +735,7 @@ static void destroy_stream_locked(grpc_exec_ctx *exec_ctx, void *sp,
722
735
  grpc_slice_buffer_destroy_internal(exec_ctx, &s->flow_controlled_buffer);
723
736
  GRPC_ERROR_UNREF(s->read_closed_error);
724
737
  GRPC_ERROR_UNREF(s->write_closed_error);
738
+ GRPC_ERROR_UNREF(s->byte_stream_error);
725
739
 
726
740
  if (s->incoming_window_delta > 0) {
727
741
  GRPC_CHTTP2_FLOW_DEBIT_STREAM_INCOMING_WINDOW_DELTA(
@@ -870,14 +884,23 @@ static void write_action_begin_locked(grpc_exec_ctx *exec_ctx, void *gt,
870
884
  GPR_TIMER_BEGIN("write_action_begin_locked", 0);
871
885
  grpc_chttp2_transport *t = gt;
872
886
  GPR_ASSERT(t->write_state != GRPC_CHTTP2_WRITE_STATE_IDLE);
873
- if (!t->closed && grpc_chttp2_begin_write(exec_ctx, t)) {
874
- set_write_state(exec_ctx, t, GRPC_CHTTP2_WRITE_STATE_WRITING,
875
- "begin writing");
876
- grpc_closure_sched(exec_ctx, &t->write_action, GRPC_ERROR_NONE);
877
- } else {
878
- set_write_state(exec_ctx, t, GRPC_CHTTP2_WRITE_STATE_IDLE,
879
- "begin writing nothing");
880
- GRPC_CHTTP2_UNREF_TRANSPORT(exec_ctx, t, "writing");
887
+ switch (t->closed ? GRPC_CHTTP2_NOTHING_TO_WRITE
888
+ : grpc_chttp2_begin_write(exec_ctx, t)) {
889
+ case GRPC_CHTTP2_NOTHING_TO_WRITE:
890
+ set_write_state(exec_ctx, t, GRPC_CHTTP2_WRITE_STATE_IDLE,
891
+ "begin writing nothing");
892
+ GRPC_CHTTP2_UNREF_TRANSPORT(exec_ctx, t, "writing");
893
+ break;
894
+ case GRPC_CHTTP2_PARTIAL_WRITE:
895
+ set_write_state(exec_ctx, t, GRPC_CHTTP2_WRITE_STATE_WRITING_WITH_MORE,
896
+ "begin writing partial");
897
+ grpc_closure_sched(exec_ctx, &t->write_action, GRPC_ERROR_NONE);
898
+ break;
899
+ case GRPC_CHTTP2_FULL_WRITE:
900
+ set_write_state(exec_ctx, t, GRPC_CHTTP2_WRITE_STATE_WRITING,
901
+ "begin writing");
902
+ grpc_closure_sched(exec_ctx, &t->write_action, GRPC_ERROR_NONE);
903
+ break;
881
904
  }
882
905
  GPR_TIMER_END("write_action_begin_locked", 0);
883
906
  }
@@ -974,7 +997,7 @@ void grpc_chttp2_add_incoming_goaway(grpc_exec_ctx *exec_ctx,
974
997
  t->seen_goaway = 1;
975
998
 
976
999
  /* When a client receives a GOAWAY with error code ENHANCE_YOUR_CALM and debug
977
- * data equal to too_many_pings”, it should log the occurrence at a log level
1000
+ * data equal to "too_many_pings", it should log the occurrence at a log level
978
1001
  * that is enabled by default and double the configured KEEPALIVE_TIME used
979
1002
  * for new connections on that channel. */
980
1003
  if (t->is_client && goaway_error == GRPC_HTTP2_ENHANCE_YOUR_CALM &&
@@ -1081,7 +1104,7 @@ void grpc_chttp2_complete_closure_step(grpc_exec_ctx *exec_ctx,
1081
1104
  return;
1082
1105
  }
1083
1106
  closure->next_data.scratch -= CLOSURE_BARRIER_FIRST_REF_BIT;
1084
- if (grpc_http_trace) {
1107
+ if (GRPC_TRACER_ON(grpc_http_trace)) {
1085
1108
  const char *errstr = grpc_error_string(error);
1086
1109
  gpr_log(GPR_DEBUG,
1087
1110
  "complete_closure_step: %p refs=%d flags=0x%04x desc=%s err=%s",
@@ -1175,8 +1198,9 @@ static void continue_fetching_send_locked(grpc_exec_ctx *exec_ctx,
1175
1198
  s->fetching_send_message = NULL;
1176
1199
  return; /* early out */
1177
1200
  } else if (grpc_byte_stream_next(exec_ctx, s->fetching_send_message,
1178
- &s->fetching_slice, UINT32_MAX,
1179
- &s->complete_fetch_locked)) {
1201
+ UINT32_MAX, &s->complete_fetch_locked)) {
1202
+ grpc_byte_stream_pull(exec_ctx, s->fetching_send_message,
1203
+ &s->fetching_slice);
1180
1204
  add_fetched_slice_locked(exec_ctx, t, s);
1181
1205
  }
1182
1206
  }
@@ -1187,9 +1211,15 @@ static void complete_fetch_locked(grpc_exec_ctx *exec_ctx, void *gs,
1187
1211
  grpc_chttp2_stream *s = gs;
1188
1212
  grpc_chttp2_transport *t = s->t;
1189
1213
  if (error == GRPC_ERROR_NONE) {
1190
- add_fetched_slice_locked(exec_ctx, t, s);
1191
- continue_fetching_send_locked(exec_ctx, t, s);
1192
- } else {
1214
+ error = grpc_byte_stream_pull(exec_ctx, s->fetching_send_message,
1215
+ &s->fetching_slice);
1216
+ if (error == GRPC_ERROR_NONE) {
1217
+ add_fetched_slice_locked(exec_ctx, t, s);
1218
+ continue_fetching_send_locked(exec_ctx, t, s);
1219
+ }
1220
+ }
1221
+
1222
+ if (error != GRPC_ERROR_NONE) {
1193
1223
  /* TODO(ctiller): what to do here */
1194
1224
  abort();
1195
1225
  }
@@ -1219,7 +1249,7 @@ static void perform_stream_op_locked(grpc_exec_ctx *exec_ctx, void *stream_op,
1219
1249
  grpc_transport_stream_op_batch_payload *op_payload = op->payload;
1220
1250
  grpc_chttp2_transport *t = s->t;
1221
1251
 
1222
- if (grpc_http_trace) {
1252
+ if (GRPC_TRACER_ON(grpc_http_trace)) {
1223
1253
  char *str = grpc_transport_stream_op_batch_string(op);
1224
1254
  gpr_log(GPR_DEBUG, "perform_stream_op_locked: %s; on_complete = %p", str,
1225
1255
  op->on_complete);
@@ -1421,12 +1451,20 @@ static void perform_stream_op_locked(grpc_exec_ctx *exec_ctx, void *stream_op,
1421
1451
  }
1422
1452
 
1423
1453
  if (op->recv_message) {
1454
+ size_t already_received;
1424
1455
  GPR_ASSERT(s->recv_message_ready == NULL);
1456
+ GPR_ASSERT(!s->pending_byte_stream);
1425
1457
  s->recv_message_ready = op_payload->recv_message.recv_message_ready;
1426
1458
  s->recv_message = op_payload->recv_message.recv_message;
1427
- if (s->id != 0 &&
1428
- (s->incoming_frames.head == NULL || s->incoming_frames.head->is_tail)) {
1429
- incoming_byte_stream_update_flow_control(exec_ctx, t, s, 5, 0);
1459
+ if (s->id != 0) {
1460
+ if (s->pending_byte_stream) {
1461
+ already_received = s->frame_storage.length;
1462
+ } else {
1463
+ already_received = s->frame_storage.length +
1464
+ s->unprocessed_incoming_frames_buffer.length;
1465
+ }
1466
+ incoming_byte_stream_update_flow_control(exec_ctx, t, s, 5,
1467
+ already_received);
1430
1468
  }
1431
1469
  grpc_chttp2_maybe_complete_recv_message(exec_ctx, t, s);
1432
1470
  }
@@ -1454,9 +1492,9 @@ static void perform_stream_op(grpc_exec_ctx *exec_ctx, grpc_transport *gt,
1454
1492
  grpc_chttp2_transport *t = (grpc_chttp2_transport *)gt;
1455
1493
  grpc_chttp2_stream *s = (grpc_chttp2_stream *)gs;
1456
1494
 
1457
- if (grpc_http_trace) {
1495
+ if (GRPC_TRACER_ON(grpc_http_trace)) {
1458
1496
  char *str = grpc_transport_stream_op_batch_string(op);
1459
- gpr_log(GPR_DEBUG, "perform_stream_op[s=%p/%d]: %s", s, s->id, str);
1497
+ gpr_log(GPR_DEBUG, "perform_stream_op[s=%p]: %s", s, str);
1460
1498
  gpr_free(str);
1461
1499
  }
1462
1500
 
@@ -1614,13 +1652,13 @@ static void perform_transport_op(grpc_exec_ctx *exec_ctx, grpc_transport *gt,
1614
1652
  void grpc_chttp2_maybe_complete_recv_initial_metadata(grpc_exec_ctx *exec_ctx,
1615
1653
  grpc_chttp2_transport *t,
1616
1654
  grpc_chttp2_stream *s) {
1617
- grpc_byte_stream *bs;
1618
1655
  if (s->recv_initial_metadata_ready != NULL &&
1619
1656
  s->published_metadata[0] != GRPC_METADATA_NOT_PUBLISHED) {
1620
1657
  if (s->seen_error) {
1621
- while ((bs = grpc_chttp2_incoming_frame_queue_pop(&s->incoming_frames)) !=
1622
- NULL) {
1623
- incoming_byte_stream_destroy_locked(exec_ctx, bs, GRPC_ERROR_NONE);
1658
+ grpc_slice_buffer_reset_and_unref_internal(exec_ctx, &s->frame_storage);
1659
+ if (!s->pending_byte_stream) {
1660
+ grpc_slice_buffer_reset_and_unref_internal(
1661
+ exec_ctx, &s->unprocessed_incoming_frames_buffer);
1624
1662
  }
1625
1663
  }
1626
1664
  grpc_chttp2_incoming_metadata_buffer_publish(
@@ -1633,39 +1671,65 @@ void grpc_chttp2_maybe_complete_recv_initial_metadata(grpc_exec_ctx *exec_ctx,
1633
1671
  void grpc_chttp2_maybe_complete_recv_message(grpc_exec_ctx *exec_ctx,
1634
1672
  grpc_chttp2_transport *t,
1635
1673
  grpc_chttp2_stream *s) {
1636
- grpc_byte_stream *bs;
1674
+ grpc_error *error = GRPC_ERROR_NONE;
1637
1675
  if (s->recv_message_ready != NULL) {
1638
- while (s->final_metadata_requested && s->seen_error &&
1639
- (bs = grpc_chttp2_incoming_frame_queue_pop(&s->incoming_frames)) !=
1640
- NULL) {
1641
- incoming_byte_stream_destroy_locked(exec_ctx, bs, GRPC_ERROR_NONE);
1676
+ *s->recv_message = NULL;
1677
+ if (s->final_metadata_requested && s->seen_error) {
1678
+ grpc_slice_buffer_reset_and_unref_internal(exec_ctx, &s->frame_storage);
1679
+ if (!s->pending_byte_stream) {
1680
+ grpc_slice_buffer_reset_and_unref_internal(
1681
+ exec_ctx, &s->unprocessed_incoming_frames_buffer);
1682
+ }
1683
+ }
1684
+ if (!s->pending_byte_stream) {
1685
+ while (s->unprocessed_incoming_frames_buffer.length > 0 ||
1686
+ s->frame_storage.length > 0) {
1687
+ if (s->unprocessed_incoming_frames_buffer.length == 0) {
1688
+ grpc_slice_buffer_swap(&s->unprocessed_incoming_frames_buffer,
1689
+ &s->frame_storage);
1690
+ }
1691
+ error = grpc_deframe_unprocessed_incoming_frames(
1692
+ exec_ctx, &s->data_parser, s,
1693
+ &s->unprocessed_incoming_frames_buffer, NULL, s->recv_message);
1694
+ if (error != GRPC_ERROR_NONE) {
1695
+ s->seen_error = true;
1696
+ grpc_slice_buffer_reset_and_unref_internal(exec_ctx,
1697
+ &s->frame_storage);
1698
+ grpc_slice_buffer_reset_and_unref_internal(
1699
+ exec_ctx, &s->unprocessed_incoming_frames_buffer);
1700
+ break;
1701
+ } else if (*s->recv_message != NULL) {
1702
+ break;
1703
+ }
1704
+ }
1642
1705
  }
1643
- if (s->incoming_frames.head != NULL) {
1644
- *s->recv_message =
1645
- grpc_chttp2_incoming_frame_queue_pop(&s->incoming_frames);
1646
- GPR_ASSERT(*s->recv_message != NULL);
1706
+ if (error == GRPC_ERROR_NONE && *s->recv_message != NULL) {
1647
1707
  null_then_run_closure(exec_ctx, &s->recv_message_ready, GRPC_ERROR_NONE);
1648
1708
  } else if (s->published_metadata[1] != GRPC_METADATA_NOT_PUBLISHED) {
1649
1709
  *s->recv_message = NULL;
1650
1710
  null_then_run_closure(exec_ctx, &s->recv_message_ready, GRPC_ERROR_NONE);
1651
1711
  }
1712
+ GRPC_ERROR_UNREF(error);
1652
1713
  }
1653
1714
  }
1654
1715
 
1655
1716
  void grpc_chttp2_maybe_complete_recv_trailing_metadata(grpc_exec_ctx *exec_ctx,
1656
1717
  grpc_chttp2_transport *t,
1657
1718
  grpc_chttp2_stream *s) {
1658
- grpc_byte_stream *bs;
1659
1719
  grpc_chttp2_maybe_complete_recv_message(exec_ctx, t, s);
1660
1720
  if (s->recv_trailing_metadata_finished != NULL && s->read_closed &&
1661
1721
  s->write_closed) {
1662
1722
  if (s->seen_error) {
1663
- while ((bs = grpc_chttp2_incoming_frame_queue_pop(&s->incoming_frames)) !=
1664
- NULL) {
1665
- incoming_byte_stream_destroy_locked(exec_ctx, bs, GRPC_ERROR_NONE);
1723
+ grpc_slice_buffer_reset_and_unref_internal(exec_ctx, &s->frame_storage);
1724
+ if (!s->pending_byte_stream) {
1725
+ grpc_slice_buffer_reset_and_unref_internal(
1726
+ exec_ctx, &s->unprocessed_incoming_frames_buffer);
1666
1727
  }
1667
1728
  }
1668
- if (s->all_incoming_byte_streams_finished &&
1729
+ bool pending_data = s->pending_byte_stream ||
1730
+ s->unprocessed_incoming_frames_buffer.length > 0;
1731
+ if (s->read_closed && s->frame_storage.length == 0 &&
1732
+ (!pending_data || s->seen_error) &&
1669
1733
  s->recv_trailing_metadata_finished != NULL) {
1670
1734
  grpc_chttp2_incoming_metadata_buffer_publish(
1671
1735
  exec_ctx, &s->metadata_buffer[1], s->recv_trailing_metadata);
@@ -1676,14 +1740,6 @@ void grpc_chttp2_maybe_complete_recv_trailing_metadata(grpc_exec_ctx *exec_ctx,
1676
1740
  }
1677
1741
  }
1678
1742
 
1679
- static void decrement_active_streams_locked(grpc_exec_ctx *exec_ctx,
1680
- grpc_chttp2_transport *t,
1681
- grpc_chttp2_stream *s) {
1682
- if ((s->all_incoming_byte_streams_finished = gpr_unref(&s->active_streams))) {
1683
- grpc_chttp2_maybe_complete_recv_trailing_metadata(exec_ctx, t, s);
1684
- }
1685
- }
1686
-
1687
1743
  static void remove_stream(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t,
1688
1744
  uint32_t id, grpc_error *error) {
1689
1745
  grpc_chttp2_stream *s = grpc_chttp2_stream_map_delete(&t->stream_map, id);
@@ -1692,10 +1748,19 @@ static void remove_stream(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t,
1692
1748
  t->incoming_stream = NULL;
1693
1749
  grpc_chttp2_parsing_become_skip_parser(exec_ctx, t);
1694
1750
  }
1695
- if (s->data_parser.parsing_frame != NULL) {
1696
- grpc_chttp2_incoming_byte_stream_finished(
1697
- exec_ctx, s->data_parser.parsing_frame, GRPC_ERROR_REF(error));
1698
- s->data_parser.parsing_frame = NULL;
1751
+ if (s->pending_byte_stream) {
1752
+ if (s->on_next != NULL) {
1753
+ grpc_chttp2_incoming_byte_stream *bs = s->data_parser.parsing_frame;
1754
+ if (error == GRPC_ERROR_NONE) {
1755
+ error = GRPC_ERROR_CREATE_FROM_STATIC_STRING("Truncated message");
1756
+ }
1757
+ incoming_byte_stream_publish_error(exec_ctx, bs, error);
1758
+ incoming_byte_stream_unref(exec_ctx, bs);
1759
+ s->data_parser.parsing_frame = NULL;
1760
+ } else {
1761
+ GRPC_ERROR_UNREF(s->byte_stream_error);
1762
+ s->byte_stream_error = GRPC_ERROR_REF(error);
1763
+ }
1699
1764
  }
1700
1765
 
1701
1766
  if (grpc_chttp2_stream_map_size(&t->stream_map) == 0) {
@@ -1881,7 +1946,6 @@ void grpc_chttp2_mark_stream_closed(grpc_exec_ctx *exec_ctx,
1881
1946
  s->published_metadata[i] = GPRC_METADATA_PUBLISHED_AT_CLOSE;
1882
1947
  }
1883
1948
  }
1884
- decrement_active_streams_locked(exec_ctx, t, s);
1885
1949
  grpc_chttp2_maybe_complete_recv_initial_metadata(exec_ctx, t, s);
1886
1950
  grpc_chttp2_maybe_complete_recv_message(exec_ctx, t, s);
1887
1951
  }
@@ -1914,7 +1978,7 @@ static void close_from_api(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t,
1914
1978
  the time we got around to sending this, so instead we ignore HPACK
1915
1979
  compression and just write the uncompressed bytes onto the wire. */
1916
1980
  if (!s->sent_initial_metadata) {
1917
- http_status_hdr = grpc_slice_malloc(13);
1981
+ http_status_hdr = GRPC_SLICE_MALLOC(13);
1918
1982
  p = GRPC_SLICE_START_PTR(http_status_hdr);
1919
1983
  *p++ = 0x00;
1920
1984
  *p++ = 7;
@@ -1932,7 +1996,7 @@ static void close_from_api(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t,
1932
1996
  GPR_ASSERT(p == GRPC_SLICE_END_PTR(http_status_hdr));
1933
1997
  len += (uint32_t)GRPC_SLICE_LENGTH(http_status_hdr);
1934
1998
 
1935
- content_type_hdr = grpc_slice_malloc(31);
1999
+ content_type_hdr = GRPC_SLICE_MALLOC(31);
1936
2000
  p = GRPC_SLICE_START_PTR(content_type_hdr);
1937
2001
  *p++ = 0x00;
1938
2002
  *p++ = 12;
@@ -1969,7 +2033,7 @@ static void close_from_api(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t,
1969
2033
  len += (uint32_t)GRPC_SLICE_LENGTH(content_type_hdr);
1970
2034
  }
1971
2035
 
1972
- status_hdr = grpc_slice_malloc(15 + (grpc_status >= 10));
2036
+ status_hdr = GRPC_SLICE_MALLOC(15 + (grpc_status >= 10));
1973
2037
  p = GRPC_SLICE_START_PTR(status_hdr);
1974
2038
  *p++ = 0x00; /* literal header, not indexed */
1975
2039
  *p++ = 11; /* len(grpc-status) */
@@ -1998,7 +2062,7 @@ static void close_from_api(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t,
1998
2062
  size_t msg_len = GRPC_SLICE_LENGTH(slice);
1999
2063
  GPR_ASSERT(msg_len <= UINT32_MAX);
2000
2064
  uint32_t msg_len_len = GRPC_CHTTP2_VARINT_LENGTH((uint32_t)msg_len, 1);
2001
- message_pfx = grpc_slice_malloc(14 + msg_len_len);
2065
+ message_pfx = GRPC_SLICE_MALLOC(14 + msg_len_len);
2002
2066
  p = GRPC_SLICE_START_PTR(message_pfx);
2003
2067
  *p++ = 0x00; /* literal header, not indexed */
2004
2068
  *p++ = 12; /* len(grpc-message) */
@@ -2020,7 +2084,7 @@ static void close_from_api(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t,
2020
2084
  len += (uint32_t)GRPC_SLICE_LENGTH(message_pfx);
2021
2085
  len += (uint32_t)msg_len;
2022
2086
 
2023
- hdr = grpc_slice_malloc(9);
2087
+ hdr = GRPC_SLICE_MALLOC(9);
2024
2088
  p = GRPC_SLICE_START_PTR(hdr);
2025
2089
  *p++ = (uint8_t)(len >> 16);
2026
2090
  *p++ = (uint8_t)(len >> 8);
@@ -2075,26 +2139,41 @@ static void end_all_the_calls(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t,
2075
2139
 
2076
2140
  static void update_bdp(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t,
2077
2141
  double bdp_dbl) {
2078
- uint32_t bdp;
2079
- if (bdp_dbl <= 0) {
2080
- bdp = 0;
2081
- } else if (bdp_dbl > UINT32_MAX) {
2082
- bdp = UINT32_MAX;
2083
- } else {
2084
- bdp = (uint32_t)(bdp_dbl);
2085
- }
2142
+ // initial window size bounded [1,2^31-1], but we set the min to 128.
2143
+ int32_t bdp = GPR_CLAMP((int32_t)bdp_dbl, 128, INT32_MAX);
2086
2144
  int64_t delta =
2087
2145
  (int64_t)bdp -
2088
2146
  (int64_t)t->settings[GRPC_LOCAL_SETTINGS]
2089
2147
  [GRPC_CHTTP2_SETTINGS_INITIAL_WINDOW_SIZE];
2090
- if (delta == 0 || (bdp != 0 && delta > -1024 && delta < 1024)) {
2148
+ if (delta == 0 || (delta > -bdp / 10 && delta < bdp / 10)) {
2091
2149
  return;
2092
2150
  }
2093
- if (grpc_bdp_estimator_trace) {
2151
+ if (GRPC_TRACER_ON(grpc_bdp_estimator_trace)) {
2094
2152
  gpr_log(GPR_DEBUG, "%s: update initial window size to %d", t->peer_string,
2095
2153
  (int)bdp);
2096
2154
  }
2097
- push_setting(exec_ctx, t, GRPC_CHTTP2_SETTINGS_INITIAL_WINDOW_SIZE, bdp);
2155
+ push_setting(exec_ctx, t, GRPC_CHTTP2_SETTINGS_INITIAL_WINDOW_SIZE,
2156
+ (uint32_t)bdp);
2157
+ }
2158
+
2159
+ static void update_frame(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t,
2160
+ double bw_dbl, double bdp_dbl) {
2161
+ int32_t bdp = GPR_CLAMP((int32_t)bdp_dbl, 128, INT32_MAX);
2162
+ int32_t target = GPR_MAX((int32_t)bw_dbl / 1000, bdp);
2163
+ // frame size is bounded [2^14,2^24-1]
2164
+ int32_t frame_size = GPR_CLAMP(target, 16384, 16777215);
2165
+ int64_t delta = (int64_t)frame_size -
2166
+ (int64_t)t->settings[GRPC_LOCAL_SETTINGS]
2167
+ [GRPC_CHTTP2_SETTINGS_MAX_FRAME_SIZE];
2168
+ if (delta == 0 || (delta > -frame_size / 10 && delta < frame_size / 10)) {
2169
+ return;
2170
+ }
2171
+ if (GRPC_TRACER_ON(grpc_bdp_estimator_trace)) {
2172
+ gpr_log(GPR_DEBUG, "%s: update max_frame size to %d", t->peer_string,
2173
+ (int)frame_size);
2174
+ }
2175
+ push_setting(exec_ctx, t, GRPC_CHTTP2_SETTINGS_MAX_FRAME_SIZE,
2176
+ (uint32_t)frame_size);
2098
2177
  }
2099
2178
 
2100
2179
  static grpc_error *try_http_parsing(grpc_exec_ctx *exec_ctx,
@@ -2213,6 +2292,7 @@ static void read_action_locked(grpc_exec_ctx *exec_ctx, void *tp,
2213
2292
  }
2214
2293
 
2215
2294
  int64_t estimate = -1;
2295
+ double bdp_guess = -1;
2216
2296
  if (grpc_bdp_estimator_get_estimate(&t->bdp_estimator, &estimate)) {
2217
2297
  double target = 1 + log2((double)estimate);
2218
2298
  double memory_pressure = grpc_resource_quota_get_memory_pressure(
@@ -2230,9 +2310,15 @@ static void read_action_locked(grpc_exec_ctx *exec_ctx, void *tp,
2230
2310
  }
2231
2311
  double log2_bdp_guess =
2232
2312
  grpc_pid_controller_update(&t->pid_controller, bdp_error, dt);
2233
- update_bdp(exec_ctx, t, pow(2, log2_bdp_guess));
2313
+ bdp_guess = pow(2, log2_bdp_guess);
2314
+ update_bdp(exec_ctx, t, bdp_guess);
2234
2315
  t->last_pid_update = now;
2235
2316
  }
2317
+
2318
+ double bw = -1;
2319
+ if (grpc_bdp_estimator_get_bw(&t->bdp_estimator, &bw)) {
2320
+ update_frame(exec_ctx, t, bw, bdp_guess);
2321
+ }
2236
2322
  }
2237
2323
  GRPC_CHTTP2_UNREF_TRANSPORT(exec_ctx, t, "keep_reading");
2238
2324
  } else {
@@ -2249,7 +2335,7 @@ static void read_action_locked(grpc_exec_ctx *exec_ctx, void *tp,
2249
2335
  static void start_bdp_ping_locked(grpc_exec_ctx *exec_ctx, void *tp,
2250
2336
  grpc_error *error) {
2251
2337
  grpc_chttp2_transport *t = tp;
2252
- if (grpc_http_trace) {
2338
+ if (GRPC_TRACER_ON(grpc_http_trace)) {
2253
2339
  gpr_log(GPR_DEBUG, "%s: Start BDP ping", t->peer_string);
2254
2340
  }
2255
2341
  /* Reset the keepalive ping timer */
@@ -2262,7 +2348,7 @@ static void start_bdp_ping_locked(grpc_exec_ctx *exec_ctx, void *tp,
2262
2348
  static void finish_bdp_ping_locked(grpc_exec_ctx *exec_ctx, void *tp,
2263
2349
  grpc_error *error) {
2264
2350
  grpc_chttp2_transport *t = tp;
2265
- if (grpc_http_trace) {
2351
+ if (GRPC_TRACER_ON(grpc_http_trace)) {
2266
2352
  gpr_log(GPR_DEBUG, "%s: Complete BDP ping", t->peer_string);
2267
2353
  }
2268
2354
  grpc_bdp_estimator_complete_ping(&t->bdp_estimator);
@@ -2312,7 +2398,9 @@ static void init_keepalive_ping_locked(grpc_exec_ctx *exec_ctx, void *arg,
2312
2398
  grpc_error *error) {
2313
2399
  grpc_chttp2_transport *t = arg;
2314
2400
  GPR_ASSERT(t->keepalive_state == GRPC_CHTTP2_KEEPALIVE_STATE_WAITING);
2315
- if (error == GRPC_ERROR_NONE && !(t->destroying || t->closed)) {
2401
+ if (t->destroying || t->closed) {
2402
+ t->keepalive_state = GRPC_CHTTP2_KEEPALIVE_STATE_DYING;
2403
+ } else if (error == GRPC_ERROR_NONE) {
2316
2404
  if (t->keepalive_permit_without_calls ||
2317
2405
  grpc_chttp2_stream_map_size(&t->stream_map) > 0) {
2318
2406
  t->keepalive_state = GRPC_CHTTP2_KEEPALIVE_STATE_PINGING;
@@ -2327,7 +2415,7 @@ static void init_keepalive_ping_locked(grpc_exec_ctx *exec_ctx, void *arg,
2327
2415
  gpr_time_add(gpr_now(GPR_CLOCK_MONOTONIC), t->keepalive_time),
2328
2416
  &t->init_keepalive_ping_locked, gpr_now(GPR_CLOCK_MONOTONIC));
2329
2417
  }
2330
- } else if (error == GRPC_ERROR_CANCELLED && !(t->destroying || t->closed)) {
2418
+ } else if (error == GRPC_ERROR_CANCELLED) {
2331
2419
  /* The keepalive ping timer may be cancelled by bdp */
2332
2420
  GRPC_CHTTP2_REF_TRANSPORT(t, "init keepalive ping");
2333
2421
  grpc_timer_init(
@@ -2419,12 +2507,28 @@ static void set_pollset_set(grpc_exec_ctx *exec_ctx, grpc_transport *gt,
2419
2507
  * BYTE STREAM
2420
2508
  */
2421
2509
 
2510
+ static void reset_byte_stream(grpc_exec_ctx *exec_ctx, void *arg,
2511
+ grpc_error *error) {
2512
+ grpc_chttp2_stream *s = (grpc_chttp2_stream *)arg;
2513
+
2514
+ s->pending_byte_stream = false;
2515
+ if (error == GRPC_ERROR_NONE) {
2516
+ grpc_chttp2_maybe_complete_recv_message(exec_ctx, s->t, s);
2517
+ grpc_chttp2_maybe_complete_recv_trailing_metadata(exec_ctx, s->t, s);
2518
+ } else {
2519
+ GPR_ASSERT(error != GRPC_ERROR_NONE);
2520
+ grpc_closure_sched(exec_ctx, s->on_next, GRPC_ERROR_REF(error));
2521
+ s->on_next = NULL;
2522
+ GRPC_ERROR_UNREF(s->byte_stream_error);
2523
+ s->byte_stream_error = GRPC_ERROR_NONE;
2524
+ grpc_chttp2_cancel_stream(exec_ctx, s->t, s, GRPC_ERROR_REF(error));
2525
+ s->byte_stream_error = error;
2526
+ }
2527
+ }
2528
+
2422
2529
  static void incoming_byte_stream_unref(grpc_exec_ctx *exec_ctx,
2423
2530
  grpc_chttp2_incoming_byte_stream *bs) {
2424
2531
  if (gpr_unref(&bs->refs)) {
2425
- GRPC_ERROR_UNREF(bs->error);
2426
- grpc_slice_buffer_destroy_internal(exec_ctx, &bs->slices);
2427
- gpr_mu_destroy(&bs->slice_mu);
2428
2532
  gpr_free(bs);
2429
2533
  }
2430
2534
  }
@@ -2484,47 +2588,91 @@ static void incoming_byte_stream_next_locked(grpc_exec_ctx *exec_ctx,
2484
2588
  grpc_chttp2_transport *t = bs->transport;
2485
2589
  grpc_chttp2_stream *s = bs->stream;
2486
2590
 
2487
- if (bs->is_tail) {
2488
- gpr_mu_lock(&bs->slice_mu);
2489
- size_t cur_length = bs->slices.length;
2490
- gpr_mu_unlock(&bs->slice_mu);
2491
- incoming_byte_stream_update_flow_control(
2492
- exec_ctx, t, s, bs->next_action.max_size_hint, cur_length);
2493
- }
2494
- gpr_mu_lock(&bs->slice_mu);
2495
- if (bs->slices.count > 0) {
2496
- *bs->next_action.slice = grpc_slice_buffer_take_first(&bs->slices);
2497
- grpc_closure_run(exec_ctx, bs->next_action.on_complete, GRPC_ERROR_NONE);
2498
- } else if (bs->error != GRPC_ERROR_NONE) {
2499
- grpc_closure_run(exec_ctx, bs->next_action.on_complete,
2500
- GRPC_ERROR_REF(bs->error));
2591
+ size_t cur_length = s->frame_storage.length;
2592
+ incoming_byte_stream_update_flow_control(
2593
+ exec_ctx, t, s, bs->next_action.max_size_hint, cur_length);
2594
+
2595
+ GPR_ASSERT(s->unprocessed_incoming_frames_buffer.length == 0);
2596
+ if (s->frame_storage.length > 0) {
2597
+ grpc_slice_buffer_swap(&s->frame_storage,
2598
+ &s->unprocessed_incoming_frames_buffer);
2599
+ grpc_closure_sched(exec_ctx, bs->next_action.on_complete, GRPC_ERROR_NONE);
2600
+ } else if (s->byte_stream_error != GRPC_ERROR_NONE) {
2601
+ grpc_closure_sched(exec_ctx, bs->next_action.on_complete,
2602
+ GRPC_ERROR_REF(s->byte_stream_error));
2603
+ if (s->data_parser.parsing_frame != NULL) {
2604
+ incoming_byte_stream_unref(exec_ctx, s->data_parser.parsing_frame);
2605
+ s->data_parser.parsing_frame = NULL;
2606
+ }
2607
+ } else if (s->read_closed) {
2608
+ if (bs->remaining_bytes != 0) {
2609
+ s->byte_stream_error =
2610
+ GRPC_ERROR_CREATE_FROM_STATIC_STRING("Truncated message");
2611
+ grpc_closure_sched(exec_ctx, bs->next_action.on_complete,
2612
+ GRPC_ERROR_REF(s->byte_stream_error));
2613
+ if (s->data_parser.parsing_frame != NULL) {
2614
+ incoming_byte_stream_unref(exec_ctx, s->data_parser.parsing_frame);
2615
+ s->data_parser.parsing_frame = NULL;
2616
+ }
2617
+ } else {
2618
+ /* Should never reach here. */
2619
+ GPR_ASSERT(false);
2620
+ }
2501
2621
  } else {
2502
- bs->on_next = bs->next_action.on_complete;
2503
- bs->next = bs->next_action.slice;
2622
+ s->on_next = bs->next_action.on_complete;
2504
2623
  }
2505
- gpr_mu_unlock(&bs->slice_mu);
2506
2624
  incoming_byte_stream_unref(exec_ctx, bs);
2507
2625
  }
2508
2626
 
2509
- static int incoming_byte_stream_next(grpc_exec_ctx *exec_ctx,
2510
- grpc_byte_stream *byte_stream,
2511
- grpc_slice *slice, size_t max_size_hint,
2512
- grpc_closure *on_complete) {
2627
+ static bool incoming_byte_stream_next(grpc_exec_ctx *exec_ctx,
2628
+ grpc_byte_stream *byte_stream,
2629
+ size_t max_size_hint,
2630
+ grpc_closure *on_complete) {
2513
2631
  GPR_TIMER_BEGIN("incoming_byte_stream_next", 0);
2514
2632
  grpc_chttp2_incoming_byte_stream *bs =
2515
2633
  (grpc_chttp2_incoming_byte_stream *)byte_stream;
2516
- gpr_ref(&bs->refs);
2517
- bs->next_action.slice = slice;
2518
- bs->next_action.max_size_hint = max_size_hint;
2519
- bs->next_action.on_complete = on_complete;
2520
- grpc_closure_sched(
2521
- exec_ctx,
2522
- grpc_closure_init(
2523
- &bs->next_action.closure, incoming_byte_stream_next_locked, bs,
2524
- grpc_combiner_scheduler(bs->transport->combiner, false)),
2525
- GRPC_ERROR_NONE);
2526
- GPR_TIMER_END("incoming_byte_stream_next", 0);
2527
- return 0;
2634
+ grpc_chttp2_stream *s = bs->stream;
2635
+ if (s->unprocessed_incoming_frames_buffer.length > 0) {
2636
+ GPR_TIMER_END("incoming_byte_stream_next", 0);
2637
+ return true;
2638
+ } else {
2639
+ gpr_ref(&bs->refs);
2640
+ bs->next_action.max_size_hint = max_size_hint;
2641
+ bs->next_action.on_complete = on_complete;
2642
+ grpc_closure_sched(
2643
+ exec_ctx,
2644
+ grpc_closure_init(
2645
+ &bs->next_action.closure, incoming_byte_stream_next_locked, bs,
2646
+ grpc_combiner_scheduler(bs->transport->combiner, false)),
2647
+ GRPC_ERROR_NONE);
2648
+ GPR_TIMER_END("incoming_byte_stream_next", 0);
2649
+ return false;
2650
+ }
2651
+ }
2652
+
2653
+ static grpc_error *incoming_byte_stream_pull(grpc_exec_ctx *exec_ctx,
2654
+ grpc_byte_stream *byte_stream,
2655
+ grpc_slice *slice) {
2656
+ GPR_TIMER_BEGIN("incoming_byte_stream_pull", 0);
2657
+ grpc_chttp2_incoming_byte_stream *bs =
2658
+ (grpc_chttp2_incoming_byte_stream *)byte_stream;
2659
+ grpc_chttp2_stream *s = bs->stream;
2660
+
2661
+ if (s->unprocessed_incoming_frames_buffer.length > 0) {
2662
+ grpc_error *error = grpc_deframe_unprocessed_incoming_frames(
2663
+ exec_ctx, &s->data_parser, s, &s->unprocessed_incoming_frames_buffer,
2664
+ slice, NULL);
2665
+ if (error != GRPC_ERROR_NONE) {
2666
+ return error;
2667
+ }
2668
+ } else {
2669
+ grpc_error *error =
2670
+ GRPC_ERROR_CREATE_FROM_STATIC_STRING("Truncated message");
2671
+ grpc_closure_sched(exec_ctx, &s->reset_byte_stream, GRPC_ERROR_REF(error));
2672
+ return error;
2673
+ }
2674
+ GPR_TIMER_END("incoming_byte_stream_pull", 0);
2675
+ return GRPC_ERROR_NONE;
2528
2676
  }
2529
2677
 
2530
2678
  static void incoming_byte_stream_destroy(grpc_exec_ctx *exec_ctx,
@@ -2534,9 +2682,14 @@ static void incoming_byte_stream_destroy_locked(grpc_exec_ctx *exec_ctx,
2534
2682
  void *byte_stream,
2535
2683
  grpc_error *error_ignored) {
2536
2684
  grpc_chttp2_incoming_byte_stream *bs = byte_stream;
2685
+ grpc_chttp2_stream *s = bs->stream;
2686
+ grpc_chttp2_transport *t = s->t;
2687
+
2537
2688
  GPR_ASSERT(bs->base.destroy == incoming_byte_stream_destroy);
2538
- decrement_active_streams_locked(exec_ctx, bs->transport, bs->stream);
2539
2689
  incoming_byte_stream_unref(exec_ctx, bs);
2690
+ s->pending_byte_stream = false;
2691
+ grpc_chttp2_maybe_complete_recv_message(exec_ctx, t, s);
2692
+ grpc_chttp2_maybe_complete_recv_trailing_metadata(exec_ctx, t, s);
2540
2693
  }
2541
2694
 
2542
2695
  static void incoming_byte_stream_destroy(grpc_exec_ctx *exec_ctx,
@@ -2556,50 +2709,53 @@ static void incoming_byte_stream_destroy(grpc_exec_ctx *exec_ctx,
2556
2709
  static void incoming_byte_stream_publish_error(
2557
2710
  grpc_exec_ctx *exec_ctx, grpc_chttp2_incoming_byte_stream *bs,
2558
2711
  grpc_error *error) {
2712
+ grpc_chttp2_stream *s = bs->stream;
2713
+
2559
2714
  GPR_ASSERT(error != GRPC_ERROR_NONE);
2560
- grpc_closure_sched(exec_ctx, bs->on_next, GRPC_ERROR_REF(error));
2561
- bs->on_next = NULL;
2562
- GRPC_ERROR_UNREF(bs->error);
2715
+ grpc_closure_sched(exec_ctx, s->on_next, GRPC_ERROR_REF(error));
2716
+ s->on_next = NULL;
2717
+ GRPC_ERROR_UNREF(s->byte_stream_error);
2718
+ s->byte_stream_error = GRPC_ERROR_REF(error);
2563
2719
  grpc_chttp2_cancel_stream(exec_ctx, bs->transport, bs->stream,
2564
2720
  GRPC_ERROR_REF(error));
2565
- bs->error = error;
2566
2721
  }
2567
2722
 
2568
- void grpc_chttp2_incoming_byte_stream_push(grpc_exec_ctx *exec_ctx,
2569
- grpc_chttp2_incoming_byte_stream *bs,
2570
- grpc_slice slice) {
2571
- gpr_mu_lock(&bs->slice_mu);
2723
+ grpc_error *grpc_chttp2_incoming_byte_stream_push(
2724
+ grpc_exec_ctx *exec_ctx, grpc_chttp2_incoming_byte_stream *bs,
2725
+ grpc_slice slice, grpc_slice *slice_out) {
2726
+ grpc_chttp2_stream *s = bs->stream;
2727
+
2572
2728
  if (bs->remaining_bytes < GRPC_SLICE_LENGTH(slice)) {
2573
- incoming_byte_stream_publish_error(
2574
- exec_ctx, bs,
2575
- GRPC_ERROR_CREATE_FROM_STATIC_STRING("Too many bytes in stream"));
2729
+ grpc_error *error =
2730
+ GRPC_ERROR_CREATE_FROM_STATIC_STRING("Too many bytes in stream");
2731
+
2732
+ grpc_closure_sched(exec_ctx, &s->reset_byte_stream, GRPC_ERROR_REF(error));
2733
+ grpc_slice_unref_internal(exec_ctx, slice);
2734
+ return error;
2576
2735
  } else {
2577
2736
  bs->remaining_bytes -= (uint32_t)GRPC_SLICE_LENGTH(slice);
2578
- if (bs->on_next != NULL) {
2579
- *bs->next = slice;
2580
- grpc_closure_sched(exec_ctx, bs->on_next, GRPC_ERROR_NONE);
2581
- bs->on_next = NULL;
2582
- } else {
2583
- grpc_slice_buffer_add(&bs->slices, slice);
2737
+ if (slice_out != NULL) {
2738
+ *slice_out = slice;
2584
2739
  }
2740
+ return GRPC_ERROR_NONE;
2585
2741
  }
2586
- gpr_mu_unlock(&bs->slice_mu);
2587
2742
  }
2588
2743
 
2589
- void grpc_chttp2_incoming_byte_stream_finished(
2744
+ grpc_error *grpc_chttp2_incoming_byte_stream_finished(
2590
2745
  grpc_exec_ctx *exec_ctx, grpc_chttp2_incoming_byte_stream *bs,
2591
- grpc_error *error) {
2746
+ grpc_error *error, bool reset_on_error) {
2747
+ grpc_chttp2_stream *s = bs->stream;
2748
+
2592
2749
  if (error == GRPC_ERROR_NONE) {
2593
- gpr_mu_lock(&bs->slice_mu);
2594
2750
  if (bs->remaining_bytes != 0) {
2595
2751
  error = GRPC_ERROR_CREATE_FROM_STATIC_STRING("Truncated message");
2596
2752
  }
2597
- gpr_mu_unlock(&bs->slice_mu);
2598
2753
  }
2599
- if (error != GRPC_ERROR_NONE) {
2600
- incoming_byte_stream_publish_error(exec_ctx, bs, error);
2754
+ if (error != GRPC_ERROR_NONE && reset_on_error) {
2755
+ grpc_closure_sched(exec_ctx, &s->reset_byte_stream, GRPC_ERROR_REF(error));
2601
2756
  }
2602
2757
  incoming_byte_stream_unref(exec_ctx, bs);
2758
+ return error;
2603
2759
  }
2604
2760
 
2605
2761
  grpc_chttp2_incoming_byte_stream *grpc_chttp2_incoming_byte_stream_create(
@@ -2611,26 +2767,13 @@ grpc_chttp2_incoming_byte_stream *grpc_chttp2_incoming_byte_stream_create(
2611
2767
  incoming_byte_stream->remaining_bytes = frame_size;
2612
2768
  incoming_byte_stream->base.flags = flags;
2613
2769
  incoming_byte_stream->base.next = incoming_byte_stream_next;
2770
+ incoming_byte_stream->base.pull = incoming_byte_stream_pull;
2614
2771
  incoming_byte_stream->base.destroy = incoming_byte_stream_destroy;
2615
- gpr_mu_init(&incoming_byte_stream->slice_mu);
2616
2772
  gpr_ref_init(&incoming_byte_stream->refs, 2);
2617
- incoming_byte_stream->next_message = NULL;
2618
2773
  incoming_byte_stream->transport = t;
2619
2774
  incoming_byte_stream->stream = s;
2620
- gpr_ref(&incoming_byte_stream->stream->active_streams);
2621
- grpc_slice_buffer_init(&incoming_byte_stream->slices);
2622
- incoming_byte_stream->on_next = NULL;
2623
- incoming_byte_stream->is_tail = 1;
2624
- incoming_byte_stream->error = GRPC_ERROR_NONE;
2625
- grpc_chttp2_incoming_frame_queue *q = &s->incoming_frames;
2626
- if (q->head == NULL) {
2627
- q->head = incoming_byte_stream;
2628
- } else {
2629
- q->tail->is_tail = 0;
2630
- q->tail->next_message = incoming_byte_stream;
2631
- }
2632
- q->tail = incoming_byte_stream;
2633
- grpc_chttp2_maybe_complete_recv_message(exec_ctx, t, s);
2775
+ GRPC_ERROR_UNREF(s->byte_stream_error);
2776
+ s->byte_stream_error = GRPC_ERROR_NONE;
2634
2777
  return incoming_byte_stream;
2635
2778
  }
2636
2779
 
@@ -2667,7 +2810,7 @@ static void benign_reclaimer_locked(grpc_exec_ctx *exec_ctx, void *arg,
2667
2810
  grpc_chttp2_stream_map_size(&t->stream_map) == 0) {
2668
2811
  /* Channel with no active streams: send a goaway to try and make it
2669
2812
  * disconnect cleanly */
2670
- if (grpc_resource_quota_trace) {
2813
+ if (GRPC_TRACER_ON(grpc_resource_quota_trace)) {
2671
2814
  gpr_log(GPR_DEBUG, "HTTP2: %s - send goaway to free memory",
2672
2815
  t->peer_string);
2673
2816
  }
@@ -2675,7 +2818,8 @@ static void benign_reclaimer_locked(grpc_exec_ctx *exec_ctx, void *arg,
2675
2818
  grpc_error_set_int(
2676
2819
  GRPC_ERROR_CREATE_FROM_STATIC_STRING("Buffers full"),
2677
2820
  GRPC_ERROR_INT_HTTP2_ERROR, GRPC_HTTP2_ENHANCE_YOUR_CALM));
2678
- } else if (error == GRPC_ERROR_NONE && grpc_resource_quota_trace) {
2821
+ } else if (error == GRPC_ERROR_NONE &&
2822
+ GRPC_TRACER_ON(grpc_resource_quota_trace)) {
2679
2823
  gpr_log(GPR_DEBUG,
2680
2824
  "HTTP2: %s - skip benign reclamation, there are still %" PRIdPTR
2681
2825
  " streams",
@@ -2696,7 +2840,7 @@ static void destructive_reclaimer_locked(grpc_exec_ctx *exec_ctx, void *arg,
2696
2840
  t->destructive_reclaimer_registered = false;
2697
2841
  if (error == GRPC_ERROR_NONE && n > 0) {
2698
2842
  grpc_chttp2_stream *s = grpc_chttp2_stream_map_rand(&t->stream_map);
2699
- if (grpc_resource_quota_trace) {
2843
+ if (GRPC_TRACER_ON(grpc_resource_quota_trace)) {
2700
2844
  gpr_log(GPR_DEBUG, "HTTP2: %s - abandon stream id %d", t->peer_string,
2701
2845
  s->id);
2702
2846
  }