Fix flow control of cancelled streams

reviewable/pr8239/r2
Craig Tiller 8 years ago
parent ef6b97659e
commit c1acca2c01
  1. 22
      src/core/ext/transport/chttp2/transport/parsing.c

@ -375,22 +375,26 @@ static grpc_error *update_incoming_window(grpc_exec_ctx *exec_ctx,
return err; return err;
} }
GRPC_CHTTP2_FLOW_DEBIT_TRANSPORT("parse", t, incoming_window,
incoming_frame_size);
if (s != NULL) {
if (incoming_frame_size > s->incoming_window) { if (incoming_frame_size > s->incoming_window) {
char *msg; char *msg;
gpr_asprintf(&msg, "frame of size %d overflows incoming window of %" PRId64, gpr_asprintf(&msg,
"frame of size %d overflows incoming window of %" PRId64,
t->incoming_frame_size, s->incoming_window); t->incoming_frame_size, s->incoming_window);
grpc_error *err = GRPC_ERROR_CREATE(msg); grpc_error *err = GRPC_ERROR_CREATE(msg);
gpr_free(msg); gpr_free(msg);
return err; return err;
} }
GRPC_CHTTP2_FLOW_DEBIT_TRANSPORT("parse", t, incoming_window,
incoming_frame_size);
GRPC_CHTTP2_FLOW_DEBIT_STREAM("parse", t, s, incoming_window, GRPC_CHTTP2_FLOW_DEBIT_STREAM("parse", t, s, incoming_window,
incoming_frame_size); incoming_frame_size);
s->received_bytes += incoming_frame_size; s->received_bytes += incoming_frame_size;
s->max_recv_bytes -= s->max_recv_bytes -=
(uint32_t)GPR_MIN(s->max_recv_bytes, incoming_frame_size); (uint32_t)GPR_MIN(s->max_recv_bytes, incoming_frame_size);
}
return GRPC_ERROR_NONE; return GRPC_ERROR_NONE;
} }
@ -400,20 +404,22 @@ static grpc_error *init_data_frame_parser(grpc_exec_ctx *exec_ctx,
grpc_chttp2_stream *s = grpc_chttp2_stream *s =
grpc_chttp2_parsing_lookup_stream(t, t->incoming_stream_id); grpc_chttp2_parsing_lookup_stream(t, t->incoming_stream_id);
grpc_error *err = GRPC_ERROR_NONE; grpc_error *err = GRPC_ERROR_NONE;
err = update_incoming_window(exec_ctx, t, s);
if (err != GRPC_ERROR_NONE) {
goto error_handler;
}
if (s == NULL) { if (s == NULL) {
return init_skip_frame_parser(exec_ctx, t, 0); return init_skip_frame_parser(exec_ctx, t, 0);
} }
s->stats.incoming.framing_bytes += 9; s->stats.incoming.framing_bytes += 9;
if (s->read_closed) { if (err == GRPC_ERROR_NONE && s->read_closed) {
return init_skip_frame_parser(exec_ctx, t, 0); return init_skip_frame_parser(exec_ctx, t, 0);
} }
if (err == GRPC_ERROR_NONE) {
err = update_incoming_window(exec_ctx, t, s);
}
if (err == GRPC_ERROR_NONE) { if (err == GRPC_ERROR_NONE) {
err = grpc_chttp2_data_parser_begin_frame(&s->data_parser, err = grpc_chttp2_data_parser_begin_frame(&s->data_parser,
t->incoming_frame_flags, s->id); t->incoming_frame_flags, s->id);
} }
error_handler:
if (err == GRPC_ERROR_NONE) { if (err == GRPC_ERROR_NONE) {
t->incoming_stream = s; t->incoming_stream = s;
t->parser = grpc_chttp2_data_parser_parse; t->parser = grpc_chttp2_data_parser_parse;
@ -421,7 +427,9 @@ static grpc_error *init_data_frame_parser(grpc_exec_ctx *exec_ctx,
return GRPC_ERROR_NONE; return GRPC_ERROR_NONE;
} else if (grpc_error_get_int(err, GRPC_ERROR_INT_STREAM_ID, NULL)) { } else if (grpc_error_get_int(err, GRPC_ERROR_INT_STREAM_ID, NULL)) {
/* handle stream errors by closing the stream */ /* handle stream errors by closing the stream */
if (s != NULL) {
grpc_chttp2_mark_stream_closed(exec_ctx, t, s, true, false, err); grpc_chttp2_mark_stream_closed(exec_ctx, t, s, true, false, err);
}
gpr_slice_buffer_add( gpr_slice_buffer_add(
&t->qbuf, grpc_chttp2_rst_stream_create(t->incoming_stream_id, &t->qbuf, grpc_chttp2_rst_stream_create(t->incoming_stream_id,
GRPC_CHTTP2_PROTOCOL_ERROR, GRPC_CHTTP2_PROTOCOL_ERROR,

Loading…
Cancel
Save