wearefair-grpc 1.3.1.pre.c → 1.4.0.fair

Sign up to get free protection for your applications and to get access to all the features.
Files changed (219) hide show
  1. checksums.yaml +4 -4
  2. data/Makefile +418 -126
  3. data/include/grpc/grpc.h +15 -69
  4. data/include/grpc/grpc_security.h +1 -1
  5. data/include/grpc/impl/codegen/compression_types.h +3 -4
  6. data/include/grpc/impl/codegen/gpr_types.h +0 -1
  7. data/include/grpc/impl/codegen/grpc_types.h +69 -3
  8. data/include/grpc/impl/codegen/port_platform.h +6 -0
  9. data/include/grpc/impl/codegen/slice.h +2 -1
  10. data/include/grpc/load_reporting.h +6 -6
  11. data/include/grpc/slice.h +25 -3
  12. data/include/grpc/slice_buffer.h +4 -0
  13. data/src/core/ext/census/context.c +1 -1
  14. data/src/core/ext/census/resource.c +3 -1
  15. data/src/core/ext/filters/client_channel/channel_connectivity.c +1 -1
  16. data/src/core/ext/filters/client_channel/client_channel.c +158 -100
  17. data/src/core/ext/filters/client_channel/client_channel_plugin.c +3 -2
  18. data/src/core/ext/filters/client_channel/lb_policy.c +2 -1
  19. data/src/core/ext/filters/client_channel/lb_policy.h +5 -6
  20. data/src/core/ext/filters/client_channel/lb_policy/grpclb/client_load_reporting_filter.c +153 -0
  21. data/src/core/ext/filters/client_channel/lb_policy/grpclb/client_load_reporting_filter.h +42 -0
  22. data/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.c +344 -88
  23. data/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_client_stats.c +133 -0
  24. data/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_client_stats.h +65 -0
  25. data/src/core/ext/filters/client_channel/lb_policy/grpclb/load_balancer_api.c +47 -5
  26. data/src/core/ext/filters/client_channel/lb_policy/grpclb/load_balancer_api.h +6 -0
  27. data/src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.c +19 -8
  28. data/src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.h +63 -34
  29. data/src/core/ext/filters/client_channel/lb_policy/pick_first/pick_first.c +2 -1
  30. data/src/core/ext/filters/client_channel/lb_policy/round_robin/round_robin.c +13 -12
  31. data/src/core/ext/filters/client_channel/lb_policy_factory.c +28 -5
  32. data/src/core/ext/filters/client_channel/lb_policy_factory.h +18 -4
  33. data/src/core/ext/filters/client_channel/parse_address.c +37 -7
  34. data/src/core/ext/filters/client_channel/parse_address.h +11 -8
  35. data/src/core/ext/filters/client_channel/resolver/sockaddr/sockaddr_resolver.c +3 -3
  36. data/src/core/ext/filters/client_channel/subchannel.c +19 -16
  37. data/src/core/ext/filters/client_channel/subchannel.h +1 -0
  38. data/src/core/ext/filters/client_channel/uri_parser.c +36 -22
  39. data/src/core/ext/filters/client_channel/uri_parser.h +1 -1
  40. data/src/core/{lib/channel → ext/filters/deadline}/deadline_filter.c +42 -17
  41. data/src/core/{lib/channel → ext/filters/deadline}/deadline_filter.h +8 -9
  42. data/src/core/{lib/channel → ext/filters/http/client}/http_client_filter.c +19 -11
  43. data/src/core/{lib/channel → ext/filters/http/client}/http_client_filter.h +3 -6
  44. data/src/core/ext/filters/http/http_filters_plugin.c +104 -0
  45. data/src/core/{lib/channel/compress_filter.c → ext/filters/http/message_compress/message_compress_filter.c} +124 -23
  46. data/src/core/{lib/channel/compress_filter.h → ext/filters/http/message_compress/message_compress_filter.h} +5 -6
  47. data/src/core/{lib/channel → ext/filters/http/server}/http_server_filter.c +4 -6
  48. data/src/core/{lib/channel → ext/filters/http/server}/http_server_filter.h +3 -3
  49. data/src/core/ext/filters/load_reporting/load_reporting.c +2 -25
  50. data/src/core/ext/filters/load_reporting/load_reporting_filter.c +26 -1
  51. data/src/core/ext/filters/max_age/max_age_filter.c +14 -14
  52. data/src/core/{lib/channel → ext/filters/message_size}/message_size_filter.c +91 -47
  53. data/src/core/{lib/channel → ext/filters/message_size}/message_size_filter.h +3 -3
  54. data/src/core/ext/transport/chttp2/client/insecure/channel_create.c +1 -1
  55. data/src/core/ext/transport/chttp2/server/chttp2_server.c +2 -2
  56. data/src/core/ext/transport/chttp2/transport/bin_decoder.c +2 -2
  57. data/src/core/ext/transport/chttp2/transport/bin_encoder.c +3 -3
  58. data/src/core/ext/transport/chttp2/transport/chttp2_transport.c +296 -172
  59. data/src/core/ext/transport/chttp2/transport/chttp2_transport.h +3 -2
  60. data/src/core/ext/transport/chttp2/transport/frame_data.c +203 -164
  61. data/src/core/ext/transport/chttp2/transport/frame_data.h +8 -14
  62. data/src/core/ext/transport/chttp2/transport/frame_goaway.c +1 -1
  63. data/src/core/ext/transport/chttp2/transport/frame_ping.c +1 -1
  64. data/src/core/ext/transport/chttp2/transport/frame_rst_stream.c +1 -1
  65. data/src/core/ext/transport/chttp2/transport/frame_settings.c +5 -5
  66. data/src/core/ext/transport/chttp2/transport/frame_window_update.c +1 -1
  67. data/src/core/ext/transport/chttp2/transport/hpack_encoder.c +4 -4
  68. data/src/core/ext/transport/chttp2/transport/hpack_parser.c +2 -4
  69. data/src/core/ext/transport/chttp2/transport/hpack_table.c +4 -3
  70. data/src/core/ext/transport/chttp2/transport/internal.h +50 -33
  71. data/src/core/ext/transport/chttp2/transport/parsing.c +10 -11
  72. data/src/core/ext/transport/chttp2/transport/writing.c +32 -13
  73. data/src/core/lib/channel/channel_args.c +28 -9
  74. data/src/core/lib/channel/channel_args.h +5 -1
  75. data/src/core/lib/channel/channel_stack.c +1 -1
  76. data/src/core/lib/channel/channel_stack.h +2 -2
  77. data/src/core/lib/channel/channel_stack_builder.c +13 -1
  78. data/src/core/lib/channel/channel_stack_builder.h +5 -1
  79. data/src/core/lib/channel/connected_channel.c +3 -1
  80. data/src/core/lib/channel/context.h +2 -2
  81. data/src/core/lib/compression/message_compress.c +2 -2
  82. data/src/core/lib/debug/trace.c +13 -6
  83. data/src/core/lib/debug/trace.h +27 -1
  84. data/src/core/lib/http/httpcli.c +1 -1
  85. data/src/core/lib/http/httpcli_security_connector.c +6 -10
  86. data/src/core/lib/http/parser.c +2 -2
  87. data/src/core/lib/http/parser.h +2 -1
  88. data/src/core/lib/iomgr/combiner.c +6 -6
  89. data/src/core/lib/iomgr/combiner.h +2 -1
  90. data/src/core/lib/iomgr/error.c +12 -5
  91. data/src/core/lib/iomgr/error.h +13 -13
  92. data/src/core/lib/iomgr/ev_epoll1_linux.c +984 -0
  93. data/src/core/lib/iomgr/ev_epoll1_linux.h +44 -0
  94. data/src/core/lib/iomgr/ev_epoll_limited_pollers_linux.c +2146 -0
  95. data/src/core/lib/iomgr/ev_epoll_limited_pollers_linux.h +43 -0
  96. data/src/core/lib/iomgr/ev_epoll_thread_pool_linux.c +1337 -0
  97. data/src/core/lib/iomgr/ev_epoll_thread_pool_linux.h +43 -0
  98. data/src/core/lib/iomgr/ev_epollex_linux.c +1511 -0
  99. data/src/core/lib/iomgr/ev_epollex_linux.h +43 -0
  100. data/src/core/lib/iomgr/{ev_epoll_linux.c → ev_epollsig_linux.c} +24 -31
  101. data/src/core/lib/iomgr/{ev_epoll_linux.h → ev_epollsig_linux.h} +4 -4
  102. data/src/core/lib/iomgr/ev_poll_posix.c +12 -27
  103. data/src/core/lib/iomgr/ev_poll_posix.h +2 -2
  104. data/src/core/lib/iomgr/ev_posix.c +22 -8
  105. data/src/core/lib/iomgr/ev_posix.h +4 -3
  106. data/src/core/lib/iomgr/exec_ctx.c +5 -0
  107. data/src/core/lib/iomgr/exec_ctx.h +2 -0
  108. data/src/core/lib/iomgr/iomgr.c +4 -0
  109. data/src/core/lib/iomgr/iomgr.h +3 -0
  110. data/src/core/lib/iomgr/is_epollexclusive_available.c +116 -0
  111. data/src/core/lib/iomgr/is_epollexclusive_available.h +41 -0
  112. data/src/core/lib/iomgr/lockfree_event.c +16 -0
  113. data/src/core/lib/iomgr/pollset.h +2 -5
  114. data/src/core/lib/iomgr/pollset_uv.c +1 -1
  115. data/src/core/lib/iomgr/pollset_windows.c +3 -3
  116. data/src/core/lib/iomgr/resource_quota.c +9 -8
  117. data/src/core/lib/iomgr/resource_quota.h +2 -1
  118. data/src/core/lib/iomgr/sockaddr_utils.h +1 -1
  119. data/src/core/lib/iomgr/socket_mutator.h +2 -0
  120. data/src/core/lib/iomgr/sys_epoll_wrapper.h +43 -0
  121. data/src/core/lib/iomgr/tcp_client_posix.c +6 -6
  122. data/src/core/lib/iomgr/tcp_client_uv.c +3 -3
  123. data/src/core/lib/iomgr/tcp_posix.c +7 -7
  124. data/src/core/lib/iomgr/tcp_posix.h +2 -1
  125. data/src/core/lib/iomgr/tcp_server_posix.c +1 -1
  126. data/src/core/lib/iomgr/tcp_uv.c +6 -6
  127. data/src/core/lib/iomgr/tcp_uv.h +2 -1
  128. data/src/core/lib/iomgr/tcp_windows.c +1 -1
  129. data/src/core/lib/iomgr/timer_generic.c +24 -25
  130. data/src/core/lib/iomgr/timer_manager.c +276 -0
  131. data/src/core/lib/iomgr/timer_manager.h +52 -0
  132. data/src/core/lib/iomgr/timer_uv.c +6 -0
  133. data/src/core/lib/iomgr/udp_server.c +42 -9
  134. data/src/core/lib/iomgr/udp_server.h +3 -1
  135. data/src/core/lib/security/credentials/credentials.c +0 -1
  136. data/src/core/lib/security/credentials/fake/fake_credentials.c +23 -0
  137. data/src/core/lib/security/credentials/fake/fake_credentials.h +12 -9
  138. data/src/core/lib/security/credentials/google_default/google_default_credentials.c +1 -1
  139. data/src/core/lib/security/credentials/jwt/jwt_credentials.c +1 -1
  140. data/src/core/lib/security/credentials/oauth2/oauth2_credentials.c +1 -1
  141. data/src/core/lib/security/credentials/ssl/ssl_credentials.c +24 -53
  142. data/src/core/lib/security/transport/client_auth_filter.c +9 -3
  143. data/src/core/lib/security/transport/secure_endpoint.c +7 -7
  144. data/src/core/lib/security/transport/secure_endpoint.h +1 -1
  145. data/src/core/lib/security/transport/security_connector.c +32 -51
  146. data/src/core/lib/security/transport/security_connector.h +10 -14
  147. data/src/core/lib/slice/b64.c +1 -1
  148. data/src/core/lib/slice/percent_encoding.c +3 -3
  149. data/src/core/lib/slice/slice.c +66 -33
  150. data/src/core/lib/slice/slice_buffer.c +25 -6
  151. data/src/core/lib/slice/slice_hash_table.c +33 -35
  152. data/src/core/lib/slice/slice_hash_table.h +7 -12
  153. data/src/core/lib/support/atomic.h +45 -0
  154. data/src/core/lib/support/atomic_with_atm.h +70 -0
  155. data/src/core/lib/support/atomic_with_std.h +48 -0
  156. data/src/core/lib/support/avl.c +14 -14
  157. data/src/core/lib/support/memory.h +74 -0
  158. data/src/core/lib/support/mpscq.c +12 -1
  159. data/src/core/lib/support/mpscq.h +4 -0
  160. data/src/core/lib/support/stack_lockfree.c +3 -36
  161. data/src/core/lib/support/time_posix.c +8 -0
  162. data/src/core/lib/support/tmpfile_posix.c +10 -10
  163. data/src/core/lib/surface/alarm.c +3 -1
  164. data/src/core/lib/surface/api_trace.c +2 -1
  165. data/src/core/lib/surface/api_trace.h +2 -2
  166. data/src/core/lib/surface/byte_buffer_reader.c +1 -1
  167. data/src/core/lib/surface/call.c +65 -22
  168. data/src/core/lib/surface/call.h +4 -2
  169. data/src/core/lib/surface/channel_init.c +2 -19
  170. data/src/core/lib/surface/channel_stack_type.c +18 -0
  171. data/src/core/lib/surface/channel_stack_type.h +2 -0
  172. data/src/core/lib/surface/completion_queue.c +249 -83
  173. data/src/core/lib/surface/completion_queue.h +18 -13
  174. data/src/core/lib/surface/completion_queue_factory.c +24 -9
  175. data/src/core/lib/surface/init.c +1 -52
  176. data/src/core/lib/surface/{lame_client.c → lame_client.cc} +37 -26
  177. data/src/core/lib/surface/server.c +50 -27
  178. data/src/core/lib/surface/server.h +2 -1
  179. data/src/core/lib/surface/version.c +2 -2
  180. data/src/core/lib/transport/bdp_estimator.c +20 -9
  181. data/src/core/lib/transport/bdp_estimator.h +5 -1
  182. data/src/core/lib/transport/byte_stream.c +23 -9
  183. data/src/core/lib/transport/byte_stream.h +15 -6
  184. data/src/core/lib/transport/connectivity_state.c +6 -6
  185. data/src/core/lib/transport/connectivity_state.h +2 -1
  186. data/src/core/lib/transport/service_config.c +6 -13
  187. data/src/core/lib/transport/service_config.h +2 -2
  188. data/src/core/lib/transport/static_metadata.c +403 -389
  189. data/src/core/lib/transport/static_metadata.h +127 -114
  190. data/src/core/plugin_registry/grpc_plugin_registry.c +12 -0
  191. data/src/core/tsi/fake_transport_security.c +5 -4
  192. data/src/core/tsi/ssl_transport_security.c +71 -82
  193. data/src/core/tsi/ssl_transport_security.h +39 -61
  194. data/src/core/tsi/transport_security.c +83 -2
  195. data/src/core/tsi/transport_security.h +27 -2
  196. data/src/core/tsi/transport_security_adapter.c +236 -0
  197. data/src/core/tsi/transport_security_adapter.h +62 -0
  198. data/src/core/tsi/transport_security_interface.h +179 -66
  199. data/src/ruby/ext/grpc/extconf.rb +2 -1
  200. data/src/ruby/ext/grpc/rb_byte_buffer.c +8 -6
  201. data/src/ruby/ext/grpc/rb_call.c +56 -48
  202. data/src/ruby/ext/grpc/rb_call.h +3 -4
  203. data/src/ruby/ext/grpc/rb_call_credentials.c +23 -22
  204. data/src/ruby/ext/grpc/rb_channel.c +45 -29
  205. data/src/ruby/ext/grpc/rb_channel_args.c +11 -9
  206. data/src/ruby/ext/grpc/rb_channel_credentials.c +16 -12
  207. data/src/ruby/ext/grpc/rb_completion_queue.c +7 -9
  208. data/src/ruby/ext/grpc/rb_compression_options.c +7 -6
  209. data/src/ruby/ext/grpc/rb_event_thread.c +10 -12
  210. data/src/ruby/ext/grpc/rb_event_thread.h +1 -2
  211. data/src/ruby/ext/grpc/rb_grpc.c +11 -15
  212. data/src/ruby/ext/grpc/rb_grpc.h +2 -2
  213. data/src/ruby/ext/grpc/rb_grpc_imports.generated.c +14 -6
  214. data/src/ruby/ext/grpc/rb_grpc_imports.generated.h +22 -10
  215. data/src/ruby/ext/grpc/rb_server.c +26 -28
  216. data/src/ruby/lib/grpc/version.rb +1 -1
  217. metadata +40 -18
  218. data/src/ruby/lib/grpc/grpc_c.bundle +0 -0
  219. data/src/ruby/lib/grpc/grpc_c.so +0 -0
@@ -29,7 +29,7 @@
29
29
  // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30
30
  //
31
31
 
32
- #include "src/core/lib/channel/message_size_filter.h"
32
+ #include "src/core/ext/filters/message_size/message_size_filter.h"
33
33
 
34
34
  #include <limits.h>
35
35
  #include <string.h>
@@ -40,7 +40,9 @@
40
40
  #include <grpc/support/string_util.h>
41
41
 
42
42
  #include "src/core/lib/channel/channel_args.h"
43
+ #include "src/core/lib/channel/channel_stack_builder.h"
43
44
  #include "src/core/lib/support/string.h"
45
+ #include "src/core/lib/surface/channel_init.h"
44
46
  #include "src/core/lib/transport/service_config.h"
45
47
 
46
48
  typedef struct message_size_limits {
@@ -48,19 +50,10 @@ typedef struct message_size_limits {
48
50
  int max_recv_size;
49
51
  } message_size_limits;
50
52
 
51
- static void* message_size_limits_copy(void* value) {
52
- void* new_value = gpr_malloc(sizeof(message_size_limits));
53
- memcpy(new_value, value, sizeof(message_size_limits));
54
- return new_value;
55
- }
56
-
57
53
  static void message_size_limits_free(grpc_exec_ctx* exec_ctx, void* value) {
58
54
  gpr_free(value);
59
55
  }
60
56
 
61
- static const grpc_slice_hash_table_vtable message_size_limits_vtable = {
62
- message_size_limits_free, message_size_limits_copy};
63
-
64
57
  static void* message_size_limits_create_from_json(const grpc_json* json) {
65
58
  int max_request_message_bytes = -1;
66
59
  int max_response_message_bytes = -1;
@@ -89,8 +82,7 @@ static void* message_size_limits_create_from_json(const grpc_json* json) {
89
82
  }
90
83
 
91
84
  typedef struct call_data {
92
- int max_send_size;
93
- int max_recv_size;
85
+ message_size_limits limits;
94
86
  // Receive closures are chained: we inject this closure as the
95
87
  // recv_message_ready up-call on transport_stream_op, and remember to
96
88
  // call our next_recv_message_ready member after handling it.
@@ -102,8 +94,7 @@ typedef struct call_data {
102
94
  } call_data;
103
95
 
104
96
  typedef struct channel_data {
105
- int max_send_size;
106
- int max_recv_size;
97
+ message_size_limits limits;
107
98
  // Maps path names to message_size_limits structs.
108
99
  grpc_slice_hash_table* method_limit_table;
109
100
  } channel_data;
@@ -114,12 +105,12 @@ static void recv_message_ready(grpc_exec_ctx* exec_ctx, void* user_data,
114
105
  grpc_error* error) {
115
106
  grpc_call_element* elem = user_data;
116
107
  call_data* calld = elem->call_data;
117
- if (*calld->recv_message != NULL && calld->max_recv_size >= 0 &&
118
- (*calld->recv_message)->length > (size_t)calld->max_recv_size) {
108
+ if (*calld->recv_message != NULL && calld->limits.max_recv_size >= 0 &&
109
+ (*calld->recv_message)->length > (size_t)calld->limits.max_recv_size) {
119
110
  char* message_string;
120
111
  gpr_asprintf(&message_string,
121
112
  "Received message larger than max (%u vs. %d)",
122
- (*calld->recv_message)->length, calld->max_recv_size);
113
+ (*calld->recv_message)->length, calld->limits.max_recv_size);
123
114
  grpc_error* new_error = grpc_error_set_int(
124
115
  GRPC_ERROR_CREATE_FROM_COPIED_STRING(message_string),
125
116
  GRPC_ERROR_INT_GRPC_STATUS, GRPC_STATUS_RESOURCE_EXHAUSTED);
@@ -130,6 +121,8 @@ static void recv_message_ready(grpc_exec_ctx* exec_ctx, void* user_data,
130
121
  GRPC_ERROR_UNREF(new_error);
131
122
  }
132
123
  gpr_free(message_string);
124
+ } else {
125
+ GRPC_ERROR_REF(error);
133
126
  }
134
127
  // Invoke the next callback.
135
128
  grpc_closure_run(exec_ctx, calld->next_recv_message_ready, error);
@@ -141,13 +134,13 @@ static void start_transport_stream_op_batch(
141
134
  grpc_transport_stream_op_batch* op) {
142
135
  call_data* calld = elem->call_data;
143
136
  // Check max send message size.
144
- if (op->send_message && calld->max_send_size >= 0 &&
137
+ if (op->send_message && calld->limits.max_send_size >= 0 &&
145
138
  op->payload->send_message.send_message->length >
146
- (size_t)calld->max_send_size) {
139
+ (size_t)calld->limits.max_send_size) {
147
140
  char* message_string;
148
141
  gpr_asprintf(&message_string, "Sent message larger than max (%u vs. %d)",
149
142
  op->payload->send_message.send_message->length,
150
- calld->max_send_size);
143
+ calld->limits.max_send_size);
151
144
  grpc_transport_stream_op_batch_finish_with_failure(
152
145
  exec_ctx, op,
153
146
  grpc_error_set_int(GRPC_ERROR_CREATE_FROM_COPIED_STRING(message_string),
@@ -180,21 +173,20 @@ static grpc_error* init_call_elem(grpc_exec_ctx* exec_ctx,
180
173
  // Note: Per-method config is only available on the client, so we
181
174
  // apply the max request size to the send limit and the max response
182
175
  // size to the receive limit.
183
- calld->max_send_size = chand->max_send_size;
184
- calld->max_recv_size = chand->max_recv_size;
176
+ calld->limits = chand->limits;
185
177
  if (chand->method_limit_table != NULL) {
186
178
  message_size_limits* limits = grpc_method_config_table_get(
187
179
  exec_ctx, chand->method_limit_table, args->path);
188
180
  if (limits != NULL) {
189
181
  if (limits->max_send_size >= 0 &&
190
- (limits->max_send_size < calld->max_send_size ||
191
- calld->max_send_size < 0)) {
192
- calld->max_send_size = limits->max_send_size;
182
+ (limits->max_send_size < calld->limits.max_send_size ||
183
+ calld->limits.max_send_size < 0)) {
184
+ calld->limits.max_send_size = limits->max_send_size;
193
185
  }
194
186
  if (limits->max_recv_size >= 0 &&
195
- (limits->max_recv_size < calld->max_recv_size ||
196
- calld->max_recv_size < 0)) {
197
- calld->max_recv_size = limits->max_recv_size;
187
+ (limits->max_recv_size < calld->limits.max_recv_size ||
188
+ calld->limits.max_recv_size < 0)) {
189
+ calld->limits.max_recv_size = limits->max_recv_size;
198
190
  }
199
191
  }
200
192
  }
@@ -206,30 +198,45 @@ static void destroy_call_elem(grpc_exec_ctx* exec_ctx, grpc_call_element* elem,
206
198
  const grpc_call_final_info* final_info,
207
199
  grpc_closure* ignored) {}
208
200
 
201
+ static int default_size(const grpc_channel_args* args,
202
+ int without_minimal_stack) {
203
+ if (grpc_channel_args_want_minimal_stack(args)) {
204
+ return -1;
205
+ }
206
+ return without_minimal_stack;
207
+ }
208
+
209
+ message_size_limits get_message_size_limits(
210
+ const grpc_channel_args* channel_args) {
211
+ message_size_limits lim;
212
+ lim.max_send_size =
213
+ default_size(channel_args, GRPC_DEFAULT_MAX_SEND_MESSAGE_LENGTH);
214
+ lim.max_recv_size =
215
+ default_size(channel_args, GRPC_DEFAULT_MAX_RECV_MESSAGE_LENGTH);
216
+ for (size_t i = 0; i < channel_args->num_args; ++i) {
217
+ if (strcmp(channel_args->args[i].key, GRPC_ARG_MAX_SEND_MESSAGE_LENGTH) ==
218
+ 0) {
219
+ const grpc_integer_options options = {lim.max_send_size, -1, INT_MAX};
220
+ lim.max_send_size =
221
+ grpc_channel_arg_get_integer(&channel_args->args[i], options);
222
+ }
223
+ if (strcmp(channel_args->args[i].key,
224
+ GRPC_ARG_MAX_RECEIVE_MESSAGE_LENGTH) == 0) {
225
+ const grpc_integer_options options = {lim.max_recv_size, -1, INT_MAX};
226
+ lim.max_recv_size =
227
+ grpc_channel_arg_get_integer(&channel_args->args[i], options);
228
+ }
229
+ }
230
+ return lim;
231
+ }
232
+
209
233
  // Constructor for channel_data.
210
234
  static grpc_error* init_channel_elem(grpc_exec_ctx* exec_ctx,
211
235
  grpc_channel_element* elem,
212
236
  grpc_channel_element_args* args) {
213
237
  GPR_ASSERT(!args->is_last);
214
238
  channel_data* chand = elem->channel_data;
215
- chand->max_send_size = GRPC_DEFAULT_MAX_SEND_MESSAGE_LENGTH;
216
- chand->max_recv_size = GRPC_DEFAULT_MAX_RECV_MESSAGE_LENGTH;
217
- for (size_t i = 0; i < args->channel_args->num_args; ++i) {
218
- if (strcmp(args->channel_args->args[i].key,
219
- GRPC_ARG_MAX_SEND_MESSAGE_LENGTH) == 0) {
220
- const grpc_integer_options options = {
221
- GRPC_DEFAULT_MAX_SEND_MESSAGE_LENGTH, -1, INT_MAX};
222
- chand->max_send_size =
223
- grpc_channel_arg_get_integer(&args->channel_args->args[i], options);
224
- }
225
- if (strcmp(args->channel_args->args[i].key,
226
- GRPC_ARG_MAX_RECEIVE_MESSAGE_LENGTH) == 0) {
227
- const grpc_integer_options options = {
228
- GRPC_DEFAULT_MAX_RECV_MESSAGE_LENGTH, -1, INT_MAX};
229
- chand->max_recv_size =
230
- grpc_channel_arg_get_integer(&args->channel_args->args[i], options);
231
- }
232
- }
239
+ chand->limits = get_message_size_limits(args->channel_args);
233
240
  // Get method config table from channel args.
234
241
  const grpc_arg* channel_arg =
235
242
  grpc_channel_args_find(args->channel_args, GRPC_ARG_SERVICE_CONFIG);
@@ -241,7 +248,7 @@ static grpc_error* init_channel_elem(grpc_exec_ctx* exec_ctx,
241
248
  chand->method_limit_table =
242
249
  grpc_service_config_create_method_config_table(
243
250
  exec_ctx, service_config, message_size_limits_create_from_json,
244
- &message_size_limits_vtable);
251
+ message_size_limits_free);
245
252
  grpc_service_config_destroy(service_config);
246
253
  }
247
254
  }
@@ -268,3 +275,40 @@ const grpc_channel_filter grpc_message_size_filter = {
268
275
  grpc_call_next_get_peer,
269
276
  grpc_channel_next_get_info,
270
277
  "message_size"};
278
+
279
+ static bool maybe_add_message_size_filter(grpc_exec_ctx* exec_ctx,
280
+ grpc_channel_stack_builder* builder,
281
+ void* arg) {
282
+ const grpc_channel_args* channel_args =
283
+ grpc_channel_stack_builder_get_channel_arguments(builder);
284
+ bool enable = false;
285
+ message_size_limits lim = get_message_size_limits(channel_args);
286
+ if (lim.max_send_size != -1 || lim.max_recv_size != -1) {
287
+ enable = true;
288
+ }
289
+ const grpc_arg* a =
290
+ grpc_channel_args_find(channel_args, GRPC_ARG_SERVICE_CONFIG);
291
+ if (a != NULL) {
292
+ enable = true;
293
+ }
294
+ if (enable) {
295
+ return grpc_channel_stack_builder_prepend_filter(
296
+ builder, &grpc_message_size_filter, NULL, NULL);
297
+ } else {
298
+ return true;
299
+ }
300
+ }
301
+
302
+ void grpc_message_size_filter_init(void) {
303
+ grpc_channel_init_register_stage(GRPC_CLIENT_SUBCHANNEL,
304
+ GRPC_CHANNEL_INIT_BUILTIN_PRIORITY,
305
+ maybe_add_message_size_filter, NULL);
306
+ grpc_channel_init_register_stage(GRPC_CLIENT_DIRECT_CHANNEL,
307
+ GRPC_CHANNEL_INIT_BUILTIN_PRIORITY,
308
+ maybe_add_message_size_filter, NULL);
309
+ grpc_channel_init_register_stage(GRPC_SERVER_CHANNEL,
310
+ GRPC_CHANNEL_INIT_BUILTIN_PRIORITY,
311
+ maybe_add_message_size_filter, NULL);
312
+ }
313
+
314
+ void grpc_message_size_filter_shutdown(void) {}
@@ -29,11 +29,11 @@
29
29
  // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30
30
  //
31
31
 
32
- #ifndef GRPC_CORE_LIB_CHANNEL_MESSAGE_SIZE_FILTER_H
33
- #define GRPC_CORE_LIB_CHANNEL_MESSAGE_SIZE_FILTER_H
32
+ #ifndef GRPC_CORE_EXT_FILTERS_MESSAGE_SIZE_MESSAGE_SIZE_FILTER_H
33
+ #define GRPC_CORE_EXT_FILTERS_MESSAGE_SIZE_MESSAGE_SIZE_FILTER_H
34
34
 
35
35
  #include "src/core/lib/channel/channel_stack.h"
36
36
 
37
37
  extern const grpc_channel_filter grpc_message_size_filter;
38
38
 
39
- #endif /* GRPC_CORE_LIB_CHANNEL_MESSAGE_SIZE_FILTER_H */
39
+ #endif /* GRPC_CORE_EXT_FILTERS_MESSAGE_SIZE_MESSAGE_SIZE_FILTER_H */
@@ -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
@@ -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,29 @@ 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;
2142
+ int32_t bdp;
2143
+ const int32_t kMinBDP = 128;
2144
+ if (bdp_dbl <= kMinBDP) {
2145
+ bdp = kMinBDP;
2146
+ } else if (bdp_dbl > INT32_MAX) {
2147
+ bdp = INT32_MAX;
2083
2148
  } else {
2084
- bdp = (uint32_t)(bdp_dbl);
2149
+ bdp = (int32_t)(bdp_dbl);
2085
2150
  }
2086
2151
  int64_t delta =
2087
2152
  (int64_t)bdp -
2088
2153
  (int64_t)t->settings[GRPC_LOCAL_SETTINGS]
2089
2154
  [GRPC_CHTTP2_SETTINGS_INITIAL_WINDOW_SIZE];
2090
- if (delta == 0 || (bdp != 0 && delta > -1024 && delta < 1024)) {
2155
+ if (delta == 0 || (delta > -bdp / 10 && delta < bdp / 10)) {
2091
2156
  return;
2092
2157
  }
2093
- if (grpc_bdp_estimator_trace) {
2158
+ if (GRPC_TRACER_ON(grpc_bdp_estimator_trace)) {
2094
2159
  gpr_log(GPR_DEBUG, "%s: update initial window size to %d", t->peer_string,
2095
2160
  (int)bdp);
2096
2161
  }
2097
- push_setting(exec_ctx, t, GRPC_CHTTP2_SETTINGS_INITIAL_WINDOW_SIZE, bdp);
2162
+ push_setting(exec_ctx, t, GRPC_CHTTP2_SETTINGS_INITIAL_WINDOW_SIZE,
2163
+ (uint32_t)bdp);
2164
+ push_setting(exec_ctx, t, GRPC_CHTTP2_SETTINGS_MAX_FRAME_SIZE, (uint32_t)bdp);
2098
2165
  }
2099
2166
 
2100
2167
  static grpc_error *try_http_parsing(grpc_exec_ctx *exec_ctx,
@@ -2249,7 +2316,7 @@ static void read_action_locked(grpc_exec_ctx *exec_ctx, void *tp,
2249
2316
  static void start_bdp_ping_locked(grpc_exec_ctx *exec_ctx, void *tp,
2250
2317
  grpc_error *error) {
2251
2318
  grpc_chttp2_transport *t = tp;
2252
- if (grpc_http_trace) {
2319
+ if (GRPC_TRACER_ON(grpc_http_trace)) {
2253
2320
  gpr_log(GPR_DEBUG, "%s: Start BDP ping", t->peer_string);
2254
2321
  }
2255
2322
  /* Reset the keepalive ping timer */
@@ -2262,7 +2329,7 @@ static void start_bdp_ping_locked(grpc_exec_ctx *exec_ctx, void *tp,
2262
2329
  static void finish_bdp_ping_locked(grpc_exec_ctx *exec_ctx, void *tp,
2263
2330
  grpc_error *error) {
2264
2331
  grpc_chttp2_transport *t = tp;
2265
- if (grpc_http_trace) {
2332
+ if (GRPC_TRACER_ON(grpc_http_trace)) {
2266
2333
  gpr_log(GPR_DEBUG, "%s: Complete BDP ping", t->peer_string);
2267
2334
  }
2268
2335
  grpc_bdp_estimator_complete_ping(&t->bdp_estimator);
@@ -2312,7 +2379,9 @@ static void init_keepalive_ping_locked(grpc_exec_ctx *exec_ctx, void *arg,
2312
2379
  grpc_error *error) {
2313
2380
  grpc_chttp2_transport *t = arg;
2314
2381
  GPR_ASSERT(t->keepalive_state == GRPC_CHTTP2_KEEPALIVE_STATE_WAITING);
2315
- if (error == GRPC_ERROR_NONE && !(t->destroying || t->closed)) {
2382
+ if (t->destroying || t->closed) {
2383
+ t->keepalive_state = GRPC_CHTTP2_KEEPALIVE_STATE_DYING;
2384
+ } else if (error == GRPC_ERROR_NONE) {
2316
2385
  if (t->keepalive_permit_without_calls ||
2317
2386
  grpc_chttp2_stream_map_size(&t->stream_map) > 0) {
2318
2387
  t->keepalive_state = GRPC_CHTTP2_KEEPALIVE_STATE_PINGING;
@@ -2327,7 +2396,7 @@ static void init_keepalive_ping_locked(grpc_exec_ctx *exec_ctx, void *arg,
2327
2396
  gpr_time_add(gpr_now(GPR_CLOCK_MONOTONIC), t->keepalive_time),
2328
2397
  &t->init_keepalive_ping_locked, gpr_now(GPR_CLOCK_MONOTONIC));
2329
2398
  }
2330
- } else if (error == GRPC_ERROR_CANCELLED && !(t->destroying || t->closed)) {
2399
+ } else if (error == GRPC_ERROR_CANCELLED) {
2331
2400
  /* The keepalive ping timer may be cancelled by bdp */
2332
2401
  GRPC_CHTTP2_REF_TRANSPORT(t, "init keepalive ping");
2333
2402
  grpc_timer_init(
@@ -2419,12 +2488,28 @@ static void set_pollset_set(grpc_exec_ctx *exec_ctx, grpc_transport *gt,
2419
2488
  * BYTE STREAM
2420
2489
  */
2421
2490
 
2491
+ static void reset_byte_stream(grpc_exec_ctx *exec_ctx, void *arg,
2492
+ grpc_error *error) {
2493
+ grpc_chttp2_stream *s = (grpc_chttp2_stream *)arg;
2494
+
2495
+ s->pending_byte_stream = false;
2496
+ if (error == GRPC_ERROR_NONE) {
2497
+ grpc_chttp2_maybe_complete_recv_message(exec_ctx, s->t, s);
2498
+ grpc_chttp2_maybe_complete_recv_trailing_metadata(exec_ctx, s->t, s);
2499
+ } else {
2500
+ GPR_ASSERT(error != GRPC_ERROR_NONE);
2501
+ grpc_closure_sched(exec_ctx, s->on_next, GRPC_ERROR_REF(error));
2502
+ s->on_next = NULL;
2503
+ GRPC_ERROR_UNREF(s->byte_stream_error);
2504
+ s->byte_stream_error = GRPC_ERROR_NONE;
2505
+ grpc_chttp2_cancel_stream(exec_ctx, s->t, s, GRPC_ERROR_REF(error));
2506
+ s->byte_stream_error = error;
2507
+ }
2508
+ }
2509
+
2422
2510
  static void incoming_byte_stream_unref(grpc_exec_ctx *exec_ctx,
2423
2511
  grpc_chttp2_incoming_byte_stream *bs) {
2424
2512
  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
2513
  gpr_free(bs);
2429
2514
  }
2430
2515
  }
@@ -2484,47 +2569,91 @@ static void incoming_byte_stream_next_locked(grpc_exec_ctx *exec_ctx,
2484
2569
  grpc_chttp2_transport *t = bs->transport;
2485
2570
  grpc_chttp2_stream *s = bs->stream;
2486
2571
 
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));
2572
+ size_t cur_length = s->frame_storage.length;
2573
+ incoming_byte_stream_update_flow_control(
2574
+ exec_ctx, t, s, bs->next_action.max_size_hint, cur_length);
2575
+
2576
+ GPR_ASSERT(s->unprocessed_incoming_frames_buffer.length == 0);
2577
+ if (s->frame_storage.length > 0) {
2578
+ grpc_slice_buffer_swap(&s->frame_storage,
2579
+ &s->unprocessed_incoming_frames_buffer);
2580
+ grpc_closure_sched(exec_ctx, bs->next_action.on_complete, GRPC_ERROR_NONE);
2581
+ } else if (s->byte_stream_error != GRPC_ERROR_NONE) {
2582
+ grpc_closure_sched(exec_ctx, bs->next_action.on_complete,
2583
+ GRPC_ERROR_REF(s->byte_stream_error));
2584
+ if (s->data_parser.parsing_frame != NULL) {
2585
+ incoming_byte_stream_unref(exec_ctx, s->data_parser.parsing_frame);
2586
+ s->data_parser.parsing_frame = NULL;
2587
+ }
2588
+ } else if (s->read_closed) {
2589
+ if (bs->remaining_bytes != 0) {
2590
+ s->byte_stream_error =
2591
+ GRPC_ERROR_CREATE_FROM_STATIC_STRING("Truncated message");
2592
+ grpc_closure_sched(exec_ctx, bs->next_action.on_complete,
2593
+ GRPC_ERROR_REF(s->byte_stream_error));
2594
+ if (s->data_parser.parsing_frame != NULL) {
2595
+ incoming_byte_stream_unref(exec_ctx, s->data_parser.parsing_frame);
2596
+ s->data_parser.parsing_frame = NULL;
2597
+ }
2598
+ } else {
2599
+ /* Should never reach here. */
2600
+ GPR_ASSERT(false);
2601
+ }
2501
2602
  } else {
2502
- bs->on_next = bs->next_action.on_complete;
2503
- bs->next = bs->next_action.slice;
2603
+ s->on_next = bs->next_action.on_complete;
2504
2604
  }
2505
- gpr_mu_unlock(&bs->slice_mu);
2506
2605
  incoming_byte_stream_unref(exec_ctx, bs);
2507
2606
  }
2508
2607
 
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) {
2608
+ static bool incoming_byte_stream_next(grpc_exec_ctx *exec_ctx,
2609
+ grpc_byte_stream *byte_stream,
2610
+ size_t max_size_hint,
2611
+ grpc_closure *on_complete) {
2513
2612
  GPR_TIMER_BEGIN("incoming_byte_stream_next", 0);
2514
2613
  grpc_chttp2_incoming_byte_stream *bs =
2515
2614
  (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;
2615
+ grpc_chttp2_stream *s = bs->stream;
2616
+ if (s->unprocessed_incoming_frames_buffer.length > 0) {
2617
+ GPR_TIMER_END("incoming_byte_stream_next", 0);
2618
+ return true;
2619
+ } else {
2620
+ gpr_ref(&bs->refs);
2621
+ bs->next_action.max_size_hint = max_size_hint;
2622
+ bs->next_action.on_complete = on_complete;
2623
+ grpc_closure_sched(
2624
+ exec_ctx,
2625
+ grpc_closure_init(
2626
+ &bs->next_action.closure, incoming_byte_stream_next_locked, bs,
2627
+ grpc_combiner_scheduler(bs->transport->combiner, false)),
2628
+ GRPC_ERROR_NONE);
2629
+ GPR_TIMER_END("incoming_byte_stream_next", 0);
2630
+ return false;
2631
+ }
2632
+ }
2633
+
2634
+ static grpc_error *incoming_byte_stream_pull(grpc_exec_ctx *exec_ctx,
2635
+ grpc_byte_stream *byte_stream,
2636
+ grpc_slice *slice) {
2637
+ GPR_TIMER_BEGIN("incoming_byte_stream_pull", 0);
2638
+ grpc_chttp2_incoming_byte_stream *bs =
2639
+ (grpc_chttp2_incoming_byte_stream *)byte_stream;
2640
+ grpc_chttp2_stream *s = bs->stream;
2641
+
2642
+ if (s->unprocessed_incoming_frames_buffer.length > 0) {
2643
+ grpc_error *error = grpc_deframe_unprocessed_incoming_frames(
2644
+ exec_ctx, &s->data_parser, s, &s->unprocessed_incoming_frames_buffer,
2645
+ slice, NULL);
2646
+ if (error != GRPC_ERROR_NONE) {
2647
+ return error;
2648
+ }
2649
+ } else {
2650
+ grpc_error *error =
2651
+ GRPC_ERROR_CREATE_FROM_STATIC_STRING("Truncated message");
2652
+ grpc_closure_sched(exec_ctx, &s->reset_byte_stream, GRPC_ERROR_REF(error));
2653
+ return error;
2654
+ }
2655
+ GPR_TIMER_END("incoming_byte_stream_pull", 0);
2656
+ return GRPC_ERROR_NONE;
2528
2657
  }
2529
2658
 
2530
2659
  static void incoming_byte_stream_destroy(grpc_exec_ctx *exec_ctx,
@@ -2534,9 +2663,14 @@ static void incoming_byte_stream_destroy_locked(grpc_exec_ctx *exec_ctx,
2534
2663
  void *byte_stream,
2535
2664
  grpc_error *error_ignored) {
2536
2665
  grpc_chttp2_incoming_byte_stream *bs = byte_stream;
2666
+ grpc_chttp2_stream *s = bs->stream;
2667
+ grpc_chttp2_transport *t = s->t;
2668
+
2537
2669
  GPR_ASSERT(bs->base.destroy == incoming_byte_stream_destroy);
2538
- decrement_active_streams_locked(exec_ctx, bs->transport, bs->stream);
2539
2670
  incoming_byte_stream_unref(exec_ctx, bs);
2671
+ s->pending_byte_stream = false;
2672
+ grpc_chttp2_maybe_complete_recv_message(exec_ctx, t, s);
2673
+ grpc_chttp2_maybe_complete_recv_trailing_metadata(exec_ctx, t, s);
2540
2674
  }
2541
2675
 
2542
2676
  static void incoming_byte_stream_destroy(grpc_exec_ctx *exec_ctx,
@@ -2556,50 +2690,53 @@ static void incoming_byte_stream_destroy(grpc_exec_ctx *exec_ctx,
2556
2690
  static void incoming_byte_stream_publish_error(
2557
2691
  grpc_exec_ctx *exec_ctx, grpc_chttp2_incoming_byte_stream *bs,
2558
2692
  grpc_error *error) {
2693
+ grpc_chttp2_stream *s = bs->stream;
2694
+
2559
2695
  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);
2696
+ grpc_closure_sched(exec_ctx, s->on_next, GRPC_ERROR_REF(error));
2697
+ s->on_next = NULL;
2698
+ GRPC_ERROR_UNREF(s->byte_stream_error);
2699
+ s->byte_stream_error = GRPC_ERROR_REF(error);
2563
2700
  grpc_chttp2_cancel_stream(exec_ctx, bs->transport, bs->stream,
2564
2701
  GRPC_ERROR_REF(error));
2565
- bs->error = error;
2566
2702
  }
2567
2703
 
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);
2704
+ grpc_error *grpc_chttp2_incoming_byte_stream_push(
2705
+ grpc_exec_ctx *exec_ctx, grpc_chttp2_incoming_byte_stream *bs,
2706
+ grpc_slice slice, grpc_slice *slice_out) {
2707
+ grpc_chttp2_stream *s = bs->stream;
2708
+
2572
2709
  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"));
2710
+ grpc_error *error =
2711
+ GRPC_ERROR_CREATE_FROM_STATIC_STRING("Too many bytes in stream");
2712
+
2713
+ grpc_closure_sched(exec_ctx, &s->reset_byte_stream, GRPC_ERROR_REF(error));
2714
+ grpc_slice_unref_internal(exec_ctx, slice);
2715
+ return error;
2576
2716
  } else {
2577
2717
  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);
2718
+ if (slice_out != NULL) {
2719
+ *slice_out = slice;
2584
2720
  }
2721
+ return GRPC_ERROR_NONE;
2585
2722
  }
2586
- gpr_mu_unlock(&bs->slice_mu);
2587
2723
  }
2588
2724
 
2589
- void grpc_chttp2_incoming_byte_stream_finished(
2725
+ grpc_error *grpc_chttp2_incoming_byte_stream_finished(
2590
2726
  grpc_exec_ctx *exec_ctx, grpc_chttp2_incoming_byte_stream *bs,
2591
- grpc_error *error) {
2727
+ grpc_error *error, bool reset_on_error) {
2728
+ grpc_chttp2_stream *s = bs->stream;
2729
+
2592
2730
  if (error == GRPC_ERROR_NONE) {
2593
- gpr_mu_lock(&bs->slice_mu);
2594
2731
  if (bs->remaining_bytes != 0) {
2595
2732
  error = GRPC_ERROR_CREATE_FROM_STATIC_STRING("Truncated message");
2596
2733
  }
2597
- gpr_mu_unlock(&bs->slice_mu);
2598
2734
  }
2599
- if (error != GRPC_ERROR_NONE) {
2600
- incoming_byte_stream_publish_error(exec_ctx, bs, error);
2735
+ if (error != GRPC_ERROR_NONE && reset_on_error) {
2736
+ grpc_closure_sched(exec_ctx, &s->reset_byte_stream, GRPC_ERROR_REF(error));
2601
2737
  }
2602
2738
  incoming_byte_stream_unref(exec_ctx, bs);
2739
+ return error;
2603
2740
  }
2604
2741
 
2605
2742
  grpc_chttp2_incoming_byte_stream *grpc_chttp2_incoming_byte_stream_create(
@@ -2611,26 +2748,12 @@ grpc_chttp2_incoming_byte_stream *grpc_chttp2_incoming_byte_stream_create(
2611
2748
  incoming_byte_stream->remaining_bytes = frame_size;
2612
2749
  incoming_byte_stream->base.flags = flags;
2613
2750
  incoming_byte_stream->base.next = incoming_byte_stream_next;
2751
+ incoming_byte_stream->base.pull = incoming_byte_stream_pull;
2614
2752
  incoming_byte_stream->base.destroy = incoming_byte_stream_destroy;
2615
- gpr_mu_init(&incoming_byte_stream->slice_mu);
2616
2753
  gpr_ref_init(&incoming_byte_stream->refs, 2);
2617
- incoming_byte_stream->next_message = NULL;
2618
2754
  incoming_byte_stream->transport = t;
2619
2755
  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);
2756
+ s->byte_stream_error = GRPC_ERROR_NONE;
2634
2757
  return incoming_byte_stream;
2635
2758
  }
2636
2759
 
@@ -2667,7 +2790,7 @@ static void benign_reclaimer_locked(grpc_exec_ctx *exec_ctx, void *arg,
2667
2790
  grpc_chttp2_stream_map_size(&t->stream_map) == 0) {
2668
2791
  /* Channel with no active streams: send a goaway to try and make it
2669
2792
  * disconnect cleanly */
2670
- if (grpc_resource_quota_trace) {
2793
+ if (GRPC_TRACER_ON(grpc_resource_quota_trace)) {
2671
2794
  gpr_log(GPR_DEBUG, "HTTP2: %s - send goaway to free memory",
2672
2795
  t->peer_string);
2673
2796
  }
@@ -2675,7 +2798,8 @@ static void benign_reclaimer_locked(grpc_exec_ctx *exec_ctx, void *arg,
2675
2798
  grpc_error_set_int(
2676
2799
  GRPC_ERROR_CREATE_FROM_STATIC_STRING("Buffers full"),
2677
2800
  GRPC_ERROR_INT_HTTP2_ERROR, GRPC_HTTP2_ENHANCE_YOUR_CALM));
2678
- } else if (error == GRPC_ERROR_NONE && grpc_resource_quota_trace) {
2801
+ } else if (error == GRPC_ERROR_NONE &&
2802
+ GRPC_TRACER_ON(grpc_resource_quota_trace)) {
2679
2803
  gpr_log(GPR_DEBUG,
2680
2804
  "HTTP2: %s - skip benign reclamation, there are still %" PRIdPTR
2681
2805
  " streams",
@@ -2696,7 +2820,7 @@ static void destructive_reclaimer_locked(grpc_exec_ctx *exec_ctx, void *arg,
2696
2820
  t->destructive_reclaimer_registered = false;
2697
2821
  if (error == GRPC_ERROR_NONE && n > 0) {
2698
2822
  grpc_chttp2_stream *s = grpc_chttp2_stream_map_rand(&t->stream_map);
2699
- if (grpc_resource_quota_trace) {
2823
+ if (GRPC_TRACER_ON(grpc_resource_quota_trace)) {
2700
2824
  gpr_log(GPR_DEBUG, "HTTP2: %s - abandon stream id %d", t->peer_string,
2701
2825
  s->id);
2702
2826
  }