From ebe8eb2db9a1620496353f8ffb91e04488226790 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Fri, 10 Feb 2017 11:04:23 -0800 Subject: Deframe lazily --- .../transport/chttp2/transport/chttp2_transport.c | 224 ++++++++++++++++++--- .../ext/transport/chttp2/transport/frame_data.c | 44 ++-- src/core/ext/transport/chttp2/transport/internal.h | 5 +- src/core/ext/transport/chttp2/transport/parsing.c | 1 + 4 files changed, 225 insertions(+), 49 deletions(-) (limited to 'src/core/ext/transport') diff --git a/src/core/ext/transport/chttp2/transport/chttp2_transport.c b/src/core/ext/transport/chttp2/transport/chttp2_transport.c index da4c7dc7b2..5c5c29389f 100644 --- a/src/core/ext/transport/chttp2/transport/chttp2_transport.c +++ b/src/core/ext/transport/chttp2/transport/chttp2_transport.c @@ -156,6 +156,10 @@ static void finish_keepalive_ping_locked(grpc_exec_ctx *exec_ctx, void *arg, static void keepalive_watchdog_fired_locked(grpc_exec_ctx *exec_ctx, void *arg, grpc_error *error); +static grpc_error *deframe_unprocessed_incoming_frames( + grpc_exec_ctx *exec_ctx, grpc_chttp2_data_parser *p, + grpc_chttp2_transport *t, grpc_chttp2_stream *s, grpc_slice_buffer *slices); + /******************************************************************************* * CONSTRUCTION/DESTRUCTION/REFCOUNTING */ @@ -595,6 +599,8 @@ static int init_stream(grpc_exec_ctx *exec_ctx, grpc_transport *gt, s->deadline = gpr_inf_future(GPR_CLOCK_MONOTONIC); grpc_closure_init(&s->complete_fetch_locked, complete_fetch_locked, s, grpc_schedule_on_exec_ctx); + s->incoming_frames = NULL; + grpc_slice_buffer_init(&s->unprocessed_incoming_frames_buffer); GRPC_CHTTP2_REF_TRANSPORT(t, "stream"); @@ -612,7 +618,6 @@ static int init_stream(grpc_exec_ctx *exec_ctx, grpc_transport *gt, static void destroy_stream_locked(grpc_exec_ctx *exec_ctx, void *sp, grpc_error *error) { - grpc_byte_stream *bs; grpc_chttp2_stream *s = sp; grpc_chttp2_transport *t = s->t; @@ -623,8 +628,12 @@ static void destroy_stream_locked(grpc_exec_ctx *exec_ctx, void *sp, GPR_ASSERT(grpc_chttp2_stream_map_find(&t->stream_map, s->id) == NULL); } - while ((bs = grpc_chttp2_incoming_frame_queue_pop(&s->incoming_frames))) { - incoming_byte_stream_destroy_locked(exec_ctx, bs, GRPC_ERROR_NONE); + if (s->incoming_frames != NULL) { + grpc_chttp2_incoming_byte_stream *ibs = s->incoming_frames; + s->incoming_frames = NULL; + incoming_byte_stream_destroy_locked(exec_ctx, &ibs->base, GRPC_ERROR_NONE); + grpc_slice_buffer_destroy_internal(exec_ctx, + &s->unprocessed_incoming_frames_buffer); } grpc_chttp2_list_remove_stalled_by_transport(t, s); @@ -1316,8 +1325,8 @@ static void perform_stream_op_locked(grpc_exec_ctx *exec_ctx, void *stream_op, GPR_ASSERT(s->recv_message_ready == NULL); s->recv_message_ready = op->recv_message_ready; s->recv_message = op->recv_message; - if (s->id != 0 && - (s->incoming_frames.head == NULL || s->incoming_frames.head->is_tail)) { + if (s->id != 0 && (s->incoming_frames == NULL || + s->unprocessed_incoming_frames_buffer.count == 0)) { incoming_byte_stream_update_flow_control(exec_ctx, t, s, 5, 0); } grpc_chttp2_maybe_complete_recv_message(exec_ctx, t, s); @@ -1483,13 +1492,16 @@ static void perform_transport_op(grpc_exec_ctx *exec_ctx, grpc_transport *gt, void grpc_chttp2_maybe_complete_recv_initial_metadata(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t, grpc_chttp2_stream *s) { - grpc_byte_stream *bs; if (s->recv_initial_metadata_ready != NULL && s->published_metadata[0] != GRPC_METADATA_NOT_PUBLISHED) { if (s->seen_error) { - while ((bs = grpc_chttp2_incoming_frame_queue_pop(&s->incoming_frames)) != - NULL) { - incoming_byte_stream_destroy_locked(exec_ctx, bs, GRPC_ERROR_NONE); + if (s->incoming_frames != NULL) { + grpc_chttp2_incoming_byte_stream *ibs = s->incoming_frames; + s->incoming_frames = NULL; + incoming_byte_stream_destroy_locked(exec_ctx, &ibs->base, + GRPC_ERROR_NONE); + grpc_slice_buffer_destroy_internal( + exec_ctx, &s->unprocessed_incoming_frames_buffer); } } grpc_chttp2_incoming_metadata_buffer_publish( @@ -1502,18 +1514,29 @@ void grpc_chttp2_maybe_complete_recv_initial_metadata(grpc_exec_ctx *exec_ctx, void grpc_chttp2_maybe_complete_recv_message(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t, grpc_chttp2_stream *s) { - grpc_byte_stream *bs; + grpc_error *error = GRPC_ERROR_NONE; if (s->recv_message_ready != NULL) { - while (s->final_metadata_requested && s->seen_error && - (bs = grpc_chttp2_incoming_frame_queue_pop(&s->incoming_frames)) != - NULL) { - incoming_byte_stream_destroy_locked(exec_ctx, bs, GRPC_ERROR_NONE); + if (s->final_metadata_requested && s->seen_error && + s->incoming_frames != NULL) { + grpc_chttp2_incoming_byte_stream *ibs = s->incoming_frames; + s->incoming_frames = NULL; + incoming_byte_stream_destroy_locked(exec_ctx, &ibs->base, + GRPC_ERROR_NONE); + grpc_slice_buffer_destroy_internal( + exec_ctx, &s->unprocessed_incoming_frames_buffer); } - if (s->incoming_frames.head != NULL) { - *s->recv_message = - grpc_chttp2_incoming_frame_queue_pop(&s->incoming_frames); + if (s->incoming_frames != NULL || + (GRPC_ERROR_NONE == (error = deframe_unprocessed_incoming_frames( + exec_ctx, &s->data_parser, t, s, + &s->unprocessed_incoming_frames_buffer)) && + s->incoming_frames != NULL)) { + *s->recv_message = &s->incoming_frames->base; + s->incoming_frames = NULL; GPR_ASSERT(*s->recv_message != NULL); null_then_run_closure(exec_ctx, &s->recv_message_ready, GRPC_ERROR_NONE); + } else if (error != GRPC_ERROR_NONE) { + GPR_ASSERT(s->incoming_frames == NULL); + null_then_run_closure(exec_ctx, &s->recv_message_ready, error); } else if (s->published_metadata[1] != GRPC_METADATA_NOT_PUBLISHED) { *s->recv_message = NULL; null_then_run_closure(exec_ctx, &s->recv_message_ready, GRPC_ERROR_NONE); @@ -1524,14 +1547,17 @@ void grpc_chttp2_maybe_complete_recv_message(grpc_exec_ctx *exec_ctx, void grpc_chttp2_maybe_complete_recv_trailing_metadata(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t, grpc_chttp2_stream *s) { - grpc_byte_stream *bs; grpc_chttp2_maybe_complete_recv_message(exec_ctx, t, s); if (s->recv_trailing_metadata_finished != NULL && s->read_closed && s->write_closed) { if (s->seen_error) { - while ((bs = grpc_chttp2_incoming_frame_queue_pop(&s->incoming_frames)) != - NULL) { - incoming_byte_stream_destroy_locked(exec_ctx, bs, GRPC_ERROR_NONE); + if (s->incoming_frames != NULL) { + grpc_chttp2_incoming_byte_stream *ibs = s->incoming_frames; + s->incoming_frames = NULL; + incoming_byte_stream_destroy_locked(exec_ctx, &ibs->base, + GRPC_ERROR_NONE); + grpc_slice_buffer_destroy_internal( + exec_ctx, &s->unprocessed_incoming_frames_buffer); } } if (s->all_incoming_byte_streams_finished && @@ -2176,6 +2202,148 @@ static void set_pollset_set(grpc_exec_ctx *exec_ctx, grpc_transport *gt, * BYTE STREAM */ +static grpc_error *deframe_unprocessed_incoming_frames( + grpc_exec_ctx *exec_ctx, grpc_chttp2_data_parser *p, + grpc_chttp2_transport *t, grpc_chttp2_stream *s, + grpc_slice_buffer *slices) { + while (slices->count > 0) { + uint8_t *beg = NULL; + uint8_t *end = NULL; + uint8_t *cur = NULL; + + grpc_slice slice = grpc_slice_buffer_take_first(slices); + + beg = GRPC_SLICE_START_PTR(slice); + end = GRPC_SLICE_END_PTR(slice); + cur = beg; + uint32_t message_flags; + char *msg; + + if (cur == end) { + grpc_slice_unref_internal(exec_ctx, slice); + continue; + } + + switch (p->state) { + case GRPC_CHTTP2_DATA_ERROR: + p->state = GRPC_CHTTP2_DATA_ERROR; + grpc_slice_unref_internal(exec_ctx, slice); + return GRPC_ERROR_REF(p->error); + case GRPC_CHTTP2_DATA_FH_0: + p->frame_type = *cur; + switch (p->frame_type) { + case 0: + p->is_frame_compressed = 0; /* GPR_FALSE */ + break; + case 1: + p->is_frame_compressed = 1; /* GPR_TRUE */ + break; + default: + gpr_asprintf(&msg, "Bad GRPC frame type 0x%02x", p->frame_type); + p->error = GRPC_ERROR_CREATE(msg); + p->error = grpc_error_set_int(p->error, GRPC_ERROR_INT_STREAM_ID, + (intptr_t)s->id); + gpr_free(msg); + msg = grpc_dump_slice(slice, GPR_DUMP_HEX | GPR_DUMP_ASCII); + p->error = + grpc_error_set_str(p->error, GRPC_ERROR_STR_RAW_BYTES, msg); + gpr_free(msg); + p->error = + grpc_error_set_int(p->error, GRPC_ERROR_INT_OFFSET, cur - beg); + p->state = GRPC_CHTTP2_DATA_ERROR; + grpc_slice_unref_internal(exec_ctx, slice); + return GRPC_ERROR_REF(p->error); + } + if (++cur == end) { + p->state = GRPC_CHTTP2_DATA_FH_1; + grpc_slice_unref_internal(exec_ctx, slice); + continue; + } + /* fallthrough */ + case GRPC_CHTTP2_DATA_FH_1: + p->frame_size = ((uint32_t)*cur) << 24; + if (++cur == end) { + p->state = GRPC_CHTTP2_DATA_FH_2; + grpc_slice_unref_internal(exec_ctx, slice); + continue; + } + /* fallthrough */ + case GRPC_CHTTP2_DATA_FH_2: + p->frame_size |= ((uint32_t)*cur) << 16; + if (++cur == end) { + p->state = GRPC_CHTTP2_DATA_FH_3; + grpc_slice_unref_internal(exec_ctx, slice); + continue; + } + /* fallthrough */ + case GRPC_CHTTP2_DATA_FH_3: + p->frame_size |= ((uint32_t)*cur) << 8; + if (++cur == end) { + p->state = GRPC_CHTTP2_DATA_FH_4; + grpc_slice_unref_internal(exec_ctx, slice); + continue; + } + /* fallthrough */ + case GRPC_CHTTP2_DATA_FH_4: + p->frame_size |= ((uint32_t)*cur); + p->state = GRPC_CHTTP2_DATA_FRAME; + ++cur; + message_flags = 0; + if (p->is_frame_compressed) { + message_flags |= GRPC_WRITE_INTERNAL_COMPRESS; + } + GPR_ASSERT(s->incoming_frames == NULL); + p->parsing_frame = s->incoming_frames = + grpc_chttp2_incoming_byte_stream_create( + exec_ctx, t, s, p->frame_size, message_flags, false); + /* fallthrough */ + case GRPC_CHTTP2_DATA_FRAME: + if (cur == end) { + grpc_slice_unref_internal(exec_ctx, slice); + continue; + } + uint32_t remaining = (uint32_t)(end - cur); + if (remaining == p->frame_size) { + grpc_chttp2_incoming_byte_stream_push( + exec_ctx, p->parsing_frame, + grpc_slice_sub(slice, (size_t)(cur - beg), (size_t)(end - beg))); + grpc_chttp2_incoming_byte_stream_finished(exec_ctx, p->parsing_frame, + GRPC_ERROR_NONE); + p->parsing_frame = NULL; + p->state = GRPC_CHTTP2_DATA_FH_0; + grpc_slice_unref_internal(exec_ctx, slice); + break; + } else if (remaining < p->frame_size) { + grpc_chttp2_incoming_byte_stream_push( + exec_ctx, p->parsing_frame, + grpc_slice_sub(slice, (size_t)(cur - beg), (size_t)(end - beg))); + p->frame_size -= remaining; + grpc_slice_unref_internal(exec_ctx, slice); + continue; + } else { + GPR_ASSERT(remaining > p->frame_size); + grpc_chttp2_incoming_byte_stream_push( + exec_ctx, p->parsing_frame, + grpc_slice_sub(slice, (size_t)(cur - beg), + (size_t)(cur + p->frame_size - beg))); + grpc_chttp2_incoming_byte_stream_finished(exec_ctx, p->parsing_frame, + GRPC_ERROR_NONE); + p->parsing_frame = NULL; + p->state = GRPC_CHTTP2_DATA_FH_0; + cur += p->frame_size; + /* slice is not used up; push back to the head of buffer */ + grpc_slice_buffer_undo_take_first( + &s->unprocessed_incoming_frames_buffer, + grpc_slice_sub(slice, (size_t)(cur - beg), (size_t)(end - beg))); + grpc_slice_unref_internal(exec_ctx, slice); + break; + } + } + } + + return GRPC_ERROR_NONE; +} + static void incoming_byte_stream_unref(grpc_exec_ctx *exec_ctx, grpc_chttp2_incoming_byte_stream *bs) { if (gpr_unref(&bs->refs)) { @@ -2249,6 +2417,7 @@ static void incoming_byte_stream_next_locked(grpc_exec_ctx *exec_ctx, exec_ctx, t, s, bs->next_action.max_size_hint, cur_length); } gpr_mu_lock(&bs->slice_mu); + if (bs->slices.count > 0) { *bs->next_action.slice = grpc_slice_buffer_take_first(&bs->slices); grpc_closure_run(exec_ctx, bs->next_action.on_complete, GRPC_ERROR_NONE); @@ -2360,7 +2529,7 @@ void grpc_chttp2_incoming_byte_stream_finished( grpc_chttp2_incoming_byte_stream *grpc_chttp2_incoming_byte_stream_create( grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t, grpc_chttp2_stream *s, - uint32_t frame_size, uint32_t flags) { + uint32_t frame_size, uint32_t flags, bool trigger_recv) { grpc_chttp2_incoming_byte_stream *incoming_byte_stream = gpr_malloc(sizeof(*incoming_byte_stream)); incoming_byte_stream->base.length = frame_size; @@ -2378,15 +2547,10 @@ grpc_chttp2_incoming_byte_stream *grpc_chttp2_incoming_byte_stream_create( incoming_byte_stream->on_next = NULL; incoming_byte_stream->is_tail = 1; incoming_byte_stream->error = GRPC_ERROR_NONE; - grpc_chttp2_incoming_frame_queue *q = &s->incoming_frames; - if (q->head == NULL) { - q->head = incoming_byte_stream; - } else { - q->tail->is_tail = 0; - q->tail->next_message = incoming_byte_stream; + s->incoming_frames = incoming_byte_stream; + if (trigger_recv) { + grpc_chttp2_maybe_complete_recv_message(exec_ctx, t, s); } - q->tail = incoming_byte_stream; - grpc_chttp2_maybe_complete_recv_message(exec_ctx, t, s); return incoming_byte_stream; } diff --git a/src/core/ext/transport/chttp2/transport/frame_data.c b/src/core/ext/transport/chttp2/transport/frame_data.c index f9b9e1b309..75657e4c70 100644 --- a/src/core/ext/transport/chttp2/transport/frame_data.c +++ b/src/core/ext/transport/chttp2/transport/frame_data.c @@ -141,7 +141,7 @@ void grpc_chttp2_encode_data(uint32_t id, grpc_slice_buffer *inbuf, stats->data_bytes += write_bytes; } -static grpc_error *parse_inner(grpc_exec_ctx *exec_ctx, +grpc_error *parse_inner_buffer(grpc_exec_ctx *exec_ctx, grpc_chttp2_data_parser *p, grpc_chttp2_transport *t, grpc_chttp2_stream *s, grpc_slice slice) { @@ -149,18 +149,26 @@ static grpc_error *parse_inner(grpc_exec_ctx *exec_ctx, uint8_t *const end = GRPC_SLICE_END_PTR(slice); uint8_t *cur = beg; uint32_t message_flags; - grpc_chttp2_incoming_byte_stream *incoming_byte_stream; char *msg; if (cur == end) { return GRPC_ERROR_NONE; } + /* If there is already pending data, or if there is a pending + * incoming_byte_stream that is finished, append the data to unprcessed frame + * buffer. */ + if (s->unprocessed_incoming_frames_buffer.count > 0 || + (s->incoming_frames != NULL && p->parsing_frame == NULL)) { + grpc_slice_ref(slice); + grpc_slice_buffer_add(&s->unprocessed_incoming_frames_buffer, slice); + return GRPC_ERROR_NONE; + } + switch (p->state) { case GRPC_CHTTP2_DATA_ERROR: p->state = GRPC_CHTTP2_DATA_ERROR; return GRPC_ERROR_REF(p->error); - fh_0: case GRPC_CHTTP2_DATA_FH_0: s->stats.incoming.framing_bytes++; p->frame_type = *cur; @@ -224,17 +232,17 @@ static grpc_error *parse_inner(grpc_exec_ctx *exec_ctx, if (p->is_frame_compressed) { message_flags |= GRPC_WRITE_INTERNAL_COMPRESS; } - p->parsing_frame = incoming_byte_stream = - grpc_chttp2_incoming_byte_stream_create(exec_ctx, t, s, p->frame_size, - message_flags); + GPR_ASSERT(s->incoming_frames == NULL); + p->parsing_frame = grpc_chttp2_incoming_byte_stream_create( + exec_ctx, t, s, p->frame_size, message_flags, true); /* fallthrough */ case GRPC_CHTTP2_DATA_FRAME: if (cur == end) { return GRPC_ERROR_NONE; } uint32_t remaining = (uint32_t)(end - cur); + s->stats.incoming.data_bytes += remaining; if (remaining == p->frame_size) { - s->stats.incoming.data_bytes += p->frame_size; grpc_chttp2_incoming_byte_stream_push( exec_ctx, p->parsing_frame, grpc_slice_sub(slice, (size_t)(cur - beg), (size_t)(end - beg))); @@ -243,8 +251,14 @@ static grpc_error *parse_inner(grpc_exec_ctx *exec_ctx, p->parsing_frame = NULL; p->state = GRPC_CHTTP2_DATA_FH_0; return GRPC_ERROR_NONE; - } else if (remaining > p->frame_size) { - s->stats.incoming.data_bytes += p->frame_size; + } else if (remaining < p->frame_size) { + grpc_chttp2_incoming_byte_stream_push( + exec_ctx, p->parsing_frame, + grpc_slice_sub(slice, (size_t)(cur - beg), (size_t)(end - beg))); + p->frame_size -= remaining; + return GRPC_ERROR_NONE; + } else { + GPR_ASSERT(remaining > p->frame_size); grpc_chttp2_incoming_byte_stream_push( exec_ctx, p->parsing_frame, grpc_slice_sub(slice, (size_t)(cur - beg), @@ -252,15 +266,11 @@ static grpc_error *parse_inner(grpc_exec_ctx *exec_ctx, grpc_chttp2_incoming_byte_stream_finished(exec_ctx, p->parsing_frame, GRPC_ERROR_NONE); p->parsing_frame = NULL; + p->state = GRPC_CHTTP2_DATA_FH_0; cur += p->frame_size; - goto fh_0; /* loop */ - } else { - GPR_ASSERT(remaining <= p->frame_size); - grpc_chttp2_incoming_byte_stream_push( - exec_ctx, p->parsing_frame, + grpc_slice_buffer_add( + &s->unprocessed_incoming_frames_buffer, grpc_slice_sub(slice, (size_t)(cur - beg), (size_t)(end - beg))); - p->frame_size -= remaining; - s->stats.incoming.data_bytes += remaining; return GRPC_ERROR_NONE; } } @@ -273,7 +283,7 @@ grpc_error *grpc_chttp2_data_parser_parse(grpc_exec_ctx *exec_ctx, void *parser, grpc_chttp2_stream *s, grpc_slice slice, int is_last) { grpc_chttp2_data_parser *p = parser; - grpc_error *error = parse_inner(exec_ctx, p, t, s, slice); + grpc_error *error = parse_inner_buffer(exec_ctx, p, t, s, slice); if (is_last && p->is_last_frame) { grpc_chttp2_mark_stream_closed(exec_ctx, t, s, true, false, diff --git a/src/core/ext/transport/chttp2/transport/internal.h b/src/core/ext/transport/chttp2/transport/internal.h index d26812ad6b..2e71c84664 100644 --- a/src/core/ext/transport/chttp2/transport/internal.h +++ b/src/core/ext/transport/chttp2/transport/internal.h @@ -489,7 +489,8 @@ struct grpc_chttp2_stream { grpc_chttp2_incoming_metadata_buffer metadata_buffer[2]; - grpc_chttp2_incoming_frame_queue incoming_frames; + grpc_chttp2_incoming_byte_stream *incoming_frames; + grpc_slice_buffer unprocessed_incoming_frames_buffer; gpr_timespec deadline; @@ -779,7 +780,7 @@ void grpc_chttp2_ref_transport(grpc_chttp2_transport *t); grpc_chttp2_incoming_byte_stream *grpc_chttp2_incoming_byte_stream_create( grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t, grpc_chttp2_stream *s, - uint32_t frame_size, uint32_t flags); + uint32_t frame_size, uint32_t flags, bool trigger_recv); void grpc_chttp2_incoming_byte_stream_push(grpc_exec_ctx *exec_ctx, grpc_chttp2_incoming_byte_stream *bs, grpc_slice slice); diff --git a/src/core/ext/transport/chttp2/transport/parsing.c b/src/core/ext/transport/chttp2/transport/parsing.c index 7ed00522c3..f48de8ea25 100644 --- a/src/core/ext/transport/chttp2/transport/parsing.c +++ b/src/core/ext/transport/chttp2/transport/parsing.c @@ -441,6 +441,7 @@ static grpc_error *init_data_frame_parser(grpc_exec_ctx *exec_ctx, error_handler: if (err == GRPC_ERROR_NONE) { t->incoming_stream = s; + /* t->parser = grpc_chttp2_data_parser_parse;*/ t->parser = grpc_chttp2_data_parser_parse; t->parser_data = &s->data_parser; return GRPC_ERROR_NONE; -- cgit v1.2.3 From bdd92b56c4dea3c64474542efe3722315042693a Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Mon, 13 Feb 2017 11:36:51 -0800 Subject: intermediate changes --- .../transport/chttp2/transport/chttp2_transport.c | 22 ++++++++++++++++++---- .../ext/transport/chttp2/transport/frame_data.c | 2 +- 2 files changed, 19 insertions(+), 5 deletions(-) (limited to 'src/core/ext/transport') diff --git a/src/core/ext/transport/chttp2/transport/chttp2_transport.c b/src/core/ext/transport/chttp2/transport/chttp2_transport.c index 5c5c29389f..df54d18800 100644 --- a/src/core/ext/transport/chttp2/transport/chttp2_transport.c +++ b/src/core/ext/transport/chttp2/transport/chttp2_transport.c @@ -2205,7 +2205,7 @@ static void set_pollset_set(grpc_exec_ctx *exec_ctx, grpc_transport *gt, static grpc_error *deframe_unprocessed_incoming_frames( grpc_exec_ctx *exec_ctx, grpc_chttp2_data_parser *p, grpc_chttp2_transport *t, grpc_chttp2_stream *s, - grpc_slice_buffer *slices) { + grpc_slice_buffer *slices, bool partial_deframe) { while (slices->count > 0) { uint8_t *beg = NULL; uint8_t *end = NULL; @@ -2298,6 +2298,20 @@ static grpc_error *deframe_unprocessed_incoming_frames( exec_ctx, t, s, p->frame_size, message_flags, false); /* fallthrough */ case GRPC_CHTTP2_DATA_FRAME: + if (partial_deframe) { + uint32_t remaining = (uint32_t)(end - cur); + if (remaining > 0) { + if (cur == beg) { + grpc_slice_buffer_undo_take_first(&s->unprocessed_incoming_frames_buffer, slice); + } else { + grpc_slice_buffer_undo_take_first( + &s->unprocessed_incoming_frames_buffer, + grpc_slice_sub(slice, (size_t)(cur - beg), (size_t)(end - beg))); + grpc_slice_unref_internal(exec_ctx, slice); + } + return GRPC_ERROR_NONE; + } + } if (cur == end) { grpc_slice_unref_internal(exec_ctx, slice); continue; @@ -2312,7 +2326,7 @@ static grpc_error *deframe_unprocessed_incoming_frames( p->parsing_frame = NULL; p->state = GRPC_CHTTP2_DATA_FH_0; grpc_slice_unref_internal(exec_ctx, slice); - break; + return GRPC_ERROR_NONE; } else if (remaining < p->frame_size) { grpc_chttp2_incoming_byte_stream_push( exec_ctx, p->parsing_frame, @@ -2336,12 +2350,12 @@ static grpc_error *deframe_unprocessed_incoming_frames( &s->unprocessed_incoming_frames_buffer, grpc_slice_sub(slice, (size_t)(cur - beg), (size_t)(end - beg))); grpc_slice_unref_internal(exec_ctx, slice); - break; + return GRPC_ERROR_NONE; } } } - return GRPC_ERROR_NONE; + GPR_UNREACHABLE_CODE(return GRPC_ERROR_CREATE("Should never reach here")); } static void incoming_byte_stream_unref(grpc_exec_ctx *exec_ctx, diff --git a/src/core/ext/transport/chttp2/transport/frame_data.c b/src/core/ext/transport/chttp2/transport/frame_data.c index 75657e4c70..501565f8a1 100644 --- a/src/core/ext/transport/chttp2/transport/frame_data.c +++ b/src/core/ext/transport/chttp2/transport/frame_data.c @@ -156,7 +156,7 @@ grpc_error *parse_inner_buffer(grpc_exec_ctx *exec_ctx, } /* If there is already pending data, or if there is a pending - * incoming_byte_stream that is finished, append the data to unprcessed frame + * incoming_byte_stream that is finished, append the data to unprocessed frame * buffer. */ if (s->unprocessed_incoming_frames_buffer.count > 0 || (s->incoming_frames != NULL && p->parsing_frame == NULL)) { -- cgit v1.2.3 From 380a8f6de54c2843c74f5a756b4c91b85cbf3809 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Wed, 15 Feb 2017 15:19:46 -0800 Subject: intermediate --- .../transport/chttp2/transport/chttp2_transport.c | 50 +++++++++++++--------- .../ext/transport/chttp2/transport/frame_data.c | 48 ++++++--------------- src/core/ext/transport/chttp2/transport/internal.h | 2 +- 3 files changed, 44 insertions(+), 56 deletions(-) (limited to 'src/core/ext/transport') diff --git a/src/core/ext/transport/chttp2/transport/chttp2_transport.c b/src/core/ext/transport/chttp2/transport/chttp2_transport.c index df54d18800..c0f43b7ffb 100644 --- a/src/core/ext/transport/chttp2/transport/chttp2_transport.c +++ b/src/core/ext/transport/chttp2/transport/chttp2_transport.c @@ -1525,11 +1525,7 @@ void grpc_chttp2_maybe_complete_recv_message(grpc_exec_ctx *exec_ctx, grpc_slice_buffer_destroy_internal( exec_ctx, &s->unprocessed_incoming_frames_buffer); } - if (s->incoming_frames != NULL || - (GRPC_ERROR_NONE == (error = deframe_unprocessed_incoming_frames( - exec_ctx, &s->data_parser, t, s, - &s->unprocessed_incoming_frames_buffer)) && - s->incoming_frames != NULL)) { + if (s->incoming_frames != NULL) { *s->recv_message = &s->incoming_frames->base; s->incoming_frames = NULL; GPR_ASSERT(*s->recv_message != NULL); @@ -2206,6 +2202,11 @@ static grpc_error *deframe_unprocessed_incoming_frames( grpc_exec_ctx *exec_ctx, grpc_chttp2_data_parser *p, grpc_chttp2_transport *t, grpc_chttp2_stream *s, grpc_slice_buffer *slices, bool partial_deframe) { + + if (p->parsing_frame == NULL && s->incoming_frames != NULL) { + return GRPC_ERROR_NONE; + } + while (slices->count > 0) { uint8_t *beg = NULL; uint8_t *end = NULL; @@ -2230,6 +2231,12 @@ static grpc_error *deframe_unprocessed_incoming_frames( grpc_slice_unref_internal(exec_ctx, slice); return GRPC_ERROR_REF(p->error); case GRPC_CHTTP2_DATA_FH_0: + if (s->incoming_frames != NULL) { + s->stats.incoming.framing_bytes += (size_t)(end - cur); + grpc_slice_buffer_add(&s->unprocessed_incoming_frames_buffer, + grpc_slice_sub(slice, (size_t)(cur - beg), (size_t)(end - beg))); + return GRPC_ERROR_NONE; + } p->frame_type = *cur; switch (p->frame_type) { case 0: @@ -2293,30 +2300,33 @@ static grpc_error *deframe_unprocessed_incoming_frames( message_flags |= GRPC_WRITE_INTERNAL_COMPRESS; } GPR_ASSERT(s->incoming_frames == NULL); - p->parsing_frame = s->incoming_frames = + p->parsing_frame = grpc_chttp2_incoming_byte_stream_create( - exec_ctx, t, s, p->frame_size, message_flags, false); + exec_ctx, t, s, p->frame_size, message_flags); + + undo_take_first? + + /* fallthrough */ case GRPC_CHTTP2_DATA_FRAME: + uint32_t remaining = (uint32_t)(end - cur); if (partial_deframe) { - uint32_t remaining = (uint32_t)(end - cur); - if (remaining > 0) { - if (cur == beg) { - grpc_slice_buffer_undo_take_first(&s->unprocessed_incoming_frames_buffer, slice); - } else { - grpc_slice_buffer_undo_take_first( + if (remaining > 0 && cur == beg) { + grpc_slice_buffer_undo_take_first(&s->unprocessed_incoming_frames_buffer, slice); + } else if (remaining > 0 && cur > beg) { + grpc_slice_buffer_undo_take_first( &s->unprocessed_incoming_frames_buffer, grpc_slice_sub(slice, (size_t)(cur - beg), (size_t)(end - beg))); - grpc_slice_unref_internal(exec_ctx, slice); - } - return GRPC_ERROR_NONE; + grpc_slice_unref_internal(exec_ctx, slice); + } else { /* remaining == 0 */ + grpc_slice_unref_internal(exec_ctx, slice); } + return GRPC_ERROR_NONE; } if (cur == end) { grpc_slice_unref_internal(exec_ctx, slice); continue; } - uint32_t remaining = (uint32_t)(end - cur); if (remaining == p->frame_size) { grpc_chttp2_incoming_byte_stream_push( exec_ctx, p->parsing_frame, @@ -2543,7 +2553,7 @@ void grpc_chttp2_incoming_byte_stream_finished( grpc_chttp2_incoming_byte_stream *grpc_chttp2_incoming_byte_stream_create( grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t, grpc_chttp2_stream *s, - uint32_t frame_size, uint32_t flags, bool trigger_recv) { + uint32_t frame_size, uint32_t flags) { grpc_chttp2_incoming_byte_stream *incoming_byte_stream = gpr_malloc(sizeof(*incoming_byte_stream)); incoming_byte_stream->base.length = frame_size; @@ -2562,9 +2572,7 @@ grpc_chttp2_incoming_byte_stream *grpc_chttp2_incoming_byte_stream_create( incoming_byte_stream->is_tail = 1; incoming_byte_stream->error = GRPC_ERROR_NONE; s->incoming_frames = incoming_byte_stream; - if (trigger_recv) { - grpc_chttp2_maybe_complete_recv_message(exec_ctx, t, s); - } + grpc_chttp2_maybe_complete_recv_message(exec_ctx, t, s); return incoming_byte_stream; } diff --git a/src/core/ext/transport/chttp2/transport/frame_data.c b/src/core/ext/transport/chttp2/transport/frame_data.c index 501565f8a1..71adf80c89 100644 --- a/src/core/ext/transport/chttp2/transport/frame_data.c +++ b/src/core/ext/transport/chttp2/transport/frame_data.c @@ -158,8 +158,8 @@ grpc_error *parse_inner_buffer(grpc_exec_ctx *exec_ctx, /* If there is already pending data, or if there is a pending * incoming_byte_stream that is finished, append the data to unprocessed frame * buffer. */ - if (s->unprocessed_incoming_frames_buffer.count > 0 || - (s->incoming_frames != NULL && p->parsing_frame == NULL)) { + if (s->unprocessed_incoming_frames_buffer.count > 0) { + s->stats.incoming.framing_bytes += GRPC_SLICE_LENGTH(slice); grpc_slice_ref(slice); grpc_slice_buffer_add(&s->unprocessed_incoming_frames_buffer, slice); return GRPC_ERROR_NONE; @@ -170,6 +170,12 @@ grpc_error *parse_inner_buffer(grpc_exec_ctx *exec_ctx, p->state = GRPC_CHTTP2_DATA_ERROR; return GRPC_ERROR_REF(p->error); case GRPC_CHTTP2_DATA_FH_0: + if (s->incoming_frames != NULL) { + s->stats.incoming.framing_bytes += (size_t)(end - cur); + grpc_slice_buffer_add(&s->unprocessed_incoming_frames_buffer, + grpc_slice_sub(slice, (size_t)(cur - beg), (size_t)(end - beg))); + return GRPC_ERROR_NONE; + } s->stats.incoming.framing_bytes++; p->frame_type = *cur; switch (p->frame_type) { @@ -234,7 +240,7 @@ grpc_error *parse_inner_buffer(grpc_exec_ctx *exec_ctx, } GPR_ASSERT(s->incoming_frames == NULL); p->parsing_frame = grpc_chttp2_incoming_byte_stream_create( - exec_ctx, t, s, p->frame_size, message_flags, true); + exec_ctx, t, s, p->frame_size, message_flags); /* fallthrough */ case GRPC_CHTTP2_DATA_FRAME: if (cur == end) { @@ -242,37 +248,11 @@ grpc_error *parse_inner_buffer(grpc_exec_ctx *exec_ctx, } uint32_t remaining = (uint32_t)(end - cur); s->stats.incoming.data_bytes += remaining; - if (remaining == p->frame_size) { - grpc_chttp2_incoming_byte_stream_push( - exec_ctx, p->parsing_frame, - grpc_slice_sub(slice, (size_t)(cur - beg), (size_t)(end - beg))); - grpc_chttp2_incoming_byte_stream_finished(exec_ctx, p->parsing_frame, - GRPC_ERROR_NONE); - p->parsing_frame = NULL; - p->state = GRPC_CHTTP2_DATA_FH_0; - return GRPC_ERROR_NONE; - } else if (remaining < p->frame_size) { - grpc_chttp2_incoming_byte_stream_push( - exec_ctx, p->parsing_frame, - grpc_slice_sub(slice, (size_t)(cur - beg), (size_t)(end - beg))); - p->frame_size -= remaining; - return GRPC_ERROR_NONE; - } else { - GPR_ASSERT(remaining > p->frame_size); - grpc_chttp2_incoming_byte_stream_push( - exec_ctx, p->parsing_frame, - grpc_slice_sub(slice, (size_t)(cur - beg), - (size_t)(cur + p->frame_size - beg))); - grpc_chttp2_incoming_byte_stream_finished(exec_ctx, p->parsing_frame, - GRPC_ERROR_NONE); - p->parsing_frame = NULL; - p->state = GRPC_CHTTP2_DATA_FH_0; - cur += p->frame_size; - grpc_slice_buffer_add( - &s->unprocessed_incoming_frames_buffer, - grpc_slice_sub(slice, (size_t)(cur - beg), (size_t)(end - beg))); - return GRPC_ERROR_NONE; - } + grpc_slice_buffer_add( + &s->unprocessed_incoming_frames_buffer, + grpc_slice_sub(slice, (size_t)(cur - beg), (size_t)(end - beg))); + grpc_chttp2_incoming_byte_stream_notify(exec_ctx, p->parsing_frame); + return GRPC_ERROR_NONE; } GPR_UNREACHABLE_CODE(return GRPC_ERROR_CREATE("Should never reach here")); diff --git a/src/core/ext/transport/chttp2/transport/internal.h b/src/core/ext/transport/chttp2/transport/internal.h index 2e71c84664..0ce67ce450 100644 --- a/src/core/ext/transport/chttp2/transport/internal.h +++ b/src/core/ext/transport/chttp2/transport/internal.h @@ -780,7 +780,7 @@ void grpc_chttp2_ref_transport(grpc_chttp2_transport *t); grpc_chttp2_incoming_byte_stream *grpc_chttp2_incoming_byte_stream_create( grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t, grpc_chttp2_stream *s, - uint32_t frame_size, uint32_t flags, bool trigger_recv); + uint32_t frame_size, uint32_t flags); void grpc_chttp2_incoming_byte_stream_push(grpc_exec_ctx *exec_ctx, grpc_chttp2_incoming_byte_stream *bs, grpc_slice slice); -- cgit v1.2.3 From 3d97670b801965ad479fc49c534be61faf8507f9 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Fri, 17 Feb 2017 13:53:10 -0800 Subject: Intermediate --- src/core/ext/transport/chttp2/transport/chttp2_transport.c | 10 ++++------ src/core/ext/transport/chttp2/transport/frame_data.c | 1 - 2 files changed, 4 insertions(+), 7 deletions(-) (limited to 'src/core/ext/transport') diff --git a/src/core/ext/transport/chttp2/transport/chttp2_transport.c b/src/core/ext/transport/chttp2/transport/chttp2_transport.c index c0f43b7ffb..18ee1a7087 100644 --- a/src/core/ext/transport/chttp2/transport/chttp2_transport.c +++ b/src/core/ext/transport/chttp2/transport/chttp2_transport.c @@ -158,7 +158,8 @@ static void keepalive_watchdog_fired_locked(grpc_exec_ctx *exec_ctx, void *arg, static grpc_error *deframe_unprocessed_incoming_frames( grpc_exec_ctx *exec_ctx, grpc_chttp2_data_parser *p, - grpc_chttp2_transport *t, grpc_chttp2_stream *s, grpc_slice_buffer *slices); + grpc_chttp2_transport *t, grpc_chttp2_stream *s, grpc_slice_buffer *slices, + bool partial_deframe); /******************************************************************************* * CONSTRUCTION/DESTRUCTION/REFCOUNTING @@ -2303,12 +2304,8 @@ static grpc_error *deframe_unprocessed_incoming_frames( p->parsing_frame = grpc_chttp2_incoming_byte_stream_create( exec_ctx, t, s, p->frame_size, message_flags); - - undo_take_first? - - /* fallthrough */ - case GRPC_CHTTP2_DATA_FRAME: + case GRPC_CHTTP2_DATA_FRAME: { uint32_t remaining = (uint32_t)(end - cur); if (partial_deframe) { if (remaining > 0 && cur == beg) { @@ -2362,6 +2359,7 @@ static grpc_error *deframe_unprocessed_incoming_frames( grpc_slice_unref_internal(exec_ctx, slice); return GRPC_ERROR_NONE; } + } } } diff --git a/src/core/ext/transport/chttp2/transport/frame_data.c b/src/core/ext/transport/chttp2/transport/frame_data.c index 71adf80c89..cde9cd9c99 100644 --- a/src/core/ext/transport/chttp2/transport/frame_data.c +++ b/src/core/ext/transport/chttp2/transport/frame_data.c @@ -251,7 +251,6 @@ grpc_error *parse_inner_buffer(grpc_exec_ctx *exec_ctx, grpc_slice_buffer_add( &s->unprocessed_incoming_frames_buffer, grpc_slice_sub(slice, (size_t)(cur - beg), (size_t)(end - beg))); - grpc_chttp2_incoming_byte_stream_notify(exec_ctx, p->parsing_frame); return GRPC_ERROR_NONE; } -- cgit v1.2.3 From 456f48ad9851b88a94b806dd451eb85056801c26 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Tue, 21 Feb 2017 11:12:49 -0800 Subject: Change stream interface for method --- .../transport/chttp2/transport/chttp2_transport.c | 25 +++++++++++++++++----- src/core/lib/surface/call.c | 5 ++++- src/core/lib/transport/byte_stream.h | 2 ++ 3 files changed, 26 insertions(+), 6 deletions(-) (limited to 'src/core/ext/transport') diff --git a/src/core/ext/transport/chttp2/transport/chttp2_transport.c b/src/core/ext/transport/chttp2/transport/chttp2_transport.c index 18ee1a7087..da5cdaea8b 100644 --- a/src/core/ext/transport/chttp2/transport/chttp2_transport.c +++ b/src/core/ext/transport/chttp2/transport/chttp2_transport.c @@ -2441,8 +2441,12 @@ static void incoming_byte_stream_next_locked(grpc_exec_ctx *exec_ctx, gpr_mu_lock(&bs->slice_mu); if (bs->slices.count > 0) { - *bs->next_action.slice = grpc_slice_buffer_take_first(&bs->slices); - grpc_closure_run(exec_ctx, bs->next_action.on_complete, GRPC_ERROR_NONE); + grpc_closure_sched(exec_ctx, bs->next_action.on_complete, GRPC_ERROR_NONE); + } else if (GRPC_ERROR_NONE == deframe_unprocessed_incoming_frames( + exec_ctx, &s->data_parser, t, s, &s->unprocessed_incoming_frames_buffer, + false) && + bs->slices.count > 0) { + grpc_closure_sched(exec_ctx, bs->next_action.on_complete, GRPC_ERROR_NONE); } else if (bs->error != GRPC_ERROR_NONE) { grpc_closure_run(exec_ctx, bs->next_action.on_complete, GRPC_ERROR_REF(bs->error)); @@ -2454,6 +2458,18 @@ static void incoming_byte_stream_next_locked(grpc_exec_ctx *exec_ctx, incoming_byte_stream_unref(exec_ctx, bs); } +static void incoming_byte_stream_pull(grpc_exec_ctx *exec_ctx, + grpc_byte_stream *byte_stream, + grpc_slice *slice) { + GPR_TIMER_BEGIN("incoming_byte_stream_pull", 0); + grpc_chttp2_incoming_byte_stream *bs = + (grpc_chttp2_incoming_byte_stream *)byte_stream; + if (bs->slices.count > 0) { + *slice = grpc_slice_buffer_take_first(&bs->slices); + } + GPR_TIMER_END("incoming_byte_stream_pull", 0); +} + static int incoming_byte_stream_next(grpc_exec_ctx *exec_ctx, grpc_byte_stream *byte_stream, grpc_slice *slice, size_t max_size_hint, @@ -2522,12 +2538,10 @@ void grpc_chttp2_incoming_byte_stream_push(grpc_exec_ctx *exec_ctx, exec_ctx, bs, GRPC_ERROR_CREATE("Too many bytes in stream")); } else { bs->remaining_bytes -= (uint32_t)GRPC_SLICE_LENGTH(slice); + grpc_slice_buffer_add(&bs->slices, slice); if (bs->on_next != NULL) { - *bs->next = slice; grpc_closure_sched(exec_ctx, bs->on_next, GRPC_ERROR_NONE); bs->on_next = NULL; - } else { - grpc_slice_buffer_add(&bs->slices, slice); } } gpr_mu_unlock(&bs->slice_mu); @@ -2558,6 +2572,7 @@ grpc_chttp2_incoming_byte_stream *grpc_chttp2_incoming_byte_stream_create( incoming_byte_stream->remaining_bytes = frame_size; incoming_byte_stream->base.flags = flags; incoming_byte_stream->base.next = incoming_byte_stream_next; + incoming_byte_stream->base.pull = incoming_byte_stream_pull; incoming_byte_stream->base.destroy = incoming_byte_stream_destroy; gpr_mu_init(&incoming_byte_stream->slice_mu); gpr_ref_init(&incoming_byte_stream->refs, 2); diff --git a/src/core/lib/surface/call.c b/src/core/lib/surface/call.c index cc57654ea4..ec1eb0a5f9 100644 --- a/src/core/lib/surface/call.c +++ b/src/core/lib/surface/call.c @@ -1177,10 +1177,13 @@ static void receiving_slice_ready(grpc_exec_ctx *exec_ctx, void *bctlp, grpc_error *error) { batch_control *bctl = bctlp; grpc_call *call = bctl->call; + grpc_byte_stream *bs = call->receiving_stream; if (error == GRPC_ERROR_NONE) { + grpc_slice slice; + bs->pull(exec_ctx, bs, &slice); grpc_slice_buffer_add(&(*call->receiving_buffer)->data.raw.slice_buffer, - call->receiving_slice); + slice); continue_receiving_slices(exec_ctx, bctl); } else { if (grpc_trace_operation_failures) { diff --git a/src/core/lib/transport/byte_stream.h b/src/core/lib/transport/byte_stream.h index 1fdd5b4d77..646ffcd660 100644 --- a/src/core/lib/transport/byte_stream.h +++ b/src/core/lib/transport/byte_stream.h @@ -52,6 +52,8 @@ struct grpc_byte_stream { int (*next)(grpc_exec_ctx *exec_ctx, grpc_byte_stream *byte_stream, grpc_slice *slice, size_t max_size_hint, grpc_closure *on_complete); + void (*pull)(grpc_exec_ctx *exec_ctx, grpc_byte_stream *byte_stream, + grpc_slice *slice); void (*destroy)(grpc_exec_ctx *exec_ctx, grpc_byte_stream *byte_stream); }; -- cgit v1.2.3 From 5a6e2416ed4938afd26ed756af6ea57c2288b8ed Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Fri, 24 Feb 2017 14:52:28 -0800 Subject: Lazy deframe pass cronet end2end tests --- .../transport/chttp2/transport/chttp2_transport.c | 116 ++++++++++++--------- .../ext/transport/chttp2/transport/frame_data.c | 42 +++++++- src/core/ext/transport/chttp2/transport/internal.h | 3 +- src/core/lib/surface/call.c | 14 ++- src/core/lib/transport/byte_stream.c | 5 + src/core/lib/transport/byte_stream.h | 5 +- 6 files changed, 121 insertions(+), 64 deletions(-) (limited to 'src/core/ext/transport') diff --git a/src/core/ext/transport/chttp2/transport/chttp2_transport.c b/src/core/ext/transport/chttp2/transport/chttp2_transport.c index da5cdaea8b..b03c79315b 100644 --- a/src/core/ext/transport/chttp2/transport/chttp2_transport.c +++ b/src/core/ext/transport/chttp2/transport/chttp2_transport.c @@ -159,7 +159,7 @@ static void keepalive_watchdog_fired_locked(grpc_exec_ctx *exec_ctx, void *arg, static grpc_error *deframe_unprocessed_incoming_frames( grpc_exec_ctx *exec_ctx, grpc_chttp2_data_parser *p, grpc_chttp2_transport *t, grpc_chttp2_stream *s, grpc_slice_buffer *slices, - bool partial_deframe); + grpc_slice *slice_out, bool partial_deframe); /******************************************************************************* * CONSTRUCTION/DESTRUCTION/REFCOUNTING @@ -602,6 +602,7 @@ static int init_stream(grpc_exec_ctx *exec_ctx, grpc_transport *gt, grpc_schedule_on_exec_ctx); s->incoming_frames = NULL; grpc_slice_buffer_init(&s->unprocessed_incoming_frames_buffer); + gpr_mu_init(&s->buffer_mu); GRPC_CHTTP2_REF_TRANSPORT(t, "stream"); @@ -633,8 +634,10 @@ static void destroy_stream_locked(grpc_exec_ctx *exec_ctx, void *sp, grpc_chttp2_incoming_byte_stream *ibs = s->incoming_frames; s->incoming_frames = NULL; incoming_byte_stream_destroy_locked(exec_ctx, &ibs->base, GRPC_ERROR_NONE); + gpr_mu_lock(&s->buffer_mu); grpc_slice_buffer_destroy_internal(exec_ctx, &s->unprocessed_incoming_frames_buffer); + gpr_mu_unlock(&s->buffer_mu); } grpc_chttp2_list_remove_stalled_by_transport(t, s); @@ -1096,7 +1099,7 @@ static void continue_fetching_send_locked(grpc_exec_ctx *exec_ctx, return; /* early out */ } else if (grpc_byte_stream_next(exec_ctx, s->fetching_send_message, &s->fetching_slice, UINT32_MAX, - &s->complete_fetch)) { + &s->complete_fetch_locked)) { add_fetched_slice_locked(exec_ctx, t, s); } } @@ -1326,9 +1329,13 @@ static void perform_stream_op_locked(grpc_exec_ctx *exec_ctx, void *stream_op, GPR_ASSERT(s->recv_message_ready == NULL); s->recv_message_ready = op->recv_message_ready; s->recv_message = op->recv_message; + gpr_mu_lock(&s->buffer_mu); if (s->id != 0 && (s->incoming_frames == NULL || s->unprocessed_incoming_frames_buffer.count == 0)) { + gpr_mu_unlock(&s->buffer_mu); incoming_byte_stream_update_flow_control(exec_ctx, t, s, 5, 0); + } else { + gpr_mu_unlock(&s->buffer_mu); } grpc_chttp2_maybe_complete_recv_message(exec_ctx, t, s); } @@ -1501,8 +1508,10 @@ void grpc_chttp2_maybe_complete_recv_initial_metadata(grpc_exec_ctx *exec_ctx, s->incoming_frames = NULL; incoming_byte_stream_destroy_locked(exec_ctx, &ibs->base, GRPC_ERROR_NONE); + gpr_mu_lock(&s->buffer_mu); grpc_slice_buffer_destroy_internal( exec_ctx, &s->unprocessed_incoming_frames_buffer); + gpr_mu_unlock(&s->buffer_mu); } } grpc_chttp2_incoming_metadata_buffer_publish( @@ -1523,8 +1532,10 @@ void grpc_chttp2_maybe_complete_recv_message(grpc_exec_ctx *exec_ctx, s->incoming_frames = NULL; incoming_byte_stream_destroy_locked(exec_ctx, &ibs->base, GRPC_ERROR_NONE); + gpr_mu_lock(&s->buffer_mu); grpc_slice_buffer_destroy_internal( exec_ctx, &s->unprocessed_incoming_frames_buffer); + gpr_mu_unlock(&s->buffer_mu); } if (s->incoming_frames != NULL) { *s->recv_message = &s->incoming_frames->base; @@ -1553,8 +1564,10 @@ void grpc_chttp2_maybe_complete_recv_trailing_metadata(grpc_exec_ctx *exec_ctx, s->incoming_frames = NULL; incoming_byte_stream_destroy_locked(exec_ctx, &ibs->base, GRPC_ERROR_NONE); + gpr_mu_lock(&s->buffer_mu); grpc_slice_buffer_destroy_internal( exec_ctx, &s->unprocessed_incoming_frames_buffer); + gpr_mu_unlock(&s->buffer_mu); } } if (s->all_incoming_byte_streams_finished && @@ -2202,12 +2215,10 @@ static void set_pollset_set(grpc_exec_ctx *exec_ctx, grpc_transport *gt, static grpc_error *deframe_unprocessed_incoming_frames( grpc_exec_ctx *exec_ctx, grpc_chttp2_data_parser *p, grpc_chttp2_transport *t, grpc_chttp2_stream *s, - grpc_slice_buffer *slices, bool partial_deframe) { - - if (p->parsing_frame == NULL && s->incoming_frames != NULL) { - return GRPC_ERROR_NONE; - } + grpc_slice_buffer *slices, grpc_slice *slice_out, + bool partial_deframe) { + bool slice_set = false; while (slices->count > 0) { uint8_t *beg = NULL; uint8_t *end = NULL; @@ -2231,10 +2242,12 @@ static grpc_error *deframe_unprocessed_incoming_frames( p->state = GRPC_CHTTP2_DATA_ERROR; grpc_slice_unref_internal(exec_ctx, slice); return GRPC_ERROR_REF(p->error); + fh_0: case GRPC_CHTTP2_DATA_FH_0: + GPR_ASSERT(s->incoming_frames == NULL); if (s->incoming_frames != NULL) { s->stats.incoming.framing_bytes += (size_t)(end - cur); - grpc_slice_buffer_add(&s->unprocessed_incoming_frames_buffer, + grpc_slice_buffer_undo_take_first(&s->unprocessed_incoming_frames_buffer, grpc_slice_sub(slice, (size_t)(cur - beg), (size_t)(end - beg))); return GRPC_ERROR_NONE; } @@ -2306,20 +2319,14 @@ static grpc_error *deframe_unprocessed_incoming_frames( exec_ctx, t, s, p->frame_size, message_flags); /* fallthrough */ case GRPC_CHTTP2_DATA_FRAME: { - uint32_t remaining = (uint32_t)(end - cur); - if (partial_deframe) { - if (remaining > 0 && cur == beg) { - grpc_slice_buffer_undo_take_first(&s->unprocessed_incoming_frames_buffer, slice); - } else if (remaining > 0 && cur > beg) { - grpc_slice_buffer_undo_take_first( - &s->unprocessed_incoming_frames_buffer, - grpc_slice_sub(slice, (size_t)(cur - beg), (size_t)(end - beg))); - grpc_slice_unref_internal(exec_ctx, slice); - } else { /* remaining == 0 */ - grpc_slice_unref_internal(exec_ctx, slice); - } + if (slice_set) { + grpc_slice_buffer_undo_take_first( + &s->unprocessed_incoming_frames_buffer, + grpc_slice_sub(slice, (size_t)(cur - beg), (size_t)(end - beg))); + grpc_slice_unref_internal(exec_ctx, slice); return GRPC_ERROR_NONE; } + uint32_t remaining = (uint32_t)(end - cur); if (cur == end) { grpc_slice_unref_internal(exec_ctx, slice); continue; @@ -2327,17 +2334,21 @@ static grpc_error *deframe_unprocessed_incoming_frames( if (remaining == p->frame_size) { grpc_chttp2_incoming_byte_stream_push( exec_ctx, p->parsing_frame, - grpc_slice_sub(slice, (size_t)(cur - beg), (size_t)(end - beg))); + grpc_slice_sub(slice, (size_t)(cur - beg), (size_t)(end - beg)), + slice_out); + slice_set = true; grpc_chttp2_incoming_byte_stream_finished(exec_ctx, p->parsing_frame, GRPC_ERROR_NONE); p->parsing_frame = NULL; p->state = GRPC_CHTTP2_DATA_FH_0; grpc_slice_unref_internal(exec_ctx, slice); - return GRPC_ERROR_NONE; + continue; } else if (remaining < p->frame_size) { grpc_chttp2_incoming_byte_stream_push( exec_ctx, p->parsing_frame, - grpc_slice_sub(slice, (size_t)(cur - beg), (size_t)(end - beg))); + grpc_slice_sub(slice, (size_t)(cur - beg), (size_t)(end - beg)), + slice_out); + slice_set = true; p->frame_size -= remaining; grpc_slice_unref_internal(exec_ctx, slice); continue; @@ -2346,24 +2357,22 @@ static grpc_error *deframe_unprocessed_incoming_frames( grpc_chttp2_incoming_byte_stream_push( exec_ctx, p->parsing_frame, grpc_slice_sub(slice, (size_t)(cur - beg), - (size_t)(cur + p->frame_size - beg))); + (size_t)(cur + p->frame_size - beg)), + slice_out); + slice_set = true; grpc_chttp2_incoming_byte_stream_finished(exec_ctx, p->parsing_frame, GRPC_ERROR_NONE); p->parsing_frame = NULL; p->state = GRPC_CHTTP2_DATA_FH_0; cur += p->frame_size; - /* slice is not used up; push back to the head of buffer */ - grpc_slice_buffer_undo_take_first( - &s->unprocessed_incoming_frames_buffer, - grpc_slice_sub(slice, (size_t)(cur - beg), (size_t)(end - beg))); - grpc_slice_unref_internal(exec_ctx, slice); + goto fh_0; return GRPC_ERROR_NONE; } } } } - GPR_UNREACHABLE_CODE(return GRPC_ERROR_CREATE("Should never reach here")); + return GRPC_ERROR_NONE; } static void incoming_byte_stream_unref(grpc_exec_ctx *exec_ctx, @@ -2438,36 +2447,45 @@ static void incoming_byte_stream_next_locked(grpc_exec_ctx *exec_ctx, incoming_byte_stream_update_flow_control( exec_ctx, t, s, bs->next_action.max_size_hint, cur_length); } + gpr_mu_lock(&s->buffer_mu); gpr_mu_lock(&bs->slice_mu); - - if (bs->slices.count > 0) { - grpc_closure_sched(exec_ctx, bs->next_action.on_complete, GRPC_ERROR_NONE); - } else if (GRPC_ERROR_NONE == deframe_unprocessed_incoming_frames( - exec_ctx, &s->data_parser, t, s, &s->unprocessed_incoming_frames_buffer, - false) && - bs->slices.count > 0) { + if (s->unprocessed_incoming_frames_buffer.length > 0) { grpc_closure_sched(exec_ctx, bs->next_action.on_complete, GRPC_ERROR_NONE); } else if (bs->error != GRPC_ERROR_NONE) { - grpc_closure_run(exec_ctx, bs->next_action.on_complete, - GRPC_ERROR_REF(bs->error)); + grpc_closure_sched(exec_ctx, bs->next_action.on_complete, + GRPC_ERROR_REF(bs->error)); } else { bs->on_next = bs->next_action.on_complete; bs->next = bs->next_action.slice; } gpr_mu_unlock(&bs->slice_mu); + gpr_mu_unlock(&s->buffer_mu); incoming_byte_stream_unref(exec_ctx, bs); } -static void incoming_byte_stream_pull(grpc_exec_ctx *exec_ctx, - grpc_byte_stream *byte_stream, - grpc_slice *slice) { +static grpc_error *incoming_byte_stream_pull(grpc_exec_ctx *exec_ctx, + grpc_byte_stream *byte_stream, + grpc_slice *slice) { GPR_TIMER_BEGIN("incoming_byte_stream_pull", 0); grpc_chttp2_incoming_byte_stream *bs = (grpc_chttp2_incoming_byte_stream *)byte_stream; - if (bs->slices.count > 0) { - *slice = grpc_slice_buffer_take_first(&bs->slices); + grpc_chttp2_stream *s = bs->stream; + grpc_chttp2_transport *t = bs->transport; + + gpr_mu_lock(&s->buffer_mu); + if (s->unprocessed_incoming_frames_buffer.length > 0) { + grpc_error *error = deframe_unprocessed_incoming_frames( + exec_ctx, &s->data_parser, t, s, + &s->unprocessed_incoming_frames_buffer, + slice, false); + if (error != GRPC_ERROR_NONE) { + gpr_mu_unlock(&s->buffer_mu); + return error; + } } + gpr_mu_unlock(&s->buffer_mu); GPR_TIMER_END("incoming_byte_stream_pull", 0); + return GRPC_ERROR_NONE; } static int incoming_byte_stream_next(grpc_exec_ctx *exec_ctx, @@ -2531,20 +2549,14 @@ static void incoming_byte_stream_publish_error( void grpc_chttp2_incoming_byte_stream_push(grpc_exec_ctx *exec_ctx, grpc_chttp2_incoming_byte_stream *bs, - grpc_slice slice) { - gpr_mu_lock(&bs->slice_mu); + grpc_slice slice, grpc_slice *slice_out) { if (bs->remaining_bytes < GRPC_SLICE_LENGTH(slice)) { incoming_byte_stream_publish_error( exec_ctx, bs, GRPC_ERROR_CREATE("Too many bytes in stream")); } else { bs->remaining_bytes -= (uint32_t)GRPC_SLICE_LENGTH(slice); - grpc_slice_buffer_add(&bs->slices, slice); - if (bs->on_next != NULL) { - grpc_closure_sched(exec_ctx, bs->on_next, GRPC_ERROR_NONE); - bs->on_next = NULL; - } + *slice_out = slice; } - gpr_mu_unlock(&bs->slice_mu); } void grpc_chttp2_incoming_byte_stream_finished( diff --git a/src/core/ext/transport/chttp2/transport/frame_data.c b/src/core/ext/transport/chttp2/transport/frame_data.c index cde9cd9c99..e889e3527b 100644 --- a/src/core/ext/transport/chttp2/transport/frame_data.c +++ b/src/core/ext/transport/chttp2/transport/frame_data.c @@ -141,6 +141,23 @@ void grpc_chttp2_encode_data(uint32_t id, grpc_slice_buffer *inbuf, stats->data_bytes += write_bytes; } +static void grpc_chttp2_unprocessed_frames_buffer_push(grpc_exec_ctx *exec_ctx, + grpc_chttp2_data_parser *p, + grpc_chttp2_stream *s, + grpc_slice slice) { + grpc_slice_buffer_add(&s->unprocessed_incoming_frames_buffer, slice); + if (p->parsing_frame) { + grpc_chttp2_incoming_byte_stream *bs = p->parsing_frame; + // Necessary? + gpr_mu_lock(&bs->slice_mu); + if (bs->on_next != NULL) { + grpc_closure_sched(exec_ctx, bs->on_next, GRPC_ERROR_NONE); + bs->on_next = NULL; + } + gpr_mu_unlock(&bs->slice_mu); + } +} + grpc_error *parse_inner_buffer(grpc_exec_ctx *exec_ctx, grpc_chttp2_data_parser *p, grpc_chttp2_transport *t, grpc_chttp2_stream *s, @@ -158,22 +175,30 @@ grpc_error *parse_inner_buffer(grpc_exec_ctx *exec_ctx, /* If there is already pending data, or if there is a pending * incoming_byte_stream that is finished, append the data to unprocessed frame * buffer. */ + gpr_mu_lock(&s->buffer_mu); if (s->unprocessed_incoming_frames_buffer.count > 0) { s->stats.incoming.framing_bytes += GRPC_SLICE_LENGTH(slice); grpc_slice_ref(slice); - grpc_slice_buffer_add(&s->unprocessed_incoming_frames_buffer, slice); + grpc_chttp2_unprocessed_frames_buffer_push(exec_ctx, + p, + s, + slice); + gpr_mu_unlock(&s->buffer_mu); return GRPC_ERROR_NONE; } switch (p->state) { case GRPC_CHTTP2_DATA_ERROR: p->state = GRPC_CHTTP2_DATA_ERROR; + gpr_mu_unlock(&s->buffer_mu); return GRPC_ERROR_REF(p->error); case GRPC_CHTTP2_DATA_FH_0: if (s->incoming_frames != NULL) { s->stats.incoming.framing_bytes += (size_t)(end - cur); - grpc_slice_buffer_add(&s->unprocessed_incoming_frames_buffer, - grpc_slice_sub(slice, (size_t)(cur - beg), (size_t)(end - beg))); + grpc_chttp2_unprocessed_frames_buffer_push( + exec_ctx, p, s, + grpc_slice_sub(slice, (size_t)(cur - beg), (size_t)(end - beg))); + gpr_mu_unlock(&s->buffer_mu); return GRPC_ERROR_NONE; } s->stats.incoming.framing_bytes++; @@ -198,10 +223,12 @@ grpc_error *parse_inner_buffer(grpc_exec_ctx *exec_ctx, p->error = grpc_error_set_int(p->error, GRPC_ERROR_INT_OFFSET, cur - beg); p->state = GRPC_CHTTP2_DATA_ERROR; + gpr_mu_unlock(&s->buffer_mu); return GRPC_ERROR_REF(p->error); } if (++cur == end) { p->state = GRPC_CHTTP2_DATA_FH_1; + gpr_mu_unlock(&s->buffer_mu); return GRPC_ERROR_NONE; } /* fallthrough */ @@ -210,6 +237,7 @@ grpc_error *parse_inner_buffer(grpc_exec_ctx *exec_ctx, p->frame_size = ((uint32_t)*cur) << 24; if (++cur == end) { p->state = GRPC_CHTTP2_DATA_FH_2; + gpr_mu_unlock(&s->buffer_mu); return GRPC_ERROR_NONE; } /* fallthrough */ @@ -218,6 +246,7 @@ grpc_error *parse_inner_buffer(grpc_exec_ctx *exec_ctx, p->frame_size |= ((uint32_t)*cur) << 16; if (++cur == end) { p->state = GRPC_CHTTP2_DATA_FH_3; + gpr_mu_unlock(&s->buffer_mu); return GRPC_ERROR_NONE; } /* fallthrough */ @@ -226,6 +255,7 @@ grpc_error *parse_inner_buffer(grpc_exec_ctx *exec_ctx, p->frame_size |= ((uint32_t)*cur) << 8; if (++cur == end) { p->state = GRPC_CHTTP2_DATA_FH_4; + gpr_mu_unlock(&s->buffer_mu); return GRPC_ERROR_NONE; } /* fallthrough */ @@ -244,13 +274,15 @@ grpc_error *parse_inner_buffer(grpc_exec_ctx *exec_ctx, /* fallthrough */ case GRPC_CHTTP2_DATA_FRAME: if (cur == end) { + gpr_mu_unlock(&s->buffer_mu); return GRPC_ERROR_NONE; } uint32_t remaining = (uint32_t)(end - cur); s->stats.incoming.data_bytes += remaining; - grpc_slice_buffer_add( - &s->unprocessed_incoming_frames_buffer, + grpc_chttp2_unprocessed_frames_buffer_push( + exec_ctx, p, s, grpc_slice_sub(slice, (size_t)(cur - beg), (size_t)(end - beg))); + gpr_mu_unlock(&s->buffer_mu); return GRPC_ERROR_NONE; } diff --git a/src/core/ext/transport/chttp2/transport/internal.h b/src/core/ext/transport/chttp2/transport/internal.h index 0ce67ce450..8d0f96efc6 100644 --- a/src/core/ext/transport/chttp2/transport/internal.h +++ b/src/core/ext/transport/chttp2/transport/internal.h @@ -490,6 +490,7 @@ struct grpc_chttp2_stream { grpc_chttp2_incoming_metadata_buffer metadata_buffer[2]; grpc_chttp2_incoming_byte_stream *incoming_frames; + gpr_mu buffer_mu; /* protects unprocessed_incoming_frames_buffer and parse_data */ grpc_slice_buffer unprocessed_incoming_frames_buffer; gpr_timespec deadline; @@ -783,7 +784,7 @@ grpc_chttp2_incoming_byte_stream *grpc_chttp2_incoming_byte_stream_create( uint32_t frame_size, uint32_t flags); void grpc_chttp2_incoming_byte_stream_push(grpc_exec_ctx *exec_ctx, grpc_chttp2_incoming_byte_stream *bs, - grpc_slice slice); + grpc_slice slice, grpc_slice *slice_out); void grpc_chttp2_incoming_byte_stream_finished( grpc_exec_ctx *exec_ctx, grpc_chttp2_incoming_byte_stream *bs, grpc_error *error); diff --git a/src/core/lib/surface/call.c b/src/core/lib/surface/call.c index ec1eb0a5f9..7baa8e10a5 100644 --- a/src/core/lib/surface/call.c +++ b/src/core/lib/surface/call.c @@ -1181,11 +1181,15 @@ static void receiving_slice_ready(grpc_exec_ctx *exec_ctx, void *bctlp, if (error == GRPC_ERROR_NONE) { grpc_slice slice; - bs->pull(exec_ctx, bs, &slice); - grpc_slice_buffer_add(&(*call->receiving_buffer)->data.raw.slice_buffer, - slice); - continue_receiving_slices(exec_ctx, bctl); - } else { + error = grpc_byte_stream_pull(exec_ctx, bs, &slice); + if (error == GRPC_ERROR_NONE) { + grpc_slice_buffer_add(&(*call->receiving_buffer)->data.raw.slice_buffer, + slice); + continue_receiving_slices(exec_ctx, bctl); + } + } + + if (error != GRPC_ERROR_NONE) { if (grpc_trace_operation_failures) { GRPC_LOG_IF_ERROR("receiving_slice_ready", GRPC_ERROR_REF(error)); } diff --git a/src/core/lib/transport/byte_stream.c b/src/core/lib/transport/byte_stream.c index 4d4206189e..afebf52cd5 100644 --- a/src/core/lib/transport/byte_stream.c +++ b/src/core/lib/transport/byte_stream.c @@ -46,6 +46,11 @@ int grpc_byte_stream_next(grpc_exec_ctx *exec_ctx, on_complete); } +grpc_error *grpc_byte_stream_pull(grpc_exec_ctx *exec_ctx, + grpc_byte_stream *byte_stream, grpc_slice *slice) { + return byte_stream->pull(exec_ctx, byte_stream, slice); +} + void grpc_byte_stream_destroy(grpc_exec_ctx *exec_ctx, grpc_byte_stream *byte_stream) { byte_stream->destroy(exec_ctx, byte_stream); diff --git a/src/core/lib/transport/byte_stream.h b/src/core/lib/transport/byte_stream.h index 646ffcd660..582480bb88 100644 --- a/src/core/lib/transport/byte_stream.h +++ b/src/core/lib/transport/byte_stream.h @@ -52,7 +52,7 @@ struct grpc_byte_stream { int (*next)(grpc_exec_ctx *exec_ctx, grpc_byte_stream *byte_stream, grpc_slice *slice, size_t max_size_hint, grpc_closure *on_complete); - void (*pull)(grpc_exec_ctx *exec_ctx, grpc_byte_stream *byte_stream, + grpc_error* (*pull)(grpc_exec_ctx *exec_ctx, grpc_byte_stream *byte_stream, grpc_slice *slice); void (*destroy)(grpc_exec_ctx *exec_ctx, grpc_byte_stream *byte_stream); }; @@ -70,6 +70,9 @@ int grpc_byte_stream_next(grpc_exec_ctx *exec_ctx, grpc_byte_stream *byte_stream, grpc_slice *slice, size_t max_size_hint, grpc_closure *on_complete); +grpc_error *grpc_byte_stream_pull(grpc_exec_ctx *exec_ctx, + grpc_byte_stream *byte_stream, grpc_slice *slice); + void grpc_byte_stream_destroy(grpc_exec_ctx *exec_ctx, grpc_byte_stream *byte_stream); -- cgit v1.2.3 From 31ed2d9effd77029b879a139f4dd9e8ab166a1f5 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Sun, 26 Feb 2017 22:10:07 -0800 Subject: clang-format --- .../transport/chttp2/transport/chttp2_transport.c | 24 ++++++++++------------ .../ext/transport/chttp2/transport/frame_data.c | 12 ++++------- src/core/ext/transport/chttp2/transport/internal.h | 6 ++++-- src/core/lib/transport/byte_stream.c | 3 ++- src/core/lib/transport/byte_stream.h | 7 ++++--- 5 files changed, 25 insertions(+), 27 deletions(-) (limited to 'src/core/ext/transport') diff --git a/src/core/ext/transport/chttp2/transport/chttp2_transport.c b/src/core/ext/transport/chttp2/transport/chttp2_transport.c index b03c79315b..b5e087d8f7 100644 --- a/src/core/ext/transport/chttp2/transport/chttp2_transport.c +++ b/src/core/ext/transport/chttp2/transport/chttp2_transport.c @@ -2214,10 +2214,8 @@ static void set_pollset_set(grpc_exec_ctx *exec_ctx, grpc_transport *gt, static grpc_error *deframe_unprocessed_incoming_frames( grpc_exec_ctx *exec_ctx, grpc_chttp2_data_parser *p, - grpc_chttp2_transport *t, grpc_chttp2_stream *s, - grpc_slice_buffer *slices, grpc_slice *slice_out, - bool partial_deframe) { - + grpc_chttp2_transport *t, grpc_chttp2_stream *s, grpc_slice_buffer *slices, + grpc_slice *slice_out, bool partial_deframe) { bool slice_set = false; while (slices->count > 0) { uint8_t *beg = NULL; @@ -2247,8 +2245,9 @@ static grpc_error *deframe_unprocessed_incoming_frames( GPR_ASSERT(s->incoming_frames == NULL); if (s->incoming_frames != NULL) { s->stats.incoming.framing_bytes += (size_t)(end - cur); - grpc_slice_buffer_undo_take_first(&s->unprocessed_incoming_frames_buffer, - grpc_slice_sub(slice, (size_t)(cur - beg), (size_t)(end - beg))); + grpc_slice_buffer_undo_take_first( + &s->unprocessed_incoming_frames_buffer, + grpc_slice_sub(slice, (size_t)(cur - beg), (size_t)(end - beg))); return GRPC_ERROR_NONE; } p->frame_type = *cur; @@ -2314,9 +2313,8 @@ static grpc_error *deframe_unprocessed_incoming_frames( message_flags |= GRPC_WRITE_INTERNAL_COMPRESS; } GPR_ASSERT(s->incoming_frames == NULL); - p->parsing_frame = - grpc_chttp2_incoming_byte_stream_create( - exec_ctx, t, s, p->frame_size, message_flags); + p->parsing_frame = grpc_chttp2_incoming_byte_stream_create( + exec_ctx, t, s, p->frame_size, message_flags); /* fallthrough */ case GRPC_CHTTP2_DATA_FRAME: { if (slice_set) { @@ -2475,9 +2473,8 @@ static grpc_error *incoming_byte_stream_pull(grpc_exec_ctx *exec_ctx, gpr_mu_lock(&s->buffer_mu); if (s->unprocessed_incoming_frames_buffer.length > 0) { grpc_error *error = deframe_unprocessed_incoming_frames( - exec_ctx, &s->data_parser, t, s, - &s->unprocessed_incoming_frames_buffer, - slice, false); + exec_ctx, &s->data_parser, t, s, &s->unprocessed_incoming_frames_buffer, + slice, false); if (error != GRPC_ERROR_NONE) { gpr_mu_unlock(&s->buffer_mu); return error; @@ -2549,7 +2546,8 @@ static void incoming_byte_stream_publish_error( void grpc_chttp2_incoming_byte_stream_push(grpc_exec_ctx *exec_ctx, grpc_chttp2_incoming_byte_stream *bs, - grpc_slice slice, grpc_slice *slice_out) { + grpc_slice slice, + grpc_slice *slice_out) { if (bs->remaining_bytes < GRPC_SLICE_LENGTH(slice)) { incoming_byte_stream_publish_error( exec_ctx, bs, GRPC_ERROR_CREATE("Too many bytes in stream")); diff --git a/src/core/ext/transport/chttp2/transport/frame_data.c b/src/core/ext/transport/chttp2/transport/frame_data.c index e889e3527b..2c12b87141 100644 --- a/src/core/ext/transport/chttp2/transport/frame_data.c +++ b/src/core/ext/transport/chttp2/transport/frame_data.c @@ -141,10 +141,9 @@ void grpc_chttp2_encode_data(uint32_t id, grpc_slice_buffer *inbuf, stats->data_bytes += write_bytes; } -static void grpc_chttp2_unprocessed_frames_buffer_push(grpc_exec_ctx *exec_ctx, - grpc_chttp2_data_parser *p, - grpc_chttp2_stream *s, - grpc_slice slice) { +static void grpc_chttp2_unprocessed_frames_buffer_push( + grpc_exec_ctx *exec_ctx, grpc_chttp2_data_parser *p, grpc_chttp2_stream *s, + grpc_slice slice) { grpc_slice_buffer_add(&s->unprocessed_incoming_frames_buffer, slice); if (p->parsing_frame) { grpc_chttp2_incoming_byte_stream *bs = p->parsing_frame; @@ -179,10 +178,7 @@ grpc_error *parse_inner_buffer(grpc_exec_ctx *exec_ctx, if (s->unprocessed_incoming_frames_buffer.count > 0) { s->stats.incoming.framing_bytes += GRPC_SLICE_LENGTH(slice); grpc_slice_ref(slice); - grpc_chttp2_unprocessed_frames_buffer_push(exec_ctx, - p, - s, - slice); + grpc_chttp2_unprocessed_frames_buffer_push(exec_ctx, p, s, slice); gpr_mu_unlock(&s->buffer_mu); return GRPC_ERROR_NONE; } diff --git a/src/core/ext/transport/chttp2/transport/internal.h b/src/core/ext/transport/chttp2/transport/internal.h index 8d0f96efc6..3d6253cd6f 100644 --- a/src/core/ext/transport/chttp2/transport/internal.h +++ b/src/core/ext/transport/chttp2/transport/internal.h @@ -490,7 +490,8 @@ struct grpc_chttp2_stream { grpc_chttp2_incoming_metadata_buffer metadata_buffer[2]; grpc_chttp2_incoming_byte_stream *incoming_frames; - gpr_mu buffer_mu; /* protects unprocessed_incoming_frames_buffer and parse_data */ + gpr_mu buffer_mu; /* protects unprocessed_incoming_frames_buffer and + parse_data */ grpc_slice_buffer unprocessed_incoming_frames_buffer; gpr_timespec deadline; @@ -784,7 +785,8 @@ grpc_chttp2_incoming_byte_stream *grpc_chttp2_incoming_byte_stream_create( uint32_t frame_size, uint32_t flags); void grpc_chttp2_incoming_byte_stream_push(grpc_exec_ctx *exec_ctx, grpc_chttp2_incoming_byte_stream *bs, - grpc_slice slice, grpc_slice *slice_out); + grpc_slice slice, + grpc_slice *slice_out); void grpc_chttp2_incoming_byte_stream_finished( grpc_exec_ctx *exec_ctx, grpc_chttp2_incoming_byte_stream *bs, grpc_error *error); diff --git a/src/core/lib/transport/byte_stream.c b/src/core/lib/transport/byte_stream.c index afebf52cd5..3a50694670 100644 --- a/src/core/lib/transport/byte_stream.c +++ b/src/core/lib/transport/byte_stream.c @@ -47,7 +47,8 @@ int grpc_byte_stream_next(grpc_exec_ctx *exec_ctx, } grpc_error *grpc_byte_stream_pull(grpc_exec_ctx *exec_ctx, - grpc_byte_stream *byte_stream, grpc_slice *slice) { + grpc_byte_stream *byte_stream, + grpc_slice *slice) { return byte_stream->pull(exec_ctx, byte_stream, slice); } diff --git a/src/core/lib/transport/byte_stream.h b/src/core/lib/transport/byte_stream.h index 582480bb88..6afba92c52 100644 --- a/src/core/lib/transport/byte_stream.h +++ b/src/core/lib/transport/byte_stream.h @@ -52,8 +52,8 @@ struct grpc_byte_stream { int (*next)(grpc_exec_ctx *exec_ctx, grpc_byte_stream *byte_stream, grpc_slice *slice, size_t max_size_hint, grpc_closure *on_complete); - grpc_error* (*pull)(grpc_exec_ctx *exec_ctx, grpc_byte_stream *byte_stream, - grpc_slice *slice); + grpc_error *(*pull)(grpc_exec_ctx *exec_ctx, grpc_byte_stream *byte_stream, + grpc_slice *slice); void (*destroy)(grpc_exec_ctx *exec_ctx, grpc_byte_stream *byte_stream); }; @@ -71,7 +71,8 @@ int grpc_byte_stream_next(grpc_exec_ctx *exec_ctx, size_t max_size_hint, grpc_closure *on_complete); grpc_error *grpc_byte_stream_pull(grpc_exec_ctx *exec_ctx, - grpc_byte_stream *byte_stream, grpc_slice *slice); + grpc_byte_stream *byte_stream, + grpc_slice *slice); void grpc_byte_stream_destroy(grpc_exec_ctx *exec_ctx, grpc_byte_stream *byte_stream); -- cgit v1.2.3 From 9767a94a6a94ac8e1bb575f8cae44e52000ba0fc Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Sun, 26 Feb 2017 23:15:51 -0800 Subject: Stop nulling the parse_frame when stream is closed --- src/core/ext/transport/chttp2/transport/chttp2_transport.c | 5 ----- 1 file changed, 5 deletions(-) (limited to 'src/core/ext/transport') diff --git a/src/core/ext/transport/chttp2/transport/chttp2_transport.c b/src/core/ext/transport/chttp2/transport/chttp2_transport.c index b5e087d8f7..9cb66d7772 100644 --- a/src/core/ext/transport/chttp2/transport/chttp2_transport.c +++ b/src/core/ext/transport/chttp2/transport/chttp2_transport.c @@ -1597,11 +1597,6 @@ static void remove_stream(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t, t->incoming_stream = NULL; grpc_chttp2_parsing_become_skip_parser(exec_ctx, t); } - if (s->data_parser.parsing_frame != NULL) { - grpc_chttp2_incoming_byte_stream_finished( - exec_ctx, s->data_parser.parsing_frame, GRPC_ERROR_REF(error)); - s->data_parser.parsing_frame = NULL; - } if (grpc_chttp2_stream_map_size(&t->stream_map) == 0) { post_benign_reclaimer(exec_ctx, t); -- cgit v1.2.3 From 3989b88ffafd738d15ae1dbeee9107af95930d90 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Mon, 27 Feb 2017 08:26:49 -0800 Subject: sanity fix --- src/core/ext/transport/chttp2/transport/frame_data.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/core/ext/transport') diff --git a/src/core/ext/transport/chttp2/transport/frame_data.c b/src/core/ext/transport/chttp2/transport/frame_data.c index 2c12b87141..e134122802 100644 --- a/src/core/ext/transport/chttp2/transport/frame_data.c +++ b/src/core/ext/transport/chttp2/transport/frame_data.c @@ -177,7 +177,7 @@ grpc_error *parse_inner_buffer(grpc_exec_ctx *exec_ctx, gpr_mu_lock(&s->buffer_mu); if (s->unprocessed_incoming_frames_buffer.count > 0) { s->stats.incoming.framing_bytes += GRPC_SLICE_LENGTH(slice); - grpc_slice_ref(slice); + grpc_slice_ref_internal(exec_ctx, slice); grpc_chttp2_unprocessed_frames_buffer_push(exec_ctx, p, s, slice); gpr_mu_unlock(&s->buffer_mu); return GRPC_ERROR_NONE; -- cgit v1.2.3 From 146cf4b57f6266b834e8d0427a6b1177dfd6bc9b Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Mon, 27 Feb 2017 08:31:52 -0800 Subject: nit fix --- src/core/ext/transport/chttp2/transport/frame_data.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'src/core/ext/transport') diff --git a/src/core/ext/transport/chttp2/transport/frame_data.c b/src/core/ext/transport/chttp2/transport/frame_data.c index e134122802..aa2ccfdcec 100644 --- a/src/core/ext/transport/chttp2/transport/frame_data.c +++ b/src/core/ext/transport/chttp2/transport/frame_data.c @@ -43,6 +43,7 @@ #include "src/core/lib/slice/slice_string_helpers.h" #include "src/core/lib/support/string.h" #include "src/core/lib/transport/transport.h" +#include "src/core/lib/slice/slice_internal.h" grpc_error *grpc_chttp2_data_parser_init(grpc_chttp2_data_parser *parser) { parser->state = GRPC_CHTTP2_DATA_FH_0; @@ -177,7 +178,7 @@ grpc_error *parse_inner_buffer(grpc_exec_ctx *exec_ctx, gpr_mu_lock(&s->buffer_mu); if (s->unprocessed_incoming_frames_buffer.count > 0) { s->stats.incoming.framing_bytes += GRPC_SLICE_LENGTH(slice); - grpc_slice_ref_internal(exec_ctx, slice); + grpc_slice_ref_internal(slice); grpc_chttp2_unprocessed_frames_buffer_push(exec_ctx, p, s, slice); gpr_mu_unlock(&s->buffer_mu); return GRPC_ERROR_NONE; -- cgit v1.2.3 From cad4c809a3b5167ac0b6a944e68adcb0d0b513d6 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Mon, 27 Feb 2017 08:47:14 -0800 Subject: clang-format --- src/core/ext/transport/chttp2/transport/frame_data.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/core/ext/transport') diff --git a/src/core/ext/transport/chttp2/transport/frame_data.c b/src/core/ext/transport/chttp2/transport/frame_data.c index aa2ccfdcec..08b4b81bf8 100644 --- a/src/core/ext/transport/chttp2/transport/frame_data.c +++ b/src/core/ext/transport/chttp2/transport/frame_data.c @@ -40,10 +40,10 @@ #include #include #include "src/core/ext/transport/chttp2/transport/internal.h" +#include "src/core/lib/slice/slice_internal.h" #include "src/core/lib/slice/slice_string_helpers.h" #include "src/core/lib/support/string.h" #include "src/core/lib/transport/transport.h" -#include "src/core/lib/slice/slice_internal.h" grpc_error *grpc_chttp2_data_parser_init(grpc_chttp2_data_parser *parser) { parser->state = GRPC_CHTTP2_DATA_FH_0; -- cgit v1.2.3 From c9b538a43886c1f2bc3ff7f7943c49686ad06472 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Mon, 27 Feb 2017 12:26:33 -0800 Subject: Revert "Stop nulling the parse_frame when stream is closed" This reverts commit d3294286b3b90e1a01772d19bc476f579066d218. --- src/core/ext/transport/chttp2/transport/chttp2_transport.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'src/core/ext/transport') diff --git a/src/core/ext/transport/chttp2/transport/chttp2_transport.c b/src/core/ext/transport/chttp2/transport/chttp2_transport.c index 9cb66d7772..b5e087d8f7 100644 --- a/src/core/ext/transport/chttp2/transport/chttp2_transport.c +++ b/src/core/ext/transport/chttp2/transport/chttp2_transport.c @@ -1597,6 +1597,11 @@ static void remove_stream(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t, t->incoming_stream = NULL; grpc_chttp2_parsing_become_skip_parser(exec_ctx, t); } + if (s->data_parser.parsing_frame != NULL) { + grpc_chttp2_incoming_byte_stream_finished( + exec_ctx, s->data_parser.parsing_frame, GRPC_ERROR_REF(error)); + s->data_parser.parsing_frame = NULL; + } if (grpc_chttp2_stream_map_size(&t->stream_map) == 0) { post_benign_reclaimer(exec_ctx, t); -- cgit v1.2.3 From 6deb74968aba72e4a008bb4f717cc8fdf64039f4 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Mon, 27 Feb 2017 12:29:04 -0800 Subject: Stop nulling the parse_frame when stream is closed and there is no error --- src/core/ext/transport/chttp2/transport/chttp2_transport.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/core/ext/transport') diff --git a/src/core/ext/transport/chttp2/transport/chttp2_transport.c b/src/core/ext/transport/chttp2/transport/chttp2_transport.c index b5e087d8f7..6155335f81 100644 --- a/src/core/ext/transport/chttp2/transport/chttp2_transport.c +++ b/src/core/ext/transport/chttp2/transport/chttp2_transport.c @@ -1597,7 +1597,7 @@ static void remove_stream(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t, t->incoming_stream = NULL; grpc_chttp2_parsing_become_skip_parser(exec_ctx, t); } - if (s->data_parser.parsing_frame != NULL) { + if (error != GRPC_ERROR_NONE && s->data_parser.parsing_frame != NULL) { grpc_chttp2_incoming_byte_stream_finished( exec_ctx, s->data_parser.parsing_frame, GRPC_ERROR_REF(error)); s->data_parser.parsing_frame = NULL; -- cgit v1.2.3 From 532f2dd53e624bbc81f521f765df32e044ca1d78 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Mon, 27 Feb 2017 15:29:06 -0800 Subject: Protect with mutex and check for bs->error at incoming_stream_pull --- src/core/ext/transport/chttp2/transport/chttp2_transport.c | 14 ++++++++++++++ src/core/ext/transport/chttp2/transport/parsing.c | 2 ++ 2 files changed, 16 insertions(+) (limited to 'src/core/ext/transport') diff --git a/src/core/ext/transport/chttp2/transport/chttp2_transport.c b/src/core/ext/transport/chttp2/transport/chttp2_transport.c index 6155335f81..d99c0dc50c 100644 --- a/src/core/ext/transport/chttp2/transport/chttp2_transport.c +++ b/src/core/ext/transport/chttp2/transport/chttp2_transport.c @@ -595,7 +595,9 @@ static int init_stream(grpc_exec_ctx *exec_ctx, grpc_transport *gt, grpc_chttp2_incoming_metadata_buffer_init(&s->metadata_buffer[0]); grpc_chttp2_incoming_metadata_buffer_init(&s->metadata_buffer[1]); + gpr_mu_lock(&s->buffer_mu); grpc_chttp2_data_parser_init(&s->data_parser); + gpr_mu_unlock(&s->buffer_mu); grpc_slice_buffer_init(&s->flow_controlled_buffer); s->deadline = gpr_inf_future(GPR_CLOCK_MONOTONIC); grpc_closure_init(&s->complete_fetch_locked, complete_fetch_locked, s, @@ -657,7 +659,9 @@ static void destroy_stream_locked(grpc_exec_ctx *exec_ctx, void *sp, GPR_ASSERT(s->recv_initial_metadata_ready == NULL); GPR_ASSERT(s->recv_message_ready == NULL); GPR_ASSERT(s->recv_trailing_metadata_finished == NULL); + gpr_mu_lock(&s->buffer_mu); grpc_chttp2_data_parser_destroy(exec_ctx, &s->data_parser); + gpr_mu_unlock(&s->buffer_mu); grpc_chttp2_incoming_metadata_buffer_destroy(exec_ctx, &s->metadata_buffer[0]); grpc_chttp2_incoming_metadata_buffer_destroy(exec_ctx, @@ -1597,11 +1601,14 @@ static void remove_stream(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t, t->incoming_stream = NULL; grpc_chttp2_parsing_become_skip_parser(exec_ctx, t); } + gpr_mu_lock(&s->buffer_mu); if (error != GRPC_ERROR_NONE && s->data_parser.parsing_frame != NULL) { grpc_chttp2_incoming_byte_stream_finished( exec_ctx, s->data_parser.parsing_frame, GRPC_ERROR_REF(error)); + s->data_parser.parsing_frame = NULL; } + gpr_mu_unlock(&s->buffer_mu); if (grpc_chttp2_stream_map_size(&t->stream_map) == 0) { post_benign_reclaimer(exec_ctx, t); @@ -2324,6 +2331,10 @@ static grpc_error *deframe_unprocessed_incoming_frames( grpc_slice_unref_internal(exec_ctx, slice); return GRPC_ERROR_NONE; } + if (p->parsing_frame == NULL) { + + return GRPC_ERROR_NONE; + } uint32_t remaining = (uint32_t)(end - cur); if (cur == end) { grpc_slice_unref_internal(exec_ctx, slice); @@ -2470,6 +2481,9 @@ static grpc_error *incoming_byte_stream_pull(grpc_exec_ctx *exec_ctx, grpc_chttp2_stream *s = bs->stream; grpc_chttp2_transport *t = bs->transport; + if (bs->error) { + return bs->error; + } gpr_mu_lock(&s->buffer_mu); if (s->unprocessed_incoming_frames_buffer.length > 0) { grpc_error *error = deframe_unprocessed_incoming_frames( diff --git a/src/core/ext/transport/chttp2/transport/parsing.c b/src/core/ext/transport/chttp2/transport/parsing.c index f48de8ea25..29405994f0 100644 --- a/src/core/ext/transport/chttp2/transport/parsing.c +++ b/src/core/ext/transport/chttp2/transport/parsing.c @@ -435,8 +435,10 @@ static grpc_error *init_data_frame_parser(grpc_exec_ctx *exec_ctx, return init_skip_frame_parser(exec_ctx, t, 0); } if (err == GRPC_ERROR_NONE) { + gpr_mu_lock(&s->buffer_mu); err = grpc_chttp2_data_parser_begin_frame(&s->data_parser, t->incoming_frame_flags, s->id); + gpr_mu_unlock(&s->buffer_mu); } error_handler: if (err == GRPC_ERROR_NONE) { -- cgit v1.2.3 From d9d3c902d7ffcb5d3bda87a46a015cd0ba0752ef Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Mon, 27 Feb 2017 20:40:41 -0800 Subject: Clean up stream when there's no unprocessed frames --- src/core/ext/transport/chttp2/transport/chttp2_transport.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) (limited to 'src/core/ext/transport') diff --git a/src/core/ext/transport/chttp2/transport/chttp2_transport.c b/src/core/ext/transport/chttp2/transport/chttp2_transport.c index d99c0dc50c..d1f0a48391 100644 --- a/src/core/ext/transport/chttp2/transport/chttp2_transport.c +++ b/src/core/ext/transport/chttp2/transport/chttp2_transport.c @@ -1602,11 +1602,12 @@ static void remove_stream(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t, grpc_chttp2_parsing_become_skip_parser(exec_ctx, t); } gpr_mu_lock(&s->buffer_mu); - if (error != GRPC_ERROR_NONE && s->data_parser.parsing_frame != NULL) { - grpc_chttp2_incoming_byte_stream_finished( - exec_ctx, s->data_parser.parsing_frame, GRPC_ERROR_REF(error)); - - s->data_parser.parsing_frame = NULL; + if (s->data_parser.parsing_frame != NULL && + (error != GRPC_ERROR_NONE || + s->unprocessed_incoming_frames_buffer.length == 0)) { + grpc_chttp2_incoming_byte_stream_finished( + exec_ctx, s->data_parser.parsing_frame, GRPC_ERROR_REF(error)); + s->data_parser.parsing_frame = NULL; } gpr_mu_unlock(&s->buffer_mu); -- cgit v1.2.3 From 4ec9a1fadc0278aabbeaf18c2ea22aabbef00bcc Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Tue, 28 Feb 2017 14:35:46 -0800 Subject: Add grpc_chttp2_incoming_byte_stream_notify --- .../transport/chttp2/transport/chttp2_transport.c | 23 +++++++++++++++++----- .../ext/transport/chttp2/transport/frame_data.c | 1 + src/core/ext/transport/chttp2/transport/internal.h | 3 +++ 3 files changed, 22 insertions(+), 5 deletions(-) (limited to 'src/core/ext/transport') diff --git a/src/core/ext/transport/chttp2/transport/chttp2_transport.c b/src/core/ext/transport/chttp2/transport/chttp2_transport.c index d1f0a48391..6cfe473075 100644 --- a/src/core/ext/transport/chttp2/transport/chttp2_transport.c +++ b/src/core/ext/transport/chttp2/transport/chttp2_transport.c @@ -595,9 +595,7 @@ static int init_stream(grpc_exec_ctx *exec_ctx, grpc_transport *gt, grpc_chttp2_incoming_metadata_buffer_init(&s->metadata_buffer[0]); grpc_chttp2_incoming_metadata_buffer_init(&s->metadata_buffer[1]); - gpr_mu_lock(&s->buffer_mu); grpc_chttp2_data_parser_init(&s->data_parser); - gpr_mu_unlock(&s->buffer_mu); grpc_slice_buffer_init(&s->flow_controlled_buffer); s->deadline = gpr_inf_future(GPR_CLOCK_MONOTONIC); grpc_closure_init(&s->complete_fetch_locked, complete_fetch_locked, s, @@ -1602,12 +1600,16 @@ static void remove_stream(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t, grpc_chttp2_parsing_become_skip_parser(exec_ctx, t); } gpr_mu_lock(&s->buffer_mu); - if (s->data_parser.parsing_frame != NULL && - (error != GRPC_ERROR_NONE || - s->unprocessed_incoming_frames_buffer.length == 0)) { + if (s->data_parser.parsing_frame != NULL) { + gpr_mu_lock(&s->data_parser.parsing_frame->slice_mu); + if (error != GRPC_ERROR_NONE || + s->data_parser.parsing_frame->on_next) { + gpr_mu_unlock(&s->data_parser.parsing_frame->slice_mu); grpc_chttp2_incoming_byte_stream_finished( exec_ctx, s->data_parser.parsing_frame, GRPC_ERROR_REF(error)); + gpr_mu_unlock(&s->data_parser.parsing_frame->slice_mu); s->data_parser.parsing_frame = NULL; + } } gpr_mu_unlock(&s->buffer_mu); @@ -2572,6 +2574,17 @@ void grpc_chttp2_incoming_byte_stream_push(grpc_exec_ctx *exec_ctx, } } +void grpc_chttp2_incoming_byte_stream_notify(grpc_exec_ctx *exec_ctx, + grpc_chttp2_incoming_byte_stream *bs, + grpc_error *error) { + gpr_mu_lock(&bs->slice_mu); + if (bs->on_next) { + grpc_closure_sched(exec_ctx, bs->next_action.on_complete, error); + bs->on_next = NULL; + } + gpr_mu_unlock(&bs->slice_mu); +} + void grpc_chttp2_incoming_byte_stream_finished( grpc_exec_ctx *exec_ctx, grpc_chttp2_incoming_byte_stream *bs, grpc_error *error) { diff --git a/src/core/ext/transport/chttp2/transport/frame_data.c b/src/core/ext/transport/chttp2/transport/frame_data.c index 08b4b81bf8..a53241ad30 100644 --- a/src/core/ext/transport/chttp2/transport/frame_data.c +++ b/src/core/ext/transport/chttp2/transport/frame_data.c @@ -279,6 +279,7 @@ grpc_error *parse_inner_buffer(grpc_exec_ctx *exec_ctx, grpc_chttp2_unprocessed_frames_buffer_push( exec_ctx, p, s, grpc_slice_sub(slice, (size_t)(cur - beg), (size_t)(end - beg))); + grpc_chttp2_incoming_byte_stream_notify(exec_ctx, p->parsing_frame, GRPC_ERROR_NONE); gpr_mu_unlock(&s->buffer_mu); return GRPC_ERROR_NONE; } diff --git a/src/core/ext/transport/chttp2/transport/internal.h b/src/core/ext/transport/chttp2/transport/internal.h index 3d6253cd6f..a7ff26a42a 100644 --- a/src/core/ext/transport/chttp2/transport/internal.h +++ b/src/core/ext/transport/chttp2/transport/internal.h @@ -790,6 +790,9 @@ void grpc_chttp2_incoming_byte_stream_push(grpc_exec_ctx *exec_ctx, void grpc_chttp2_incoming_byte_stream_finished( grpc_exec_ctx *exec_ctx, grpc_chttp2_incoming_byte_stream *bs, grpc_error *error); +void grpc_chttp2_incoming_byte_stream_notify(grpc_exec_ctx *exec_ctx, + grpc_chttp2_incoming_byte_stream *bs, + grpc_error *error); void grpc_chttp2_ack_ping(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t, uint64_t id); -- cgit v1.2.3 From d106082c2f967386aa596e5f641b81bbc499eb51 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Tue, 28 Feb 2017 18:18:03 -0800 Subject: Nit --- src/core/ext/transport/chttp2/transport/chttp2_transport.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'src/core/ext/transport') diff --git a/src/core/ext/transport/chttp2/transport/chttp2_transport.c b/src/core/ext/transport/chttp2/transport/chttp2_transport.c index 6cfe473075..b842a889ba 100644 --- a/src/core/ext/transport/chttp2/transport/chttp2_transport.c +++ b/src/core/ext/transport/chttp2/transport/chttp2_transport.c @@ -1604,10 +1604,8 @@ static void remove_stream(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t, gpr_mu_lock(&s->data_parser.parsing_frame->slice_mu); if (error != GRPC_ERROR_NONE || s->data_parser.parsing_frame->on_next) { - gpr_mu_unlock(&s->data_parser.parsing_frame->slice_mu); grpc_chttp2_incoming_byte_stream_finished( exec_ctx, s->data_parser.parsing_frame, GRPC_ERROR_REF(error)); - gpr_mu_unlock(&s->data_parser.parsing_frame->slice_mu); s->data_parser.parsing_frame = NULL; } } -- cgit v1.2.3 From 369d5cce0222b911d491135c7b2db6044654d829 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Tue, 28 Feb 2017 18:20:19 -0800 Subject: nit --- src/core/ext/transport/chttp2/transport/chttp2_transport.c | 1 + 1 file changed, 1 insertion(+) (limited to 'src/core/ext/transport') diff --git a/src/core/ext/transport/chttp2/transport/chttp2_transport.c b/src/core/ext/transport/chttp2/transport/chttp2_transport.c index b842a889ba..56829900e1 100644 --- a/src/core/ext/transport/chttp2/transport/chttp2_transport.c +++ b/src/core/ext/transport/chttp2/transport/chttp2_transport.c @@ -1604,6 +1604,7 @@ static void remove_stream(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t, gpr_mu_lock(&s->data_parser.parsing_frame->slice_mu); if (error != GRPC_ERROR_NONE || s->data_parser.parsing_frame->on_next) { + gpr_mu_unlock(&s->data_parser.parsing_frame->slice_mu); grpc_chttp2_incoming_byte_stream_finished( exec_ctx, s->data_parser.parsing_frame, GRPC_ERROR_REF(error)); s->data_parser.parsing_frame = NULL; -- cgit v1.2.3 From 58500218452332a72ded0dee6273675e57839621 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Tue, 28 Feb 2017 19:08:00 -0800 Subject: nit --- src/core/ext/transport/chttp2/transport/chttp2_transport.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'src/core/ext/transport') diff --git a/src/core/ext/transport/chttp2/transport/chttp2_transport.c b/src/core/ext/transport/chttp2/transport/chttp2_transport.c index 56829900e1..436440d7b1 100644 --- a/src/core/ext/transport/chttp2/transport/chttp2_transport.c +++ b/src/core/ext/transport/chttp2/transport/chttp2_transport.c @@ -1602,9 +1602,9 @@ static void remove_stream(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t, gpr_mu_lock(&s->buffer_mu); if (s->data_parser.parsing_frame != NULL) { gpr_mu_lock(&s->data_parser.parsing_frame->slice_mu); - if (error != GRPC_ERROR_NONE || - s->data_parser.parsing_frame->on_next) { - gpr_mu_unlock(&s->data_parser.parsing_frame->slice_mu); + grpc_closure *next = s->data_parser.parsing_frame->on_next; + gpr_mu_unlock(&s->data_parser.parsing_frame->slice_mu); + if (error != GRPC_ERROR_NONE || next != NULL) { grpc_chttp2_incoming_byte_stream_finished( exec_ctx, s->data_parser.parsing_frame, GRPC_ERROR_REF(error)); s->data_parser.parsing_frame = NULL; -- cgit v1.2.3 From 59469c911d0434ae9355d78453869c351e98bfdc Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Thu, 2 Mar 2017 18:49:31 -0800 Subject: better handling of stream closure --- .../transport/chttp2/transport/chttp2_transport.c | 24 +++++++++++++++++----- src/core/ext/transport/chttp2/transport/internal.h | 1 + 2 files changed, 20 insertions(+), 5 deletions(-) (limited to 'src/core/ext/transport') diff --git a/src/core/ext/transport/chttp2/transport/chttp2_transport.c b/src/core/ext/transport/chttp2/transport/chttp2_transport.c index 436440d7b1..598dae40a0 100644 --- a/src/core/ext/transport/chttp2/transport/chttp2_transport.c +++ b/src/core/ext/transport/chttp2/transport/chttp2_transport.c @@ -1601,13 +1601,17 @@ static void remove_stream(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t, } gpr_mu_lock(&s->buffer_mu); if (s->data_parser.parsing_frame != NULL) { - gpr_mu_lock(&s->data_parser.parsing_frame->slice_mu); - grpc_closure *next = s->data_parser.parsing_frame->on_next; - gpr_mu_unlock(&s->data_parser.parsing_frame->slice_mu); - if (error != GRPC_ERROR_NONE || next != NULL) { + grpc_chttp2_incoming_byte_stream *bs = s->data_parser.parsing_frame; + gpr_mu_lock(&bs->slice_mu); + bs->push_closed = true; + if (bs->on_next != NULL) { + gpr_mu_unlock(&bs->slice_mu); grpc_chttp2_incoming_byte_stream_finished( - exec_ctx, s->data_parser.parsing_frame, GRPC_ERROR_REF(error)); + exec_ctx, s->data_parser.parsing_frame, GRPC_ERROR_REF(error)); s->data_parser.parsing_frame = NULL; + } else { + bs->error = GRPC_ERROR_REF(error); + gpr_mu_unlock(&bs->slice_mu); } } gpr_mu_unlock(&s->buffer_mu); @@ -2465,6 +2469,15 @@ static void incoming_byte_stream_next_locked(grpc_exec_ctx *exec_ctx, } else if (bs->error != GRPC_ERROR_NONE) { grpc_closure_sched(exec_ctx, bs->next_action.on_complete, GRPC_ERROR_REF(bs->error)); + } else if (bs->push_closed) { + if (bs->remaining_bytes != 0) { + grpc_closure_sched(exec_ctx, bs->next_action.on_complete, + GRPC_ERROR_CREATE("Truncated message")); + } else { + /* Should never reach here. */ + GPR_ASSERT(false); + grpc_closure_sched(exec_ctx, bs->next_action.on_complete, GRPC_ERROR_NONE); + } } else { bs->on_next = bs->next_action.on_complete; bs->next = bs->next_action.slice; @@ -2621,6 +2634,7 @@ grpc_chttp2_incoming_byte_stream *grpc_chttp2_incoming_byte_stream_create( incoming_byte_stream->on_next = NULL; incoming_byte_stream->is_tail = 1; incoming_byte_stream->error = GRPC_ERROR_NONE; + incoming_byte_stream->push_closed = false; s->incoming_frames = incoming_byte_stream; grpc_chttp2_maybe_complete_recv_message(exec_ctx, t, s); return incoming_byte_stream; diff --git a/src/core/ext/transport/chttp2/transport/internal.h b/src/core/ext/transport/chttp2/transport/internal.h index a7ff26a42a..5ec107c3f3 100644 --- a/src/core/ext/transport/chttp2/transport/internal.h +++ b/src/core/ext/transport/chttp2/transport/internal.h @@ -188,6 +188,7 @@ struct grpc_chttp2_incoming_byte_stream { gpr_refcount refs; struct grpc_chttp2_incoming_byte_stream *next_message; grpc_error *error; + bool push_closed; grpc_chttp2_transport *transport; grpc_chttp2_stream *stream; -- cgit v1.2.3 From dc1937472a3213ec0d624ed91e72abf470fd6dcc Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Fri, 3 Mar 2017 18:25:11 -0800 Subject: Fix python bug --- .../transport/chttp2/transport/chttp2_transport.c | 29 ++++++++++++++++------ 1 file changed, 22 insertions(+), 7 deletions(-) (limited to 'src/core/ext/transport') diff --git a/src/core/ext/transport/chttp2/transport/chttp2_transport.c b/src/core/ext/transport/chttp2/transport/chttp2_transport.c index 598dae40a0..eec21cf569 100644 --- a/src/core/ext/transport/chttp2/transport/chttp2_transport.c +++ b/src/core/ext/transport/chttp2/transport/chttp2_transport.c @@ -1339,6 +1339,11 @@ static void perform_stream_op_locked(grpc_exec_ctx *exec_ctx, void *stream_op, } else { gpr_mu_unlock(&s->buffer_mu); } + gpr_mu_lock(&s->buffer_mu); + if (s->incoming_frames == NULL && s->unprocessed_incoming_frames_buffer.count > 0) { + deframe_unprocessed_incoming_frames(exec_ctx, &s->data_parser, t, s, &s->unprocessed_incoming_frames_buffer, NULL, true); + } + gpr_mu_unlock(&s->buffer_mu); grpc_chttp2_maybe_complete_recv_message(exec_ctx, t, s); } @@ -1539,18 +1544,23 @@ void grpc_chttp2_maybe_complete_recv_message(grpc_exec_ctx *exec_ctx, exec_ctx, &s->unprocessed_incoming_frames_buffer); gpr_mu_unlock(&s->buffer_mu); } + gpr_mu_lock(&s->buffer_mu); if (s->incoming_frames != NULL) { *s->recv_message = &s->incoming_frames->base; s->incoming_frames = NULL; GPR_ASSERT(*s->recv_message != NULL); - null_then_run_closure(exec_ctx, &s->recv_message_ready, GRPC_ERROR_NONE); + grpc_closure_sched(exec_ctx, s->recv_message_ready, GRPC_ERROR_NONE); + s->recv_message_ready = NULL; } else if (error != GRPC_ERROR_NONE) { GPR_ASSERT(s->incoming_frames == NULL); - null_then_run_closure(exec_ctx, &s->recv_message_ready, error); + grpc_closure_sched(exec_ctx, s->recv_message_ready, error); + s->recv_message_ready = NULL; } else if (s->published_metadata[1] != GRPC_METADATA_NOT_PUBLISHED) { *s->recv_message = NULL; - null_then_run_closure(exec_ctx, &s->recv_message_ready, GRPC_ERROR_NONE); + grpc_closure_sched(exec_ctx, s->recv_message_ready, GRPC_ERROR_NONE); + s->recv_message_ready = NULL; } + gpr_mu_unlock(&s->buffer_mu); } } @@ -2330,6 +2340,15 @@ static grpc_error *deframe_unprocessed_incoming_frames( exec_ctx, t, s, p->frame_size, message_flags); /* fallthrough */ case GRPC_CHTTP2_DATA_FRAME: { + GPR_ASSERT(p->parsing_frame != NULL); + if (partial_deframe) { + if (cur != end) { + grpc_slice_buffer_undo_take_first(&s->unprocessed_incoming_frames_buffer, + grpc_slice_sub(slice, (size_t)(cur - beg), (size_t)(end - beg))); + } + grpc_slice_unref_internal(exec_ctx, slice); + return GRPC_ERROR_NONE; + } if (slice_set) { grpc_slice_buffer_undo_take_first( &s->unprocessed_incoming_frames_buffer, @@ -2337,10 +2356,6 @@ static grpc_error *deframe_unprocessed_incoming_frames( grpc_slice_unref_internal(exec_ctx, slice); return GRPC_ERROR_NONE; } - if (p->parsing_frame == NULL) { - - return GRPC_ERROR_NONE; - } uint32_t remaining = (uint32_t)(end - cur); if (cur == end) { grpc_slice_unref_internal(exec_ctx, slice); -- cgit v1.2.3 From 6f10b56649fe96859edda8c100256813db602fa9 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Fri, 3 Mar 2017 18:41:46 -0800 Subject: bug fix --- src/core/ext/transport/chttp2/transport/chttp2_transport.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'src/core/ext/transport') diff --git a/src/core/ext/transport/chttp2/transport/chttp2_transport.c b/src/core/ext/transport/chttp2/transport/chttp2_transport.c index eec21cf569..e221ef36a6 100644 --- a/src/core/ext/transport/chttp2/transport/chttp2_transport.c +++ b/src/core/ext/transport/chttp2/transport/chttp2_transport.c @@ -1544,7 +1544,6 @@ void grpc_chttp2_maybe_complete_recv_message(grpc_exec_ctx *exec_ctx, exec_ctx, &s->unprocessed_incoming_frames_buffer); gpr_mu_unlock(&s->buffer_mu); } - gpr_mu_lock(&s->buffer_mu); if (s->incoming_frames != NULL) { *s->recv_message = &s->incoming_frames->base; s->incoming_frames = NULL; @@ -1560,7 +1559,6 @@ void grpc_chttp2_maybe_complete_recv_message(grpc_exec_ctx *exec_ctx, grpc_closure_sched(exec_ctx, s->recv_message_ready, GRPC_ERROR_NONE); s->recv_message_ready = NULL; } - gpr_mu_unlock(&s->buffer_mu); } } -- cgit v1.2.3 From 15e23ecb74492637f9ef6fa9a262c63ad1d6f259 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Sat, 4 Mar 2017 15:01:24 -0800 Subject: Bug fix and clang-format --- src/core/ext/transport/chttp2/transport/frame_data.c | 10 ++++++++++ src/core/ext/transport/chttp2/transport/internal.h | 6 +++--- 2 files changed, 13 insertions(+), 3 deletions(-) (limited to 'src/core/ext/transport') diff --git a/src/core/ext/transport/chttp2/transport/frame_data.c b/src/core/ext/transport/chttp2/transport/frame_data.c index a53241ad30..cfa9a3d3c5 100644 --- a/src/core/ext/transport/chttp2/transport/frame_data.c +++ b/src/core/ext/transport/chttp2/transport/frame_data.c @@ -189,6 +189,7 @@ grpc_error *parse_inner_buffer(grpc_exec_ctx *exec_ctx, p->state = GRPC_CHTTP2_DATA_ERROR; gpr_mu_unlock(&s->buffer_mu); return GRPC_ERROR_REF(p->error); + fh_0: case GRPC_CHTTP2_DATA_FH_0: if (s->incoming_frames != NULL) { s->stats.incoming.framing_bytes += (size_t)(end - cur); @@ -270,6 +271,15 @@ grpc_error *parse_inner_buffer(grpc_exec_ctx *exec_ctx, exec_ctx, t, s, p->frame_size, message_flags); /* fallthrough */ case GRPC_CHTTP2_DATA_FRAME: + if (p->parsing_frame->remaining_bytes == 0) { + grpc_chttp2_incoming_byte_stream_finished(exec_ctx, p->parsing_frame, + GRPC_ERROR_NONE); + p->parsing_frame = NULL; + p->state = GRPC_CHTTP2_DATA_FH_0; + if (cur != end) { + goto fh_0; + } + } if (cur == end) { gpr_mu_unlock(&s->buffer_mu); return GRPC_ERROR_NONE; diff --git a/src/core/ext/transport/chttp2/transport/internal.h b/src/core/ext/transport/chttp2/transport/internal.h index 5ec107c3f3..54bfd42357 100644 --- a/src/core/ext/transport/chttp2/transport/internal.h +++ b/src/core/ext/transport/chttp2/transport/internal.h @@ -791,9 +791,9 @@ void grpc_chttp2_incoming_byte_stream_push(grpc_exec_ctx *exec_ctx, void grpc_chttp2_incoming_byte_stream_finished( grpc_exec_ctx *exec_ctx, grpc_chttp2_incoming_byte_stream *bs, grpc_error *error); -void grpc_chttp2_incoming_byte_stream_notify(grpc_exec_ctx *exec_ctx, - grpc_chttp2_incoming_byte_stream *bs, - grpc_error *error); +void grpc_chttp2_incoming_byte_stream_notify( + grpc_exec_ctx *exec_ctx, grpc_chttp2_incoming_byte_stream *bs, + grpc_error *error); void grpc_chttp2_ack_ping(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t, uint64_t id); -- cgit v1.2.3 From 8e6f3371b350030a5f656d1a94e008f30b37f898 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Sat, 4 Mar 2017 16:28:11 -0800 Subject: bug fix --- .../transport/chttp2/transport/chttp2_transport.c | 29 ++++++++++++---------- 1 file changed, 16 insertions(+), 13 deletions(-) (limited to 'src/core/ext/transport') diff --git a/src/core/ext/transport/chttp2/transport/chttp2_transport.c b/src/core/ext/transport/chttp2/transport/chttp2_transport.c index e221ef36a6..51bb47127f 100644 --- a/src/core/ext/transport/chttp2/transport/chttp2_transport.c +++ b/src/core/ext/transport/chttp2/transport/chttp2_transport.c @@ -2263,12 +2263,11 @@ static grpc_error *deframe_unprocessed_incoming_frames( return GRPC_ERROR_REF(p->error); fh_0: case GRPC_CHTTP2_DATA_FH_0: - GPR_ASSERT(s->incoming_frames == NULL); if (s->incoming_frames != NULL) { - s->stats.incoming.framing_bytes += (size_t)(end - cur); grpc_slice_buffer_undo_take_first( &s->unprocessed_incoming_frames_buffer, grpc_slice_sub(slice, (size_t)(cur - beg), (size_t)(end - beg))); + grpc_slice_unref_internal(exec_ctx, slice); return GRPC_ERROR_NONE; } p->frame_type = *cur; @@ -2339,7 +2338,7 @@ static grpc_error *deframe_unprocessed_incoming_frames( /* fallthrough */ case GRPC_CHTTP2_DATA_FRAME: { GPR_ASSERT(p->parsing_frame != NULL); - if (partial_deframe) { + if (partial_deframe && p->frame_size > 0) { if (cur != end) { grpc_slice_buffer_undo_take_first(&s->unprocessed_incoming_frames_buffer, grpc_slice_sub(slice, (size_t)(cur - beg), (size_t)(end - beg))); @@ -2347,6 +2346,10 @@ static grpc_error *deframe_unprocessed_incoming_frames( grpc_slice_unref_internal(exec_ctx, slice); return GRPC_ERROR_NONE; } + if (cur == end) { + grpc_slice_unref_internal(exec_ctx, slice); + continue; + } if (slice_set) { grpc_slice_buffer_undo_take_first( &s->unprocessed_incoming_frames_buffer, @@ -2355,10 +2358,6 @@ static grpc_error *deframe_unprocessed_incoming_frames( return GRPC_ERROR_NONE; } uint32_t remaining = (uint32_t)(end - cur); - if (cur == end) { - grpc_slice_unref_internal(exec_ctx, slice); - continue; - } if (remaining == p->frame_size) { grpc_chttp2_incoming_byte_stream_push( exec_ctx, p->parsing_frame, @@ -2382,11 +2381,13 @@ static grpc_error *deframe_unprocessed_incoming_frames( continue; } else { GPR_ASSERT(remaining > p->frame_size); - grpc_chttp2_incoming_byte_stream_push( - exec_ctx, p->parsing_frame, - grpc_slice_sub(slice, (size_t)(cur - beg), - (size_t)(cur + p->frame_size - beg)), - slice_out); + if (p->frame_size > 0) { + grpc_chttp2_incoming_byte_stream_push( + exec_ctx, p->parsing_frame, + grpc_slice_sub(slice, (size_t)(cur - beg), + (size_t)(cur + p->frame_size - beg)), + slice_out); + } slice_set = true; grpc_chttp2_incoming_byte_stream_finished(exec_ctx, p->parsing_frame, GRPC_ERROR_NONE); @@ -2595,7 +2596,9 @@ void grpc_chttp2_incoming_byte_stream_push(grpc_exec_ctx *exec_ctx, exec_ctx, bs, GRPC_ERROR_CREATE("Too many bytes in stream")); } else { bs->remaining_bytes -= (uint32_t)GRPC_SLICE_LENGTH(slice); - *slice_out = slice; + if (slice_out != NULL) { + *slice_out = slice; + } } } -- cgit v1.2.3 From e4f9eb4e6f9ecc6cd61c0fd7d2eaeea266709d94 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Sat, 4 Mar 2017 22:07:46 -0800 Subject: clang-format --- .../transport/chttp2/transport/chttp2_transport.c | 22 ++++++++++++++-------- .../ext/transport/chttp2/transport/frame_data.c | 3 ++- 2 files changed, 16 insertions(+), 9 deletions(-) (limited to 'src/core/ext/transport') diff --git a/src/core/ext/transport/chttp2/transport/chttp2_transport.c b/src/core/ext/transport/chttp2/transport/chttp2_transport.c index 51bb47127f..b1fa3595f2 100644 --- a/src/core/ext/transport/chttp2/transport/chttp2_transport.c +++ b/src/core/ext/transport/chttp2/transport/chttp2_transport.c @@ -1340,8 +1340,11 @@ static void perform_stream_op_locked(grpc_exec_ctx *exec_ctx, void *stream_op, gpr_mu_unlock(&s->buffer_mu); } gpr_mu_lock(&s->buffer_mu); - if (s->incoming_frames == NULL && s->unprocessed_incoming_frames_buffer.count > 0) { - deframe_unprocessed_incoming_frames(exec_ctx, &s->data_parser, t, s, &s->unprocessed_incoming_frames_buffer, NULL, true); + if (s->incoming_frames == NULL && + s->unprocessed_incoming_frames_buffer.count > 0) { + deframe_unprocessed_incoming_frames( + exec_ctx, &s->data_parser, t, s, + &s->unprocessed_incoming_frames_buffer, NULL, true); } gpr_mu_unlock(&s->buffer_mu); grpc_chttp2_maybe_complete_recv_message(exec_ctx, t, s); @@ -2340,8 +2343,10 @@ static grpc_error *deframe_unprocessed_incoming_frames( GPR_ASSERT(p->parsing_frame != NULL); if (partial_deframe && p->frame_size > 0) { if (cur != end) { - grpc_slice_buffer_undo_take_first(&s->unprocessed_incoming_frames_buffer, - grpc_slice_sub(slice, (size_t)(cur - beg), (size_t)(end - beg))); + grpc_slice_buffer_undo_take_first( + &s->unprocessed_incoming_frames_buffer, + grpc_slice_sub(slice, (size_t)(cur - beg), + (size_t)(end - beg))); } grpc_slice_unref_internal(exec_ctx, slice); return GRPC_ERROR_NONE; @@ -2490,7 +2495,8 @@ static void incoming_byte_stream_next_locked(grpc_exec_ctx *exec_ctx, } else { /* Should never reach here. */ GPR_ASSERT(false); - grpc_closure_sched(exec_ctx, bs->next_action.on_complete, GRPC_ERROR_NONE); + grpc_closure_sched(exec_ctx, bs->next_action.on_complete, + GRPC_ERROR_NONE); } } else { bs->on_next = bs->next_action.on_complete; @@ -2602,9 +2608,9 @@ void grpc_chttp2_incoming_byte_stream_push(grpc_exec_ctx *exec_ctx, } } -void grpc_chttp2_incoming_byte_stream_notify(grpc_exec_ctx *exec_ctx, - grpc_chttp2_incoming_byte_stream *bs, - grpc_error *error) { +void grpc_chttp2_incoming_byte_stream_notify( + grpc_exec_ctx *exec_ctx, grpc_chttp2_incoming_byte_stream *bs, + grpc_error *error) { gpr_mu_lock(&bs->slice_mu); if (bs->on_next) { grpc_closure_sched(exec_ctx, bs->next_action.on_complete, error); diff --git a/src/core/ext/transport/chttp2/transport/frame_data.c b/src/core/ext/transport/chttp2/transport/frame_data.c index cfa9a3d3c5..eed5c92376 100644 --- a/src/core/ext/transport/chttp2/transport/frame_data.c +++ b/src/core/ext/transport/chttp2/transport/frame_data.c @@ -289,7 +289,8 @@ grpc_error *parse_inner_buffer(grpc_exec_ctx *exec_ctx, grpc_chttp2_unprocessed_frames_buffer_push( exec_ctx, p, s, grpc_slice_sub(slice, (size_t)(cur - beg), (size_t)(end - beg))); - grpc_chttp2_incoming_byte_stream_notify(exec_ctx, p->parsing_frame, GRPC_ERROR_NONE); + grpc_chttp2_incoming_byte_stream_notify(exec_ctx, p->parsing_frame, + GRPC_ERROR_NONE); gpr_mu_unlock(&s->buffer_mu); return GRPC_ERROR_NONE; } -- cgit v1.2.3 From bd0a295b2a4f8a35c18330e3e83b6ae5537de4ea Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Sun, 5 Mar 2017 16:49:10 -0800 Subject: Destroy slice buffer bug --- src/core/ext/transport/chttp2/transport/chttp2_transport.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'src/core/ext/transport') diff --git a/src/core/ext/transport/chttp2/transport/chttp2_transport.c b/src/core/ext/transport/chttp2/transport/chttp2_transport.c index b1fa3595f2..9ec0bd02c2 100644 --- a/src/core/ext/transport/chttp2/transport/chttp2_transport.c +++ b/src/core/ext/transport/chttp2/transport/chttp2_transport.c @@ -630,15 +630,15 @@ static void destroy_stream_locked(grpc_exec_ctx *exec_ctx, void *sp, GPR_ASSERT(grpc_chttp2_stream_map_find(&t->stream_map, s->id) == NULL); } + gpr_mu_lock(&s->buffer_mu); + grpc_slice_buffer_destroy_internal(exec_ctx, + &s->unprocessed_incoming_frames_buffer); if (s->incoming_frames != NULL) { grpc_chttp2_incoming_byte_stream *ibs = s->incoming_frames; s->incoming_frames = NULL; incoming_byte_stream_destroy_locked(exec_ctx, &ibs->base, GRPC_ERROR_NONE); - gpr_mu_lock(&s->buffer_mu); - grpc_slice_buffer_destroy_internal(exec_ctx, - &s->unprocessed_incoming_frames_buffer); - gpr_mu_unlock(&s->buffer_mu); } + gpr_mu_unlock(&s->buffer_mu); grpc_chttp2_list_remove_stalled_by_transport(t, s); grpc_chttp2_list_remove_stalled_by_stream(t, s); -- cgit v1.2.3 From 24c131cbfd2201112df63d4f67dd9310a1ae671d Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Sun, 5 Mar 2017 19:54:52 -0800 Subject: Bug fix --- src/core/ext/transport/chttp2/transport/chttp2_transport.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'src/core/ext/transport') diff --git a/src/core/ext/transport/chttp2/transport/chttp2_transport.c b/src/core/ext/transport/chttp2/transport/chttp2_transport.c index 9ec0bd02c2..618d933647 100644 --- a/src/core/ext/transport/chttp2/transport/chttp2_transport.c +++ b/src/core/ext/transport/chttp2/transport/chttp2_transport.c @@ -1519,7 +1519,7 @@ void grpc_chttp2_maybe_complete_recv_initial_metadata(grpc_exec_ctx *exec_ctx, incoming_byte_stream_destroy_locked(exec_ctx, &ibs->base, GRPC_ERROR_NONE); gpr_mu_lock(&s->buffer_mu); - grpc_slice_buffer_destroy_internal( + grpc_slice_buffer_reset_and_unref_internal( exec_ctx, &s->unprocessed_incoming_frames_buffer); gpr_mu_unlock(&s->buffer_mu); } @@ -1543,7 +1543,7 @@ void grpc_chttp2_maybe_complete_recv_message(grpc_exec_ctx *exec_ctx, incoming_byte_stream_destroy_locked(exec_ctx, &ibs->base, GRPC_ERROR_NONE); gpr_mu_lock(&s->buffer_mu); - grpc_slice_buffer_destroy_internal( + grpc_slice_buffer_reset_and_unref_internal( exec_ctx, &s->unprocessed_incoming_frames_buffer); gpr_mu_unlock(&s->buffer_mu); } @@ -1578,7 +1578,7 @@ void grpc_chttp2_maybe_complete_recv_trailing_metadata(grpc_exec_ctx *exec_ctx, incoming_byte_stream_destroy_locked(exec_ctx, &ibs->base, GRPC_ERROR_NONE); gpr_mu_lock(&s->buffer_mu); - grpc_slice_buffer_destroy_internal( + grpc_slice_buffer_reset_and_unref_internal( exec_ctx, &s->unprocessed_incoming_frames_buffer); gpr_mu_unlock(&s->buffer_mu); } -- cgit v1.2.3 From a9af945817954a74e5ede427f0ff9248636672e4 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Thu, 9 Mar 2017 14:41:44 -0800 Subject: Fix python bug --- .../transport/chttp2/transport/chttp2_transport.c | 46 ++++++++++++++-------- 1 file changed, 30 insertions(+), 16 deletions(-) (limited to 'src/core/ext/transport') diff --git a/src/core/ext/transport/chttp2/transport/chttp2_transport.c b/src/core/ext/transport/chttp2/transport/chttp2_transport.c index 618d933647..b60f96e342 100644 --- a/src/core/ext/transport/chttp2/transport/chttp2_transport.c +++ b/src/core/ext/transport/chttp2/transport/chttp2_transport.c @@ -160,6 +160,9 @@ static grpc_error *deframe_unprocessed_incoming_frames( grpc_exec_ctx *exec_ctx, grpc_chttp2_data_parser *p, grpc_chttp2_transport *t, grpc_chttp2_stream *s, grpc_slice_buffer *slices, grpc_slice *slice_out, bool partial_deframe); +static void clean_unprocessed_frames_buffer(grpc_exec_ctx *exec_ctx, + grpc_chttp2_transport *t, + grpc_chttp2_stream *s); /******************************************************************************* * CONSTRUCTION/DESTRUCTION/REFCOUNTING @@ -630,15 +633,12 @@ static void destroy_stream_locked(grpc_exec_ctx *exec_ctx, void *sp, GPR_ASSERT(grpc_chttp2_stream_map_find(&t->stream_map, s->id) == NULL); } - gpr_mu_lock(&s->buffer_mu); - grpc_slice_buffer_destroy_internal(exec_ctx, - &s->unprocessed_incoming_frames_buffer); + clean_unprocessed_frames_buffer(exec_ctx, t, s); if (s->incoming_frames != NULL) { grpc_chttp2_incoming_byte_stream *ibs = s->incoming_frames; s->incoming_frames = NULL; incoming_byte_stream_destroy_locked(exec_ctx, &ibs->base, GRPC_ERROR_NONE); } - gpr_mu_unlock(&s->buffer_mu); grpc_chttp2_list_remove_stalled_by_transport(t, s); grpc_chttp2_list_remove_stalled_by_stream(t, s); @@ -1519,8 +1519,7 @@ void grpc_chttp2_maybe_complete_recv_initial_metadata(grpc_exec_ctx *exec_ctx, incoming_byte_stream_destroy_locked(exec_ctx, &ibs->base, GRPC_ERROR_NONE); gpr_mu_lock(&s->buffer_mu); - grpc_slice_buffer_reset_and_unref_internal( - exec_ctx, &s->unprocessed_incoming_frames_buffer); + clean_unprocessed_frames_buffer(exec_ctx, t, s); gpr_mu_unlock(&s->buffer_mu); } } @@ -1534,7 +1533,6 @@ void grpc_chttp2_maybe_complete_recv_initial_metadata(grpc_exec_ctx *exec_ctx, void grpc_chttp2_maybe_complete_recv_message(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t, grpc_chttp2_stream *s) { - grpc_error *error = GRPC_ERROR_NONE; if (s->recv_message_ready != NULL) { if (s->final_metadata_requested && s->seen_error && s->incoming_frames != NULL) { @@ -1543,8 +1541,7 @@ void grpc_chttp2_maybe_complete_recv_message(grpc_exec_ctx *exec_ctx, incoming_byte_stream_destroy_locked(exec_ctx, &ibs->base, GRPC_ERROR_NONE); gpr_mu_lock(&s->buffer_mu); - grpc_slice_buffer_reset_and_unref_internal( - exec_ctx, &s->unprocessed_incoming_frames_buffer); + clean_unprocessed_frames_buffer(exec_ctx, t, s); gpr_mu_unlock(&s->buffer_mu); } if (s->incoming_frames != NULL) { @@ -1553,10 +1550,6 @@ void grpc_chttp2_maybe_complete_recv_message(grpc_exec_ctx *exec_ctx, GPR_ASSERT(*s->recv_message != NULL); grpc_closure_sched(exec_ctx, s->recv_message_ready, GRPC_ERROR_NONE); s->recv_message_ready = NULL; - } else if (error != GRPC_ERROR_NONE) { - GPR_ASSERT(s->incoming_frames == NULL); - grpc_closure_sched(exec_ctx, s->recv_message_ready, error); - s->recv_message_ready = NULL; } else if (s->published_metadata[1] != GRPC_METADATA_NOT_PUBLISHED) { *s->recv_message = NULL; grpc_closure_sched(exec_ctx, s->recv_message_ready, GRPC_ERROR_NONE); @@ -1578,8 +1571,7 @@ void grpc_chttp2_maybe_complete_recv_trailing_metadata(grpc_exec_ctx *exec_ctx, incoming_byte_stream_destroy_locked(exec_ctx, &ibs->base, GRPC_ERROR_NONE); gpr_mu_lock(&s->buffer_mu); - grpc_slice_buffer_reset_and_unref_internal( - exec_ctx, &s->unprocessed_incoming_frames_buffer); + clean_unprocessed_frames_buffer(exec_ctx, t, s); gpr_mu_unlock(&s->buffer_mu); } } @@ -1597,11 +1589,33 @@ void grpc_chttp2_maybe_complete_recv_trailing_metadata(grpc_exec_ctx *exec_ctx, static void decrement_active_streams_locked(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t, grpc_chttp2_stream *s) { - if ((s->all_incoming_byte_streams_finished = gpr_unref(&s->active_streams))) { + gpr_mu_lock(&s->buffer_mu); + if ((s->all_incoming_byte_streams_finished = (gpr_unref(&s->active_streams) && + s->unprocessed_incoming_frames_buffer.length == 0))) { + gpr_mu_unlock(&s->buffer_mu); grpc_chttp2_maybe_complete_recv_trailing_metadata(exec_ctx, t, s); + } else { + gpr_mu_unlock(&s->buffer_mu); } } +static void clean_unprocessed_frames_buffer(grpc_exec_ctx *exec_ctx, + grpc_chttp2_transport *t, + grpc_chttp2_stream *s) { + gpr_mu_lock(&s->buffer_mu); + grpc_slice_buffer_destroy_internal(exec_ctx, + &s->unprocessed_incoming_frames_buffer); + // TODO (mxyan): add get ref count in sync.c? + gpr_atm active_streams = gpr_atm_no_barrier_fetch_add(&s->active_streams.count, 0); + if ((s->all_incoming_byte_streams_finished = + (active_streams == 0))) { + gpr_mu_unlock(&s->buffer_mu); + grpc_chttp2_maybe_complete_recv_trailing_metadata(exec_ctx, t, s); + } else { + gpr_mu_unlock(&s->buffer_mu); + } +} + static void remove_stream(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t, uint32_t id, grpc_error *error) { grpc_chttp2_stream *s = grpc_chttp2_stream_map_delete(&t->stream_map, id); -- cgit v1.2.3 From d54b9e929c85dd02bb883285b801ad90cfd3044b Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Thu, 9 Mar 2017 17:45:37 -0800 Subject: Minor fix --- src/core/ext/transport/chttp2/transport/chttp2_transport.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/core/ext/transport') diff --git a/src/core/ext/transport/chttp2/transport/chttp2_transport.c b/src/core/ext/transport/chttp2/transport/chttp2_transport.c index b60f96e342..da8131c1a2 100644 --- a/src/core/ext/transport/chttp2/transport/chttp2_transport.c +++ b/src/core/ext/transport/chttp2/transport/chttp2_transport.c @@ -1603,8 +1603,8 @@ static void clean_unprocessed_frames_buffer(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t, grpc_chttp2_stream *s) { gpr_mu_lock(&s->buffer_mu); - grpc_slice_buffer_destroy_internal(exec_ctx, - &s->unprocessed_incoming_frames_buffer); + grpc_slice_buffer_reset_and_unref_internal(exec_ctx, + &s->unprocessed_incoming_frames_buffer); // TODO (mxyan): add get ref count in sync.c? gpr_atm active_streams = gpr_atm_no_barrier_fetch_add(&s->active_streams.count, 0); if ((s->all_incoming_byte_streams_finished = -- cgit v1.2.3 From 19cd0f3679dc2fae3c6997eb061afa2812fb0aac Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Thu, 9 Mar 2017 21:33:40 -0800 Subject: Bug fix --- .../transport/chttp2/transport/chttp2_transport.c | 25 +++++++++++----------- 1 file changed, 13 insertions(+), 12 deletions(-) (limited to 'src/core/ext/transport') diff --git a/src/core/ext/transport/chttp2/transport/chttp2_transport.c b/src/core/ext/transport/chttp2/transport/chttp2_transport.c index da8131c1a2..cb04c30a08 100644 --- a/src/core/ext/transport/chttp2/transport/chttp2_transport.c +++ b/src/core/ext/transport/chttp2/transport/chttp2_transport.c @@ -1518,10 +1518,10 @@ void grpc_chttp2_maybe_complete_recv_initial_metadata(grpc_exec_ctx *exec_ctx, s->incoming_frames = NULL; incoming_byte_stream_destroy_locked(exec_ctx, &ibs->base, GRPC_ERROR_NONE); - gpr_mu_lock(&s->buffer_mu); - clean_unprocessed_frames_buffer(exec_ctx, t, s); - gpr_mu_unlock(&s->buffer_mu); } + gpr_mu_lock(&s->buffer_mu); + clean_unprocessed_frames_buffer(exec_ctx, t, s); + gpr_mu_unlock(&s->buffer_mu); } grpc_chttp2_incoming_metadata_buffer_publish( exec_ctx, &s->metadata_buffer[0], s->recv_initial_metadata); @@ -1534,12 +1534,13 @@ void grpc_chttp2_maybe_complete_recv_message(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t, grpc_chttp2_stream *s) { if (s->recv_message_ready != NULL) { - if (s->final_metadata_requested && s->seen_error && - s->incoming_frames != NULL) { - grpc_chttp2_incoming_byte_stream *ibs = s->incoming_frames; - s->incoming_frames = NULL; - incoming_byte_stream_destroy_locked(exec_ctx, &ibs->base, - GRPC_ERROR_NONE); + if (s->final_metadata_requested && s->seen_error) { + if(s->incoming_frames != NULL) { + grpc_chttp2_incoming_byte_stream *ibs = s->incoming_frames; + s->incoming_frames = NULL; + incoming_byte_stream_destroy_locked(exec_ctx, &ibs->base, + GRPC_ERROR_NONE); + } gpr_mu_lock(&s->buffer_mu); clean_unprocessed_frames_buffer(exec_ctx, t, s); gpr_mu_unlock(&s->buffer_mu); @@ -1570,10 +1571,10 @@ void grpc_chttp2_maybe_complete_recv_trailing_metadata(grpc_exec_ctx *exec_ctx, s->incoming_frames = NULL; incoming_byte_stream_destroy_locked(exec_ctx, &ibs->base, GRPC_ERROR_NONE); - gpr_mu_lock(&s->buffer_mu); - clean_unprocessed_frames_buffer(exec_ctx, t, s); - gpr_mu_unlock(&s->buffer_mu); } + gpr_mu_lock(&s->buffer_mu); + clean_unprocessed_frames_buffer(exec_ctx, t, s); + gpr_mu_unlock(&s->buffer_mu); } if (s->all_incoming_byte_streams_finished && s->recv_trailing_metadata_finished != NULL) { -- cgit v1.2.3 From bdcdf31fb92011afc7d3642d81dd7cabccfa4f7e Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Thu, 9 Mar 2017 22:13:59 -0800 Subject: Bug fix --- .../transport/chttp2/transport/chttp2_transport.c | 30 ++++++++++++++-------- 1 file changed, 20 insertions(+), 10 deletions(-) (limited to 'src/core/ext/transport') diff --git a/src/core/ext/transport/chttp2/transport/chttp2_transport.c b/src/core/ext/transport/chttp2/transport/chttp2_transport.c index cb04c30a08..5237a78cfc 100644 --- a/src/core/ext/transport/chttp2/transport/chttp2_transport.c +++ b/src/core/ext/transport/chttp2/transport/chttp2_transport.c @@ -1519,9 +1519,13 @@ void grpc_chttp2_maybe_complete_recv_initial_metadata(grpc_exec_ctx *exec_ctx, incoming_byte_stream_destroy_locked(exec_ctx, &ibs->base, GRPC_ERROR_NONE); } + size_t length; gpr_mu_lock(&s->buffer_mu); - clean_unprocessed_frames_buffer(exec_ctx, t, s); + length = s->unprocessed_incoming_frames_buffer.length; gpr_mu_unlock(&s->buffer_mu); + if (length > 0) { + clean_unprocessed_frames_buffer(exec_ctx, t, s); + } } grpc_chttp2_incoming_metadata_buffer_publish( exec_ctx, &s->metadata_buffer[0], s->recv_initial_metadata); @@ -1541,9 +1545,13 @@ void grpc_chttp2_maybe_complete_recv_message(grpc_exec_ctx *exec_ctx, incoming_byte_stream_destroy_locked(exec_ctx, &ibs->base, GRPC_ERROR_NONE); } + size_t length; gpr_mu_lock(&s->buffer_mu); - clean_unprocessed_frames_buffer(exec_ctx, t, s); + length = s->unprocessed_incoming_frames_buffer.length; gpr_mu_unlock(&s->buffer_mu); + if (length > 0) { + clean_unprocessed_frames_buffer(exec_ctx, t, s); + } } if (s->incoming_frames != NULL) { *s->recv_message = &s->incoming_frames->base; @@ -1572,9 +1580,13 @@ void grpc_chttp2_maybe_complete_recv_trailing_metadata(grpc_exec_ctx *exec_ctx, incoming_byte_stream_destroy_locked(exec_ctx, &ibs->base, GRPC_ERROR_NONE); } + size_t length; gpr_mu_lock(&s->buffer_mu); - clean_unprocessed_frames_buffer(exec_ctx, t, s); + length = s->unprocessed_incoming_frames_buffer.length; gpr_mu_unlock(&s->buffer_mu); + if (length > 0) { + clean_unprocessed_frames_buffer(exec_ctx, t, s); + } } if (s->all_incoming_byte_streams_finished && s->recv_trailing_metadata_finished != NULL) { @@ -1590,13 +1602,13 @@ void grpc_chttp2_maybe_complete_recv_trailing_metadata(grpc_exec_ctx *exec_ctx, static void decrement_active_streams_locked(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t, grpc_chttp2_stream *s) { + size_t length; gpr_mu_lock(&s->buffer_mu); + length = s->unprocessed_incoming_frames_buffer.length; + gpr_mu_unlock(&s->buffer_mu); if ((s->all_incoming_byte_streams_finished = (gpr_unref(&s->active_streams) && - s->unprocessed_incoming_frames_buffer.length == 0))) { - gpr_mu_unlock(&s->buffer_mu); + length == 0))) { grpc_chttp2_maybe_complete_recv_trailing_metadata(exec_ctx, t, s); - } else { - gpr_mu_unlock(&s->buffer_mu); } } @@ -1606,14 +1618,12 @@ static void clean_unprocessed_frames_buffer(grpc_exec_ctx *exec_ctx, gpr_mu_lock(&s->buffer_mu); grpc_slice_buffer_reset_and_unref_internal(exec_ctx, &s->unprocessed_incoming_frames_buffer); + gpr_mu_unlock(&s->buffer_mu); // TODO (mxyan): add get ref count in sync.c? gpr_atm active_streams = gpr_atm_no_barrier_fetch_add(&s->active_streams.count, 0); if ((s->all_incoming_byte_streams_finished = (active_streams == 0))) { - gpr_mu_unlock(&s->buffer_mu); grpc_chttp2_maybe_complete_recv_trailing_metadata(exec_ctx, t, s); - } else { - gpr_mu_unlock(&s->buffer_mu); } } -- cgit v1.2.3 From 6f2e6e68be4aef872342e6e6451c1b74d2a61d9e Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Fri, 10 Mar 2017 09:27:50 -0800 Subject: clang-format --- .../transport/chttp2/transport/chttp2_transport.c | 48 ++++++++++++---------- 1 file changed, 26 insertions(+), 22 deletions(-) (limited to 'src/core/ext/transport') diff --git a/src/core/ext/transport/chttp2/transport/chttp2_transport.c b/src/core/ext/transport/chttp2/transport/chttp2_transport.c index 5237a78cfc..edcb243c37 100644 --- a/src/core/ext/transport/chttp2/transport/chttp2_transport.c +++ b/src/core/ext/transport/chttp2/transport/chttp2_transport.c @@ -509,10 +509,11 @@ static void destroy_transport_locked(grpc_exec_ctx *exec_ctx, void *tp, static void destroy_transport(grpc_exec_ctx *exec_ctx, grpc_transport *gt) { grpc_chttp2_transport *t = (grpc_chttp2_transport *)gt; - grpc_closure_sched(exec_ctx, grpc_closure_create( - destroy_transport_locked, t, - grpc_combiner_scheduler(t->combiner, false)), - GRPC_ERROR_NONE); + grpc_closure_sched( + exec_ctx, + grpc_closure_create(destroy_transport_locked, t, + grpc_combiner_scheduler(t->combiner, false)), + GRPC_ERROR_NONE); } static void close_transport_locked(grpc_exec_ctx *exec_ctx, @@ -691,8 +692,9 @@ static void destroy_stream(grpc_exec_ctx *exec_ctx, grpc_transport *gt, s->destroy_stream_arg = and_free_memory; grpc_closure_sched( - exec_ctx, grpc_closure_init(&s->destroy_stream, destroy_stream_locked, s, - grpc_combiner_scheduler(t->combiner, false)), + exec_ctx, + grpc_closure_init(&s->destroy_stream, destroy_stream_locked, s, + grpc_combiner_scheduler(t->combiner, false)), GRPC_ERROR_NONE); GPR_TIMER_END("destroy_stream", 0); } @@ -1497,9 +1499,10 @@ static void perform_transport_op(grpc_exec_ctx *exec_ctx, grpc_transport *gt, op->transport_private.args[0] = gt; GRPC_CHTTP2_REF_TRANSPORT(t, "transport_op"); grpc_closure_sched( - exec_ctx, grpc_closure_init(&op->transport_private.closure, - perform_transport_op_locked, op, - grpc_combiner_scheduler(t->combiner, false)), + exec_ctx, + grpc_closure_init(&op->transport_private.closure, + perform_transport_op_locked, op, + grpc_combiner_scheduler(t->combiner, false)), GRPC_ERROR_NONE); } @@ -1539,7 +1542,7 @@ void grpc_chttp2_maybe_complete_recv_message(grpc_exec_ctx *exec_ctx, grpc_chttp2_stream *s) { if (s->recv_message_ready != NULL) { if (s->final_metadata_requested && s->seen_error) { - if(s->incoming_frames != NULL) { + if (s->incoming_frames != NULL) { grpc_chttp2_incoming_byte_stream *ibs = s->incoming_frames; s->incoming_frames = NULL; incoming_byte_stream_destroy_locked(exec_ctx, &ibs->base, @@ -1606,8 +1609,8 @@ static void decrement_active_streams_locked(grpc_exec_ctx *exec_ctx, gpr_mu_lock(&s->buffer_mu); length = s->unprocessed_incoming_frames_buffer.length; gpr_mu_unlock(&s->buffer_mu); - if ((s->all_incoming_byte_streams_finished = (gpr_unref(&s->active_streams) && - length == 0))) { + if ((s->all_incoming_byte_streams_finished = + (gpr_unref(&s->active_streams) && length == 0))) { grpc_chttp2_maybe_complete_recv_trailing_metadata(exec_ctx, t, s); } } @@ -1616,15 +1619,15 @@ static void clean_unprocessed_frames_buffer(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t, grpc_chttp2_stream *s) { gpr_mu_lock(&s->buffer_mu); - grpc_slice_buffer_reset_and_unref_internal(exec_ctx, - &s->unprocessed_incoming_frames_buffer); + grpc_slice_buffer_reset_and_unref_internal( + exec_ctx, &s->unprocessed_incoming_frames_buffer); gpr_mu_unlock(&s->buffer_mu); // TODO (mxyan): add get ref count in sync.c? - gpr_atm active_streams = gpr_atm_no_barrier_fetch_add(&s->active_streams.count, 0); - if ((s->all_incoming_byte_streams_finished = - (active_streams == 0))) { - grpc_chttp2_maybe_complete_recv_trailing_metadata(exec_ctx, t, s); - } + gpr_atm active_streams = + gpr_atm_no_barrier_fetch_add(&s->active_streams.count, 0); + if ((s->all_incoming_byte_streams_finished = (active_streams == 0))) { + grpc_chttp2_maybe_complete_recv_trailing_metadata(exec_ctx, t, s); + } } static void remove_stream(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t, @@ -2754,9 +2757,10 @@ static void destructive_reclaimer_locked(grpc_exec_ctx *exec_ctx, void *arg, s->id); } grpc_chttp2_cancel_stream( - exec_ctx, t, s, grpc_error_set_int(GRPC_ERROR_CREATE("Buffers full"), - GRPC_ERROR_INT_HTTP2_ERROR, - GRPC_HTTP2_ENHANCE_YOUR_CALM)); + exec_ctx, t, s, + grpc_error_set_int(GRPC_ERROR_CREATE("Buffers full"), + GRPC_ERROR_INT_HTTP2_ERROR, + GRPC_HTTP2_ENHANCE_YOUR_CALM)); if (n > 1) { /* Since we cancel one stream per destructive reclamation, if there are more streams left, we can immediately post a new -- cgit v1.2.3 From 0901b168f391858ff44ea3c724a5b5fdeb18ea93 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Fri, 10 Mar 2017 11:24:09 -0800 Subject: Bug fix --- src/core/ext/transport/chttp2/transport/chttp2_transport.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'src/core/ext/transport') diff --git a/src/core/ext/transport/chttp2/transport/chttp2_transport.c b/src/core/ext/transport/chttp2/transport/chttp2_transport.c index edcb243c37..83b27a49aa 100644 --- a/src/core/ext/transport/chttp2/transport/chttp2_transport.c +++ b/src/core/ext/transport/chttp2/transport/chttp2_transport.c @@ -634,7 +634,8 @@ static void destroy_stream_locked(grpc_exec_ctx *exec_ctx, void *sp, GPR_ASSERT(grpc_chttp2_stream_map_find(&t->stream_map, s->id) == NULL); } - clean_unprocessed_frames_buffer(exec_ctx, t, s); + grpc_slice_buffer_destroy_internal(exec_ctx, + &s->unprocessed_incoming_frames_buffer); if (s->incoming_frames != NULL) { grpc_chttp2_incoming_byte_stream *ibs = s->incoming_frames; s->incoming_frames = NULL; -- cgit v1.2.3 From 408f36bf286928f069ef256577736a655c38e9d1 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Sun, 19 Mar 2017 00:25:22 -0700 Subject: Bug fix --- src/core/ext/transport/chttp2/transport/chttp2_transport.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) (limited to 'src/core/ext/transport') diff --git a/src/core/ext/transport/chttp2/transport/chttp2_transport.c b/src/core/ext/transport/chttp2/transport/chttp2_transport.c index 83b27a49aa..79aa05e212 100644 --- a/src/core/ext/transport/chttp2/transport/chttp2_transport.c +++ b/src/core/ext/transport/chttp2/transport/chttp2_transport.c @@ -1646,15 +1646,18 @@ static void remove_stream(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t, bs->push_closed = true; if (bs->on_next != NULL) { gpr_mu_unlock(&bs->slice_mu); + gpr_mu_unlock(&s->buffer_mu); grpc_chttp2_incoming_byte_stream_finished( exec_ctx, s->data_parser.parsing_frame, GRPC_ERROR_REF(error)); s->data_parser.parsing_frame = NULL; } else { bs->error = GRPC_ERROR_REF(error); gpr_mu_unlock(&bs->slice_mu); + gpr_mu_unlock(&s->buffer_mu); } + } else { + gpr_mu_unlock(&s->buffer_mu); } - gpr_mu_unlock(&s->buffer_mu); if (grpc_chttp2_stream_map_size(&t->stream_map) == 0) { post_benign_reclaimer(exec_ctx, t); @@ -2519,8 +2522,9 @@ static void incoming_byte_stream_next_locked(grpc_exec_ctx *exec_ctx, GRPC_ERROR_REF(bs->error)); } else if (bs->push_closed) { if (bs->remaining_bytes != 0) { + bs->error = GRPC_ERROR_CREATE("Truncated message"); grpc_closure_sched(exec_ctx, bs->next_action.on_complete, - GRPC_ERROR_CREATE("Truncated message")); + GRPC_ERROR_REF(bs->error)); } else { /* Should never reach here. */ GPR_ASSERT(false); @@ -2557,6 +2561,10 @@ static grpc_error *incoming_byte_stream_pull(grpc_exec_ctx *exec_ctx, gpr_mu_unlock(&s->buffer_mu); return error; } + } else { + bs->error = GRPC_ERROR_CREATE("Truncated message"); + gpr_mu_unlock(&s->buffer_mu); + return bs->error; } gpr_mu_unlock(&s->buffer_mu); GPR_TIMER_END("incoming_byte_stream_pull", 0); -- cgit v1.2.3 From 1f9fd13a15f97d6e3d1a93d942d3a44bd9526471 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Sun, 19 Mar 2017 10:39:09 -0700 Subject: clang-format --- .../transport/chttp2/transport/chttp2_transport.c | 28 ++++++++++------------ 1 file changed, 12 insertions(+), 16 deletions(-) (limited to 'src/core/ext/transport') diff --git a/src/core/ext/transport/chttp2/transport/chttp2_transport.c b/src/core/ext/transport/chttp2/transport/chttp2_transport.c index 79aa05e212..a8962d305d 100644 --- a/src/core/ext/transport/chttp2/transport/chttp2_transport.c +++ b/src/core/ext/transport/chttp2/transport/chttp2_transport.c @@ -509,11 +509,10 @@ static void destroy_transport_locked(grpc_exec_ctx *exec_ctx, void *tp, static void destroy_transport(grpc_exec_ctx *exec_ctx, grpc_transport *gt) { grpc_chttp2_transport *t = (grpc_chttp2_transport *)gt; - grpc_closure_sched( - exec_ctx, - grpc_closure_create(destroy_transport_locked, t, - grpc_combiner_scheduler(t->combiner, false)), - GRPC_ERROR_NONE); + grpc_closure_sched(exec_ctx, grpc_closure_create( + destroy_transport_locked, t, + grpc_combiner_scheduler(t->combiner, false)), + GRPC_ERROR_NONE); } static void close_transport_locked(grpc_exec_ctx *exec_ctx, @@ -693,9 +692,8 @@ static void destroy_stream(grpc_exec_ctx *exec_ctx, grpc_transport *gt, s->destroy_stream_arg = and_free_memory; grpc_closure_sched( - exec_ctx, - grpc_closure_init(&s->destroy_stream, destroy_stream_locked, s, - grpc_combiner_scheduler(t->combiner, false)), + exec_ctx, grpc_closure_init(&s->destroy_stream, destroy_stream_locked, s, + grpc_combiner_scheduler(t->combiner, false)), GRPC_ERROR_NONE); GPR_TIMER_END("destroy_stream", 0); } @@ -1500,10 +1498,9 @@ static void perform_transport_op(grpc_exec_ctx *exec_ctx, grpc_transport *gt, op->transport_private.args[0] = gt; GRPC_CHTTP2_REF_TRANSPORT(t, "transport_op"); grpc_closure_sched( - exec_ctx, - grpc_closure_init(&op->transport_private.closure, - perform_transport_op_locked, op, - grpc_combiner_scheduler(t->combiner, false)), + exec_ctx, grpc_closure_init(&op->transport_private.closure, + perform_transport_op_locked, op, + grpc_combiner_scheduler(t->combiner, false)), GRPC_ERROR_NONE); } @@ -2766,10 +2763,9 @@ static void destructive_reclaimer_locked(grpc_exec_ctx *exec_ctx, void *arg, s->id); } grpc_chttp2_cancel_stream( - exec_ctx, t, s, - grpc_error_set_int(GRPC_ERROR_CREATE("Buffers full"), - GRPC_ERROR_INT_HTTP2_ERROR, - GRPC_HTTP2_ENHANCE_YOUR_CALM)); + exec_ctx, t, s, grpc_error_set_int(GRPC_ERROR_CREATE("Buffers full"), + GRPC_ERROR_INT_HTTP2_ERROR, + GRPC_HTTP2_ENHANCE_YOUR_CALM)); if (n > 1) { /* Since we cancel one stream per destructive reclamation, if there are more streams left, we can immediately post a new -- cgit v1.2.3 From 1bfcc40fd32357018cb7bfd729e069018abb3689 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Tue, 21 Mar 2017 11:51:40 -0700 Subject: Clean up byte_stream_next interface usage --- .../transport/chttp2/transport/chttp2_transport.c | 21 +++++++++++++-------- src/core/ext/transport/chttp2/transport/internal.h | 2 -- .../transport/cronet/transport/cronet_transport.c | 12 ++++++++++-- src/core/lib/channel/compress_filter.c | 11 +++++++++-- src/core/lib/channel/http_client_filter.c | 11 +++++++++-- src/core/lib/surface/call.c | 5 +++-- src/core/lib/transport/byte_stream.c | 20 ++++++++++++++------ src/core/lib/transport/byte_stream.h | 15 +++++++++------ 8 files changed, 67 insertions(+), 30 deletions(-) (limited to 'src/core/ext/transport') diff --git a/src/core/ext/transport/chttp2/transport/chttp2_transport.c b/src/core/ext/transport/chttp2/transport/chttp2_transport.c index a8962d305d..95f20725f3 100644 --- a/src/core/ext/transport/chttp2/transport/chttp2_transport.c +++ b/src/core/ext/transport/chttp2/transport/chttp2_transport.c @@ -1101,8 +1101,9 @@ static void continue_fetching_send_locked(grpc_exec_ctx *exec_ctx, s->fetching_send_message = NULL; return; /* early out */ } else if (grpc_byte_stream_next(exec_ctx, s->fetching_send_message, - &s->fetching_slice, UINT32_MAX, - &s->complete_fetch_locked)) { + UINT32_MAX, &s->complete_fetch_locked)) { + grpc_byte_stream_pull(exec_ctx, s->fetching_send_message, + &s->fetching_slice); add_fetched_slice_locked(exec_ctx, t, s); } } @@ -1113,9 +1114,15 @@ static void complete_fetch_locked(grpc_exec_ctx *exec_ctx, void *gs, grpc_chttp2_stream *s = gs; grpc_chttp2_transport *t = s->t; if (error == GRPC_ERROR_NONE) { - add_fetched_slice_locked(exec_ctx, t, s); - continue_fetching_send_locked(exec_ctx, t, s); - } else { + error = grpc_byte_stream_pull(exec_ctx, s->fetching_send_message, + &s->fetching_slice); + if (error == GRPC_ERROR_NONE) { + add_fetched_slice_locked(exec_ctx, t, s); + continue_fetching_send_locked(exec_ctx, t, s); + } + } + + if (error != GRPC_ERROR_NONE) { /* TODO(ctiller): what to do here */ abort(); } @@ -2530,7 +2537,6 @@ static void incoming_byte_stream_next_locked(grpc_exec_ctx *exec_ctx, } } else { bs->on_next = bs->next_action.on_complete; - bs->next = bs->next_action.slice; } gpr_mu_unlock(&bs->slice_mu); gpr_mu_unlock(&s->buffer_mu); @@ -2570,13 +2576,12 @@ static grpc_error *incoming_byte_stream_pull(grpc_exec_ctx *exec_ctx, static int incoming_byte_stream_next(grpc_exec_ctx *exec_ctx, grpc_byte_stream *byte_stream, - grpc_slice *slice, size_t max_size_hint, + size_t max_size_hint, grpc_closure *on_complete) { GPR_TIMER_BEGIN("incoming_byte_stream_next", 0); grpc_chttp2_incoming_byte_stream *bs = (grpc_chttp2_incoming_byte_stream *)byte_stream; gpr_ref(&bs->refs); - bs->next_action.slice = slice; bs->next_action.max_size_hint = max_size_hint; bs->next_action.on_complete = on_complete; grpc_closure_sched( diff --git a/src/core/ext/transport/chttp2/transport/internal.h b/src/core/ext/transport/chttp2/transport/internal.h index 54bfd42357..adbd48c581 100644 --- a/src/core/ext/transport/chttp2/transport/internal.h +++ b/src/core/ext/transport/chttp2/transport/internal.h @@ -197,12 +197,10 @@ struct grpc_chttp2_incoming_byte_stream { gpr_mu slice_mu; // protects slices, on_next grpc_slice_buffer slices; grpc_closure *on_next; - grpc_slice *next; uint32_t remaining_bytes; struct { grpc_closure closure; - grpc_slice *slice; size_t max_size_hint; grpc_closure *on_complete; } next_action; diff --git a/src/core/ext/transport/cronet/transport/cronet_transport.c b/src/core/ext/transport/cronet/transport/cronet_transport.c index 01a03533da..da180e5144 100644 --- a/src/core/ext/transport/cronet/transport/cronet_transport.c +++ b/src/core/ext/transport/cronet/transport/cronet_transport.c @@ -908,8 +908,16 @@ static enum e_op_result execute_stream_op(grpc_exec_ctx *exec_ctx, grpc_slice_buffer write_slice_buffer; grpc_slice slice; grpc_slice_buffer_init(&write_slice_buffer); - grpc_byte_stream_next(NULL, stream_op->send_message, &slice, - stream_op->send_message->length, NULL); + if (1 != grpc_byte_stream_next(exec_ctx, stream_op->send_message, + stream_op->send_message->length, NULL)) { + /* Should never reach here */ + GPR_ASSERT(false); + } + if (GRPC_ERROR_NONE != + grpc_byte_stream_pull(exec_ctx, stream_op->send_message, &slice)) { + /* Should never reach here */ + GPR_ASSERT(false); + } /* Check that compression flag is OFF. We don't support compression yet. */ if (stream_op->send_message->flags != 0) { diff --git a/src/core/lib/channel/compress_filter.c b/src/core/lib/channel/compress_filter.c index aa41014a21..53d3b86f45 100644 --- a/src/core/lib/channel/compress_filter.c +++ b/src/core/lib/channel/compress_filter.c @@ -220,6 +220,12 @@ static void finish_send_message(grpc_exec_ctx *exec_ctx, static void got_slice(grpc_exec_ctx *exec_ctx, void *elemp, grpc_error *error) { grpc_call_element *elem = elemp; call_data *calld = elem->call_data; + if (GRPC_ERROR_NONE != grpc_byte_stream_pull(exec_ctx, + calld->send_op->send_message, + &calld->incoming_slice)) { + /* Should never reach here */ + abort(); + } grpc_slice_buffer_add(&calld->slices, calld->incoming_slice); if (calld->send_length == calld->slices.length) { finish_send_message(exec_ctx, elem); @@ -232,8 +238,9 @@ static void continue_send_message(grpc_exec_ctx *exec_ctx, grpc_call_element *elem) { call_data *calld = elem->call_data; while (grpc_byte_stream_next(exec_ctx, calld->send_op->send_message, - &calld->incoming_slice, ~(size_t)0, - &calld->got_slice)) { + ~(size_t)0, &calld->got_slice)) { + grpc_byte_stream_pull(exec_ctx, calld->send_op->send_message, + &calld->incoming_slice); grpc_slice_buffer_add(&calld->slices, calld->incoming_slice); if (calld->send_length == calld->slices.length) { finish_send_message(exec_ctx, elem); diff --git a/src/core/lib/channel/http_client_filter.c b/src/core/lib/channel/http_client_filter.c index c031533dd8..af2451e1eb 100644 --- a/src/core/lib/channel/http_client_filter.c +++ b/src/core/lib/channel/http_client_filter.c @@ -220,8 +220,9 @@ static void continue_send_message(grpc_exec_ctx *exec_ctx, call_data *calld = elem->call_data; uint8_t *wrptr = calld->payload_bytes; while (grpc_byte_stream_next(exec_ctx, calld->send_op.send_message, - &calld->incoming_slice, ~(size_t)0, - &calld->got_slice)) { + ~(size_t)0, &calld->got_slice)) { + grpc_byte_stream_pull(exec_ctx, calld->send_op.send_message, + &calld->incoming_slice); memcpy(wrptr, GRPC_SLICE_START_PTR(calld->incoming_slice), GRPC_SLICE_LENGTH(calld->incoming_slice)); wrptr += GRPC_SLICE_LENGTH(calld->incoming_slice); @@ -237,6 +238,12 @@ static void got_slice(grpc_exec_ctx *exec_ctx, void *elemp, grpc_error *error) { grpc_call_element *elem = elemp; call_data *calld = elem->call_data; calld->send_message_blocked = false; + if (GRPC_ERROR_NONE != grpc_byte_stream_pull(exec_ctx, + calld->send_op.send_message, + &calld->incoming_slice)) { + /* Should never reach here */ + abort(); + } grpc_slice_buffer_add(&calld->slices, calld->incoming_slice); if (calld->send_length == calld->slices.length) { /* Pass down the original send_message op that was blocked.*/ diff --git a/src/core/lib/surface/call.c b/src/core/lib/surface/call.c index 4471ada106..5dac90c60c 100644 --- a/src/core/lib/surface/call.c +++ b/src/core/lib/surface/call.c @@ -1162,9 +1162,10 @@ static void continue_receiving_slices(grpc_exec_ctx *exec_ctx, finish_batch_step(exec_ctx, bctl); return; } - if (grpc_byte_stream_next(exec_ctx, call->receiving_stream, - &call->receiving_slice, remaining, + if (grpc_byte_stream_next(exec_ctx, call->receiving_stream, remaining, &call->receiving_slice_ready)) { + grpc_byte_stream_pull(exec_ctx, call->receiving_stream, + &call->receiving_slice); grpc_slice_buffer_add(&(*call->receiving_buffer)->data.raw.slice_buffer, call->receiving_slice); } else { diff --git a/src/core/lib/transport/byte_stream.c b/src/core/lib/transport/byte_stream.c index 3a50694670..79801c4b46 100644 --- a/src/core/lib/transport/byte_stream.c +++ b/src/core/lib/transport/byte_stream.c @@ -40,10 +40,9 @@ #include "src/core/lib/slice/slice_internal.h" int grpc_byte_stream_next(grpc_exec_ctx *exec_ctx, - grpc_byte_stream *byte_stream, grpc_slice *slice, - size_t max_size_hint, grpc_closure *on_complete) { - return byte_stream->next(exec_ctx, byte_stream, slice, max_size_hint, - on_complete); + grpc_byte_stream *byte_stream, size_t max_size_hint, + grpc_closure *on_complete) { + return byte_stream->next(exec_ctx, byte_stream, max_size_hint, on_complete); } grpc_error *grpc_byte_stream_pull(grpc_exec_ctx *exec_ctx, @@ -61,14 +60,22 @@ void grpc_byte_stream_destroy(grpc_exec_ctx *exec_ctx, static int slice_buffer_stream_next(grpc_exec_ctx *exec_ctx, grpc_byte_stream *byte_stream, - grpc_slice *slice, size_t max_size_hint, + size_t max_size_hint, grpc_closure *on_complete) { grpc_slice_buffer_stream *stream = (grpc_slice_buffer_stream *)byte_stream; GPR_ASSERT(stream->cursor < stream->backing_buffer->count); + return 1; +} + +static grpc_error *slice_buffer_stream_pull(grpc_exec_ctx *exec_ctx, + grpc_byte_stream *byte_stream, + grpc_slice *slice) { + grpc_slice_buffer_stream *stream = (grpc_slice_buffer_stream *)byte_stream; + GPR_ASSERT(stream->cursor < stream->backing_buffer->count); *slice = grpc_slice_ref_internal(stream->backing_buffer->slices[stream->cursor]); stream->cursor++; - return 1; + return GRPC_ERROR_NONE; } static void slice_buffer_stream_destroy(grpc_exec_ctx *exec_ctx, @@ -81,6 +88,7 @@ void grpc_slice_buffer_stream_init(grpc_slice_buffer_stream *stream, stream->base.length = (uint32_t)slice_buffer->length; stream->base.flags = flags; stream->base.next = slice_buffer_stream_next; + stream->base.pull = slice_buffer_stream_pull; stream->base.destroy = slice_buffer_stream_destroy; stream->backing_buffer = slice_buffer; stream->cursor = 0; diff --git a/src/core/lib/transport/byte_stream.h b/src/core/lib/transport/byte_stream.h index 6afba92c52..800e2341f9 100644 --- a/src/core/lib/transport/byte_stream.h +++ b/src/core/lib/transport/byte_stream.h @@ -50,8 +50,7 @@ struct grpc_byte_stream { uint32_t length; uint32_t flags; int (*next)(grpc_exec_ctx *exec_ctx, grpc_byte_stream *byte_stream, - grpc_slice *slice, size_t max_size_hint, - grpc_closure *on_complete); + size_t max_size_hint, grpc_closure *on_complete); grpc_error *(*pull)(grpc_exec_ctx *exec_ctx, grpc_byte_stream *byte_stream, grpc_slice *slice); void (*destroy)(grpc_exec_ctx *exec_ctx, grpc_byte_stream *byte_stream); @@ -63,13 +62,17 @@ struct grpc_byte_stream { * * max_size_hint can be set as a hint as to the maximum number * of bytes that would be acceptable to read. - * - * once a slice is returned into *slice, it is owned by the caller. */ int grpc_byte_stream_next(grpc_exec_ctx *exec_ctx, - grpc_byte_stream *byte_stream, grpc_slice *slice, - size_t max_size_hint, grpc_closure *on_complete); + grpc_byte_stream *byte_stream, size_t max_size_hint, + grpc_closure *on_complete); +/* returns the next slice in the byte stream when it is ready (indicated by + * either grpc_byte_stream_next returning 1 or on_complete passed to + * grpc_byte_stream_next is called). + * + * once a slice is returned into *slice, it is owned by the caller. + */ grpc_error *grpc_byte_stream_pull(grpc_exec_ctx *exec_ctx, grpc_byte_stream *byte_stream, grpc_slice *slice); -- cgit v1.2.3 From ed3e300d8a42fd3b586761563d6ff1ca4bbc486f Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Fri, 24 Mar 2017 10:24:20 -0700 Subject: Tagging fields to identify protection --- src/core/ext/transport/chttp2/transport/internal.h | 30 +++++++++++----------- 1 file changed, 15 insertions(+), 15 deletions(-) (limited to 'src/core/ext/transport') diff --git a/src/core/ext/transport/chttp2/transport/internal.h b/src/core/ext/transport/chttp2/transport/internal.h index adbd48c581..31f2f06bba 100644 --- a/src/core/ext/transport/chttp2/transport/internal.h +++ b/src/core/ext/transport/chttp2/transport/internal.h @@ -186,24 +186,24 @@ typedef struct grpc_chttp2_write_cb { struct grpc_chttp2_incoming_byte_stream { grpc_byte_stream base; gpr_refcount refs; - struct grpc_chttp2_incoming_byte_stream *next_message; - grpc_error *error; - bool push_closed; + struct grpc_chttp2_incoming_byte_stream *next_message; /* unused; should be removed */ + grpc_error *error; /* protected by slice_mu */ + bool push_closed; /* protected by slice_mu */ - grpc_chttp2_transport *transport; - grpc_chttp2_stream *stream; - bool is_tail; + grpc_chttp2_transport *transport; /* immutable */ + grpc_chttp2_stream *stream; /* immutable */ + bool is_tail; /* immutable */ - gpr_mu slice_mu; // protects slices, on_next - grpc_slice_buffer slices; - grpc_closure *on_next; - uint32_t remaining_bytes; + gpr_mu slice_mu; + grpc_slice_buffer slices; /* unused; should be removed */ + grpc_closure *on_next; /* protected by slice_mu */ + uint32_t remaining_bytes; /* guaranteed one thread access */ struct { grpc_closure closure; size_t max_size_hint; grpc_closure *on_complete; - } next_action; + } next_action; /* guaranteed one thread access */ grpc_closure destroy_action; grpc_closure finished_action; }; @@ -488,10 +488,10 @@ struct grpc_chttp2_stream { grpc_chttp2_incoming_metadata_buffer metadata_buffer[2]; - grpc_chttp2_incoming_byte_stream *incoming_frames; + grpc_chttp2_incoming_byte_stream *incoming_frames; /* protected by buffer_mu */ gpr_mu buffer_mu; /* protects unprocessed_incoming_frames_buffer and - parse_data */ - grpc_slice_buffer unprocessed_incoming_frames_buffer; + data_parser */ + grpc_slice_buffer unprocessed_incoming_frames_buffer; /* protected by buffer_mu */ gpr_timespec deadline; @@ -504,7 +504,7 @@ struct grpc_chttp2_stream { * incoming_window = incoming_window_delta + transport.initial_window_size */ int64_t incoming_window_delta; /** parsing state for data frames */ - grpc_chttp2_data_parser data_parser; + grpc_chttp2_data_parser data_parser; /* protected by buffer_mu */ /** number of bytes received - reset at end of parse thread execution */ int64_t received_bytes; -- cgit v1.2.3 From e3c566431e1e8a3e49c413ef3525218d20759b48 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Fri, 24 Mar 2017 11:19:25 -0700 Subject: Merge upstream for error interface changes --- src/core/ext/transport/chttp2/transport/chttp2_transport.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'src/core/ext/transport') diff --git a/src/core/ext/transport/chttp2/transport/chttp2_transport.c b/src/core/ext/transport/chttp2/transport/chttp2_transport.c index a3e596fda7..1b0606ed9a 100644 --- a/src/core/ext/transport/chttp2/transport/chttp2_transport.c +++ b/src/core/ext/transport/chttp2/transport/chttp2_transport.c @@ -2351,13 +2351,13 @@ static grpc_error *deframe_unprocessed_incoming_frames( break; default: gpr_asprintf(&msg, "Bad GRPC frame type 0x%02x", p->frame_type); - p->error = GRPC_ERROR_CREATE(msg); + p->error = GRPC_ERROR_CREATE_FROM_COPIED_STRING(msg); p->error = grpc_error_set_int(p->error, GRPC_ERROR_INT_STREAM_ID, (intptr_t)s->id); gpr_free(msg); msg = grpc_dump_slice(slice, GPR_DUMP_HEX | GPR_DUMP_ASCII); p->error = - grpc_error_set_str(p->error, GRPC_ERROR_STR_RAW_BYTES, msg); + grpc_error_set_str(p->error, GRPC_ERROR_STR_RAW_BYTES, grpc_slice_from_copied_string(msg)); gpr_free(msg); p->error = grpc_error_set_int(p->error, GRPC_ERROR_INT_OFFSET, cur - beg); @@ -2558,7 +2558,7 @@ static void incoming_byte_stream_next_locked(grpc_exec_ctx *exec_ctx, GRPC_ERROR_REF(bs->error)); } else if (bs->push_closed) { if (bs->remaining_bytes != 0) { - bs->error = GRPC_ERROR_CREATE("Truncated message"); + bs->error = GRPC_ERROR_CREATE_FROM_STATIC_STRING("Truncated message"); grpc_closure_sched(exec_ctx, bs->next_action.on_complete, GRPC_ERROR_REF(bs->error)); } else { @@ -2597,7 +2597,7 @@ static grpc_error *incoming_byte_stream_pull(grpc_exec_ctx *exec_ctx, return error; } } else { - bs->error = GRPC_ERROR_CREATE("Truncated message"); + bs->error = GRPC_ERROR_CREATE_FROM_STATIC_STRING("Truncated message"); gpr_mu_unlock(&s->buffer_mu); return bs->error; } -- cgit v1.2.3 From ef033aa6a865584fe9e8aa805e342b2b0e69ef8c Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Fri, 24 Mar 2017 11:50:13 -0700 Subject: Remove duplicated code --- src/core/ext/transport/chttp2/transport/chttp2_transport.c | 11 ----------- src/core/ext/transport/chttp2/transport/frame_data.c | 2 -- 2 files changed, 13 deletions(-) (limited to 'src/core/ext/transport') diff --git a/src/core/ext/transport/chttp2/transport/chttp2_transport.c b/src/core/ext/transport/chttp2/transport/chttp2_transport.c index 1b0606ed9a..8c197f2b85 100644 --- a/src/core/ext/transport/chttp2/transport/chttp2_transport.c +++ b/src/core/ext/transport/chttp2/transport/chttp2_transport.c @@ -2680,17 +2680,6 @@ void grpc_chttp2_incoming_byte_stream_push(grpc_exec_ctx *exec_ctx, } } -void grpc_chttp2_incoming_byte_stream_notify( - grpc_exec_ctx *exec_ctx, grpc_chttp2_incoming_byte_stream *bs, - grpc_error *error) { - gpr_mu_lock(&bs->slice_mu); - if (bs->on_next) { - grpc_closure_sched(exec_ctx, bs->next_action.on_complete, error); - bs->on_next = NULL; - } - gpr_mu_unlock(&bs->slice_mu); -} - void grpc_chttp2_incoming_byte_stream_finished( grpc_exec_ctx *exec_ctx, grpc_chttp2_incoming_byte_stream *bs, grpc_error *error) { diff --git a/src/core/ext/transport/chttp2/transport/frame_data.c b/src/core/ext/transport/chttp2/transport/frame_data.c index 921dcef11c..ecd53e2ce9 100644 --- a/src/core/ext/transport/chttp2/transport/frame_data.c +++ b/src/core/ext/transport/chttp2/transport/frame_data.c @@ -291,8 +291,6 @@ grpc_error *parse_inner_buffer(grpc_exec_ctx *exec_ctx, grpc_chttp2_unprocessed_frames_buffer_push( exec_ctx, p, s, grpc_slice_sub(slice, (size_t)(cur - beg), (size_t)(end - beg))); - grpc_chttp2_incoming_byte_stream_notify(exec_ctx, p->parsing_frame, - GRPC_ERROR_NONE); gpr_mu_unlock(&s->buffer_mu); return GRPC_ERROR_NONE; } -- cgit v1.2.3 From 397a6684cbec4812cff3580da80255fa1a00d087 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Fri, 24 Mar 2017 17:27:19 -0700 Subject: clang-format --- .../transport/chttp2/transport/chttp2_transport.c | 30 ++++++++++++---------- 1 file changed, 17 insertions(+), 13 deletions(-) (limited to 'src/core/ext/transport') diff --git a/src/core/ext/transport/chttp2/transport/chttp2_transport.c b/src/core/ext/transport/chttp2/transport/chttp2_transport.c index 8c197f2b85..719a17fe10 100644 --- a/src/core/ext/transport/chttp2/transport/chttp2_transport.c +++ b/src/core/ext/transport/chttp2/transport/chttp2_transport.c @@ -511,10 +511,11 @@ static void destroy_transport_locked(grpc_exec_ctx *exec_ctx, void *tp, static void destroy_transport(grpc_exec_ctx *exec_ctx, grpc_transport *gt) { grpc_chttp2_transport *t = (grpc_chttp2_transport *)gt; - grpc_closure_sched(exec_ctx, grpc_closure_create( - destroy_transport_locked, t, - grpc_combiner_scheduler(t->combiner, false)), - GRPC_ERROR_NONE); + grpc_closure_sched( + exec_ctx, + grpc_closure_create(destroy_transport_locked, t, + grpc_combiner_scheduler(t->combiner, false)), + GRPC_ERROR_NONE); } static void close_transport_locked(grpc_exec_ctx *exec_ctx, @@ -696,8 +697,9 @@ static void destroy_stream(grpc_exec_ctx *exec_ctx, grpc_transport *gt, s->destroy_stream_arg = then_schedule_closure; grpc_closure_sched( - exec_ctx, grpc_closure_init(&s->destroy_stream, destroy_stream_locked, s, - grpc_combiner_scheduler(t->combiner, false)), + exec_ctx, + grpc_closure_init(&s->destroy_stream, destroy_stream_locked, s, + grpc_combiner_scheduler(t->combiner, false)), GRPC_ERROR_NONE); GPR_TIMER_END("destroy_stream", 0); } @@ -1511,9 +1513,10 @@ static void perform_transport_op(grpc_exec_ctx *exec_ctx, grpc_transport *gt, op->transport_private.args[0] = gt; GRPC_CHTTP2_REF_TRANSPORT(t, "transport_op"); grpc_closure_sched( - exec_ctx, grpc_closure_init(&op->transport_private.closure, - perform_transport_op_locked, op, - grpc_combiner_scheduler(t->combiner, false)), + exec_ctx, + grpc_closure_init(&op->transport_private.closure, + perform_transport_op_locked, op, + grpc_combiner_scheduler(t->combiner, false)), GRPC_ERROR_NONE); } @@ -2256,8 +2259,9 @@ static void keepalive_watchdog_fired_locked(grpc_exec_ctx *exec_ctx, void *arg, if (t->keepalive_state == GRPC_CHTTP2_KEEPALIVE_STATE_PINGING) { if (error == GRPC_ERROR_NONE) { t->keepalive_state = GRPC_CHTTP2_KEEPALIVE_STATE_DYING; - close_transport_locked(exec_ctx, t, GRPC_ERROR_CREATE_FROM_STATIC_STRING( - "keepalive watchdog timeout")); + close_transport_locked( + exec_ctx, t, + GRPC_ERROR_CREATE_FROM_STATIC_STRING("keepalive watchdog timeout")); } } else { /** The watchdog timer should have been cancelled by @@ -2356,8 +2360,8 @@ static grpc_error *deframe_unprocessed_incoming_frames( (intptr_t)s->id); gpr_free(msg); msg = grpc_dump_slice(slice, GPR_DUMP_HEX | GPR_DUMP_ASCII); - p->error = - grpc_error_set_str(p->error, GRPC_ERROR_STR_RAW_BYTES, grpc_slice_from_copied_string(msg)); + p->error = grpc_error_set_str(p->error, GRPC_ERROR_STR_RAW_BYTES, + grpc_slice_from_copied_string(msg)); gpr_free(msg); p->error = grpc_error_set_int(p->error, GRPC_ERROR_INT_OFFSET, cur - beg); -- cgit v1.2.3 From ac399579285661ce13cdbc51c2c8bf7509412be2 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Tue, 28 Mar 2017 18:42:00 -0700 Subject: Polished with better thread safety --- .../transport/chttp2/transport/chttp2_transport.c | 431 ++++++++++----------- .../ext/transport/chttp2/transport/frame_data.c | 184 ++------- .../ext/transport/chttp2/transport/frame_data.h | 4 +- src/core/ext/transport/chttp2/transport/internal.h | 28 +- src/core/ext/transport/chttp2/transport/parsing.c | 4 +- src/core/lib/surface/call.c | 17 +- 6 files changed, 248 insertions(+), 420 deletions(-) (limited to 'src/core/ext/transport') diff --git a/src/core/ext/transport/chttp2/transport/chttp2_transport.c b/src/core/ext/transport/chttp2/transport/chttp2_transport.c index 8c197f2b85..c86fefe2cf 100644 --- a/src/core/ext/transport/chttp2/transport/chttp2_transport.c +++ b/src/core/ext/transport/chttp2/transport/chttp2_transport.c @@ -115,6 +115,11 @@ static void incoming_byte_stream_update_flow_control(grpc_exec_ctx *exec_ctx, static void incoming_byte_stream_destroy_locked(grpc_exec_ctx *exec_ctx, void *byte_stream, grpc_error *error_ignored); +static void incoming_byte_stream_publish_error(grpc_exec_ctx *exec_ctx, + grpc_chttp2_incoming_byte_stream *bs, + grpc_error *error); +static void incoming_byte_stream_unref(grpc_exec_ctx *exec_ctx, + grpc_chttp2_incoming_byte_stream *bs); static void benign_reclaimer_locked(grpc_exec_ctx *exec_ctx, void *t, grpc_error *error); @@ -156,13 +161,14 @@ static void finish_keepalive_ping_locked(grpc_exec_ctx *exec_ctx, void *arg, static void keepalive_watchdog_fired_locked(grpc_exec_ctx *exec_ctx, void *arg, grpc_error *error); -static grpc_error *deframe_unprocessed_incoming_frames( - grpc_exec_ctx *exec_ctx, grpc_chttp2_data_parser *p, - grpc_chttp2_transport *t, grpc_chttp2_stream *s, grpc_slice_buffer *slices, - grpc_slice *slice_out, bool partial_deframe); -static void clean_unprocessed_frames_buffer(grpc_exec_ctx *exec_ctx, - grpc_chttp2_transport *t, - grpc_chttp2_stream *s); +static grpc_error *deframe_unprocessed_incoming_frames(grpc_exec_ctx *exec_ctx, + grpc_chttp2_data_parser *p, + grpc_chttp2_stream *s, + grpc_slice_buffer *slices, + grpc_slice *slice_out, + grpc_byte_stream **stream_out); +static void reset_byte_stream(grpc_exec_ctx *exec_ctx, void *arg, + grpc_error *error); /******************************************************************************* * CONSTRUCTION/DESTRUCTION/REFCOUNTING @@ -596,7 +602,6 @@ static int init_stream(grpc_exec_ctx *exec_ctx, grpc_transport *gt, /* We reserve one 'active stream' that's dropped when the stream is read-closed. The others are for incoming_byte_streams that are actively reading */ - gpr_ref_init(&s->active_streams, 1); GRPC_CHTTP2_STREAM_REF(s, "chttp2"); grpc_chttp2_incoming_metadata_buffer_init(&s->metadata_buffer[0], arena); @@ -606,9 +611,10 @@ static int init_stream(grpc_exec_ctx *exec_ctx, grpc_transport *gt, s->deadline = gpr_inf_future(GPR_CLOCK_MONOTONIC); grpc_closure_init(&s->complete_fetch_locked, complete_fetch_locked, s, grpc_schedule_on_exec_ctx); - s->incoming_frames = NULL; grpc_slice_buffer_init(&s->unprocessed_incoming_frames_buffer); - gpr_mu_init(&s->buffer_mu); + grpc_slice_buffer_init(&s->frame_storage); + s->pending_byte_stream = false; + grpc_closure_init(&s->reset_byte_stream, reset_byte_stream, s, grpc_combiner_scheduler(t->combiner, false)); GRPC_CHTTP2_REF_TRANSPORT(t, "stream"); @@ -638,11 +644,7 @@ static void destroy_stream_locked(grpc_exec_ctx *exec_ctx, void *sp, grpc_slice_buffer_destroy_internal(exec_ctx, &s->unprocessed_incoming_frames_buffer); - if (s->incoming_frames != NULL) { - grpc_chttp2_incoming_byte_stream *ibs = s->incoming_frames; - s->incoming_frames = NULL; - incoming_byte_stream_destroy_locked(exec_ctx, &ibs->base, GRPC_ERROR_NONE); - } + grpc_slice_buffer_destroy_internal(exec_ctx, &s->frame_storage); grpc_chttp2_list_remove_stalled_by_transport(t, s); grpc_chttp2_list_remove_stalled_by_stream(t, s); @@ -661,9 +663,7 @@ static void destroy_stream_locked(grpc_exec_ctx *exec_ctx, void *sp, GPR_ASSERT(s->recv_initial_metadata_ready == NULL); GPR_ASSERT(s->recv_message_ready == NULL); GPR_ASSERT(s->recv_trailing_metadata_finished == NULL); - gpr_mu_lock(&s->buffer_mu); grpc_chttp2_data_parser_destroy(exec_ctx, &s->data_parser); - gpr_mu_unlock(&s->buffer_mu); grpc_chttp2_incoming_metadata_buffer_destroy(exec_ctx, &s->metadata_buffer[0]); grpc_chttp2_incoming_metadata_buffer_destroy(exec_ctx, @@ -671,6 +671,7 @@ static void destroy_stream_locked(grpc_exec_ctx *exec_ctx, void *sp, grpc_slice_buffer_destroy_internal(exec_ctx, &s->flow_controlled_buffer); GRPC_ERROR_UNREF(s->read_closed_error); GRPC_ERROR_UNREF(s->write_closed_error); + GRPC_ERROR_UNREF(s->byte_stream_error); if (s->incoming_window_delta > 0) { GRPC_CHTTP2_FLOW_DEBIT_STREAM_INCOMING_WINDOW_DELTA( @@ -1345,22 +1346,9 @@ static void perform_stream_op_locked(grpc_exec_ctx *exec_ctx, void *stream_op, GPR_ASSERT(s->recv_message_ready == NULL); s->recv_message_ready = op->recv_message_ready; s->recv_message = op->recv_message; - gpr_mu_lock(&s->buffer_mu); - if (s->id != 0 && (s->incoming_frames == NULL || - s->unprocessed_incoming_frames_buffer.count == 0)) { - gpr_mu_unlock(&s->buffer_mu); + if (s->id != 0 && s->frame_storage.length == 0) { incoming_byte_stream_update_flow_control(exec_ctx, t, s, 5, 0); - } else { - gpr_mu_unlock(&s->buffer_mu); - } - gpr_mu_lock(&s->buffer_mu); - if (s->incoming_frames == NULL && - s->unprocessed_incoming_frames_buffer.count > 0) { - deframe_unprocessed_incoming_frames( - exec_ctx, &s->data_parser, t, s, - &s->unprocessed_incoming_frames_buffer, NULL, true); } - gpr_mu_unlock(&s->buffer_mu); grpc_chttp2_maybe_complete_recv_message(exec_ctx, t, s); } @@ -1527,18 +1515,9 @@ void grpc_chttp2_maybe_complete_recv_initial_metadata(grpc_exec_ctx *exec_ctx, if (s->recv_initial_metadata_ready != NULL && s->published_metadata[0] != GRPC_METADATA_NOT_PUBLISHED) { if (s->seen_error) { - if (s->incoming_frames != NULL) { - grpc_chttp2_incoming_byte_stream *ibs = s->incoming_frames; - s->incoming_frames = NULL; - incoming_byte_stream_destroy_locked(exec_ctx, &ibs->base, - GRPC_ERROR_NONE); - } - size_t length; - gpr_mu_lock(&s->buffer_mu); - length = s->unprocessed_incoming_frames_buffer.length; - gpr_mu_unlock(&s->buffer_mu); - if (length > 0) { - clean_unprocessed_frames_buffer(exec_ctx, t, s); + grpc_slice_buffer_reset_and_unref(&s->frame_storage); + if (!s->pending_byte_stream) { + grpc_slice_buffer_reset_and_unref(&s->unprocessed_incoming_frames_buffer); } } grpc_chttp2_incoming_metadata_buffer_publish( @@ -1551,32 +1530,38 @@ void grpc_chttp2_maybe_complete_recv_initial_metadata(grpc_exec_ctx *exec_ctx, void grpc_chttp2_maybe_complete_recv_message(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t, grpc_chttp2_stream *s) { + grpc_error *error = GRPC_ERROR_NONE; if (s->recv_message_ready != NULL) { + *s->recv_message = NULL; if (s->final_metadata_requested && s->seen_error) { - if (s->incoming_frames != NULL) { - grpc_chttp2_incoming_byte_stream *ibs = s->incoming_frames; - s->incoming_frames = NULL; - incoming_byte_stream_destroy_locked(exec_ctx, &ibs->base, - GRPC_ERROR_NONE); + grpc_slice_buffer_reset_and_unref(&s->frame_storage); + if (!s->pending_byte_stream) { + grpc_slice_buffer_reset_and_unref(&s->unprocessed_incoming_frames_buffer); } - size_t length; - gpr_mu_lock(&s->buffer_mu); - length = s->unprocessed_incoming_frames_buffer.length; - gpr_mu_unlock(&s->buffer_mu); - if (length > 0) { - clean_unprocessed_frames_buffer(exec_ctx, t, s); + } + if (!s->pending_byte_stream) { + while (s->unprocessed_incoming_frames_buffer.length > 0 || + s->frame_storage.length > 0) { + if (s->unprocessed_incoming_frames_buffer.length == 0) { + grpc_slice_buffer_swap(&s->unprocessed_incoming_frames_buffer, &s->frame_storage); + } + /* error handling ok? */ + error = deframe_unprocessed_incoming_frames(exec_ctx, &s->data_parser, s, &s->unprocessed_incoming_frames_buffer, NULL, s->recv_message); + if (error != GRPC_ERROR_NONE) { + s->seen_error = true; + grpc_slice_buffer_reset_and_unref(&s->frame_storage); + grpc_slice_buffer_reset_and_unref(&s->unprocessed_incoming_frames_buffer); + break; + } else if (*s->recv_message != NULL) { + break; + } } } - if (s->incoming_frames != NULL) { - *s->recv_message = &s->incoming_frames->base; - s->incoming_frames = NULL; - GPR_ASSERT(*s->recv_message != NULL); - grpc_closure_sched(exec_ctx, s->recv_message_ready, GRPC_ERROR_NONE); - s->recv_message_ready = NULL; + if (error == GRPC_ERROR_NONE && *s->recv_message != NULL) { + null_then_run_closure(exec_ctx, &s->recv_message_ready, GRPC_ERROR_NONE); } else if (s->published_metadata[1] != GRPC_METADATA_NOT_PUBLISHED) { *s->recv_message = NULL; - grpc_closure_sched(exec_ctx, s->recv_message_ready, GRPC_ERROR_NONE); - s->recv_message_ready = NULL; + null_then_run_closure(exec_ctx, &s->recv_message_ready, GRPC_ERROR_NONE); } } } @@ -1588,21 +1573,13 @@ void grpc_chttp2_maybe_complete_recv_trailing_metadata(grpc_exec_ctx *exec_ctx, if (s->recv_trailing_metadata_finished != NULL && s->read_closed && s->write_closed) { if (s->seen_error) { - if (s->incoming_frames != NULL) { - grpc_chttp2_incoming_byte_stream *ibs = s->incoming_frames; - s->incoming_frames = NULL; - incoming_byte_stream_destroy_locked(exec_ctx, &ibs->base, - GRPC_ERROR_NONE); - } - size_t length; - gpr_mu_lock(&s->buffer_mu); - length = s->unprocessed_incoming_frames_buffer.length; - gpr_mu_unlock(&s->buffer_mu); - if (length > 0) { - clean_unprocessed_frames_buffer(exec_ctx, t, s); + grpc_slice_buffer_reset_and_unref(&s->frame_storage); + if (!s->pending_byte_stream) { + grpc_slice_buffer_reset_and_unref(&s->unprocessed_incoming_frames_buffer); } } - if (s->all_incoming_byte_streams_finished && + if (s->read_closed && s->frame_storage.length == 0 && + (!s->pending_byte_stream || s->seen_error) && s->recv_trailing_metadata_finished != NULL) { grpc_chttp2_incoming_metadata_buffer_publish( exec_ctx, &s->metadata_buffer[1], s->recv_trailing_metadata); @@ -1613,34 +1590,6 @@ void grpc_chttp2_maybe_complete_recv_trailing_metadata(grpc_exec_ctx *exec_ctx, } } -static void decrement_active_streams_locked(grpc_exec_ctx *exec_ctx, - grpc_chttp2_transport *t, - grpc_chttp2_stream *s) { - size_t length; - gpr_mu_lock(&s->buffer_mu); - length = s->unprocessed_incoming_frames_buffer.length; - gpr_mu_unlock(&s->buffer_mu); - if ((s->all_incoming_byte_streams_finished = - (gpr_unref(&s->active_streams) && length == 0))) { - grpc_chttp2_maybe_complete_recv_trailing_metadata(exec_ctx, t, s); - } -} - -static void clean_unprocessed_frames_buffer(grpc_exec_ctx *exec_ctx, - grpc_chttp2_transport *t, - grpc_chttp2_stream *s) { - gpr_mu_lock(&s->buffer_mu); - grpc_slice_buffer_reset_and_unref_internal( - exec_ctx, &s->unprocessed_incoming_frames_buffer); - gpr_mu_unlock(&s->buffer_mu); - // TODO (mxyan): add get ref count in sync.c? - gpr_atm active_streams = - gpr_atm_no_barrier_fetch_add(&s->active_streams.count, 0); - if ((s->all_incoming_byte_streams_finished = (active_streams == 0))) { - grpc_chttp2_maybe_complete_recv_trailing_metadata(exec_ctx, t, s); - } -} - static void remove_stream(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t, uint32_t id, grpc_error *error) { grpc_chttp2_stream *s = grpc_chttp2_stream_map_delete(&t->stream_map, id); @@ -1649,24 +1598,18 @@ static void remove_stream(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t, t->incoming_stream = NULL; grpc_chttp2_parsing_become_skip_parser(exec_ctx, t); } - gpr_mu_lock(&s->buffer_mu); - if (s->data_parser.parsing_frame != NULL) { - grpc_chttp2_incoming_byte_stream *bs = s->data_parser.parsing_frame; - gpr_mu_lock(&bs->slice_mu); - bs->push_closed = true; - if (bs->on_next != NULL) { - gpr_mu_unlock(&bs->slice_mu); - gpr_mu_unlock(&s->buffer_mu); - grpc_chttp2_incoming_byte_stream_finished( - exec_ctx, s->data_parser.parsing_frame, GRPC_ERROR_REF(error)); + if (s->pending_byte_stream) { + if (s->on_next != NULL) { + grpc_chttp2_incoming_byte_stream *bs = s->data_parser.parsing_frame; + if (error == GRPC_ERROR_NONE) { + error = GRPC_ERROR_CREATE_FROM_STATIC_STRING("Truncated message"); + } + incoming_byte_stream_publish_error(exec_ctx, bs, error); + incoming_byte_stream_unref(exec_ctx, bs); s->data_parser.parsing_frame = NULL; } else { - bs->error = GRPC_ERROR_REF(error); - gpr_mu_unlock(&bs->slice_mu); - gpr_mu_unlock(&s->buffer_mu); + s->byte_stream_error = GRPC_ERROR_REF(error); } - } else { - gpr_mu_unlock(&s->buffer_mu); } if (grpc_chttp2_stream_map_size(&t->stream_map) == 0) { @@ -1852,7 +1795,6 @@ void grpc_chttp2_mark_stream_closed(grpc_exec_ctx *exec_ctx, s->published_metadata[i] = GPRC_METADATA_PUBLISHED_AT_CLOSE; } } - decrement_active_streams_locked(exec_ctx, t, s); grpc_chttp2_maybe_complete_recv_initial_metadata(exec_ctx, t, s); grpc_chttp2_maybe_complete_recv_message(exec_ctx, t, s); } @@ -2304,11 +2246,32 @@ static void set_pollset_set(grpc_exec_ctx *exec_ctx, grpc_transport *gt, * BYTE STREAM */ +static void reset_byte_stream(grpc_exec_ctx *exec_ctx, void *arg, + grpc_error *error) { + grpc_chttp2_stream *s = (grpc_chttp2_stream *)arg; + + s->pending_byte_stream = false; + if (error == GRPC_ERROR_NONE) { + grpc_chttp2_maybe_complete_recv_message(exec_ctx, s->t, s); + grpc_chttp2_maybe_complete_recv_trailing_metadata(exec_ctx, s->t, s); + } else { + GPR_ASSERT(error != GRPC_ERROR_NONE); + grpc_closure_sched(exec_ctx, s->on_next, GRPC_ERROR_REF(error)); + s->on_next = NULL; + GRPC_ERROR_UNREF(s->byte_stream_error); + grpc_chttp2_cancel_stream(exec_ctx, s->t, s, + GRPC_ERROR_REF(error)); + s->byte_stream_error = error; + } +} + static grpc_error *deframe_unprocessed_incoming_frames( grpc_exec_ctx *exec_ctx, grpc_chttp2_data_parser *p, - grpc_chttp2_transport *t, grpc_chttp2_stream *s, grpc_slice_buffer *slices, - grpc_slice *slice_out, bool partial_deframe) { - bool slice_set = false; + grpc_chttp2_stream *s, grpc_slice_buffer *slices, + grpc_slice *slice_out, grpc_byte_stream **stream_out) { + grpc_error *error = GRPC_ERROR_NONE; + grpc_chttp2_transport *t = s->t; + while (slices->count > 0) { uint8_t *beg = NULL; uint8_t *end = NULL; @@ -2332,15 +2295,7 @@ static grpc_error *deframe_unprocessed_incoming_frames( p->state = GRPC_CHTTP2_DATA_ERROR; grpc_slice_unref_internal(exec_ctx, slice); return GRPC_ERROR_REF(p->error); - fh_0: case GRPC_CHTTP2_DATA_FH_0: - if (s->incoming_frames != NULL) { - grpc_slice_buffer_undo_take_first( - &s->unprocessed_incoming_frames_buffer, - grpc_slice_sub(slice, (size_t)(cur - beg), (size_t)(end - beg))); - grpc_slice_unref_internal(exec_ctx, slice); - return GRPC_ERROR_NONE; - } p->frame_type = *cur; switch (p->frame_type) { case 0: @@ -2396,6 +2351,8 @@ static grpc_error *deframe_unprocessed_incoming_frames( } /* fallthrough */ case GRPC_CHTTP2_DATA_FH_4: + GPR_ASSERT(stream_out != NULL); + GPR_ASSERT(p->parsing_frame == NULL); p->frame_size |= ((uint32_t)*cur); p->state = GRPC_CHTTP2_DATA_FRAME; ++cur; @@ -2403,71 +2360,69 @@ static grpc_error *deframe_unprocessed_incoming_frames( if (p->is_frame_compressed) { message_flags |= GRPC_WRITE_INTERNAL_COMPRESS; } - GPR_ASSERT(s->incoming_frames == NULL); p->parsing_frame = grpc_chttp2_incoming_byte_stream_create( exec_ctx, t, s, p->frame_size, message_flags); - /* fallthrough */ + *stream_out = &p->parsing_frame->base; + if (p->parsing_frame->remaining_bytes == 0) { + grpc_chttp2_incoming_byte_stream_finished(exec_ctx, p->parsing_frame, GRPC_ERROR_NONE); + p->parsing_frame = NULL; + p->state = GRPC_CHTTP2_DATA_FH_0; + } else { + s->pending_byte_stream = true; + } + + if (cur != end) { + grpc_slice_buffer_undo_take_first(&s->unprocessed_incoming_frames_buffer, grpc_slice_sub(slice, (size_t)(cur - beg), (size_t)(end - beg))); + } + grpc_slice_unref(slice); + return GRPC_ERROR_NONE; case GRPC_CHTTP2_DATA_FRAME: { GPR_ASSERT(p->parsing_frame != NULL); - if (partial_deframe && p->frame_size > 0) { - if (cur != end) { - grpc_slice_buffer_undo_take_first( - &s->unprocessed_incoming_frames_buffer, - grpc_slice_sub(slice, (size_t)(cur - beg), - (size_t)(end - beg))); - } - grpc_slice_unref_internal(exec_ctx, slice); - return GRPC_ERROR_NONE; - } + GPR_ASSERT(slice_out != NULL); if (cur == end) { grpc_slice_unref_internal(exec_ctx, slice); continue; } - if (slice_set) { - grpc_slice_buffer_undo_take_first( - &s->unprocessed_incoming_frames_buffer, - grpc_slice_sub(slice, (size_t)(cur - beg), (size_t)(end - beg))); - grpc_slice_unref_internal(exec_ctx, slice); - return GRPC_ERROR_NONE; - } uint32_t remaining = (uint32_t)(end - cur); if (remaining == p->frame_size) { - grpc_chttp2_incoming_byte_stream_push( + if (GRPC_ERROR_NONE != (error = grpc_chttp2_incoming_byte_stream_push( exec_ctx, p->parsing_frame, grpc_slice_sub(slice, (size_t)(cur - beg), (size_t)(end - beg)), - slice_out); - slice_set = true; + slice_out))) { + grpc_slice_unref_internal(exec_ctx, slice); + return error; + } grpc_chttp2_incoming_byte_stream_finished(exec_ctx, p->parsing_frame, GRPC_ERROR_NONE); p->parsing_frame = NULL; p->state = GRPC_CHTTP2_DATA_FH_0; + grpc_closure_sched(exec_ctx, &s->reset_byte_stream, GRPC_ERROR_NONE); grpc_slice_unref_internal(exec_ctx, slice); - continue; + return GRPC_ERROR_NONE; } else if (remaining < p->frame_size) { - grpc_chttp2_incoming_byte_stream_push( + if (GRPC_ERROR_NONE != (error = grpc_chttp2_incoming_byte_stream_push( exec_ctx, p->parsing_frame, grpc_slice_sub(slice, (size_t)(cur - beg), (size_t)(end - beg)), - slice_out); - slice_set = true; + slice_out))) { + return error; + } p->frame_size -= remaining; grpc_slice_unref_internal(exec_ctx, slice); - continue; + return GRPC_ERROR_NONE; } else { GPR_ASSERT(remaining > p->frame_size); - if (p->frame_size > 0) { - grpc_chttp2_incoming_byte_stream_push( - exec_ctx, p->parsing_frame, - grpc_slice_sub(slice, (size_t)(cur - beg), - (size_t)(cur + p->frame_size - beg)), - slice_out); + if (GRPC_ERROR_NONE != (grpc_chttp2_incoming_byte_stream_push(exec_ctx, p->parsing_frame, grpc_slice_sub(slice, (size_t)(cur - beg), (size_t)(cur + p->frame_size - beg)), slice_out))) { + grpc_slice_unref_internal(exec_ctx, slice); + return error; } - slice_set = true; grpc_chttp2_incoming_byte_stream_finished(exec_ctx, p->parsing_frame, GRPC_ERROR_NONE); p->parsing_frame = NULL; p->state = GRPC_CHTTP2_DATA_FH_0; cur += p->frame_size; - goto fh_0; + grpc_slice_buffer_undo_take_first(&s->unprocessed_incoming_frames_buffer, grpc_slice_sub(slice, (size_t)(cur - beg), (size_t)(end - beg))); + grpc_closure_sched(exec_ctx, &s->reset_byte_stream, GRPC_ERROR_NONE); + grpc_slice_unref(slice); return GRPC_ERROR_NONE; } } @@ -2480,7 +2435,6 @@ static grpc_error *deframe_unprocessed_incoming_frames( static void incoming_byte_stream_unref(grpc_exec_ctx *exec_ctx, grpc_chttp2_incoming_byte_stream *bs) { if (gpr_unref(&bs->refs)) { - GRPC_ERROR_UNREF(bs->error); grpc_slice_buffer_destroy_internal(exec_ctx, &bs->slices); gpr_mu_destroy(&bs->slice_mu); gpr_free(bs); @@ -2542,90 +2496,90 @@ static void incoming_byte_stream_next_locked(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t = bs->transport; grpc_chttp2_stream *s = bs->stream; - if (bs->is_tail) { - gpr_mu_lock(&bs->slice_mu); - size_t cur_length = bs->slices.length; - gpr_mu_unlock(&bs->slice_mu); - incoming_byte_stream_update_flow_control( - exec_ctx, t, s, bs->next_action.max_size_hint, cur_length); - } - gpr_mu_lock(&s->buffer_mu); - gpr_mu_lock(&bs->slice_mu); - if (s->unprocessed_incoming_frames_buffer.length > 0) { + size_t cur_length = s->frame_storage.length; + incoming_byte_stream_update_flow_control( + exec_ctx, t, s, bs->next_action.max_size_hint, cur_length); + + GPR_ASSERT(s->unprocessed_incoming_frames_buffer.length == 0); + if (s->frame_storage.length > 0) { + grpc_slice_buffer_swap(&s->frame_storage, &s->unprocessed_incoming_frames_buffer); grpc_closure_sched(exec_ctx, bs->next_action.on_complete, GRPC_ERROR_NONE); - } else if (bs->error != GRPC_ERROR_NONE) { + } else if (s->byte_stream_error != GRPC_ERROR_NONE) { grpc_closure_sched(exec_ctx, bs->next_action.on_complete, - GRPC_ERROR_REF(bs->error)); - } else if (bs->push_closed) { + GRPC_ERROR_REF(s->byte_stream_error)); + if (s->data_parser.parsing_frame != NULL) { + incoming_byte_stream_unref(exec_ctx, s->data_parser.parsing_frame); + s->data_parser.parsing_frame = NULL; + } + } else if (s->read_closed) { if (bs->remaining_bytes != 0) { - bs->error = GRPC_ERROR_CREATE_FROM_STATIC_STRING("Truncated message"); + s->byte_stream_error = GRPC_ERROR_CREATE_FROM_STATIC_STRING("Truncated message"); grpc_closure_sched(exec_ctx, bs->next_action.on_complete, - GRPC_ERROR_REF(bs->error)); + GRPC_ERROR_REF(s->byte_stream_error)); + if (s->data_parser.parsing_frame != NULL) { + incoming_byte_stream_unref(exec_ctx, s->data_parser.parsing_frame); + s->data_parser.parsing_frame = NULL; + } } else { /* Should never reach here. */ GPR_ASSERT(false); - grpc_closure_sched(exec_ctx, bs->next_action.on_complete, - GRPC_ERROR_NONE); } } else { - bs->on_next = bs->next_action.on_complete; + s->on_next = bs->next_action.on_complete; } - gpr_mu_unlock(&bs->slice_mu); - gpr_mu_unlock(&s->buffer_mu); incoming_byte_stream_unref(exec_ctx, bs); } +static int incoming_byte_stream_next(grpc_exec_ctx *exec_ctx, + grpc_byte_stream *byte_stream, + size_t max_size_hint, + grpc_closure *on_complete) { + GPR_TIMER_BEGIN("incoming_byte_stream_next", 0); + grpc_chttp2_incoming_byte_stream *bs = + (grpc_chttp2_incoming_byte_stream *)byte_stream; + grpc_chttp2_stream *s = bs->stream; + if (s->unprocessed_incoming_frames_buffer.length > 0) { + return 1; + } else { + gpr_ref(&bs->refs); + bs->next_action.max_size_hint = max_size_hint; + bs->next_action.on_complete = on_complete; + grpc_closure_sched( + exec_ctx, + grpc_closure_init( + &bs->next_action.closure, incoming_byte_stream_next_locked, bs, + grpc_combiner_scheduler(bs->transport->combiner, false)), + GRPC_ERROR_NONE); + GPR_TIMER_END("incoming_byte_stream_next", 0); + return 0; + } +} + static grpc_error *incoming_byte_stream_pull(grpc_exec_ctx *exec_ctx, grpc_byte_stream *byte_stream, grpc_slice *slice) { GPR_TIMER_BEGIN("incoming_byte_stream_pull", 0); grpc_chttp2_incoming_byte_stream *bs = - (grpc_chttp2_incoming_byte_stream *)byte_stream; + (grpc_chttp2_incoming_byte_stream *)byte_stream; grpc_chttp2_stream *s = bs->stream; - grpc_chttp2_transport *t = bs->transport; - if (bs->error) { - return bs->error; - } - gpr_mu_lock(&s->buffer_mu); if (s->unprocessed_incoming_frames_buffer.length > 0) { grpc_error *error = deframe_unprocessed_incoming_frames( - exec_ctx, &s->data_parser, t, s, &s->unprocessed_incoming_frames_buffer, - slice, false); + exec_ctx, &s->data_parser, s, &s->unprocessed_incoming_frames_buffer, + slice, NULL); if (error != GRPC_ERROR_NONE) { - gpr_mu_unlock(&s->buffer_mu); return error; } } else { - bs->error = GRPC_ERROR_CREATE_FROM_STATIC_STRING("Truncated message"); - gpr_mu_unlock(&s->buffer_mu); - return bs->error; + grpc_error *error = GRPC_ERROR_CREATE_FROM_STATIC_STRING("Truncated message"); + grpc_closure_sched(exec_ctx, + &s->reset_byte_stream, GRPC_ERROR_REF(error)); + return error; } - gpr_mu_unlock(&s->buffer_mu); GPR_TIMER_END("incoming_byte_stream_pull", 0); return GRPC_ERROR_NONE; } -static int incoming_byte_stream_next(grpc_exec_ctx *exec_ctx, - grpc_byte_stream *byte_stream, - size_t max_size_hint, - grpc_closure *on_complete) { - GPR_TIMER_BEGIN("incoming_byte_stream_next", 0); - grpc_chttp2_incoming_byte_stream *bs = - (grpc_chttp2_incoming_byte_stream *)byte_stream; - gpr_ref(&bs->refs); - bs->next_action.max_size_hint = max_size_hint; - bs->next_action.on_complete = on_complete; - grpc_closure_sched( - exec_ctx, - grpc_closure_init( - &bs->next_action.closure, incoming_byte_stream_next_locked, bs, - grpc_combiner_scheduler(bs->transport->combiner, false)), - GRPC_ERROR_NONE); - GPR_TIMER_END("incoming_byte_stream_next", 0); - return 0; -} - static void incoming_byte_stream_destroy(grpc_exec_ctx *exec_ctx, grpc_byte_stream *byte_stream); @@ -2634,7 +2588,6 @@ static void incoming_byte_stream_destroy_locked(grpc_exec_ctx *exec_ctx, grpc_error *error_ignored) { grpc_chttp2_incoming_byte_stream *bs = byte_stream; GPR_ASSERT(bs->base.destroy == incoming_byte_stream_destroy); - decrement_active_streams_locked(exec_ctx, bs->transport, bs->stream); incoming_byte_stream_unref(exec_ctx, bs); } @@ -2655,34 +2608,44 @@ static void incoming_byte_stream_destroy(grpc_exec_ctx *exec_ctx, static void incoming_byte_stream_publish_error( grpc_exec_ctx *exec_ctx, grpc_chttp2_incoming_byte_stream *bs, grpc_error *error) { + grpc_chttp2_stream *s = bs->stream; + GPR_ASSERT(error != GRPC_ERROR_NONE); - grpc_closure_sched(exec_ctx, bs->on_next, GRPC_ERROR_REF(error)); - bs->on_next = NULL; - GRPC_ERROR_UNREF(bs->error); + grpc_closure_sched(exec_ctx, s->on_next, GRPC_ERROR_REF(error)); + s->on_next = NULL; + GRPC_ERROR_UNREF(s->byte_stream_error); grpc_chttp2_cancel_stream(exec_ctx, bs->transport, bs->stream, GRPC_ERROR_REF(error)); - bs->error = error; + s->byte_stream_error = error; } -void grpc_chttp2_incoming_byte_stream_push(grpc_exec_ctx *exec_ctx, +grpc_error *grpc_chttp2_incoming_byte_stream_push(grpc_exec_ctx *exec_ctx, grpc_chttp2_incoming_byte_stream *bs, grpc_slice slice, grpc_slice *slice_out) { + grpc_chttp2_stream *s = bs->stream; + if (bs->remaining_bytes < GRPC_SLICE_LENGTH(slice)) { - incoming_byte_stream_publish_error( - exec_ctx, bs, - GRPC_ERROR_CREATE_FROM_STATIC_STRING("Too many bytes in stream")); + grpc_error *error = GRPC_ERROR_CREATE_FROM_STATIC_STRING("Too many bytes in stream"); + + grpc_closure_sched(exec_ctx, + &s->reset_byte_stream, GRPC_ERROR_REF(error)); + grpc_slice_unref_internal(exec_ctx, slice); + return error; } else { bs->remaining_bytes -= (uint32_t)GRPC_SLICE_LENGTH(slice); if (slice_out != NULL) { *slice_out = slice; } + return GRPC_ERROR_NONE; } } -void grpc_chttp2_incoming_byte_stream_finished( +grpc_error *grpc_chttp2_incoming_byte_stream_finished( grpc_exec_ctx *exec_ctx, grpc_chttp2_incoming_byte_stream *bs, grpc_error *error) { + grpc_chttp2_stream *s = bs->stream; + if (error == GRPC_ERROR_NONE) { gpr_mu_lock(&bs->slice_mu); if (bs->remaining_bytes != 0) { @@ -2691,9 +2654,11 @@ void grpc_chttp2_incoming_byte_stream_finished( gpr_mu_unlock(&bs->slice_mu); } if (error != GRPC_ERROR_NONE) { - incoming_byte_stream_publish_error(exec_ctx, bs, error); + grpc_closure_sched(exec_ctx, + &s->reset_byte_stream, GRPC_ERROR_REF(error)); } incoming_byte_stream_unref(exec_ctx, bs); + return error; } grpc_chttp2_incoming_byte_stream *grpc_chttp2_incoming_byte_stream_create( @@ -2712,14 +2677,10 @@ grpc_chttp2_incoming_byte_stream *grpc_chttp2_incoming_byte_stream_create( incoming_byte_stream->next_message = NULL; incoming_byte_stream->transport = t; incoming_byte_stream->stream = s; - gpr_ref(&incoming_byte_stream->stream->active_streams); grpc_slice_buffer_init(&incoming_byte_stream->slices); - incoming_byte_stream->on_next = NULL; incoming_byte_stream->is_tail = 1; - incoming_byte_stream->error = GRPC_ERROR_NONE; + s->byte_stream_error = GRPC_ERROR_NONE; incoming_byte_stream->push_closed = false; - s->incoming_frames = incoming_byte_stream; - grpc_chttp2_maybe_complete_recv_message(exec_ctx, t, s); return incoming_byte_stream; } diff --git a/src/core/ext/transport/chttp2/transport/frame_data.c b/src/core/ext/transport/chttp2/transport/frame_data.c index ecd53e2ce9..ecb941e366 100644 --- a/src/core/ext/transport/chttp2/transport/frame_data.c +++ b/src/core/ext/transport/chttp2/transport/frame_data.c @@ -63,7 +63,8 @@ void grpc_chttp2_data_parser_destroy(grpc_exec_ctx *exec_ctx, grpc_error *grpc_chttp2_data_parser_begin_frame(grpc_chttp2_data_parser *parser, uint8_t flags, - uint32_t stream_id) { + uint32_t stream_id, + grpc_chttp2_stream *s) { if (flags & ~GRPC_CHTTP2_DATA_FLAG_END_STREAM) { char *msg; gpr_asprintf(&msg, "unsupported data flags: 0x%02x", flags); @@ -75,9 +76,9 @@ grpc_error *grpc_chttp2_data_parser_begin_frame(grpc_chttp2_data_parser *parser, } if (flags & GRPC_CHTTP2_DATA_FLAG_END_STREAM) { - parser->is_last_frame = 1; + s->received_last_frame = true; } else { - parser->is_last_frame = 0; + s->received_last_frame = false; } return GRPC_ERROR_NONE; @@ -144,172 +145,31 @@ void grpc_chttp2_encode_data(uint32_t id, grpc_slice_buffer *inbuf, stats->data_bytes += write_bytes; } -static void grpc_chttp2_unprocessed_frames_buffer_push( - grpc_exec_ctx *exec_ctx, grpc_chttp2_data_parser *p, grpc_chttp2_stream *s, - grpc_slice slice) { - grpc_slice_buffer_add(&s->unprocessed_incoming_frames_buffer, slice); - if (p->parsing_frame) { - grpc_chttp2_incoming_byte_stream *bs = p->parsing_frame; - // Necessary? - gpr_mu_lock(&bs->slice_mu); - if (bs->on_next != NULL) { - grpc_closure_sched(exec_ctx, bs->on_next, GRPC_ERROR_NONE); - bs->on_next = NULL; - } - gpr_mu_unlock(&bs->slice_mu); - } -} - -grpc_error *parse_inner_buffer(grpc_exec_ctx *exec_ctx, - grpc_chttp2_data_parser *p, - grpc_chttp2_transport *t, grpc_chttp2_stream *s, - grpc_slice slice) { - uint8_t *const beg = GRPC_SLICE_START_PTR(slice); - uint8_t *const end = GRPC_SLICE_END_PTR(slice); - uint8_t *cur = beg; - uint32_t message_flags; - char *msg; - - if (cur == end) { - return GRPC_ERROR_NONE; - } - - /* If there is already pending data, or if there is a pending - * incoming_byte_stream that is finished, append the data to unprocessed frame - * buffer. */ - gpr_mu_lock(&s->buffer_mu); - if (s->unprocessed_incoming_frames_buffer.count > 0) { - s->stats.incoming.framing_bytes += GRPC_SLICE_LENGTH(slice); - grpc_slice_ref_internal(slice); - grpc_chttp2_unprocessed_frames_buffer_push(exec_ctx, p, s, slice); - gpr_mu_unlock(&s->buffer_mu); - return GRPC_ERROR_NONE; - } - - switch (p->state) { - case GRPC_CHTTP2_DATA_ERROR: - p->state = GRPC_CHTTP2_DATA_ERROR; - gpr_mu_unlock(&s->buffer_mu); - return GRPC_ERROR_REF(p->error); - fh_0: - case GRPC_CHTTP2_DATA_FH_0: - if (s->incoming_frames != NULL) { - s->stats.incoming.framing_bytes += (size_t)(end - cur); - grpc_chttp2_unprocessed_frames_buffer_push( - exec_ctx, p, s, - grpc_slice_sub(slice, (size_t)(cur - beg), (size_t)(end - beg))); - gpr_mu_unlock(&s->buffer_mu); - return GRPC_ERROR_NONE; - } - s->stats.incoming.framing_bytes++; - p->frame_type = *cur; - switch (p->frame_type) { - case 0: - p->is_frame_compressed = 0; /* GPR_FALSE */ - break; - case 1: - p->is_frame_compressed = 1; /* GPR_TRUE */ - break; - default: - gpr_asprintf(&msg, "Bad GRPC frame type 0x%02x", p->frame_type); - p->error = GRPC_ERROR_CREATE_FROM_COPIED_STRING(msg); - p->error = grpc_error_set_int(p->error, GRPC_ERROR_INT_STREAM_ID, - (intptr_t)s->id); - gpr_free(msg); - msg = grpc_dump_slice(slice, GPR_DUMP_HEX | GPR_DUMP_ASCII); - p->error = grpc_error_set_str(p->error, GRPC_ERROR_STR_RAW_BYTES, - grpc_slice_from_copied_string(msg)); - gpr_free(msg); - p->error = - grpc_error_set_int(p->error, GRPC_ERROR_INT_OFFSET, cur - beg); - p->state = GRPC_CHTTP2_DATA_ERROR; - gpr_mu_unlock(&s->buffer_mu); - return GRPC_ERROR_REF(p->error); - } - if (++cur == end) { - p->state = GRPC_CHTTP2_DATA_FH_1; - gpr_mu_unlock(&s->buffer_mu); - return GRPC_ERROR_NONE; - } - /* fallthrough */ - case GRPC_CHTTP2_DATA_FH_1: - s->stats.incoming.framing_bytes++; - p->frame_size = ((uint32_t)*cur) << 24; - if (++cur == end) { - p->state = GRPC_CHTTP2_DATA_FH_2; - gpr_mu_unlock(&s->buffer_mu); - return GRPC_ERROR_NONE; - } - /* fallthrough */ - case GRPC_CHTTP2_DATA_FH_2: - s->stats.incoming.framing_bytes++; - p->frame_size |= ((uint32_t)*cur) << 16; - if (++cur == end) { - p->state = GRPC_CHTTP2_DATA_FH_3; - gpr_mu_unlock(&s->buffer_mu); - return GRPC_ERROR_NONE; - } - /* fallthrough */ - case GRPC_CHTTP2_DATA_FH_3: - s->stats.incoming.framing_bytes++; - p->frame_size |= ((uint32_t)*cur) << 8; - if (++cur == end) { - p->state = GRPC_CHTTP2_DATA_FH_4; - gpr_mu_unlock(&s->buffer_mu); - return GRPC_ERROR_NONE; - } - /* fallthrough */ - case GRPC_CHTTP2_DATA_FH_4: - s->stats.incoming.framing_bytes++; - p->frame_size |= ((uint32_t)*cur); - p->state = GRPC_CHTTP2_DATA_FRAME; - ++cur; - message_flags = 0; - if (p->is_frame_compressed) { - message_flags |= GRPC_WRITE_INTERNAL_COMPRESS; - } - GPR_ASSERT(s->incoming_frames == NULL); - p->parsing_frame = grpc_chttp2_incoming_byte_stream_create( - exec_ctx, t, s, p->frame_size, message_flags); - /* fallthrough */ - case GRPC_CHTTP2_DATA_FRAME: - if (p->parsing_frame->remaining_bytes == 0) { - grpc_chttp2_incoming_byte_stream_finished(exec_ctx, p->parsing_frame, - GRPC_ERROR_NONE); - p->parsing_frame = NULL; - p->state = GRPC_CHTTP2_DATA_FH_0; - if (cur != end) { - goto fh_0; - } - } - if (cur == end) { - gpr_mu_unlock(&s->buffer_mu); - return GRPC_ERROR_NONE; - } - uint32_t remaining = (uint32_t)(end - cur); - s->stats.incoming.data_bytes += remaining; - grpc_chttp2_unprocessed_frames_buffer_push( - exec_ctx, p, s, - grpc_slice_sub(slice, (size_t)(cur - beg), (size_t)(end - beg))); - gpr_mu_unlock(&s->buffer_mu); - return GRPC_ERROR_NONE; - } - - GPR_UNREACHABLE_CODE( - return GRPC_ERROR_CREATE_FROM_STATIC_STRING("Should never reach here")); -} - grpc_error *grpc_chttp2_data_parser_parse(grpc_exec_ctx *exec_ctx, void *parser, grpc_chttp2_transport *t, grpc_chttp2_stream *s, grpc_slice slice, int is_last) { - grpc_chttp2_data_parser *p = parser; - grpc_error *error = parse_inner_buffer(exec_ctx, p, t, s, slice); + /* grpc_error *error = parse_inner_buffer(exec_ctx, p, t, s, slice); */ + s->stats.incoming.framing_bytes += GRPC_SLICE_LENGTH(slice); + if (!s->pending_byte_stream) { + grpc_slice_ref_internal(slice); + grpc_slice_buffer_add(&s->frame_storage, slice); + grpc_chttp2_maybe_complete_recv_message(exec_ctx, t, s); + } else if (s->on_next) { + GPR_ASSERT(s->frame_storage.length == 0); + grpc_slice_ref_internal(slice); + grpc_slice_buffer_add(&s->unprocessed_incoming_frames_buffer, slice); + grpc_closure_sched(exec_ctx, s->on_next, GRPC_ERROR_NONE); + s->on_next = NULL; + } else { + grpc_slice_ref_internal(slice); + grpc_slice_buffer_add(&s->frame_storage, slice); + } - if (is_last && p->is_last_frame) { + if (is_last && s->received_last_frame) { grpc_chttp2_mark_stream_closed(exec_ctx, t, s, true, false, GRPC_ERROR_NONE); } - return error; + return GRPC_ERROR_NONE; } diff --git a/src/core/ext/transport/chttp2/transport/frame_data.h b/src/core/ext/transport/chttp2/transport/frame_data.h index 264ad14608..e7e459c79f 100644 --- a/src/core/ext/transport/chttp2/transport/frame_data.h +++ b/src/core/ext/transport/chttp2/transport/frame_data.h @@ -63,7 +63,6 @@ typedef struct grpc_chttp2_incoming_frame_queue { typedef struct { grpc_chttp2_stream_state state; - uint8_t is_last_frame; uint8_t frame_type; uint32_t frame_size; grpc_error *error; @@ -87,7 +86,8 @@ void grpc_chttp2_data_parser_destroy(grpc_exec_ctx *exec_ctx, /* start processing a new data frame */ grpc_error *grpc_chttp2_data_parser_begin_frame(grpc_chttp2_data_parser *parser, uint8_t flags, - uint32_t stream_id); + uint32_t stream_id, + grpc_chttp2_stream *s); /* handle a slice of a data frame - is_last indicates the last slice of a frame */ diff --git a/src/core/ext/transport/chttp2/transport/internal.h b/src/core/ext/transport/chttp2/transport/internal.h index 5604ea3e31..917fc1b71e 100644 --- a/src/core/ext/transport/chttp2/transport/internal.h +++ b/src/core/ext/transport/chttp2/transport/internal.h @@ -187,7 +187,6 @@ struct grpc_chttp2_incoming_byte_stream { grpc_byte_stream base; gpr_refcount refs; struct grpc_chttp2_incoming_byte_stream *next_message; /* unused; should be removed */ - grpc_error *error; /* protected by slice_mu */ bool push_closed; /* protected by slice_mu */ grpc_chttp2_transport *transport; /* immutable */ @@ -196,7 +195,6 @@ struct grpc_chttp2_incoming_byte_stream { gpr_mu slice_mu; grpc_slice_buffer slices; /* unused; should be removed */ - grpc_closure *on_next; /* protected by slice_mu */ uint32_t remaining_bytes; /* guaranteed one thread access */ struct { @@ -462,9 +460,6 @@ struct grpc_chttp2_stream { grpc_transport_stream_stats *collecting_stats; grpc_transport_stream_stats stats; - /** number of streams that are currently being read */ - gpr_refcount active_streams; - /** Is this stream closed for writing. */ bool write_closed; /** Is this stream reading half-closed. */ @@ -488,10 +483,13 @@ struct grpc_chttp2_stream { grpc_chttp2_incoming_metadata_buffer metadata_buffer[2]; - grpc_chttp2_incoming_byte_stream *incoming_frames; /* protected by buffer_mu */ - gpr_mu buffer_mu; /* protects unprocessed_incoming_frames_buffer and - data_parser */ - grpc_slice_buffer unprocessed_incoming_frames_buffer; /* protected by buffer_mu */ + grpc_slice_buffer frame_storage; /* protected by t combiner */ + grpc_slice_buffer unprocessed_incoming_frames_buffer; /* guaranteed one thread access */ + grpc_closure *on_next; /* protected by t combiner */ + bool pending_byte_stream; /* protected by t combiner */ + grpc_closure reset_byte_stream; + grpc_error *byte_stream_error; /* protected by t combiner */ + bool received_last_frame; /* proected by t combiner */ gpr_timespec deadline; @@ -504,7 +502,7 @@ struct grpc_chttp2_stream { * incoming_window = incoming_window_delta + transport.initial_window_size */ int64_t incoming_window_delta; /** parsing state for data frames */ - grpc_chttp2_data_parser data_parser; /* protected by buffer_mu */ + grpc_chttp2_data_parser data_parser; /* guaranteed one thread access */ /** number of bytes received - reset at end of parse thread execution */ int64_t received_bytes; @@ -782,11 +780,11 @@ void grpc_chttp2_ref_transport(grpc_chttp2_transport *t); grpc_chttp2_incoming_byte_stream *grpc_chttp2_incoming_byte_stream_create( grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t, grpc_chttp2_stream *s, uint32_t frame_size, uint32_t flags); -void grpc_chttp2_incoming_byte_stream_push(grpc_exec_ctx *exec_ctx, - grpc_chttp2_incoming_byte_stream *bs, - grpc_slice slice, - grpc_slice *slice_out); -void grpc_chttp2_incoming_byte_stream_finished( +grpc_error *grpc_chttp2_incoming_byte_stream_push(grpc_exec_ctx *exec_ctx, + grpc_chttp2_incoming_byte_stream *bs, + grpc_slice slice, + grpc_slice *slice_out); +grpc_error *grpc_chttp2_incoming_byte_stream_finished( grpc_exec_ctx *exec_ctx, grpc_chttp2_incoming_byte_stream *bs, grpc_error *error); void grpc_chttp2_incoming_byte_stream_notify( diff --git a/src/core/ext/transport/chttp2/transport/parsing.c b/src/core/ext/transport/chttp2/transport/parsing.c index f1c6f96db5..2c662b6721 100644 --- a/src/core/ext/transport/chttp2/transport/parsing.c +++ b/src/core/ext/transport/chttp2/transport/parsing.c @@ -458,10 +458,8 @@ static grpc_error *init_data_frame_parser(grpc_exec_ctx *exec_ctx, return init_skip_frame_parser(exec_ctx, t, 0); } if (err == GRPC_ERROR_NONE) { - gpr_mu_lock(&s->buffer_mu); err = grpc_chttp2_data_parser_begin_frame(&s->data_parser, - t->incoming_frame_flags, s->id); - gpr_mu_unlock(&s->buffer_mu); + t->incoming_frame_flags, s->id, s); } error_handler: if (err == GRPC_ERROR_NONE) { diff --git a/src/core/lib/surface/call.c b/src/core/lib/surface/call.c index 963e16046a..6ea199e84f 100644 --- a/src/core/lib/surface/call.c +++ b/src/core/lib/surface/call.c @@ -1143,6 +1143,7 @@ static void finish_batch_step(grpc_exec_ctx *exec_ctx, batch_control *bctl) { static void continue_receiving_slices(grpc_exec_ctx *exec_ctx, batch_control *bctl) { + grpc_error *error; grpc_call *call = bctl->call; for (;;) { size_t remaining = call->receiving_stream->length - @@ -1156,10 +1157,20 @@ static void continue_receiving_slices(grpc_exec_ctx *exec_ctx, } if (grpc_byte_stream_next(exec_ctx, call->receiving_stream, remaining, &call->receiving_slice_ready)) { - grpc_byte_stream_pull(exec_ctx, call->receiving_stream, + error = grpc_byte_stream_pull(exec_ctx, call->receiving_stream, &call->receiving_slice); - grpc_slice_buffer_add(&(*call->receiving_buffer)->data.raw.slice_buffer, - call->receiving_slice); + if (error == GRPC_ERROR_NONE) { + grpc_slice_buffer_add(&(*call->receiving_buffer)->data.raw.slice_buffer, + call->receiving_slice); + } else { + grpc_byte_stream_destroy(exec_ctx, call->receiving_stream); + call->receiving_stream = NULL; + grpc_byte_buffer_destroy(*call->receiving_buffer); + *call->receiving_buffer = NULL; + call->receiving_message = 0; + finish_batch_step(exec_ctx, bctl); + return; + } } else { return; } -- cgit v1.2.3 From 69b2d2d40bd06b872bdf0c484a459831ed399dbc Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Sun, 2 Apr 2017 18:09:03 -0700 Subject: Bug fix --- src/core/ext/transport/chttp2/transport/chttp2_transport.c | 12 ++++++------ src/core/ext/transport/chttp2/transport/frame_data.c | 2 +- src/core/ext/transport/chttp2/transport/internal.h | 2 +- 3 files changed, 8 insertions(+), 8 deletions(-) (limited to 'src/core/ext/transport') diff --git a/src/core/ext/transport/chttp2/transport/chttp2_transport.c b/src/core/ext/transport/chttp2/transport/chttp2_transport.c index c86fefe2cf..2ac87b9b24 100644 --- a/src/core/ext/transport/chttp2/transport/chttp2_transport.c +++ b/src/core/ext/transport/chttp2/transport/chttp2_transport.c @@ -2364,7 +2364,7 @@ static grpc_error *deframe_unprocessed_incoming_frames( exec_ctx, t, s, p->frame_size, message_flags); *stream_out = &p->parsing_frame->base; if (p->parsing_frame->remaining_bytes == 0) { - grpc_chttp2_incoming_byte_stream_finished(exec_ctx, p->parsing_frame, GRPC_ERROR_NONE); + grpc_chttp2_incoming_byte_stream_finished(exec_ctx, p->parsing_frame, GRPC_ERROR_NONE, 1); p->parsing_frame = NULL; p->state = GRPC_CHTTP2_DATA_FH_0; } else { @@ -2393,7 +2393,7 @@ static grpc_error *deframe_unprocessed_incoming_frames( return error; } grpc_chttp2_incoming_byte_stream_finished(exec_ctx, p->parsing_frame, - GRPC_ERROR_NONE); + GRPC_ERROR_NONE, 1); p->parsing_frame = NULL; p->state = GRPC_CHTTP2_DATA_FH_0; grpc_closure_sched(exec_ctx, &s->reset_byte_stream, GRPC_ERROR_NONE); @@ -2416,7 +2416,7 @@ static grpc_error *deframe_unprocessed_incoming_frames( return error; } grpc_chttp2_incoming_byte_stream_finished(exec_ctx, p->parsing_frame, - GRPC_ERROR_NONE); + GRPC_ERROR_NONE, 1); p->parsing_frame = NULL; p->state = GRPC_CHTTP2_DATA_FH_0; cur += p->frame_size; @@ -2616,7 +2616,7 @@ static void incoming_byte_stream_publish_error( GRPC_ERROR_UNREF(s->byte_stream_error); grpc_chttp2_cancel_stream(exec_ctx, bs->transport, bs->stream, GRPC_ERROR_REF(error)); - s->byte_stream_error = error; + s->byte_stream_error = GRPC_ERROR_REF(error); } grpc_error *grpc_chttp2_incoming_byte_stream_push(grpc_exec_ctx *exec_ctx, @@ -2643,7 +2643,7 @@ grpc_error *grpc_chttp2_incoming_byte_stream_push(grpc_exec_ctx *exec_ctx, grpc_error *grpc_chttp2_incoming_byte_stream_finished( grpc_exec_ctx *exec_ctx, grpc_chttp2_incoming_byte_stream *bs, - grpc_error *error) { + grpc_error *error, int reset_on_error) { grpc_chttp2_stream *s = bs->stream; if (error == GRPC_ERROR_NONE) { @@ -2653,7 +2653,7 @@ grpc_error *grpc_chttp2_incoming_byte_stream_finished( } gpr_mu_unlock(&bs->slice_mu); } - if (error != GRPC_ERROR_NONE) { + if (error != GRPC_ERROR_NONE && reset_on_error) { grpc_closure_sched(exec_ctx, &s->reset_byte_stream, GRPC_ERROR_REF(error)); } diff --git a/src/core/ext/transport/chttp2/transport/frame_data.c b/src/core/ext/transport/chttp2/transport/frame_data.c index ecb941e366..8b42d05c72 100644 --- a/src/core/ext/transport/chttp2/transport/frame_data.c +++ b/src/core/ext/transport/chttp2/transport/frame_data.c @@ -56,7 +56,7 @@ void grpc_chttp2_data_parser_destroy(grpc_exec_ctx *exec_ctx, if (parser->parsing_frame != NULL) { grpc_chttp2_incoming_byte_stream_finished( exec_ctx, parser->parsing_frame, - GRPC_ERROR_CREATE_FROM_STATIC_STRING("Parser destroyed")); + GRPC_ERROR_CREATE_FROM_STATIC_STRING("Parser destroyed"), 0); } GRPC_ERROR_UNREF(parser->error); } diff --git a/src/core/ext/transport/chttp2/transport/internal.h b/src/core/ext/transport/chttp2/transport/internal.h index 917fc1b71e..a43c825b70 100644 --- a/src/core/ext/transport/chttp2/transport/internal.h +++ b/src/core/ext/transport/chttp2/transport/internal.h @@ -786,7 +786,7 @@ grpc_error *grpc_chttp2_incoming_byte_stream_push(grpc_exec_ctx *exec_ctx, grpc_slice *slice_out); grpc_error *grpc_chttp2_incoming_byte_stream_finished( grpc_exec_ctx *exec_ctx, grpc_chttp2_incoming_byte_stream *bs, - grpc_error *error); + grpc_error *error, int reset_on_error); void grpc_chttp2_incoming_byte_stream_notify( grpc_exec_ctx *exec_ctx, grpc_chttp2_incoming_byte_stream *bs, grpc_error *error); -- cgit v1.2.3 From 0fa217dfb938166c0442dc023db8095264f77e77 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Sun, 2 Apr 2017 18:18:51 -0700 Subject: clang-format --- .../transport/chttp2/transport/chttp2_transport.c | 123 ++++++++++++--------- src/core/ext/transport/chttp2/transport/internal.h | 35 +++--- src/core/ext/transport/chttp2/transport/parsing.c | 22 ++-- src/core/lib/surface/call.c | 2 +- 4 files changed, 101 insertions(+), 81 deletions(-) (limited to 'src/core/ext/transport') diff --git a/src/core/ext/transport/chttp2/transport/chttp2_transport.c b/src/core/ext/transport/chttp2/transport/chttp2_transport.c index 176382cb10..d3a4f35ea4 100644 --- a/src/core/ext/transport/chttp2/transport/chttp2_transport.c +++ b/src/core/ext/transport/chttp2/transport/chttp2_transport.c @@ -115,9 +115,9 @@ static void incoming_byte_stream_update_flow_control(grpc_exec_ctx *exec_ctx, static void incoming_byte_stream_destroy_locked(grpc_exec_ctx *exec_ctx, void *byte_stream, grpc_error *error_ignored); -static void incoming_byte_stream_publish_error(grpc_exec_ctx *exec_ctx, - grpc_chttp2_incoming_byte_stream *bs, - grpc_error *error); +static void incoming_byte_stream_publish_error( + grpc_exec_ctx *exec_ctx, grpc_chttp2_incoming_byte_stream *bs, + grpc_error *error); static void incoming_byte_stream_unref(grpc_exec_ctx *exec_ctx, grpc_chttp2_incoming_byte_stream *bs); @@ -161,12 +161,10 @@ static void finish_keepalive_ping_locked(grpc_exec_ctx *exec_ctx, void *arg, static void keepalive_watchdog_fired_locked(grpc_exec_ctx *exec_ctx, void *arg, grpc_error *error); -static grpc_error *deframe_unprocessed_incoming_frames(grpc_exec_ctx *exec_ctx, - grpc_chttp2_data_parser *p, - grpc_chttp2_stream *s, - grpc_slice_buffer *slices, - grpc_slice *slice_out, - grpc_byte_stream **stream_out); +static grpc_error *deframe_unprocessed_incoming_frames( + grpc_exec_ctx *exec_ctx, grpc_chttp2_data_parser *p, grpc_chttp2_stream *s, + grpc_slice_buffer *slices, grpc_slice *slice_out, + grpc_byte_stream **stream_out); static void reset_byte_stream(grpc_exec_ctx *exec_ctx, void *arg, grpc_error *error); @@ -615,7 +613,8 @@ static int init_stream(grpc_exec_ctx *exec_ctx, grpc_transport *gt, grpc_slice_buffer_init(&s->unprocessed_incoming_frames_buffer); grpc_slice_buffer_init(&s->frame_storage); s->pending_byte_stream = false; - grpc_closure_init(&s->reset_byte_stream, reset_byte_stream, s, grpc_combiner_scheduler(t->combiner, false)); + grpc_closure_init(&s->reset_byte_stream, reset_byte_stream, s, + grpc_combiner_scheduler(t->combiner, false)); GRPC_CHTTP2_REF_TRANSPORT(t, "stream"); @@ -1520,7 +1519,8 @@ void grpc_chttp2_maybe_complete_recv_initial_metadata(grpc_exec_ctx *exec_ctx, if (s->seen_error) { grpc_slice_buffer_reset_and_unref(&s->frame_storage); if (!s->pending_byte_stream) { - grpc_slice_buffer_reset_and_unref(&s->unprocessed_incoming_frames_buffer); + grpc_slice_buffer_reset_and_unref( + &s->unprocessed_incoming_frames_buffer); } } grpc_chttp2_incoming_metadata_buffer_publish( @@ -1539,21 +1539,26 @@ void grpc_chttp2_maybe_complete_recv_message(grpc_exec_ctx *exec_ctx, if (s->final_metadata_requested && s->seen_error) { grpc_slice_buffer_reset_and_unref(&s->frame_storage); if (!s->pending_byte_stream) { - grpc_slice_buffer_reset_and_unref(&s->unprocessed_incoming_frames_buffer); + grpc_slice_buffer_reset_and_unref( + &s->unprocessed_incoming_frames_buffer); } } if (!s->pending_byte_stream) { while (s->unprocessed_incoming_frames_buffer.length > 0 || s->frame_storage.length > 0) { if (s->unprocessed_incoming_frames_buffer.length == 0) { - grpc_slice_buffer_swap(&s->unprocessed_incoming_frames_buffer, &s->frame_storage); + grpc_slice_buffer_swap(&s->unprocessed_incoming_frames_buffer, + &s->frame_storage); } /* error handling ok? */ - error = deframe_unprocessed_incoming_frames(exec_ctx, &s->data_parser, s, &s->unprocessed_incoming_frames_buffer, NULL, s->recv_message); + error = deframe_unprocessed_incoming_frames( + exec_ctx, &s->data_parser, s, + &s->unprocessed_incoming_frames_buffer, NULL, s->recv_message); if (error != GRPC_ERROR_NONE) { s->seen_error = true; grpc_slice_buffer_reset_and_unref(&s->frame_storage); - grpc_slice_buffer_reset_and_unref(&s->unprocessed_incoming_frames_buffer); + grpc_slice_buffer_reset_and_unref( + &s->unprocessed_incoming_frames_buffer); break; } else if (*s->recv_message != NULL) { break; @@ -1578,7 +1583,8 @@ void grpc_chttp2_maybe_complete_recv_trailing_metadata(grpc_exec_ctx *exec_ctx, if (s->seen_error) { grpc_slice_buffer_reset_and_unref(&s->frame_storage); if (!s->pending_byte_stream) { - grpc_slice_buffer_reset_and_unref(&s->unprocessed_incoming_frames_buffer); + grpc_slice_buffer_reset_and_unref( + &s->unprocessed_incoming_frames_buffer); } } if (s->read_closed && s->frame_storage.length == 0 && @@ -2263,16 +2269,15 @@ static void reset_byte_stream(grpc_exec_ctx *exec_ctx, void *arg, grpc_closure_sched(exec_ctx, s->on_next, GRPC_ERROR_REF(error)); s->on_next = NULL; GRPC_ERROR_UNREF(s->byte_stream_error); - grpc_chttp2_cancel_stream(exec_ctx, s->t, s, - GRPC_ERROR_REF(error)); + grpc_chttp2_cancel_stream(exec_ctx, s->t, s, GRPC_ERROR_REF(error)); s->byte_stream_error = error; } } static grpc_error *deframe_unprocessed_incoming_frames( - grpc_exec_ctx *exec_ctx, grpc_chttp2_data_parser *p, - grpc_chttp2_stream *s, grpc_slice_buffer *slices, - grpc_slice *slice_out, grpc_byte_stream **stream_out) { + grpc_exec_ctx *exec_ctx, grpc_chttp2_data_parser *p, grpc_chttp2_stream *s, + grpc_slice_buffer *slices, grpc_slice *slice_out, + grpc_byte_stream **stream_out) { grpc_error *error = GRPC_ERROR_NONE; grpc_chttp2_transport *t = s->t; @@ -2368,7 +2373,8 @@ static grpc_error *deframe_unprocessed_incoming_frames( exec_ctx, t, s, p->frame_size, message_flags); *stream_out = &p->parsing_frame->base; if (p->parsing_frame->remaining_bytes == 0) { - grpc_chttp2_incoming_byte_stream_finished(exec_ctx, p->parsing_frame, GRPC_ERROR_NONE, 1); + grpc_chttp2_incoming_byte_stream_finished(exec_ctx, p->parsing_frame, + GRPC_ERROR_NONE, 1); p->parsing_frame = NULL; p->state = GRPC_CHTTP2_DATA_FH_0; } else { @@ -2376,7 +2382,9 @@ static grpc_error *deframe_unprocessed_incoming_frames( } if (cur != end) { - grpc_slice_buffer_undo_take_first(&s->unprocessed_incoming_frames_buffer, grpc_slice_sub(slice, (size_t)(cur - beg), (size_t)(end - beg))); + grpc_slice_buffer_undo_take_first( + &s->unprocessed_incoming_frames_buffer, + grpc_slice_sub(slice, (size_t)(cur - beg), (size_t)(end - beg))); } grpc_slice_unref(slice); return GRPC_ERROR_NONE; @@ -2390,9 +2398,10 @@ static grpc_error *deframe_unprocessed_incoming_frames( uint32_t remaining = (uint32_t)(end - cur); if (remaining == p->frame_size) { if (GRPC_ERROR_NONE != (error = grpc_chttp2_incoming_byte_stream_push( - exec_ctx, p->parsing_frame, - grpc_slice_sub(slice, (size_t)(cur - beg), (size_t)(end - beg)), - slice_out))) { + exec_ctx, p->parsing_frame, + grpc_slice_sub(slice, (size_t)(cur - beg), + (size_t)(end - beg)), + slice_out))) { grpc_slice_unref_internal(exec_ctx, slice); return error; } @@ -2405,9 +2414,10 @@ static grpc_error *deframe_unprocessed_incoming_frames( return GRPC_ERROR_NONE; } else if (remaining < p->frame_size) { if (GRPC_ERROR_NONE != (error = grpc_chttp2_incoming_byte_stream_push( - exec_ctx, p->parsing_frame, - grpc_slice_sub(slice, (size_t)(cur - beg), (size_t)(end - beg)), - slice_out))) { + exec_ctx, p->parsing_frame, + grpc_slice_sub(slice, (size_t)(cur - beg), + (size_t)(end - beg)), + slice_out))) { return error; } p->frame_size -= remaining; @@ -2415,7 +2425,12 @@ static grpc_error *deframe_unprocessed_incoming_frames( return GRPC_ERROR_NONE; } else { GPR_ASSERT(remaining > p->frame_size); - if (GRPC_ERROR_NONE != (grpc_chttp2_incoming_byte_stream_push(exec_ctx, p->parsing_frame, grpc_slice_sub(slice, (size_t)(cur - beg), (size_t)(cur + p->frame_size - beg)), slice_out))) { + if (GRPC_ERROR_NONE != + (grpc_chttp2_incoming_byte_stream_push( + exec_ctx, p->parsing_frame, + grpc_slice_sub(slice, (size_t)(cur - beg), + (size_t)(cur + p->frame_size - beg)), + slice_out))) { grpc_slice_unref_internal(exec_ctx, slice); return error; } @@ -2424,7 +2439,9 @@ static grpc_error *deframe_unprocessed_incoming_frames( p->parsing_frame = NULL; p->state = GRPC_CHTTP2_DATA_FH_0; cur += p->frame_size; - grpc_slice_buffer_undo_take_first(&s->unprocessed_incoming_frames_buffer, grpc_slice_sub(slice, (size_t)(cur - beg), (size_t)(end - beg))); + grpc_slice_buffer_undo_take_first( + &s->unprocessed_incoming_frames_buffer, + grpc_slice_sub(slice, (size_t)(cur - beg), (size_t)(end - beg))); grpc_closure_sched(exec_ctx, &s->reset_byte_stream, GRPC_ERROR_NONE); grpc_slice_unref(slice); return GRPC_ERROR_NONE; @@ -2506,7 +2523,8 @@ static void incoming_byte_stream_next_locked(grpc_exec_ctx *exec_ctx, GPR_ASSERT(s->unprocessed_incoming_frames_buffer.length == 0); if (s->frame_storage.length > 0) { - grpc_slice_buffer_swap(&s->frame_storage, &s->unprocessed_incoming_frames_buffer); + grpc_slice_buffer_swap(&s->frame_storage, + &s->unprocessed_incoming_frames_buffer); grpc_closure_sched(exec_ctx, bs->next_action.on_complete, GRPC_ERROR_NONE); } else if (s->byte_stream_error != GRPC_ERROR_NONE) { grpc_closure_sched(exec_ctx, bs->next_action.on_complete, @@ -2517,7 +2535,8 @@ static void incoming_byte_stream_next_locked(grpc_exec_ctx *exec_ctx, } } else if (s->read_closed) { if (bs->remaining_bytes != 0) { - s->byte_stream_error = GRPC_ERROR_CREATE_FROM_STATIC_STRING("Truncated message"); + s->byte_stream_error = + GRPC_ERROR_CREATE_FROM_STATIC_STRING("Truncated message"); grpc_closure_sched(exec_ctx, bs->next_action.on_complete, GRPC_ERROR_REF(s->byte_stream_error)); if (s->data_parser.parsing_frame != NULL) { @@ -2549,11 +2568,11 @@ static int incoming_byte_stream_next(grpc_exec_ctx *exec_ctx, bs->next_action.max_size_hint = max_size_hint; bs->next_action.on_complete = on_complete; grpc_closure_sched( - exec_ctx, - grpc_closure_init( - &bs->next_action.closure, incoming_byte_stream_next_locked, bs, - grpc_combiner_scheduler(bs->transport->combiner, false)), - GRPC_ERROR_NONE); + exec_ctx, + grpc_closure_init( + &bs->next_action.closure, incoming_byte_stream_next_locked, bs, + grpc_combiner_scheduler(bs->transport->combiner, false)), + GRPC_ERROR_NONE); GPR_TIMER_END("incoming_byte_stream_next", 0); return 0; } @@ -2564,20 +2583,20 @@ static grpc_error *incoming_byte_stream_pull(grpc_exec_ctx *exec_ctx, grpc_slice *slice) { GPR_TIMER_BEGIN("incoming_byte_stream_pull", 0); grpc_chttp2_incoming_byte_stream *bs = - (grpc_chttp2_incoming_byte_stream *)byte_stream; + (grpc_chttp2_incoming_byte_stream *)byte_stream; grpc_chttp2_stream *s = bs->stream; if (s->unprocessed_incoming_frames_buffer.length > 0) { grpc_error *error = deframe_unprocessed_incoming_frames( - exec_ctx, &s->data_parser, s, &s->unprocessed_incoming_frames_buffer, - slice, NULL); + exec_ctx, &s->data_parser, s, &s->unprocessed_incoming_frames_buffer, + slice, NULL); if (error != GRPC_ERROR_NONE) { return error; } } else { - grpc_error *error = GRPC_ERROR_CREATE_FROM_STATIC_STRING("Truncated message"); - grpc_closure_sched(exec_ctx, - &s->reset_byte_stream, GRPC_ERROR_REF(error)); + grpc_error *error = + GRPC_ERROR_CREATE_FROM_STATIC_STRING("Truncated message"); + grpc_closure_sched(exec_ctx, &s->reset_byte_stream, GRPC_ERROR_REF(error)); return error; } GPR_TIMER_END("incoming_byte_stream_pull", 0); @@ -2623,17 +2642,16 @@ static void incoming_byte_stream_publish_error( s->byte_stream_error = GRPC_ERROR_REF(error); } -grpc_error *grpc_chttp2_incoming_byte_stream_push(grpc_exec_ctx *exec_ctx, - grpc_chttp2_incoming_byte_stream *bs, - grpc_slice slice, - grpc_slice *slice_out) { +grpc_error *grpc_chttp2_incoming_byte_stream_push( + grpc_exec_ctx *exec_ctx, grpc_chttp2_incoming_byte_stream *bs, + grpc_slice slice, grpc_slice *slice_out) { grpc_chttp2_stream *s = bs->stream; if (bs->remaining_bytes < GRPC_SLICE_LENGTH(slice)) { - grpc_error *error = GRPC_ERROR_CREATE_FROM_STATIC_STRING("Too many bytes in stream"); + grpc_error *error = + GRPC_ERROR_CREATE_FROM_STATIC_STRING("Too many bytes in stream"); - grpc_closure_sched(exec_ctx, - &s->reset_byte_stream, GRPC_ERROR_REF(error)); + grpc_closure_sched(exec_ctx, &s->reset_byte_stream, GRPC_ERROR_REF(error)); grpc_slice_unref_internal(exec_ctx, slice); return error; } else { @@ -2658,8 +2676,7 @@ grpc_error *grpc_chttp2_incoming_byte_stream_finished( gpr_mu_unlock(&bs->slice_mu); } if (error != GRPC_ERROR_NONE && reset_on_error) { - grpc_closure_sched(exec_ctx, - &s->reset_byte_stream, GRPC_ERROR_REF(error)); + grpc_closure_sched(exec_ctx, &s->reset_byte_stream, GRPC_ERROR_REF(error)); } incoming_byte_stream_unref(exec_ctx, bs); return error; diff --git a/src/core/ext/transport/chttp2/transport/internal.h b/src/core/ext/transport/chttp2/transport/internal.h index a43c825b70..a2deac6315 100644 --- a/src/core/ext/transport/chttp2/transport/internal.h +++ b/src/core/ext/transport/chttp2/transport/internal.h @@ -186,22 +186,23 @@ typedef struct grpc_chttp2_write_cb { struct grpc_chttp2_incoming_byte_stream { grpc_byte_stream base; gpr_refcount refs; - struct grpc_chttp2_incoming_byte_stream *next_message; /* unused; should be removed */ - bool push_closed; /* protected by slice_mu */ + struct grpc_chttp2_incoming_byte_stream + *next_message; /* unused; should be removed */ + bool push_closed; /* protected by slice_mu */ grpc_chttp2_transport *transport; /* immutable */ grpc_chttp2_stream *stream; /* immutable */ bool is_tail; /* immutable */ gpr_mu slice_mu; - grpc_slice_buffer slices; /* unused; should be removed */ - uint32_t remaining_bytes; /* guaranteed one thread access */ + grpc_slice_buffer slices; /* unused; should be removed */ + uint32_t remaining_bytes; /* guaranteed one thread access */ struct { grpc_closure closure; size_t max_size_hint; grpc_closure *on_complete; - } next_action; /* guaranteed one thread access */ + } next_action; /* guaranteed one thread access */ grpc_closure destroy_action; grpc_closure finished_action; }; @@ -431,8 +432,8 @@ struct grpc_chttp2_stream { uint32_t id; /** window available for us to send to peer, over or under the initial window - * size of the transport... ie: - * outgoing_window = outgoing_window_delta + transport.initial_window_size */ + * size of the transport... ie: + * outgoing_window = outgoing_window_delta + transport.initial_window_size */ int64_t outgoing_window_delta; /** things the upper layers would like to send */ grpc_metadata_batch *send_initial_metadata; @@ -484,12 +485,13 @@ struct grpc_chttp2_stream { grpc_chttp2_incoming_metadata_buffer metadata_buffer[2]; grpc_slice_buffer frame_storage; /* protected by t combiner */ - grpc_slice_buffer unprocessed_incoming_frames_buffer; /* guaranteed one thread access */ - grpc_closure *on_next; /* protected by t combiner */ - bool pending_byte_stream; /* protected by t combiner */ + grpc_slice_buffer + unprocessed_incoming_frames_buffer; /* guaranteed one thread access */ + grpc_closure *on_next; /* protected by t combiner */ + bool pending_byte_stream; /* protected by t combiner */ grpc_closure reset_byte_stream; grpc_error *byte_stream_error; /* protected by t combiner */ - bool received_last_frame; /* proected by t combiner */ + bool received_last_frame; /* proected by t combiner */ gpr_timespec deadline; @@ -502,7 +504,7 @@ struct grpc_chttp2_stream { * incoming_window = incoming_window_delta + transport.initial_window_size */ int64_t incoming_window_delta; /** parsing state for data frames */ - grpc_chttp2_data_parser data_parser; /* guaranteed one thread access */ + grpc_chttp2_data_parser data_parser; /* guaranteed one thread access */ /** number of bytes received - reset at end of parse thread execution */ int64_t received_bytes; @@ -617,7 +619,7 @@ extern int grpc_flowctl_trace; if (!(grpc_http_trace)) \ ; \ else \ - stmt + stmt typedef enum { GRPC_CHTTP2_FLOWCTL_MOVE, @@ -780,10 +782,9 @@ void grpc_chttp2_ref_transport(grpc_chttp2_transport *t); grpc_chttp2_incoming_byte_stream *grpc_chttp2_incoming_byte_stream_create( grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t, grpc_chttp2_stream *s, uint32_t frame_size, uint32_t flags); -grpc_error *grpc_chttp2_incoming_byte_stream_push(grpc_exec_ctx *exec_ctx, - grpc_chttp2_incoming_byte_stream *bs, - grpc_slice slice, - grpc_slice *slice_out); +grpc_error *grpc_chttp2_incoming_byte_stream_push( + grpc_exec_ctx *exec_ctx, grpc_chttp2_incoming_byte_stream *bs, + grpc_slice slice, grpc_slice *slice_out); grpc_error *grpc_chttp2_incoming_byte_stream_finished( grpc_exec_ctx *exec_ctx, grpc_chttp2_incoming_byte_stream *bs, grpc_error *error, int reset_on_error); diff --git a/src/core/ext/transport/chttp2/transport/parsing.c b/src/core/ext/transport/chttp2/transport/parsing.c index 2c662b6721..bf1cf58cb2 100644 --- a/src/core/ext/transport/chttp2/transport/parsing.c +++ b/src/core/ext/transport/chttp2/transport/parsing.c @@ -230,10 +230,11 @@ grpc_error *grpc_chttp2_perform_read(grpc_exec_ctx *exec_ctx, case GRPC_DTS_FRAME: GPR_ASSERT(cur < end); if ((uint32_t)(end - cur) == t->incoming_frame_size) { - err = parse_frame_slice( - exec_ctx, t, grpc_slice_sub_no_ref(slice, (size_t)(cur - beg), - (size_t)(end - beg)), - 1); + err = + parse_frame_slice(exec_ctx, t, + grpc_slice_sub_no_ref(slice, (size_t)(cur - beg), + (size_t)(end - beg)), + 1); if (err != GRPC_ERROR_NONE) { return err; } @@ -254,10 +255,11 @@ grpc_error *grpc_chttp2_perform_read(grpc_exec_ctx *exec_ctx, t->incoming_stream = NULL; goto dts_fh_0; /* loop */ } else { - err = parse_frame_slice( - exec_ctx, t, grpc_slice_sub_no_ref(slice, (size_t)(cur - beg), - (size_t)(end - beg)), - 0); + err = + parse_frame_slice(exec_ctx, t, + grpc_slice_sub_no_ref(slice, (size_t)(cur - beg), + (size_t)(end - beg)), + 0); if (err != GRPC_ERROR_NONE) { return err; } @@ -458,8 +460,8 @@ static grpc_error *init_data_frame_parser(grpc_exec_ctx *exec_ctx, return init_skip_frame_parser(exec_ctx, t, 0); } if (err == GRPC_ERROR_NONE) { - err = grpc_chttp2_data_parser_begin_frame(&s->data_parser, - t->incoming_frame_flags, s->id, s); + err = grpc_chttp2_data_parser_begin_frame( + &s->data_parser, t->incoming_frame_flags, s->id, s); } error_handler: if (err == GRPC_ERROR_NONE) { diff --git a/src/core/lib/surface/call.c b/src/core/lib/surface/call.c index 6ea199e84f..c7b0b7ead3 100644 --- a/src/core/lib/surface/call.c +++ b/src/core/lib/surface/call.c @@ -1158,7 +1158,7 @@ static void continue_receiving_slices(grpc_exec_ctx *exec_ctx, if (grpc_byte_stream_next(exec_ctx, call->receiving_stream, remaining, &call->receiving_slice_ready)) { error = grpc_byte_stream_pull(exec_ctx, call->receiving_stream, - &call->receiving_slice); + &call->receiving_slice); if (error == GRPC_ERROR_NONE) { grpc_slice_buffer_add(&(*call->receiving_buffer)->data.raw.slice_buffer, call->receiving_slice); -- cgit v1.2.3 From ec9698f8364934808c0272008735ec16e1cf4e12 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Mon, 3 Apr 2017 11:27:16 -0700 Subject: Fix asan and use internal version of grpc_slice_buffer_reset_and_unref --- .../ext/transport/chttp2/transport/chttp2_transport.c | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) (limited to 'src/core/ext/transport') diff --git a/src/core/ext/transport/chttp2/transport/chttp2_transport.c b/src/core/ext/transport/chttp2/transport/chttp2_transport.c index d3a4f35ea4..63bb622c29 100644 --- a/src/core/ext/transport/chttp2/transport/chttp2_transport.c +++ b/src/core/ext/transport/chttp2/transport/chttp2_transport.c @@ -1517,9 +1517,9 @@ void grpc_chttp2_maybe_complete_recv_initial_metadata(grpc_exec_ctx *exec_ctx, if (s->recv_initial_metadata_ready != NULL && s->published_metadata[0] != GRPC_METADATA_NOT_PUBLISHED) { if (s->seen_error) { - grpc_slice_buffer_reset_and_unref(&s->frame_storage); + grpc_slice_buffer_reset_and_unref_internal(exec_ctx, &s->frame_storage); if (!s->pending_byte_stream) { - grpc_slice_buffer_reset_and_unref( + grpc_slice_buffer_reset_and_unref_internal(exec_ctx, &s->unprocessed_incoming_frames_buffer); } } @@ -1537,9 +1537,9 @@ void grpc_chttp2_maybe_complete_recv_message(grpc_exec_ctx *exec_ctx, if (s->recv_message_ready != NULL) { *s->recv_message = NULL; if (s->final_metadata_requested && s->seen_error) { - grpc_slice_buffer_reset_and_unref(&s->frame_storage); + grpc_slice_buffer_reset_and_unref_internal(exec_ctx, &s->frame_storage); if (!s->pending_byte_stream) { - grpc_slice_buffer_reset_and_unref( + grpc_slice_buffer_reset_and_unref_internal(exec_ctx, &s->unprocessed_incoming_frames_buffer); } } @@ -1556,8 +1556,8 @@ void grpc_chttp2_maybe_complete_recv_message(grpc_exec_ctx *exec_ctx, &s->unprocessed_incoming_frames_buffer, NULL, s->recv_message); if (error != GRPC_ERROR_NONE) { s->seen_error = true; - grpc_slice_buffer_reset_and_unref(&s->frame_storage); - grpc_slice_buffer_reset_and_unref( + grpc_slice_buffer_reset_and_unref_internal(exec_ctx, &s->frame_storage); + grpc_slice_buffer_reset_and_unref_internal(exec_ctx, &s->unprocessed_incoming_frames_buffer); break; } else if (*s->recv_message != NULL) { @@ -1581,9 +1581,9 @@ void grpc_chttp2_maybe_complete_recv_trailing_metadata(grpc_exec_ctx *exec_ctx, if (s->recv_trailing_metadata_finished != NULL && s->read_closed && s->write_closed) { if (s->seen_error) { - grpc_slice_buffer_reset_and_unref(&s->frame_storage); + grpc_slice_buffer_reset_and_unref_internal(exec_ctx, &s->frame_storage); if (!s->pending_byte_stream) { - grpc_slice_buffer_reset_and_unref( + grpc_slice_buffer_reset_and_unref_internal(exec_ctx, &s->unprocessed_incoming_frames_buffer); } } @@ -2678,6 +2678,7 @@ grpc_error *grpc_chttp2_incoming_byte_stream_finished( if (error != GRPC_ERROR_NONE && reset_on_error) { grpc_closure_sched(exec_ctx, &s->reset_byte_stream, GRPC_ERROR_REF(error)); } + GRPC_ERROR_UNREF(error); incoming_byte_stream_unref(exec_ctx, bs); return error; } -- cgit v1.2.3 From f5684b4e13bb8281a2246b3219a9e53cfa8d6bfb Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Mon, 3 Apr 2017 11:29:41 -0700 Subject: clang-format --- .../transport/chttp2/transport/chttp2_transport.c | 43 ++++++++++------------ src/core/ext/transport/chttp2/transport/internal.h | 2 +- src/core/ext/transport/chttp2/transport/parsing.c | 18 ++++----- 3 files changed, 29 insertions(+), 34 deletions(-) (limited to 'src/core/ext/transport') diff --git a/src/core/ext/transport/chttp2/transport/chttp2_transport.c b/src/core/ext/transport/chttp2/transport/chttp2_transport.c index 63bb622c29..301140311a 100644 --- a/src/core/ext/transport/chttp2/transport/chttp2_transport.c +++ b/src/core/ext/transport/chttp2/transport/chttp2_transport.c @@ -515,11 +515,10 @@ static void destroy_transport_locked(grpc_exec_ctx *exec_ctx, void *tp, static void destroy_transport(grpc_exec_ctx *exec_ctx, grpc_transport *gt) { grpc_chttp2_transport *t = (grpc_chttp2_transport *)gt; - grpc_closure_sched( - exec_ctx, - grpc_closure_create(destroy_transport_locked, t, - grpc_combiner_scheduler(t->combiner, false)), - GRPC_ERROR_NONE); + grpc_closure_sched(exec_ctx, grpc_closure_create( + destroy_transport_locked, t, + grpc_combiner_scheduler(t->combiner, false)), + GRPC_ERROR_NONE); } static void close_transport_locked(grpc_exec_ctx *exec_ctx, @@ -697,9 +696,8 @@ static void destroy_stream(grpc_exec_ctx *exec_ctx, grpc_transport *gt, s->destroy_stream_arg = then_schedule_closure; grpc_closure_sched( - exec_ctx, - grpc_closure_init(&s->destroy_stream, destroy_stream_locked, s, - grpc_combiner_scheduler(t->combiner, false)), + exec_ctx, grpc_closure_init(&s->destroy_stream, destroy_stream_locked, s, + grpc_combiner_scheduler(t->combiner, false)), GRPC_ERROR_NONE); GPR_TIMER_END("destroy_stream", 0); } @@ -1500,10 +1498,9 @@ static void perform_transport_op(grpc_exec_ctx *exec_ctx, grpc_transport *gt, op->transport_private.args[0] = gt; GRPC_CHTTP2_REF_TRANSPORT(t, "transport_op"); grpc_closure_sched( - exec_ctx, - grpc_closure_init(&op->transport_private.closure, - perform_transport_op_locked, op, - grpc_combiner_scheduler(t->combiner, false)), + exec_ctx, grpc_closure_init(&op->transport_private.closure, + perform_transport_op_locked, op, + grpc_combiner_scheduler(t->combiner, false)), GRPC_ERROR_NONE); } @@ -1519,8 +1516,8 @@ void grpc_chttp2_maybe_complete_recv_initial_metadata(grpc_exec_ctx *exec_ctx, if (s->seen_error) { grpc_slice_buffer_reset_and_unref_internal(exec_ctx, &s->frame_storage); if (!s->pending_byte_stream) { - grpc_slice_buffer_reset_and_unref_internal(exec_ctx, - &s->unprocessed_incoming_frames_buffer); + grpc_slice_buffer_reset_and_unref_internal( + exec_ctx, &s->unprocessed_incoming_frames_buffer); } } grpc_chttp2_incoming_metadata_buffer_publish( @@ -1539,8 +1536,8 @@ void grpc_chttp2_maybe_complete_recv_message(grpc_exec_ctx *exec_ctx, if (s->final_metadata_requested && s->seen_error) { grpc_slice_buffer_reset_and_unref_internal(exec_ctx, &s->frame_storage); if (!s->pending_byte_stream) { - grpc_slice_buffer_reset_and_unref_internal(exec_ctx, - &s->unprocessed_incoming_frames_buffer); + grpc_slice_buffer_reset_and_unref_internal( + exec_ctx, &s->unprocessed_incoming_frames_buffer); } } if (!s->pending_byte_stream) { @@ -1556,9 +1553,10 @@ void grpc_chttp2_maybe_complete_recv_message(grpc_exec_ctx *exec_ctx, &s->unprocessed_incoming_frames_buffer, NULL, s->recv_message); if (error != GRPC_ERROR_NONE) { s->seen_error = true; - grpc_slice_buffer_reset_and_unref_internal(exec_ctx, &s->frame_storage); grpc_slice_buffer_reset_and_unref_internal(exec_ctx, - &s->unprocessed_incoming_frames_buffer); + &s->frame_storage); + grpc_slice_buffer_reset_and_unref_internal( + exec_ctx, &s->unprocessed_incoming_frames_buffer); break; } else if (*s->recv_message != NULL) { break; @@ -1583,8 +1581,8 @@ void grpc_chttp2_maybe_complete_recv_trailing_metadata(grpc_exec_ctx *exec_ctx, if (s->seen_error) { grpc_slice_buffer_reset_and_unref_internal(exec_ctx, &s->frame_storage); if (!s->pending_byte_stream) { - grpc_slice_buffer_reset_and_unref_internal(exec_ctx, - &s->unprocessed_incoming_frames_buffer); + grpc_slice_buffer_reset_and_unref_internal( + exec_ctx, &s->unprocessed_incoming_frames_buffer); } } if (s->read_closed && s->frame_storage.length == 0 && @@ -2207,9 +2205,8 @@ static void keepalive_watchdog_fired_locked(grpc_exec_ctx *exec_ctx, void *arg, if (t->keepalive_state == GRPC_CHTTP2_KEEPALIVE_STATE_PINGING) { if (error == GRPC_ERROR_NONE) { t->keepalive_state = GRPC_CHTTP2_KEEPALIVE_STATE_DYING; - close_transport_locked( - exec_ctx, t, - GRPC_ERROR_CREATE_FROM_STATIC_STRING("keepalive watchdog timeout")); + close_transport_locked(exec_ctx, t, GRPC_ERROR_CREATE_FROM_STATIC_STRING( + "keepalive watchdog timeout")); } } else { /** The watchdog timer should have been cancelled by diff --git a/src/core/ext/transport/chttp2/transport/internal.h b/src/core/ext/transport/chttp2/transport/internal.h index a2deac6315..b4938dc281 100644 --- a/src/core/ext/transport/chttp2/transport/internal.h +++ b/src/core/ext/transport/chttp2/transport/internal.h @@ -619,7 +619,7 @@ extern int grpc_flowctl_trace; if (!(grpc_http_trace)) \ ; \ else \ - stmt + stmt typedef enum { GRPC_CHTTP2_FLOWCTL_MOVE, diff --git a/src/core/ext/transport/chttp2/transport/parsing.c b/src/core/ext/transport/chttp2/transport/parsing.c index bf1cf58cb2..638b137316 100644 --- a/src/core/ext/transport/chttp2/transport/parsing.c +++ b/src/core/ext/transport/chttp2/transport/parsing.c @@ -230,11 +230,10 @@ grpc_error *grpc_chttp2_perform_read(grpc_exec_ctx *exec_ctx, case GRPC_DTS_FRAME: GPR_ASSERT(cur < end); if ((uint32_t)(end - cur) == t->incoming_frame_size) { - err = - parse_frame_slice(exec_ctx, t, - grpc_slice_sub_no_ref(slice, (size_t)(cur - beg), - (size_t)(end - beg)), - 1); + err = parse_frame_slice( + exec_ctx, t, grpc_slice_sub_no_ref(slice, (size_t)(cur - beg), + (size_t)(end - beg)), + 1); if (err != GRPC_ERROR_NONE) { return err; } @@ -255,11 +254,10 @@ grpc_error *grpc_chttp2_perform_read(grpc_exec_ctx *exec_ctx, t->incoming_stream = NULL; goto dts_fh_0; /* loop */ } else { - err = - parse_frame_slice(exec_ctx, t, - grpc_slice_sub_no_ref(slice, (size_t)(cur - beg), - (size_t)(end - beg)), - 0); + err = parse_frame_slice( + exec_ctx, t, grpc_slice_sub_no_ref(slice, (size_t)(cur - beg), + (size_t)(end - beg)), + 0); if (err != GRPC_ERROR_NONE) { return err; } -- cgit v1.2.3 From c8f62bcb038b10d03e7cfa49cda7b197aed8fe54 Mon Sep 17 00:00:00 2001 From: Craig Tiller Date: Mon, 3 Apr 2017 16:25:45 -0700 Subject: Add new setting for true-binary mode --- CMakeLists.txt | 4 + Makefile | 4 + binding.gyp | 1 + build.yaml | 2 + config.m4 | 1 + gRPC-Core.podspec | 3 + grpc.gemspec | 2 + package.xml | 2 + .../transport/chttp2/transport/frame_settings.c | 38 ++---- .../transport/chttp2/transport/frame_settings.h | 30 +---- .../transport/chttp2/transport/http2_settings.c | 85 ++++++++++++++ .../transport/chttp2/transport/http2_settings.h | 74 ++++++++++++ src/python/grpcio/grpc_core_dependencies.py | 1 + tools/codegen/core/gen_settings_ids.py | 130 ++++++++++++++++++--- tools/doxygen/Doxyfile.core.internal | 2 + tools/run_tests/generated/sources_and_headers.json | 3 + vsprojects/vcxproj/grpc/grpc.vcxproj | 3 + vsprojects/vcxproj/grpc/grpc.vcxproj.filters | 6 + .../vcxproj/grpc_unsecure/grpc_unsecure.vcxproj | 3 + .../grpc_unsecure/grpc_unsecure.vcxproj.filters | 6 + 20 files changed, 326 insertions(+), 74 deletions(-) create mode 100644 src/core/ext/transport/chttp2/transport/http2_settings.c create mode 100644 src/core/ext/transport/chttp2/transport/http2_settings.h (limited to 'src/core/ext/transport') diff --git a/CMakeLists.txt b/CMakeLists.txt index e3b2558ad2..ca44f02c67 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1046,6 +1046,7 @@ add_library(grpc src/core/ext/transport/chttp2/transport/hpack_encoder.c src/core/ext/transport/chttp2/transport/hpack_parser.c src/core/ext/transport/chttp2/transport/hpack_table.c + src/core/ext/transport/chttp2/transport/http2_settings.c src/core/ext/transport/chttp2/transport/huffsyms.c src/core/ext/transport/chttp2/transport/incoming_metadata.c src/core/ext/transport/chttp2/transport/parsing.c @@ -1371,6 +1372,7 @@ add_library(grpc_cronet src/core/ext/transport/chttp2/transport/hpack_encoder.c src/core/ext/transport/chttp2/transport/hpack_parser.c src/core/ext/transport/chttp2/transport/hpack_table.c + src/core/ext/transport/chttp2/transport/http2_settings.c src/core/ext/transport/chttp2/transport/huffsyms.c src/core/ext/transport/chttp2/transport/incoming_metadata.c src/core/ext/transport/chttp2/transport/parsing.c @@ -1939,6 +1941,7 @@ add_library(grpc_unsecure src/core/ext/transport/chttp2/transport/hpack_encoder.c src/core/ext/transport/chttp2/transport/hpack_parser.c src/core/ext/transport/chttp2/transport/hpack_table.c + src/core/ext/transport/chttp2/transport/http2_settings.c src/core/ext/transport/chttp2/transport/huffsyms.c src/core/ext/transport/chttp2/transport/incoming_metadata.c src/core/ext/transport/chttp2/transport/parsing.c @@ -2691,6 +2694,7 @@ add_library(grpc++_cronet src/core/ext/transport/chttp2/transport/hpack_encoder.c src/core/ext/transport/chttp2/transport/hpack_parser.c src/core/ext/transport/chttp2/transport/hpack_table.c + src/core/ext/transport/chttp2/transport/http2_settings.c src/core/ext/transport/chttp2/transport/huffsyms.c src/core/ext/transport/chttp2/transport/incoming_metadata.c src/core/ext/transport/chttp2/transport/parsing.c diff --git a/Makefile b/Makefile index 7499dbbf50..61f5ffae67 100644 --- a/Makefile +++ b/Makefile @@ -2948,6 +2948,7 @@ LIBGRPC_SRC = \ src/core/ext/transport/chttp2/transport/hpack_encoder.c \ src/core/ext/transport/chttp2/transport/hpack_parser.c \ src/core/ext/transport/chttp2/transport/hpack_table.c \ + src/core/ext/transport/chttp2/transport/http2_settings.c \ src/core/ext/transport/chttp2/transport/huffsyms.c \ src/core/ext/transport/chttp2/transport/incoming_metadata.c \ src/core/ext/transport/chttp2/transport/parsing.c \ @@ -3271,6 +3272,7 @@ LIBGRPC_CRONET_SRC = \ src/core/ext/transport/chttp2/transport/hpack_encoder.c \ src/core/ext/transport/chttp2/transport/hpack_parser.c \ src/core/ext/transport/chttp2/transport/hpack_table.c \ + src/core/ext/transport/chttp2/transport/http2_settings.c \ src/core/ext/transport/chttp2/transport/huffsyms.c \ src/core/ext/transport/chttp2/transport/incoming_metadata.c \ src/core/ext/transport/chttp2/transport/parsing.c \ @@ -3810,6 +3812,7 @@ LIBGRPC_UNSECURE_SRC = \ src/core/ext/transport/chttp2/transport/hpack_encoder.c \ src/core/ext/transport/chttp2/transport/hpack_parser.c \ src/core/ext/transport/chttp2/transport/hpack_table.c \ + src/core/ext/transport/chttp2/transport/http2_settings.c \ src/core/ext/transport/chttp2/transport/huffsyms.c \ src/core/ext/transport/chttp2/transport/incoming_metadata.c \ src/core/ext/transport/chttp2/transport/parsing.c \ @@ -4547,6 +4550,7 @@ LIBGRPC++_CRONET_SRC = \ src/core/ext/transport/chttp2/transport/hpack_encoder.c \ src/core/ext/transport/chttp2/transport/hpack_parser.c \ src/core/ext/transport/chttp2/transport/hpack_table.c \ + src/core/ext/transport/chttp2/transport/http2_settings.c \ src/core/ext/transport/chttp2/transport/huffsyms.c \ src/core/ext/transport/chttp2/transport/incoming_metadata.c \ src/core/ext/transport/chttp2/transport/parsing.c \ diff --git a/binding.gyp b/binding.gyp index cd2de83bcb..01a2c49f19 100644 --- a/binding.gyp +++ b/binding.gyp @@ -754,6 +754,7 @@ 'src/core/ext/transport/chttp2/transport/hpack_encoder.c', 'src/core/ext/transport/chttp2/transport/hpack_parser.c', 'src/core/ext/transport/chttp2/transport/hpack_table.c', + 'src/core/ext/transport/chttp2/transport/http2_settings.c', 'src/core/ext/transport/chttp2/transport/huffsyms.c', 'src/core/ext/transport/chttp2/transport/incoming_metadata.c', 'src/core/ext/transport/chttp2/transport/parsing.c', diff --git a/build.yaml b/build.yaml index 8aff16854c..49a8b34657 100644 --- a/build.yaml +++ b/build.yaml @@ -658,6 +658,7 @@ filegroups: - src/core/ext/transport/chttp2/transport/hpack_encoder.h - src/core/ext/transport/chttp2/transport/hpack_parser.h - src/core/ext/transport/chttp2/transport/hpack_table.h + - src/core/ext/transport/chttp2/transport/http2_settings.h - src/core/ext/transport/chttp2/transport/huffsyms.h - src/core/ext/transport/chttp2/transport/incoming_metadata.h - src/core/ext/transport/chttp2/transport/internal.h @@ -677,6 +678,7 @@ filegroups: - src/core/ext/transport/chttp2/transport/hpack_encoder.c - src/core/ext/transport/chttp2/transport/hpack_parser.c - src/core/ext/transport/chttp2/transport/hpack_table.c + - src/core/ext/transport/chttp2/transport/http2_settings.c - src/core/ext/transport/chttp2/transport/huffsyms.c - src/core/ext/transport/chttp2/transport/incoming_metadata.c - src/core/ext/transport/chttp2/transport/parsing.c diff --git a/config.m4 b/config.m4 index 6e6a65a3de..f980bebda0 100644 --- a/config.m4 +++ b/config.m4 @@ -222,6 +222,7 @@ if test "$PHP_GRPC" != "no"; then src/core/ext/transport/chttp2/transport/hpack_encoder.c \ src/core/ext/transport/chttp2/transport/hpack_parser.c \ src/core/ext/transport/chttp2/transport/hpack_table.c \ + src/core/ext/transport/chttp2/transport/http2_settings.c \ src/core/ext/transport/chttp2/transport/huffsyms.c \ src/core/ext/transport/chttp2/transport/incoming_metadata.c \ src/core/ext/transport/chttp2/transport/parsing.c \ diff --git a/gRPC-Core.podspec b/gRPC-Core.podspec index d750a5b984..42e56abff5 100644 --- a/gRPC-Core.podspec +++ b/gRPC-Core.podspec @@ -379,6 +379,7 @@ Pod::Spec.new do |s| 'src/core/ext/transport/chttp2/transport/hpack_encoder.h', 'src/core/ext/transport/chttp2/transport/hpack_parser.h', 'src/core/ext/transport/chttp2/transport/hpack_table.h', + 'src/core/ext/transport/chttp2/transport/http2_settings.h', 'src/core/ext/transport/chttp2/transport/huffsyms.h', 'src/core/ext/transport/chttp2/transport/incoming_metadata.h', 'src/core/ext/transport/chttp2/transport/internal.h', @@ -597,6 +598,7 @@ Pod::Spec.new do |s| 'src/core/ext/transport/chttp2/transport/hpack_encoder.c', 'src/core/ext/transport/chttp2/transport/hpack_parser.c', 'src/core/ext/transport/chttp2/transport/hpack_table.c', + 'src/core/ext/transport/chttp2/transport/http2_settings.c', 'src/core/ext/transport/chttp2/transport/huffsyms.c', 'src/core/ext/transport/chttp2/transport/incoming_metadata.c', 'src/core/ext/transport/chttp2/transport/parsing.c', @@ -829,6 +831,7 @@ Pod::Spec.new do |s| 'src/core/ext/transport/chttp2/transport/hpack_encoder.h', 'src/core/ext/transport/chttp2/transport/hpack_parser.h', 'src/core/ext/transport/chttp2/transport/hpack_table.h', + 'src/core/ext/transport/chttp2/transport/http2_settings.h', 'src/core/ext/transport/chttp2/transport/huffsyms.h', 'src/core/ext/transport/chttp2/transport/incoming_metadata.h', 'src/core/ext/transport/chttp2/transport/internal.h', diff --git a/grpc.gemspec b/grpc.gemspec index 42d4298c9b..7b8761cb95 100755 --- a/grpc.gemspec +++ b/grpc.gemspec @@ -295,6 +295,7 @@ Gem::Specification.new do |s| s.files += %w( src/core/ext/transport/chttp2/transport/hpack_encoder.h ) s.files += %w( src/core/ext/transport/chttp2/transport/hpack_parser.h ) s.files += %w( src/core/ext/transport/chttp2/transport/hpack_table.h ) + s.files += %w( src/core/ext/transport/chttp2/transport/http2_settings.h ) s.files += %w( src/core/ext/transport/chttp2/transport/huffsyms.h ) s.files += %w( src/core/ext/transport/chttp2/transport/incoming_metadata.h ) s.files += %w( src/core/ext/transport/chttp2/transport/internal.h ) @@ -513,6 +514,7 @@ Gem::Specification.new do |s| s.files += %w( src/core/ext/transport/chttp2/transport/hpack_encoder.c ) s.files += %w( src/core/ext/transport/chttp2/transport/hpack_parser.c ) s.files += %w( src/core/ext/transport/chttp2/transport/hpack_table.c ) + s.files += %w( src/core/ext/transport/chttp2/transport/http2_settings.c ) s.files += %w( src/core/ext/transport/chttp2/transport/huffsyms.c ) s.files += %w( src/core/ext/transport/chttp2/transport/incoming_metadata.c ) s.files += %w( src/core/ext/transport/chttp2/transport/parsing.c ) diff --git a/package.xml b/package.xml index 382393cbe5..26be06621f 100644 --- a/package.xml +++ b/package.xml @@ -304,6 +304,7 @@ + @@ -522,6 +523,7 @@ + diff --git a/src/core/ext/transport/chttp2/transport/frame_settings.c b/src/core/ext/transport/chttp2/transport/frame_settings.c index 16881c0707..5719bf19b2 100644 --- a/src/core/ext/transport/chttp2/transport/frame_settings.c +++ b/src/core/ext/transport/chttp2/transport/frame_settings.c @@ -48,27 +48,6 @@ #define MAX_MAX_HEADER_LIST_SIZE (1024 * 1024 * 1024) -/* HTTP/2 mandated initial connection settings */ -const grpc_chttp2_setting_parameters - grpc_chttp2_settings_parameters[GRPC_CHTTP2_NUM_SETTINGS] = { - {NULL, 0, 0, 0, GRPC_CHTTP2_DISCONNECT_ON_INVALID_VALUE, - GRPC_HTTP2_PROTOCOL_ERROR}, - {"HEADER_TABLE_SIZE", 4096, 0, 0xffffffff, - GRPC_CHTTP2_CLAMP_INVALID_VALUE, GRPC_HTTP2_PROTOCOL_ERROR}, - {"ENABLE_PUSH", 1, 0, 1, GRPC_CHTTP2_DISCONNECT_ON_INVALID_VALUE, - GRPC_HTTP2_PROTOCOL_ERROR}, - {"MAX_CONCURRENT_STREAMS", 0xffffffffu, 0, 0xffffffffu, - GRPC_CHTTP2_DISCONNECT_ON_INVALID_VALUE, GRPC_HTTP2_PROTOCOL_ERROR}, - {"INITIAL_WINDOW_SIZE", 65535, 0, 0x7fffffffu, - GRPC_CHTTP2_DISCONNECT_ON_INVALID_VALUE, - GRPC_HTTP2_FLOW_CONTROL_ERROR}, - {"MAX_FRAME_SIZE", 16384, 16384, 16777215, - GRPC_CHTTP2_DISCONNECT_ON_INVALID_VALUE, GRPC_HTTP2_PROTOCOL_ERROR}, - {"MAX_HEADER_LIST_SIZE", MAX_MAX_HEADER_LIST_SIZE, 0, - MAX_MAX_HEADER_LIST_SIZE, GRPC_CHTTP2_CLAMP_INVALID_VALUE, - GRPC_HTTP2_PROTOCOL_ERROR}, -}; - static uint8_t *fill_header(uint8_t *out, uint32_t length, uint8_t flags) { *out++ = (uint8_t)(length >> 16); *out++ = (uint8_t)(length >> 8); @@ -99,8 +78,8 @@ grpc_slice grpc_chttp2_settings_create(uint32_t *old, const uint32_t *new, for (i = 0; i < count; i++) { if (new[i] != old[i] || (force_mask & (1u << i)) != 0) { GPR_ASSERT(i); - *p++ = (uint8_t)(i >> 8); - *p++ = (uint8_t)(i); + *p++ = (uint8_t)(grpc_setting_id_to_wire_id[i] >> 8); + *p++ = (uint8_t)(grpc_setting_id_to_wire_id[i]); *p++ = (uint8_t)(new[i] >> 24); *p++ = (uint8_t)(new[i] >> 16); *p++ = (uint8_t)(new[i] >> 8); @@ -154,6 +133,7 @@ grpc_error *grpc_chttp2_settings_parser_parse(grpc_exec_ctx *exec_ctx, void *p, const uint8_t *cur = GRPC_SLICE_START_PTR(slice); const uint8_t *end = GRPC_SLICE_END_PTR(slice); char *msg; + grpc_chttp2_setting_id id; if (parser->is_ack) { return GRPC_ERROR_NONE; @@ -216,9 +196,9 @@ grpc_error *grpc_chttp2_settings_parser_parse(grpc_exec_ctx *exec_ctx, void *p, parser->value |= *cur; cur++; - if (parser->id > 0 && parser->id < GRPC_CHTTP2_NUM_SETTINGS) { + if (grpc_wire_id_to_setting_id(parser->id, &id)) { const grpc_chttp2_setting_parameters *sp = - &grpc_chttp2_settings_parameters[parser->id]; + &grpc_chttp2_settings_parameters[id]; if (parser->value < sp->min_value || parser->value > sp->max_value) { switch (sp->invalid_value_behavior) { case GRPC_CHTTP2_CLAMP_INVALID_VALUE: @@ -237,16 +217,16 @@ grpc_error *grpc_chttp2_settings_parser_parse(grpc_exec_ctx *exec_ctx, void *p, return err; } } - if (parser->id == GRPC_CHTTP2_SETTINGS_INITIAL_WINDOW_SIZE && - parser->incoming_settings[parser->id] != parser->value) { + if (id == GRPC_CHTTP2_SETTINGS_INITIAL_WINDOW_SIZE && + parser->incoming_settings[id] != parser->value) { t->initial_window_update += - (int64_t)parser->value - parser->incoming_settings[parser->id]; + (int64_t)parser->value - parser->incoming_settings[id]; if (grpc_http_trace) { gpr_log(GPR_DEBUG, "adding %d for initial_window change", (int)t->initial_window_update); } } - parser->incoming_settings[parser->id] = parser->value; + parser->incoming_settings[id] = parser->value; if (grpc_http_trace) { gpr_log(GPR_DEBUG, "CHTTP2:%s:%s: got setting %d = %d", t->is_client ? "CLI" : "SVR", t->peer_string, parser->id, diff --git a/src/core/ext/transport/chttp2/transport/frame_settings.h b/src/core/ext/transport/chttp2/transport/frame_settings.h index 44137798c0..2a85d0dba7 100644 --- a/src/core/ext/transport/chttp2/transport/frame_settings.h +++ b/src/core/ext/transport/chttp2/transport/frame_settings.h @@ -37,6 +37,7 @@ #include #include #include "src/core/ext/transport/chttp2/transport/frame.h" +#include "src/core/ext/transport/chttp2/transport/http2_settings.h" #include "src/core/lib/iomgr/exec_ctx.h" typedef enum { @@ -48,17 +49,6 @@ typedef enum { GRPC_CHTTP2_SPS_VAL3 } grpc_chttp2_settings_parse_state; -/* The things HTTP/2 defines as connection level settings */ -typedef enum { - GRPC_CHTTP2_SETTINGS_HEADER_TABLE_SIZE = 1, - GRPC_CHTTP2_SETTINGS_ENABLE_PUSH = 2, - GRPC_CHTTP2_SETTINGS_MAX_CONCURRENT_STREAMS = 3, - GRPC_CHTTP2_SETTINGS_INITIAL_WINDOW_SIZE = 4, - GRPC_CHTTP2_SETTINGS_MAX_FRAME_SIZE = 5, - GRPC_CHTTP2_SETTINGS_MAX_HEADER_LIST_SIZE = 6, - GRPC_CHTTP2_NUM_SETTINGS -} grpc_chttp2_setting_id; - typedef struct { grpc_chttp2_settings_parse_state state; uint32_t *target_settings; @@ -68,24 +58,6 @@ typedef struct { uint32_t incoming_settings[GRPC_CHTTP2_NUM_SETTINGS]; } grpc_chttp2_settings_parser; -typedef enum { - GRPC_CHTTP2_CLAMP_INVALID_VALUE, - GRPC_CHTTP2_DISCONNECT_ON_INVALID_VALUE -} grpc_chttp2_invalid_value_behavior; - -typedef struct { - const char *name; - uint32_t default_value; - uint32_t min_value; - uint32_t max_value; - grpc_chttp2_invalid_value_behavior invalid_value_behavior; - uint32_t error_value; -} grpc_chttp2_setting_parameters; - -/* HTTP/2 mandated connection setting parameters */ -extern const grpc_chttp2_setting_parameters - grpc_chttp2_settings_parameters[GRPC_CHTTP2_NUM_SETTINGS]; - /* Create a settings frame by diffing old & new, and updating old to be new */ grpc_slice grpc_chttp2_settings_create(uint32_t *old, const uint32_t *newval, uint32_t force_mask, size_t count); diff --git a/src/core/ext/transport/chttp2/transport/http2_settings.c b/src/core/ext/transport/chttp2/transport/http2_settings.c new file mode 100644 index 0000000000..eea6305c8e --- /dev/null +++ b/src/core/ext/transport/chttp2/transport/http2_settings.c @@ -0,0 +1,85 @@ +/* + * Copyright 2015, Google Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/* + * Automatically generated by tools/codegen/core/gen_settings_ids.py + */ + +#include "src/core/ext/transport/chttp2/transport/http2_settings.h" + +#include +#include "src/core/lib/transport/http2_errors.h" + +const uint16_t grpc_setting_id_to_wire_id[] = {1, 2, 3, 4, 5, 6, 65027}; + +bool grpc_wire_id_to_setting_id(uint32_t wire_id, grpc_chttp2_setting_id *out) { + static const uint32_t r[] = { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0}; + uint32_t i = wire_id - 1; + uint32_t x = i % 256; + uint32_t y = i / 256; + uint32_t h = x; + if (y < GPR_ARRAY_SIZE(r)) { + uint32_t delta = (uint32_t)r[y]; + h += delta; + } + *out = (grpc_chttp2_setting_id)i; + return i < GPR_ARRAY_SIZE(grpc_setting_id_to_wire_id) && + grpc_setting_id_to_wire_id[i] == wire_id; +} +const grpc_chttp2_setting_parameters + grpc_chttp2_settings_parameters[GRPC_CHTTP2_NUM_SETTINGS] = { + {"HEADER_TABLE_SIZE", 4096u, 0u, 4294967295u, + GRPC_CHTTP2_CLAMP_INVALID_VALUE, GRPC_HTTP2_PROTOCOL_ERROR}, + {"ENABLE_PUSH", 1u, 0u, 1u, GRPC_CHTTP2_DISCONNECT_ON_INVALID_VALUE, + GRPC_HTTP2_PROTOCOL_ERROR}, + {"MAX_CONCURRENT_STREAMS", 4294967295u, 0u, 4294967295u, + GRPC_CHTTP2_DISCONNECT_ON_INVALID_VALUE, GRPC_HTTP2_PROTOCOL_ERROR}, + {"INITIAL_WINDOW_SIZE", 65535u, 0u, 2147483647u, + GRPC_CHTTP2_DISCONNECT_ON_INVALID_VALUE, + GRPC_HTTP2_FLOW_CONTROL_ERROR}, + {"MAX_FRAME_SIZE", 16384u, 16384u, 16777215u, + GRPC_CHTTP2_DISCONNECT_ON_INVALID_VALUE, GRPC_HTTP2_PROTOCOL_ERROR}, + {"MAX_HEADER_LIST_SIZE", 16777216u, 0u, 16777216u, + GRPC_CHTTP2_CLAMP_INVALID_VALUE, GRPC_HTTP2_PROTOCOL_ERROR}, + {"GRPC_ALLOW_TRUE_BINARY_METADATA", 0u, 0u, 1u, + GRPC_CHTTP2_CLAMP_INVALID_VALUE, GRPC_HTTP2_PROTOCOL_ERROR}, +}; diff --git a/src/core/ext/transport/chttp2/transport/http2_settings.h b/src/core/ext/transport/chttp2/transport/http2_settings.h new file mode 100644 index 0000000000..393c14f7f1 --- /dev/null +++ b/src/core/ext/transport/chttp2/transport/http2_settings.h @@ -0,0 +1,74 @@ +/* + * Copyright 2015, Google Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/* + * Automatically generated by tools/codegen/core/gen_settings_ids.py + */ + +#ifndef SRC_CORE_EXT_TRANSPORT_CHTTP2_TRANSPORT_HTTP2_SETTINGS_H +#define SRC_CORE_EXT_TRANSPORT_CHTTP2_TRANSPORT_HTTP2_SETTINGS_H + +#include +#include + +typedef enum { + GRPC_CHTTP2_SETTINGS_ENABLE_PUSH = 1, /* wire id 2 */ + GRPC_CHTTP2_SETTINGS_GRPC_ALLOW_TRUE_BINARY_METADATA = 6, /* wire id 65027 */ + GRPC_CHTTP2_SETTINGS_HEADER_TABLE_SIZE = 0, /* wire id 1 */ + GRPC_CHTTP2_SETTINGS_INITIAL_WINDOW_SIZE = 3, /* wire id 4 */ + GRPC_CHTTP2_SETTINGS_MAX_CONCURRENT_STREAMS = 2, /* wire id 3 */ + GRPC_CHTTP2_SETTINGS_MAX_FRAME_SIZE = 4, /* wire id 5 */ + GRPC_CHTTP2_SETTINGS_MAX_HEADER_LIST_SIZE = 5, /* wire id 6 */ +} grpc_chttp2_setting_id; + +#define GRPC_CHTTP2_NUM_SETTINGS 7 +extern const uint16_t grpc_setting_id_to_wire_id[]; + +bool grpc_wire_id_to_setting_id(uint32_t wire_id, grpc_chttp2_setting_id *out); + +typedef enum { + GRPC_CHTTP2_CLAMP_INVALID_VALUE, + GRPC_CHTTP2_DISCONNECT_ON_INVALID_VALUE +} grpc_chttp2_invalid_value_behavior; + +typedef struct { + const char *name; + uint32_t default_value; + uint32_t min_value; + uint32_t max_value; + grpc_chttp2_invalid_value_behavior invalid_value_behavior; + uint32_t error_value; +} grpc_chttp2_setting_parameters; + +extern const grpc_chttp2_setting_parameters + grpc_chttp2_settings_parameters[GRPC_CHTTP2_NUM_SETTINGS]; + +#endif /* SRC_CORE_EXT_TRANSPORT_CHTTP2_TRANSPORT_HTTP2_SETTINGS_H */ diff --git a/src/python/grpcio/grpc_core_dependencies.py b/src/python/grpcio/grpc_core_dependencies.py index ed8793b019..522791e17a 100644 --- a/src/python/grpcio/grpc_core_dependencies.py +++ b/src/python/grpcio/grpc_core_dependencies.py @@ -216,6 +216,7 @@ CORE_SOURCE_FILES = [ 'src/core/ext/transport/chttp2/transport/hpack_encoder.c', 'src/core/ext/transport/chttp2/transport/hpack_parser.c', 'src/core/ext/transport/chttp2/transport/hpack_table.c', + 'src/core/ext/transport/chttp2/transport/http2_settings.c', 'src/core/ext/transport/chttp2/transport/huffsyms.c', 'src/core/ext/transport/chttp2/transport/incoming_metadata.c', 'src/core/ext/transport/chttp2/transport/parsing.c', diff --git a/tools/codegen/core/gen_settings_ids.py b/tools/codegen/core/gen_settings_ids.py index fa3aad1f1f..c807f70c2a 100755 --- a/tools/codegen/core/gen_settings_ids.py +++ b/tools/codegen/core/gen_settings_ids.py @@ -29,19 +29,71 @@ # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +import collections import perfection +import sys + +_MAX_HEADER_LIST_SIZE = 16 * 1024 * 1024 + +Setting = collections.namedtuple('Setting', 'id default min max on_error') +OnError = collections.namedtuple('OnError', 'behavior code') +clamp_invalid_value = OnError('CLAMP_INVALID_VALUE', 'PROTOCOL_ERROR') +disconnect_on_invalid_value = lambda e: OnError('DISCONNECT_ON_INVALID_VALUE', e) +DecoratedSetting = collections.namedtuple('DecoratedSetting', 'enum name setting') _SETTINGS = { - 'HEADER_TABLE_SIZE': 1, - 'ENABLE_PUSH': 2, - 'MAX_CONCURRENT_STREAMS': 3, - 'INITIAL_WINDOW_SIZE': 4, - 'MAX_FRAME_SIZE': 5, - 'MAX_HEADER_LIST_SIZE': 6, - 'GRPC_ALLOW_TRUE_BINARY_METADATA': 0xfe03, + 'HEADER_TABLE_SIZE': Setting(1, 4096, 0, 0xffffffff, clamp_invalid_value), + 'ENABLE_PUSH': Setting(2, 1, 0, 1, disconnect_on_invalid_value('PROTOCOL_ERROR')), + 'MAX_CONCURRENT_STREAMS': Setting(3, 0xffffffff, 0, 0xffffffff, disconnect_on_invalid_value('PROTOCOL_ERROR')), + 'INITIAL_WINDOW_SIZE': Setting(4, 65535, 0, 0x7fffffff, disconnect_on_invalid_value('FLOW_CONTROL_ERROR')), + 'MAX_FRAME_SIZE': Setting(5, 16384, 16384, 16777215, disconnect_on_invalid_value('PROTOCOL_ERROR')), + 'MAX_HEADER_LIST_SIZE': Setting(6, _MAX_HEADER_LIST_SIZE, 0, _MAX_HEADER_LIST_SIZE, clamp_invalid_value), + 'GRPC_ALLOW_TRUE_BINARY_METADATA': Setting(0xfe03, 0, 0, 1, clamp_invalid_value), } -p = perfection.hash_parameters(sorted(_SETTINGS.values())) +H = open('src/core/ext/transport/chttp2/transport/http2_settings.h', 'w') +C = open('src/core/ext/transport/chttp2/transport/http2_settings.c', 'w') + +# utility: print a big comment block into a set of files +def put_banner(files, banner): + for f in files: + print >>f, '/*' + for line in banner: + print >>f, ' * %s' % line + print >>f, ' */' + print >>f + +# copy-paste copyright notice from this file +with open(sys.argv[0]) as my_source: + copyright = [] + for line in my_source: + if line[0] != '#': break + for line in my_source: + if line[0] == '#': + copyright.append(line) + break + for line in my_source: + if line[0] != '#': + break + copyright.append(line) + put_banner([H,C], [line[2:].rstrip() for line in copyright]) + +put_banner([H,C], ["Automatically generated by tools/codegen/core/gen_settings_ids.py"]) + +print >>H, "#ifndef SRC_CORE_EXT_TRANSPORT_CHTTP2_TRANSPORT_HTTP2_SETTINGS_H" +print >>H, "#define SRC_CORE_EXT_TRANSPORT_CHTTP2_TRANSPORT_HTTP2_SETTINGS_H" +print >>H +print >>H, "#include " +print >>H, "#include " +print >>H + +print >>C, "#include \"src/core/ext/transport/chttp2/transport/http2_settings.h\"" +print >>C +print >>C, "#include " +print >>C, "#include \"src/core/lib/transport/http2_errors.h\"" +print >>C + +p = perfection.hash_parameters(sorted(x.id for x in _SETTINGS.values())) print p def hash(i): @@ -50,17 +102,24 @@ def hash(i): y = i / p.t return x + p.r[y] -print 'typedef enum {' +decorated_settings = [DecoratedSetting(hash(setting.id), name, setting) + for name, setting in _SETTINGS.iteritems()] + +print >>H, 'typedef enum {' for name in sorted(_SETTINGS.keys()): - index = _SETTINGS[name] - print ' GRPC_CHTTP2_SETTING_%s = %d, /* wire id %d */' % ( - name, hash(index), index) -print '} grpc_chttp2_setting_id;' + setting = _SETTINGS[name] + print >>H, ' GRPC_CHTTP2_SETTINGS_%s = %d, /* wire id %d */' % ( + name, hash(setting.id), setting.id) +print >>H, '} grpc_chttp2_setting_id;' +print >>H +print >>H, '#define GRPC_CHTTP2_NUM_SETTINGS %d' % (max(x.enum for x in decorated_settings) + 1) -print 'const uint16_t grpc_setting_id_to_wire_id[] = {%s};' % ','.join( +print >>H, 'extern const uint16_t grpc_setting_id_to_wire_id[];' +print >>C, 'const uint16_t grpc_setting_id_to_wire_id[] = {%s};' % ','.join( '%d' % s for s in p.slots) - -print """ +print >>H +print >>H, "bool grpc_wire_id_to_setting_id(uint32_t wire_id, grpc_chttp2_setting_id *out);" +print >>C, """ bool grpc_wire_id_to_setting_id(uint32_t wire_id, grpc_chttp2_setting_id *out) { static const uint32_t r[] = {%(r)s}; uint32_t i = wire_id %(offset_sign)s %(offset)d; @@ -79,3 +138,42 @@ bool grpc_wire_id_to_setting_id(uint32_t wire_id, grpc_chttp2_setting_id *out) { 'offset': abs(p.offset), 'offset_sign': '+' if p.offset > 0 else '-' } + +print >>H, """ +typedef enum { + GRPC_CHTTP2_CLAMP_INVALID_VALUE, + GRPC_CHTTP2_DISCONNECT_ON_INVALID_VALUE +} grpc_chttp2_invalid_value_behavior; + +typedef struct { + const char *name; + uint32_t default_value; + uint32_t min_value; + uint32_t max_value; + grpc_chttp2_invalid_value_behavior invalid_value_behavior; + uint32_t error_value; +} grpc_chttp2_setting_parameters; +""" +print >>H, "extern const grpc_chttp2_setting_parameters grpc_chttp2_settings_parameters[GRPC_CHTTP2_NUM_SETTINGS];" +print >>C, "const grpc_chttp2_setting_parameters grpc_chttp2_settings_parameters[GRPC_CHTTP2_NUM_SETTINGS] = {" +i = 0 +for decorated_setting in sorted(decorated_settings): + while i < decorated_setting.enum: + print >>C, "{NULL, 0, 0, 0, GRPC_CHTTP2_DISCONNECT_ON_INVALID_VALUE, GRPC_HTTP2_PROTOCOL_ERROR}," + i += 1 + print >>C, "{\"%s\", %du, %du, %du, GRPC_CHTTP2_%s, GRPC_HTTP2_%s}," % ( + decorated_setting.name, + decorated_setting.setting.default, + decorated_setting.setting.min, + decorated_setting.setting.max, + decorated_setting.setting.on_error.behavior, + decorated_setting.setting.on_error.code, + ) + i += 1 +print >>C, "};" + +print >>H +print >>H, "#endif /* SRC_CORE_EXT_TRANSPORT_CHTTP2_TRANSPORT_HTTP2_SETTINGS_H */" + +H.close() +C.close() diff --git a/tools/doxygen/Doxyfile.core.internal b/tools/doxygen/Doxyfile.core.internal index a9343499e7..08a0213f0e 100644 --- a/tools/doxygen/Doxyfile.core.internal +++ b/tools/doxygen/Doxyfile.core.internal @@ -1003,6 +1003,8 @@ src/core/ext/transport/chttp2/transport/hpack_parser.c \ src/core/ext/transport/chttp2/transport/hpack_parser.h \ src/core/ext/transport/chttp2/transport/hpack_table.c \ src/core/ext/transport/chttp2/transport/hpack_table.h \ +src/core/ext/transport/chttp2/transport/http2_settings.c \ +src/core/ext/transport/chttp2/transport/http2_settings.h \ src/core/ext/transport/chttp2/transport/huffsyms.c \ src/core/ext/transport/chttp2/transport/huffsyms.h \ src/core/ext/transport/chttp2/transport/incoming_metadata.c \ diff --git a/tools/run_tests/generated/sources_and_headers.json b/tools/run_tests/generated/sources_and_headers.json index be1d8768bd..e621ca39ce 100644 --- a/tools/run_tests/generated/sources_and_headers.json +++ b/tools/run_tests/generated/sources_and_headers.json @@ -8297,6 +8297,7 @@ "src/core/ext/transport/chttp2/transport/hpack_encoder.h", "src/core/ext/transport/chttp2/transport/hpack_parser.h", "src/core/ext/transport/chttp2/transport/hpack_table.h", + "src/core/ext/transport/chttp2/transport/http2_settings.h", "src/core/ext/transport/chttp2/transport/huffsyms.h", "src/core/ext/transport/chttp2/transport/incoming_metadata.h", "src/core/ext/transport/chttp2/transport/internal.h", @@ -8333,6 +8334,8 @@ "src/core/ext/transport/chttp2/transport/hpack_parser.h", "src/core/ext/transport/chttp2/transport/hpack_table.c", "src/core/ext/transport/chttp2/transport/hpack_table.h", + "src/core/ext/transport/chttp2/transport/http2_settings.c", + "src/core/ext/transport/chttp2/transport/http2_settings.h", "src/core/ext/transport/chttp2/transport/huffsyms.c", "src/core/ext/transport/chttp2/transport/huffsyms.h", "src/core/ext/transport/chttp2/transport/incoming_metadata.c", diff --git a/vsprojects/vcxproj/grpc/grpc.vcxproj b/vsprojects/vcxproj/grpc/grpc.vcxproj index ada8f1a228..366678cafd 100644 --- a/vsprojects/vcxproj/grpc/grpc.vcxproj +++ b/vsprojects/vcxproj/grpc/grpc.vcxproj @@ -424,6 +424,7 @@ + @@ -784,6 +785,8 @@ + + diff --git a/vsprojects/vcxproj/grpc/grpc.vcxproj.filters b/vsprojects/vcxproj/grpc/grpc.vcxproj.filters index 02468451e9..7e8b8b1246 100644 --- a/vsprojects/vcxproj/grpc/grpc.vcxproj.filters +++ b/vsprojects/vcxproj/grpc/grpc.vcxproj.filters @@ -421,6 +421,9 @@ src\core\ext\transport\chttp2\transport + + src\core\ext\transport\chttp2\transport + src\core\ext\transport\chttp2\transport @@ -1169,6 +1172,9 @@ src\core\ext\transport\chttp2\transport + + src\core\ext\transport\chttp2\transport + src\core\ext\transport\chttp2\transport diff --git a/vsprojects/vcxproj/grpc_unsecure/grpc_unsecure.vcxproj b/vsprojects/vcxproj/grpc_unsecure/grpc_unsecure.vcxproj index 83e76586ac..7cfbb95986 100644 --- a/vsprojects/vcxproj/grpc_unsecure/grpc_unsecure.vcxproj +++ b/vsprojects/vcxproj/grpc_unsecure/grpc_unsecure.vcxproj @@ -414,6 +414,7 @@ + @@ -754,6 +755,8 @@ + + diff --git a/vsprojects/vcxproj/grpc_unsecure/grpc_unsecure.vcxproj.filters b/vsprojects/vcxproj/grpc_unsecure/grpc_unsecure.vcxproj.filters index 5e2b7c2c31..650fdbc57e 100644 --- a/vsprojects/vcxproj/grpc_unsecure/grpc_unsecure.vcxproj.filters +++ b/vsprojects/vcxproj/grpc_unsecure/grpc_unsecure.vcxproj.filters @@ -427,6 +427,9 @@ src\core\ext\transport\chttp2\transport + + src\core\ext\transport\chttp2\transport + src\core\ext\transport\chttp2\transport @@ -1082,6 +1085,9 @@ src\core\ext\transport\chttp2\transport + + src\core\ext\transport\chttp2\transport + src\core\ext\transport\chttp2\transport -- cgit v1.2.3 From f408784ae9c3aebb7c76ea66708ef985dc466be1 Mon Sep 17 00:00:00 2001 From: Craig Tiller Date: Mon, 3 Apr 2017 16:50:14 -0700 Subject: better logging --- src/core/ext/transport/chttp2/transport/frame_settings.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/core/ext/transport') diff --git a/src/core/ext/transport/chttp2/transport/frame_settings.c b/src/core/ext/transport/chttp2/transport/frame_settings.c index 5719bf19b2..46630a6cc6 100644 --- a/src/core/ext/transport/chttp2/transport/frame_settings.c +++ b/src/core/ext/transport/chttp2/transport/frame_settings.c @@ -228,8 +228,8 @@ grpc_error *grpc_chttp2_settings_parser_parse(grpc_exec_ctx *exec_ctx, void *p, } parser->incoming_settings[id] = parser->value; if (grpc_http_trace) { - gpr_log(GPR_DEBUG, "CHTTP2:%s:%s: got setting %d = %d", - t->is_client ? "CLI" : "SVR", t->peer_string, parser->id, + gpr_log(GPR_DEBUG, "CHTTP2:%s:%s: got setting %s = %d", + t->is_client ? "CLI" : "SVR", t->peer_string, sp->name, parser->value); } } else if (grpc_http_trace) { -- cgit v1.2.3 From 87c79795e6bc0047d22e9c5f638df832587f3418 Mon Sep 17 00:00:00 2001 From: Craig Tiller Date: Mon, 3 Apr 2017 17:05:12 -0700 Subject: Perform option exchange --- include/grpc/impl/codegen/grpc_types.h | 2 + .../transport/chttp2/transport/chttp2_transport.c | 47 +++++++++++++--------- .../transport/chttp2/transport/http2_settings.c | 6 +-- tools/codegen/core/gen_settings_ids.py | 4 +- 4 files changed, 34 insertions(+), 25 deletions(-) (limited to 'src/core/ext/transport') diff --git a/include/grpc/impl/codegen/grpc_types.h b/include/grpc/impl/codegen/grpc_types.h index aa4210b1a7..c76f9e0ac4 100644 --- a/include/grpc/impl/codegen/grpc_types.h +++ b/include/grpc/impl/codegen/grpc_types.h @@ -205,6 +205,8 @@ typedef struct { /** How much data are we willing to queue up per stream if GRPC_WRITE_BUFFER_HINT is set? This is an upper bound */ #define GRPC_ARG_HTTP2_WRITE_BUFFER_SIZE "grpc.http2.write_buffer_size" +/** Should we allow receipt of true-binary data on http2 connections? */ +#define GRPC_ARG_HTTP2_ENABLE_TRUE_BINARY "grpc.http2.true_binary" /** After a duration of this time the client pings the server to see if the transport is still alive. Int valued, seconds. */ #define GRPC_ARG_CLIENT_KEEPALIVE_TIME_S "grpc.client_keepalive_time" diff --git a/src/core/ext/transport/chttp2/transport/chttp2_transport.c b/src/core/ext/transport/chttp2/transport/chttp2_transport.c index 26f9449f4b..2347bf6d90 100644 --- a/src/core/ext/transport/chttp2/transport/chttp2_transport.c +++ b/src/core/ext/transport/chttp2/transport/chttp2_transport.c @@ -346,6 +346,8 @@ static void init_transport(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t, DEFAULT_WINDOW); push_setting(exec_ctx, t, GRPC_CHTTP2_SETTINGS_MAX_HEADER_LIST_SIZE, DEFAULT_MAX_HEADER_LIST_SIZE); + push_setting(exec_ctx, t, + GRPC_CHTTP2_SETTINGS_GRPC_ALLOW_TRUE_BINARY_METADATA, 1); t->ping_policy = (grpc_chttp2_repeated_ping_policy){ .max_pings_without_data = DEFAULT_MAX_PINGS_BETWEEN_DATA, @@ -442,26 +444,31 @@ static void init_transport(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t, grpc_chttp2_setting_id setting_id; grpc_integer_options integer_options; bool availability[2] /* server, client */; - } settings_map[] = {{GRPC_ARG_MAX_CONCURRENT_STREAMS, - GRPC_CHTTP2_SETTINGS_MAX_CONCURRENT_STREAMS, - {-1, 0, INT32_MAX}, - {true, false}}, - {GRPC_ARG_HTTP2_HPACK_TABLE_SIZE_DECODER, - GRPC_CHTTP2_SETTINGS_HEADER_TABLE_SIZE, - {-1, 0, INT32_MAX}, - {true, true}}, - {GRPC_ARG_MAX_METADATA_SIZE, - GRPC_CHTTP2_SETTINGS_MAX_HEADER_LIST_SIZE, - {-1, 0, INT32_MAX}, - {true, true}}, - {GRPC_ARG_HTTP2_MAX_FRAME_SIZE, - GRPC_CHTTP2_SETTINGS_MAX_FRAME_SIZE, - {-1, 16384, 16777215}, - {true, true}}, - {GRPC_ARG_HTTP2_STREAM_LOOKAHEAD_BYTES, - GRPC_CHTTP2_SETTINGS_INITIAL_WINDOW_SIZE, - {-1, 5, INT32_MAX}, - {true, true}}}; + } settings_map[] = { + {GRPC_ARG_MAX_CONCURRENT_STREAMS, + GRPC_CHTTP2_SETTINGS_MAX_CONCURRENT_STREAMS, + {-1, 0, INT32_MAX}, + {true, false}}, + {GRPC_ARG_HTTP2_HPACK_TABLE_SIZE_DECODER, + GRPC_CHTTP2_SETTINGS_HEADER_TABLE_SIZE, + {-1, 0, INT32_MAX}, + {true, true}}, + {GRPC_ARG_MAX_METADATA_SIZE, + GRPC_CHTTP2_SETTINGS_MAX_HEADER_LIST_SIZE, + {-1, 0, INT32_MAX}, + {true, true}}, + {GRPC_ARG_HTTP2_MAX_FRAME_SIZE, + GRPC_CHTTP2_SETTINGS_MAX_FRAME_SIZE, + {-1, 16384, 16777215}, + {true, true}}, + {GRPC_ARG_HTTP2_ENABLE_TRUE_BINARY, + GRPC_CHTTP2_SETTINGS_GRPC_ALLOW_TRUE_BINARY_METADATA, + {1, 0, 1}, + {true, true}}, + {GRPC_ARG_HTTP2_STREAM_LOOKAHEAD_BYTES, + GRPC_CHTTP2_SETTINGS_INITIAL_WINDOW_SIZE, + {-1, 5, INT32_MAX}, + {true, true}}}; for (j = 0; j < (int)GPR_ARRAY_SIZE(settings_map); j++) { if (0 == strcmp(channel_args->args[i].key, settings_map[j].channel_arg_name)) { diff --git a/src/core/ext/transport/chttp2/transport/http2_settings.c b/src/core/ext/transport/chttp2/transport/http2_settings.c index eea6305c8e..05f0d8cb46 100644 --- a/src/core/ext/transport/chttp2/transport/http2_settings.c +++ b/src/core/ext/transport/chttp2/transport/http2_settings.c @@ -61,9 +61,9 @@ bool grpc_wire_id_to_setting_id(uint32_t wire_id, grpc_chttp2_setting_id *out) { uint32_t delta = (uint32_t)r[y]; h += delta; } - *out = (grpc_chttp2_setting_id)i; - return i < GPR_ARRAY_SIZE(grpc_setting_id_to_wire_id) && - grpc_setting_id_to_wire_id[i] == wire_id; + *out = (grpc_chttp2_setting_id)h; + return h < GPR_ARRAY_SIZE(grpc_setting_id_to_wire_id) && + grpc_setting_id_to_wire_id[h] == wire_id; } const grpc_chttp2_setting_parameters grpc_chttp2_settings_parameters[GRPC_CHTTP2_NUM_SETTINGS] = { diff --git a/tools/codegen/core/gen_settings_ids.py b/tools/codegen/core/gen_settings_ids.py index c807f70c2a..54498a18f2 100755 --- a/tools/codegen/core/gen_settings_ids.py +++ b/tools/codegen/core/gen_settings_ids.py @@ -130,8 +130,8 @@ bool grpc_wire_id_to_setting_id(uint32_t wire_id, grpc_chttp2_setting_id *out) { uint32_t delta = (uint32_t)r[y]; h += delta; } - *out = (grpc_chttp2_setting_id)i; - return i < GPR_ARRAY_SIZE(grpc_setting_id_to_wire_id) && grpc_setting_id_to_wire_id[i] == wire_id; + *out = (grpc_chttp2_setting_id)h; + return h < GPR_ARRAY_SIZE(grpc_setting_id_to_wire_id) && grpc_setting_id_to_wire_id[h] == wire_id; }""" % { 'r': ','.join('%d' % (r if r is not None else 0) for r in p.r), 't': p.t, -- cgit v1.2.3 From 83f7b9559c52d3c7f857a8ac80f5c21dcb9d2490 Mon Sep 17 00:00:00 2001 From: Craig Tiller Date: Tue, 4 Apr 2017 07:58:18 -0700 Subject: Starting the encode path --- .../ext/transport/chttp2/transport/hpack_encoder.c | 16 +++++----- .../ext/transport/chttp2/transport/hpack_encoder.h | 15 ++++++--- src/core/ext/transport/chttp2/transport/writing.c | 36 ++++++++++++++++------ 3 files changed, 45 insertions(+), 22 deletions(-) (limited to 'src/core/ext/transport') diff --git a/src/core/ext/transport/chttp2/transport/hpack_encoder.c b/src/core/ext/transport/chttp2/transport/hpack_encoder.c index 84586cd998..f5f52a3360 100644 --- a/src/core/ext/transport/chttp2/transport/hpack_encoder.c +++ b/src/core/ext/transport/chttp2/transport/hpack_encoder.c @@ -595,23 +595,21 @@ void grpc_chttp2_hpack_compressor_set_max_table_size( void grpc_chttp2_encode_header(grpc_exec_ctx *exec_ctx, grpc_chttp2_hpack_compressor *c, - uint32_t stream_id, - grpc_metadata_batch *metadata, int is_eof, - size_t max_frame_size, - grpc_transport_one_way_stats *stats, + grpc_metadata_batch *metadata, + const grpc_encode_header_options *options, grpc_slice_buffer *outbuf) { framer_state st; grpc_linked_mdelem *l; gpr_timespec deadline; - GPR_ASSERT(stream_id != 0); + GPR_ASSERT(options->stream_id != 0); st.seen_regular_header = 0; - st.stream_id = stream_id; + st.stream_id = options->stream_id; st.output = outbuf; st.is_first_frame = 1; - st.stats = stats; - st.max_frame_size = max_frame_size; + st.stats = options->stats; + st.max_frame_size = options->max_frame_size; /* Encode a metadata batch; store the returned values, representing a metadata element that needs to be unreffed back into the metadata @@ -630,5 +628,5 @@ void grpc_chttp2_encode_header(grpc_exec_ctx *exec_ctx, deadline_enc(exec_ctx, c, deadline, &st); } - finish_frame(&st, 1, is_eof); + finish_frame(&st, 1, options->is_eof); } diff --git a/src/core/ext/transport/chttp2/transport/hpack_encoder.h b/src/core/ext/transport/chttp2/transport/hpack_encoder.h index 83ba5b1b3e..6ce3209604 100644 --- a/src/core/ext/transport/chttp2/transport/hpack_encoder.h +++ b/src/core/ext/transport/chttp2/transport/hpack_encoder.h @@ -90,11 +90,18 @@ void grpc_chttp2_hpack_compressor_set_max_table_size( void grpc_chttp2_hpack_compressor_set_max_usable_size( grpc_chttp2_hpack_compressor *c, uint32_t max_table_size); +typedef struct { + uint32_t stream_id; + bool is_eof; + bool use_true_binary_metadata; + size_t max_frame_size; + grpc_transport_one_way_stats *stats; +} grpc_encode_header_options; + void grpc_chttp2_encode_header(grpc_exec_ctx *exec_ctx, - grpc_chttp2_hpack_compressor *c, uint32_t id, - grpc_metadata_batch *metadata, int is_eof, - size_t max_frame_size, - grpc_transport_one_way_stats *stats, + grpc_chttp2_hpack_compressor *c, + grpc_metadata_batch *metadata, + const grpc_encode_header_options *options, grpc_slice_buffer *outbuf); #endif /* GRPC_CORE_EXT_TRANSPORT_CHTTP2_TRANSPORT_HPACK_ENCODER_H */ diff --git a/src/core/ext/transport/chttp2/transport/writing.c b/src/core/ext/transport/chttp2/transport/writing.c index 0869056f56..b3918df7dc 100644 --- a/src/core/ext/transport/chttp2/transport/writing.c +++ b/src/core/ext/transport/chttp2/transport/writing.c @@ -219,10 +219,18 @@ bool grpc_chttp2_begin_write(grpc_exec_ctx *exec_ctx, /* send initial metadata if it's available */ if (!sent_initial_metadata && s->send_initial_metadata) { - grpc_chttp2_encode_header( - exec_ctx, &t->hpack_compressor, s->id, s->send_initial_metadata, 0, - t->settings[GRPC_ACKED_SETTINGS][GRPC_CHTTP2_SETTINGS_MAX_FRAME_SIZE], - &s->stats.outgoing, &t->outbuf); + grpc_encode_header_options hopt = { + .stream_id = s->id, + .is_eof = false, + .use_true_binary_metadata = + t->settings + [GRPC_ACKED_SETTINGS] + [GRPC_CHTTP2_SETTINGS_GRPC_ALLOW_TRUE_BINARY_METADATA] != 0, + .max_frame_size = t->settings[GRPC_ACKED_SETTINGS] + [GRPC_CHTTP2_SETTINGS_MAX_FRAME_SIZE], + .stats = &s->stats.outgoing}; + grpc_chttp2_encode_header(exec_ctx, &t->hpack_compressor, + s->send_initial_metadata, &hopt, &t->outbuf); s->send_initial_metadata = NULL; s->sent_initial_metadata = true; sent_initial_metadata = true; @@ -300,11 +308,21 @@ bool grpc_chttp2_begin_write(grpc_exec_ctx *exec_ctx, grpc_chttp2_encode_data(s->id, &s->flow_controlled_buffer, 0, true, &s->stats.outgoing, &t->outbuf); } else { - grpc_chttp2_encode_header( - exec_ctx, &t->hpack_compressor, s->id, s->send_trailing_metadata, - true, t->settings[GRPC_ACKED_SETTINGS] - [GRPC_CHTTP2_SETTINGS_MAX_FRAME_SIZE], - &s->stats.outgoing, &t->outbuf); + grpc_encode_header_options hopt = { + .stream_id = s->id, + .is_eof = true, + .use_true_binary_metadata = + t->settings + [GRPC_ACKED_SETTINGS] + [GRPC_CHTTP2_SETTINGS_GRPC_ALLOW_TRUE_BINARY_METADATA] != + 0, + .max_frame_size = + t->settings[GRPC_ACKED_SETTINGS] + [GRPC_CHTTP2_SETTINGS_MAX_FRAME_SIZE], + .stats = &s->stats.outgoing}; + grpc_chttp2_encode_header(exec_ctx, &t->hpack_compressor, + s->send_trailing_metadata, &hopt, + &t->outbuf); } s->send_trailing_metadata = NULL; s->sent_trailing_metadata = true; -- cgit v1.2.3 From 94736b9d67733b3a86ae1f405c5edcd385edcb5f Mon Sep 17 00:00:00 2001 From: Craig Tiller Date: Tue, 4 Apr 2017 15:30:56 -0700 Subject: Add encode path --- .../ext/transport/chttp2/transport/hpack_encoder.c | 85 +++++++++++++++------- 1 file changed, 57 insertions(+), 28 deletions(-) (limited to 'src/core/ext/transport') diff --git a/src/core/ext/transport/chttp2/transport/hpack_encoder.c b/src/core/ext/transport/chttp2/transport/hpack_encoder.c index f5f52a3360..b1bc677a7a 100644 --- a/src/core/ext/transport/chttp2/transport/hpack_encoder.c +++ b/src/core/ext/transport/chttp2/transport/hpack_encoder.c @@ -86,6 +86,7 @@ typedef struct { grpc_transport_one_way_stats *stats; /* maximum size of a frame */ size_t max_frame_size; + bool use_true_binary_metadata; } framer_state; /* fills p (which is expected to be 9 bytes long) with a data frame header */ @@ -290,86 +291,113 @@ static void emit_indexed(grpc_chttp2_hpack_compressor *c, uint32_t elem_index, len); } -static grpc_slice get_wire_value(grpc_mdelem elem, uint8_t *huffman_prefix) { +typedef struct { + grpc_slice data; + uint8_t huffman_prefix; + bool insert_null_before_wire_value; +} wire_value; + +static wire_value get_wire_value(grpc_mdelem elem, bool true_binary_enabled) { if (grpc_is_binary_header(GRPC_MDKEY(elem))) { - *huffman_prefix = 0x80; - return grpc_chttp2_base64_encode_and_huffman_compress(GRPC_MDVALUE(elem)); + if (true_binary_enabled) { + return (wire_value){ + .huffman_prefix = 0x00, + .insert_null_before_wire_value = true, + .data = grpc_slice_ref_internal(GRPC_MDVALUE(elem)), + }; + } else { + return (wire_value){ + .huffman_prefix = 0x80, + .insert_null_before_wire_value = false, + .data = grpc_chttp2_base64_encode_and_huffman_compress( + GRPC_MDVALUE(elem)), + }; + } + } else { + /* TODO(ctiller): opportunistically compress non-binary headers */ + return (wire_value){ + .huffman_prefix = 0x00, + .insert_null_before_wire_value = false, + .data = grpc_slice_ref_internal(GRPC_MDVALUE(elem)), + }; } - /* TODO(ctiller): opportunistically compress non-binary headers */ - *huffman_prefix = 0x00; - return grpc_slice_ref_internal(GRPC_MDVALUE(elem)); +} + +static size_t wire_value_length(wire_value v) { + return GPR_SLICE_LENGTH(v.data) + v.insert_null_before_wire_value; +} + +static void add_wire_value(framer_state *st, wire_value v) { + if (v.insert_null_before_wire_value) *add_tiny_header_data(st, 1) = 0; + add_header_data(st, v.data); } static void emit_lithdr_incidx(grpc_chttp2_hpack_compressor *c, uint32_t key_index, grpc_mdelem elem, framer_state *st) { uint32_t len_pfx = GRPC_CHTTP2_VARINT_LENGTH(key_index, 2); - uint8_t huffman_prefix; - grpc_slice value_slice = get_wire_value(elem, &huffman_prefix); - size_t len_val = GRPC_SLICE_LENGTH(value_slice); + wire_value value = get_wire_value(elem, st->use_true_binary_metadata); + size_t len_val = wire_value_length(value); uint32_t len_val_len; GPR_ASSERT(len_val <= UINT32_MAX); len_val_len = GRPC_CHTTP2_VARINT_LENGTH((uint32_t)len_val, 1); GRPC_CHTTP2_WRITE_VARINT(key_index, 2, 0x40, add_tiny_header_data(st, len_pfx), len_pfx); - GRPC_CHTTP2_WRITE_VARINT((uint32_t)len_val, 1, huffman_prefix, + GRPC_CHTTP2_WRITE_VARINT((uint32_t)len_val, 1, value.huffman_prefix, add_tiny_header_data(st, len_val_len), len_val_len); - add_header_data(st, value_slice); + add_wire_value(st, value); } static void emit_lithdr_noidx(grpc_chttp2_hpack_compressor *c, uint32_t key_index, grpc_mdelem elem, framer_state *st) { uint32_t len_pfx = GRPC_CHTTP2_VARINT_LENGTH(key_index, 4); - uint8_t huffman_prefix; - grpc_slice value_slice = get_wire_value(elem, &huffman_prefix); - size_t len_val = GRPC_SLICE_LENGTH(value_slice); + wire_value value = get_wire_value(elem, st->use_true_binary_metadata); + size_t len_val = wire_value_length(value); uint32_t len_val_len; GPR_ASSERT(len_val <= UINT32_MAX); len_val_len = GRPC_CHTTP2_VARINT_LENGTH((uint32_t)len_val, 1); GRPC_CHTTP2_WRITE_VARINT(key_index, 4, 0x00, add_tiny_header_data(st, len_pfx), len_pfx); - GRPC_CHTTP2_WRITE_VARINT((uint32_t)len_val, 1, huffman_prefix, + GRPC_CHTTP2_WRITE_VARINT((uint32_t)len_val, 1, value.huffman_prefix, add_tiny_header_data(st, len_val_len), len_val_len); - add_header_data(st, value_slice); + add_wire_value(st, value); } static void emit_lithdr_incidx_v(grpc_chttp2_hpack_compressor *c, grpc_mdelem elem, framer_state *st) { uint32_t len_key = (uint32_t)GRPC_SLICE_LENGTH(GRPC_MDKEY(elem)); - uint8_t huffman_prefix; - grpc_slice value_slice = get_wire_value(elem, &huffman_prefix); - uint32_t len_val = (uint32_t)GRPC_SLICE_LENGTH(value_slice); + wire_value value = get_wire_value(elem, st->use_true_binary_metadata); + uint32_t len_val = (uint32_t)wire_value_length(value); uint32_t len_key_len = GRPC_CHTTP2_VARINT_LENGTH(len_key, 1); uint32_t len_val_len = GRPC_CHTTP2_VARINT_LENGTH(len_val, 1); GPR_ASSERT(len_key <= UINT32_MAX); - GPR_ASSERT(GRPC_SLICE_LENGTH(value_slice) <= UINT32_MAX); + GPR_ASSERT(wire_value_length(value) <= UINT32_MAX); *add_tiny_header_data(st, 1) = 0x40; GRPC_CHTTP2_WRITE_VARINT(len_key, 1, 0x00, add_tiny_header_data(st, len_key_len), len_key_len); add_header_data(st, grpc_slice_ref_internal(GRPC_MDKEY(elem))); - GRPC_CHTTP2_WRITE_VARINT(len_val, 1, huffman_prefix, + GRPC_CHTTP2_WRITE_VARINT(len_val, 1, value.huffman_prefix, add_tiny_header_data(st, len_val_len), len_val_len); - add_header_data(st, value_slice); + add_wire_value(st, value); } static void emit_lithdr_noidx_v(grpc_chttp2_hpack_compressor *c, grpc_mdelem elem, framer_state *st) { uint32_t len_key = (uint32_t)GRPC_SLICE_LENGTH(GRPC_MDKEY(elem)); - uint8_t huffman_prefix; - grpc_slice value_slice = get_wire_value(elem, &huffman_prefix); - uint32_t len_val = (uint32_t)GRPC_SLICE_LENGTH(value_slice); + wire_value value = get_wire_value(elem, st->use_true_binary_metadata); + uint32_t len_val = (uint32_t)wire_value_length(value); uint32_t len_key_len = GRPC_CHTTP2_VARINT_LENGTH(len_key, 1); uint32_t len_val_len = GRPC_CHTTP2_VARINT_LENGTH(len_val, 1); GPR_ASSERT(len_key <= UINT32_MAX); - GPR_ASSERT(GRPC_SLICE_LENGTH(value_slice) <= UINT32_MAX); + GPR_ASSERT(wire_value_length(value) <= UINT32_MAX); *add_tiny_header_data(st, 1) = 0x00; GRPC_CHTTP2_WRITE_VARINT(len_key, 1, 0x00, add_tiny_header_data(st, len_key_len), len_key_len); add_header_data(st, grpc_slice_ref_internal(GRPC_MDKEY(elem))); - GRPC_CHTTP2_WRITE_VARINT(len_val, 1, huffman_prefix, + GRPC_CHTTP2_WRITE_VARINT(len_val, 1, value.huffman_prefix, add_tiny_header_data(st, len_val_len), len_val_len); - add_header_data(st, value_slice); + add_wire_value(st, value); } static void emit_advertise_table_size_change(grpc_chttp2_hpack_compressor *c, @@ -610,6 +638,7 @@ void grpc_chttp2_encode_header(grpc_exec_ctx *exec_ctx, st.is_first_frame = 1; st.stats = options->stats; st.max_frame_size = options->max_frame_size; + st.use_true_binary_metadata = options->use_true_binary_metadata; /* Encode a metadata batch; store the returned values, representing a metadata element that needs to be unreffed back into the metadata -- cgit v1.2.3 From c5548cce42f8c4783c3c0368ea3ce00a196ff944 Mon Sep 17 00:00:00 2001 From: Craig Tiller Date: Tue, 4 Apr 2017 16:05:23 -0700 Subject: Add parsing for true-binary metadata --- .../ext/transport/chttp2/transport/hpack_parser.c | 26 ++++++++++++++-------- 1 file changed, 17 insertions(+), 9 deletions(-) (limited to 'src/core/ext/transport') diff --git a/src/core/ext/transport/chttp2/transport/hpack_parser.c b/src/core/ext/transport/chttp2/transport/hpack_parser.c index 5099d736bf..1846a85fc6 100644 --- a/src/core/ext/transport/chttp2/transport/hpack_parser.c +++ b/src/core/ext/transport/chttp2/transport/hpack_parser.c @@ -38,11 +38,6 @@ #include #include -/* This is here for grpc_is_binary_header - * TODO(murgatroid99): Remove this - */ -#include - #include #include #include @@ -55,13 +50,11 @@ #include "src/core/lib/support/string.h" #include "src/core/lib/transport/http2_errors.h" -/* TODO(ctiller): remove before submission */ -#include "src/core/lib/slice/slice_string_helpers.h" - extern int grpc_http_trace; typedef enum { NOT_BINARY, + BINARY_BEGIN, B64_BYTE0, B64_BYTE1, B64_BYTE2, @@ -1325,6 +1318,19 @@ static grpc_error *append_string(grpc_exec_ctx *exec_ctx, case NOT_BINARY: append_bytes(str, cur, (size_t)(end - cur)); return GRPC_ERROR_NONE; + case BINARY_BEGIN: + if (cur == end) { + p->binary = BINARY_BEGIN; + return GRPC_ERROR_NONE; + } + if (*cur == 0) { + /* 'true-binary' case */ + ++cur; + p->binary = NOT_BINARY; + append_bytes(str, cur, (size_t)(end - cur)); + return GRPC_ERROR_NONE; + } + /* fallthrough */ b64_byte0: case B64_BYTE0: if (cur == end) { @@ -1409,6 +1415,8 @@ static grpc_error *finish_str(grpc_exec_ctx *exec_ctx, switch ((binary_state)p->binary) { case NOT_BINARY: break; + case BINARY_BEGIN: + break; case B64_BYTE0: break; case B64_BYTE1: @@ -1571,7 +1579,7 @@ static grpc_error *parse_value_string(grpc_exec_ctx *exec_ctx, const uint8_t *cur, const uint8_t *end, bool is_binary) { return begin_parse_string(exec_ctx, p, cur, end, - is_binary ? B64_BYTE0 : NOT_BINARY, &p->value); + is_binary ? BINARY_BEGIN : NOT_BINARY, &p->value); } static grpc_error *parse_value_string_with_indexed_key( -- cgit v1.2.3 From 2a4731e2eb24efce9fa6322630bdf19b953260d2 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Tue, 4 Apr 2017 17:14:40 -0700 Subject: More merging fixes and asan fix --- src/core/ext/transport/chttp2/transport/chttp2_transport.c | 2 +- src/core/lib/channel/compress_filter.c | 2 +- src/core/lib/channel/http_client_filter.c | 2 +- src/core/lib/surface/call.c | 1 + 4 files changed, 4 insertions(+), 3 deletions(-) (limited to 'src/core/ext/transport') diff --git a/src/core/ext/transport/chttp2/transport/chttp2_transport.c b/src/core/ext/transport/chttp2/transport/chttp2_transport.c index 965306cbbe..c90bf69d15 100644 --- a/src/core/ext/transport/chttp2/transport/chttp2_transport.c +++ b/src/core/ext/transport/chttp2/transport/chttp2_transport.c @@ -1583,7 +1583,6 @@ void grpc_chttp2_maybe_complete_recv_message(grpc_exec_ctx *exec_ctx, grpc_slice_buffer_swap(&s->unprocessed_incoming_frames_buffer, &s->frame_storage); } - /* error handling ok? */ error = deframe_unprocessed_incoming_frames( exec_ctx, &s->data_parser, s, &s->unprocessed_incoming_frames_buffer, NULL, s->recv_message); @@ -1593,6 +1592,7 @@ void grpc_chttp2_maybe_complete_recv_message(grpc_exec_ctx *exec_ctx, &s->frame_storage); grpc_slice_buffer_reset_and_unref_internal( exec_ctx, &s->unprocessed_incoming_frames_buffer); + GRPC_ERROR_UNREF(error); break; } else if (*s->recv_message != NULL) { break; diff --git a/src/core/lib/channel/compress_filter.c b/src/core/lib/channel/compress_filter.c index 1fc0104911..a945639fae 100644 --- a/src/core/lib/channel/compress_filter.c +++ b/src/core/lib/channel/compress_filter.c @@ -222,7 +222,7 @@ static void got_slice(grpc_exec_ctx *exec_ctx, void *elemp, grpc_error *error) { grpc_call_element *elem = elemp; call_data *calld = elem->call_data; if (GRPC_ERROR_NONE != grpc_byte_stream_pull(exec_ctx, - calld->send_op->send_message, + calld->send_op->payload->send_message.send_message, &calld->incoming_slice)) { /* Should never reach here */ abort(); diff --git a/src/core/lib/channel/http_client_filter.c b/src/core/lib/channel/http_client_filter.c index 8455e154ac..57bbb98139 100644 --- a/src/core/lib/channel/http_client_filter.c +++ b/src/core/lib/channel/http_client_filter.c @@ -239,7 +239,7 @@ static void got_slice(grpc_exec_ctx *exec_ctx, void *elemp, grpc_error *error) { call_data *calld = elem->call_data; calld->send_message_blocked = false; if (GRPC_ERROR_NONE != grpc_byte_stream_pull(exec_ctx, - calld->send_op.send_message, + calld->send_op->payload->send_message.send_message, &calld->incoming_slice)) { /* Should never reach here */ abort(); diff --git a/src/core/lib/surface/call.c b/src/core/lib/surface/call.c index 4c1472bd4c..9905545422 100644 --- a/src/core/lib/surface/call.c +++ b/src/core/lib/surface/call.c @@ -1210,6 +1210,7 @@ static void receiving_slice_ready(grpc_exec_ctx *exec_ctx, void *bctlp, *call->receiving_buffer = NULL; call->receiving_message = 0; finish_batch_step(exec_ctx, bctl); + GRPC_ERROR_UNREF(error); } } -- cgit v1.2.3 From 769b7c367d511e8f5e44c5e59c7bd06dc417cbca Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Tue, 4 Apr 2017 19:07:50 -0700 Subject: Bug fix --- src/core/ext/transport/chttp2/transport/chttp2_transport.c | 2 ++ src/core/lib/surface/call.c | 1 - 2 files changed, 2 insertions(+), 1 deletion(-) (limited to 'src/core/ext/transport') diff --git a/src/core/ext/transport/chttp2/transport/chttp2_transport.c b/src/core/ext/transport/chttp2/transport/chttp2_transport.c index c90bf69d15..7aee014e63 100644 --- a/src/core/ext/transport/chttp2/transport/chttp2_transport.c +++ b/src/core/ext/transport/chttp2/transport/chttp2_transport.c @@ -2326,6 +2326,7 @@ static void reset_byte_stream(grpc_exec_ctx *exec_ctx, void *arg, grpc_closure_sched(exec_ctx, s->on_next, GRPC_ERROR_REF(error)); s->on_next = NULL; GRPC_ERROR_UNREF(s->byte_stream_error); + s->byte_stream_error = GRPC_ERROR_NONE; grpc_chttp2_cancel_stream(exec_ctx, s->t, s, GRPC_ERROR_REF(error)); s->byte_stream_error = error; } @@ -2694,6 +2695,7 @@ static void incoming_byte_stream_publish_error( grpc_closure_sched(exec_ctx, s->on_next, GRPC_ERROR_REF(error)); s->on_next = NULL; GRPC_ERROR_UNREF(s->byte_stream_error); + s->byte_stream_error = GRPC_ERROR_NONE; grpc_chttp2_cancel_stream(exec_ctx, bs->transport, bs->stream, GRPC_ERROR_REF(error)); s->byte_stream_error = GRPC_ERROR_REF(error); diff --git a/src/core/lib/surface/call.c b/src/core/lib/surface/call.c index 9905545422..4c1472bd4c 100644 --- a/src/core/lib/surface/call.c +++ b/src/core/lib/surface/call.c @@ -1210,7 +1210,6 @@ static void receiving_slice_ready(grpc_exec_ctx *exec_ctx, void *bctlp, *call->receiving_buffer = NULL; call->receiving_message = 0; finish_batch_step(exec_ctx, bctl); - GRPC_ERROR_UNREF(error); } } -- cgit v1.2.3 From 702bf3b2dca1c0829bc671d2d4c5737c52ef2f44 Mon Sep 17 00:00:00 2001 From: Craig Tiller Date: Wed, 5 Apr 2017 06:53:57 -0700 Subject: Remove bogus assert --- src/core/ext/transport/chttp2/transport/frame_settings.c | 1 - 1 file changed, 1 deletion(-) (limited to 'src/core/ext/transport') diff --git a/src/core/ext/transport/chttp2/transport/frame_settings.c b/src/core/ext/transport/chttp2/transport/frame_settings.c index 46630a6cc6..d53f51a1e8 100644 --- a/src/core/ext/transport/chttp2/transport/frame_settings.c +++ b/src/core/ext/transport/chttp2/transport/frame_settings.c @@ -77,7 +77,6 @@ grpc_slice grpc_chttp2_settings_create(uint32_t *old, const uint32_t *new, for (i = 0; i < count; i++) { if (new[i] != old[i] || (force_mask & (1u << i)) != 0) { - GPR_ASSERT(i); *p++ = (uint8_t)(grpc_setting_id_to_wire_id[i] >> 8); *p++ = (uint8_t)(grpc_setting_id_to_wire_id[i]); *p++ = (uint8_t)(new[i] >> 24); -- cgit v1.2.3 From 3d13d7e162f39c24d7bdd915981ebb74154bc91e Mon Sep 17 00:00:00 2001 From: Craig Tiller Date: Wed, 5 Apr 2017 08:02:42 -0700 Subject: Update copyright, choose a better sort order for our enum --- src/core/ext/transport/chttp2/transport/http2_settings.c | 2 +- src/core/ext/transport/chttp2/transport/http2_settings.h | 8 ++++---- tools/codegen/core/gen_settings_ids.py | 7 +++---- 3 files changed, 8 insertions(+), 9 deletions(-) (limited to 'src/core/ext/transport') diff --git a/src/core/ext/transport/chttp2/transport/http2_settings.c b/src/core/ext/transport/chttp2/transport/http2_settings.c index 05f0d8cb46..52969e6b4a 100644 --- a/src/core/ext/transport/chttp2/transport/http2_settings.c +++ b/src/core/ext/transport/chttp2/transport/http2_settings.c @@ -1,5 +1,5 @@ /* - * Copyright 2015, Google Inc. + * Copyright 2017, Google Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/src/core/ext/transport/chttp2/transport/http2_settings.h b/src/core/ext/transport/chttp2/transport/http2_settings.h index 393c14f7f1..61048a6478 100644 --- a/src/core/ext/transport/chttp2/transport/http2_settings.h +++ b/src/core/ext/transport/chttp2/transport/http2_settings.h @@ -1,5 +1,5 @@ /* - * Copyright 2015, Google Inc. + * Copyright 2017, Google Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -40,13 +40,13 @@ #include typedef enum { - GRPC_CHTTP2_SETTINGS_ENABLE_PUSH = 1, /* wire id 2 */ - GRPC_CHTTP2_SETTINGS_GRPC_ALLOW_TRUE_BINARY_METADATA = 6, /* wire id 65027 */ GRPC_CHTTP2_SETTINGS_HEADER_TABLE_SIZE = 0, /* wire id 1 */ - GRPC_CHTTP2_SETTINGS_INITIAL_WINDOW_SIZE = 3, /* wire id 4 */ + GRPC_CHTTP2_SETTINGS_ENABLE_PUSH = 1, /* wire id 2 */ GRPC_CHTTP2_SETTINGS_MAX_CONCURRENT_STREAMS = 2, /* wire id 3 */ + GRPC_CHTTP2_SETTINGS_INITIAL_WINDOW_SIZE = 3, /* wire id 4 */ GRPC_CHTTP2_SETTINGS_MAX_FRAME_SIZE = 4, /* wire id 5 */ GRPC_CHTTP2_SETTINGS_MAX_HEADER_LIST_SIZE = 5, /* wire id 6 */ + GRPC_CHTTP2_SETTINGS_GRPC_ALLOW_TRUE_BINARY_METADATA = 6, /* wire id 65027 */ } grpc_chttp2_setting_id; #define GRPC_CHTTP2_NUM_SETTINGS 7 diff --git a/tools/codegen/core/gen_settings_ids.py b/tools/codegen/core/gen_settings_ids.py index 54498a18f2..4253396ead 100755 --- a/tools/codegen/core/gen_settings_ids.py +++ b/tools/codegen/core/gen_settings_ids.py @@ -1,6 +1,6 @@ #!/usr/bin/env python2.7 -# Copyright 2015, Google Inc. +# Copyright 2017, Google Inc. # All rights reserved. # # Redistribution and use in source and binary forms, with or without @@ -106,10 +106,9 @@ decorated_settings = [DecoratedSetting(hash(setting.id), name, setting) for name, setting in _SETTINGS.iteritems()] print >>H, 'typedef enum {' -for name in sorted(_SETTINGS.keys()): - setting = _SETTINGS[name] +for decorated_setting in sorted(decorated_settings): print >>H, ' GRPC_CHTTP2_SETTINGS_%s = %d, /* wire id %d */' % ( - name, hash(setting.id), setting.id) + decorated_setting.name, decorated_setting.enum, decorated_setting.setting.id) print >>H, '} grpc_chttp2_setting_id;' print >>H print >>H, '#define GRPC_CHTTP2_NUM_SETTINGS %d' % (max(x.enum for x in decorated_settings) + 1) -- cgit v1.2.3 From bcf9d9f4632e54526b34d44b6b9838bf9626c66a Mon Sep 17 00:00:00 2001 From: Craig Tiller Date: Wed, 5 Apr 2017 08:03:07 -0700 Subject: Remove old code --- src/core/ext/transport/chttp2/transport/frame_settings.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'src/core/ext/transport') diff --git a/src/core/ext/transport/chttp2/transport/frame_settings.c b/src/core/ext/transport/chttp2/transport/frame_settings.c index d53f51a1e8..4f2b827832 100644 --- a/src/core/ext/transport/chttp2/transport/frame_settings.c +++ b/src/core/ext/transport/chttp2/transport/frame_settings.c @@ -46,8 +46,6 @@ #include "src/core/lib/debug/trace.h" #include "src/core/lib/transport/http2_errors.h" -#define MAX_MAX_HEADER_LIST_SIZE (1024 * 1024 * 1024) - static uint8_t *fill_header(uint8_t *out, uint32_t length, uint8_t flags) { *out++ = (uint8_t)(length >> 16); *out++ = (uint8_t)(length >> 8); -- cgit v1.2.3 From dd2f706b8b9672f31ee40f678afea54c7bab899d Mon Sep 17 00:00:00 2001 From: Craig Tiller Date: Wed, 5 Apr 2017 08:11:44 -0700 Subject: Generate slightly more efficient code --- .../transport/chttp2/transport/http2_settings.c | 19 ++++------------- tools/codegen/core/gen_settings_ids.py | 24 +++++++++++++--------- 2 files changed, 18 insertions(+), 25 deletions(-) (limited to 'src/core/ext/transport') diff --git a/src/core/ext/transport/chttp2/transport/http2_settings.c b/src/core/ext/transport/chttp2/transport/http2_settings.c index 52969e6b4a..bca3834b55 100644 --- a/src/core/ext/transport/chttp2/transport/http2_settings.c +++ b/src/core/ext/transport/chttp2/transport/http2_settings.c @@ -41,25 +41,14 @@ const uint16_t grpc_setting_id_to_wire_id[] = {1, 2, 3, 4, 5, 6, 65027}; bool grpc_wire_id_to_setting_id(uint32_t wire_id, grpc_chttp2_setting_id *out) { - static const uint32_t r[] = { - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0}; uint32_t i = wire_id - 1; uint32_t x = i % 256; uint32_t y = i / 256; uint32_t h = x; - if (y < GPR_ARRAY_SIZE(r)) { - uint32_t delta = (uint32_t)r[y]; - h += delta; + switch (y) { + case 254: + h += 4; + break; } *out = (grpc_chttp2_setting_id)h; return h < GPR_ARRAY_SIZE(grpc_setting_id_to_wire_id) && diff --git a/tools/codegen/core/gen_settings_ids.py b/tools/codegen/core/gen_settings_ids.py index 4253396ead..cfc2c5d0a4 100755 --- a/tools/codegen/core/gen_settings_ids.py +++ b/tools/codegen/core/gen_settings_ids.py @@ -118,25 +118,29 @@ print >>C, 'const uint16_t grpc_setting_id_to_wire_id[] = {%s};' % ','.join( '%d' % s for s in p.slots) print >>H print >>H, "bool grpc_wire_id_to_setting_id(uint32_t wire_id, grpc_chttp2_setting_id *out);" +cgargs = { + 'r': ','.join('%d' % (r if r is not None else 0) for r in p.r), + 't': p.t, + 'offset': abs(p.offset), + 'offset_sign': '+' if p.offset > 0 else '-' + } print >>C, """ bool grpc_wire_id_to_setting_id(uint32_t wire_id, grpc_chttp2_setting_id *out) { - static const uint32_t r[] = {%(r)s}; uint32_t i = wire_id %(offset_sign)s %(offset)d; uint32_t x = i %% %(t)d; uint32_t y = i / %(t)d; uint32_t h = x; - if (y < GPR_ARRAY_SIZE(r)) { - uint32_t delta = (uint32_t)r[y]; - h += delta; + switch (y) { +""" % cgargs +for i, r in enumerate(p.r): + if not r: continue + if r < 0: print >>C, 'case %d: h -= %d; break;' % (i, -r) + else: print >>C, 'case %d: h += %d; break;' % (i, r) +print >>C, """ } *out = (grpc_chttp2_setting_id)h; return h < GPR_ARRAY_SIZE(grpc_setting_id_to_wire_id) && grpc_setting_id_to_wire_id[h] == wire_id; -}""" % { - 'r': ','.join('%d' % (r if r is not None else 0) for r in p.r), - 't': p.t, - 'offset': abs(p.offset), - 'offset_sign': '+' if p.offset > 0 else '-' - } +}""" % cgargs print >>H, """ typedef enum { -- cgit v1.2.3 From 9702e92d09465d34fecc1ca07cae75f2686f1c32 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Wed, 5 Apr 2017 13:37:59 -0700 Subject: Asan fix --- src/core/ext/transport/chttp2/transport/chttp2_transport.c | 1 + 1 file changed, 1 insertion(+) (limited to 'src/core/ext/transport') diff --git a/src/core/ext/transport/chttp2/transport/chttp2_transport.c b/src/core/ext/transport/chttp2/transport/chttp2_transport.c index 7aee014e63..b59f02b9b6 100644 --- a/src/core/ext/transport/chttp2/transport/chttp2_transport.c +++ b/src/core/ext/transport/chttp2/transport/chttp2_transport.c @@ -1651,6 +1651,7 @@ static void remove_stream(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t, incoming_byte_stream_unref(exec_ctx, bs); s->data_parser.parsing_frame = NULL; } else { + GRPC_ERROR_UNREF(s->byte_stream_error); s->byte_stream_error = GRPC_ERROR_REF(error); } } -- cgit v1.2.3 From bee6a33c5c1c33548406849f9b52f9ddcce13d27 Mon Sep 17 00:00:00 2001 From: Craig Tiller Date: Wed, 5 Apr 2017 14:46:56 -0700 Subject: Fix include guards --- src/core/ext/transport/chttp2/transport/http2_settings.h | 6 +++--- tools/codegen/core/gen_settings_ids.py | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) (limited to 'src/core/ext/transport') diff --git a/src/core/ext/transport/chttp2/transport/http2_settings.h b/src/core/ext/transport/chttp2/transport/http2_settings.h index 61048a6478..9781cdc989 100644 --- a/src/core/ext/transport/chttp2/transport/http2_settings.h +++ b/src/core/ext/transport/chttp2/transport/http2_settings.h @@ -33,8 +33,8 @@ * Automatically generated by tools/codegen/core/gen_settings_ids.py */ -#ifndef SRC_CORE_EXT_TRANSPORT_CHTTP2_TRANSPORT_HTTP2_SETTINGS_H -#define SRC_CORE_EXT_TRANSPORT_CHTTP2_TRANSPORT_HTTP2_SETTINGS_H +#ifndef GRPC_CORE_EXT_TRANSPORT_CHTTP2_TRANSPORT_HTTP2_SETTINGS_H +#define GRPC_CORE_EXT_TRANSPORT_CHTTP2_TRANSPORT_HTTP2_SETTINGS_H #include #include @@ -71,4 +71,4 @@ typedef struct { extern const grpc_chttp2_setting_parameters grpc_chttp2_settings_parameters[GRPC_CHTTP2_NUM_SETTINGS]; -#endif /* SRC_CORE_EXT_TRANSPORT_CHTTP2_TRANSPORT_HTTP2_SETTINGS_H */ +#endif /* GRPC_CORE_EXT_TRANSPORT_CHTTP2_TRANSPORT_HTTP2_SETTINGS_H */ diff --git a/tools/codegen/core/gen_settings_ids.py b/tools/codegen/core/gen_settings_ids.py index cfc2c5d0a4..29c67956c7 100755 --- a/tools/codegen/core/gen_settings_ids.py +++ b/tools/codegen/core/gen_settings_ids.py @@ -80,8 +80,8 @@ with open(sys.argv[0]) as my_source: put_banner([H,C], ["Automatically generated by tools/codegen/core/gen_settings_ids.py"]) -print >>H, "#ifndef SRC_CORE_EXT_TRANSPORT_CHTTP2_TRANSPORT_HTTP2_SETTINGS_H" -print >>H, "#define SRC_CORE_EXT_TRANSPORT_CHTTP2_TRANSPORT_HTTP2_SETTINGS_H" +print >>H, "#ifndef GRPC_CORE_EXT_TRANSPORT_CHTTP2_TRANSPORT_HTTP2_SETTINGS_H" +print >>H, "#define GRPC_CORE_EXT_TRANSPORT_CHTTP2_TRANSPORT_HTTP2_SETTINGS_H" print >>H print >>H, "#include " print >>H, "#include " @@ -176,7 +176,7 @@ for decorated_setting in sorted(decorated_settings): print >>C, "};" print >>H -print >>H, "#endif /* SRC_CORE_EXT_TRANSPORT_CHTTP2_TRANSPORT_HTTP2_SETTINGS_H */" +print >>H, "#endif /* GRPC_CORE_EXT_TRANSPORT_CHTTP2_TRANSPORT_HTTP2_SETTINGS_H */" H.close() C.close() -- cgit v1.2.3 From 95b5ce0ddc02606dd7118f1e43c77790946a5a6d Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Thu, 6 Apr 2017 13:56:52 -0700 Subject: Python bug fix --- src/core/ext/transport/chttp2/transport/chttp2_transport.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'src/core/ext/transport') diff --git a/src/core/ext/transport/chttp2/transport/chttp2_transport.c b/src/core/ext/transport/chttp2/transport/chttp2_transport.c index b59f02b9b6..43349beb29 100644 --- a/src/core/ext/transport/chttp2/transport/chttp2_transport.c +++ b/src/core/ext/transport/chttp2/transport/chttp2_transport.c @@ -1621,8 +1621,9 @@ void grpc_chttp2_maybe_complete_recv_trailing_metadata(grpc_exec_ctx *exec_ctx, exec_ctx, &s->unprocessed_incoming_frames_buffer); } } + bool pending_data = s->pending_byte_stream || s->unprocessed_incoming_frames_buffer.length > 0; if (s->read_closed && s->frame_storage.length == 0 && - (!s->pending_byte_stream || s->seen_error) && + (!pending_data || s->seen_error) && s->recv_trailing_metadata_finished != NULL) { grpc_chttp2_incoming_metadata_buffer_publish( exec_ctx, &s->metadata_buffer[1], s->recv_trailing_metadata); -- cgit v1.2.3 From 50da9d83b6420c8028b11903232db144a4eabf23 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Thu, 6 Apr 2017 18:18:00 -0700 Subject: Fix python bug --- src/core/ext/transport/chttp2/transport/chttp2_transport.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) (limited to 'src/core/ext/transport') diff --git a/src/core/ext/transport/chttp2/transport/chttp2_transport.c b/src/core/ext/transport/chttp2/transport/chttp2_transport.c index 43349beb29..ca95d8289a 100644 --- a/src/core/ext/transport/chttp2/transport/chttp2_transport.c +++ b/src/core/ext/transport/chttp2/transport/chttp2_transport.c @@ -2437,9 +2437,8 @@ static grpc_error *deframe_unprocessed_incoming_frames( GRPC_ERROR_NONE, 1); p->parsing_frame = NULL; p->state = GRPC_CHTTP2_DATA_FH_0; - } else { - s->pending_byte_stream = true; } + s->pending_byte_stream = true; if (cur != end) { grpc_slice_buffer_undo_take_first( @@ -2469,7 +2468,6 @@ static grpc_error *deframe_unprocessed_incoming_frames( GRPC_ERROR_NONE, 1); p->parsing_frame = NULL; p->state = GRPC_CHTTP2_DATA_FH_0; - grpc_closure_sched(exec_ctx, &s->reset_byte_stream, GRPC_ERROR_NONE); grpc_slice_unref_internal(exec_ctx, slice); return GRPC_ERROR_NONE; } else if (remaining < p->frame_size) { @@ -2502,7 +2500,6 @@ static grpc_error *deframe_unprocessed_incoming_frames( grpc_slice_buffer_undo_take_first( &s->unprocessed_incoming_frames_buffer, grpc_slice_sub(slice, (size_t)(cur - beg), (size_t)(end - beg))); - grpc_closure_sched(exec_ctx, &s->reset_byte_stream, GRPC_ERROR_NONE); grpc_slice_unref(slice); return GRPC_ERROR_NONE; } @@ -2670,8 +2667,14 @@ static void incoming_byte_stream_destroy_locked(grpc_exec_ctx *exec_ctx, void *byte_stream, grpc_error *error_ignored) { grpc_chttp2_incoming_byte_stream *bs = byte_stream; + grpc_chttp2_stream *s = bs->stream; + grpc_chttp2_transport *t = s->t; + GPR_ASSERT(bs->base.destroy == incoming_byte_stream_destroy); incoming_byte_stream_unref(exec_ctx, bs); + s->pending_byte_stream = false; + grpc_chttp2_maybe_complete_recv_message(exec_ctx, t, s); + grpc_chttp2_maybe_complete_recv_trailing_metadata(exec_ctx, t, s); } static void incoming_byte_stream_destroy(grpc_exec_ctx *exec_ctx, -- cgit v1.2.3 From e27f061fa91cc57c6d4f0620b63cdbac83afeead Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Fri, 7 Apr 2017 00:37:04 -0700 Subject: Unban --- src/core/ext/transport/chttp2/transport/chttp2_transport.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/core/ext/transport') diff --git a/src/core/ext/transport/chttp2/transport/chttp2_transport.c b/src/core/ext/transport/chttp2/transport/chttp2_transport.c index ca95d8289a..ed3f5e6192 100644 --- a/src/core/ext/transport/chttp2/transport/chttp2_transport.c +++ b/src/core/ext/transport/chttp2/transport/chttp2_transport.c @@ -2445,7 +2445,7 @@ static grpc_error *deframe_unprocessed_incoming_frames( &s->unprocessed_incoming_frames_buffer, grpc_slice_sub(slice, (size_t)(cur - beg), (size_t)(end - beg))); } - grpc_slice_unref(slice); + grpc_slice_unref_internal(exec_ctx, slice); return GRPC_ERROR_NONE; case GRPC_CHTTP2_DATA_FRAME: { GPR_ASSERT(p->parsing_frame != NULL); -- cgit v1.2.3 From d7a610bf545e03f49ef029f81b2b06a378869646 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Fri, 7 Apr 2017 09:46:43 -0700 Subject: clang-format and unban --- .../transport/chttp2/transport/chttp2_transport.c | 31 +++++++++++++--------- 1 file changed, 18 insertions(+), 13 deletions(-) (limited to 'src/core/ext/transport') diff --git a/src/core/ext/transport/chttp2/transport/chttp2_transport.c b/src/core/ext/transport/chttp2/transport/chttp2_transport.c index ed3f5e6192..65bd56477c 100644 --- a/src/core/ext/transport/chttp2/transport/chttp2_transport.c +++ b/src/core/ext/transport/chttp2/transport/chttp2_transport.c @@ -528,10 +528,11 @@ static void destroy_transport_locked(grpc_exec_ctx *exec_ctx, void *tp, static void destroy_transport(grpc_exec_ctx *exec_ctx, grpc_transport *gt) { grpc_chttp2_transport *t = (grpc_chttp2_transport *)gt; - grpc_closure_sched(exec_ctx, grpc_closure_create( - destroy_transport_locked, t, - grpc_combiner_scheduler(t->combiner, false)), - GRPC_ERROR_NONE); + grpc_closure_sched( + exec_ctx, + grpc_closure_create(destroy_transport_locked, t, + grpc_combiner_scheduler(t->combiner, false)), + GRPC_ERROR_NONE); } static void close_transport_locked(grpc_exec_ctx *exec_ctx, @@ -709,8 +710,9 @@ static void destroy_stream(grpc_exec_ctx *exec_ctx, grpc_transport *gt, s->destroy_stream_arg = then_schedule_closure; grpc_closure_sched( - exec_ctx, grpc_closure_init(&s->destroy_stream, destroy_stream_locked, s, - grpc_combiner_scheduler(t->combiner, false)), + exec_ctx, + grpc_closure_init(&s->destroy_stream, destroy_stream_locked, s, + grpc_combiner_scheduler(t->combiner, false)), GRPC_ERROR_NONE); GPR_TIMER_END("destroy_stream", 0); } @@ -1534,9 +1536,10 @@ static void perform_transport_op(grpc_exec_ctx *exec_ctx, grpc_transport *gt, op->handler_private.extra_arg = gt; GRPC_CHTTP2_REF_TRANSPORT(t, "transport_op"); grpc_closure_sched( - exec_ctx, grpc_closure_init(&op->handler_private.closure, - perform_transport_op_locked, op, - grpc_combiner_scheduler(t->combiner, false)), + exec_ctx, + grpc_closure_init(&op->handler_private.closure, + perform_transport_op_locked, op, + grpc_combiner_scheduler(t->combiner, false)), GRPC_ERROR_NONE); } @@ -1621,7 +1624,8 @@ void grpc_chttp2_maybe_complete_recv_trailing_metadata(grpc_exec_ctx *exec_ctx, exec_ctx, &s->unprocessed_incoming_frames_buffer); } } - bool pending_data = s->pending_byte_stream || s->unprocessed_incoming_frames_buffer.length > 0; + bool pending_data = s->pending_byte_stream || + s->unprocessed_incoming_frames_buffer.length > 0; if (s->read_closed && s->frame_storage.length == 0 && (!pending_data || s->seen_error) && s->recv_trailing_metadata_finished != NULL) { @@ -2267,8 +2271,9 @@ static void keepalive_watchdog_fired_locked(grpc_exec_ctx *exec_ctx, void *arg, if (t->keepalive_state == GRPC_CHTTP2_KEEPALIVE_STATE_PINGING) { if (error == GRPC_ERROR_NONE) { t->keepalive_state = GRPC_CHTTP2_KEEPALIVE_STATE_DYING; - close_transport_locked(exec_ctx, t, GRPC_ERROR_CREATE_FROM_STATIC_STRING( - "keepalive watchdog timeout")); + close_transport_locked( + exec_ctx, t, + GRPC_ERROR_CREATE_FROM_STATIC_STRING("keepalive watchdog timeout")); } } else { /** The watchdog timer should have been cancelled by @@ -2500,7 +2505,7 @@ static grpc_error *deframe_unprocessed_incoming_frames( grpc_slice_buffer_undo_take_first( &s->unprocessed_incoming_frames_buffer, grpc_slice_sub(slice, (size_t)(cur - beg), (size_t)(end - beg))); - grpc_slice_unref(slice); + grpc_slice_unref_internal(exec_ctx, slice); return GRPC_ERROR_NONE; } } -- cgit v1.2.3 From 848073f77d3750ee587bb07624a213d293c9fc48 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Fri, 7 Apr 2017 10:53:15 -0700 Subject: Clean up unused variables and funcs --- .../transport/chttp2/transport/chttp2_transport.c | 8 ------ .../ext/transport/chttp2/transport/frame_data.c | 33 ---------------------- src/core/ext/transport/chttp2/transport/internal.h | 5 ---- test/cpp/microbenchmarks/bm_chttp2_transport.cc | 3 +- 4 files changed, 1 insertion(+), 48 deletions(-) (limited to 'src/core/ext/transport') diff --git a/src/core/ext/transport/chttp2/transport/chttp2_transport.c b/src/core/ext/transport/chttp2/transport/chttp2_transport.c index 79ff5e6e72..209d76c271 100644 --- a/src/core/ext/transport/chttp2/transport/chttp2_transport.c +++ b/src/core/ext/transport/chttp2/transport/chttp2_transport.c @@ -2624,8 +2624,6 @@ static grpc_error *deframe_unprocessed_incoming_frames( static void incoming_byte_stream_unref(grpc_exec_ctx *exec_ctx, grpc_chttp2_incoming_byte_stream *bs) { if (gpr_unref(&bs->refs)) { - grpc_slice_buffer_destroy_internal(exec_ctx, &bs->slices); - gpr_mu_destroy(&bs->slice_mu); gpr_free(bs); } } @@ -2844,11 +2842,9 @@ grpc_error *grpc_chttp2_incoming_byte_stream_finished( grpc_chttp2_stream *s = bs->stream; if (error == GRPC_ERROR_NONE) { - gpr_mu_lock(&bs->slice_mu); if (bs->remaining_bytes != 0) { error = GRPC_ERROR_CREATE_FROM_STATIC_STRING("Truncated message"); } - gpr_mu_unlock(&bs->slice_mu); } if (error != GRPC_ERROR_NONE && reset_on_error) { grpc_closure_sched(exec_ctx, &s->reset_byte_stream, GRPC_ERROR_REF(error)); @@ -2869,15 +2865,11 @@ grpc_chttp2_incoming_byte_stream *grpc_chttp2_incoming_byte_stream_create( incoming_byte_stream->base.next = incoming_byte_stream_next; incoming_byte_stream->base.pull = incoming_byte_stream_pull; incoming_byte_stream->base.destroy = incoming_byte_stream_destroy; - gpr_mu_init(&incoming_byte_stream->slice_mu); gpr_ref_init(&incoming_byte_stream->refs, 2); - incoming_byte_stream->next_message = NULL; incoming_byte_stream->transport = t; incoming_byte_stream->stream = s; - grpc_slice_buffer_init(&incoming_byte_stream->slices); incoming_byte_stream->is_tail = 1; s->byte_stream_error = GRPC_ERROR_NONE; - incoming_byte_stream->push_closed = false; return incoming_byte_stream; } diff --git a/src/core/ext/transport/chttp2/transport/frame_data.c b/src/core/ext/transport/chttp2/transport/frame_data.c index 8b42d05c72..af754e1a77 100644 --- a/src/core/ext/transport/chttp2/transport/frame_data.c +++ b/src/core/ext/transport/chttp2/transport/frame_data.c @@ -84,39 +84,6 @@ grpc_error *grpc_chttp2_data_parser_begin_frame(grpc_chttp2_data_parser *parser, return GRPC_ERROR_NONE; } -void grpc_chttp2_incoming_frame_queue_merge( - grpc_chttp2_incoming_frame_queue *head_dst, - grpc_chttp2_incoming_frame_queue *tail_src) { - if (tail_src->head == NULL) { - return; - } - - if (head_dst->head == NULL) { - *head_dst = *tail_src; - memset(tail_src, 0, sizeof(*tail_src)); - return; - } - - head_dst->tail->next_message = tail_src->head; - head_dst->tail = tail_src->tail; - memset(tail_src, 0, sizeof(*tail_src)); -} - -grpc_byte_stream *grpc_chttp2_incoming_frame_queue_pop( - grpc_chttp2_incoming_frame_queue *q) { - grpc_byte_stream *out; - if (q->head == NULL) { - return NULL; - } - out = &q->head->base; - if (q->head == q->tail) { - memset(q, 0, sizeof(*q)); - } else { - q->head = q->head->next_message; - } - return out; -} - void grpc_chttp2_encode_data(uint32_t id, grpc_slice_buffer *inbuf, uint32_t write_bytes, int is_eof, grpc_transport_one_way_stats *stats, diff --git a/src/core/ext/transport/chttp2/transport/internal.h b/src/core/ext/transport/chttp2/transport/internal.h index 467c9353dd..773f541e97 100644 --- a/src/core/ext/transport/chttp2/transport/internal.h +++ b/src/core/ext/transport/chttp2/transport/internal.h @@ -195,16 +195,11 @@ typedef struct grpc_chttp2_write_cb { struct grpc_chttp2_incoming_byte_stream { grpc_byte_stream base; gpr_refcount refs; - struct grpc_chttp2_incoming_byte_stream - *next_message; /* unused; should be removed */ - bool push_closed; /* protected by slice_mu */ grpc_chttp2_transport *transport; /* immutable */ grpc_chttp2_stream *stream; /* immutable */ bool is_tail; /* immutable */ - gpr_mu slice_mu; - grpc_slice_buffer slices; /* unused; should be removed */ uint32_t remaining_bytes; /* guaranteed one thread access */ struct { diff --git a/test/cpp/microbenchmarks/bm_chttp2_transport.cc b/test/cpp/microbenchmarks/bm_chttp2_transport.cc index 5456f69d50..8c5413b5fd 100644 --- a/test/cpp/microbenchmarks/bm_chttp2_transport.cc +++ b/test/cpp/microbenchmarks/bm_chttp2_transport.cc @@ -575,8 +575,7 @@ static void BM_TransportStreamRecv(benchmark::State &state) { GRPC_ERROR_NONE == grpc_byte_stream_pull(exec_ctx, recv_stream, &recv_slice) && (received += GRPC_SLICE_LENGTH(recv_slice), - grpc_slice_unref_internal(exec_ctx, recv_slice), - true)); + grpc_slice_unref_internal(exec_ctx, recv_slice), true)); }); drain_continue = MakeClosure([&](grpc_exec_ctx *exec_ctx, grpc_error *error) { -- cgit v1.2.3 From c702a7a85f9756e94c04e011c11d47a96733ac95 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Sun, 9 Apr 2017 13:18:55 -0700 Subject: clang-format --- .../transport/chttp2/transport/chttp2_transport.c | 26 +++++++++------------- .../transport/cronet/transport/cronet_transport.c | 10 ++++++--- src/core/lib/channel/compress_filter.c | 15 ++++++++----- src/core/lib/channel/http_client_filter.c | 15 ++++++++----- 4 files changed, 36 insertions(+), 30 deletions(-) (limited to 'src/core/ext/transport') diff --git a/src/core/ext/transport/chttp2/transport/chttp2_transport.c b/src/core/ext/transport/chttp2/transport/chttp2_transport.c index 209d76c271..c78c8def69 100644 --- a/src/core/ext/transport/chttp2/transport/chttp2_transport.c +++ b/src/core/ext/transport/chttp2/transport/chttp2_transport.c @@ -575,11 +575,10 @@ static void destroy_transport_locked(grpc_exec_ctx *exec_ctx, void *tp, static void destroy_transport(grpc_exec_ctx *exec_ctx, grpc_transport *gt) { grpc_chttp2_transport *t = (grpc_chttp2_transport *)gt; - grpc_closure_sched( - exec_ctx, - grpc_closure_create(destroy_transport_locked, t, - grpc_combiner_scheduler(t->combiner, false)), - GRPC_ERROR_NONE); + grpc_closure_sched(exec_ctx, grpc_closure_create( + destroy_transport_locked, t, + grpc_combiner_scheduler(t->combiner, false)), + GRPC_ERROR_NONE); } static void close_transport_locked(grpc_exec_ctx *exec_ctx, @@ -757,9 +756,8 @@ static void destroy_stream(grpc_exec_ctx *exec_ctx, grpc_transport *gt, s->destroy_stream_arg = then_schedule_closure; grpc_closure_sched( - exec_ctx, - grpc_closure_init(&s->destroy_stream, destroy_stream_locked, s, - grpc_combiner_scheduler(t->combiner, false)), + exec_ctx, grpc_closure_init(&s->destroy_stream, destroy_stream_locked, s, + grpc_combiner_scheduler(t->combiner, false)), GRPC_ERROR_NONE); GPR_TIMER_END("destroy_stream", 0); } @@ -1618,10 +1616,9 @@ static void perform_transport_op(grpc_exec_ctx *exec_ctx, grpc_transport *gt, op->handler_private.extra_arg = gt; GRPC_CHTTP2_REF_TRANSPORT(t, "transport_op"); grpc_closure_sched( - exec_ctx, - grpc_closure_init(&op->handler_private.closure, - perform_transport_op_locked, op, - grpc_combiner_scheduler(t->combiner, false)), + exec_ctx, grpc_closure_init(&op->handler_private.closure, + perform_transport_op_locked, op, + grpc_combiner_scheduler(t->combiner, false)), GRPC_ERROR_NONE); } @@ -2377,9 +2374,8 @@ static void keepalive_watchdog_fired_locked(grpc_exec_ctx *exec_ctx, void *arg, if (t->keepalive_state == GRPC_CHTTP2_KEEPALIVE_STATE_PINGING) { if (error == GRPC_ERROR_NONE) { t->keepalive_state = GRPC_CHTTP2_KEEPALIVE_STATE_DYING; - close_transport_locked( - exec_ctx, t, - GRPC_ERROR_CREATE_FROM_STATIC_STRING("keepalive watchdog timeout")); + close_transport_locked(exec_ctx, t, GRPC_ERROR_CREATE_FROM_STATIC_STRING( + "keepalive watchdog timeout")); } } else { /* The watchdog timer should have been cancelled by diff --git a/src/core/ext/transport/cronet/transport/cronet_transport.c b/src/core/ext/transport/cronet/transport/cronet_transport.c index 0b55a5a3bb..7f09936e93 100644 --- a/src/core/ext/transport/cronet/transport/cronet_transport.c +++ b/src/core/ext/transport/cronet/transport/cronet_transport.c @@ -973,13 +973,17 @@ static enum e_op_result execute_stream_op(grpc_exec_ctx *exec_ctx, grpc_slice_buffer write_slice_buffer; grpc_slice slice; grpc_slice_buffer_init(&write_slice_buffer); - if (1 != grpc_byte_stream_next(exec_ctx, stream_op->payload->send_message.send_message, - stream_op->payload->send_message.send_message->length, NULL)) { + if (1 != grpc_byte_stream_next( + exec_ctx, stream_op->payload->send_message.send_message, + stream_op->payload->send_message.send_message->length, + NULL)) { /* Should never reach here */ GPR_ASSERT(false); } if (GRPC_ERROR_NONE != - grpc_byte_stream_pull(exec_ctx, stream_op->payload->send_message.send_message, &slice)) { + grpc_byte_stream_pull(exec_ctx, + stream_op->payload->send_message.send_message, + &slice)) { /* Should never reach here */ GPR_ASSERT(false); } diff --git a/src/core/lib/channel/compress_filter.c b/src/core/lib/channel/compress_filter.c index a945639fae..764524b24d 100644 --- a/src/core/lib/channel/compress_filter.c +++ b/src/core/lib/channel/compress_filter.c @@ -221,9 +221,10 @@ static void finish_send_message(grpc_exec_ctx *exec_ctx, static void got_slice(grpc_exec_ctx *exec_ctx, void *elemp, grpc_error *error) { grpc_call_element *elem = elemp; call_data *calld = elem->call_data; - if (GRPC_ERROR_NONE != grpc_byte_stream_pull(exec_ctx, - calld->send_op->payload->send_message.send_message, - &calld->incoming_slice)) { + if (GRPC_ERROR_NONE != + grpc_byte_stream_pull(exec_ctx, + calld->send_op->payload->send_message.send_message, + &calld->incoming_slice)) { /* Should never reach here */ abort(); } @@ -238,9 +239,11 @@ static void got_slice(grpc_exec_ctx *exec_ctx, void *elemp, grpc_error *error) { static void continue_send_message(grpc_exec_ctx *exec_ctx, grpc_call_element *elem) { call_data *calld = elem->call_data; - while (grpc_byte_stream_next(exec_ctx, calld->send_op->payload->send_message.send_message, - ~(size_t)0, &calld->got_slice)) { - grpc_byte_stream_pull(exec_ctx, calld->send_op->payload->send_message.send_message, + while (grpc_byte_stream_next( + exec_ctx, calld->send_op->payload->send_message.send_message, ~(size_t)0, + &calld->got_slice)) { + grpc_byte_stream_pull(exec_ctx, + calld->send_op->payload->send_message.send_message, &calld->incoming_slice); grpc_slice_buffer_add(&calld->slices, calld->incoming_slice); if (calld->send_length == calld->slices.length) { diff --git a/src/core/lib/channel/http_client_filter.c b/src/core/lib/channel/http_client_filter.c index 57bbb98139..151fb9885d 100644 --- a/src/core/lib/channel/http_client_filter.c +++ b/src/core/lib/channel/http_client_filter.c @@ -219,9 +219,11 @@ static void continue_send_message(grpc_exec_ctx *exec_ctx, grpc_call_element *elem) { call_data *calld = elem->call_data; uint8_t *wrptr = calld->payload_bytes; - while (grpc_byte_stream_next(exec_ctx, calld->send_op->payload->send_message.send_message, - ~(size_t)0, &calld->got_slice)) { - grpc_byte_stream_pull(exec_ctx, calld->send_op->payload->send_message.send_message, + while (grpc_byte_stream_next( + exec_ctx, calld->send_op->payload->send_message.send_message, ~(size_t)0, + &calld->got_slice)) { + grpc_byte_stream_pull(exec_ctx, + calld->send_op->payload->send_message.send_message, &calld->incoming_slice); memcpy(wrptr, GRPC_SLICE_START_PTR(calld->incoming_slice), GRPC_SLICE_LENGTH(calld->incoming_slice)); @@ -238,9 +240,10 @@ static void got_slice(grpc_exec_ctx *exec_ctx, void *elemp, grpc_error *error) { grpc_call_element *elem = elemp; call_data *calld = elem->call_data; calld->send_message_blocked = false; - if (GRPC_ERROR_NONE != grpc_byte_stream_pull(exec_ctx, - calld->send_op->payload->send_message.send_message, - &calld->incoming_slice)) { + if (GRPC_ERROR_NONE != + grpc_byte_stream_pull(exec_ctx, + calld->send_op->payload->send_message.send_message, + &calld->incoming_slice)) { /* Should never reach here */ abort(); } -- cgit v1.2.3 From 300be7ece2fc7a0c893bd3cf7b34a8558b34726e Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Sun, 9 Apr 2017 15:44:19 -0700 Subject: Fix the cronet_transport error --- src/core/ext/transport/cronet/transport/cronet_transport.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/core/ext/transport') diff --git a/src/core/ext/transport/cronet/transport/cronet_transport.c b/src/core/ext/transport/cronet/transport/cronet_transport.c index 0b9189558f..3ca6b2fdf6 100644 --- a/src/core/ext/transport/cronet/transport/cronet_transport.c +++ b/src/core/ext/transport/cronet/transport/cronet_transport.c @@ -1124,7 +1124,7 @@ static enum e_op_result execute_stream_op(grpc_exec_ctx *exec_ctx, if (stream_state->rs.compressed) { stream_state->rs.sbs.base.flags |= GRPC_WRITE_INTERNAL_COMPRESS; } - *((grpc_byte_buffer **)stream_op->recv_message) = + *((grpc_byte_buffer **)stream_op->payload->recv_message.recv_message) = (grpc_byte_buffer *)&stream_state->rs.sbs; grpc_closure_sched( exec_ctx, stream_op->payload->recv_message.recv_message_ready, -- cgit v1.2.3 From 48cba2adb45bc3a60b9fc6234757bcd9a84c5697 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Mon, 10 Apr 2017 17:08:01 -0700 Subject: Send content-type on trailer-only responses --- .../transport/chttp2/transport/chttp2_transport.c | 38 ++++++++++++++++++++++ 1 file changed, 38 insertions(+) (limited to 'src/core/ext/transport') diff --git a/src/core/ext/transport/chttp2/transport/chttp2_transport.c b/src/core/ext/transport/chttp2/transport/chttp2_transport.c index e2816b0e04..7323f4cb2e 100644 --- a/src/core/ext/transport/chttp2/transport/chttp2_transport.c +++ b/src/core/ext/transport/chttp2/transport/chttp2_transport.c @@ -1890,6 +1890,7 @@ static void close_from_api(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t, grpc_slice hdr; grpc_slice status_hdr; grpc_slice http_status_hdr; + grpc_slice content_type_hdr; grpc_slice message_pfx; uint8_t *p; uint32_t len = 0; @@ -1923,6 +1924,42 @@ static void close_from_api(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t, *p++ = '0'; GPR_ASSERT(p == GRPC_SLICE_END_PTR(http_status_hdr)); len += (uint32_t)GRPC_SLICE_LENGTH(http_status_hdr); + + content_type_hdr = grpc_slice_malloc(31); + p = GRPC_SLICE_START_PTR(content_type_hdr); + *p++ = 0x00; + *p++ = 12; + *p++ = 'c'; + *p++ = 'o'; + *p++ = 'n'; + *p++ = 't'; + *p++ = 'e'; + *p++ = 'n'; + *p++ = 't'; + *p++ = '-'; + *p++ = 't'; + *p++ = 'y'; + *p++ = 'p'; + *p++ = 'e'; + *p++ = 16; + *p++ = 'a'; + *p++ = 'p'; + *p++ = 'p'; + *p++ = 'l'; + *p++ = 'i'; + *p++ = 'c'; + *p++ = 'a'; + *p++ = 't'; + *p++ = 'i'; + *p++ = 'o'; + *p++ = 'n'; + *p++ = '/'; + *p++ = 'g'; + *p++ = 'r'; + *p++ = 'p'; + *p++ = 'c'; + GPR_ASSERT(p == GRPC_SLICE_END_PTR(content_type_hdr)); + len += (uint32_t)GRPC_SLICE_LENGTH(content_type_hdr); } status_hdr = grpc_slice_malloc(15 + (grpc_status >= 10)); @@ -1992,6 +2029,7 @@ static void close_from_api(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t, grpc_slice_buffer_add(&t->qbuf, hdr); if (!s->sent_initial_metadata) { grpc_slice_buffer_add(&t->qbuf, http_status_hdr); + grpc_slice_buffer_add(&t->qbuf, content_type_hdr); } grpc_slice_buffer_add(&t->qbuf, status_hdr); grpc_slice_buffer_add(&t->qbuf, message_pfx); -- cgit v1.2.3 From e899e32710ba6742d986a3c7725a2358d1081f83 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Mon, 10 Apr 2017 18:14:49 -0700 Subject: Move deframe_unprocessed_incoming_frames to frame_data.c --- .../transport/chttp2/transport/chttp2_transport.c | 181 +-------------------- .../ext/transport/chttp2/transport/frame_data.c | 178 ++++++++++++++++++++ .../ext/transport/chttp2/transport/frame_data.h | 7 + 3 files changed, 186 insertions(+), 180 deletions(-) (limited to 'src/core/ext/transport') diff --git a/src/core/ext/transport/chttp2/transport/chttp2_transport.c b/src/core/ext/transport/chttp2/transport/chttp2_transport.c index c78c8def69..093370d11a 100644 --- a/src/core/ext/transport/chttp2/transport/chttp2_transport.c +++ b/src/core/ext/transport/chttp2/transport/chttp2_transport.c @@ -44,6 +44,7 @@ #include #include +#include "src/core/ext/transport/chttp2/transport/frame_data.h" #include "src/core/ext/transport/chttp2/transport/internal.h" #include "src/core/ext/transport/chttp2/transport/varint.h" #include "src/core/lib/channel/channel_args.h" @@ -179,10 +180,6 @@ static void finish_keepalive_ping_locked(grpc_exec_ctx *exec_ctx, void *arg, static void keepalive_watchdog_fired_locked(grpc_exec_ctx *exec_ctx, void *arg, grpc_error *error); -static grpc_error *deframe_unprocessed_incoming_frames( - grpc_exec_ctx *exec_ctx, grpc_chttp2_data_parser *p, grpc_chttp2_stream *s, - grpc_slice_buffer *slices, grpc_slice *slice_out, - grpc_byte_stream **stream_out); static void reset_byte_stream(grpc_exec_ctx *exec_ctx, void *arg, grpc_error *error); @@ -2441,182 +2438,6 @@ static void reset_byte_stream(grpc_exec_ctx *exec_ctx, void *arg, } } -static grpc_error *deframe_unprocessed_incoming_frames( - grpc_exec_ctx *exec_ctx, grpc_chttp2_data_parser *p, grpc_chttp2_stream *s, - grpc_slice_buffer *slices, grpc_slice *slice_out, - grpc_byte_stream **stream_out) { - grpc_error *error = GRPC_ERROR_NONE; - grpc_chttp2_transport *t = s->t; - - while (slices->count > 0) { - uint8_t *beg = NULL; - uint8_t *end = NULL; - uint8_t *cur = NULL; - - grpc_slice slice = grpc_slice_buffer_take_first(slices); - - beg = GRPC_SLICE_START_PTR(slice); - end = GRPC_SLICE_END_PTR(slice); - cur = beg; - uint32_t message_flags; - char *msg; - - if (cur == end) { - grpc_slice_unref_internal(exec_ctx, slice); - continue; - } - - switch (p->state) { - case GRPC_CHTTP2_DATA_ERROR: - p->state = GRPC_CHTTP2_DATA_ERROR; - grpc_slice_unref_internal(exec_ctx, slice); - return GRPC_ERROR_REF(p->error); - case GRPC_CHTTP2_DATA_FH_0: - p->frame_type = *cur; - switch (p->frame_type) { - case 0: - p->is_frame_compressed = 0; /* GPR_FALSE */ - break; - case 1: - p->is_frame_compressed = 1; /* GPR_TRUE */ - break; - default: - gpr_asprintf(&msg, "Bad GRPC frame type 0x%02x", p->frame_type); - p->error = GRPC_ERROR_CREATE_FROM_COPIED_STRING(msg); - p->error = grpc_error_set_int(p->error, GRPC_ERROR_INT_STREAM_ID, - (intptr_t)s->id); - gpr_free(msg); - msg = grpc_dump_slice(slice, GPR_DUMP_HEX | GPR_DUMP_ASCII); - p->error = grpc_error_set_str(p->error, GRPC_ERROR_STR_RAW_BYTES, - grpc_slice_from_copied_string(msg)); - gpr_free(msg); - p->error = - grpc_error_set_int(p->error, GRPC_ERROR_INT_OFFSET, cur - beg); - p->state = GRPC_CHTTP2_DATA_ERROR; - grpc_slice_unref_internal(exec_ctx, slice); - return GRPC_ERROR_REF(p->error); - } - if (++cur == end) { - p->state = GRPC_CHTTP2_DATA_FH_1; - grpc_slice_unref_internal(exec_ctx, slice); - continue; - } - /* fallthrough */ - case GRPC_CHTTP2_DATA_FH_1: - p->frame_size = ((uint32_t)*cur) << 24; - if (++cur == end) { - p->state = GRPC_CHTTP2_DATA_FH_2; - grpc_slice_unref_internal(exec_ctx, slice); - continue; - } - /* fallthrough */ - case GRPC_CHTTP2_DATA_FH_2: - p->frame_size |= ((uint32_t)*cur) << 16; - if (++cur == end) { - p->state = GRPC_CHTTP2_DATA_FH_3; - grpc_slice_unref_internal(exec_ctx, slice); - continue; - } - /* fallthrough */ - case GRPC_CHTTP2_DATA_FH_3: - p->frame_size |= ((uint32_t)*cur) << 8; - if (++cur == end) { - p->state = GRPC_CHTTP2_DATA_FH_4; - grpc_slice_unref_internal(exec_ctx, slice); - continue; - } - /* fallthrough */ - case GRPC_CHTTP2_DATA_FH_4: - GPR_ASSERT(stream_out != NULL); - GPR_ASSERT(p->parsing_frame == NULL); - p->frame_size |= ((uint32_t)*cur); - p->state = GRPC_CHTTP2_DATA_FRAME; - ++cur; - message_flags = 0; - if (p->is_frame_compressed) { - message_flags |= GRPC_WRITE_INTERNAL_COMPRESS; - } - p->parsing_frame = grpc_chttp2_incoming_byte_stream_create( - exec_ctx, t, s, p->frame_size, message_flags); - *stream_out = &p->parsing_frame->base; - if (p->parsing_frame->remaining_bytes == 0) { - grpc_chttp2_incoming_byte_stream_finished(exec_ctx, p->parsing_frame, - GRPC_ERROR_NONE, 1); - p->parsing_frame = NULL; - p->state = GRPC_CHTTP2_DATA_FH_0; - } - s->pending_byte_stream = true; - - if (cur != end) { - grpc_slice_buffer_undo_take_first( - &s->unprocessed_incoming_frames_buffer, - grpc_slice_sub(slice, (size_t)(cur - beg), (size_t)(end - beg))); - } - grpc_slice_unref_internal(exec_ctx, slice); - return GRPC_ERROR_NONE; - case GRPC_CHTTP2_DATA_FRAME: { - GPR_ASSERT(p->parsing_frame != NULL); - GPR_ASSERT(slice_out != NULL); - if (cur == end) { - grpc_slice_unref_internal(exec_ctx, slice); - continue; - } - uint32_t remaining = (uint32_t)(end - cur); - if (remaining == p->frame_size) { - if (GRPC_ERROR_NONE != (error = grpc_chttp2_incoming_byte_stream_push( - exec_ctx, p->parsing_frame, - grpc_slice_sub(slice, (size_t)(cur - beg), - (size_t)(end - beg)), - slice_out))) { - grpc_slice_unref_internal(exec_ctx, slice); - return error; - } - grpc_chttp2_incoming_byte_stream_finished(exec_ctx, p->parsing_frame, - GRPC_ERROR_NONE, 1); - p->parsing_frame = NULL; - p->state = GRPC_CHTTP2_DATA_FH_0; - grpc_slice_unref_internal(exec_ctx, slice); - return GRPC_ERROR_NONE; - } else if (remaining < p->frame_size) { - if (GRPC_ERROR_NONE != (error = grpc_chttp2_incoming_byte_stream_push( - exec_ctx, p->parsing_frame, - grpc_slice_sub(slice, (size_t)(cur - beg), - (size_t)(end - beg)), - slice_out))) { - return error; - } - p->frame_size -= remaining; - grpc_slice_unref_internal(exec_ctx, slice); - return GRPC_ERROR_NONE; - } else { - GPR_ASSERT(remaining > p->frame_size); - if (GRPC_ERROR_NONE != - (grpc_chttp2_incoming_byte_stream_push( - exec_ctx, p->parsing_frame, - grpc_slice_sub(slice, (size_t)(cur - beg), - (size_t)(cur + p->frame_size - beg)), - slice_out))) { - grpc_slice_unref_internal(exec_ctx, slice); - return error; - } - grpc_chttp2_incoming_byte_stream_finished(exec_ctx, p->parsing_frame, - GRPC_ERROR_NONE, 1); - p->parsing_frame = NULL; - p->state = GRPC_CHTTP2_DATA_FH_0; - cur += p->frame_size; - grpc_slice_buffer_undo_take_first( - &s->unprocessed_incoming_frames_buffer, - grpc_slice_sub(slice, (size_t)(cur - beg), (size_t)(end - beg))); - grpc_slice_unref_internal(exec_ctx, slice); - return GRPC_ERROR_NONE; - } - } - } - } - - return GRPC_ERROR_NONE; -} - static void incoming_byte_stream_unref(grpc_exec_ctx *exec_ctx, grpc_chttp2_incoming_byte_stream *bs) { if (gpr_unref(&bs->refs)) { diff --git a/src/core/ext/transport/chttp2/transport/frame_data.c b/src/core/ext/transport/chttp2/transport/frame_data.c index af754e1a77..4aa61ae68e 100644 --- a/src/core/ext/transport/chttp2/transport/frame_data.c +++ b/src/core/ext/transport/chttp2/transport/frame_data.c @@ -112,6 +112,184 @@ void grpc_chttp2_encode_data(uint32_t id, grpc_slice_buffer *inbuf, stats->data_bytes += write_bytes; } +grpc_error *deframe_unprocessed_incoming_frames(grpc_exec_ctx *exec_ctx, + grpc_chttp2_data_parser *p, + grpc_chttp2_stream *s, + grpc_slice_buffer *slices, + grpc_slice *slice_out, + grpc_byte_stream **stream_out) { + grpc_error *error = GRPC_ERROR_NONE; + grpc_chttp2_transport *t = s->t; + + while (slices->count > 0) { + uint8_t *beg = NULL; + uint8_t *end = NULL; + uint8_t *cur = NULL; + + grpc_slice slice = grpc_slice_buffer_take_first(slices); + + beg = GRPC_SLICE_START_PTR(slice); + end = GRPC_SLICE_END_PTR(slice); + cur = beg; + uint32_t message_flags; + char *msg; + + if (cur == end) { + grpc_slice_unref_internal(exec_ctx, slice); + continue; + } + + switch (p->state) { + case GRPC_CHTTP2_DATA_ERROR: + p->state = GRPC_CHTTP2_DATA_ERROR; + grpc_slice_unref_internal(exec_ctx, slice); + return GRPC_ERROR_REF(p->error); + case GRPC_CHTTP2_DATA_FH_0: + p->frame_type = *cur; + switch (p->frame_type) { + case 0: + p->is_frame_compressed = 0; /* GPR_FALSE */ + break; + case 1: + p->is_frame_compressed = 1; /* GPR_TRUE */ + break; + default: + gpr_asprintf(&msg, "Bad GRPC frame type 0x%02x", p->frame_type); + p->error = GRPC_ERROR_CREATE_FROM_COPIED_STRING(msg); + p->error = grpc_error_set_int(p->error, GRPC_ERROR_INT_STREAM_ID, + (intptr_t)s->id); + gpr_free(msg); + msg = grpc_dump_slice(slice, GPR_DUMP_HEX | GPR_DUMP_ASCII); + p->error = grpc_error_set_str(p->error, GRPC_ERROR_STR_RAW_BYTES, + grpc_slice_from_copied_string(msg)); + gpr_free(msg); + p->error = + grpc_error_set_int(p->error, GRPC_ERROR_INT_OFFSET, cur - beg); + p->state = GRPC_CHTTP2_DATA_ERROR; + grpc_slice_unref_internal(exec_ctx, slice); + return GRPC_ERROR_REF(p->error); + } + if (++cur == end) { + p->state = GRPC_CHTTP2_DATA_FH_1; + grpc_slice_unref_internal(exec_ctx, slice); + continue; + } + /* fallthrough */ + case GRPC_CHTTP2_DATA_FH_1: + p->frame_size = ((uint32_t)*cur) << 24; + if (++cur == end) { + p->state = GRPC_CHTTP2_DATA_FH_2; + grpc_slice_unref_internal(exec_ctx, slice); + continue; + } + /* fallthrough */ + case GRPC_CHTTP2_DATA_FH_2: + p->frame_size |= ((uint32_t)*cur) << 16; + if (++cur == end) { + p->state = GRPC_CHTTP2_DATA_FH_3; + grpc_slice_unref_internal(exec_ctx, slice); + continue; + } + /* fallthrough */ + case GRPC_CHTTP2_DATA_FH_3: + p->frame_size |= ((uint32_t)*cur) << 8; + if (++cur == end) { + p->state = GRPC_CHTTP2_DATA_FH_4; + grpc_slice_unref_internal(exec_ctx, slice); + continue; + } + /* fallthrough */ + case GRPC_CHTTP2_DATA_FH_4: + GPR_ASSERT(stream_out != NULL); + GPR_ASSERT(p->parsing_frame == NULL); + p->frame_size |= ((uint32_t)*cur); + p->state = GRPC_CHTTP2_DATA_FRAME; + ++cur; + message_flags = 0; + if (p->is_frame_compressed) { + message_flags |= GRPC_WRITE_INTERNAL_COMPRESS; + } + p->parsing_frame = grpc_chttp2_incoming_byte_stream_create( + exec_ctx, t, s, p->frame_size, message_flags); + *stream_out = &p->parsing_frame->base; + if (p->parsing_frame->remaining_bytes == 0) { + grpc_chttp2_incoming_byte_stream_finished(exec_ctx, p->parsing_frame, + GRPC_ERROR_NONE, 1); + p->parsing_frame = NULL; + p->state = GRPC_CHTTP2_DATA_FH_0; + } + s->pending_byte_stream = true; + + if (cur != end) { + grpc_slice_buffer_undo_take_first( + &s->unprocessed_incoming_frames_buffer, + grpc_slice_sub(slice, (size_t)(cur - beg), (size_t)(end - beg))); + } + grpc_slice_unref_internal(exec_ctx, slice); + return GRPC_ERROR_NONE; + case GRPC_CHTTP2_DATA_FRAME: { + GPR_ASSERT(p->parsing_frame != NULL); + GPR_ASSERT(slice_out != NULL); + if (cur == end) { + grpc_slice_unref_internal(exec_ctx, slice); + continue; + } + uint32_t remaining = (uint32_t)(end - cur); + if (remaining == p->frame_size) { + if (GRPC_ERROR_NONE != (error = grpc_chttp2_incoming_byte_stream_push( + exec_ctx, p->parsing_frame, + grpc_slice_sub(slice, (size_t)(cur - beg), + (size_t)(end - beg)), + slice_out))) { + grpc_slice_unref_internal(exec_ctx, slice); + return error; + } + grpc_chttp2_incoming_byte_stream_finished(exec_ctx, p->parsing_frame, + GRPC_ERROR_NONE, 1); + p->parsing_frame = NULL; + p->state = GRPC_CHTTP2_DATA_FH_0; + grpc_slice_unref_internal(exec_ctx, slice); + return GRPC_ERROR_NONE; + } else if (remaining < p->frame_size) { + if (GRPC_ERROR_NONE != (error = grpc_chttp2_incoming_byte_stream_push( + exec_ctx, p->parsing_frame, + grpc_slice_sub(slice, (size_t)(cur - beg), + (size_t)(end - beg)), + slice_out))) { + return error; + } + p->frame_size -= remaining; + grpc_slice_unref_internal(exec_ctx, slice); + return GRPC_ERROR_NONE; + } else { + GPR_ASSERT(remaining > p->frame_size); + if (GRPC_ERROR_NONE != + (grpc_chttp2_incoming_byte_stream_push( + exec_ctx, p->parsing_frame, + grpc_slice_sub(slice, (size_t)(cur - beg), + (size_t)(cur + p->frame_size - beg)), + slice_out))) { + grpc_slice_unref_internal(exec_ctx, slice); + return error; + } + grpc_chttp2_incoming_byte_stream_finished(exec_ctx, p->parsing_frame, + GRPC_ERROR_NONE, 1); + p->parsing_frame = NULL; + p->state = GRPC_CHTTP2_DATA_FH_0; + cur += p->frame_size; + grpc_slice_buffer_undo_take_first( + &s->unprocessed_incoming_frames_buffer, + grpc_slice_sub(slice, (size_t)(cur - beg), (size_t)(end - beg))); + grpc_slice_unref_internal(exec_ctx, slice); + return GRPC_ERROR_NONE; + } + } + } + } + + return GRPC_ERROR_NONE; +} + grpc_error *grpc_chttp2_data_parser_parse(grpc_exec_ctx *exec_ctx, void *parser, grpc_chttp2_transport *t, grpc_chttp2_stream *s, diff --git a/src/core/ext/transport/chttp2/transport/frame_data.h b/src/core/ext/transport/chttp2/transport/frame_data.h index e7e459c79f..5783f447b5 100644 --- a/src/core/ext/transport/chttp2/transport/frame_data.h +++ b/src/core/ext/transport/chttp2/transport/frame_data.h @@ -101,4 +101,11 @@ void grpc_chttp2_encode_data(uint32_t id, grpc_slice_buffer *inbuf, grpc_transport_one_way_stats *stats, grpc_slice_buffer *outbuf); +grpc_error *deframe_unprocessed_incoming_frames(grpc_exec_ctx *exec_ctx, + grpc_chttp2_data_parser *p, + grpc_chttp2_stream *s, + grpc_slice_buffer *slices, + grpc_slice *slice_out, + grpc_byte_stream **stream_out); + #endif /* GRPC_CORE_EXT_TRANSPORT_CHTTP2_TRANSPORT_FRAME_DATA_H */ -- cgit v1.2.3 From c248f5b45073850bcb6c05b55870a689dad2ff11 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Mon, 10 Apr 2017 18:15:42 -0700 Subject: int -> bool --- src/core/ext/transport/chttp2/transport/frame_data.c | 4 ++-- src/core/ext/transport/chttp2/transport/frame_data.h | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) (limited to 'src/core/ext/transport') diff --git a/src/core/ext/transport/chttp2/transport/frame_data.c b/src/core/ext/transport/chttp2/transport/frame_data.c index 4aa61ae68e..d2193cdb32 100644 --- a/src/core/ext/transport/chttp2/transport/frame_data.c +++ b/src/core/ext/transport/chttp2/transport/frame_data.c @@ -148,10 +148,10 @@ grpc_error *deframe_unprocessed_incoming_frames(grpc_exec_ctx *exec_ctx, p->frame_type = *cur; switch (p->frame_type) { case 0: - p->is_frame_compressed = 0; /* GPR_FALSE */ + p->is_frame_compressed = false; /* GPR_FALSE */ break; case 1: - p->is_frame_compressed = 1; /* GPR_TRUE */ + p->is_frame_compressed = true; /* GPR_TRUE */ break; default: gpr_asprintf(&msg, "Bad GRPC frame type 0x%02x", p->frame_type); diff --git a/src/core/ext/transport/chttp2/transport/frame_data.h b/src/core/ext/transport/chttp2/transport/frame_data.h index 5783f447b5..17cc8d2073 100644 --- a/src/core/ext/transport/chttp2/transport/frame_data.h +++ b/src/core/ext/transport/chttp2/transport/frame_data.h @@ -67,7 +67,7 @@ typedef struct { uint32_t frame_size; grpc_error *error; - int is_frame_compressed; + bool is_frame_compressed; grpc_chttp2_incoming_byte_stream *parsing_frame; } grpc_chttp2_data_parser; -- cgit v1.2.3 From afdad3e8bb40f1f771e24cd6dded81e91603a971 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Mon, 10 Apr 2017 18:22:05 -0700 Subject: clean up unused code --- src/core/ext/transport/chttp2/transport/frame_data.h | 11 ----------- 1 file changed, 11 deletions(-) (limited to 'src/core/ext/transport') diff --git a/src/core/ext/transport/chttp2/transport/frame_data.h b/src/core/ext/transport/chttp2/transport/frame_data.h index 17cc8d2073..2fb8983c38 100644 --- a/src/core/ext/transport/chttp2/transport/frame_data.h +++ b/src/core/ext/transport/chttp2/transport/frame_data.h @@ -56,11 +56,6 @@ typedef enum { typedef struct grpc_chttp2_incoming_byte_stream grpc_chttp2_incoming_byte_stream; -typedef struct grpc_chttp2_incoming_frame_queue { - grpc_chttp2_incoming_byte_stream *head; - grpc_chttp2_incoming_byte_stream *tail; -} grpc_chttp2_incoming_frame_queue; - typedef struct { grpc_chttp2_stream_state state; uint8_t frame_type; @@ -71,12 +66,6 @@ typedef struct { grpc_chttp2_incoming_byte_stream *parsing_frame; } grpc_chttp2_data_parser; -void grpc_chttp2_incoming_frame_queue_merge( - grpc_chttp2_incoming_frame_queue *head_dst, - grpc_chttp2_incoming_frame_queue *tail_src); -grpc_byte_stream *grpc_chttp2_incoming_frame_queue_pop( - grpc_chttp2_incoming_frame_queue *q); - /* initialize per-stream state for data frame parsing */ grpc_error *grpc_chttp2_data_parser_init(grpc_chttp2_data_parser *parser); -- cgit v1.2.3 From 02646c3f62d6e5b07b62ffbdacfb64ae7946b721 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Mon, 10 Apr 2017 18:28:23 -0700 Subject: int -> bool --- src/core/ext/transport/chttp2/transport/chttp2_transport.c | 12 ++++++------ src/core/lib/transport/byte_stream.c | 10 +++++----- src/core/lib/transport/byte_stream.h | 4 ++-- 3 files changed, 13 insertions(+), 13 deletions(-) (limited to 'src/core/ext/transport') diff --git a/src/core/ext/transport/chttp2/transport/chttp2_transport.c b/src/core/ext/transport/chttp2/transport/chttp2_transport.c index 093370d11a..a0bce1e077 100644 --- a/src/core/ext/transport/chttp2/transport/chttp2_transport.c +++ b/src/core/ext/transport/chttp2/transport/chttp2_transport.c @@ -2536,16 +2536,16 @@ static void incoming_byte_stream_next_locked(grpc_exec_ctx *exec_ctx, incoming_byte_stream_unref(exec_ctx, bs); } -static int incoming_byte_stream_next(grpc_exec_ctx *exec_ctx, - grpc_byte_stream *byte_stream, - size_t max_size_hint, - grpc_closure *on_complete) { +static bool incoming_byte_stream_next(grpc_exec_ctx *exec_ctx, + grpc_byte_stream *byte_stream, + size_t max_size_hint, + grpc_closure *on_complete) { GPR_TIMER_BEGIN("incoming_byte_stream_next", 0); grpc_chttp2_incoming_byte_stream *bs = (grpc_chttp2_incoming_byte_stream *)byte_stream; grpc_chttp2_stream *s = bs->stream; if (s->unprocessed_incoming_frames_buffer.length > 0) { - return 1; + return true; } else { gpr_ref(&bs->refs); bs->next_action.max_size_hint = max_size_hint; @@ -2557,7 +2557,7 @@ static int incoming_byte_stream_next(grpc_exec_ctx *exec_ctx, grpc_combiner_scheduler(bs->transport->combiner, false)), GRPC_ERROR_NONE); GPR_TIMER_END("incoming_byte_stream_next", 0); - return 0; + return false; } } diff --git a/src/core/lib/transport/byte_stream.c b/src/core/lib/transport/byte_stream.c index 79801c4b46..5800c70ef4 100644 --- a/src/core/lib/transport/byte_stream.c +++ b/src/core/lib/transport/byte_stream.c @@ -58,13 +58,13 @@ void grpc_byte_stream_destroy(grpc_exec_ctx *exec_ctx, /* slice_buffer_stream */ -static int slice_buffer_stream_next(grpc_exec_ctx *exec_ctx, - grpc_byte_stream *byte_stream, - size_t max_size_hint, - grpc_closure *on_complete) { +static bool slice_buffer_stream_next(grpc_exec_ctx *exec_ctx, + grpc_byte_stream *byte_stream, + size_t max_size_hint, + grpc_closure *on_complete) { grpc_slice_buffer_stream *stream = (grpc_slice_buffer_stream *)byte_stream; GPR_ASSERT(stream->cursor < stream->backing_buffer->count); - return 1; + return true; } static grpc_error *slice_buffer_stream_pull(grpc_exec_ctx *exec_ctx, diff --git a/src/core/lib/transport/byte_stream.h b/src/core/lib/transport/byte_stream.h index 800e2341f9..381c65fb04 100644 --- a/src/core/lib/transport/byte_stream.h +++ b/src/core/lib/transport/byte_stream.h @@ -49,8 +49,8 @@ typedef struct grpc_byte_stream grpc_byte_stream; struct grpc_byte_stream { uint32_t length; uint32_t flags; - int (*next)(grpc_exec_ctx *exec_ctx, grpc_byte_stream *byte_stream, - size_t max_size_hint, grpc_closure *on_complete); + bool (*next)(grpc_exec_ctx *exec_ctx, grpc_byte_stream *byte_stream, + size_t max_size_hint, grpc_closure *on_complete); grpc_error *(*pull)(grpc_exec_ctx *exec_ctx, grpc_byte_stream *byte_stream, grpc_slice *slice); void (*destroy)(grpc_exec_ctx *exec_ctx, grpc_byte_stream *byte_stream); -- cgit v1.2.3 From 6cc2a993a4f6dac641c7de640876775e22f2aac2 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Mon, 10 Apr 2017 18:30:53 -0700 Subject: Remove redundant assignment --- src/core/ext/transport/chttp2/transport/chttp2_transport.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'src/core/ext/transport') diff --git a/src/core/ext/transport/chttp2/transport/chttp2_transport.c b/src/core/ext/transport/chttp2/transport/chttp2_transport.c index a0bce1e077..1cbd078211 100644 --- a/src/core/ext/transport/chttp2/transport/chttp2_transport.c +++ b/src/core/ext/transport/chttp2/transport/chttp2_transport.c @@ -2626,10 +2626,9 @@ static void incoming_byte_stream_publish_error( grpc_closure_sched(exec_ctx, s->on_next, GRPC_ERROR_REF(error)); s->on_next = NULL; GRPC_ERROR_UNREF(s->byte_stream_error); - s->byte_stream_error = GRPC_ERROR_NONE; + s->byte_stream_error = GRPC_ERROR_REF(error); grpc_chttp2_cancel_stream(exec_ctx, bs->transport, bs->stream, GRPC_ERROR_REF(error)); - s->byte_stream_error = GRPC_ERROR_REF(error); } grpc_error *grpc_chttp2_incoming_byte_stream_push( -- cgit v1.2.3 From 9da7b95c27843136e3ca92ac71b141978344339a Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Mon, 10 Apr 2017 18:33:01 -0700 Subject: int -> bool --- src/core/ext/transport/chttp2/transport/chttp2_transport.c | 2 +- src/core/ext/transport/chttp2/transport/frame_data.c | 8 ++++---- src/core/ext/transport/chttp2/transport/internal.h | 2 +- 3 files changed, 6 insertions(+), 6 deletions(-) (limited to 'src/core/ext/transport') diff --git a/src/core/ext/transport/chttp2/transport/chttp2_transport.c b/src/core/ext/transport/chttp2/transport/chttp2_transport.c index 1cbd078211..4146701af6 100644 --- a/src/core/ext/transport/chttp2/transport/chttp2_transport.c +++ b/src/core/ext/transport/chttp2/transport/chttp2_transport.c @@ -2654,7 +2654,7 @@ grpc_error *grpc_chttp2_incoming_byte_stream_push( grpc_error *grpc_chttp2_incoming_byte_stream_finished( grpc_exec_ctx *exec_ctx, grpc_chttp2_incoming_byte_stream *bs, - grpc_error *error, int reset_on_error) { + grpc_error *error, bool reset_on_error) { grpc_chttp2_stream *s = bs->stream; if (error == GRPC_ERROR_NONE) { diff --git a/src/core/ext/transport/chttp2/transport/frame_data.c b/src/core/ext/transport/chttp2/transport/frame_data.c index d2193cdb32..1f51e0cd6f 100644 --- a/src/core/ext/transport/chttp2/transport/frame_data.c +++ b/src/core/ext/transport/chttp2/transport/frame_data.c @@ -56,7 +56,7 @@ void grpc_chttp2_data_parser_destroy(grpc_exec_ctx *exec_ctx, if (parser->parsing_frame != NULL) { grpc_chttp2_incoming_byte_stream_finished( exec_ctx, parser->parsing_frame, - GRPC_ERROR_CREATE_FROM_STATIC_STRING("Parser destroyed"), 0); + GRPC_ERROR_CREATE_FROM_STATIC_STRING("Parser destroyed"), false); } GRPC_ERROR_UNREF(parser->error); } @@ -214,7 +214,7 @@ grpc_error *deframe_unprocessed_incoming_frames(grpc_exec_ctx *exec_ctx, *stream_out = &p->parsing_frame->base; if (p->parsing_frame->remaining_bytes == 0) { grpc_chttp2_incoming_byte_stream_finished(exec_ctx, p->parsing_frame, - GRPC_ERROR_NONE, 1); + GRPC_ERROR_NONE, true); p->parsing_frame = NULL; p->state = GRPC_CHTTP2_DATA_FH_0; } @@ -245,7 +245,7 @@ grpc_error *deframe_unprocessed_incoming_frames(grpc_exec_ctx *exec_ctx, return error; } grpc_chttp2_incoming_byte_stream_finished(exec_ctx, p->parsing_frame, - GRPC_ERROR_NONE, 1); + GRPC_ERROR_NONE, true); p->parsing_frame = NULL; p->state = GRPC_CHTTP2_DATA_FH_0; grpc_slice_unref_internal(exec_ctx, slice); @@ -273,7 +273,7 @@ grpc_error *deframe_unprocessed_incoming_frames(grpc_exec_ctx *exec_ctx, return error; } grpc_chttp2_incoming_byte_stream_finished(exec_ctx, p->parsing_frame, - GRPC_ERROR_NONE, 1); + GRPC_ERROR_NONE, true); p->parsing_frame = NULL; p->state = GRPC_CHTTP2_DATA_FH_0; cur += p->frame_size; diff --git a/src/core/ext/transport/chttp2/transport/internal.h b/src/core/ext/transport/chttp2/transport/internal.h index 773f541e97..d5767c8d8d 100644 --- a/src/core/ext/transport/chttp2/transport/internal.h +++ b/src/core/ext/transport/chttp2/transport/internal.h @@ -792,7 +792,7 @@ grpc_error *grpc_chttp2_incoming_byte_stream_push( grpc_slice slice, grpc_slice *slice_out); grpc_error *grpc_chttp2_incoming_byte_stream_finished( grpc_exec_ctx *exec_ctx, grpc_chttp2_incoming_byte_stream *bs, - grpc_error *error, int reset_on_error); + grpc_error *error, bool reset_on_error); void grpc_chttp2_incoming_byte_stream_notify( grpc_exec_ctx *exec_ctx, grpc_chttp2_incoming_byte_stream *bs, grpc_error *error); -- cgit v1.2.3 From 2c01070bc3119d1f5e0dce33b72928fb87a55505 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Mon, 10 Apr 2017 19:20:58 -0700 Subject: Work with error refs --- .../transport/chttp2/transport/chttp2_transport.c | 1 - .../ext/transport/chttp2/transport/frame_data.c | 24 ++++++++++++++-------- src/core/lib/surface/call.c | 8 ++++++++ 3 files changed, 24 insertions(+), 9 deletions(-) (limited to 'src/core/ext/transport') diff --git a/src/core/ext/transport/chttp2/transport/chttp2_transport.c b/src/core/ext/transport/chttp2/transport/chttp2_transport.c index 4146701af6..0002253dfe 100644 --- a/src/core/ext/transport/chttp2/transport/chttp2_transport.c +++ b/src/core/ext/transport/chttp2/transport/chttp2_transport.c @@ -2665,7 +2665,6 @@ grpc_error *grpc_chttp2_incoming_byte_stream_finished( if (error != GRPC_ERROR_NONE && reset_on_error) { grpc_closure_sched(exec_ctx, &s->reset_byte_stream, GRPC_ERROR_REF(error)); } - GRPC_ERROR_UNREF(error); incoming_byte_stream_unref(exec_ctx, bs); return error; } diff --git a/src/core/ext/transport/chttp2/transport/frame_data.c b/src/core/ext/transport/chttp2/transport/frame_data.c index 1f51e0cd6f..5d382d80a8 100644 --- a/src/core/ext/transport/chttp2/transport/frame_data.c +++ b/src/core/ext/transport/chttp2/transport/frame_data.c @@ -54,9 +54,9 @@ grpc_error *grpc_chttp2_data_parser_init(grpc_chttp2_data_parser *parser) { void grpc_chttp2_data_parser_destroy(grpc_exec_ctx *exec_ctx, grpc_chttp2_data_parser *parser) { if (parser->parsing_frame != NULL) { - grpc_chttp2_incoming_byte_stream_finished( + GRPC_ERROR_UNREF(grpc_chttp2_incoming_byte_stream_finished( exec_ctx, parser->parsing_frame, - GRPC_ERROR_CREATE_FROM_STATIC_STRING("Parser destroyed"), false); + GRPC_ERROR_CREATE_FROM_STATIC_STRING("Parser destroyed"), false)); } GRPC_ERROR_UNREF(parser->error); } @@ -213,8 +213,8 @@ grpc_error *deframe_unprocessed_incoming_frames(grpc_exec_ctx *exec_ctx, exec_ctx, t, s, p->frame_size, message_flags); *stream_out = &p->parsing_frame->base; if (p->parsing_frame->remaining_bytes == 0) { - grpc_chttp2_incoming_byte_stream_finished(exec_ctx, p->parsing_frame, - GRPC_ERROR_NONE, true); + GRPC_ERROR_UNREF(grpc_chttp2_incoming_byte_stream_finished( + exec_ctx, p->parsing_frame, GRPC_ERROR_NONE, true)); p->parsing_frame = NULL; p->state = GRPC_CHTTP2_DATA_FH_0; } @@ -244,8 +244,12 @@ grpc_error *deframe_unprocessed_incoming_frames(grpc_exec_ctx *exec_ctx, grpc_slice_unref_internal(exec_ctx, slice); return error; } - grpc_chttp2_incoming_byte_stream_finished(exec_ctx, p->parsing_frame, - GRPC_ERROR_NONE, true); + if (GRPC_ERROR_NONE != + (error = grpc_chttp2_incoming_byte_stream_finished( + exec_ctx, p->parsing_frame, GRPC_ERROR_NONE, true))) { + grpc_slice_unref_internal(exec_ctx, slice); + return error; + } p->parsing_frame = NULL; p->state = GRPC_CHTTP2_DATA_FH_0; grpc_slice_unref_internal(exec_ctx, slice); @@ -272,8 +276,12 @@ grpc_error *deframe_unprocessed_incoming_frames(grpc_exec_ctx *exec_ctx, grpc_slice_unref_internal(exec_ctx, slice); return error; } - grpc_chttp2_incoming_byte_stream_finished(exec_ctx, p->parsing_frame, - GRPC_ERROR_NONE, true); + if (GRPC_ERROR_NONE != + (error = grpc_chttp2_incoming_byte_stream_finished( + exec_ctx, p->parsing_frame, GRPC_ERROR_NONE, true))) { + grpc_slice_unref_internal(exec_ctx, slice); + return error; + } p->parsing_frame = NULL; p->state = GRPC_CHTTP2_DATA_FH_0; cur += p->frame_size; diff --git a/src/core/lib/surface/call.c b/src/core/lib/surface/call.c index b1cb7f7fb1..3e96d09798 100644 --- a/src/core/lib/surface/call.c +++ b/src/core/lib/surface/call.c @@ -1226,6 +1226,7 @@ static void receiving_slice_ready(grpc_exec_ctx *exec_ctx, void *bctlp, batch_control *bctl = bctlp; grpc_call *call = bctl->call; grpc_byte_stream *bs = call->receiving_stream; + bool release_error = false; if (error == GRPC_ERROR_NONE) { grpc_slice slice; @@ -1234,6 +1235,10 @@ static void receiving_slice_ready(grpc_exec_ctx *exec_ctx, void *bctlp, grpc_slice_buffer_add(&(*call->receiving_buffer)->data.raw.slice_buffer, slice); continue_receiving_slices(exec_ctx, bctl); + } else { + /* Error returned by grpc_byte_stream_pull needs to be released manually + */ + release_error = true; } } @@ -1247,6 +1252,9 @@ static void receiving_slice_ready(grpc_exec_ctx *exec_ctx, void *bctlp, *call->receiving_buffer = NULL; call->receiving_message = 0; finish_batch_step(exec_ctx, bctl); + if (release_error) { + GRPC_ERROR_UNREF(error); + } } } -- cgit v1.2.3 From 9396914c1430e9974e5315065d93eb634302fa06 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Mon, 10 Apr 2017 19:28:34 -0700 Subject: Work with error refs --- src/core/ext/transport/chttp2/transport/chttp2_transport.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/core/ext/transport') diff --git a/src/core/ext/transport/chttp2/transport/chttp2_transport.c b/src/core/ext/transport/chttp2/transport/chttp2_transport.c index 0002253dfe..1e9a460628 100644 --- a/src/core/ext/transport/chttp2/transport/chttp2_transport.c +++ b/src/core/ext/transport/chttp2/transport/chttp2_transport.c @@ -1671,7 +1671,6 @@ void grpc_chttp2_maybe_complete_recv_message(grpc_exec_ctx *exec_ctx, &s->frame_storage); grpc_slice_buffer_reset_and_unref_internal( exec_ctx, &s->unprocessed_incoming_frames_buffer); - GRPC_ERROR_UNREF(error); break; } else if (*s->recv_message != NULL) { break; @@ -1684,6 +1683,7 @@ void grpc_chttp2_maybe_complete_recv_message(grpc_exec_ctx *exec_ctx, *s->recv_message = NULL; null_then_run_closure(exec_ctx, &s->recv_message_ready, GRPC_ERROR_NONE); } + GRPC_ERROR_UNREF(error); } } -- cgit v1.2.3 From 3ce4d9c715274d46fb1ca6e6e99dd29ffb183b8f Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Mon, 10 Apr 2017 19:36:37 -0700 Subject: Remove unused variable --- src/core/ext/transport/chttp2/transport/chttp2_transport.c | 1 - 1 file changed, 1 deletion(-) (limited to 'src/core/ext/transport') diff --git a/src/core/ext/transport/chttp2/transport/chttp2_transport.c b/src/core/ext/transport/chttp2/transport/chttp2_transport.c index 1e9a460628..54c0252fb9 100644 --- a/src/core/ext/transport/chttp2/transport/chttp2_transport.c +++ b/src/core/ext/transport/chttp2/transport/chttp2_transport.c @@ -2683,7 +2683,6 @@ grpc_chttp2_incoming_byte_stream *grpc_chttp2_incoming_byte_stream_create( gpr_ref_init(&incoming_byte_stream->refs, 2); incoming_byte_stream->transport = t; incoming_byte_stream->stream = s; - incoming_byte_stream->is_tail = 1; s->byte_stream_error = GRPC_ERROR_NONE; return incoming_byte_stream; } -- cgit v1.2.3 From 62f91a43cd7a7d518807c553be4dc6145fb842ae Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Mon, 10 Apr 2017 19:37:19 -0700 Subject: Update comments on variables thread safety --- src/core/ext/transport/chttp2/transport/internal.h | 25 ++++++++++++++++------ 1 file changed, 18 insertions(+), 7 deletions(-) (limited to 'src/core/ext/transport') diff --git a/src/core/ext/transport/chttp2/transport/internal.h b/src/core/ext/transport/chttp2/transport/internal.h index d5767c8d8d..cc904178cf 100644 --- a/src/core/ext/transport/chttp2/transport/internal.h +++ b/src/core/ext/transport/chttp2/transport/internal.h @@ -198,15 +198,20 @@ struct grpc_chttp2_incoming_byte_stream { grpc_chttp2_transport *transport; /* immutable */ grpc_chttp2_stream *stream; /* immutable */ - bool is_tail; /* immutable */ - uint32_t remaining_bytes; /* guaranteed one thread access */ + /* Accessed only by transport thread when stream->pending_byte_stream == false + * Accessed only by application thread when stream->pending_byte_stream == + * true */ + uint32_t remaining_bytes; + /* Accessed only by transport thread when stream->pending_byte_stream == false + * Accessed only by application thread when stream->pending_byte_stream == + * true */ struct { grpc_closure closure; size_t max_size_hint; grpc_closure *on_complete; - } next_action; /* guaranteed one thread access */ + } next_action; grpc_closure destroy_action; grpc_closure finished_action; }; @@ -490,13 +495,16 @@ struct grpc_chttp2_stream { grpc_chttp2_incoming_metadata_buffer metadata_buffer[2]; grpc_slice_buffer frame_storage; /* protected by t combiner */ - grpc_slice_buffer - unprocessed_incoming_frames_buffer; /* guaranteed one thread access */ + + /* Accessed only by transport thread when stream->pending_byte_stream == false + * Accessed only by application thread when stream->pending_byte_stream == + * true */ + grpc_slice_buffer unprocessed_incoming_frames_buffer; grpc_closure *on_next; /* protected by t combiner */ bool pending_byte_stream; /* protected by t combiner */ grpc_closure reset_byte_stream; grpc_error *byte_stream_error; /* protected by t combiner */ - bool received_last_frame; /* proected by t combiner */ + bool received_last_frame; /* protected by t combiner */ gpr_timespec deadline; @@ -509,7 +517,10 @@ struct grpc_chttp2_stream { * incoming_window = incoming_window_delta + transport.initial_window_size */ int64_t incoming_window_delta; /** parsing state for data frames */ - grpc_chttp2_data_parser data_parser; /* guaranteed one thread access */ + /* Accessed only by transport thread when stream->pending_byte_stream == false + * Accessed only by application thread when stream->pending_byte_stream == + * true */ + grpc_chttp2_data_parser data_parser; /** number of bytes received - reset at end of parse thread execution */ int64_t received_bytes; -- cgit v1.2.3 From a002b2413dac2b8c4304349d549c7f30a9f4aff0 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Tue, 11 Apr 2017 09:19:42 -0700 Subject: clang-format --- src/core/ext/transport/chttp2/transport/internal.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/core/ext/transport') diff --git a/src/core/ext/transport/chttp2/transport/internal.h b/src/core/ext/transport/chttp2/transport/internal.h index cc904178cf..a10e3886ea 100644 --- a/src/core/ext/transport/chttp2/transport/internal.h +++ b/src/core/ext/transport/chttp2/transport/internal.h @@ -500,8 +500,8 @@ struct grpc_chttp2_stream { * Accessed only by application thread when stream->pending_byte_stream == * true */ grpc_slice_buffer unprocessed_incoming_frames_buffer; - grpc_closure *on_next; /* protected by t combiner */ - bool pending_byte_stream; /* protected by t combiner */ + grpc_closure *on_next; /* protected by t combiner */ + bool pending_byte_stream; /* protected by t combiner */ grpc_closure reset_byte_stream; grpc_error *byte_stream_error; /* protected by t combiner */ bool received_last_frame; /* protected by t combiner */ -- cgit v1.2.3 From 3e1f562a2b5f33ce781485fa90f92c0406718876 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Tue, 11 Apr 2017 14:05:28 -0700 Subject: clang-format --- src/core/ext/transport/cronet/transport/cronet_transport.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'src/core/ext/transport') diff --git a/src/core/ext/transport/cronet/transport/cronet_transport.c b/src/core/ext/transport/cronet/transport/cronet_transport.c index 3ca6b2fdf6..88335ecd0b 100644 --- a/src/core/ext/transport/cronet/transport/cronet_transport.c +++ b/src/core/ext/transport/cronet/transport/cronet_transport.c @@ -1124,7 +1124,8 @@ static enum e_op_result execute_stream_op(grpc_exec_ctx *exec_ctx, if (stream_state->rs.compressed) { stream_state->rs.sbs.base.flags |= GRPC_WRITE_INTERNAL_COMPRESS; } - *((grpc_byte_buffer **)stream_op->payload->recv_message.recv_message) = + *((grpc_byte_buffer **) + stream_op->payload->recv_message.recv_message) = (grpc_byte_buffer *)&stream_state->rs.sbs; grpc_closure_sched( exec_ctx, stream_op->payload->recv_message.recv_message_ready, -- cgit v1.2.3 From 12d716c88ce3b4f81d1d4c7a8fdbcddf65134b62 Mon Sep 17 00:00:00 2001 From: Craig Tiller Date: Wed, 12 Apr 2017 09:00:41 -0700 Subject: add nl --- src/core/ext/transport/chttp2/transport/http2_settings.c | 1 + tools/codegen/core/gen_settings_ids.py | 6 ++++-- 2 files changed, 5 insertions(+), 2 deletions(-) (limited to 'src/core/ext/transport') diff --git a/src/core/ext/transport/chttp2/transport/http2_settings.c b/src/core/ext/transport/chttp2/transport/http2_settings.c index bca3834b55..d4905107ef 100644 --- a/src/core/ext/transport/chttp2/transport/http2_settings.c +++ b/src/core/ext/transport/chttp2/transport/http2_settings.c @@ -54,6 +54,7 @@ bool grpc_wire_id_to_setting_id(uint32_t wire_id, grpc_chttp2_setting_id *out) { return h < GPR_ARRAY_SIZE(grpc_setting_id_to_wire_id) && grpc_setting_id_to_wire_id[h] == wire_id; } + const grpc_chttp2_setting_parameters grpc_chttp2_settings_parameters[GRPC_CHTTP2_NUM_SETTINGS] = { {"HEADER_TABLE_SIZE", 4096u, 0u, 4294967295u, diff --git a/tools/codegen/core/gen_settings_ids.py b/tools/codegen/core/gen_settings_ids.py index 29c67956c7..a986138337 100755 --- a/tools/codegen/core/gen_settings_ids.py +++ b/tools/codegen/core/gen_settings_ids.py @@ -140,7 +140,8 @@ print >>C, """ } *out = (grpc_chttp2_setting_id)h; return h < GPR_ARRAY_SIZE(grpc_setting_id_to_wire_id) && grpc_setting_id_to_wire_id[h] == wire_id; -}""" % cgargs +} +""" % cgargs print >>H, """ typedef enum { @@ -156,8 +157,9 @@ typedef struct { grpc_chttp2_invalid_value_behavior invalid_value_behavior; uint32_t error_value; } grpc_chttp2_setting_parameters; + +extern const grpc_chttp2_setting_parameters grpc_chttp2_settings_parameters[GRPC_CHTTP2_NUM_SETTINGS]; """ -print >>H, "extern const grpc_chttp2_setting_parameters grpc_chttp2_settings_parameters[GRPC_CHTTP2_NUM_SETTINGS];" print >>C, "const grpc_chttp2_setting_parameters grpc_chttp2_settings_parameters[GRPC_CHTTP2_NUM_SETTINGS] = {" i = 0 for decorated_setting in sorted(decorated_settings): -- cgit v1.2.3 From c71e6a6ad689c10df0981fa43ab7d3e6776dcb08 Mon Sep 17 00:00:00 2001 From: Craig Tiller Date: Wed, 12 Apr 2017 15:49:39 -0700 Subject: Revert "Implement lazy deframe" --- .../transport/chttp2/transport/chttp2_transport.c | 338 +++++++------------ .../ext/transport/chttp2/transport/frame_data.c | 365 +++++++++------------ .../ext/transport/chttp2/transport/frame_data.h | 24 +- src/core/ext/transport/chttp2/transport/internal.h | 51 ++- src/core/ext/transport/chttp2/transport/parsing.c | 5 +- .../transport/cronet/transport/cronet_transport.c | 17 +- src/core/lib/channel/compress_filter.c | 14 +- src/core/lib/channel/http_client_filter.c | 14 +- src/core/lib/surface/call.c | 44 +-- src/core/lib/transport/byte_stream.c | 32 +- src/core/lib/transport/byte_stream.h | 21 +- test/cpp/microbenchmarks/bm_chttp2_transport.cc | 9 +- 12 files changed, 350 insertions(+), 584 deletions(-) (limited to 'src/core/ext/transport') diff --git a/src/core/ext/transport/chttp2/transport/chttp2_transport.c b/src/core/ext/transport/chttp2/transport/chttp2_transport.c index 29ed4bf90e..a7d047d6e7 100644 --- a/src/core/ext/transport/chttp2/transport/chttp2_transport.c +++ b/src/core/ext/transport/chttp2/transport/chttp2_transport.c @@ -44,7 +44,6 @@ #include #include -#include "src/core/ext/transport/chttp2/transport/frame_data.h" #include "src/core/ext/transport/chttp2/transport/internal.h" #include "src/core/ext/transport/chttp2/transport/varint.h" #include "src/core/lib/channel/channel_args.h" @@ -130,11 +129,6 @@ static void incoming_byte_stream_update_flow_control(grpc_exec_ctx *exec_ctx, static void incoming_byte_stream_destroy_locked(grpc_exec_ctx *exec_ctx, void *byte_stream, grpc_error *error_ignored); -static void incoming_byte_stream_publish_error( - grpc_exec_ctx *exec_ctx, grpc_chttp2_incoming_byte_stream *bs, - grpc_error *error); -static void incoming_byte_stream_unref(grpc_exec_ctx *exec_ctx, - grpc_chttp2_incoming_byte_stream *bs); static void benign_reclaimer_locked(grpc_exec_ctx *exec_ctx, void *t, grpc_error *error); @@ -180,9 +174,6 @@ static void finish_keepalive_ping_locked(grpc_exec_ctx *exec_ctx, void *arg, static void keepalive_watchdog_fired_locked(grpc_exec_ctx *exec_ctx, void *arg, grpc_error *error); -static void reset_byte_stream(grpc_exec_ctx *exec_ctx, void *arg, - grpc_error *error); - /******************************************************************************* * CONSTRUCTION/DESTRUCTION/REFCOUNTING */ @@ -664,6 +655,7 @@ static int init_stream(grpc_exec_ctx *exec_ctx, grpc_transport *gt, /* We reserve one 'active stream' that's dropped when the stream is read-closed. The others are for incoming_byte_streams that are actively reading */ + gpr_ref_init(&s->active_streams, 1); GRPC_CHTTP2_STREAM_REF(s, "chttp2"); grpc_chttp2_incoming_metadata_buffer_init(&s->metadata_buffer[0], arena); @@ -673,11 +665,6 @@ static int init_stream(grpc_exec_ctx *exec_ctx, grpc_transport *gt, s->deadline = gpr_inf_future(GPR_CLOCK_MONOTONIC); grpc_closure_init(&s->complete_fetch_locked, complete_fetch_locked, s, grpc_schedule_on_exec_ctx); - grpc_slice_buffer_init(&s->unprocessed_incoming_frames_buffer); - grpc_slice_buffer_init(&s->frame_storage); - s->pending_byte_stream = false; - grpc_closure_init(&s->reset_byte_stream, reset_byte_stream, s, - grpc_combiner_scheduler(t->combiner, false)); GRPC_CHTTP2_REF_TRANSPORT(t, "stream"); @@ -695,6 +682,7 @@ static int init_stream(grpc_exec_ctx *exec_ctx, grpc_transport *gt, static void destroy_stream_locked(grpc_exec_ctx *exec_ctx, void *sp, grpc_error *error) { + grpc_byte_stream *bs; grpc_chttp2_stream *s = sp; grpc_chttp2_transport *t = s->t; @@ -705,9 +693,9 @@ static void destroy_stream_locked(grpc_exec_ctx *exec_ctx, void *sp, GPR_ASSERT(grpc_chttp2_stream_map_find(&t->stream_map, s->id) == NULL); } - grpc_slice_buffer_destroy_internal(exec_ctx, - &s->unprocessed_incoming_frames_buffer); - grpc_slice_buffer_destroy_internal(exec_ctx, &s->frame_storage); + while ((bs = grpc_chttp2_incoming_frame_queue_pop(&s->incoming_frames))) { + incoming_byte_stream_destroy_locked(exec_ctx, bs, GRPC_ERROR_NONE); + } grpc_chttp2_list_remove_stalled_by_transport(t, s); grpc_chttp2_list_remove_stalled_by_stream(t, s); @@ -734,7 +722,6 @@ static void destroy_stream_locked(grpc_exec_ctx *exec_ctx, void *sp, grpc_slice_buffer_destroy_internal(exec_ctx, &s->flow_controlled_buffer); GRPC_ERROR_UNREF(s->read_closed_error); GRPC_ERROR_UNREF(s->write_closed_error); - GRPC_ERROR_UNREF(s->byte_stream_error); if (s->incoming_window_delta > 0) { GRPC_CHTTP2_FLOW_DEBIT_STREAM_INCOMING_WINDOW_DELTA( @@ -1188,9 +1175,8 @@ static void continue_fetching_send_locked(grpc_exec_ctx *exec_ctx, s->fetching_send_message = NULL; return; /* early out */ } else if (grpc_byte_stream_next(exec_ctx, s->fetching_send_message, - UINT32_MAX, &s->complete_fetch_locked)) { - grpc_byte_stream_pull(exec_ctx, s->fetching_send_message, - &s->fetching_slice); + &s->fetching_slice, UINT32_MAX, + &s->complete_fetch_locked)) { add_fetched_slice_locked(exec_ctx, t, s); } } @@ -1201,15 +1187,9 @@ static void complete_fetch_locked(grpc_exec_ctx *exec_ctx, void *gs, grpc_chttp2_stream *s = gs; grpc_chttp2_transport *t = s->t; if (error == GRPC_ERROR_NONE) { - error = grpc_byte_stream_pull(exec_ctx, s->fetching_send_message, - &s->fetching_slice); - if (error == GRPC_ERROR_NONE) { - add_fetched_slice_locked(exec_ctx, t, s); - continue_fetching_send_locked(exec_ctx, t, s); - } - } - - if (error != GRPC_ERROR_NONE) { + add_fetched_slice_locked(exec_ctx, t, s); + continue_fetching_send_locked(exec_ctx, t, s); + } else { /* TODO(ctiller): what to do here */ abort(); } @@ -1444,7 +1424,8 @@ static void perform_stream_op_locked(grpc_exec_ctx *exec_ctx, void *stream_op, GPR_ASSERT(s->recv_message_ready == NULL); s->recv_message_ready = op_payload->recv_message.recv_message_ready; s->recv_message = op_payload->recv_message.recv_message; - if (s->id != 0 && s->frame_storage.length == 0) { + if (s->id != 0 && + (s->incoming_frames.head == NULL || s->incoming_frames.head->is_tail)) { incoming_byte_stream_update_flow_control(exec_ctx, t, s, 5, 0); } grpc_chttp2_maybe_complete_recv_message(exec_ctx, t, s); @@ -1633,13 +1614,13 @@ static void perform_transport_op(grpc_exec_ctx *exec_ctx, grpc_transport *gt, void grpc_chttp2_maybe_complete_recv_initial_metadata(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t, grpc_chttp2_stream *s) { + grpc_byte_stream *bs; if (s->recv_initial_metadata_ready != NULL && s->published_metadata[0] != GRPC_METADATA_NOT_PUBLISHED) { if (s->seen_error) { - grpc_slice_buffer_reset_and_unref_internal(exec_ctx, &s->frame_storage); - if (!s->pending_byte_stream) { - grpc_slice_buffer_reset_and_unref_internal( - exec_ctx, &s->unprocessed_incoming_frames_buffer); + while ((bs = grpc_chttp2_incoming_frame_queue_pop(&s->incoming_frames)) != + NULL) { + incoming_byte_stream_destroy_locked(exec_ctx, bs, GRPC_ERROR_NONE); } } grpc_chttp2_incoming_metadata_buffer_publish( @@ -1652,65 +1633,39 @@ void grpc_chttp2_maybe_complete_recv_initial_metadata(grpc_exec_ctx *exec_ctx, void grpc_chttp2_maybe_complete_recv_message(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t, grpc_chttp2_stream *s) { - grpc_error *error = GRPC_ERROR_NONE; + grpc_byte_stream *bs; if (s->recv_message_ready != NULL) { - *s->recv_message = NULL; - if (s->final_metadata_requested && s->seen_error) { - grpc_slice_buffer_reset_and_unref_internal(exec_ctx, &s->frame_storage); - if (!s->pending_byte_stream) { - grpc_slice_buffer_reset_and_unref_internal( - exec_ctx, &s->unprocessed_incoming_frames_buffer); - } + while (s->final_metadata_requested && s->seen_error && + (bs = grpc_chttp2_incoming_frame_queue_pop(&s->incoming_frames)) != + NULL) { + incoming_byte_stream_destroy_locked(exec_ctx, bs, GRPC_ERROR_NONE); } - if (!s->pending_byte_stream) { - while (s->unprocessed_incoming_frames_buffer.length > 0 || - s->frame_storage.length > 0) { - if (s->unprocessed_incoming_frames_buffer.length == 0) { - grpc_slice_buffer_swap(&s->unprocessed_incoming_frames_buffer, - &s->frame_storage); - } - error = deframe_unprocessed_incoming_frames( - exec_ctx, &s->data_parser, s, - &s->unprocessed_incoming_frames_buffer, NULL, s->recv_message); - if (error != GRPC_ERROR_NONE) { - s->seen_error = true; - grpc_slice_buffer_reset_and_unref_internal(exec_ctx, - &s->frame_storage); - grpc_slice_buffer_reset_and_unref_internal( - exec_ctx, &s->unprocessed_incoming_frames_buffer); - break; - } else if (*s->recv_message != NULL) { - break; - } - } - } - if (error == GRPC_ERROR_NONE && *s->recv_message != NULL) { + if (s->incoming_frames.head != NULL) { + *s->recv_message = + grpc_chttp2_incoming_frame_queue_pop(&s->incoming_frames); + GPR_ASSERT(*s->recv_message != NULL); null_then_run_closure(exec_ctx, &s->recv_message_ready, GRPC_ERROR_NONE); } else if (s->published_metadata[1] != GRPC_METADATA_NOT_PUBLISHED) { *s->recv_message = NULL; null_then_run_closure(exec_ctx, &s->recv_message_ready, GRPC_ERROR_NONE); } - GRPC_ERROR_UNREF(error); } } void grpc_chttp2_maybe_complete_recv_trailing_metadata(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t, grpc_chttp2_stream *s) { + grpc_byte_stream *bs; grpc_chttp2_maybe_complete_recv_message(exec_ctx, t, s); if (s->recv_trailing_metadata_finished != NULL && s->read_closed && s->write_closed) { if (s->seen_error) { - grpc_slice_buffer_reset_and_unref_internal(exec_ctx, &s->frame_storage); - if (!s->pending_byte_stream) { - grpc_slice_buffer_reset_and_unref_internal( - exec_ctx, &s->unprocessed_incoming_frames_buffer); + while ((bs = grpc_chttp2_incoming_frame_queue_pop(&s->incoming_frames)) != + NULL) { + incoming_byte_stream_destroy_locked(exec_ctx, bs, GRPC_ERROR_NONE); } } - bool pending_data = s->pending_byte_stream || - s->unprocessed_incoming_frames_buffer.length > 0; - if (s->read_closed && s->frame_storage.length == 0 && - (!pending_data || s->seen_error) && + if (s->all_incoming_byte_streams_finished && s->recv_trailing_metadata_finished != NULL) { grpc_chttp2_incoming_metadata_buffer_publish( exec_ctx, &s->metadata_buffer[1], s->recv_trailing_metadata); @@ -1721,6 +1676,14 @@ void grpc_chttp2_maybe_complete_recv_trailing_metadata(grpc_exec_ctx *exec_ctx, } } +static void decrement_active_streams_locked(grpc_exec_ctx *exec_ctx, + grpc_chttp2_transport *t, + grpc_chttp2_stream *s) { + if ((s->all_incoming_byte_streams_finished = gpr_unref(&s->active_streams))) { + grpc_chttp2_maybe_complete_recv_trailing_metadata(exec_ctx, t, s); + } +} + static void remove_stream(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t, uint32_t id, grpc_error *error) { grpc_chttp2_stream *s = grpc_chttp2_stream_map_delete(&t->stream_map, id); @@ -1729,19 +1692,10 @@ static void remove_stream(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t, t->incoming_stream = NULL; grpc_chttp2_parsing_become_skip_parser(exec_ctx, t); } - if (s->pending_byte_stream) { - if (s->on_next != NULL) { - grpc_chttp2_incoming_byte_stream *bs = s->data_parser.parsing_frame; - if (error == GRPC_ERROR_NONE) { - error = GRPC_ERROR_CREATE_FROM_STATIC_STRING("Truncated message"); - } - incoming_byte_stream_publish_error(exec_ctx, bs, error); - incoming_byte_stream_unref(exec_ctx, bs); - s->data_parser.parsing_frame = NULL; - } else { - GRPC_ERROR_UNREF(s->byte_stream_error); - s->byte_stream_error = GRPC_ERROR_REF(error); - } + if (s->data_parser.parsing_frame != NULL) { + grpc_chttp2_incoming_byte_stream_finished( + exec_ctx, s->data_parser.parsing_frame, GRPC_ERROR_REF(error)); + s->data_parser.parsing_frame = NULL; } if (grpc_chttp2_stream_map_size(&t->stream_map) == 0) { @@ -1927,6 +1881,7 @@ void grpc_chttp2_mark_stream_closed(grpc_exec_ctx *exec_ctx, s->published_metadata[i] = GPRC_METADATA_PUBLISHED_AT_CLOSE; } } + decrement_active_streams_locked(exec_ctx, t, s); grpc_chttp2_maybe_complete_recv_initial_metadata(exec_ctx, t, s); grpc_chttp2_maybe_complete_recv_message(exec_ctx, t, s); } @@ -2464,28 +2419,12 @@ static void set_pollset_set(grpc_exec_ctx *exec_ctx, grpc_transport *gt, * BYTE STREAM */ -static void reset_byte_stream(grpc_exec_ctx *exec_ctx, void *arg, - grpc_error *error) { - grpc_chttp2_stream *s = (grpc_chttp2_stream *)arg; - - s->pending_byte_stream = false; - if (error == GRPC_ERROR_NONE) { - grpc_chttp2_maybe_complete_recv_message(exec_ctx, s->t, s); - grpc_chttp2_maybe_complete_recv_trailing_metadata(exec_ctx, s->t, s); - } else { - GPR_ASSERT(error != GRPC_ERROR_NONE); - grpc_closure_sched(exec_ctx, s->on_next, GRPC_ERROR_REF(error)); - s->on_next = NULL; - GRPC_ERROR_UNREF(s->byte_stream_error); - s->byte_stream_error = GRPC_ERROR_NONE; - grpc_chttp2_cancel_stream(exec_ctx, s->t, s, GRPC_ERROR_REF(error)); - s->byte_stream_error = error; - } -} - static void incoming_byte_stream_unref(grpc_exec_ctx *exec_ctx, grpc_chttp2_incoming_byte_stream *bs) { if (gpr_unref(&bs->refs)) { + GRPC_ERROR_UNREF(bs->error); + grpc_slice_buffer_destroy_internal(exec_ctx, &bs->slices); + gpr_mu_destroy(&bs->slice_mu); gpr_free(bs); } } @@ -2545,90 +2484,47 @@ static void incoming_byte_stream_next_locked(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t = bs->transport; grpc_chttp2_stream *s = bs->stream; - size_t cur_length = s->frame_storage.length; - incoming_byte_stream_update_flow_control( - exec_ctx, t, s, bs->next_action.max_size_hint, cur_length); - - GPR_ASSERT(s->unprocessed_incoming_frames_buffer.length == 0); - if (s->frame_storage.length > 0) { - grpc_slice_buffer_swap(&s->frame_storage, - &s->unprocessed_incoming_frames_buffer); - grpc_closure_sched(exec_ctx, bs->next_action.on_complete, GRPC_ERROR_NONE); - } else if (s->byte_stream_error != GRPC_ERROR_NONE) { - grpc_closure_sched(exec_ctx, bs->next_action.on_complete, - GRPC_ERROR_REF(s->byte_stream_error)); - if (s->data_parser.parsing_frame != NULL) { - incoming_byte_stream_unref(exec_ctx, s->data_parser.parsing_frame); - s->data_parser.parsing_frame = NULL; - } - } else if (s->read_closed) { - if (bs->remaining_bytes != 0) { - s->byte_stream_error = - GRPC_ERROR_CREATE_FROM_STATIC_STRING("Truncated message"); - grpc_closure_sched(exec_ctx, bs->next_action.on_complete, - GRPC_ERROR_REF(s->byte_stream_error)); - if (s->data_parser.parsing_frame != NULL) { - incoming_byte_stream_unref(exec_ctx, s->data_parser.parsing_frame); - s->data_parser.parsing_frame = NULL; - } - } else { - /* Should never reach here. */ - GPR_ASSERT(false); - } + if (bs->is_tail) { + gpr_mu_lock(&bs->slice_mu); + size_t cur_length = bs->slices.length; + gpr_mu_unlock(&bs->slice_mu); + incoming_byte_stream_update_flow_control( + exec_ctx, t, s, bs->next_action.max_size_hint, cur_length); + } + gpr_mu_lock(&bs->slice_mu); + if (bs->slices.count > 0) { + *bs->next_action.slice = grpc_slice_buffer_take_first(&bs->slices); + grpc_closure_run(exec_ctx, bs->next_action.on_complete, GRPC_ERROR_NONE); + } else if (bs->error != GRPC_ERROR_NONE) { + grpc_closure_run(exec_ctx, bs->next_action.on_complete, + GRPC_ERROR_REF(bs->error)); } else { - s->on_next = bs->next_action.on_complete; + bs->on_next = bs->next_action.on_complete; + bs->next = bs->next_action.slice; } + gpr_mu_unlock(&bs->slice_mu); incoming_byte_stream_unref(exec_ctx, bs); } -static bool incoming_byte_stream_next(grpc_exec_ctx *exec_ctx, - grpc_byte_stream *byte_stream, - size_t max_size_hint, - grpc_closure *on_complete) { +static int incoming_byte_stream_next(grpc_exec_ctx *exec_ctx, + grpc_byte_stream *byte_stream, + grpc_slice *slice, size_t max_size_hint, + grpc_closure *on_complete) { GPR_TIMER_BEGIN("incoming_byte_stream_next", 0); grpc_chttp2_incoming_byte_stream *bs = (grpc_chttp2_incoming_byte_stream *)byte_stream; - grpc_chttp2_stream *s = bs->stream; - if (s->unprocessed_incoming_frames_buffer.length > 0) { - return true; - } else { - gpr_ref(&bs->refs); - bs->next_action.max_size_hint = max_size_hint; - bs->next_action.on_complete = on_complete; - grpc_closure_sched( - exec_ctx, - grpc_closure_init( - &bs->next_action.closure, incoming_byte_stream_next_locked, bs, - grpc_combiner_scheduler(bs->transport->combiner, false)), - GRPC_ERROR_NONE); - GPR_TIMER_END("incoming_byte_stream_next", 0); - return false; - } -} - -static grpc_error *incoming_byte_stream_pull(grpc_exec_ctx *exec_ctx, - grpc_byte_stream *byte_stream, - grpc_slice *slice) { - GPR_TIMER_BEGIN("incoming_byte_stream_pull", 0); - grpc_chttp2_incoming_byte_stream *bs = - (grpc_chttp2_incoming_byte_stream *)byte_stream; - grpc_chttp2_stream *s = bs->stream; - - if (s->unprocessed_incoming_frames_buffer.length > 0) { - grpc_error *error = deframe_unprocessed_incoming_frames( - exec_ctx, &s->data_parser, s, &s->unprocessed_incoming_frames_buffer, - slice, NULL); - if (error != GRPC_ERROR_NONE) { - return error; - } - } else { - grpc_error *error = - GRPC_ERROR_CREATE_FROM_STATIC_STRING("Truncated message"); - grpc_closure_sched(exec_ctx, &s->reset_byte_stream, GRPC_ERROR_REF(error)); - return error; - } - GPR_TIMER_END("incoming_byte_stream_pull", 0); - return GRPC_ERROR_NONE; + gpr_ref(&bs->refs); + bs->next_action.slice = slice; + bs->next_action.max_size_hint = max_size_hint; + bs->next_action.on_complete = on_complete; + grpc_closure_sched( + exec_ctx, + grpc_closure_init( + &bs->next_action.closure, incoming_byte_stream_next_locked, bs, + grpc_combiner_scheduler(bs->transport->combiner, false)), + GRPC_ERROR_NONE); + GPR_TIMER_END("incoming_byte_stream_next", 0); + return 0; } static void incoming_byte_stream_destroy(grpc_exec_ctx *exec_ctx, @@ -2638,14 +2534,9 @@ static void incoming_byte_stream_destroy_locked(grpc_exec_ctx *exec_ctx, void *byte_stream, grpc_error *error_ignored) { grpc_chttp2_incoming_byte_stream *bs = byte_stream; - grpc_chttp2_stream *s = bs->stream; - grpc_chttp2_transport *t = s->t; - GPR_ASSERT(bs->base.destroy == incoming_byte_stream_destroy); + decrement_active_streams_locked(exec_ctx, bs->transport, bs->stream); incoming_byte_stream_unref(exec_ctx, bs); - s->pending_byte_stream = false; - grpc_chttp2_maybe_complete_recv_message(exec_ctx, t, s); - grpc_chttp2_maybe_complete_recv_trailing_metadata(exec_ctx, t, s); } static void incoming_byte_stream_destroy(grpc_exec_ctx *exec_ctx, @@ -2665,53 +2556,50 @@ static void incoming_byte_stream_destroy(grpc_exec_ctx *exec_ctx, static void incoming_byte_stream_publish_error( grpc_exec_ctx *exec_ctx, grpc_chttp2_incoming_byte_stream *bs, grpc_error *error) { - grpc_chttp2_stream *s = bs->stream; - GPR_ASSERT(error != GRPC_ERROR_NONE); - grpc_closure_sched(exec_ctx, s->on_next, GRPC_ERROR_REF(error)); - s->on_next = NULL; - GRPC_ERROR_UNREF(s->byte_stream_error); - s->byte_stream_error = GRPC_ERROR_REF(error); + grpc_closure_sched(exec_ctx, bs->on_next, GRPC_ERROR_REF(error)); + bs->on_next = NULL; + GRPC_ERROR_UNREF(bs->error); grpc_chttp2_cancel_stream(exec_ctx, bs->transport, bs->stream, GRPC_ERROR_REF(error)); + bs->error = error; } -grpc_error *grpc_chttp2_incoming_byte_stream_push( - grpc_exec_ctx *exec_ctx, grpc_chttp2_incoming_byte_stream *bs, - grpc_slice slice, grpc_slice *slice_out) { - grpc_chttp2_stream *s = bs->stream; - +void grpc_chttp2_incoming_byte_stream_push(grpc_exec_ctx *exec_ctx, + grpc_chttp2_incoming_byte_stream *bs, + grpc_slice slice) { + gpr_mu_lock(&bs->slice_mu); if (bs->remaining_bytes < GRPC_SLICE_LENGTH(slice)) { - grpc_error *error = - GRPC_ERROR_CREATE_FROM_STATIC_STRING("Too many bytes in stream"); - - grpc_closure_sched(exec_ctx, &s->reset_byte_stream, GRPC_ERROR_REF(error)); - grpc_slice_unref_internal(exec_ctx, slice); - return error; + incoming_byte_stream_publish_error( + exec_ctx, bs, + GRPC_ERROR_CREATE_FROM_STATIC_STRING("Too many bytes in stream")); } else { bs->remaining_bytes -= (uint32_t)GRPC_SLICE_LENGTH(slice); - if (slice_out != NULL) { - *slice_out = slice; + if (bs->on_next != NULL) { + *bs->next = slice; + grpc_closure_sched(exec_ctx, bs->on_next, GRPC_ERROR_NONE); + bs->on_next = NULL; + } else { + grpc_slice_buffer_add(&bs->slices, slice); } - return GRPC_ERROR_NONE; } + gpr_mu_unlock(&bs->slice_mu); } -grpc_error *grpc_chttp2_incoming_byte_stream_finished( +void grpc_chttp2_incoming_byte_stream_finished( grpc_exec_ctx *exec_ctx, grpc_chttp2_incoming_byte_stream *bs, - grpc_error *error, bool reset_on_error) { - grpc_chttp2_stream *s = bs->stream; - + grpc_error *error) { if (error == GRPC_ERROR_NONE) { + gpr_mu_lock(&bs->slice_mu); if (bs->remaining_bytes != 0) { error = GRPC_ERROR_CREATE_FROM_STATIC_STRING("Truncated message"); } + gpr_mu_unlock(&bs->slice_mu); } - if (error != GRPC_ERROR_NONE && reset_on_error) { - grpc_closure_sched(exec_ctx, &s->reset_byte_stream, GRPC_ERROR_REF(error)); + if (error != GRPC_ERROR_NONE) { + incoming_byte_stream_publish_error(exec_ctx, bs, error); } incoming_byte_stream_unref(exec_ctx, bs); - return error; } grpc_chttp2_incoming_byte_stream *grpc_chttp2_incoming_byte_stream_create( @@ -2723,12 +2611,26 @@ grpc_chttp2_incoming_byte_stream *grpc_chttp2_incoming_byte_stream_create( incoming_byte_stream->remaining_bytes = frame_size; incoming_byte_stream->base.flags = flags; incoming_byte_stream->base.next = incoming_byte_stream_next; - incoming_byte_stream->base.pull = incoming_byte_stream_pull; incoming_byte_stream->base.destroy = incoming_byte_stream_destroy; + gpr_mu_init(&incoming_byte_stream->slice_mu); gpr_ref_init(&incoming_byte_stream->refs, 2); + incoming_byte_stream->next_message = NULL; incoming_byte_stream->transport = t; incoming_byte_stream->stream = s; - s->byte_stream_error = GRPC_ERROR_NONE; + gpr_ref(&incoming_byte_stream->stream->active_streams); + grpc_slice_buffer_init(&incoming_byte_stream->slices); + incoming_byte_stream->on_next = NULL; + incoming_byte_stream->is_tail = 1; + incoming_byte_stream->error = GRPC_ERROR_NONE; + grpc_chttp2_incoming_frame_queue *q = &s->incoming_frames; + if (q->head == NULL) { + q->head = incoming_byte_stream; + } else { + q->tail->is_tail = 0; + q->tail->next_message = incoming_byte_stream; + } + q->tail = incoming_byte_stream; + grpc_chttp2_maybe_complete_recv_message(exec_ctx, t, s); return incoming_byte_stream; } diff --git a/src/core/ext/transport/chttp2/transport/frame_data.c b/src/core/ext/transport/chttp2/transport/frame_data.c index 5d382d80a8..6e9258ee7e 100644 --- a/src/core/ext/transport/chttp2/transport/frame_data.c +++ b/src/core/ext/transport/chttp2/transport/frame_data.c @@ -40,7 +40,6 @@ #include #include #include "src/core/ext/transport/chttp2/transport/internal.h" -#include "src/core/lib/slice/slice_internal.h" #include "src/core/lib/slice/slice_string_helpers.h" #include "src/core/lib/support/string.h" #include "src/core/lib/transport/transport.h" @@ -54,17 +53,16 @@ grpc_error *grpc_chttp2_data_parser_init(grpc_chttp2_data_parser *parser) { void grpc_chttp2_data_parser_destroy(grpc_exec_ctx *exec_ctx, grpc_chttp2_data_parser *parser) { if (parser->parsing_frame != NULL) { - GRPC_ERROR_UNREF(grpc_chttp2_incoming_byte_stream_finished( + grpc_chttp2_incoming_byte_stream_finished( exec_ctx, parser->parsing_frame, - GRPC_ERROR_CREATE_FROM_STATIC_STRING("Parser destroyed"), false)); + GRPC_ERROR_CREATE_FROM_STATIC_STRING("Parser destroyed")); } GRPC_ERROR_UNREF(parser->error); } grpc_error *grpc_chttp2_data_parser_begin_frame(grpc_chttp2_data_parser *parser, uint8_t flags, - uint32_t stream_id, - grpc_chttp2_stream *s) { + uint32_t stream_id) { if (flags & ~GRPC_CHTTP2_DATA_FLAG_END_STREAM) { char *msg; gpr_asprintf(&msg, "unsupported data flags: 0x%02x", flags); @@ -76,14 +74,47 @@ grpc_error *grpc_chttp2_data_parser_begin_frame(grpc_chttp2_data_parser *parser, } if (flags & GRPC_CHTTP2_DATA_FLAG_END_STREAM) { - s->received_last_frame = true; + parser->is_last_frame = 1; } else { - s->received_last_frame = false; + parser->is_last_frame = 0; } return GRPC_ERROR_NONE; } +void grpc_chttp2_incoming_frame_queue_merge( + grpc_chttp2_incoming_frame_queue *head_dst, + grpc_chttp2_incoming_frame_queue *tail_src) { + if (tail_src->head == NULL) { + return; + } + + if (head_dst->head == NULL) { + *head_dst = *tail_src; + memset(tail_src, 0, sizeof(*tail_src)); + return; + } + + head_dst->tail->next_message = tail_src->head; + head_dst->tail = tail_src->tail; + memset(tail_src, 0, sizeof(*tail_src)); +} + +grpc_byte_stream *grpc_chttp2_incoming_frame_queue_pop( + grpc_chttp2_incoming_frame_queue *q) { + grpc_byte_stream *out; + if (q->head == NULL) { + return NULL; + } + out = &q->head->base; + if (q->head == q->tail) { + memset(q, 0, sizeof(*q)); + } else { + q->head = q->head->next_message; + } + return out; +} + void grpc_chttp2_encode_data(uint32_t id, grpc_slice_buffer *inbuf, uint32_t write_bytes, int is_eof, grpc_transport_one_way_stats *stats, @@ -112,217 +143,145 @@ void grpc_chttp2_encode_data(uint32_t id, grpc_slice_buffer *inbuf, stats->data_bytes += write_bytes; } -grpc_error *deframe_unprocessed_incoming_frames(grpc_exec_ctx *exec_ctx, - grpc_chttp2_data_parser *p, - grpc_chttp2_stream *s, - grpc_slice_buffer *slices, - grpc_slice *slice_out, - grpc_byte_stream **stream_out) { - grpc_error *error = GRPC_ERROR_NONE; - grpc_chttp2_transport *t = s->t; - - while (slices->count > 0) { - uint8_t *beg = NULL; - uint8_t *end = NULL; - uint8_t *cur = NULL; - - grpc_slice slice = grpc_slice_buffer_take_first(slices); +static grpc_error *parse_inner(grpc_exec_ctx *exec_ctx, + grpc_chttp2_data_parser *p, + grpc_chttp2_transport *t, grpc_chttp2_stream *s, + grpc_slice slice) { + uint8_t *const beg = GRPC_SLICE_START_PTR(slice); + uint8_t *const end = GRPC_SLICE_END_PTR(slice); + uint8_t *cur = beg; + uint32_t message_flags; + grpc_chttp2_incoming_byte_stream *incoming_byte_stream; + char *msg; - beg = GRPC_SLICE_START_PTR(slice); - end = GRPC_SLICE_END_PTR(slice); - cur = beg; - uint32_t message_flags; - char *msg; - - if (cur == end) { - grpc_slice_unref_internal(exec_ctx, slice); - continue; - } - - switch (p->state) { - case GRPC_CHTTP2_DATA_ERROR: - p->state = GRPC_CHTTP2_DATA_ERROR; - grpc_slice_unref_internal(exec_ctx, slice); - return GRPC_ERROR_REF(p->error); - case GRPC_CHTTP2_DATA_FH_0: - p->frame_type = *cur; - switch (p->frame_type) { - case 0: - p->is_frame_compressed = false; /* GPR_FALSE */ - break; - case 1: - p->is_frame_compressed = true; /* GPR_TRUE */ - break; - default: - gpr_asprintf(&msg, "Bad GRPC frame type 0x%02x", p->frame_type); - p->error = GRPC_ERROR_CREATE_FROM_COPIED_STRING(msg); - p->error = grpc_error_set_int(p->error, GRPC_ERROR_INT_STREAM_ID, - (intptr_t)s->id); - gpr_free(msg); - msg = grpc_dump_slice(slice, GPR_DUMP_HEX | GPR_DUMP_ASCII); - p->error = grpc_error_set_str(p->error, GRPC_ERROR_STR_RAW_BYTES, - grpc_slice_from_copied_string(msg)); - gpr_free(msg); - p->error = - grpc_error_set_int(p->error, GRPC_ERROR_INT_OFFSET, cur - beg); - p->state = GRPC_CHTTP2_DATA_ERROR; - grpc_slice_unref_internal(exec_ctx, slice); - return GRPC_ERROR_REF(p->error); - } - if (++cur == end) { - p->state = GRPC_CHTTP2_DATA_FH_1; - grpc_slice_unref_internal(exec_ctx, slice); - continue; - } - /* fallthrough */ - case GRPC_CHTTP2_DATA_FH_1: - p->frame_size = ((uint32_t)*cur) << 24; - if (++cur == end) { - p->state = GRPC_CHTTP2_DATA_FH_2; - grpc_slice_unref_internal(exec_ctx, slice); - continue; - } - /* fallthrough */ - case GRPC_CHTTP2_DATA_FH_2: - p->frame_size |= ((uint32_t)*cur) << 16; - if (++cur == end) { - p->state = GRPC_CHTTP2_DATA_FH_3; - grpc_slice_unref_internal(exec_ctx, slice); - continue; - } - /* fallthrough */ - case GRPC_CHTTP2_DATA_FH_3: - p->frame_size |= ((uint32_t)*cur) << 8; - if (++cur == end) { - p->state = GRPC_CHTTP2_DATA_FH_4; - grpc_slice_unref_internal(exec_ctx, slice); - continue; - } - /* fallthrough */ - case GRPC_CHTTP2_DATA_FH_4: - GPR_ASSERT(stream_out != NULL); - GPR_ASSERT(p->parsing_frame == NULL); - p->frame_size |= ((uint32_t)*cur); - p->state = GRPC_CHTTP2_DATA_FRAME; - ++cur; - message_flags = 0; - if (p->is_frame_compressed) { - message_flags |= GRPC_WRITE_INTERNAL_COMPRESS; - } - p->parsing_frame = grpc_chttp2_incoming_byte_stream_create( - exec_ctx, t, s, p->frame_size, message_flags); - *stream_out = &p->parsing_frame->base; - if (p->parsing_frame->remaining_bytes == 0) { - GRPC_ERROR_UNREF(grpc_chttp2_incoming_byte_stream_finished( - exec_ctx, p->parsing_frame, GRPC_ERROR_NONE, true)); - p->parsing_frame = NULL; - p->state = GRPC_CHTTP2_DATA_FH_0; - } - s->pending_byte_stream = true; + if (cur == end) { + return GRPC_ERROR_NONE; + } - if (cur != end) { - grpc_slice_buffer_undo_take_first( - &s->unprocessed_incoming_frames_buffer, - grpc_slice_sub(slice, (size_t)(cur - beg), (size_t)(end - beg))); - } - grpc_slice_unref_internal(exec_ctx, slice); + switch (p->state) { + case GRPC_CHTTP2_DATA_ERROR: + p->state = GRPC_CHTTP2_DATA_ERROR; + return GRPC_ERROR_REF(p->error); + fh_0: + case GRPC_CHTTP2_DATA_FH_0: + s->stats.incoming.framing_bytes++; + p->frame_type = *cur; + switch (p->frame_type) { + case 0: + p->is_frame_compressed = 0; /* GPR_FALSE */ + break; + case 1: + p->is_frame_compressed = 1; /* GPR_TRUE */ + break; + default: + gpr_asprintf(&msg, "Bad GRPC frame type 0x%02x", p->frame_type); + p->error = GRPC_ERROR_CREATE_FROM_COPIED_STRING(msg); + p->error = grpc_error_set_int(p->error, GRPC_ERROR_INT_STREAM_ID, + (intptr_t)s->id); + gpr_free(msg); + msg = grpc_dump_slice(slice, GPR_DUMP_HEX | GPR_DUMP_ASCII); + p->error = grpc_error_set_str(p->error, GRPC_ERROR_STR_RAW_BYTES, + grpc_slice_from_copied_string(msg)); + gpr_free(msg); + p->error = + grpc_error_set_int(p->error, GRPC_ERROR_INT_OFFSET, cur - beg); + p->state = GRPC_CHTTP2_DATA_ERROR; + return GRPC_ERROR_REF(p->error); + } + if (++cur == end) { + p->state = GRPC_CHTTP2_DATA_FH_1; + return GRPC_ERROR_NONE; + } + /* fallthrough */ + case GRPC_CHTTP2_DATA_FH_1: + s->stats.incoming.framing_bytes++; + p->frame_size = ((uint32_t)*cur) << 24; + if (++cur == end) { + p->state = GRPC_CHTTP2_DATA_FH_2; + return GRPC_ERROR_NONE; + } + /* fallthrough */ + case GRPC_CHTTP2_DATA_FH_2: + s->stats.incoming.framing_bytes++; + p->frame_size |= ((uint32_t)*cur) << 16; + if (++cur == end) { + p->state = GRPC_CHTTP2_DATA_FH_3; + return GRPC_ERROR_NONE; + } + /* fallthrough */ + case GRPC_CHTTP2_DATA_FH_3: + s->stats.incoming.framing_bytes++; + p->frame_size |= ((uint32_t)*cur) << 8; + if (++cur == end) { + p->state = GRPC_CHTTP2_DATA_FH_4; + return GRPC_ERROR_NONE; + } + /* fallthrough */ + case GRPC_CHTTP2_DATA_FH_4: + s->stats.incoming.framing_bytes++; + p->frame_size |= ((uint32_t)*cur); + p->state = GRPC_CHTTP2_DATA_FRAME; + ++cur; + message_flags = 0; + if (p->is_frame_compressed) { + message_flags |= GRPC_WRITE_INTERNAL_COMPRESS; + } + p->parsing_frame = incoming_byte_stream = + grpc_chttp2_incoming_byte_stream_create(exec_ctx, t, s, p->frame_size, + message_flags); + /* fallthrough */ + case GRPC_CHTTP2_DATA_FRAME: + if (cur == end) { + return GRPC_ERROR_NONE; + } + uint32_t remaining = (uint32_t)(end - cur); + if (remaining == p->frame_size) { + s->stats.incoming.data_bytes += p->frame_size; + grpc_chttp2_incoming_byte_stream_push( + exec_ctx, p->parsing_frame, + grpc_slice_sub(slice, (size_t)(cur - beg), (size_t)(end - beg))); + grpc_chttp2_incoming_byte_stream_finished(exec_ctx, p->parsing_frame, + GRPC_ERROR_NONE); + p->parsing_frame = NULL; + p->state = GRPC_CHTTP2_DATA_FH_0; + return GRPC_ERROR_NONE; + } else if (remaining > p->frame_size) { + s->stats.incoming.data_bytes += p->frame_size; + grpc_chttp2_incoming_byte_stream_push( + exec_ctx, p->parsing_frame, + grpc_slice_sub(slice, (size_t)(cur - beg), + (size_t)(cur + p->frame_size - beg))); + grpc_chttp2_incoming_byte_stream_finished(exec_ctx, p->parsing_frame, + GRPC_ERROR_NONE); + p->parsing_frame = NULL; + cur += p->frame_size; + goto fh_0; /* loop */ + } else { + GPR_ASSERT(remaining <= p->frame_size); + grpc_chttp2_incoming_byte_stream_push( + exec_ctx, p->parsing_frame, + grpc_slice_sub(slice, (size_t)(cur - beg), (size_t)(end - beg))); + p->frame_size -= remaining; + s->stats.incoming.data_bytes += remaining; return GRPC_ERROR_NONE; - case GRPC_CHTTP2_DATA_FRAME: { - GPR_ASSERT(p->parsing_frame != NULL); - GPR_ASSERT(slice_out != NULL); - if (cur == end) { - grpc_slice_unref_internal(exec_ctx, slice); - continue; - } - uint32_t remaining = (uint32_t)(end - cur); - if (remaining == p->frame_size) { - if (GRPC_ERROR_NONE != (error = grpc_chttp2_incoming_byte_stream_push( - exec_ctx, p->parsing_frame, - grpc_slice_sub(slice, (size_t)(cur - beg), - (size_t)(end - beg)), - slice_out))) { - grpc_slice_unref_internal(exec_ctx, slice); - return error; - } - if (GRPC_ERROR_NONE != - (error = grpc_chttp2_incoming_byte_stream_finished( - exec_ctx, p->parsing_frame, GRPC_ERROR_NONE, true))) { - grpc_slice_unref_internal(exec_ctx, slice); - return error; - } - p->parsing_frame = NULL; - p->state = GRPC_CHTTP2_DATA_FH_0; - grpc_slice_unref_internal(exec_ctx, slice); - return GRPC_ERROR_NONE; - } else if (remaining < p->frame_size) { - if (GRPC_ERROR_NONE != (error = grpc_chttp2_incoming_byte_stream_push( - exec_ctx, p->parsing_frame, - grpc_slice_sub(slice, (size_t)(cur - beg), - (size_t)(end - beg)), - slice_out))) { - return error; - } - p->frame_size -= remaining; - grpc_slice_unref_internal(exec_ctx, slice); - return GRPC_ERROR_NONE; - } else { - GPR_ASSERT(remaining > p->frame_size); - if (GRPC_ERROR_NONE != - (grpc_chttp2_incoming_byte_stream_push( - exec_ctx, p->parsing_frame, - grpc_slice_sub(slice, (size_t)(cur - beg), - (size_t)(cur + p->frame_size - beg)), - slice_out))) { - grpc_slice_unref_internal(exec_ctx, slice); - return error; - } - if (GRPC_ERROR_NONE != - (error = grpc_chttp2_incoming_byte_stream_finished( - exec_ctx, p->parsing_frame, GRPC_ERROR_NONE, true))) { - grpc_slice_unref_internal(exec_ctx, slice); - return error; - } - p->parsing_frame = NULL; - p->state = GRPC_CHTTP2_DATA_FH_0; - cur += p->frame_size; - grpc_slice_buffer_undo_take_first( - &s->unprocessed_incoming_frames_buffer, - grpc_slice_sub(slice, (size_t)(cur - beg), (size_t)(end - beg))); - grpc_slice_unref_internal(exec_ctx, slice); - return GRPC_ERROR_NONE; - } } - } } - return GRPC_ERROR_NONE; + GPR_UNREACHABLE_CODE( + return GRPC_ERROR_CREATE_FROM_STATIC_STRING("Should never reach here")); } grpc_error *grpc_chttp2_data_parser_parse(grpc_exec_ctx *exec_ctx, void *parser, grpc_chttp2_transport *t, grpc_chttp2_stream *s, grpc_slice slice, int is_last) { - /* grpc_error *error = parse_inner_buffer(exec_ctx, p, t, s, slice); */ - s->stats.incoming.framing_bytes += GRPC_SLICE_LENGTH(slice); - if (!s->pending_byte_stream) { - grpc_slice_ref_internal(slice); - grpc_slice_buffer_add(&s->frame_storage, slice); - grpc_chttp2_maybe_complete_recv_message(exec_ctx, t, s); - } else if (s->on_next) { - GPR_ASSERT(s->frame_storage.length == 0); - grpc_slice_ref_internal(slice); - grpc_slice_buffer_add(&s->unprocessed_incoming_frames_buffer, slice); - grpc_closure_sched(exec_ctx, s->on_next, GRPC_ERROR_NONE); - s->on_next = NULL; - } else { - grpc_slice_ref_internal(slice); - grpc_slice_buffer_add(&s->frame_storage, slice); - } + grpc_chttp2_data_parser *p = parser; + grpc_error *error = parse_inner(exec_ctx, p, t, s, slice); - if (is_last && s->received_last_frame) { + if (is_last && p->is_last_frame) { grpc_chttp2_mark_stream_closed(exec_ctx, t, s, true, false, GRPC_ERROR_NONE); } - return GRPC_ERROR_NONE; + return error; } diff --git a/src/core/ext/transport/chttp2/transport/frame_data.h b/src/core/ext/transport/chttp2/transport/frame_data.h index 2fb8983c38..264ad14608 100644 --- a/src/core/ext/transport/chttp2/transport/frame_data.h +++ b/src/core/ext/transport/chttp2/transport/frame_data.h @@ -56,16 +56,28 @@ typedef enum { typedef struct grpc_chttp2_incoming_byte_stream grpc_chttp2_incoming_byte_stream; +typedef struct grpc_chttp2_incoming_frame_queue { + grpc_chttp2_incoming_byte_stream *head; + grpc_chttp2_incoming_byte_stream *tail; +} grpc_chttp2_incoming_frame_queue; + typedef struct { grpc_chttp2_stream_state state; + uint8_t is_last_frame; uint8_t frame_type; uint32_t frame_size; grpc_error *error; - bool is_frame_compressed; + int is_frame_compressed; grpc_chttp2_incoming_byte_stream *parsing_frame; } grpc_chttp2_data_parser; +void grpc_chttp2_incoming_frame_queue_merge( + grpc_chttp2_incoming_frame_queue *head_dst, + grpc_chttp2_incoming_frame_queue *tail_src); +grpc_byte_stream *grpc_chttp2_incoming_frame_queue_pop( + grpc_chttp2_incoming_frame_queue *q); + /* initialize per-stream state for data frame parsing */ grpc_error *grpc_chttp2_data_parser_init(grpc_chttp2_data_parser *parser); @@ -75,8 +87,7 @@ void grpc_chttp2_data_parser_destroy(grpc_exec_ctx *exec_ctx, /* start processing a new data frame */ grpc_error *grpc_chttp2_data_parser_begin_frame(grpc_chttp2_data_parser *parser, uint8_t flags, - uint32_t stream_id, - grpc_chttp2_stream *s); + uint32_t stream_id); /* handle a slice of a data frame - is_last indicates the last slice of a frame */ @@ -90,11 +101,4 @@ void grpc_chttp2_encode_data(uint32_t id, grpc_slice_buffer *inbuf, grpc_transport_one_way_stats *stats, grpc_slice_buffer *outbuf); -grpc_error *deframe_unprocessed_incoming_frames(grpc_exec_ctx *exec_ctx, - grpc_chttp2_data_parser *p, - grpc_chttp2_stream *s, - grpc_slice_buffer *slices, - grpc_slice *slice_out, - grpc_byte_stream **stream_out); - #endif /* GRPC_CORE_EXT_TRANSPORT_CHTTP2_TRANSPORT_FRAME_DATA_H */ diff --git a/src/core/ext/transport/chttp2/transport/internal.h b/src/core/ext/transport/chttp2/transport/internal.h index a10e3886ea..6eb848b8d7 100644 --- a/src/core/ext/transport/chttp2/transport/internal.h +++ b/src/core/ext/transport/chttp2/transport/internal.h @@ -195,20 +195,22 @@ typedef struct grpc_chttp2_write_cb { struct grpc_chttp2_incoming_byte_stream { grpc_byte_stream base; gpr_refcount refs; + struct grpc_chttp2_incoming_byte_stream *next_message; + grpc_error *error; - grpc_chttp2_transport *transport; /* immutable */ - grpc_chttp2_stream *stream; /* immutable */ + grpc_chttp2_transport *transport; + grpc_chttp2_stream *stream; + bool is_tail; - /* Accessed only by transport thread when stream->pending_byte_stream == false - * Accessed only by application thread when stream->pending_byte_stream == - * true */ + gpr_mu slice_mu; // protects slices, on_next + grpc_slice_buffer slices; + grpc_closure *on_next; + grpc_slice *next; uint32_t remaining_bytes; - /* Accessed only by transport thread when stream->pending_byte_stream == false - * Accessed only by application thread when stream->pending_byte_stream == - * true */ struct { grpc_closure closure; + grpc_slice *slice; size_t max_size_hint; grpc_closure *on_complete; } next_action; @@ -443,8 +445,8 @@ struct grpc_chttp2_stream { uint32_t id; /** window available for us to send to peer, over or under the initial window - * size of the transport... ie: - * outgoing_window = outgoing_window_delta + transport.initial_window_size */ + * size of the transport... ie: + * outgoing_window = outgoing_window_delta + transport.initial_window_size */ int64_t outgoing_window_delta; /** things the upper layers would like to send */ grpc_metadata_batch *send_initial_metadata; @@ -471,6 +473,9 @@ struct grpc_chttp2_stream { grpc_transport_stream_stats *collecting_stats; grpc_transport_stream_stats stats; + /** number of streams that are currently being read */ + gpr_refcount active_streams; + /** Is this stream closed for writing. */ bool write_closed; /** Is this stream reading half-closed. */ @@ -494,17 +499,7 @@ struct grpc_chttp2_stream { grpc_chttp2_incoming_metadata_buffer metadata_buffer[2]; - grpc_slice_buffer frame_storage; /* protected by t combiner */ - - /* Accessed only by transport thread when stream->pending_byte_stream == false - * Accessed only by application thread when stream->pending_byte_stream == - * true */ - grpc_slice_buffer unprocessed_incoming_frames_buffer; - grpc_closure *on_next; /* protected by t combiner */ - bool pending_byte_stream; /* protected by t combiner */ - grpc_closure reset_byte_stream; - grpc_error *byte_stream_error; /* protected by t combiner */ - bool received_last_frame; /* protected by t combiner */ + grpc_chttp2_incoming_frame_queue incoming_frames; gpr_timespec deadline; @@ -517,9 +512,6 @@ struct grpc_chttp2_stream { * incoming_window = incoming_window_delta + transport.initial_window_size */ int64_t incoming_window_delta; /** parsing state for data frames */ - /* Accessed only by transport thread when stream->pending_byte_stream == false - * Accessed only by application thread when stream->pending_byte_stream == - * true */ grpc_chttp2_data_parser data_parser; /** number of bytes received - reset at end of parse thread execution */ int64_t received_bytes; @@ -798,13 +790,10 @@ void grpc_chttp2_ref_transport(grpc_chttp2_transport *t); grpc_chttp2_incoming_byte_stream *grpc_chttp2_incoming_byte_stream_create( grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t, grpc_chttp2_stream *s, uint32_t frame_size, uint32_t flags); -grpc_error *grpc_chttp2_incoming_byte_stream_push( - grpc_exec_ctx *exec_ctx, grpc_chttp2_incoming_byte_stream *bs, - grpc_slice slice, grpc_slice *slice_out); -grpc_error *grpc_chttp2_incoming_byte_stream_finished( - grpc_exec_ctx *exec_ctx, grpc_chttp2_incoming_byte_stream *bs, - grpc_error *error, bool reset_on_error); -void grpc_chttp2_incoming_byte_stream_notify( +void grpc_chttp2_incoming_byte_stream_push(grpc_exec_ctx *exec_ctx, + grpc_chttp2_incoming_byte_stream *bs, + grpc_slice slice); +void grpc_chttp2_incoming_byte_stream_finished( grpc_exec_ctx *exec_ctx, grpc_chttp2_incoming_byte_stream *bs, grpc_error *error); diff --git a/src/core/ext/transport/chttp2/transport/parsing.c b/src/core/ext/transport/chttp2/transport/parsing.c index 638b137316..7e457ced27 100644 --- a/src/core/ext/transport/chttp2/transport/parsing.c +++ b/src/core/ext/transport/chttp2/transport/parsing.c @@ -458,13 +458,12 @@ static grpc_error *init_data_frame_parser(grpc_exec_ctx *exec_ctx, return init_skip_frame_parser(exec_ctx, t, 0); } if (err == GRPC_ERROR_NONE) { - err = grpc_chttp2_data_parser_begin_frame( - &s->data_parser, t->incoming_frame_flags, s->id, s); + err = grpc_chttp2_data_parser_begin_frame(&s->data_parser, + t->incoming_frame_flags, s->id); } error_handler: if (err == GRPC_ERROR_NONE) { t->incoming_stream = s; - /* t->parser = grpc_chttp2_data_parser_parse;*/ t->parser = grpc_chttp2_data_parser_parse; t->parser_data = &s->data_parser; return GRPC_ERROR_NONE; diff --git a/src/core/ext/transport/cronet/transport/cronet_transport.c b/src/core/ext/transport/cronet/transport/cronet_transport.c index 7896c70f9e..88335ecd0b 100644 --- a/src/core/ext/transport/cronet/transport/cronet_transport.c +++ b/src/core/ext/transport/cronet/transport/cronet_transport.c @@ -973,20 +973,9 @@ static enum e_op_result execute_stream_op(grpc_exec_ctx *exec_ctx, grpc_slice_buffer write_slice_buffer; grpc_slice slice; grpc_slice_buffer_init(&write_slice_buffer); - if (1 != grpc_byte_stream_next( - exec_ctx, stream_op->payload->send_message.send_message, - stream_op->payload->send_message.send_message->length, - NULL)) { - /* Should never reach here */ - GPR_ASSERT(false); - } - if (GRPC_ERROR_NONE != - grpc_byte_stream_pull(exec_ctx, - stream_op->payload->send_message.send_message, - &slice)) { - /* Should never reach here */ - GPR_ASSERT(false); - } + grpc_byte_stream_next( + NULL, stream_op->payload->send_message.send_message, &slice, + stream_op->payload->send_message.send_message->length, NULL); grpc_slice_buffer_add(&write_slice_buffer, slice); if (write_slice_buffer.count != 1) { /* Empty request not handled yet */ diff --git a/src/core/lib/channel/compress_filter.c b/src/core/lib/channel/compress_filter.c index 764524b24d..4625cba0d2 100644 --- a/src/core/lib/channel/compress_filter.c +++ b/src/core/lib/channel/compress_filter.c @@ -221,13 +221,6 @@ static void finish_send_message(grpc_exec_ctx *exec_ctx, static void got_slice(grpc_exec_ctx *exec_ctx, void *elemp, grpc_error *error) { grpc_call_element *elem = elemp; call_data *calld = elem->call_data; - if (GRPC_ERROR_NONE != - grpc_byte_stream_pull(exec_ctx, - calld->send_op->payload->send_message.send_message, - &calld->incoming_slice)) { - /* Should never reach here */ - abort(); - } grpc_slice_buffer_add(&calld->slices, calld->incoming_slice); if (calld->send_length == calld->slices.length) { finish_send_message(exec_ctx, elem); @@ -240,11 +233,8 @@ static void continue_send_message(grpc_exec_ctx *exec_ctx, grpc_call_element *elem) { call_data *calld = elem->call_data; while (grpc_byte_stream_next( - exec_ctx, calld->send_op->payload->send_message.send_message, ~(size_t)0, - &calld->got_slice)) { - grpc_byte_stream_pull(exec_ctx, - calld->send_op->payload->send_message.send_message, - &calld->incoming_slice); + exec_ctx, calld->send_op->payload->send_message.send_message, + &calld->incoming_slice, ~(size_t)0, &calld->got_slice)) { grpc_slice_buffer_add(&calld->slices, calld->incoming_slice); if (calld->send_length == calld->slices.length) { finish_send_message(exec_ctx, elem); diff --git a/src/core/lib/channel/http_client_filter.c b/src/core/lib/channel/http_client_filter.c index 151fb9885d..4e47c5c658 100644 --- a/src/core/lib/channel/http_client_filter.c +++ b/src/core/lib/channel/http_client_filter.c @@ -220,11 +220,8 @@ static void continue_send_message(grpc_exec_ctx *exec_ctx, call_data *calld = elem->call_data; uint8_t *wrptr = calld->payload_bytes; while (grpc_byte_stream_next( - exec_ctx, calld->send_op->payload->send_message.send_message, ~(size_t)0, - &calld->got_slice)) { - grpc_byte_stream_pull(exec_ctx, - calld->send_op->payload->send_message.send_message, - &calld->incoming_slice); + exec_ctx, calld->send_op->payload->send_message.send_message, + &calld->incoming_slice, ~(size_t)0, &calld->got_slice)) { memcpy(wrptr, GRPC_SLICE_START_PTR(calld->incoming_slice), GRPC_SLICE_LENGTH(calld->incoming_slice)); wrptr += GRPC_SLICE_LENGTH(calld->incoming_slice); @@ -240,13 +237,6 @@ static void got_slice(grpc_exec_ctx *exec_ctx, void *elemp, grpc_error *error) { grpc_call_element *elem = elemp; call_data *calld = elem->call_data; calld->send_message_blocked = false; - if (GRPC_ERROR_NONE != - grpc_byte_stream_pull(exec_ctx, - calld->send_op->payload->send_message.send_message, - &calld->incoming_slice)) { - /* Should never reach here */ - abort(); - } grpc_slice_buffer_add(&calld->slices, calld->incoming_slice); if (calld->send_length == calld->slices.length) { /* Pass down the original send_message op that was blocked.*/ diff --git a/src/core/lib/surface/call.c b/src/core/lib/surface/call.c index 3e96d09798..97d50a91be 100644 --- a/src/core/lib/surface/call.c +++ b/src/core/lib/surface/call.c @@ -1187,7 +1187,6 @@ static void finish_batch_step(grpc_exec_ctx *exec_ctx, batch_control *bctl) { static void continue_receiving_slices(grpc_exec_ctx *exec_ctx, batch_control *bctl) { - grpc_error *error; grpc_call *call = bctl->call; for (;;) { size_t remaining = call->receiving_stream->length - @@ -1199,22 +1198,11 @@ static void continue_receiving_slices(grpc_exec_ctx *exec_ctx, finish_batch_step(exec_ctx, bctl); return; } - if (grpc_byte_stream_next(exec_ctx, call->receiving_stream, remaining, + if (grpc_byte_stream_next(exec_ctx, call->receiving_stream, + &call->receiving_slice, remaining, &call->receiving_slice_ready)) { - error = grpc_byte_stream_pull(exec_ctx, call->receiving_stream, - &call->receiving_slice); - if (error == GRPC_ERROR_NONE) { - grpc_slice_buffer_add(&(*call->receiving_buffer)->data.raw.slice_buffer, - call->receiving_slice); - } else { - grpc_byte_stream_destroy(exec_ctx, call->receiving_stream); - call->receiving_stream = NULL; - grpc_byte_buffer_destroy(*call->receiving_buffer); - *call->receiving_buffer = NULL; - call->receiving_message = 0; - finish_batch_step(exec_ctx, bctl); - return; - } + grpc_slice_buffer_add(&(*call->receiving_buffer)->data.raw.slice_buffer, + call->receiving_slice); } else { return; } @@ -1225,24 +1213,12 @@ static void receiving_slice_ready(grpc_exec_ctx *exec_ctx, void *bctlp, grpc_error *error) { batch_control *bctl = bctlp; grpc_call *call = bctl->call; - grpc_byte_stream *bs = call->receiving_stream; - bool release_error = false; if (error == GRPC_ERROR_NONE) { - grpc_slice slice; - error = grpc_byte_stream_pull(exec_ctx, bs, &slice); - if (error == GRPC_ERROR_NONE) { - grpc_slice_buffer_add(&(*call->receiving_buffer)->data.raw.slice_buffer, - slice); - continue_receiving_slices(exec_ctx, bctl); - } else { - /* Error returned by grpc_byte_stream_pull needs to be released manually - */ - release_error = true; - } - } - - if (error != GRPC_ERROR_NONE) { + grpc_slice_buffer_add(&(*call->receiving_buffer)->data.raw.slice_buffer, + call->receiving_slice); + continue_receiving_slices(exec_ctx, bctl); + } else { if (grpc_trace_operation_failures) { GRPC_LOG_IF_ERROR("receiving_slice_ready", GRPC_ERROR_REF(error)); } @@ -1250,11 +1226,7 @@ static void receiving_slice_ready(grpc_exec_ctx *exec_ctx, void *bctlp, call->receiving_stream = NULL; grpc_byte_buffer_destroy(*call->receiving_buffer); *call->receiving_buffer = NULL; - call->receiving_message = 0; finish_batch_step(exec_ctx, bctl); - if (release_error) { - GRPC_ERROR_UNREF(error); - } } } diff --git a/src/core/lib/transport/byte_stream.c b/src/core/lib/transport/byte_stream.c index 5800c70ef4..4d4206189e 100644 --- a/src/core/lib/transport/byte_stream.c +++ b/src/core/lib/transport/byte_stream.c @@ -40,15 +40,10 @@ #include "src/core/lib/slice/slice_internal.h" int grpc_byte_stream_next(grpc_exec_ctx *exec_ctx, - grpc_byte_stream *byte_stream, size_t max_size_hint, - grpc_closure *on_complete) { - return byte_stream->next(exec_ctx, byte_stream, max_size_hint, on_complete); -} - -grpc_error *grpc_byte_stream_pull(grpc_exec_ctx *exec_ctx, - grpc_byte_stream *byte_stream, - grpc_slice *slice) { - return byte_stream->pull(exec_ctx, byte_stream, slice); + grpc_byte_stream *byte_stream, grpc_slice *slice, + size_t max_size_hint, grpc_closure *on_complete) { + return byte_stream->next(exec_ctx, byte_stream, slice, max_size_hint, + on_complete); } void grpc_byte_stream_destroy(grpc_exec_ctx *exec_ctx, @@ -58,24 +53,16 @@ void grpc_byte_stream_destroy(grpc_exec_ctx *exec_ctx, /* slice_buffer_stream */ -static bool slice_buffer_stream_next(grpc_exec_ctx *exec_ctx, - grpc_byte_stream *byte_stream, - size_t max_size_hint, - grpc_closure *on_complete) { - grpc_slice_buffer_stream *stream = (grpc_slice_buffer_stream *)byte_stream; - GPR_ASSERT(stream->cursor < stream->backing_buffer->count); - return true; -} - -static grpc_error *slice_buffer_stream_pull(grpc_exec_ctx *exec_ctx, - grpc_byte_stream *byte_stream, - grpc_slice *slice) { +static int slice_buffer_stream_next(grpc_exec_ctx *exec_ctx, + grpc_byte_stream *byte_stream, + grpc_slice *slice, size_t max_size_hint, + grpc_closure *on_complete) { grpc_slice_buffer_stream *stream = (grpc_slice_buffer_stream *)byte_stream; GPR_ASSERT(stream->cursor < stream->backing_buffer->count); *slice = grpc_slice_ref_internal(stream->backing_buffer->slices[stream->cursor]); stream->cursor++; - return GRPC_ERROR_NONE; + return 1; } static void slice_buffer_stream_destroy(grpc_exec_ctx *exec_ctx, @@ -88,7 +75,6 @@ void grpc_slice_buffer_stream_init(grpc_slice_buffer_stream *stream, stream->base.length = (uint32_t)slice_buffer->length; stream->base.flags = flags; stream->base.next = slice_buffer_stream_next; - stream->base.pull = slice_buffer_stream_pull; stream->base.destroy = slice_buffer_stream_destroy; stream->backing_buffer = slice_buffer; stream->cursor = 0; diff --git a/src/core/lib/transport/byte_stream.h b/src/core/lib/transport/byte_stream.h index 381c65fb04..1fdd5b4d77 100644 --- a/src/core/lib/transport/byte_stream.h +++ b/src/core/lib/transport/byte_stream.h @@ -49,10 +49,9 @@ typedef struct grpc_byte_stream grpc_byte_stream; struct grpc_byte_stream { uint32_t length; uint32_t flags; - bool (*next)(grpc_exec_ctx *exec_ctx, grpc_byte_stream *byte_stream, - size_t max_size_hint, grpc_closure *on_complete); - grpc_error *(*pull)(grpc_exec_ctx *exec_ctx, grpc_byte_stream *byte_stream, - grpc_slice *slice); + int (*next)(grpc_exec_ctx *exec_ctx, grpc_byte_stream *byte_stream, + grpc_slice *slice, size_t max_size_hint, + grpc_closure *on_complete); void (*destroy)(grpc_exec_ctx *exec_ctx, grpc_byte_stream *byte_stream); }; @@ -62,20 +61,12 @@ struct grpc_byte_stream { * * max_size_hint can be set as a hint as to the maximum number * of bytes that would be acceptable to read. - */ -int grpc_byte_stream_next(grpc_exec_ctx *exec_ctx, - grpc_byte_stream *byte_stream, size_t max_size_hint, - grpc_closure *on_complete); - -/* returns the next slice in the byte stream when it is ready (indicated by - * either grpc_byte_stream_next returning 1 or on_complete passed to - * grpc_byte_stream_next is called). * * once a slice is returned into *slice, it is owned by the caller. */ -grpc_error *grpc_byte_stream_pull(grpc_exec_ctx *exec_ctx, - grpc_byte_stream *byte_stream, - grpc_slice *slice); +int grpc_byte_stream_next(grpc_exec_ctx *exec_ctx, + grpc_byte_stream *byte_stream, grpc_slice *slice, + size_t max_size_hint, grpc_closure *on_complete); void grpc_byte_stream_destroy(grpc_exec_ctx *exec_ctx, grpc_byte_stream *byte_stream); diff --git a/test/cpp/microbenchmarks/bm_chttp2_transport.cc b/test/cpp/microbenchmarks/bm_chttp2_transport.cc index 8c5413b5fd..c89f349ca7 100644 --- a/test/cpp/microbenchmarks/bm_chttp2_transport.cc +++ b/test/cpp/microbenchmarks/bm_chttp2_transport.cc @@ -569,17 +569,12 @@ static void BM_TransportStreamRecv(benchmark::State &state) { grpc_closure_sched(exec_ctx, c.get(), GRPC_ERROR_NONE); return; } - } while (grpc_byte_stream_next(exec_ctx, recv_stream, + } while (grpc_byte_stream_next(exec_ctx, recv_stream, &recv_slice, recv_stream->length - received, - drain_continue.get()) && - GRPC_ERROR_NONE == - grpc_byte_stream_pull(exec_ctx, recv_stream, &recv_slice) && - (received += GRPC_SLICE_LENGTH(recv_slice), - grpc_slice_unref_internal(exec_ctx, recv_slice), true)); + drain_continue.get())); }); drain_continue = MakeClosure([&](grpc_exec_ctx *exec_ctx, grpc_error *error) { - grpc_byte_stream_pull(exec_ctx, recv_stream, &recv_slice); received += GRPC_SLICE_LENGTH(recv_slice); grpc_slice_unref_internal(exec_ctx, recv_slice); grpc_closure_run(exec_ctx, drain.get(), GRPC_ERROR_NONE); -- cgit v1.2.3