From ebe8eb2db9a1620496353f8ffb91e04488226790 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Fri, 10 Feb 2017 11:04:23 -0800 Subject: [PATCH 001/127] Deframe lazily --- .../chttp2/transport/chttp2_transport.c | 224 +++++++++++++++--- .../transport/chttp2/transport/frame_data.c | 44 ++-- .../ext/transport/chttp2/transport/internal.h | 5 +- .../ext/transport/chttp2/transport/parsing.c | 1 + 4 files changed, 225 insertions(+), 49 deletions(-) diff --git a/src/core/ext/transport/chttp2/transport/chttp2_transport.c b/src/core/ext/transport/chttp2/transport/chttp2_transport.c index da4c7dc7b23..5c5c29389f4 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 f9b9e1b3092..75657e4c70b 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 d26812ad6be..2e71c846646 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 7ed00522c3e..f48de8ea25b 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; From bdd92b56c4dea3c64474542efe3722315042693a Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Mon, 13 Feb 2017 11:36:51 -0800 Subject: [PATCH 002/127] intermediate changes --- .../chttp2/transport/chttp2_transport.c | 22 +++++++++++++++---- .../transport/chttp2/transport/frame_data.c | 2 +- 2 files changed, 19 insertions(+), 5 deletions(-) diff --git a/src/core/ext/transport/chttp2/transport/chttp2_transport.c b/src/core/ext/transport/chttp2/transport/chttp2_transport.c index 5c5c29389f4..df54d188006 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 75657e4c70b..501565f8a14 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)) { From 380a8f6de54c2843c74f5a756b4c91b85cbf3809 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Wed, 15 Feb 2017 15:19:46 -0800 Subject: [PATCH 003/127] intermediate --- .../chttp2/transport/chttp2_transport.c | 50 +++++++++++-------- .../transport/chttp2/transport/frame_data.c | 48 ++++++------------ .../ext/transport/chttp2/transport/internal.h | 2 +- 3 files changed, 44 insertions(+), 56 deletions(-) diff --git a/src/core/ext/transport/chttp2/transport/chttp2_transport.c b/src/core/ext/transport/chttp2/transport/chttp2_transport.c index df54d188006..c0f43b7ffb5 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 501565f8a14..71adf80c890 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 2e71c846646..0ce67ce450a 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); From 3d97670b801965ad479fc49c534be61faf8507f9 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Fri, 17 Feb 2017 13:53:10 -0800 Subject: [PATCH 004/127] Intermediate --- .../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(-) diff --git a/src/core/ext/transport/chttp2/transport/chttp2_transport.c b/src/core/ext/transport/chttp2/transport/chttp2_transport.c index c0f43b7ffb5..18ee1a70876 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 71adf80c890..cde9cd9c99c 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; } From 456f48ad9851b88a94b806dd451eb85056801c26 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Tue, 21 Feb 2017 11:12:49 -0800 Subject: [PATCH 005/127] Change stream interface for method --- .../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(-) diff --git a/src/core/ext/transport/chttp2/transport/chttp2_transport.c b/src/core/ext/transport/chttp2/transport/chttp2_transport.c index 18ee1a70876..da5cdaea8b4 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 cc57654ea41..ec1eb0a5f9f 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 1fdd5b4d775..646ffcd660b 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); }; From 5a6e2416ed4938afd26ed756af6ea57c2288b8ed Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Fri, 24 Feb 2017 14:52:28 -0800 Subject: [PATCH 006/127] Lazy deframe pass cronet end2end tests --- .../chttp2/transport/chttp2_transport.c | 116 ++++++++++-------- .../transport/chttp2/transport/frame_data.c | 42 ++++++- .../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(-) diff --git a/src/core/ext/transport/chttp2/transport/chttp2_transport.c b/src/core/ext/transport/chttp2/transport/chttp2_transport.c index da5cdaea8b4..b03c79315bb 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 cde9cd9c99c..e889e3527bd 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 0ce67ce450a..8d0f96efc6b 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 ec1eb0a5f9f..7baa8e10a59 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 4d4206189e7..afebf52cd58 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 646ffcd660b..582480bb88f 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); From 31ed2d9effd77029b879a139f4dd9e8ab166a1f5 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Sun, 26 Feb 2017 22:10:07 -0800 Subject: [PATCH 007/127] clang-format --- .../chttp2/transport/chttp2_transport.c | 24 +++++++++---------- .../transport/chttp2/transport/frame_data.c | 12 ++++------ .../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(-) diff --git a/src/core/ext/transport/chttp2/transport/chttp2_transport.c b/src/core/ext/transport/chttp2/transport/chttp2_transport.c index b03c79315bb..b5e087d8f72 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 e889e3527bd..2c12b871418 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 8d0f96efc6b..3d6253cd6fa 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 afebf52cd58..3a50694670f 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 582480bb88f..6afba92c523 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); From 9767a94a6a94ac8e1bb575f8cae44e52000ba0fc Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Sun, 26 Feb 2017 23:15:51 -0800 Subject: [PATCH 008/127] Stop nulling the parse_frame when stream is closed --- src/core/ext/transport/chttp2/transport/chttp2_transport.c | 5 ----- 1 file changed, 5 deletions(-) diff --git a/src/core/ext/transport/chttp2/transport/chttp2_transport.c b/src/core/ext/transport/chttp2/transport/chttp2_transport.c index b5e087d8f72..9cb66d77727 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); From 3989b88ffafd738d15ae1dbeee9107af95930d90 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Mon, 27 Feb 2017 08:26:49 -0800 Subject: [PATCH 009/127] sanity fix --- src/core/ext/transport/chttp2/transport/frame_data.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core/ext/transport/chttp2/transport/frame_data.c b/src/core/ext/transport/chttp2/transport/frame_data.c index 2c12b871418..e1341228026 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; From 146cf4b57f6266b834e8d0427a6b1177dfd6bc9b Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Mon, 27 Feb 2017 08:31:52 -0800 Subject: [PATCH 010/127] nit fix --- src/core/ext/transport/chttp2/transport/frame_data.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/core/ext/transport/chttp2/transport/frame_data.c b/src/core/ext/transport/chttp2/transport/frame_data.c index e1341228026..aa2ccfdcec3 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; From cad4c809a3b5167ac0b6a944e68adcb0d0b513d6 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Mon, 27 Feb 2017 08:47:14 -0800 Subject: [PATCH 011/127] clang-format --- src/core/ext/transport/chttp2/transport/frame_data.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core/ext/transport/chttp2/transport/frame_data.c b/src/core/ext/transport/chttp2/transport/frame_data.c index aa2ccfdcec3..08b4b81bf8d 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; From c9b538a43886c1f2bc3ff7f7943c49686ad06472 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Mon, 27 Feb 2017 12:26:33 -0800 Subject: [PATCH 012/127] 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(+) diff --git a/src/core/ext/transport/chttp2/transport/chttp2_transport.c b/src/core/ext/transport/chttp2/transport/chttp2_transport.c index 9cb66d77727..b5e087d8f72 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); From 6deb74968aba72e4a008bb4f717cc8fdf64039f4 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Mon, 27 Feb 2017 12:29:04 -0800 Subject: [PATCH 013/127] 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(-) diff --git a/src/core/ext/transport/chttp2/transport/chttp2_transport.c b/src/core/ext/transport/chttp2/transport/chttp2_transport.c index b5e087d8f72..6155335f814 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; From 532f2dd53e624bbc81f521f765df32e044ca1d78 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Mon, 27 Feb 2017 15:29:06 -0800 Subject: [PATCH 014/127] Protect with mutex and check for bs->error at incoming_stream_pull --- .../transport/chttp2/transport/chttp2_transport.c | 14 ++++++++++++++ src/core/ext/transport/chttp2/transport/parsing.c | 2 ++ 2 files changed, 16 insertions(+) diff --git a/src/core/ext/transport/chttp2/transport/chttp2_transport.c b/src/core/ext/transport/chttp2/transport/chttp2_transport.c index 6155335f814..d99c0dc50c2 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 f48de8ea25b..29405994f02 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) { From d9d3c902d7ffcb5d3bda87a46a015cd0ba0752ef Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Mon, 27 Feb 2017 20:40:41 -0800 Subject: [PATCH 015/127] Clean up stream when there's no unprocessed frames --- .../ext/transport/chttp2/transport/chttp2_transport.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/src/core/ext/transport/chttp2/transport/chttp2_transport.c b/src/core/ext/transport/chttp2/transport/chttp2_transport.c index d99c0dc50c2..d1f0a483915 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); From 4ec9a1fadc0278aabbeaf18c2ea22aabbef00bcc Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Tue, 28 Feb 2017 14:35:46 -0800 Subject: [PATCH 016/127] Add grpc_chttp2_incoming_byte_stream_notify --- .../chttp2/transport/chttp2_transport.c | 23 +++++++++++++++---- .../transport/chttp2/transport/frame_data.c | 1 + .../ext/transport/chttp2/transport/internal.h | 3 +++ 3 files changed, 22 insertions(+), 5 deletions(-) diff --git a/src/core/ext/transport/chttp2/transport/chttp2_transport.c b/src/core/ext/transport/chttp2/transport/chttp2_transport.c index d1f0a483915..6cfe4730756 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 08b4b81bf8d..a53241ad30d 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 3d6253cd6fa..a7ff26a42a2 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); From d106082c2f967386aa596e5f641b81bbc499eb51 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Tue, 28 Feb 2017 18:18:03 -0800 Subject: [PATCH 017/127] Nit --- src/core/ext/transport/chttp2/transport/chttp2_transport.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/core/ext/transport/chttp2/transport/chttp2_transport.c b/src/core/ext/transport/chttp2/transport/chttp2_transport.c index 6cfe4730756..b842a889bab 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; } } From 369d5cce0222b911d491135c7b2db6044654d829 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Tue, 28 Feb 2017 18:20:19 -0800 Subject: [PATCH 018/127] nit --- src/core/ext/transport/chttp2/transport/chttp2_transport.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/core/ext/transport/chttp2/transport/chttp2_transport.c b/src/core/ext/transport/chttp2/transport/chttp2_transport.c index b842a889bab..56829900e11 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; From 58500218452332a72ded0dee6273675e57839621 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Tue, 28 Feb 2017 19:08:00 -0800 Subject: [PATCH 019/127] nit --- src/core/ext/transport/chttp2/transport/chttp2_transport.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/core/ext/transport/chttp2/transport/chttp2_transport.c b/src/core/ext/transport/chttp2/transport/chttp2_transport.c index 56829900e11..436440d7b16 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; From 9a0356b1e6d0f4fdd1e29a48596b91458b038f46 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Wed, 1 Mar 2017 18:48:43 -0800 Subject: [PATCH 020/127] Fix a bug in slice_buffer:maybe_embiggen --- src/core/lib/slice/slice_buffer.c | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/src/core/lib/slice/slice_buffer.c b/src/core/lib/slice/slice_buffer.c index 9176dc8a420..451319c50d6 100644 --- a/src/core/lib/slice/slice_buffer.c +++ b/src/core/lib/slice/slice_buffer.c @@ -46,11 +46,6 @@ #define GROW(x) (3 * (x) / 2) static void maybe_embiggen(grpc_slice_buffer *sb) { - if (sb->base_slices != sb->slices) { - memmove(sb->base_slices, sb->slices, sb->count * sizeof(grpc_slice)); - sb->slices = sb->base_slices; - } - /* How far away from sb->base_slices is sb->slices pointer */ size_t slice_offset = (size_t)(sb->slices - sb->base_slices); size_t slice_count = sb->count + slice_offset; @@ -61,12 +56,15 @@ static void maybe_embiggen(grpc_slice_buffer *sb) { if (sb->base_slices == sb->inlined) { sb->base_slices = gpr_malloc(sb->capacity * sizeof(grpc_slice)); memcpy(sb->base_slices, sb->inlined, slice_count * sizeof(grpc_slice)); + sb->slices = sb->base_slices + slice_offset; } else { + if (sb->base_slices != sb->slices) { + memmove(sb->base_slices, sb->slices, sb->count * sizeof(grpc_slice)); + } sb->base_slices = gpr_realloc(sb->base_slices, sb->capacity * sizeof(grpc_slice)); + sb->slices = sb->base_slices; } - - sb->slices = sb->base_slices + slice_offset; } } From 59469c911d0434ae9355d78453869c351e98bfdc Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Thu, 2 Mar 2017 18:49:31 -0800 Subject: [PATCH 021/127] better handling of stream closure --- .../chttp2/transport/chttp2_transport.c | 24 +++++++++++++++---- .../ext/transport/chttp2/transport/internal.h | 1 + 2 files changed, 20 insertions(+), 5 deletions(-) diff --git a/src/core/ext/transport/chttp2/transport/chttp2_transport.c b/src/core/ext/transport/chttp2/transport/chttp2_transport.c index 436440d7b16..598dae40a05 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 a7ff26a42a2..5ec107c3f32 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; From dc1937472a3213ec0d624ed91e72abf470fd6dcc Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Fri, 3 Mar 2017 18:25:11 -0800 Subject: [PATCH 022/127] Fix python bug --- .../chttp2/transport/chttp2_transport.c | 29 ++++++++++++++----- 1 file changed, 22 insertions(+), 7 deletions(-) diff --git a/src/core/ext/transport/chttp2/transport/chttp2_transport.c b/src/core/ext/transport/chttp2/transport/chttp2_transport.c index 598dae40a05..eec21cf5693 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); From 6f10b56649fe96859edda8c100256813db602fa9 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Fri, 3 Mar 2017 18:41:46 -0800 Subject: [PATCH 023/127] bug fix --- src/core/ext/transport/chttp2/transport/chttp2_transport.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/core/ext/transport/chttp2/transport/chttp2_transport.c b/src/core/ext/transport/chttp2/transport/chttp2_transport.c index eec21cf5693..e221ef36a62 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); } } From 15e23ecb74492637f9ef6fa9a262c63ad1d6f259 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Sat, 4 Mar 2017 15:01:24 -0800 Subject: [PATCH 024/127] 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(-) diff --git a/src/core/ext/transport/chttp2/transport/frame_data.c b/src/core/ext/transport/chttp2/transport/frame_data.c index a53241ad30d..cfa9a3d3c5f 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 5ec107c3f32..54bfd42357d 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); From 8e6f3371b350030a5f656d1a94e008f30b37f898 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Sat, 4 Mar 2017 16:28:11 -0800 Subject: [PATCH 025/127] bug fix --- .../chttp2/transport/chttp2_transport.c | 29 ++++++++++--------- 1 file changed, 16 insertions(+), 13 deletions(-) diff --git a/src/core/ext/transport/chttp2/transport/chttp2_transport.c b/src/core/ext/transport/chttp2/transport/chttp2_transport.c index e221ef36a62..51bb47127fb 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; + } } } From e4f9eb4e6f9ecc6cd61c0fd7d2eaeea266709d94 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Sat, 4 Mar 2017 22:07:46 -0800 Subject: [PATCH 026/127] clang-format --- .../chttp2/transport/chttp2_transport.c | 22 ++++++++++++------- .../transport/chttp2/transport/frame_data.c | 3 ++- 2 files changed, 16 insertions(+), 9 deletions(-) diff --git a/src/core/ext/transport/chttp2/transport/chttp2_transport.c b/src/core/ext/transport/chttp2/transport/chttp2_transport.c index 51bb47127fb..b1fa3595f24 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 cfa9a3d3c5f..eed5c923765 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; } From bd0a295b2a4f8a35c18330e3e83b6ae5537de4ea Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Sun, 5 Mar 2017 16:49:10 -0800 Subject: [PATCH 027/127] Destroy slice buffer bug --- .../ext/transport/chttp2/transport/chttp2_transport.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/core/ext/transport/chttp2/transport/chttp2_transport.c b/src/core/ext/transport/chttp2/transport/chttp2_transport.c index b1fa3595f24..9ec0bd02c27 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); From 24c131cbfd2201112df63d4f67dd9310a1ae671d Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Sun, 5 Mar 2017 19:54:52 -0800 Subject: [PATCH 028/127] Bug fix --- src/core/ext/transport/chttp2/transport/chttp2_transport.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/core/ext/transport/chttp2/transport/chttp2_transport.c b/src/core/ext/transport/chttp2/transport/chttp2_transport.c index 9ec0bd02c27..618d9336471 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); } From b17764905eb4f589dc9612f37490e165c6548539 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Tue, 7 Mar 2017 14:20:40 -0800 Subject: [PATCH 029/127] Fix a bug in receiving_slice_ready --- src/core/lib/surface/call.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/core/lib/surface/call.c b/src/core/lib/surface/call.c index 7baa8e10a59..4471ada106e 100644 --- a/src/core/lib/surface/call.c +++ b/src/core/lib/surface/call.c @@ -1197,6 +1197,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); } } From a9af945817954a74e5ede427f0ff9248636672e4 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Thu, 9 Mar 2017 14:41:44 -0800 Subject: [PATCH 030/127] Fix python bug --- .../chttp2/transport/chttp2_transport.c | 46 ++++++++++++------- 1 file changed, 30 insertions(+), 16 deletions(-) diff --git a/src/core/ext/transport/chttp2/transport/chttp2_transport.c b/src/core/ext/transport/chttp2/transport/chttp2_transport.c index 618d9336471..b60f96e342a 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); From d54b9e929c85dd02bb883285b801ad90cfd3044b Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Thu, 9 Mar 2017 17:45:37 -0800 Subject: [PATCH 031/127] Minor fix --- src/core/ext/transport/chttp2/transport/chttp2_transport.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/core/ext/transport/chttp2/transport/chttp2_transport.c b/src/core/ext/transport/chttp2/transport/chttp2_transport.c index b60f96e342a..da8131c1a25 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 = From 19cd0f3679dc2fae3c6997eb061afa2812fb0aac Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Thu, 9 Mar 2017 21:33:40 -0800 Subject: [PATCH 032/127] Bug fix --- .../chttp2/transport/chttp2_transport.c | 25 ++++++++++--------- 1 file changed, 13 insertions(+), 12 deletions(-) diff --git a/src/core/ext/transport/chttp2/transport/chttp2_transport.c b/src/core/ext/transport/chttp2/transport/chttp2_transport.c index da8131c1a25..cb04c30a080 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) { From bdcdf31fb92011afc7d3642d81dd7cabccfa4f7e Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Thu, 9 Mar 2017 22:13:59 -0800 Subject: [PATCH 033/127] Bug fix --- .../chttp2/transport/chttp2_transport.c | 30 ++++++++++++------- 1 file changed, 20 insertions(+), 10 deletions(-) diff --git a/src/core/ext/transport/chttp2/transport/chttp2_transport.c b/src/core/ext/transport/chttp2/transport/chttp2_transport.c index cb04c30a080..5237a78cfc1 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); } } From 6f2e6e68be4aef872342e6e6451c1b74d2a61d9e Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Fri, 10 Mar 2017 09:27:50 -0800 Subject: [PATCH 034/127] clang-format --- .../chttp2/transport/chttp2_transport.c | 48 ++++++++++--------- 1 file changed, 26 insertions(+), 22 deletions(-) diff --git a/src/core/ext/transport/chttp2/transport/chttp2_transport.c b/src/core/ext/transport/chttp2/transport/chttp2_transport.c index 5237a78cfc1..edcb243c373 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 From 0901b168f391858ff44ea3c724a5b5fdeb18ea93 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Fri, 10 Mar 2017 11:24:09 -0800 Subject: [PATCH 035/127] Bug fix --- src/core/ext/transport/chttp2/transport/chttp2_transport.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/core/ext/transport/chttp2/transport/chttp2_transport.c b/src/core/ext/transport/chttp2/transport/chttp2_transport.c index edcb243c373..83b27a49aad 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; From 408f36bf286928f069ef256577736a655c38e9d1 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Sun, 19 Mar 2017 00:25:22 -0700 Subject: [PATCH 036/127] Bug fix --- .../transport/chttp2/transport/chttp2_transport.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/src/core/ext/transport/chttp2/transport/chttp2_transport.c b/src/core/ext/transport/chttp2/transport/chttp2_transport.c index 83b27a49aad..79aa05e2124 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); From 1f9fd13a15f97d6e3d1a93d942d3a44bd9526471 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Sun, 19 Mar 2017 10:39:09 -0700 Subject: [PATCH 037/127] clang-format --- .../chttp2/transport/chttp2_transport.c | 28 ++++++++----------- 1 file changed, 12 insertions(+), 16 deletions(-) diff --git a/src/core/ext/transport/chttp2/transport/chttp2_transport.c b/src/core/ext/transport/chttp2/transport/chttp2_transport.c index 79aa05e2124..a8962d305d4 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 From 1bfcc40fd32357018cb7bfd729e069018abb3689 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Tue, 21 Mar 2017 11:51:40 -0700 Subject: [PATCH 038/127] Clean up byte_stream_next interface usage --- .../chttp2/transport/chttp2_transport.c | 21 ++++++++++++------- .../ext/transport/chttp2/transport/internal.h | 2 -- .../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(-) diff --git a/src/core/ext/transport/chttp2/transport/chttp2_transport.c b/src/core/ext/transport/chttp2/transport/chttp2_transport.c index a8962d305d4..95f20725f31 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 54bfd42357d..adbd48c5810 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 01a03533daf..da180e5144b 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 aa41014a217..53d3b86f45b 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 c031533dd86..af2451e1eb6 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 4471ada106e..5dac90c60c9 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 3a50694670f..79801c4b465 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 6afba92c523..800e2341f9e 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); From ed3e300d8a42fd3b586761563d6ff1ca4bbc486f Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Fri, 24 Mar 2017 10:24:20 -0700 Subject: [PATCH 039/127] Tagging fields to identify protection --- .../ext/transport/chttp2/transport/internal.h | 30 +++++++++---------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/src/core/ext/transport/chttp2/transport/internal.h b/src/core/ext/transport/chttp2/transport/internal.h index adbd48c5810..31f2f06bba7 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; From e3c566431e1e8a3e49c413ef3525218d20759b48 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Fri, 24 Mar 2017 11:19:25 -0700 Subject: [PATCH 040/127] Merge upstream for error interface changes --- .../ext/transport/chttp2/transport/chttp2_transport.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/core/ext/transport/chttp2/transport/chttp2_transport.c b/src/core/ext/transport/chttp2/transport/chttp2_transport.c index a3e596fda71..1b0606ed9af 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; } From ef033aa6a865584fe9e8aa805e342b2b0e69ef8c Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Fri, 24 Mar 2017 11:50:13 -0700 Subject: [PATCH 041/127] Remove duplicated code --- .../ext/transport/chttp2/transport/chttp2_transport.c | 11 ----------- src/core/ext/transport/chttp2/transport/frame_data.c | 2 -- 2 files changed, 13 deletions(-) diff --git a/src/core/ext/transport/chttp2/transport/chttp2_transport.c b/src/core/ext/transport/chttp2/transport/chttp2_transport.c index 1b0606ed9af..8c197f2b85f 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 921dcef11c4..ecd53e2ce96 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; } From 397a6684cbec4812cff3580da80255fa1a00d087 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Fri, 24 Mar 2017 17:27:19 -0700 Subject: [PATCH 042/127] clang-format --- .../chttp2/transport/chttp2_transport.c | 30 +++++++++++-------- 1 file changed, 17 insertions(+), 13 deletions(-) diff --git a/src/core/ext/transport/chttp2/transport/chttp2_transport.c b/src/core/ext/transport/chttp2/transport/chttp2_transport.c index 8c197f2b85f..719a17fe104 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); From 9e760da81a61afb6b9fe4c8ca3a30fae879002f2 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Fri, 24 Mar 2017 17:45:00 -0700 Subject: [PATCH 043/127] Fix c++ test --- test/cpp/microbenchmarks/bm_chttp2_transport.cc | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/test/cpp/microbenchmarks/bm_chttp2_transport.cc b/test/cpp/microbenchmarks/bm_chttp2_transport.cc index 254d57de205..265a5a6b220 100644 --- a/test/cpp/microbenchmarks/bm_chttp2_transport.cc +++ b/test/cpp/microbenchmarks/bm_chttp2_transport.cc @@ -541,9 +541,11 @@ 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, &recv_slice, + } while (grpc_byte_stream_next(exec_ctx, recv_stream, recv_stream->length - received, - drain_continue.get())); + drain_continue.get()) && + GRPC_ERROR_NONE == grpc_byte_stream_pull(exec_ctx, recv_stream, + &recv_slice)); }); drain_continue = MakeClosure([&](grpc_exec_ctx *exec_ctx, grpc_error *error) { From ac399579285661ce13cdbc51c2c8bf7509412be2 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Tue, 28 Mar 2017 18:42:00 -0700 Subject: [PATCH 044/127] Polished with better thread safety --- .../chttp2/transport/chttp2_transport.c | 431 ++++++++---------- .../transport/chttp2/transport/frame_data.c | 184 +------- .../transport/chttp2/transport/frame_data.h | 4 +- .../ext/transport/chttp2/transport/internal.h | 28 +- .../ext/transport/chttp2/transport/parsing.c | 4 +- src/core/lib/surface/call.c | 17 +- 6 files changed, 248 insertions(+), 420 deletions(-) diff --git a/src/core/ext/transport/chttp2/transport/chttp2_transport.c b/src/core/ext/transport/chttp2/transport/chttp2_transport.c index 8c197f2b85f..c86fefe2cfb 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 ecd53e2ce96..ecb941e366c 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 264ad146085..e7e459c79fa 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 5604ea3e31c..917fc1b71eb 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 f1c6f96db58..2c662b67219 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 963e16046a3..6ea199e84f8 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; } From 69b2d2d40bd06b872bdf0c484a459831ed399dbc Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Sun, 2 Apr 2017 18:09:03 -0700 Subject: [PATCH 045/127] Bug fix --- .../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(-) diff --git a/src/core/ext/transport/chttp2/transport/chttp2_transport.c b/src/core/ext/transport/chttp2/transport/chttp2_transport.c index c86fefe2cfb..2ac87b9b241 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 ecb941e366c..8b42d05c726 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 917fc1b71eb..a43c825b70a 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); From 0fa217dfb938166c0442dc023db8095264f77e77 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Sun, 2 Apr 2017 18:18:51 -0700 Subject: [PATCH 046/127] clang-format --- .../chttp2/transport/chttp2_transport.c | 123 ++++++++++-------- .../ext/transport/chttp2/transport/internal.h | 35 ++--- .../ext/transport/chttp2/transport/parsing.c | 22 ++-- src/core/lib/surface/call.c | 2 +- 4 files changed, 101 insertions(+), 81 deletions(-) diff --git a/src/core/ext/transport/chttp2/transport/chttp2_transport.c b/src/core/ext/transport/chttp2/transport/chttp2_transport.c index 176382cb10b..d3a4f35ea40 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 a43c825b70a..a2deac63151 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 2c662b67219..bf1cf58cb25 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 6ea199e84f8..c7b0b7ead34 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); From ec9698f8364934808c0272008735ec16e1cf4e12 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Mon, 3 Apr 2017 11:27:16 -0700 Subject: [PATCH 047/127] Fix asan and use internal version of grpc_slice_buffer_reset_and_unref --- .../chttp2/transport/chttp2_transport.c | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/src/core/ext/transport/chttp2/transport/chttp2_transport.c b/src/core/ext/transport/chttp2/transport/chttp2_transport.c index d3a4f35ea40..63bb622c292 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; } From f5684b4e13bb8281a2246b3219a9e53cfa8d6bfb Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Mon, 3 Apr 2017 11:29:41 -0700 Subject: [PATCH 048/127] clang-format --- .../chttp2/transport/chttp2_transport.c | 43 +++++++++---------- .../ext/transport/chttp2/transport/internal.h | 2 +- .../ext/transport/chttp2/transport/parsing.c | 18 ++++---- 3 files changed, 29 insertions(+), 34 deletions(-) diff --git a/src/core/ext/transport/chttp2/transport/chttp2_transport.c b/src/core/ext/transport/chttp2/transport/chttp2_transport.c index 63bb622c292..301140311ab 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 a2deac63151..b4938dc2812 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 bf1cf58cb25..638b137316f 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; } From 753b0544fdbea8618f2a98fe86eab5419f51c0ce Mon Sep 17 00:00:00 2001 From: murgatroid99 Date: Mon, 3 Apr 2017 15:31:53 -0700 Subject: [PATCH 049/127] Properly unref some slices in Node glue code --- src/node/ext/call.cc | 17 +++++++++++++---- src/node/ext/node_grpc.cc | 12 +++++++++--- 2 files changed, 22 insertions(+), 7 deletions(-) diff --git a/src/node/ext/call.cc b/src/node/ext/call.cc index 244546d3d78..5c311158542 100644 --- a/src/node/ext/call.cc +++ b/src/node/ext/call.cc @@ -574,6 +574,14 @@ void Call::CompleteBatch(bool is_final_op) { } NAN_METHOD(Call::New) { + /* Arguments: + * 0: Channel to make the call on + * 1: Method + * 2: Deadline + * 3: host + * 4: parent Call + * 5: propagation flags + */ if (info.IsConstructCall()) { Call *call; if (info[0]->IsExternal()) { @@ -618,25 +626,26 @@ NAN_METHOD(Call::New) { double deadline = Nan::To(info[2]).FromJust(); grpc_channel *wrapped_channel = channel->GetWrappedChannel(); grpc_call *wrapped_call; + grpc_slice method = CreateSliceFromString( + Nan::To(info[1]).ToLocalChecked()); if (info[3]->IsString()) { grpc_slice *host = new grpc_slice; *host = CreateSliceFromString( Nan::To(info[3]).ToLocalChecked()); wrapped_call = grpc_channel_create_call( wrapped_channel, parent_call, propagate_flags, - GetCompletionQueue(), CreateSliceFromString( - Nan::To(info[1]).ToLocalChecked()), + GetCompletionQueue(), method, host, MillisecondsToTimespec(deadline), NULL); delete host; } else if (info[3]->IsUndefined() || info[3]->IsNull()) { wrapped_call = grpc_channel_create_call( wrapped_channel, parent_call, propagate_flags, - GetCompletionQueue(), CreateSliceFromString( - Nan::To(info[1]).ToLocalChecked()), + GetCompletionQueue(), method, NULL, MillisecondsToTimespec(deadline), NULL); } else { return Nan::ThrowTypeError("Call's fourth argument must be a string"); } + grpc_slice_unref(method); call = new Call(wrapped_call); Nan::Set(info.This(), Nan::New("channel_").ToLocalChecked(), channel_object); diff --git a/src/node/ext/node_grpc.cc b/src/node/ext/node_grpc.cc index 95e273f8ac9..122e5e63ee9 100644 --- a/src/node/ext/node_grpc.cc +++ b/src/node/ext/node_grpc.cc @@ -286,8 +286,10 @@ NAN_METHOD(MetadataKeyIsLegal) { "headerKeyIsLegal's argument must be a string"); } Local key = Nan::To(info[0]).ToLocalChecked(); + grpc_slice slice = CreateSliceFromString(key); info.GetReturnValue().Set(static_cast( - grpc_header_key_is_legal(CreateSliceFromString(key)))); + grpc_header_key_is_legal(slice))); + grpc_slice_unref(slice); } NAN_METHOD(MetadataNonbinValueIsLegal) { @@ -296,8 +298,10 @@ NAN_METHOD(MetadataNonbinValueIsLegal) { "metadataNonbinValueIsLegal's argument must be a string"); } Local value = Nan::To(info[0]).ToLocalChecked(); + grpc_slice slice = CreateSliceFromString(value); info.GetReturnValue().Set(static_cast( - grpc_header_nonbin_value_is_legal(CreateSliceFromString(value)))); + grpc_header_nonbin_value_is_legal(slice))); + grpc_slice_unref(slice); } NAN_METHOD(MetadataKeyIsBinary) { @@ -306,8 +310,10 @@ NAN_METHOD(MetadataKeyIsBinary) { "metadataKeyIsLegal's argument must be a string"); } Local key = Nan::To(info[0]).ToLocalChecked(); + grpc_slice slice = CreateSliceFromString(key); info.GetReturnValue().Set(static_cast( - grpc_is_binary_header(CreateSliceFromString(key)))); + grpc_is_binary_header(slice))); + grpc_slice_unref(slice); } static grpc_ssl_roots_override_result get_ssl_roots_override( From bf289563f6849feb4900c265584c1f5b3434c129 Mon Sep 17 00:00:00 2001 From: Craig Tiller Date: Mon, 3 Apr 2017 15:36:16 -0700 Subject: [PATCH 050/127] Start gen script for new settings handling --- tools/codegen/core/gen_settings_ids.py | 81 ++++++++++++++++++++++++++ 1 file changed, 81 insertions(+) create mode 100755 tools/codegen/core/gen_settings_ids.py diff --git a/tools/codegen/core/gen_settings_ids.py b/tools/codegen/core/gen_settings_ids.py new file mode 100755 index 00000000000..fa3aad1f1f2 --- /dev/null +++ b/tools/codegen/core/gen_settings_ids.py @@ -0,0 +1,81 @@ +#!/usr/bin/env python2.7 + +# 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. + +import perfection + +_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, +} + +p = perfection.hash_parameters(sorted(_SETTINGS.values())) +print p + +def hash(i): + i += p.offset + x = i % p.t + y = i / p.t + return x + p.r[y] + +print '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;' + +print 'const uint16_t grpc_setting_id_to_wire_id[] = {%s};' % ','.join( + '%d' % s for s in p.slots) + +print """ +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; + } + *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; +}""" % { + '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 '-' + } From c8f62bcb038b10d03e7cfa49cda7b197aed8fe54 Mon Sep 17 00:00:00 2001 From: Craig Tiller Date: Mon, 3 Apr 2017 16:25:45 -0700 Subject: [PATCH 051/127] 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 + .../chttp2/transport/frame_settings.c | 38 ++--- .../chttp2/transport/frame_settings.h | 30 +--- .../chttp2/transport/http2_settings.c | 85 ++++++++++++ .../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 + .../generated/sources_and_headers.json | 3 + vsprojects/vcxproj/grpc/grpc.vcxproj | 3 + vsprojects/vcxproj/grpc/grpc.vcxproj.filters | 6 + .../grpc_unsecure/grpc_unsecure.vcxproj | 3 + .../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 diff --git a/CMakeLists.txt b/CMakeLists.txt index e3b2558ad29..ca44f02c67c 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 7499dbbf50d..61f5ffae672 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 cd2de83bcb4..01a2c49f194 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 8aff16854ce..49a8b34657e 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 6e6a65a3ded..f980bebda01 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 d750a5b9841..42e56abff57 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 42d4298c9b6..7b8761cb956 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 382393cbe59..26be06621f2 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 16881c0707a..5719bf19b2f 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 44137798c06..2a85d0dba76 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 00000000000..eea6305c8ee --- /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 00000000000..393c14f7f1b --- /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 ed8793b019f..522791e17a0 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 fa3aad1f1f2..c807f70c2ac 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 a9343499e76..08a0213f0e1 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 be1d8768bd5..e621ca39ce8 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 ada8f1a2289..366678cafd7 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 02468451e98..7e8b8b12466 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 83e76586ac2..7cfbb959863 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 5e2b7c2c318..650fdbc57e5 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 From f408784ae9c3aebb7c76ea66708ef985dc466be1 Mon Sep 17 00:00:00 2001 From: Craig Tiller Date: Mon, 3 Apr 2017 16:50:14 -0700 Subject: [PATCH 052/127] better logging --- src/core/ext/transport/chttp2/transport/frame_settings.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/core/ext/transport/chttp2/transport/frame_settings.c b/src/core/ext/transport/chttp2/transport/frame_settings.c index 5719bf19b2f..46630a6cc62 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) { From 87c79795e6bc0047d22e9c5f638df832587f3418 Mon Sep 17 00:00:00 2001 From: Craig Tiller Date: Mon, 3 Apr 2017 17:05:12 -0700 Subject: [PATCH 053/127] Perform option exchange --- include/grpc/impl/codegen/grpc_types.h | 2 + .../chttp2/transport/chttp2_transport.c | 47 +++++++++++-------- .../chttp2/transport/http2_settings.c | 6 +-- tools/codegen/core/gen_settings_ids.py | 4 +- 4 files changed, 34 insertions(+), 25 deletions(-) diff --git a/include/grpc/impl/codegen/grpc_types.h b/include/grpc/impl/codegen/grpc_types.h index aa4210b1a76..c76f9e0ac47 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 26f9449f4b9..2347bf6d902 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 eea6305c8ee..05f0d8cb468 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 c807f70c2ac..54498a18f25 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, From 83f7b9559c52d3c7f857a8ac80f5c21dcb9d2490 Mon Sep 17 00:00:00 2001 From: Craig Tiller Date: Tue, 4 Apr 2017 07:58:18 -0700 Subject: [PATCH 054/127] Starting the encode path --- .../chttp2/transport/hpack_encoder.c | 16 ++++----- .../chttp2/transport/hpack_encoder.h | 15 +++++--- .../ext/transport/chttp2/transport/writing.c | 36 ++++++++++++++----- 3 files changed, 45 insertions(+), 22 deletions(-) diff --git a/src/core/ext/transport/chttp2/transport/hpack_encoder.c b/src/core/ext/transport/chttp2/transport/hpack_encoder.c index 84586cd9988..f5f52a33608 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 83ba5b1b3e0..6ce32096046 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 0869056f56d..b3918df7dca 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; From eb0e34f73616a6fd8af79d2a02f477baf82d88e1 Mon Sep 17 00:00:00 2001 From: Craig Tiller Date: Tue, 4 Apr 2017 08:46:47 -0700 Subject: [PATCH 055/127] Convert everything to new encode API --- .../transport/chttp2/hpack_encoder_test.c | 61 +++++++++++-------- test/cpp/microbenchmarks/bm_chttp2_hpack.cc | 11 +++- 2 files changed, 45 insertions(+), 27 deletions(-) diff --git a/test/core/transport/chttp2/hpack_encoder_test.c b/test/core/transport/chttp2/hpack_encoder_test.c index d572d79a7ff..701d663cbbc 100644 --- a/test/core/transport/chttp2/hpack_encoder_test.c +++ b/test/core/transport/chttp2/hpack_encoder_test.c @@ -60,9 +60,9 @@ size_t cap_to_delete = 0; /* verify that the output generated by encoding the stream matches the hexstring passed in */ -static void verify(grpc_exec_ctx *exec_ctx, size_t window_available, int eof, - size_t expect_window_used, const char *expected, - size_t nheaders, ...) { +static void verify(grpc_exec_ctx *exec_ctx, size_t window_available, bool eof, + bool use_true_binary_metadata, size_t expect_window_used, + const char *expected, size_t nheaders, ...) { grpc_slice_buffer output; grpc_slice merged; grpc_slice expect = parse_hexstring(expected); @@ -103,8 +103,14 @@ static void verify(grpc_exec_ctx *exec_ctx, size_t window_available, int eof, grpc_transport_one_way_stats stats; memset(&stats, 0, sizeof(stats)); - grpc_chttp2_encode_header(exec_ctx, &g_compressor, 0xdeadbeef, &b, eof, 16384, - &stats, &output); + grpc_encode_header_options hopt = { + .stream_id = 0xdeadbeef, + .is_eof = eof, + .use_true_binary_metadata = false, + .max_frame_size = 16384, + .stats = &stats, + }; + grpc_chttp2_encode_header(exec_ctx, &g_compressor, &b, &hopt, &output); merged = grpc_slice_merge(output.slices, output.count); grpc_slice_buffer_destroy_internal(exec_ctx, &output); grpc_metadata_batch_destroy(exec_ctx, &b); @@ -127,25 +133,28 @@ static void verify(grpc_exec_ctx *exec_ctx, size_t window_available, int eof, static void test_basic_headers(grpc_exec_ctx *exec_ctx) { int i; - verify(exec_ctx, 0, 0, 0, "000005 0104 deadbeef 40 0161 0161", 1, "a", "a"); - verify(exec_ctx, 0, 0, 0, "000001 0104 deadbeef be", 1, "a", "a"); - verify(exec_ctx, 0, 0, 0, "000001 0104 deadbeef be", 1, "a", "a"); - verify(exec_ctx, 0, 0, 0, "000006 0104 deadbeef be 40 0162 0163", 2, "a", "a", - "b", "c"); - verify(exec_ctx, 0, 0, 0, "000002 0104 deadbeef bf be", 2, "a", "a", "b", - "c"); - verify(exec_ctx, 0, 0, 0, "000004 0104 deadbeef 7f 00 0164", 1, "a", "d"); + verify(exec_ctx, 0, false, false, 0, "000005 0104 deadbeef 40 0161 0161", 1, + "a", "a"); + verify(exec_ctx, 0, false, false, 0, "000001 0104 deadbeef be", 1, "a", "a"); + verify(exec_ctx, 0, false, false, 0, "000001 0104 deadbeef be", 1, "a", "a"); + verify(exec_ctx, 0, false, false, 0, "000006 0104 deadbeef be 40 0162 0163", + 2, "a", "a", "b", "c"); + verify(exec_ctx, 0, false, false, 0, "000002 0104 deadbeef bf be", 2, "a", + "a", "b", "c"); + verify(exec_ctx, 0, false, false, 0, "000004 0104 deadbeef 7f 00 0164", 1, + "a", "d"); /* flush out what's there to make a few values look very popular */ for (i = 0; i < 350; i++) { - verify(exec_ctx, 0, 0, 0, "000003 0104 deadbeef c0 bf be", 3, "a", "a", "b", - "c", "a", "d"); + verify(exec_ctx, 0, false, false, 0, "000003 0104 deadbeef c0 bf be", 3, + "a", "a", "b", "c", "a", "d"); } - verify(exec_ctx, 0, 0, 0, "000006 0104 deadbeef c0 00 016b 0176", 2, "a", "a", - "k", "v"); + verify(exec_ctx, 0, false, false, 0, "000006 0104 deadbeef c0 00 016b 0176", + 2, "a", "a", "k", "v"); /* this could be 000004 0104 deadbeef 0f 30 0176 also */ - verify(exec_ctx, 0, 0, 0, "000004 0104 deadbeef 0f 2f 0176", 1, "a", "v"); + verify(exec_ctx, 0, false, false, 0, "000004 0104 deadbeef 0f 2f 0176", 1, + "a", "v"); } static void encode_int_to_str(int i, char *p) { @@ -179,17 +188,17 @@ static void test_decode_table_overflow(grpc_exec_ctx *exec_ctx) { } if (i > 0) { - verify(exec_ctx, 0, 0, 0, expect, 2, "aa", "ba", key, value); + verify(exec_ctx, 0, false, false, 0, expect, 2, "aa", "ba", key, value); } else { - verify(exec_ctx, 0, 0, 0, expect, 1, key, value); + verify(exec_ctx, 0, false, false, 0, expect, 1, key, value); } gpr_free(expect); } /* if the above passes, then we must have just knocked this pair out of the decoder stack, and so we'll be forced to re-encode it */ - verify(exec_ctx, 0, 0, 0, "000007 0104 deadbeef 40 026161 026261", 1, "aa", - "ba"); + verify(exec_ctx, 0, false, false, 0, "000007 0104 deadbeef 40 026161 026261", + 1, "aa", "ba"); } static void verify_table_size_change_match_elem_size(grpc_exec_ctx *exec_ctx, @@ -214,8 +223,12 @@ static void verify_table_size_change_match_elem_size(grpc_exec_ctx *exec_ctx, grpc_transport_one_way_stats stats; memset(&stats, 0, sizeof(stats)); - grpc_chttp2_encode_header(exec_ctx, &g_compressor, 0xdeadbeef, &b, 0, 16384, - &stats, &output); + grpc_encode_header_options hopt = {.stream_id = 0xdeadbeef, + .is_eof = false, + .use_true_binary_metadata = false, + .max_frame_size = 16384, + .stats = &stats}; + grpc_chttp2_encode_header(exec_ctx, &g_compressor, &b, &hopt, &output); grpc_slice_buffer_destroy_internal(exec_ctx, &output); grpc_metadata_batch_destroy(exec_ctx, &b); diff --git a/test/cpp/microbenchmarks/bm_chttp2_hpack.cc b/test/cpp/microbenchmarks/bm_chttp2_hpack.cc index 55d2d2f58d0..7426407874b 100644 --- a/test/cpp/microbenchmarks/bm_chttp2_hpack.cc +++ b/test/cpp/microbenchmarks/bm_chttp2_hpack.cc @@ -90,9 +90,14 @@ static void BM_HpackEncoderEncodeHeader(benchmark::State &state) { grpc_slice_buffer outbuf; grpc_slice_buffer_init(&outbuf); while (state.KeepRunning()) { - uint32_t stream_id = static_cast(state.iterations()); - grpc_chttp2_encode_header(&exec_ctx, &c, stream_id, &b, state.range(0), - state.range(1), &stats, &outbuf); + grpc_encode_header_options hopt = { + static_cast(state.iterations()), + state.range(0) != 0, + false, + (size_t)state.range(1), + &stats, + }; + grpc_chttp2_encode_header(&exec_ctx, &c, &b, &hopt, &outbuf); if (!logged_representative_output) { logged_representative_output = true; for (size_t i = 0; i < outbuf.count; i++) { From 130568e5151ed468d8b40362272104c10aa6488e Mon Sep 17 00:00:00 2001 From: murgatroid99 Date: Tue, 4 Apr 2017 13:43:49 -0700 Subject: [PATCH 056/127] Fix call destruction bug --- src/node/ext/call.cc | 10 +++++++--- src/node/ext/call.h | 5 ++++- src/node/ext/channel.cc | 2 +- src/node/ext/server.cc | 4 ++-- src/node/ext/server_uv.cc | 3 ++- 5 files changed, 16 insertions(+), 8 deletions(-) diff --git a/src/node/ext/call.cc b/src/node/ext/call.cc index 244546d3d78..62f0130d537 100644 --- a/src/node/ext/call.cc +++ b/src/node/ext/call.cc @@ -466,8 +466,10 @@ class ServerCloseResponseOp : public Op { int cancelled; }; -tag::tag(Callback *callback, OpVec *ops, Call *call) : +tag::tag(Callback *callback, OpVec *ops, Call *call, Local call_value) : callback(callback), ops(ops), call(call){ + HandleScope scope; + call_persist.Reset(call_value); } tag::~tag() { @@ -521,6 +523,7 @@ Call::Call(grpc_call *call) : wrapped_call(call), Call::~Call() { if (wrapped_call != NULL) { grpc_call_destroy(wrapped_call); + wrapped_call = NULL; } } @@ -567,7 +570,8 @@ void Call::CompleteBatch(bool is_final_op) { this->has_final_op_completed = true; } this->pending_batches--; - if (this->has_final_op_completed && this->pending_batches == 0) { + if (this->has_final_op_completed && this->pending_batches == 0 && + this->wrapped_call != NULL) { grpc_call_destroy(this->wrapped_call); this->wrapped_call = NULL; } @@ -721,7 +725,7 @@ NAN_METHOD(Call::StartBatch) { Callback *callback = new Callback(callback_func); grpc_call_error error = grpc_call_start_batch( call->wrapped_call, &ops[0], nops, new struct tag( - callback, op_vector.release(), call), NULL); + callback, op_vector.release(), call, info.This()), NULL); if (error != GRPC_CALL_OK) { return Nan::ThrowError(nanErrorWithCode("startBatch failed", error)); } diff --git a/src/node/ext/call.h b/src/node/ext/call.h index cffff00fce4..cceec9c45b5 100644 --- a/src/node/ext/call.h +++ b/src/node/ext/call.h @@ -109,11 +109,14 @@ class Op { typedef std::vector> OpVec; struct tag { - tag(Nan::Callback *callback, OpVec *ops, Call *call); + tag(Nan::Callback *callback, OpVec *ops, Call *call, + v8::Local call_value); ~tag(); Nan::Callback *callback; OpVec *ops; Call *call; + Nan::Persistent> + call_persist; }; v8::Local GetTagNodeValue(void *tag); diff --git a/src/node/ext/channel.cc b/src/node/ext/channel.cc index c795ff7f42f..1263cc0d286 100644 --- a/src/node/ext/channel.cc +++ b/src/node/ext/channel.cc @@ -280,7 +280,7 @@ NAN_METHOD(Channel::WatchConnectivityState) { channel->wrapped_channel, last_state, MillisecondsToTimespec(deadline), GetCompletionQueue(), new struct tag(callback, - ops.release(), NULL)); + ops.release(), NULL, Nan::Null())); CompletionQueueNext(); } diff --git a/src/node/ext/server.cc b/src/node/ext/server.cc index ccb55aa54cf..f0920c842a3 100644 --- a/src/node/ext/server.cc +++ b/src/node/ext/server.cc @@ -193,7 +193,7 @@ NAN_METHOD(Server::RequestCall) { GetCompletionQueue(), GetCompletionQueue(), new struct tag(new Callback(info[0].As()), ops.release(), - NULL)); + NULL, Nan::Null())); if (error != GRPC_CALL_OK) { return Nan::ThrowError(nanErrorWithCode("requestCall failed", error)); } @@ -246,7 +246,7 @@ NAN_METHOD(Server::TryShutdown) { grpc_server_shutdown_and_notify( server->wrapped_server, GetCompletionQueue(), new struct tag(new Nan::Callback(info[0].As()), ops.release(), - NULL)); + NULL, Nan::Null())); CompletionQueueNext(); } diff --git a/src/node/ext/server_uv.cc b/src/node/ext/server_uv.cc index c5e5ca9f42d..82e7589fc87 100644 --- a/src/node/ext/server_uv.cc +++ b/src/node/ext/server_uv.cc @@ -118,7 +118,8 @@ void Server::ShutdownServer() { grpc_server_shutdown_and_notify( this->wrapped_server, GetCompletionQueue(), - new struct tag(new Callback(**shutdown_callback), ops.release(), NULL)); + new struct tag(new Callback(**shutdown_callback), ops.release(), NULL, + Nan::Null())); grpc_server_cancel_all_calls(this->wrapped_server); CompletionQueueNext(); this->wrapped_server = NULL; From 94736b9d67733b3a86ae1f405c5edcd385edcb5f Mon Sep 17 00:00:00 2001 From: Craig Tiller Date: Tue, 4 Apr 2017 15:30:56 -0700 Subject: [PATCH 057/127] Add encode path --- .../chttp2/transport/hpack_encoder.c | 85 +++++++++++++------ 1 file changed, 57 insertions(+), 28 deletions(-) diff --git a/src/core/ext/transport/chttp2/transport/hpack_encoder.c b/src/core/ext/transport/chttp2/transport/hpack_encoder.c index f5f52a33608..b1bc677a7a4 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 From c5548cce42f8c4783c3c0368ea3ce00a196ff944 Mon Sep 17 00:00:00 2001 From: Craig Tiller Date: Tue, 4 Apr 2017 16:05:23 -0700 Subject: [PATCH 058/127] Add parsing for true-binary metadata --- .../transport/chttp2/transport/hpack_parser.c | 26 ++++++++++++------- 1 file changed, 17 insertions(+), 9 deletions(-) diff --git a/src/core/ext/transport/chttp2/transport/hpack_parser.c b/src/core/ext/transport/chttp2/transport/hpack_parser.c index 5099d736bf4..1846a85fc65 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( From e76a0ecc034c135d271bac7a8fa082fbe0b80243 Mon Sep 17 00:00:00 2001 From: Craig Tiller Date: Tue, 4 Apr 2017 16:24:20 -0700 Subject: [PATCH 059/127] Update hpack benchmarks for true binary --- test/cpp/microbenchmarks/bm_chttp2_hpack.cc | 143 ++++++++++++++------ 1 file changed, 101 insertions(+), 42 deletions(-) diff --git a/test/cpp/microbenchmarks/bm_chttp2_hpack.cc b/test/cpp/microbenchmarks/bm_chttp2_hpack.cc index 7426407874b..5489eb99739 100644 --- a/test/cpp/microbenchmarks/bm_chttp2_hpack.cc +++ b/test/cpp/microbenchmarks/bm_chttp2_hpack.cc @@ -93,7 +93,7 @@ static void BM_HpackEncoderEncodeHeader(benchmark::State &state) { grpc_encode_header_options hopt = { static_cast(state.iterations()), state.range(0) != 0, - false, + Fixture::kEnableTrueBinary, (size_t)state.range(1), &stats, }; @@ -127,6 +127,7 @@ namespace hpack_encoder_fixtures { class EmptyBatch { public: + static constexpr bool kEnableTrueBinary = false; static std::vector GetElems(grpc_exec_ctx *exec_ctx) { return {}; } @@ -134,6 +135,7 @@ class EmptyBatch { class SingleStaticElem { public: + static constexpr bool kEnableTrueBinary = false; static std::vector GetElems(grpc_exec_ctx *exec_ctx) { return {GRPC_MDELEM_GRPC_ACCEPT_ENCODING_IDENTITY_COMMA_DEFLATE}; } @@ -141,6 +143,7 @@ class SingleStaticElem { class SingleInternedElem { public: + static constexpr bool kEnableTrueBinary = false; static std::vector GetElems(grpc_exec_ctx *exec_ctx) { return {grpc_mdelem_from_slices( exec_ctx, grpc_slice_intern(grpc_slice_from_static_string("abc")), @@ -148,9 +151,10 @@ class SingleInternedElem { } }; -template +template class SingleInternedBinaryElem { public: + static constexpr bool kEnableTrueBinary = kTrueBinary; static std::vector GetElems(grpc_exec_ctx *exec_ctx) { grpc_slice bytes = MakeBytes(); std::vector out = {grpc_mdelem_from_slices( @@ -172,6 +176,7 @@ class SingleInternedBinaryElem { class SingleInternedKeyElem { public: + static constexpr bool kEnableTrueBinary = false; static std::vector GetElems(grpc_exec_ctx *exec_ctx) { return {grpc_mdelem_from_slices( exec_ctx, grpc_slice_intern(grpc_slice_from_static_string("abc")), @@ -181,6 +186,7 @@ class SingleInternedKeyElem { class SingleNonInternedElem { public: + static constexpr bool kEnableTrueBinary = false; static std::vector GetElems(grpc_exec_ctx *exec_ctx) { return {grpc_mdelem_from_slices(exec_ctx, grpc_slice_from_static_string("abc"), @@ -188,9 +194,10 @@ class SingleNonInternedElem { } }; -template +template class SingleNonInternedBinaryElem { public: + static constexpr bool kEnableTrueBinary = kTrueBinary; static std::vector GetElems(grpc_exec_ctx *exec_ctx) { return {grpc_mdelem_from_slices( exec_ctx, grpc_slice_from_static_string("abc-bin"), MakeBytes())}; @@ -208,6 +215,7 @@ class SingleNonInternedBinaryElem { class RepresentativeClientInitialMetadata { public: + static constexpr bool kEnableTrueBinary = true; static std::vector GetElems(grpc_exec_ctx *exec_ctx) { return { GRPC_MDELEM_SCHEME_HTTP, GRPC_MDELEM_METHOD_POST, @@ -229,6 +237,7 @@ class RepresentativeClientInitialMetadata { class RepresentativeServerInitialMetadata { public: + static constexpr bool kEnableTrueBinary = true; static std::vector GetElems(grpc_exec_ctx *exec_ctx) { return {GRPC_MDELEM_STATUS_200, GRPC_MDELEM_CONTENT_TYPE_APPLICATION_SLASH_GRPC, @@ -238,6 +247,7 @@ class RepresentativeServerInitialMetadata { class RepresentativeServerTrailingMetadata { public: + static constexpr bool kEnableTrueBinary = true; static std::vector GetElems(grpc_exec_ctx *exec_ctx) { return {GRPC_MDELEM_GRPC_STATUS_0}; } @@ -252,28 +262,67 @@ BENCHMARK_TEMPLATE(BM_HpackEncoderEncodeHeader, SingleInternedKeyElem) ->Args({0, 16384}); BENCHMARK_TEMPLATE(BM_HpackEncoderEncodeHeader, SingleInternedElem) ->Args({0, 16384}); -BENCHMARK_TEMPLATE(BM_HpackEncoderEncodeHeader, SingleInternedBinaryElem<1>) +BENCHMARK_TEMPLATE(BM_HpackEncoderEncodeHeader, + SingleInternedBinaryElem<1, false>) + ->Args({0, 16384}); +BENCHMARK_TEMPLATE(BM_HpackEncoderEncodeHeader, + SingleInternedBinaryElem<3, false>) + ->Args({0, 16384}); +BENCHMARK_TEMPLATE(BM_HpackEncoderEncodeHeader, + SingleInternedBinaryElem<10, false>) + ->Args({0, 16384}); +BENCHMARK_TEMPLATE(BM_HpackEncoderEncodeHeader, + SingleInternedBinaryElem<31, false>) + ->Args({0, 16384}); +BENCHMARK_TEMPLATE(BM_HpackEncoderEncodeHeader, + SingleInternedBinaryElem<100, false>) + ->Args({0, 16384}); +BENCHMARK_TEMPLATE(BM_HpackEncoderEncodeHeader, + SingleInternedBinaryElem<1, true>) ->Args({0, 16384}); -BENCHMARK_TEMPLATE(BM_HpackEncoderEncodeHeader, SingleInternedBinaryElem<3>) +BENCHMARK_TEMPLATE(BM_HpackEncoderEncodeHeader, + SingleInternedBinaryElem<3, true>) ->Args({0, 16384}); -BENCHMARK_TEMPLATE(BM_HpackEncoderEncodeHeader, SingleInternedBinaryElem<10>) +BENCHMARK_TEMPLATE(BM_HpackEncoderEncodeHeader, + SingleInternedBinaryElem<10, true>) ->Args({0, 16384}); -BENCHMARK_TEMPLATE(BM_HpackEncoderEncodeHeader, SingleInternedBinaryElem<31>) +BENCHMARK_TEMPLATE(BM_HpackEncoderEncodeHeader, + SingleInternedBinaryElem<31, true>) ->Args({0, 16384}); -BENCHMARK_TEMPLATE(BM_HpackEncoderEncodeHeader, SingleInternedBinaryElem<100>) +BENCHMARK_TEMPLATE(BM_HpackEncoderEncodeHeader, + SingleInternedBinaryElem<100, true>) ->Args({0, 16384}); BENCHMARK_TEMPLATE(BM_HpackEncoderEncodeHeader, SingleNonInternedElem) ->Args({0, 16384}); -BENCHMARK_TEMPLATE(BM_HpackEncoderEncodeHeader, SingleNonInternedBinaryElem<1>) +BENCHMARK_TEMPLATE(BM_HpackEncoderEncodeHeader, + SingleNonInternedBinaryElem<1, false>) + ->Args({0, 16384}); +BENCHMARK_TEMPLATE(BM_HpackEncoderEncodeHeader, + SingleNonInternedBinaryElem<3, false>) ->Args({0, 16384}); -BENCHMARK_TEMPLATE(BM_HpackEncoderEncodeHeader, SingleNonInternedBinaryElem<3>) +BENCHMARK_TEMPLATE(BM_HpackEncoderEncodeHeader, + SingleNonInternedBinaryElem<10, false>) ->Args({0, 16384}); -BENCHMARK_TEMPLATE(BM_HpackEncoderEncodeHeader, SingleNonInternedBinaryElem<10>) +BENCHMARK_TEMPLATE(BM_HpackEncoderEncodeHeader, + SingleNonInternedBinaryElem<31, false>) ->Args({0, 16384}); -BENCHMARK_TEMPLATE(BM_HpackEncoderEncodeHeader, SingleNonInternedBinaryElem<31>) +BENCHMARK_TEMPLATE(BM_HpackEncoderEncodeHeader, + SingleNonInternedBinaryElem<100, false>) ->Args({0, 16384}); BENCHMARK_TEMPLATE(BM_HpackEncoderEncodeHeader, - SingleNonInternedBinaryElem<100>) + SingleNonInternedBinaryElem<1, true>) + ->Args({0, 16384}); +BENCHMARK_TEMPLATE(BM_HpackEncoderEncodeHeader, + SingleNonInternedBinaryElem<3, true>) + ->Args({0, 16384}); +BENCHMARK_TEMPLATE(BM_HpackEncoderEncodeHeader, + SingleNonInternedBinaryElem<10, true>) + ->Args({0, 16384}); +BENCHMARK_TEMPLATE(BM_HpackEncoderEncodeHeader, + SingleNonInternedBinaryElem<31, true>) + ->Args({0, 16384}); +BENCHMARK_TEMPLATE(BM_HpackEncoderEncodeHeader, + SingleNonInternedBinaryElem<100, true>) ->Args({0, 16384}); // test with a tiny frame size, to highlight continuation costs BENCHMARK_TEMPLATE(BM_HpackEncoderEncodeHeader, SingleNonInternedElem) @@ -426,7 +475,27 @@ class NonIndexedElem { } }; -class NonIndexedBinaryElem1 { +template +class NonIndexedBinaryElem; + +template +class NonIndexedBinaryElem { + public: + static std::vector GetInitSlices() { return {}; } + static std::vector GetBenchmarkSlices() { + std::vector v = { + 0x00, 0x07, 'a', 'b', 'c', + '-', 'b', 'i', 'n', static_cast(kLength + 1), + 0}; + for (int i = 0; i < kLength; i++) { + v.push_back(static_cast(i)); + } + return {MakeSlice(v)}; + } +}; + +template <> +class NonIndexedBinaryElem<1, false> { public: static std::vector GetInitSlices() { return {}; } static std::vector GetBenchmarkSlices() { @@ -435,7 +504,8 @@ class NonIndexedBinaryElem1 { } }; -class NonIndexedBinaryElem3 { +template <> +class NonIndexedBinaryElem<3, false> { public: static std::vector GetInitSlices() { return {}; } static std::vector GetBenchmarkSlices() { @@ -444,7 +514,8 @@ class NonIndexedBinaryElem3 { } }; -class NonIndexedBinaryElem10 { +template <> +class NonIndexedBinaryElem<10, false> { public: static std::vector GetInitSlices() { return {}; } static std::vector GetBenchmarkSlices() { @@ -454,7 +525,8 @@ class NonIndexedBinaryElem10 { } }; -class NonIndexedBinaryElem31 { +template <> +class NonIndexedBinaryElem<31, false> { public: static std::vector GetInitSlices() { return {}; } static std::vector GetBenchmarkSlices() { @@ -466,7 +538,8 @@ class NonIndexedBinaryElem31 { } }; -class NonIndexedBinaryElem100 { +template <> +class NonIndexedBinaryElem<100, false> { public: static std::vector GetInitSlices() { return {}; } static std::vector GetBenchmarkSlices() { @@ -575,11 +648,16 @@ BENCHMARK_TEMPLATE(BM_HpackParserParseHeader, IndexedSingleInternedElem); BENCHMARK_TEMPLATE(BM_HpackParserParseHeader, AddIndexedSingleInternedElem); BENCHMARK_TEMPLATE(BM_HpackParserParseHeader, KeyIndexedSingleInternedElem); BENCHMARK_TEMPLATE(BM_HpackParserParseHeader, NonIndexedElem); -BENCHMARK_TEMPLATE(BM_HpackParserParseHeader, NonIndexedBinaryElem1); -BENCHMARK_TEMPLATE(BM_HpackParserParseHeader, NonIndexedBinaryElem3); -BENCHMARK_TEMPLATE(BM_HpackParserParseHeader, NonIndexedBinaryElem10); -BENCHMARK_TEMPLATE(BM_HpackParserParseHeader, NonIndexedBinaryElem31); -BENCHMARK_TEMPLATE(BM_HpackParserParseHeader, NonIndexedBinaryElem100); +BENCHMARK_TEMPLATE(BM_HpackParserParseHeader, NonIndexedBinaryElem<1, false>); +BENCHMARK_TEMPLATE(BM_HpackParserParseHeader, NonIndexedBinaryElem<3, false>); +BENCHMARK_TEMPLATE(BM_HpackParserParseHeader, NonIndexedBinaryElem<10, false>); +BENCHMARK_TEMPLATE(BM_HpackParserParseHeader, NonIndexedBinaryElem<31, false>); +BENCHMARK_TEMPLATE(BM_HpackParserParseHeader, NonIndexedBinaryElem<100, false>); +BENCHMARK_TEMPLATE(BM_HpackParserParseHeader, NonIndexedBinaryElem<1, true>); +BENCHMARK_TEMPLATE(BM_HpackParserParseHeader, NonIndexedBinaryElem<3, true>); +BENCHMARK_TEMPLATE(BM_HpackParserParseHeader, NonIndexedBinaryElem<10, true>); +BENCHMARK_TEMPLATE(BM_HpackParserParseHeader, NonIndexedBinaryElem<31, true>); +BENCHMARK_TEMPLATE(BM_HpackParserParseHeader, NonIndexedBinaryElem<100, true>); BENCHMARK_TEMPLATE(BM_HpackParserParseHeader, RepresentativeClientInitialMetadata); BENCHMARK_TEMPLATE(BM_HpackParserParseHeader, @@ -589,23 +667,4 @@ BENCHMARK_TEMPLATE(BM_HpackParserParseHeader, } // namespace hpack_parser_fixtures -static void BM_Base16SomeStuff(benchmark::State &state) { - uint8_t *bytes = new uint8_t[state.range(0)]; - for (int i = 0; i < state.range(0); i++) { - bytes[i] = static_cast(rand()); - } - uint8_t *encoded = new uint8_t[state.range(0) * 2]; - static const uint8_t hex[] = "0123456789abcdef"; - while (state.KeepRunning()) { - for (int i = 0; i < state.range(0); i++) { - encoded[2 * i + 0] = hex[encoded[i] >> 8]; - encoded[2 * i + 1] = hex[encoded[i] & 0xf]; - } - } - delete[] encoded; - delete[] bytes; - state.SetBytesProcessed(state.iterations() * state.range(0)); -} -BENCHMARK(BM_Base16SomeStuff)->Range(1, 4096); - BENCHMARK_MAIN(); From 2a4731e2eb24efce9fa6322630bdf19b953260d2 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Tue, 4 Apr 2017 17:14:40 -0700 Subject: [PATCH 060/127] 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(-) diff --git a/src/core/ext/transport/chttp2/transport/chttp2_transport.c b/src/core/ext/transport/chttp2/transport/chttp2_transport.c index 965306cbbe0..c90bf69d157 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 1fc01049118..a945639faea 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 8455e154ac1..57bbb98139d 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 4c1472bd4c3..99055454227 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); } } From 85a747ed06d4e2ce9c299439ea0923e0b9ccdd8d Mon Sep 17 00:00:00 2001 From: Craig Tiller Date: Tue, 4 Apr 2017 17:20:29 -0700 Subject: [PATCH 061/127] better representative output --- test/cpp/microbenchmarks/bm_chttp2_hpack.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/cpp/microbenchmarks/bm_chttp2_hpack.cc b/test/cpp/microbenchmarks/bm_chttp2_hpack.cc index 5489eb99739..581440682aa 100644 --- a/test/cpp/microbenchmarks/bm_chttp2_hpack.cc +++ b/test/cpp/microbenchmarks/bm_chttp2_hpack.cc @@ -98,7 +98,7 @@ static void BM_HpackEncoderEncodeHeader(benchmark::State &state) { &stats, }; grpc_chttp2_encode_header(&exec_ctx, &c, &b, &hopt, &outbuf); - if (!logged_representative_output) { + if (!logged_representative_output && state.iterations() > 3) { logged_representative_output = true; for (size_t i = 0; i < outbuf.count; i++) { char *s = grpc_dump_slice(outbuf.slices[i], GPR_DUMP_HEX); From 769b7c367d511e8f5e44c5e59c7bd06dc417cbca Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Tue, 4 Apr 2017 19:07:50 -0700 Subject: [PATCH 062/127] 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(-) diff --git a/src/core/ext/transport/chttp2/transport/chttp2_transport.c b/src/core/ext/transport/chttp2/transport/chttp2_transport.c index c90bf69d157..7aee014e633 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 99055454227..4c1472bd4c3 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); } } From 702bf3b2dca1c0829bc671d2d4c5737c52ef2f44 Mon Sep 17 00:00:00 2001 From: Craig Tiller Date: Wed, 5 Apr 2017 06:53:57 -0700 Subject: [PATCH 063/127] Remove bogus assert --- src/core/ext/transport/chttp2/transport/frame_settings.c | 1 - 1 file changed, 1 deletion(-) diff --git a/src/core/ext/transport/chttp2/transport/frame_settings.c b/src/core/ext/transport/chttp2/transport/frame_settings.c index 46630a6cc62..d53f51a1e84 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); From 7d55746bb3e8f177f7646222553bc0edd907686c Mon Sep 17 00:00:00 2001 From: Craig Tiller Date: Wed, 5 Apr 2017 07:57:16 -0700 Subject: [PATCH 064/127] Update BUILD --- BUILD | 2 ++ 1 file changed, 2 insertions(+) diff --git a/BUILD b/BUILD index c4632fc0a24..c164daeca1c 100644 --- a/BUILD +++ b/BUILD @@ -978,6 +978,7 @@ grpc_cc_library( "src/core/ext/transport/chttp2/transport/frame_ping.c", "src/core/ext/transport/chttp2/transport/frame_rst_stream.c", "src/core/ext/transport/chttp2/transport/frame_settings.c", + "src/core/ext/transport/chttp2/transport/http2_settings.c", "src/core/ext/transport/chttp2/transport/frame_window_update.c", "src/core/ext/transport/chttp2/transport/hpack_encoder.c", "src/core/ext/transport/chttp2/transport/hpack_parser.c", @@ -1000,6 +1001,7 @@ grpc_cc_library( "src/core/ext/transport/chttp2/transport/frame_ping.h", "src/core/ext/transport/chttp2/transport/frame_rst_stream.h", "src/core/ext/transport/chttp2/transport/frame_settings.h", + "src/core/ext/transport/chttp2/transport/http2_settings.h", "src/core/ext/transport/chttp2/transport/frame_window_update.h", "src/core/ext/transport/chttp2/transport/hpack_encoder.h", "src/core/ext/transport/chttp2/transport/hpack_parser.h", From 3d13d7e162f39c24d7bdd915981ebb74154bc91e Mon Sep 17 00:00:00 2001 From: Craig Tiller Date: Wed, 5 Apr 2017 08:02:42 -0700 Subject: [PATCH 065/127] 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(-) diff --git a/src/core/ext/transport/chttp2/transport/http2_settings.c b/src/core/ext/transport/chttp2/transport/http2_settings.c index 05f0d8cb468..52969e6b4a8 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 393c14f7f1b..61048a64783 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 54498a18f25..4253396ead4 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) From bcf9d9f4632e54526b34d44b6b9838bf9626c66a Mon Sep 17 00:00:00 2001 From: Craig Tiller Date: Wed, 5 Apr 2017 08:03:07 -0700 Subject: [PATCH 066/127] Remove old code --- src/core/ext/transport/chttp2/transport/frame_settings.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/core/ext/transport/chttp2/transport/frame_settings.c b/src/core/ext/transport/chttp2/transport/frame_settings.c index d53f51a1e84..4f2b8278326 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); From dd2f706b8b9672f31ee40f678afea54c7bab899d Mon Sep 17 00:00:00 2001 From: Craig Tiller Date: Wed, 5 Apr 2017 08:11:44 -0700 Subject: [PATCH 067/127] Generate slightly more efficient code --- .../chttp2/transport/http2_settings.c | 19 ++++----------- tools/codegen/core/gen_settings_ids.py | 24 +++++++++++-------- 2 files changed, 18 insertions(+), 25 deletions(-) diff --git a/src/core/ext/transport/chttp2/transport/http2_settings.c b/src/core/ext/transport/chttp2/transport/http2_settings.c index 52969e6b4a8..bca3834b55f 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 4253396ead4..cfc2c5d0a40 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 { From 9702e92d09465d34fecc1ca07cae75f2686f1c32 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Wed, 5 Apr 2017 13:37:59 -0700 Subject: [PATCH 068/127] Asan fix --- src/core/ext/transport/chttp2/transport/chttp2_transport.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/core/ext/transport/chttp2/transport/chttp2_transport.c b/src/core/ext/transport/chttp2/transport/chttp2_transport.c index 7aee014e633..b59f02b9b68 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); } } From bee6a33c5c1c33548406849f9b52f9ddcce13d27 Mon Sep 17 00:00:00 2001 From: Craig Tiller Date: Wed, 5 Apr 2017 14:46:56 -0700 Subject: [PATCH 069/127] 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(-) diff --git a/src/core/ext/transport/chttp2/transport/http2_settings.h b/src/core/ext/transport/chttp2/transport/http2_settings.h index 61048a64783..9781cdc9893 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 cfc2c5d0a40..29c67956c70 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() From 512b6371f4c188cbc061ec7544d0ca3ac8941b18 Mon Sep 17 00:00:00 2001 From: yang-g Date: Wed, 5 Apr 2017 22:29:04 -0700 Subject: [PATCH 070/127] Unref the tail, not the original slice --- src/core/lib/security/transport/security_handshaker.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/src/core/lib/security/transport/security_handshaker.c b/src/core/lib/security/transport/security_handshaker.c index 7065d261ba2..e65368c8f84 100644 --- a/src/core/lib/security/transport/security_handshaker.c +++ b/src/core/lib/security/transport/security_handshaker.c @@ -285,12 +285,11 @@ static void on_handshake_data_received_from_peer(grpc_exec_ctx *exec_ctx, if (num_left_overs > 0) { /* Put the leftovers in our buffer (ownership transfered). */ if (has_left_overs_in_current_slice) { - grpc_slice_buffer_add( - &h->left_overs, - grpc_slice_split_tail(&h->args->read_buffer->slices[i], - consumed_slice_size)); + grpc_slice tail = grpc_slice_split_tail(&h->args->read_buffer->slices[i], + consumed_slice_size); + grpc_slice_buffer_add(&h->left_overs, tail); /* split_tail above increments refcount. */ - grpc_slice_unref_internal(exec_ctx, h->args->read_buffer->slices[i]); + grpc_slice_unref_internal(exec_ctx, tail); } grpc_slice_buffer_addn( &h->left_overs, &h->args->read_buffer->slices[i + 1], From 77e06b2f8617f190fbd14e47238ce8d304118d2c Mon Sep 17 00:00:00 2001 From: murgatroid99 Date: Thu, 6 Apr 2017 10:37:44 -0700 Subject: [PATCH 071/127] Node: fix leak of sent metadata --- src/node/ext/call.cc | 48 +++++++++++++++++++++++--------- src/node/ext/call.h | 2 ++ src/node/ext/call_credentials.cc | 2 ++ 3 files changed, 39 insertions(+), 13 deletions(-) diff --git a/src/node/ext/call.cc b/src/node/ext/call.cc index 5c311158542..c77d6a3379b 100644 --- a/src/node/ext/call.cc +++ b/src/node/ext/call.cc @@ -99,7 +99,6 @@ Local nanErrorWithCode(const char *msg, grpc_call_error code) { bool CreateMetadataArray(Local metadata, grpc_metadata_array *array) { HandleScope scope; - grpc_metadata_array_init(array); Local keys = Nan::GetOwnPropertyNames(metadata).ToLocalChecked(); for (unsigned int i = 0; i < keys->Length(); i++) { Local current_key = Nan::To( @@ -111,18 +110,20 @@ bool CreateMetadataArray(Local metadata, grpc_metadata_array *array) { array->capacity += Local::Cast(value_array)->Length(); } array->metadata = reinterpret_cast( - gpr_malloc(array->capacity * sizeof(grpc_metadata))); + gpr_zalloc(array->capacity * sizeof(grpc_metadata))); for (unsigned int i = 0; i < keys->Length(); i++) { Local current_key(Nan::To(keys->Get(i)).ToLocalChecked()); Local values = Local::Cast( Nan::Get(metadata, current_key).ToLocalChecked()); - grpc_slice key_slice = grpc_slice_intern(CreateSliceFromString(current_key)); + grpc_slice key_slice = CreateSliceFromString(current_key); + grpc_slice key_intern_slice = grpc_slice_intern(key_slice); + grpc_slice_unref(key_slice); for (unsigned int j = 0; j < values->Length(); j++) { Local value = Nan::Get(values, j).ToLocalChecked(); grpc_metadata *current = &array->metadata[array->count]; - current->key = key_slice; + current->key = key_intern_slice; // Only allow binary headers for "-bin" keys - if (grpc_is_binary_header(key_slice)) { + if (grpc_is_binary_header(key_intern_slice)) { if (::node::Buffer::HasInstance(value)) { current->value = CreateSliceFromBuffer(value); } else { @@ -142,6 +143,14 @@ bool CreateMetadataArray(Local metadata, grpc_metadata_array *array) { return true; } +void DestroyMetadataArray(grpc_metadata_array *array) { + for (size_t i = 0; i < array->count; i++) { + // Don't unref keys because they are interned + grpc_slice_unref(array->metadata[i].value); + } + grpc_metadata_array_destroy(array); +} + Local ParseMetadata(const grpc_metadata_array *metadata_array) { EscapableHandleScope scope; grpc_metadata *metadata_elements = metadata_array->metadata; @@ -179,6 +188,12 @@ Op::~Op() { class SendMetadataOp : public Op { public: + SendMetadataOp() { + grpc_metadata_array_init(&send_metadata); + } + ~SendMetadataOp() { + DestroyMetadataArray(&send_metadata); + } Local GetNodeValue() const { EscapableHandleScope scope; return scope.Escape(Nan::True()); @@ -187,17 +202,16 @@ class SendMetadataOp : public Op { if (!value->IsObject()) { return false; } - grpc_metadata_array array; MaybeLocal maybe_metadata = Nan::To(value); if (maybe_metadata.IsEmpty()) { return false; } if (!CreateMetadataArray(maybe_metadata.ToLocalChecked(), - &array)) { + &send_metadata)) { return false; } - out->data.send_initial_metadata.count = array.count; - out->data.send_initial_metadata.metadata = array.metadata; + out->data.send_initial_metadata.count = send_metadata.count; + out->data.send_initial_metadata.metadata = send_metadata.metadata; return true; } bool IsFinalOp() { @@ -207,6 +221,8 @@ class SendMetadataOp : public Op { std::string GetTypeString() const { return "send_metadata"; } + private: + grpc_metadata_array send_metadata; }; class SendMessageOp : public Op { @@ -272,8 +288,12 @@ class SendClientCloseOp : public Op { class SendServerStatusOp : public Op { public: + SendServerStatusOp() { + grpc_metadata_array_init(&status_metadata); + } ~SendServerStatusOp() { grpc_slice_unref(details); + DestroyMetadataArray(&status_metadata); } Local GetNodeValue() const { EscapableHandleScope scope; @@ -313,12 +333,13 @@ class SendServerStatusOp : public Op { } Local details = Nan::To( maybe_details.ToLocalChecked()).ToLocalChecked(); - grpc_metadata_array array; - if (!CreateMetadataArray(metadata, &array)) { + if (!CreateMetadataArray(metadata, &status_metadata)) { return false; } - out->data.send_status_from_server.trailing_metadata_count = array.count; - out->data.send_status_from_server.trailing_metadata = array.metadata; + out->data.send_status_from_server.trailing_metadata_count = + status_metadata.count; + out->data.send_status_from_server.trailing_metadata = + status_metadata.metadata; out->data.send_status_from_server.status = static_cast(code); this->details = CreateSliceFromString(details); @@ -335,6 +356,7 @@ class SendServerStatusOp : public Op { private: grpc_slice details; + grpc_metadata_array status_metadata; }; class GetMetadataOp : public Op { diff --git a/src/node/ext/call.h b/src/node/ext/call.h index cffff00fce4..fe2abab9ee3 100644 --- a/src/node/ext/call.h +++ b/src/node/ext/call.h @@ -58,6 +58,8 @@ v8::Local ParseMetadata(const grpc_metadata_array *metadata_array); bool CreateMetadataArray(v8::Local metadata, grpc_metadata_array *array); +void DestroyMetadataArray(grpc_metadata_array *array); + /* Wrapper class for grpc_call structs. */ class Call : public Nan::ObjectWrap { public: diff --git a/src/node/ext/call_credentials.cc b/src/node/ext/call_credentials.cc index afcc363131e..5bd4bdcd5ab 100644 --- a/src/node/ext/call_credentials.cc +++ b/src/node/ext/call_credentials.cc @@ -211,6 +211,7 @@ NAN_METHOD(PluginCallback) { Utf8String details_utf8_str(info[1]); char *details = *details_utf8_str; grpc_metadata_array array; + grpc_metadata_array_init(&array); Local callback_data = Nan::To(info[3]).ToLocalChecked(); if (!CreateMetadataArray(Nan::To(info[2]).ToLocalChecked(), &array)){ @@ -226,6 +227,7 @@ NAN_METHOD(PluginCallback) { Nan::New("user_data").ToLocalChecked() ).ToLocalChecked().As()->Value(); cb(user_data, array.metadata, array.count, code, details); + DestroyMetadataArray(&array); } NAUV_WORK_CB(SendPluginCallback) { From 2a4ea2daafaf9a79f749d1fef1a6a5970613b9fb Mon Sep 17 00:00:00 2001 From: murgatroid99 Date: Thu, 6 Apr 2017 13:54:37 -0700 Subject: [PATCH 072/127] Node: consolidate call destruction logic --- src/node/ext/call.cc | 18 ++++++++++-------- src/node/ext/call.h | 2 ++ 2 files changed, 12 insertions(+), 8 deletions(-) diff --git a/src/node/ext/call.cc b/src/node/ext/call.cc index 62f0130d537..769f744b862 100644 --- a/src/node/ext/call.cc +++ b/src/node/ext/call.cc @@ -515,16 +515,20 @@ void DestroyTag(void *tag) { delete tag_struct; } +void Call::DestroyCall() { + if (this->wrapped_call != NULL) { + grpc_call_destroy(this->wrapped_call); + this->wrapped_call = NULL; + } +} + Call::Call(grpc_call *call) : wrapped_call(call), pending_batches(0), has_final_op_completed(false) { } Call::~Call() { - if (wrapped_call != NULL) { - grpc_call_destroy(wrapped_call); - wrapped_call = NULL; - } + DestroyCall(); } void Call::Init(Local exports) { @@ -570,10 +574,8 @@ void Call::CompleteBatch(bool is_final_op) { this->has_final_op_completed = true; } this->pending_batches--; - if (this->has_final_op_completed && this->pending_batches == 0 && - this->wrapped_call != NULL) { - grpc_call_destroy(this->wrapped_call); - this->wrapped_call = NULL; + if (this->has_final_op_completed && this->pending_batches == 0) { + this->DestroyCall(); } } diff --git a/src/node/ext/call.h b/src/node/ext/call.h index cceec9c45b5..7fd03ca1de3 100644 --- a/src/node/ext/call.h +++ b/src/node/ext/call.h @@ -76,6 +76,8 @@ class Call : public Nan::ObjectWrap { Call(const Call &); Call &operator=(const Call &); + void DestroyCall(); + static NAN_METHOD(New); static NAN_METHOD(StartBatch); static NAN_METHOD(Cancel); From 95b5ce0ddc02606dd7118f1e43c77790946a5a6d Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Thu, 6 Apr 2017 13:56:52 -0700 Subject: [PATCH 073/127] Python bug fix --- src/core/ext/transport/chttp2/transport/chttp2_transport.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/core/ext/transport/chttp2/transport/chttp2_transport.c b/src/core/ext/transport/chttp2/transport/chttp2_transport.c index b59f02b9b68..43349beb29d 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); From 3ac309eb6f511ac1194397fa82b5cec134344c3e Mon Sep 17 00:00:00 2001 From: murgatroid99 Date: Thu, 6 Apr 2017 16:10:41 -0700 Subject: [PATCH 074/127] Node: fix hang after DNS resolution failure --- src/core/lib/iomgr/resolve_address_uv.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/core/lib/iomgr/resolve_address_uv.c b/src/core/lib/iomgr/resolve_address_uv.c index 4d715be94c7..0a0bf5f8da1 100644 --- a/src/core/lib/iomgr/resolve_address_uv.c +++ b/src/core/lib/iomgr/resolve_address_uv.c @@ -69,8 +69,9 @@ static int retry_named_port_failure(int status, request *r, int retry_status; uv_getaddrinfo_t *req = gpr_malloc(sizeof(uv_getaddrinfo_t)); req->data = r; + r->port = svc[i][1]; retry_status = uv_getaddrinfo(uv_default_loop(), req, getaddrinfo_cb, - r->host, svc[i][1], r->hints); + r->host, r->port, r->hints); if (retry_status < 0 || getaddrinfo_cb == NULL) { // The callback will not be called gpr_free(req); From 50da9d83b6420c8028b11903232db144a4eabf23 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Thu, 6 Apr 2017 18:18:00 -0700 Subject: [PATCH 075/127] Fix python bug --- .../ext/transport/chttp2/transport/chttp2_transport.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/src/core/ext/transport/chttp2/transport/chttp2_transport.c b/src/core/ext/transport/chttp2/transport/chttp2_transport.c index 43349beb29d..ca95d8289ad 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, From 97a0ded7c59a123dfe2be0d2a4e0e27b58754a1b Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Fri, 7 Apr 2017 00:34:19 -0700 Subject: [PATCH 076/127] Fix bm_chttp2_transport --- test/cpp/microbenchmarks/bm_chttp2_transport.cc | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/test/cpp/microbenchmarks/bm_chttp2_transport.cc b/test/cpp/microbenchmarks/bm_chttp2_transport.cc index 16112508500..d3ca27a68e5 100644 --- a/test/cpp/microbenchmarks/bm_chttp2_transport.cc +++ b/test/cpp/microbenchmarks/bm_chttp2_transport.cc @@ -572,11 +572,13 @@ static void BM_TransportStreamRecv(benchmark::State &state) { } while (grpc_byte_stream_next(exec_ctx, recv_stream, recv_stream->length - received, drain_continue.get()) && - GRPC_ERROR_NONE == grpc_byte_stream_pull(exec_ctx, recv_stream, - &recv_slice)); + GRPC_ERROR_NONE == + grpc_byte_stream_pull(exec_ctx, recv_stream, &recv_slice) && + (received += GRPC_SLICE_LENGTH(recv_slice), true)); }); 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); From e27f061fa91cc57c6d4f0620b63cdbac83afeead Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Fri, 7 Apr 2017 00:37:04 -0700 Subject: [PATCH 077/127] Unban --- src/core/ext/transport/chttp2/transport/chttp2_transport.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core/ext/transport/chttp2/transport/chttp2_transport.c b/src/core/ext/transport/chttp2/transport/chttp2_transport.c index ca95d8289ad..ed3f5e61925 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); From 9c9e00958d1f5a09ec4ad80fb176fe6f48367639 Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Thu, 9 Mar 2017 10:15:41 +0100 Subject: [PATCH 078/127] Add newest dotnet SDK to C# dockerfile --- templates/tools/dockerfile/csharp_dotnetcli_deps.include | 8 ++++++-- .../interoptest/grpc_interop_csharpcoreclr/Dockerfile | 8 ++++++-- tools/dockerfile/test/csharp_coreclr_x64/Dockerfile | 8 ++++++-- 3 files changed, 18 insertions(+), 6 deletions(-) diff --git a/templates/tools/dockerfile/csharp_dotnetcli_deps.include b/templates/tools/dockerfile/csharp_dotnetcli_deps.include index 430f3fa3f22..058ce15fb52 100644 --- a/templates/tools/dockerfile/csharp_dotnetcli_deps.include +++ b/templates/tools/dockerfile/csharp_dotnetcli_deps.include @@ -1,7 +1,11 @@ # Install dotnet SDK based on https://www.microsoft.com/net/core#debian RUN apt-get update && apt-get install -y curl libunwind8 gettext -RUN curl -sSL -o dotnet.tar.gz https://go.microsoft.com/fwlink/?LinkID=809130 -RUN mkdir -p /opt/dotnet && tar zxf dotnet.tar.gz -C /opt/dotnet +# dotnet-dev-1.0.0-preview2-003121 +RUN curl -sSL -o dotnet100.tar.gz https://go.microsoft.com/fwlink/?LinkID=809130 +RUN mkdir -p /opt/dotnet && tar zxf dotnet100.tar.gz -C /opt/dotnet +# dotnet-dev-1.0.1 +RUN curl -sSL -o dotnet101.tar.gz https://go.microsoft.com/fwlink/?LinkID=843453 +RUN mkdir -p /opt/dotnet && tar zxf dotnet101.tar.gz -C /opt/dotnet RUN ln -s /opt/dotnet/dotnet /usr/local/bin # Trigger the population of the local package cache diff --git a/tools/dockerfile/interoptest/grpc_interop_csharpcoreclr/Dockerfile b/tools/dockerfile/interoptest/grpc_interop_csharpcoreclr/Dockerfile index 91639829dcd..c26c9a2826e 100644 --- a/tools/dockerfile/interoptest/grpc_interop_csharpcoreclr/Dockerfile +++ b/tools/dockerfile/interoptest/grpc_interop_csharpcoreclr/Dockerfile @@ -99,8 +99,12 @@ RUN nuget update -self # Install dotnet SDK based on https://www.microsoft.com/net/core#debian RUN apt-get update && apt-get install -y curl libunwind8 gettext -RUN curl -sSL -o dotnet.tar.gz https://go.microsoft.com/fwlink/?LinkID=809130 -RUN mkdir -p /opt/dotnet && tar zxf dotnet.tar.gz -C /opt/dotnet +# dotnet-dev-1.0.0-preview2-003121 +RUN curl -sSL -o dotnet100.tar.gz https://go.microsoft.com/fwlink/?LinkID=809130 +RUN mkdir -p /opt/dotnet && tar zxf dotnet100.tar.gz -C /opt/dotnet +# dotnet-dev-1.0.1 +RUN curl -sSL -o dotnet101.tar.gz https://go.microsoft.com/fwlink/?LinkID=843453 +RUN mkdir -p /opt/dotnet && tar zxf dotnet101.tar.gz -C /opt/dotnet RUN ln -s /opt/dotnet/dotnet /usr/local/bin # Trigger the population of the local package cache diff --git a/tools/dockerfile/test/csharp_coreclr_x64/Dockerfile b/tools/dockerfile/test/csharp_coreclr_x64/Dockerfile index 91639829dcd..c26c9a2826e 100644 --- a/tools/dockerfile/test/csharp_coreclr_x64/Dockerfile +++ b/tools/dockerfile/test/csharp_coreclr_x64/Dockerfile @@ -99,8 +99,12 @@ RUN nuget update -self # Install dotnet SDK based on https://www.microsoft.com/net/core#debian RUN apt-get update && apt-get install -y curl libunwind8 gettext -RUN curl -sSL -o dotnet.tar.gz https://go.microsoft.com/fwlink/?LinkID=809130 -RUN mkdir -p /opt/dotnet && tar zxf dotnet.tar.gz -C /opt/dotnet +# dotnet-dev-1.0.0-preview2-003121 +RUN curl -sSL -o dotnet100.tar.gz https://go.microsoft.com/fwlink/?LinkID=809130 +RUN mkdir -p /opt/dotnet && tar zxf dotnet100.tar.gz -C /opt/dotnet +# dotnet-dev-1.0.1 +RUN curl -sSL -o dotnet101.tar.gz https://go.microsoft.com/fwlink/?LinkID=843453 +RUN mkdir -p /opt/dotnet && tar zxf dotnet101.tar.gz -C /opt/dotnet RUN ln -s /opt/dotnet/dotnet /usr/local/bin # Trigger the population of the local package cache From d3a563554668a3a3fb64b1149418f90d1143dc96 Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Thu, 9 Mar 2017 16:55:06 +0100 Subject: [PATCH 079/127] Add global.json file to pick dotnet core SDK version --- examples/csharp/helloworld-from-cli/global.json | 5 +++++ src/csharp/global.json | 5 +++++ 2 files changed, 10 insertions(+) create mode 100644 examples/csharp/helloworld-from-cli/global.json create mode 100644 src/csharp/global.json diff --git a/examples/csharp/helloworld-from-cli/global.json b/examples/csharp/helloworld-from-cli/global.json new file mode 100644 index 00000000000..32ff399ef94 --- /dev/null +++ b/examples/csharp/helloworld-from-cli/global.json @@ -0,0 +1,5 @@ +{ + "sdk": { + "version": "1.0.0-preview2-003121" + } +} \ No newline at end of file diff --git a/src/csharp/global.json b/src/csharp/global.json new file mode 100644 index 00000000000..32ff399ef94 --- /dev/null +++ b/src/csharp/global.json @@ -0,0 +1,5 @@ +{ + "sdk": { + "version": "1.0.0-preview2-003121" + } +} \ No newline at end of file From 6ed454ef44d100e21dd1cb6b34951de150454640 Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Thu, 6 Apr 2017 13:20:49 +0200 Subject: [PATCH 080/127] make C# docker image in sync with GCE performance workers --- src/csharp/global.json | 2 +- templates/tools/dockerfile/csharp_dotnetcli_deps.include | 4 ++-- .../interoptest/grpc_interop_csharpcoreclr/Dockerfile | 4 ++-- tools/dockerfile/test/csharp_coreclr_x64/Dockerfile | 4 ++-- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/csharp/global.json b/src/csharp/global.json index 32ff399ef94..f3c33cef6a5 100644 --- a/src/csharp/global.json +++ b/src/csharp/global.json @@ -1,5 +1,5 @@ { "sdk": { - "version": "1.0.0-preview2-003121" + "version": "1.0.0-preview2-003131" } } \ No newline at end of file diff --git a/templates/tools/dockerfile/csharp_dotnetcli_deps.include b/templates/tools/dockerfile/csharp_dotnetcli_deps.include index 058ce15fb52..bc88d2bfa39 100644 --- a/templates/tools/dockerfile/csharp_dotnetcli_deps.include +++ b/templates/tools/dockerfile/csharp_dotnetcli_deps.include @@ -1,7 +1,7 @@ # Install dotnet SDK based on https://www.microsoft.com/net/core#debian RUN apt-get update && apt-get install -y curl libunwind8 gettext -# dotnet-dev-1.0.0-preview2-003121 -RUN curl -sSL -o dotnet100.tar.gz https://go.microsoft.com/fwlink/?LinkID=809130 +# dotnet-dev-1.0.0-preview2-003131 +RUN curl -sSL -o dotnet100.tar.gz https://go.microsoft.com/fwlink/?LinkID=827530 RUN mkdir -p /opt/dotnet && tar zxf dotnet100.tar.gz -C /opt/dotnet # dotnet-dev-1.0.1 RUN curl -sSL -o dotnet101.tar.gz https://go.microsoft.com/fwlink/?LinkID=843453 diff --git a/tools/dockerfile/interoptest/grpc_interop_csharpcoreclr/Dockerfile b/tools/dockerfile/interoptest/grpc_interop_csharpcoreclr/Dockerfile index c26c9a2826e..2a59628b487 100644 --- a/tools/dockerfile/interoptest/grpc_interop_csharpcoreclr/Dockerfile +++ b/tools/dockerfile/interoptest/grpc_interop_csharpcoreclr/Dockerfile @@ -99,8 +99,8 @@ RUN nuget update -self # Install dotnet SDK based on https://www.microsoft.com/net/core#debian RUN apt-get update && apt-get install -y curl libunwind8 gettext -# dotnet-dev-1.0.0-preview2-003121 -RUN curl -sSL -o dotnet100.tar.gz https://go.microsoft.com/fwlink/?LinkID=809130 +# dotnet-dev-1.0.0-preview2-003131 +RUN curl -sSL -o dotnet100.tar.gz https://go.microsoft.com/fwlink/?LinkID=827530 RUN mkdir -p /opt/dotnet && tar zxf dotnet100.tar.gz -C /opt/dotnet # dotnet-dev-1.0.1 RUN curl -sSL -o dotnet101.tar.gz https://go.microsoft.com/fwlink/?LinkID=843453 diff --git a/tools/dockerfile/test/csharp_coreclr_x64/Dockerfile b/tools/dockerfile/test/csharp_coreclr_x64/Dockerfile index c26c9a2826e..2a59628b487 100644 --- a/tools/dockerfile/test/csharp_coreclr_x64/Dockerfile +++ b/tools/dockerfile/test/csharp_coreclr_x64/Dockerfile @@ -99,8 +99,8 @@ RUN nuget update -self # Install dotnet SDK based on https://www.microsoft.com/net/core#debian RUN apt-get update && apt-get install -y curl libunwind8 gettext -# dotnet-dev-1.0.0-preview2-003121 -RUN curl -sSL -o dotnet100.tar.gz https://go.microsoft.com/fwlink/?LinkID=809130 +# dotnet-dev-1.0.0-preview2-003131 +RUN curl -sSL -o dotnet100.tar.gz https://go.microsoft.com/fwlink/?LinkID=827530 RUN mkdir -p /opt/dotnet && tar zxf dotnet100.tar.gz -C /opt/dotnet # dotnet-dev-1.0.1 RUN curl -sSL -o dotnet101.tar.gz https://go.microsoft.com/fwlink/?LinkID=843453 From 87b211244399b5d03b41860180c0a2aad7b86d5d Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Fri, 7 Apr 2017 10:18:12 +0200 Subject: [PATCH 081/127] also fix global.json in helloworld --- examples/csharp/helloworld-from-cli/global.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/csharp/helloworld-from-cli/global.json b/examples/csharp/helloworld-from-cli/global.json index 32ff399ef94..f3c33cef6a5 100644 --- a/examples/csharp/helloworld-from-cli/global.json +++ b/examples/csharp/helloworld-from-cli/global.json @@ -1,5 +1,5 @@ { "sdk": { - "version": "1.0.0-preview2-003121" + "version": "1.0.0-preview2-003131" } } \ No newline at end of file From 58aa2cb8f19bead7d4436fa9fcaee6ef8519f217 Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Fri, 7 Apr 2017 09:30:49 +0200 Subject: [PATCH 082/127] fix 1MB perf scenarios --- tools/run_tests/generated/tests.json | 16 +++++++-------- .../run_tests/performance/scenario_config.py | 20 +++++++++---------- 2 files changed, 18 insertions(+), 18 deletions(-) diff --git a/tools/run_tests/generated/tests.json b/tools/run_tests/generated/tests.json index d9c878170d7..e0b8a4cc6fb 100644 --- a/tools/run_tests/generated/tests.json +++ b/tools/run_tests/generated/tests.json @@ -41456,7 +41456,7 @@ { "args": [ "--scenarios_json", - "{\"scenarios\": [{\"name\": \"cpp_protobuf_async_unary_ping_pong_secure_1mb\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"async_server_threads\": 0, \"security_params\": {\"use_test_ca\": true, \"server_host_override\": \"foo.test.google.fr\"}, \"server_type\": \"ASYNC_SERVER\"}, \"num_clients\": 1, \"client_config\": {\"client_type\": \"ASYNC_CLIENT\", \"security_params\": {\"use_test_ca\": true, \"server_host_override\": \"foo.test.google.fr\"}, \"payload_config\": {\"simple_params\": {\"resp_size\": 1048576, \"req_size\": 1048576}}, \"client_channels\": 1, \"async_client_threads\": 1, \"outstanding_rpcs_per_channel\": 1, \"rpc_type\": \"UNARY\", \"load_params\": {\"closed_loop\": {}}, \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}}]}" + "{\"scenarios\": [{\"name\": \"cpp_protobuf_async_unary_ping_pong_secure_1MB\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"async_server_threads\": 0, \"security_params\": {\"use_test_ca\": true, \"server_host_override\": \"foo.test.google.fr\"}, \"server_type\": \"ASYNC_SERVER\"}, \"num_clients\": 1, \"client_config\": {\"client_type\": \"ASYNC_CLIENT\", \"security_params\": {\"use_test_ca\": true, \"server_host_override\": \"foo.test.google.fr\"}, \"payload_config\": {\"simple_params\": {\"resp_size\": 1048576, \"req_size\": 1048576}}, \"client_channels\": 1, \"async_client_threads\": 1, \"outstanding_rpcs_per_channel\": 1, \"rpc_type\": \"UNARY\", \"load_params\": {\"closed_loop\": {}}, \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}}]}" ], "boringssl": true, "ci_platforms": [ @@ -41475,7 +41475,7 @@ "platforms": [ "linux" ], - "shortname": "json_run_localhost:cpp_protobuf_async_unary_ping_pong_secure_1mb", + "shortname": "json_run_localhost:cpp_protobuf_async_unary_ping_pong_secure_1MB", "timeout_seconds": 360 }, { @@ -42035,7 +42035,7 @@ { "args": [ "--scenarios_json", - "{\"scenarios\": [{\"name\": \"cpp_protobuf_async_unary_ping_pong_insecure_1mb\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"async_server_threads\": 0, \"security_params\": null, \"server_type\": \"ASYNC_SERVER\"}, \"num_clients\": 1, \"client_config\": {\"client_type\": \"ASYNC_CLIENT\", \"security_params\": null, \"payload_config\": {\"simple_params\": {\"resp_size\": 1048576, \"req_size\": 1048576}}, \"client_channels\": 1, \"async_client_threads\": 1, \"outstanding_rpcs_per_channel\": 1, \"rpc_type\": \"UNARY\", \"load_params\": {\"closed_loop\": {}}, \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}}]}" + "{\"scenarios\": [{\"name\": \"cpp_protobuf_async_unary_ping_pong_insecure_1MB\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"async_server_threads\": 0, \"security_params\": null, \"server_type\": \"ASYNC_SERVER\"}, \"num_clients\": 1, \"client_config\": {\"client_type\": \"ASYNC_CLIENT\", \"security_params\": null, \"payload_config\": {\"simple_params\": {\"resp_size\": 1048576, \"req_size\": 1048576}}, \"client_channels\": 1, \"async_client_threads\": 1, \"outstanding_rpcs_per_channel\": 1, \"rpc_type\": \"UNARY\", \"load_params\": {\"closed_loop\": {}}, \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}}]}" ], "boringssl": true, "ci_platforms": [ @@ -42054,7 +42054,7 @@ "platforms": [ "linux" ], - "shortname": "json_run_localhost:cpp_protobuf_async_unary_ping_pong_insecure_1mb", + "shortname": "json_run_localhost:cpp_protobuf_async_unary_ping_pong_insecure_1MB", "timeout_seconds": 360 }, { @@ -42734,7 +42734,7 @@ { "args": [ "--scenarios_json", - "{\"scenarios\": [{\"name\": \"cpp_protobuf_async_unary_ping_pong_secure_1mb\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"async_server_threads\": 0, \"security_params\": {\"use_test_ca\": true, \"server_host_override\": \"foo.test.google.fr\"}, \"server_type\": \"ASYNC_SERVER\"}, \"num_clients\": 1, \"client_config\": {\"client_type\": \"ASYNC_CLIENT\", \"security_params\": {\"use_test_ca\": true, \"server_host_override\": \"foo.test.google.fr\"}, \"payload_config\": {\"simple_params\": {\"resp_size\": 1048576, \"req_size\": 1048576}}, \"client_channels\": 1, \"async_client_threads\": 1, \"outstanding_rpcs_per_channel\": 1, \"rpc_type\": \"UNARY\", \"load_params\": {\"closed_loop\": {}}, \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}}]}" + "{\"scenarios\": [{\"name\": \"cpp_protobuf_async_unary_ping_pong_secure_1MB\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"async_server_threads\": 0, \"security_params\": {\"use_test_ca\": true, \"server_host_override\": \"foo.test.google.fr\"}, \"server_type\": \"ASYNC_SERVER\"}, \"num_clients\": 1, \"client_config\": {\"client_type\": \"ASYNC_CLIENT\", \"security_params\": {\"use_test_ca\": true, \"server_host_override\": \"foo.test.google.fr\"}, \"payload_config\": {\"simple_params\": {\"resp_size\": 1048576, \"req_size\": 1048576}}, \"client_channels\": 1, \"async_client_threads\": 1, \"outstanding_rpcs_per_channel\": 1, \"rpc_type\": \"UNARY\", \"load_params\": {\"closed_loop\": {}}, \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}}]}" ], "boringssl": true, "ci_platforms": [ @@ -42765,7 +42765,7 @@ "platforms": [ "linux" ], - "shortname": "json_run_localhost:cpp_protobuf_async_unary_ping_pong_secure_1mb_low_thread_count", + "shortname": "json_run_localhost:cpp_protobuf_async_unary_ping_pong_secure_1MB_low_thread_count", "timeout_seconds": 360 }, { @@ -43589,7 +43589,7 @@ { "args": [ "--scenarios_json", - "{\"scenarios\": [{\"name\": \"cpp_protobuf_async_unary_ping_pong_insecure_1mb\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"async_server_threads\": 0, \"security_params\": null, \"server_type\": \"ASYNC_SERVER\"}, \"num_clients\": 1, \"client_config\": {\"client_type\": \"ASYNC_CLIENT\", \"security_params\": null, \"payload_config\": {\"simple_params\": {\"resp_size\": 1048576, \"req_size\": 1048576}}, \"client_channels\": 1, \"async_client_threads\": 1, \"outstanding_rpcs_per_channel\": 1, \"rpc_type\": \"UNARY\", \"load_params\": {\"closed_loop\": {}}, \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}}]}" + "{\"scenarios\": [{\"name\": \"cpp_protobuf_async_unary_ping_pong_insecure_1MB\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"async_server_threads\": 0, \"security_params\": null, \"server_type\": \"ASYNC_SERVER\"}, \"num_clients\": 1, \"client_config\": {\"client_type\": \"ASYNC_CLIENT\", \"security_params\": null, \"payload_config\": {\"simple_params\": {\"resp_size\": 1048576, \"req_size\": 1048576}}, \"client_channels\": 1, \"async_client_threads\": 1, \"outstanding_rpcs_per_channel\": 1, \"rpc_type\": \"UNARY\", \"load_params\": {\"closed_loop\": {}}, \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}}]}" ], "boringssl": true, "ci_platforms": [ @@ -43620,7 +43620,7 @@ "platforms": [ "linux" ], - "shortname": "json_run_localhost:cpp_protobuf_async_unary_ping_pong_insecure_1mb_low_thread_count", + "shortname": "json_run_localhost:cpp_protobuf_async_unary_ping_pong_insecure_1MB_low_thread_count", "timeout_seconds": 360 }, { diff --git a/tools/run_tests/performance/scenario_config.py b/tools/run_tests/performance/scenario_config.py index dca3fba0990..200da5e36db 100644 --- a/tools/run_tests/performance/scenario_config.py +++ b/tools/run_tests/performance/scenario_config.py @@ -304,11 +304,11 @@ class CXXLanguage: excluded_poll_engines = ['poll-cv']) yield _ping_pong_scenario( - 'cpp_protobuf_async_unary_ping_pong_%s_1mb' % secstr, rpc_type='UNARY', + 'cpp_protobuf_async_unary_ping_pong_%s_1MB' % secstr, rpc_type='UNARY', client_type='ASYNC_CLIENT', server_type='ASYNC_SERVER', req_size=1024*1024, resp_size=1024*1024, secure=secure, - categories=smoketest_categories) + categories=smoketest_categories + [SCALABLE]) for rpc_type in ['unary', 'streaming']: for synchronicity in ['sync', 'async']: @@ -464,10 +464,10 @@ class CSharpLanguage: categories=[SCALABLE]) yield _ping_pong_scenario( - 'csharp_protobuf_async_unary_ping_pong_1mb', rpc_type='UNARY', + 'csharp_protobuf_async_unary_ping_pong_1MB', rpc_type='UNARY', client_type='ASYNC_CLIENT', server_type='ASYNC_SERVER', req_size=1024*1024, resp_size=1024*1024, - categories=[SMOKETEST]) + categories=[SMOKETEST, SCALABLE]) def __str__(self): @@ -510,10 +510,10 @@ class NodeLanguage: client_language='c++') yield _ping_pong_scenario( - 'node_protobuf_async_unary_ping_pong_1mb', rpc_type='UNARY', + 'node_protobuf_unary_ping_pong_1MB', rpc_type='UNARY', client_type='ASYNC_CLIENT', server_type='ASYNC_SERVER', req_size=1024*1024, resp_size=1024*1024, - categories=[SMOKETEST]) + categories=[SCALABLE, SMOKETEST]) # TODO(murgatroid99): fix bugs with this scenario and re-enable it # yield _ping_pong_scenario( @@ -596,10 +596,10 @@ class PythonLanguage: server_language='c++', async_server_threads=1) yield _ping_pong_scenario( - 'python_protobuf_sync_unary_ping_pong_1mb', rpc_type='UNARY', + 'python_protobuf_sync_unary_ping_pong_1MB', rpc_type='UNARY', client_type='SYNC_CLIENT', server_type='ASYNC_SERVER', req_size=1024*1024, resp_size=1024*1024, - categories=[SMOKETEST]) + categories=[SMOKETEST, SCALABLE]) def __str__(self): return 'python' @@ -648,10 +648,10 @@ class RubyLanguage: server_language='c++', async_server_threads=1) yield _ping_pong_scenario( - 'ruby_protobuf_async_unary_ping_pong_1mb', rpc_type='UNARY', + 'ruby_protobuf_unary_ping_pong_1MB', rpc_type='UNARY', client_type='SYNC_CLIENT', server_type='SYNC_SERVER', req_size=1024*1024, resp_size=1024*1024, - categories=[SMOKETEST]) + categories=[SMOKETEST, SCALABLE]) def __str__(self): return 'ruby' From d7a610bf545e03f49ef029f81b2b06a378869646 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Fri, 7 Apr 2017 09:46:43 -0700 Subject: [PATCH 083/127] clang-format and unban --- .../chttp2/transport/chttp2_transport.c | 31 +++++++++++-------- 1 file changed, 18 insertions(+), 13 deletions(-) diff --git a/src/core/ext/transport/chttp2/transport/chttp2_transport.c b/src/core/ext/transport/chttp2/transport/chttp2_transport.c index ed3f5e61925..65bd56477c8 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; } } From 01499e051e3c55410ba09b39b9e6431de43f53b7 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Fri, 7 Apr 2017 09:48:03 -0700 Subject: [PATCH 084/127] Revert "Fix a bug in slice_buffer:maybe_embiggen" This reverts commit 9a0356b1e6d0f4fdd1e29a48596b91458b038f46. --- src/core/lib/slice/slice_buffer.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/src/core/lib/slice/slice_buffer.c b/src/core/lib/slice/slice_buffer.c index 451319c50d6..9176dc8a420 100644 --- a/src/core/lib/slice/slice_buffer.c +++ b/src/core/lib/slice/slice_buffer.c @@ -46,6 +46,11 @@ #define GROW(x) (3 * (x) / 2) static void maybe_embiggen(grpc_slice_buffer *sb) { + if (sb->base_slices != sb->slices) { + memmove(sb->base_slices, sb->slices, sb->count * sizeof(grpc_slice)); + sb->slices = sb->base_slices; + } + /* How far away from sb->base_slices is sb->slices pointer */ size_t slice_offset = (size_t)(sb->slices - sb->base_slices); size_t slice_count = sb->count + slice_offset; @@ -56,15 +61,12 @@ static void maybe_embiggen(grpc_slice_buffer *sb) { if (sb->base_slices == sb->inlined) { sb->base_slices = gpr_malloc(sb->capacity * sizeof(grpc_slice)); memcpy(sb->base_slices, sb->inlined, slice_count * sizeof(grpc_slice)); - sb->slices = sb->base_slices + slice_offset; } else { - if (sb->base_slices != sb->slices) { - memmove(sb->base_slices, sb->slices, sb->count * sizeof(grpc_slice)); - } sb->base_slices = gpr_realloc(sb->base_slices, sb->capacity * sizeof(grpc_slice)); - sb->slices = sb->base_slices; } + + sb->slices = sb->base_slices + slice_offset; } } From a3fda8fdc94aa7dcb3e0da0dfc28e3d85b5cf798 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Fri, 7 Apr 2017 10:34:33 -0700 Subject: [PATCH 085/127] Fix bm_chttp2_transport memory leak --- test/cpp/microbenchmarks/bm_chttp2_transport.cc | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/test/cpp/microbenchmarks/bm_chttp2_transport.cc b/test/cpp/microbenchmarks/bm_chttp2_transport.cc index d3ca27a68e5..5456f69d505 100644 --- a/test/cpp/microbenchmarks/bm_chttp2_transport.cc +++ b/test/cpp/microbenchmarks/bm_chttp2_transport.cc @@ -574,7 +574,9 @@ static void BM_TransportStreamRecv(benchmark::State &state) { drain_continue.get()) && GRPC_ERROR_NONE == grpc_byte_stream_pull(exec_ctx, recv_stream, &recv_slice) && - (received += GRPC_SLICE_LENGTH(recv_slice), true)); + (received += GRPC_SLICE_LENGTH(recv_slice), + grpc_slice_unref_internal(exec_ctx, recv_slice), + true)); }); drain_continue = MakeClosure([&](grpc_exec_ctx *exec_ctx, grpc_error *error) { From 7cfa1bfb7378c4a55ec49867bb93895234b973c5 Mon Sep 17 00:00:00 2001 From: murgatroid99 Date: Fri, 7 Apr 2017 10:41:21 -0700 Subject: [PATCH 086/127] Bump version to 1.2.3 --- BUILD | 2 +- CMakeLists.txt | 2 +- Makefile | 4 ++-- build.yaml | 2 +- gRPC-Core.podspec | 2 +- gRPC-ProtoRPC.podspec | 2 +- gRPC-RxLibrary.podspec | 2 +- gRPC.podspec | 2 +- package.json | 2 +- package.xml | 4 ++-- src/cpp/common/version_cc.cc | 2 +- src/csharp/Grpc.Auth/project.json | 4 ++-- src/csharp/Grpc.Core.Testing/project.json | 4 ++-- src/csharp/Grpc.Core/VersionInfo.cs | 4 ++-- src/csharp/Grpc.Core/project.json | 2 +- src/csharp/Grpc.HealthCheck/project.json | 4 ++-- src/csharp/Grpc.Reflection/project.json | 4 ++-- src/csharp/build_packages_dotnetcli.bat | 2 +- src/csharp/build_packages_dotnetcli.sh | 4 ++-- src/node/health_check/package.json | 4 ++-- src/node/tools/package.json | 2 +- src/objective-c/!ProtoCompiler-gRPCPlugin.podspec | 2 +- src/objective-c/GRPCClient/private/version.h | 2 +- src/php/composer.json | 2 +- src/python/grpcio/grpc_version.py | 2 +- src/python/grpcio_health_checking/grpc_version.py | 2 +- src/python/grpcio_reflection/grpc_version.py | 2 +- src/python/grpcio_tests/grpc_version.py | 2 +- src/ruby/lib/grpc/version.rb | 2 +- src/ruby/tools/version.rb | 2 +- tools/distrib/python/grpcio_tools/grpc_version.py | 2 +- tools/doxygen/Doxyfile.c++ | 2 +- tools/doxygen/Doxyfile.c++.internal | 2 +- 33 files changed, 42 insertions(+), 42 deletions(-) diff --git a/BUILD b/BUILD index 0e8b058cb5f..680722ac66b 100644 --- a/BUILD +++ b/BUILD @@ -41,7 +41,7 @@ g_stands_for = "green" core_version = "3.0.0-dev" -version = "1.2.2" +version = "1.2.3" grpc_cc_library( name = "gpr", diff --git a/CMakeLists.txt b/CMakeLists.txt index 4496d37bd6a..e09f7297333 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -42,7 +42,7 @@ cmake_minimum_required(VERSION 2.8) set(PACKAGE_NAME "grpc") -set(PACKAGE_VERSION "1.2.2") +set(PACKAGE_VERSION "1.2.3") set(PACKAGE_STRING "${PACKAGE_NAME} ${PACKAGE_VERSION}") set(PACKAGE_TARNAME "${PACKAGE_NAME}-${PACKAGE_VERSION}") set(PACKAGE_BUGREPORT "https://github.com/grpc/grpc/issues/") diff --git a/Makefile b/Makefile index 00a99ab964f..52e80b01879 100644 --- a/Makefile +++ b/Makefile @@ -412,8 +412,8 @@ Q = @ endif CORE_VERSION = 3.0.0-dev -CPP_VERSION = 1.2.2 -CSHARP_VERSION = 1.2.2 +CPP_VERSION = 1.2.3 +CSHARP_VERSION = 1.2.3 CPPFLAGS_NO_ARCH += $(addprefix -I, $(INCLUDES)) $(addprefix -D, $(DEFINES)) CPPFLAGS += $(CPPFLAGS_NO_ARCH) $(ARCH_FLAGS) diff --git a/build.yaml b/build.yaml index 8df00f2c4bd..ac183a91b56 100644 --- a/build.yaml +++ b/build.yaml @@ -14,7 +14,7 @@ settings: '#10': See the expand_version.py for all the quirks here core_version: 3.0.0-dev g_stands_for: green - version: 1.2.2 + version: 1.2.3 filegroups: - name: census public_headers: diff --git a/gRPC-Core.podspec b/gRPC-Core.podspec index 51e8fdfa02e..9e6218d031c 100644 --- a/gRPC-Core.podspec +++ b/gRPC-Core.podspec @@ -37,7 +37,7 @@ Pod::Spec.new do |s| s.name = 'gRPC-Core' - version = '1.2.2' + version = '1.2.3' s.version = version s.summary = 'Core cross-platform gRPC library, written in C' s.homepage = 'http://www.grpc.io' diff --git a/gRPC-ProtoRPC.podspec b/gRPC-ProtoRPC.podspec index 86c51819227..a4b56fe1054 100644 --- a/gRPC-ProtoRPC.podspec +++ b/gRPC-ProtoRPC.podspec @@ -36,7 +36,7 @@ Pod::Spec.new do |s| s.name = 'gRPC-ProtoRPC' - version = '1.2.2' + version = '1.2.3' s.version = version s.summary = 'RPC library for Protocol Buffers, based on gRPC' s.homepage = 'http://www.grpc.io' diff --git a/gRPC-RxLibrary.podspec b/gRPC-RxLibrary.podspec index ba365ceaa04..a567e6aa0f5 100644 --- a/gRPC-RxLibrary.podspec +++ b/gRPC-RxLibrary.podspec @@ -36,7 +36,7 @@ Pod::Spec.new do |s| s.name = 'gRPC-RxLibrary' - version = '1.2.2' + version = '1.2.3' s.version = version s.summary = 'Reactive Extensions library for iOS/OSX.' s.homepage = 'http://www.grpc.io' diff --git a/gRPC.podspec b/gRPC.podspec index b51c4df5dae..891f9a5aebe 100644 --- a/gRPC.podspec +++ b/gRPC.podspec @@ -35,7 +35,7 @@ Pod::Spec.new do |s| s.name = 'gRPC' - version = '1.2.2' + version = '1.2.3' s.version = version s.summary = 'gRPC client library for iOS/OSX' s.homepage = 'http://www.grpc.io' diff --git a/package.json b/package.json index b4503d00dba..f2646c0d6d1 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "grpc", - "version": "1.2.2", + "version": "1.2.3", "author": "Google Inc.", "description": "gRPC Library for Node", "homepage": "http://www.grpc.io/", diff --git a/package.xml b/package.xml index 6ff9a9c9cc4..f120d57a6d1 100644 --- a/package.xml +++ b/package.xml @@ -13,8 +13,8 @@ 2017-03-01 - 1.2.2 - 1.2.2 + 1.2.3 + 1.2.3 beta diff --git a/src/cpp/common/version_cc.cc b/src/cpp/common/version_cc.cc index 6405fbcbd7d..cda07999244 100644 --- a/src/cpp/common/version_cc.cc +++ b/src/cpp/common/version_cc.cc @@ -37,5 +37,5 @@ #include namespace grpc { -grpc::string Version() { return "1.2.2"; } +grpc::string Version() { return "1.2.3"; } } diff --git a/src/csharp/Grpc.Auth/project.json b/src/csharp/Grpc.Auth/project.json index 31022e65bdf..45ee3a3112b 100644 --- a/src/csharp/Grpc.Auth/project.json +++ b/src/csharp/Grpc.Auth/project.json @@ -1,5 +1,5 @@ { - "version": "1.2.2", + "version": "1.2.3", "title": "gRPC C# Auth", "authors": [ "Google Inc." ], "copyright": "Copyright 2015, Google Inc.", @@ -21,7 +21,7 @@ } }, "dependencies": { - "Grpc.Core": "1.2.2", + "Grpc.Core": "1.2.3", "Google.Apis.Auth": "1.21.0" }, "frameworks": { diff --git a/src/csharp/Grpc.Core.Testing/project.json b/src/csharp/Grpc.Core.Testing/project.json index 22d728fc159..40dc57ac76f 100644 --- a/src/csharp/Grpc.Core.Testing/project.json +++ b/src/csharp/Grpc.Core.Testing/project.json @@ -1,5 +1,5 @@ { - "version": "1.2.2", + "version": "1.2.3", "title": "gRPC C# Core Testing", "authors": [ "Google Inc." ], "copyright": "Copyright 2017, Google Inc.", @@ -21,7 +21,7 @@ } }, "dependencies": { - "Grpc.Core": "1.2.2" + "Grpc.Core": "1.2.3" }, "frameworks": { "net45": { diff --git a/src/csharp/Grpc.Core/VersionInfo.cs b/src/csharp/Grpc.Core/VersionInfo.cs index d46f863e173..c3339ce1a45 100644 --- a/src/csharp/Grpc.Core/VersionInfo.cs +++ b/src/csharp/Grpc.Core/VersionInfo.cs @@ -48,11 +48,11 @@ namespace Grpc.Core /// /// Current AssemblyFileVersion of gRPC C# assemblies /// - public const string CurrentAssemblyFileVersion = "1.2.2.0"; + public const string CurrentAssemblyFileVersion = "1.2.3.0"; /// /// Current version of gRPC C# /// - public const string CurrentVersion = "1.2.2"; + public const string CurrentVersion = "1.2.3"; } } diff --git a/src/csharp/Grpc.Core/project.json b/src/csharp/Grpc.Core/project.json index 0d56b55fe30..0381b04cf5c 100644 --- a/src/csharp/Grpc.Core/project.json +++ b/src/csharp/Grpc.Core/project.json @@ -1,5 +1,5 @@ { - "version": "1.2.2", + "version": "1.2.3", "title": "gRPC C# Core", "authors": [ "Google Inc." ], "copyright": "Copyright 2015, Google Inc.", diff --git a/src/csharp/Grpc.HealthCheck/project.json b/src/csharp/Grpc.HealthCheck/project.json index 259d973ff62..4010d5566ab 100644 --- a/src/csharp/Grpc.HealthCheck/project.json +++ b/src/csharp/Grpc.HealthCheck/project.json @@ -1,5 +1,5 @@ { - "version": "1.2.2", + "version": "1.2.3", "title": "gRPC C# Healthchecking", "authors": [ "Google Inc." ], "copyright": "Copyright 2015, Google Inc.", @@ -21,7 +21,7 @@ } }, "dependencies": { - "Grpc.Core": "1.2.2", + "Grpc.Core": "1.2.3", "Google.Protobuf": "3.2.0" }, "frameworks": { diff --git a/src/csharp/Grpc.Reflection/project.json b/src/csharp/Grpc.Reflection/project.json index b40945cad40..996aa51512f 100644 --- a/src/csharp/Grpc.Reflection/project.json +++ b/src/csharp/Grpc.Reflection/project.json @@ -1,5 +1,5 @@ { - "version": "1.2.2", + "version": "1.2.3", "title": "gRPC C# Reflection", "authors": [ "Google Inc." ], "copyright": "Copyright 2016, Google Inc.", @@ -21,7 +21,7 @@ } }, "dependencies": { - "Grpc.Core": "1.2.2", + "Grpc.Core": "1.2.3", "Google.Protobuf": "3.2.0" }, "frameworks": { diff --git a/src/csharp/build_packages_dotnetcli.bat b/src/csharp/build_packages_dotnetcli.bat index 51c87246bf0..aa47067d740 100755 --- a/src/csharp/build_packages_dotnetcli.bat +++ b/src/csharp/build_packages_dotnetcli.bat @@ -28,7 +28,7 @@ @rem OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. @rem Current package versions -set VERSION=1.2.2 +set VERSION=1.2.3 set PROTOBUF_VERSION=3.0.0 @rem Adjust the location of nuget.exe diff --git a/src/csharp/build_packages_dotnetcli.sh b/src/csharp/build_packages_dotnetcli.sh index 7e7a029fcfd..b0432f4b18a 100755 --- a/src/csharp/build_packages_dotnetcli.sh +++ b/src/csharp/build_packages_dotnetcli.sh @@ -66,7 +66,7 @@ dotnet pack --configuration Release Grpc.Auth/project.json --output ../../artifa dotnet pack --configuration Release Grpc.HealthCheck/project.json --output ../../artifacts dotnet pack --configuration Release Grpc.Reflection/project.json --output ../../artifacts -nuget pack Grpc.nuspec -Version "1.2.2" -OutputDirectory ../../artifacts -nuget pack Grpc.Tools.nuspec -Version "1.2.2" -OutputDirectory ../../artifacts +nuget pack Grpc.nuspec -Version "1.2.3" -OutputDirectory ../../artifacts +nuget pack Grpc.Tools.nuspec -Version "1.2.3" -OutputDirectory ../../artifacts (cd ../../artifacts && zip csharp_nugets_dotnetcli.zip *.nupkg) diff --git a/src/node/health_check/package.json b/src/node/health_check/package.json index 61bb83f229a..5ad59e27e6a 100644 --- a/src/node/health_check/package.json +++ b/src/node/health_check/package.json @@ -1,6 +1,6 @@ { "name": "grpc-health-check", - "version": "1.2.2", + "version": "1.2.3", "author": "Google Inc.", "description": "Health check service for use with gRPC", "repository": { @@ -15,7 +15,7 @@ } ], "dependencies": { - "grpc": "^1.2.2", + "grpc": "^1.2.3", "lodash": "^3.9.3", "google-protobuf": "^3.0.0" }, diff --git a/src/node/tools/package.json b/src/node/tools/package.json index 460f2fc857a..e06775b5bb6 100644 --- a/src/node/tools/package.json +++ b/src/node/tools/package.json @@ -1,6 +1,6 @@ { "name": "grpc-tools", - "version": "1.2.2", + "version": "1.2.3", "author": "Google Inc.", "description": "Tools for developing with gRPC on Node.js", "homepage": "http://www.grpc.io/", diff --git a/src/objective-c/!ProtoCompiler-gRPCPlugin.podspec b/src/objective-c/!ProtoCompiler-gRPCPlugin.podspec index ca5ad7b2f56..f314d48c887 100644 --- a/src/objective-c/!ProtoCompiler-gRPCPlugin.podspec +++ b/src/objective-c/!ProtoCompiler-gRPCPlugin.podspec @@ -42,7 +42,7 @@ Pod::Spec.new do |s| # exclamation mark ensures that other "regular" pods will be able to find it as it'll be installed # before them. s.name = '!ProtoCompiler-gRPCPlugin' - v = '1.2.2' + v = '1.2.3' s.version = v s.summary = 'The gRPC ProtoC plugin generates Objective-C files from .proto services.' s.description = <<-DESC diff --git a/src/objective-c/GRPCClient/private/version.h b/src/objective-c/GRPCClient/private/version.h index d04f73d3188..69035cf8add 100644 --- a/src/objective-c/GRPCClient/private/version.h +++ b/src/objective-c/GRPCClient/private/version.h @@ -38,4 +38,4 @@ // `tools/buildgen/generate_projects.sh`. -#define GRPC_OBJC_VERSION_STRING @"1.2.2" +#define GRPC_OBJC_VERSION_STRING @"1.2.3" diff --git a/src/php/composer.json b/src/php/composer.json index fa4e3e5990f..a2f83ec1e00 100644 --- a/src/php/composer.json +++ b/src/php/composer.json @@ -2,7 +2,7 @@ "name": "grpc/grpc-dev", "description": "gRPC library for PHP - for Developement use only", "license": "BSD-3-Clause", - "version": "1.2.2", + "version": "1.2.3", "require": { "php": ">=5.5.0", "google/protobuf": "^v3.1.0" diff --git a/src/python/grpcio/grpc_version.py b/src/python/grpcio/grpc_version.py index caf940273e2..0fdb76072b3 100644 --- a/src/python/grpcio/grpc_version.py +++ b/src/python/grpcio/grpc_version.py @@ -29,4 +29,4 @@ # AUTO-GENERATED FROM `$REPO_ROOT/templates/src/python/grpcio/grpc_version.py.template`!!! -VERSION='1.2.2' +VERSION='1.2.3' diff --git a/src/python/grpcio_health_checking/grpc_version.py b/src/python/grpcio_health_checking/grpc_version.py index 7b7d95daacf..d3ac3aa3ef0 100644 --- a/src/python/grpcio_health_checking/grpc_version.py +++ b/src/python/grpcio_health_checking/grpc_version.py @@ -29,4 +29,4 @@ # AUTO-GENERATED FROM `$REPO_ROOT/templates/src/python/grpcio_health_checking/grpc_version.py.template`!!! -VERSION='1.2.2' +VERSION='1.2.3' diff --git a/src/python/grpcio_reflection/grpc_version.py b/src/python/grpcio_reflection/grpc_version.py index dffabad634f..416910c6ab9 100644 --- a/src/python/grpcio_reflection/grpc_version.py +++ b/src/python/grpcio_reflection/grpc_version.py @@ -29,4 +29,4 @@ # AUTO-GENERATED FROM `$REPO_ROOT/templates/src/python/grpcio_reflection/grpc_version.py.template`!!! -VERSION='1.2.2' +VERSION='1.2.3' diff --git a/src/python/grpcio_tests/grpc_version.py b/src/python/grpcio_tests/grpc_version.py index d31ddd3c221..71495a1075f 100644 --- a/src/python/grpcio_tests/grpc_version.py +++ b/src/python/grpcio_tests/grpc_version.py @@ -29,4 +29,4 @@ # AUTO-GENERATED FROM `$REPO_ROOT/templates/src/python/grpcio_tests/grpc_version.py.template`!!! -VERSION='1.2.2' +VERSION='1.2.3' diff --git a/src/ruby/lib/grpc/version.rb b/src/ruby/lib/grpc/version.rb index cc25ca10a0e..51f9ccace9e 100644 --- a/src/ruby/lib/grpc/version.rb +++ b/src/ruby/lib/grpc/version.rb @@ -29,5 +29,5 @@ # GRPC contains the General RPC module. module GRPC - VERSION = '1.2.2' + VERSION = '1.2.3' end diff --git a/src/ruby/tools/version.rb b/src/ruby/tools/version.rb index 7c7eada243d..dd07b264d4b 100644 --- a/src/ruby/tools/version.rb +++ b/src/ruby/tools/version.rb @@ -29,6 +29,6 @@ module GRPC module Tools - VERSION = '1.2.2' + VERSION = '1.2.3' end end diff --git a/tools/distrib/python/grpcio_tools/grpc_version.py b/tools/distrib/python/grpcio_tools/grpc_version.py index a28f2448d4d..32fad56ca4d 100644 --- a/tools/distrib/python/grpcio_tools/grpc_version.py +++ b/tools/distrib/python/grpcio_tools/grpc_version.py @@ -29,4 +29,4 @@ # AUTO-GENERATED FROM `$REPO_ROOT/templates/tools/distrib/python/grpcio_tools/grpc_version.py.template`!!! -VERSION='1.2.2' +VERSION='1.2.3' diff --git a/tools/doxygen/Doxyfile.c++ b/tools/doxygen/Doxyfile.c++ index 70c7f6d5ae8..4bb1414e868 100644 --- a/tools/doxygen/Doxyfile.c++ +++ b/tools/doxygen/Doxyfile.c++ @@ -40,7 +40,7 @@ PROJECT_NAME = "GRPC C++" # could be handy for archiving the generated documentation or if some version # control system is used. -PROJECT_NUMBER = 1.2.2 +PROJECT_NUMBER = 1.2.3 # Using the PROJECT_BRIEF tag one can provide an optional one line description # for a project that appears at the top of each page and should give viewer a diff --git a/tools/doxygen/Doxyfile.c++.internal b/tools/doxygen/Doxyfile.c++.internal index 34d6a59be20..db987191b60 100644 --- a/tools/doxygen/Doxyfile.c++.internal +++ b/tools/doxygen/Doxyfile.c++.internal @@ -40,7 +40,7 @@ PROJECT_NAME = "GRPC C++" # could be handy for archiving the generated documentation or if some version # control system is used. -PROJECT_NUMBER = 1.2.2 +PROJECT_NUMBER = 1.2.3 # Using the PROJECT_BRIEF tag one can provide an optional one line description # for a project that appears at the top of each page and should give viewer a From 848073f77d3750ee587bb07624a213d293c9fc48 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Fri, 7 Apr 2017 10:53:15 -0700 Subject: [PATCH 087/127] Clean up unused variables and funcs --- .../chttp2/transport/chttp2_transport.c | 8 ----- .../transport/chttp2/transport/frame_data.c | 33 ------------------- .../ext/transport/chttp2/transport/internal.h | 5 --- .../microbenchmarks/bm_chttp2_transport.cc | 3 +- 4 files changed, 1 insertion(+), 48 deletions(-) diff --git a/src/core/ext/transport/chttp2/transport/chttp2_transport.c b/src/core/ext/transport/chttp2/transport/chttp2_transport.c index 79ff5e6e728..209d76c2712 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 8b42d05c726..af754e1a779 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 467c9353dd9..773f541e97a 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 5456f69d505..8c5413b5fda 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) { From c702a7a85f9756e94c04e011c11d47a96733ac95 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Sun, 9 Apr 2017 13:18:55 -0700 Subject: [PATCH 088/127] clang-format --- .../chttp2/transport/chttp2_transport.c | 26 ++++++++----------- .../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(-) diff --git a/src/core/ext/transport/chttp2/transport/chttp2_transport.c b/src/core/ext/transport/chttp2/transport/chttp2_transport.c index 209d76c2712..c78c8def69e 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 0b55a5a3bb7..7f09936e931 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 a945639faea..764524b24d1 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 57bbb98139d..151fb9885de 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(); } From da2f0cf89242d83a3f3c3207d3554888bfebc5d7 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Sun, 9 Apr 2017 15:34:28 -0700 Subject: [PATCH 089/127] Restore Cronet test accidentally removed --- src/objective-c/tests/InteropTests.m | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/objective-c/tests/InteropTests.m b/src/objective-c/tests/InteropTests.m index 91053568690..69968dcb609 100644 --- a/src/objective-c/tests/InteropTests.m +++ b/src/objective-c/tests/InteropTests.m @@ -100,6 +100,15 @@ return 0; } ++ (void)setUp { +#ifdef GRPC_COMPILE_WITH_CRONET + // Cronet setup + [Cronet setHttp2Enabled:YES]; + [Cronet start]; + [GRPCCall useCronetWithEngine:[Cronet getGlobalEngine]]; +#endif +} + - (void)setUp { self.continueAfterFailure = NO; From 300be7ece2fc7a0c893bd3cf7b34a8558b34726e Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Sun, 9 Apr 2017 15:44:19 -0700 Subject: [PATCH 090/127] Fix the cronet_transport error --- src/core/ext/transport/cronet/transport/cronet_transport.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core/ext/transport/cronet/transport/cronet_transport.c b/src/core/ext/transport/cronet/transport/cronet_transport.c index 0b9189558f8..3ca6b2fdf69 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, From 025f110ed26afe600c10a4af9648bd6933174168 Mon Sep 17 00:00:00 2001 From: murgatroid99 Date: Mon, 10 Apr 2017 13:07:37 -0700 Subject: [PATCH 091/127] Node: fix Windows warning in binding.gyp for Win10 console --- binding.gyp | 5 +++-- templates/binding.gyp.template | 5 +++-- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/binding.gyp b/binding.gyp index 3444fa53dba..17a86335581 100644 --- a/binding.gyp +++ b/binding.gyp @@ -519,9 +519,10 @@ # the OpenSSL headers, from the downloaded Node development package, # which is typically located in `.node-gyp` in your home directory. 'target_name': 'WINDOWS_BUILD_WARNING', - 'actions': [ + 'rules': [ { - 'action_name': 'WINDOWS_BUILD_WARNING', + 'rule_name': 'WINDOWS_BUILD_WARNING', + 'extension': 'S', 'inputs': [ 'package.json' ], diff --git a/templates/binding.gyp.template b/templates/binding.gyp.template index aeeb56b9a6a..55a91c5b93d 100644 --- a/templates/binding.gyp.template +++ b/templates/binding.gyp.template @@ -217,9 +217,10 @@ # the OpenSSL headers, from the downloaded Node development package, # which is typically located in `.node-gyp` in your home directory. 'target_name': 'WINDOWS_BUILD_WARNING', - 'actions': [ + 'rules': [ { - 'action_name': 'WINDOWS_BUILD_WARNING', + 'rule_name': 'WINDOWS_BUILD_WARNING', + 'extension': 'S', 'inputs': [ 'package.json' ], From 5101b3f7cf87c9b2f9e6c5c4bb4c1023dcb999b2 Mon Sep 17 00:00:00 2001 From: Matt Kwong Date: Mon, 10 Apr 2017 14:34:39 -0700 Subject: [PATCH 092/127] Pin Bazel version to 0.4.4 in Dockerfile --- tools/dockerfile/test/bazel/Dockerfile | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/tools/dockerfile/test/bazel/Dockerfile b/tools/dockerfile/test/bazel/Dockerfile index cc413848337..6ea8ef316c6 100644 --- a/tools/dockerfile/test/bazel/Dockerfile +++ b/tools/dockerfile/test/bazel/Dockerfile @@ -72,6 +72,13 @@ RUN curl https://bazel.build/bazel-release.pub.gpg | apt-key add - RUN apt-get -y update RUN apt-get -y install bazel +# Pin Bazel to 0.4.4 +# Installing Bazel via apt-get first is required before installing 0.4.4 to +# allow gRPC to build without errors. See https://github.com/grpc/grpc/issues/10553 +RUN curl -fSsL -O https://github.com/bazelbuild/bazel/releases/download/0.4.4/bazel-0.4.4-installer-linux-x86_64.sh +RUN chmod +x ./bazel-0.4.4-installer-linux-x86_64.sh +RUN ./bazel-0.4.4-installer-linux-x86_64.sh + RUN mkdir -p /var/local/jenkins # Define the default command. From d6dd46a1d9558c32ed17f1e9ce1726b272b06404 Mon Sep 17 00:00:00 2001 From: Alexander Polcyn Date: Mon, 10 Apr 2017 16:45:02 -0700 Subject: [PATCH 093/127] fix flakey race in ruby tests --- src/ruby/spec/generic/rpc_server_pool_spec.rb | 41 +++++++++++-------- 1 file changed, 25 insertions(+), 16 deletions(-) diff --git a/src/ruby/spec/generic/rpc_server_pool_spec.rb b/src/ruby/spec/generic/rpc_server_pool_spec.rb index 69e8222cb97..75b40225680 100644 --- a/src/ruby/spec/generic/rpc_server_pool_spec.rb +++ b/src/ruby/spec/generic/rpc_server_pool_spec.rb @@ -52,27 +52,36 @@ describe GRPC::Pool do expect(p.ready_for_work?).to be(false) end - it 'it stops being ready after all workers jobs waiting or running' do + it 'it stops being ready after all workers are busy, ' \ + 'and it becomes ready again after jobs complete' do p = Pool.new(5) p.start - job = proc { sleep(3) } # sleep so workers busy when done scheduling - 5.times do - expect(p.ready_for_work?).to be(true) - p.schedule(&job) + + wait_mu = Mutex.new + wait_cv = ConditionVariable.new + wait = true + + job = proc do + wait_mu.synchronize do + wait_cv.wait(wait_mu) while wait + end end - expect(p.ready_for_work?).to be(false) - end - it 'it becomes ready again after jobs complete' do - p = Pool.new(5) - p.start - job = proc {} 5.times do expect(p.ready_for_work?).to be(true) p.schedule(&job) end + expect(p.ready_for_work?).to be(false) - sleep 5 # give the pool time do get at least one task done + + wait_mu.synchronize do + wait = false + wait_cv.broadcast + end + + # There's a potential race here but it shouldn't ever be + # reached with a 5 second sleep. + sleep 5 expect(p.ready_for_work?).to be(true) end end @@ -105,13 +114,13 @@ describe GRPC::Pool do it 'stops jobs when there are long running jobs' do p = Pool.new(1) p.start - o, q = Object.new, Queue.new + job_running = Queue.new job = proc do - sleep(5) # long running - q.push(o) + job_running.push(Object.new) + sleep(5000) end p.schedule(&job) - sleep(1) # should ensure the long job gets scheduled + job_running.pop expect { p.stop }.not_to raise_error end end From 48cba2adb45bc3a60b9fc6234757bcd9a84c5697 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Mon, 10 Apr 2017 17:08:01 -0700 Subject: [PATCH 094/127] Send content-type on trailer-only responses --- .../chttp2/transport/chttp2_transport.c | 38 +++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/src/core/ext/transport/chttp2/transport/chttp2_transport.c b/src/core/ext/transport/chttp2/transport/chttp2_transport.c index e2816b0e045..7323f4cb2e4 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); From e899e32710ba6742d986a3c7725a2358d1081f83 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Mon, 10 Apr 2017 18:14:49 -0700 Subject: [PATCH 095/127] Move deframe_unprocessed_incoming_frames to frame_data.c --- .../chttp2/transport/chttp2_transport.c | 181 +----------------- .../transport/chttp2/transport/frame_data.c | 178 +++++++++++++++++ .../transport/chttp2/transport/frame_data.h | 7 + 3 files changed, 186 insertions(+), 180 deletions(-) diff --git a/src/core/ext/transport/chttp2/transport/chttp2_transport.c b/src/core/ext/transport/chttp2/transport/chttp2_transport.c index c78c8def69e..093370d11a9 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 af754e1a779..4aa61ae68ea 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 e7e459c79fa..5783f447b53 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 */ From c248f5b45073850bcb6c05b55870a689dad2ff11 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Mon, 10 Apr 2017 18:15:42 -0700 Subject: [PATCH 096/127] 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(-) diff --git a/src/core/ext/transport/chttp2/transport/frame_data.c b/src/core/ext/transport/chttp2/transport/frame_data.c index 4aa61ae68ea..d2193cdb321 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 5783f447b53..17cc8d20736 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; From afdad3e8bb40f1f771e24cd6dded81e91603a971 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Mon, 10 Apr 2017 18:22:05 -0700 Subject: [PATCH 097/127] clean up unused code --- src/core/ext/transport/chttp2/transport/frame_data.h | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/src/core/ext/transport/chttp2/transport/frame_data.h b/src/core/ext/transport/chttp2/transport/frame_data.h index 17cc8d20736..2fb8983c38e 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); From 02646c3f62d6e5b07b62ffbdacfb64ae7946b721 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Mon, 10 Apr 2017 18:28:23 -0700 Subject: [PATCH 098/127] int -> bool --- .../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(-) diff --git a/src/core/ext/transport/chttp2/transport/chttp2_transport.c b/src/core/ext/transport/chttp2/transport/chttp2_transport.c index 093370d11a9..a0bce1e0775 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 79801c4b465..5800c70ef44 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 800e2341f9e..381c65fb044 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); From 6cc2a993a4f6dac641c7de640876775e22f2aac2 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Mon, 10 Apr 2017 18:30:53 -0700 Subject: [PATCH 099/127] Remove redundant assignment --- src/core/ext/transport/chttp2/transport/chttp2_transport.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/core/ext/transport/chttp2/transport/chttp2_transport.c b/src/core/ext/transport/chttp2/transport/chttp2_transport.c index a0bce1e0775..1cbd0782113 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( From 9da7b95c27843136e3ca92ac71b141978344339a Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Mon, 10 Apr 2017 18:33:01 -0700 Subject: [PATCH 100/127] int -> bool --- .../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(-) diff --git a/src/core/ext/transport/chttp2/transport/chttp2_transport.c b/src/core/ext/transport/chttp2/transport/chttp2_transport.c index 1cbd0782113..4146701af6e 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 d2193cdb321..1f51e0cd6fc 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 773f541e97a..d5767c8d8da 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); From 2c01070bc3119d1f5e0dce33b72928fb87a55505 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Mon, 10 Apr 2017 19:20:58 -0700 Subject: [PATCH 101/127] Work with error refs --- .../chttp2/transport/chttp2_transport.c | 1 - .../transport/chttp2/transport/frame_data.c | 24 ++++++++++++------- src/core/lib/surface/call.c | 8 +++++++ 3 files changed, 24 insertions(+), 9 deletions(-) diff --git a/src/core/ext/transport/chttp2/transport/chttp2_transport.c b/src/core/ext/transport/chttp2/transport/chttp2_transport.c index 4146701af6e..0002253dfee 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 1f51e0cd6fc..5d382d80a8b 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 b1cb7f7fb1c..3e96d097985 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); + } } } From 9396914c1430e9974e5315065d93eb634302fa06 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Mon, 10 Apr 2017 19:28:34 -0700 Subject: [PATCH 102/127] Work with error refs --- src/core/ext/transport/chttp2/transport/chttp2_transport.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core/ext/transport/chttp2/transport/chttp2_transport.c b/src/core/ext/transport/chttp2/transport/chttp2_transport.c index 0002253dfee..1e9a460628e 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); } } From 3ce4d9c715274d46fb1ca6e6e99dd29ffb183b8f Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Mon, 10 Apr 2017 19:36:37 -0700 Subject: [PATCH 103/127] Remove unused variable --- src/core/ext/transport/chttp2/transport/chttp2_transport.c | 1 - 1 file changed, 1 deletion(-) diff --git a/src/core/ext/transport/chttp2/transport/chttp2_transport.c b/src/core/ext/transport/chttp2/transport/chttp2_transport.c index 1e9a460628e..54c0252fb99 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; } From 62f91a43cd7a7d518807c553be4dc6145fb842ae Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Mon, 10 Apr 2017 19:37:19 -0700 Subject: [PATCH 104/127] Update comments on variables thread safety --- .../ext/transport/chttp2/transport/internal.h | 25 +++++++++++++------ 1 file changed, 18 insertions(+), 7 deletions(-) diff --git a/src/core/ext/transport/chttp2/transport/internal.h b/src/core/ext/transport/chttp2/transport/internal.h index d5767c8d8da..cc904178cfa 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; From 64657762f09939f77a6ed6cd635947ab94c6dae0 Mon Sep 17 00:00:00 2001 From: Yuchen Zeng Date: Mon, 10 Apr 2017 22:54:14 -0700 Subject: [PATCH 105/127] Generate projects --- CMakeLists.txt | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 1fcd2d01310..7ef7311627e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -8981,7 +8981,7 @@ if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX) add_executable(bm_cq_multiple_threads test/cpp/microbenchmarks/bm_cq_multiple_threads.cc - third_party/googletest/src/gtest-all.cc + third_party/googletest/googletest/src/gtest-all.cc ) @@ -8998,8 +8998,8 @@ target_include_directories(bm_cq_multiple_threads PRIVATE ${CARES_PLATFORM_INCLUDE_DIR} PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/cares/cares PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include - PRIVATE third_party/googletest/include - PRIVATE third_party/googletest + PRIVATE third_party/googletest/googletest/include + PRIVATE third_party/googletest/googletest PRIVATE ${_gRPC_PROTO_GENS_DIR} ) From a002b2413dac2b8c4304349d549c7f30a9f4aff0 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Tue, 11 Apr 2017 09:19:42 -0700 Subject: [PATCH 106/127] clang-format --- src/core/ext/transport/chttp2/transport/internal.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/core/ext/transport/chttp2/transport/internal.h b/src/core/ext/transport/chttp2/transport/internal.h index cc904178cfa..a10e3886ea1 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 */ From 50858f51c1146f02c24145d033f10b8b1eaa3e45 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Tue, 11 Apr 2017 09:25:36 -0700 Subject: [PATCH 107/127] generate_project --- CMakeLists.txt | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 1fcd2d01310..7ef7311627e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -8981,7 +8981,7 @@ if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX) add_executable(bm_cq_multiple_threads test/cpp/microbenchmarks/bm_cq_multiple_threads.cc - third_party/googletest/src/gtest-all.cc + third_party/googletest/googletest/src/gtest-all.cc ) @@ -8998,8 +8998,8 @@ target_include_directories(bm_cq_multiple_threads PRIVATE ${CARES_PLATFORM_INCLUDE_DIR} PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/cares/cares PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include - PRIVATE third_party/googletest/include - PRIVATE third_party/googletest + PRIVATE third_party/googletest/googletest/include + PRIVATE third_party/googletest/googletest PRIVATE ${_gRPC_PROTO_GENS_DIR} ) From 108a109c02ae38d2253673edde592b17c54fb49c Mon Sep 17 00:00:00 2001 From: Chris Trimble Date: Wed, 11 Jan 2017 18:05:08 -0800 Subject: [PATCH 108/127] Google Compute Metadata hostname fix From within containers (or possibly other scenarios), the metadata hostname might not resolve on GCP. Setting this to the full path guarantees it will resolve. --- src/core/lib/security/credentials/credentials.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core/lib/security/credentials/credentials.h b/src/core/lib/security/credentials/credentials.h index 510b79552a3..89b8e3c0b38 100644 --- a/src/core/lib/security/credentials/credentials.h +++ b/src/core/lib/security/credentials/credentials.h @@ -71,7 +71,7 @@ typedef enum { #define GRPC_SECURE_TOKEN_REFRESH_THRESHOLD_SECS 60 -#define GRPC_COMPUTE_ENGINE_METADATA_HOST "metadata" +#define GRPC_COMPUTE_ENGINE_METADATA_HOST "metadata.google.internal" #define GRPC_COMPUTE_ENGINE_METADATA_TOKEN_PATH \ "/computeMetadata/v1/instance/service-accounts/default/token" From 82d8b28036a5f222b21f38d739f3b6965346f04d Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Tue, 11 Apr 2017 10:08:07 -0700 Subject: [PATCH 109/127] generate_project --- CMakeLists.txt | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 4356fcbb4b2..2b94f861f84 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -8988,7 +8988,7 @@ if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX) add_executable(bm_cq_multiple_threads test/cpp/microbenchmarks/bm_cq_multiple_threads.cc - third_party/googletest/src/gtest-all.cc + third_party/googletest/googletest/src/gtest-all.cc ) @@ -9005,8 +9005,8 @@ target_include_directories(bm_cq_multiple_threads PRIVATE ${CARES_PLATFORM_INCLUDE_DIR} PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/cares/cares PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include - PRIVATE third_party/googletest/include - PRIVATE third_party/googletest + PRIVATE third_party/googletest/googletest/include + PRIVATE third_party/googletest/googletest PRIVATE ${_gRPC_PROTO_GENS_DIR} ) From 9b020019497f5fb9fb035027d55d350450fb4ed0 Mon Sep 17 00:00:00 2001 From: Alexander Polcyn Date: Tue, 11 Apr 2017 10:14:13 -0700 Subject: [PATCH 110/127] get rid of racey sleep 5 and use a cv to wait forever --- src/ruby/spec/generic/rpc_server_pool_spec.rb | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/src/ruby/spec/generic/rpc_server_pool_spec.rb b/src/ruby/spec/generic/rpc_server_pool_spec.rb index 75b40225680..0803ca74ed6 100644 --- a/src/ruby/spec/generic/rpc_server_pool_spec.rb +++ b/src/ruby/spec/generic/rpc_server_pool_spec.rb @@ -52,8 +52,7 @@ describe GRPC::Pool do expect(p.ready_for_work?).to be(false) end - it 'it stops being ready after all workers are busy, ' \ - 'and it becomes ready again after jobs complete' do + it 'it stops being ready after all workers are busy' do p = Pool.new(5) p.start @@ -78,11 +77,6 @@ describe GRPC::Pool do wait = false wait_cv.broadcast end - - # There's a potential race here but it shouldn't ever be - # reached with a 5 second sleep. - sleep 5 - expect(p.ready_for_work?).to be(true) end end @@ -114,10 +108,17 @@ describe GRPC::Pool do it 'stops jobs when there are long running jobs' do p = Pool.new(1) p.start + + wait_forever_mu = Mutex.new + wait_forever_cv = ConditionVariable.new + wait_forever = true + job_running = Queue.new job = proc do job_running.push(Object.new) - sleep(5000) + wait_forever_mu.synchronize do + wait_forever_cv.wait while wait_forever + end end p.schedule(&job) job_running.pop From 1abba9df60d338e66ee52ad2a27d5eda4ffc0a86 Mon Sep 17 00:00:00 2001 From: murgatroid99 Date: Tue, 11 Apr 2017 11:09:25 -0700 Subject: [PATCH 111/127] Fix lower bound on max message size channel arguments --- src/core/lib/channel/message_size_filter.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/core/lib/channel/message_size_filter.c b/src/core/lib/channel/message_size_filter.c index b424c0d2acb..dd173c5b663 100644 --- a/src/core/lib/channel/message_size_filter.c +++ b/src/core/lib/channel/message_size_filter.c @@ -214,14 +214,14 @@ static grpc_error* init_channel_elem(grpc_exec_ctx* exec_ctx, if (strcmp(args->channel_args->args[i].key, GRPC_ARG_MAX_SEND_MESSAGE_LENGTH) == 0) { const grpc_integer_options options = { - GRPC_DEFAULT_MAX_SEND_MESSAGE_LENGTH, 0, INT_MAX}; + GRPC_DEFAULT_MAX_SEND_MESSAGE_LENGTH, -1, INT_MAX}; chand->max_send_size = grpc_channel_arg_get_integer(&args->channel_args->args[i], options); } if (strcmp(args->channel_args->args[i].key, GRPC_ARG_MAX_RECEIVE_MESSAGE_LENGTH) == 0) { const grpc_integer_options options = { - GRPC_DEFAULT_MAX_RECV_MESSAGE_LENGTH, 0, INT_MAX}; + GRPC_DEFAULT_MAX_RECV_MESSAGE_LENGTH, -1, INT_MAX}; chand->max_recv_size = grpc_channel_arg_get_integer(&args->channel_args->args[i], options); } From 3e1f562a2b5f33ce781485fa90f92c0406718876 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Tue, 11 Apr 2017 14:05:28 -0700 Subject: [PATCH 112/127] clang-format --- src/core/ext/transport/cronet/transport/cronet_transport.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/core/ext/transport/cronet/transport/cronet_transport.c b/src/core/ext/transport/cronet/transport/cronet_transport.c index 3ca6b2fdf69..88335ecd0be 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, From 654c367cb667f9125c3c101beb115c13274c182f Mon Sep 17 00:00:00 2001 From: Matt Kwong Date: Tue, 11 Apr 2017 14:31:39 -0700 Subject: [PATCH 113/127] Update VM creation scripts to update Linux kernel --- tools/gce/linux_performance_worker_init.sh | 23 +++++++++++++++++----- tools/gce/linux_worker_init.sh | 12 +++++++++-- 2 files changed, 28 insertions(+), 7 deletions(-) diff --git a/tools/gce/linux_performance_worker_init.sh b/tools/gce/linux_performance_worker_init.sh index 641271214ee..17f36fb4ff8 100755 --- a/tools/gce/linux_performance_worker_init.sh +++ b/tools/gce/linux_performance_worker_init.sh @@ -40,11 +40,6 @@ sudo apt-get update sudo apt-get install -y openjdk-8-jdk sudo apt-get install -y unzip lsof -# Add pubkey of jenkins@grpc-jenkins-master to authorized keys of jenkins@ -# This needs to happen as the last step to prevent Jenkins master from connecting -# to a machine that hasn't been properly setup yet. -cat jenkins_master.pub | sudo tee --append ~jenkins/.ssh/authorized_keys - sudo apt-get install -y \ autoconf \ autotools-dev \ @@ -169,3 +164,21 @@ git clone -v https://github.com/brendangregg/FlameGraph ~/FlameGraph # Install scipy and numpy for benchmarking scripts sudo apt-get install python-scipy python-numpy + +# Update Linux kernel to 4.9 +wget \ + kernel.ubuntu.com/~kernel-ppa/mainline/v4.9.20/linux-headers-4.9.20-040920_4.9.20-040920.201703310531_all.deb \ + kernel.ubuntu.com/~kernel-ppa/mainline/v4.9.20/linux-headers-4.9.20-040920-generic_4.9.20-040920.201703310531_amd64.deb \ + kernel.ubuntu.com/~kernel-ppa/mainline/v4.9.20/linux-image-4.9.20-040920-generic_4.9.20-040920.201703310531_amd64.deb +sudo dpkg -i linux-headers-4.9*.deb linux-image-4.9*.deb +rm linux-* + +# Add pubkey of jenkins@grpc-jenkins-master to authorized keys of jenkins@ +# This needs to happen as the last step to prevent Jenkins master from connecting +# to a machine that hasn't been properly setup yet. +cat jenkins_master.pub | sudo tee --append ~jenkins/.ssh/authorized_keys + +# Restart for VM to pick up kernel update +echo 'Successfully initialized the linux worker, going for reboot in 10 seconds' +sleep 10 +sudo reboot diff --git a/tools/gce/linux_worker_init.sh b/tools/gce/linux_worker_init.sh index 9230acdca6d..d552343bde6 100755 --- a/tools/gce/linux_worker_init.sh +++ b/tools/gce/linux_worker_init.sh @@ -59,19 +59,27 @@ sudo usermod -aG docker jenkins # Use "overlay" storage driver for docker # see https://github.com/grpc/grpc/issues/4988 -echo 'DOCKER_OPTS="${DOCKER_OPTS} --storage-driver=overlay"' | sudo tee --append /etc/default/docker +printf "{\n\t\"storage-driver\": \"overlay\"\n}" | sudo tee /etc/docker/daemon.json # Install RVM # TODO(jtattermusch): why is RVM needed? gpg --keyserver hkp://keys.gnupg.net --recv-keys 409B6B1796C275462A1703113804BB82D39DC0E3 curl -sSL https://get.rvm.io | bash -s stable --ruby +# Upgrade Linux kernel to 4.9 +wget \ + kernel.ubuntu.com/~kernel-ppa/mainline/v4.9.20/linux-headers-4.9.20-040920_4.9.20-040920.201703310531_all.deb \ + kernel.ubuntu.com/~kernel-ppa/mainline/v4.9.20/linux-headers-4.9.20-040920-generic_4.9.20-040920.201703310531_amd64.deb \ + kernel.ubuntu.com/~kernel-ppa/mainline/v4.9.20/linux-image-4.9.20-040920-generic_4.9.20-040920.201703310531_amd64.deb +sudo dpkg -i linux-headers-4.9*.deb linux-image-4.9*.deb +rm linux-* + # Add pubkey of jenkins@grpc-jenkins-master to authorized keys of jenkins@ # This needs to happen as the last step to prevent Jenkins master from connecting # to a machine that hasn't been properly setup yet. cat jenkins_master.pub | sudo tee --append ~jenkins/.ssh/authorized_keys -# Restart for docker to pickup the config changes. +# Restart for docker to pick up the config changes. echo 'Successfully initialized the linux worker, going for reboot in 10 seconds' sleep 10 From eceec8eaf6f38766364b203e92ccb6b25028b89b Mon Sep 17 00:00:00 2001 From: yang-g Date: Mon, 10 Apr 2017 11:58:44 -0700 Subject: [PATCH 114/127] Add helper function to supply and parse error_details from Status. --- BUILD | 16 ++ CMakeLists.txt | 109 ++++++++++ Makefile | 159 +++++++++++++- build.yaml | 22 ++ include/grpc++/impl/codegen/status.h | 2 +- include/grpc++/support/error_details.h | 61 ++++++ src/cpp/util/error_details.cc | 62 ++++++ src/proto/grpc/status/BUILD | 43 ++++ src/proto/grpc/status/README | 2 + src/proto/grpc/status/status.proto | 92 ++++++++ test/cpp/util/BUILD | 15 +- test/cpp/util/error_details_test.cc | 120 +++++++++++ .../generated/sources_and_headers.json | 37 ++++ tools/run_tests/generated/tests.json | 22 ++ vsprojects/grpc.sln | 24 +++ .../grpc++_error_details.vcxproj | 178 +++++++++++++++ .../grpc++_error_details.vcxproj.filters | 47 ++++ .../error_details_test.vcxproj | 203 ++++++++++++++++++ .../error_details_test.vcxproj.filters | 36 ++++ 19 files changed, 1246 insertions(+), 4 deletions(-) create mode 100644 include/grpc++/support/error_details.h create mode 100644 src/cpp/util/error_details.cc create mode 100644 src/proto/grpc/status/BUILD create mode 100644 src/proto/grpc/status/README create mode 100644 src/proto/grpc/status/status.proto create mode 100644 test/cpp/util/error_details_test.cc create mode 100644 vsprojects/vcxproj/grpc++_error_details/grpc++_error_details.vcxproj create mode 100644 vsprojects/vcxproj/grpc++_error_details/grpc++_error_details.vcxproj.filters create mode 100644 vsprojects/vcxproj/test/error_details_test/error_details_test.vcxproj create mode 100644 vsprojects/vcxproj/test/error_details_test/error_details_test.vcxproj.filters diff --git a/BUILD b/BUILD index ab4c1cff17f..7890a89df8f 100644 --- a/BUILD +++ b/BUILD @@ -164,6 +164,22 @@ grpc_cc_library( ], ) +grpc_cc_library( + name = "grpc++_error_details", + srcs = [ + "src/cpp/util/error_details.cc", + ], + hdrs = [ + "include/grpc++/support/error_details.h", + ], + language = "c++", + standalone = True, + deps = [ + "grpc++", + "//src/proto/grpc/status:status_proto", + ], +) + grpc_cc_library( name = "grpc_plugin_support", srcs = [ diff --git a/CMakeLists.txt b/CMakeLists.txt index 2b94f861f84..08bf646c823 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -661,6 +661,7 @@ add_dependencies(buildtests_cxx cxx_slice_test) add_dependencies(buildtests_cxx cxx_string_ref_test) add_dependencies(buildtests_cxx cxx_time_test) add_dependencies(buildtests_cxx end2end_test) +add_dependencies(buildtests_cxx error_details_test) add_dependencies(buildtests_cxx filter_end2end_test) add_dependencies(buildtests_cxx generic_end2end_test) add_dependencies(buildtests_cxx golden_file_test) @@ -2900,6 +2901,72 @@ if (gRPC_INSTALL) ) endif() + +add_library(grpc++_error_details + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/status/status.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/status/status.grpc.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/status/status.pb.h + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/status/status.grpc.pb.h + src/cpp/util/error_details.cc +) + +if(WIN32 AND MSVC) + set_target_properties(grpc++_error_details PROPERTIES COMPILE_PDB_NAME "grpc++_error_details" + COMPILE_PDB_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}" + ) + if (gRPC_INSTALL) + install(FILES ${CMAKE_CURRENT_BINARY_DIR}/grpc++_error_details.pdb + DESTINATION ${CMAKE_INSTALL_LIBDIR} OPTIONAL + ) + endif() +endif() + +protobuf_generate_grpc_cpp( + src/proto/grpc/status/status.proto +) + +target_include_directories(grpc++_error_details + PRIVATE ${CMAKE_CURRENT_SOURCE_DIR} + PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include + PRIVATE ${BORINGSSL_ROOT_DIR}/include + PRIVATE ${PROTOBUF_ROOT_DIR}/src + PRIVATE ${ZLIB_INCLUDE_DIR} + PRIVATE ${BENCHMARK}/include + PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib + PRIVATE ${CARES_BUILD_INCLUDE_DIR} + PRIVATE ${CARES_INCLUDE_DIR} + PRIVATE ${CARES_PLATFORM_INCLUDE_DIR} + PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/cares/cares + PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include + PRIVATE ${_gRPC_PROTO_GENS_DIR} +) + +target_link_libraries(grpc++_error_details + ${_gRPC_BASELIB_LIBRARIES} + ${_gRPC_PROTOBUF_LIBRARIES} + ${_gRPC_ALLTARGETS_LIBRARIES} + grpc++ +) + +foreach(_hdr + include/grpc++/support/error_details.h +) + string(REPLACE "include/" "" _path ${_hdr}) + get_filename_component(_path ${_path} PATH) + install(FILES ${_hdr} + DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}/${_path}" + ) +endforeach() + + +if (gRPC_INSTALL) + install(TARGETS grpc++_error_details EXPORT gRPCTargets + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} + LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} + ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} + ) +endif() + if (gRPC_BUILD_TESTS) add_library(grpc++_proto_reflection_desc_db @@ -9884,6 +9951,48 @@ target_link_libraries(end2end_test endif (gRPC_BUILD_TESTS) if (gRPC_BUILD_TESTS) +add_executable(error_details_test + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo_messages.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo_messages.grpc.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo_messages.pb.h + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo_messages.grpc.pb.h + test/cpp/util/error_details_test.cc + third_party/googletest/googletest/src/gtest-all.cc +) + +protobuf_generate_grpc_cpp( + src/proto/grpc/testing/echo_messages.proto +) + +target_include_directories(error_details_test + PRIVATE ${CMAKE_CURRENT_SOURCE_DIR} + PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include + PRIVATE ${BORINGSSL_ROOT_DIR}/include + PRIVATE ${PROTOBUF_ROOT_DIR}/src + PRIVATE ${BENCHMARK_ROOT_DIR}/include + PRIVATE ${ZLIB_ROOT_DIR} + PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib + PRIVATE ${CARES_BUILD_INCLUDE_DIR} + PRIVATE ${CARES_INCLUDE_DIR} + PRIVATE ${CARES_PLATFORM_INCLUDE_DIR} + PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/cares/cares + PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include + PRIVATE third_party/googletest/googletest/include + PRIVATE third_party/googletest/googletest + PRIVATE ${_gRPC_PROTO_GENS_DIR} +) + +target_link_libraries(error_details_test + ${_gRPC_PROTOBUF_LIBRARIES} + ${_gRPC_ALLTARGETS_LIBRARIES} + grpc++_error_details + grpc++ + ${_gRPC_GFLAGS_LIBRARIES} +) + +endif (gRPC_BUILD_TESTS) +if (gRPC_BUILD_TESTS) + add_executable(filter_end2end_test test/cpp/end2end/filter_end2end_test.cc third_party/googletest/googletest/src/gtest-all.cc diff --git a/Makefile b/Makefile index 1fb0ad16dc3..5868664d879 100644 --- a/Makefile +++ b/Makefile @@ -1126,6 +1126,7 @@ cxx_slice_test: $(BINDIR)/$(CONFIG)/cxx_slice_test cxx_string_ref_test: $(BINDIR)/$(CONFIG)/cxx_string_ref_test cxx_time_test: $(BINDIR)/$(CONFIG)/cxx_time_test end2end_test: $(BINDIR)/$(CONFIG)/end2end_test +error_details_test: $(BINDIR)/$(CONFIG)/error_details_test filter_end2end_test: $(BINDIR)/$(CONFIG)/filter_end2end_test generic_end2end_test: $(BINDIR)/$(CONFIG)/generic_end2end_test golden_file_test: $(BINDIR)/$(CONFIG)/golden_file_test @@ -1305,12 +1306,12 @@ static: static_c static_cxx static_c: pc_c pc_c_unsecure cache.mk $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgrpc_cronet.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a -static_cxx: pc_cxx pc_cxx_unsecure cache.mk $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc++_cronet.a $(LIBDIR)/$(CONFIG)/libgrpc++_reflection.a $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure.a +static_cxx: pc_cxx pc_cxx_unsecure cache.mk $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc++_cronet.a $(LIBDIR)/$(CONFIG)/libgrpc++_error_details.a $(LIBDIR)/$(CONFIG)/libgrpc++_reflection.a $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure.a shared: shared_c shared_cxx shared_c: pc_c pc_c_unsecure cache.mk $(LIBDIR)/$(CONFIG)/$(SHARED_PREFIX)gpr$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(LIBDIR)/$(CONFIG)/$(SHARED_PREFIX)grpc$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(LIBDIR)/$(CONFIG)/$(SHARED_PREFIX)grpc_cronet$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(LIBDIR)/$(CONFIG)/$(SHARED_PREFIX)grpc_unsecure$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) -shared_cxx: pc_cxx pc_cxx_unsecure cache.mk $(LIBDIR)/$(CONFIG)/$(SHARED_PREFIX)grpc++$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(LIBDIR)/$(CONFIG)/$(SHARED_PREFIX)grpc++_cronet$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(LIBDIR)/$(CONFIG)/$(SHARED_PREFIX)grpc++_reflection$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(LIBDIR)/$(CONFIG)/$(SHARED_PREFIX)grpc++_unsecure$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) +shared_cxx: pc_cxx pc_cxx_unsecure cache.mk $(LIBDIR)/$(CONFIG)/$(SHARED_PREFIX)grpc++$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(LIBDIR)/$(CONFIG)/$(SHARED_PREFIX)grpc++_cronet$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(LIBDIR)/$(CONFIG)/$(SHARED_PREFIX)grpc++_error_details$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(LIBDIR)/$(CONFIG)/$(SHARED_PREFIX)grpc++_reflection$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(LIBDIR)/$(CONFIG)/$(SHARED_PREFIX)grpc++_unsecure$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) shared_csharp: shared_c $(LIBDIR)/$(CONFIG)/$(SHARED_PREFIX)grpc_csharp_ext$(SHARED_VERSION_CSHARP).$(SHARED_EXT_CSHARP) grpc_csharp_ext: shared_csharp @@ -1552,6 +1553,7 @@ buildtests_cxx: privatelibs_cxx \ $(BINDIR)/$(CONFIG)/cxx_string_ref_test \ $(BINDIR)/$(CONFIG)/cxx_time_test \ $(BINDIR)/$(CONFIG)/end2end_test \ + $(BINDIR)/$(CONFIG)/error_details_test \ $(BINDIR)/$(CONFIG)/filter_end2end_test \ $(BINDIR)/$(CONFIG)/generic_end2end_test \ $(BINDIR)/$(CONFIG)/golden_file_test \ @@ -1671,6 +1673,7 @@ buildtests_cxx: privatelibs_cxx \ $(BINDIR)/$(CONFIG)/cxx_string_ref_test \ $(BINDIR)/$(CONFIG)/cxx_time_test \ $(BINDIR)/$(CONFIG)/end2end_test \ + $(BINDIR)/$(CONFIG)/error_details_test \ $(BINDIR)/$(CONFIG)/filter_end2end_test \ $(BINDIR)/$(CONFIG)/generic_end2end_test \ $(BINDIR)/$(CONFIG)/golden_file_test \ @@ -2040,6 +2043,8 @@ test_cxx: buildtests_cxx $(Q) $(BINDIR)/$(CONFIG)/cxx_time_test || ( echo test cxx_time_test failed ; exit 1 ) $(E) "[RUN] Testing end2end_test" $(Q) $(BINDIR)/$(CONFIG)/end2end_test || ( echo test end2end_test failed ; exit 1 ) + $(E) "[RUN] Testing error_details_test" + $(Q) $(BINDIR)/$(CONFIG)/error_details_test || ( echo test error_details_test failed ; exit 1 ) $(E) "[RUN] Testing filter_end2end_test" $(Q) $(BINDIR)/$(CONFIG)/filter_end2end_test || ( echo test filter_end2end_test failed ; exit 1 ) $(E) "[RUN] Testing generic_end2end_test" @@ -2144,6 +2149,8 @@ ifeq ($(CONFIG),opt) $(Q) $(STRIP) $(LIBDIR)/$(CONFIG)/libgrpc++.a $(E) "[STRIP] Stripping libgrpc++_cronet.a" $(Q) $(STRIP) $(LIBDIR)/$(CONFIG)/libgrpc++_cronet.a + $(E) "[STRIP] Stripping libgrpc++_error_details.a" + $(Q) $(STRIP) $(LIBDIR)/$(CONFIG)/libgrpc++_error_details.a $(E) "[STRIP] Stripping libgrpc++_reflection.a" $(Q) $(STRIP) $(LIBDIR)/$(CONFIG)/libgrpc++_reflection.a $(E) "[STRIP] Stripping libgrpc++_unsecure.a" @@ -2168,6 +2175,8 @@ ifeq ($(CONFIG),opt) $(Q) $(STRIP) $(LIBDIR)/$(CONFIG)/$(SHARED_PREFIX)grpc++$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(E) "[STRIP] Stripping $(SHARED_PREFIX)grpc++_cronet$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP)" $(Q) $(STRIP) $(LIBDIR)/$(CONFIG)/$(SHARED_PREFIX)grpc++_cronet$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) + $(E) "[STRIP] Stripping $(SHARED_PREFIX)grpc++_error_details$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP)" + $(Q) $(STRIP) $(LIBDIR)/$(CONFIG)/$(SHARED_PREFIX)grpc++_error_details$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(E) "[STRIP] Stripping $(SHARED_PREFIX)grpc++_reflection$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP)" $(Q) $(STRIP) $(LIBDIR)/$(CONFIG)/$(SHARED_PREFIX)grpc++_reflection$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(E) "[STRIP] Stripping $(SHARED_PREFIX)grpc++_unsecure$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP)" @@ -2249,6 +2258,21 @@ $(GENDIR)/src/proto/grpc/reflection/v1alpha/reflection.grpc.pb.cc: src/proto/grp $(Q) $(PROTOC) -Ithird_party/protobuf/src -I. --grpc_out=$(GENDIR) --plugin=protoc-gen-grpc=$(PROTOC_PLUGINS_DIR)/grpc_cpp_plugin$(EXECUTABLE_SUFFIX) $< endif +ifeq ($(NO_PROTOC),true) +$(GENDIR)/src/proto/grpc/status/status.pb.cc: protoc_dep_error +$(GENDIR)/src/proto/grpc/status/status.grpc.pb.cc: protoc_dep_error +else +$(GENDIR)/src/proto/grpc/status/status.pb.cc: src/proto/grpc/status/status.proto $(PROTOBUF_DEP) $(PROTOC_PLUGINS) + $(E) "[PROTOC] Generating protobuf CC file from $<" + $(Q) mkdir -p `dirname $@` + $(Q) $(PROTOC) -Ithird_party/protobuf/src -I. --cpp_out=$(GENDIR) $< + +$(GENDIR)/src/proto/grpc/status/status.grpc.pb.cc: src/proto/grpc/status/status.proto $(PROTOBUF_DEP) $(PROTOC_PLUGINS) + $(E) "[GRPC] Generating gRPC's protobuf service CC file from $<" + $(Q) mkdir -p `dirname $@` + $(Q) $(PROTOC) -Ithird_party/protobuf/src -I. --grpc_out=$(GENDIR) --plugin=protoc-gen-grpc=$(PROTOC_PLUGINS_DIR)/grpc_cpp_plugin$(EXECUTABLE_SUFFIX) $< +endif + ifeq ($(NO_PROTOC),true) $(GENDIR)/src/proto/grpc/testing/compiler_test.pb.cc: protoc_dep_error $(GENDIR)/src/proto/grpc/testing/compiler_test.grpc.pb.cc: protoc_dep_error @@ -2507,6 +2531,9 @@ install-static_cxx: static_cxx strip-static_cxx install-pkg-config_cxx $(E) "[INSTALL] Installing libgrpc++_cronet.a" $(Q) $(INSTALL) -d $(prefix)/lib $(Q) $(INSTALL) $(LIBDIR)/$(CONFIG)/libgrpc++_cronet.a $(prefix)/lib/libgrpc++_cronet.a + $(E) "[INSTALL] Installing libgrpc++_error_details.a" + $(Q) $(INSTALL) -d $(prefix)/lib + $(Q) $(INSTALL) $(LIBDIR)/$(CONFIG)/libgrpc++_error_details.a $(prefix)/lib/libgrpc++_error_details.a $(E) "[INSTALL] Installing libgrpc++_reflection.a" $(Q) $(INSTALL) -d $(prefix)/lib $(Q) $(INSTALL) $(LIBDIR)/$(CONFIG)/libgrpc++_reflection.a $(prefix)/lib/libgrpc++_reflection.a @@ -2578,6 +2605,15 @@ ifeq ($(SYSTEM),MINGW32) else ifneq ($(SYSTEM),Darwin) $(Q) ln -sf $(SHARED_PREFIX)grpc++_cronet$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(prefix)/lib/libgrpc++_cronet.so.3 $(Q) ln -sf $(SHARED_PREFIX)grpc++_cronet$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(prefix)/lib/libgrpc++_cronet.so +endif + $(E) "[INSTALL] Installing $(SHARED_PREFIX)grpc++_error_details$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP)" + $(Q) $(INSTALL) -d $(prefix)/lib + $(Q) $(INSTALL) $(LIBDIR)/$(CONFIG)/$(SHARED_PREFIX)grpc++_error_details$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(prefix)/lib/$(SHARED_PREFIX)grpc++_error_details$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) +ifeq ($(SYSTEM),MINGW32) + $(Q) $(INSTALL) $(LIBDIR)/$(CONFIG)/libgrpc++_error_details$(SHARED_VERSION_CPP)-dll.a $(prefix)/lib/libgrpc++_error_details.a +else ifneq ($(SYSTEM),Darwin) + $(Q) ln -sf $(SHARED_PREFIX)grpc++_error_details$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(prefix)/lib/libgrpc++_error_details.so.3 + $(Q) ln -sf $(SHARED_PREFIX)grpc++_error_details$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(prefix)/lib/libgrpc++_error_details.so endif $(E) "[INSTALL] Installing $(SHARED_PREFIX)grpc++_reflection$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP)" $(Q) $(INSTALL) -d $(prefix)/lib @@ -4770,6 +4806,77 @@ endif endif +LIBGRPC++_ERROR_DETAILS_SRC = \ + $(GENDIR)/src/proto/grpc/status/status.pb.cc $(GENDIR)/src/proto/grpc/status/status.grpc.pb.cc \ + src/cpp/util/error_details.cc \ + +PUBLIC_HEADERS_CXX += \ + include/grpc++/support/error_details.h \ + +LIBGRPC++_ERROR_DETAILS_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(LIBGRPC++_ERROR_DETAILS_SRC)))) + + +ifeq ($(NO_SECURE),true) + +# You can't build secure libraries if you don't have OpenSSL. + +$(LIBDIR)/$(CONFIG)/libgrpc++_error_details.a: openssl_dep_error + +$(LIBDIR)/$(CONFIG)/$(SHARED_PREFIX)grpc++_error_details$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP): openssl_dep_error + +else + +ifeq ($(NO_PROTOBUF),true) + +# You can't build a C++ library if you don't have protobuf - a bit overreached, but still okay. + +$(LIBDIR)/$(CONFIG)/libgrpc++_error_details.a: protobuf_dep_error + +$(LIBDIR)/$(CONFIG)/$(SHARED_PREFIX)grpc++_error_details$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP): protobuf_dep_error + +else + +$(LIBDIR)/$(CONFIG)/libgrpc++_error_details.a: $(ZLIB_DEP) $(OPENSSL_DEP) $(CARES_DEP) $(PROTOBUF_DEP) $(LIBGRPC++_ERROR_DETAILS_OBJS) $(LIBGPR_OBJS) $(ZLIB_MERGE_OBJS) $(CARES_MERGE_OBJS) + $(E) "[AR] Creating $@" + $(Q) mkdir -p `dirname $@` + $(Q) rm -f $(LIBDIR)/$(CONFIG)/libgrpc++_error_details.a + $(Q) $(AR) $(AROPTS) $(LIBDIR)/$(CONFIG)/libgrpc++_error_details.a $(LIBGRPC++_ERROR_DETAILS_OBJS) $(LIBGPR_OBJS) $(ZLIB_MERGE_OBJS) $(CARES_MERGE_OBJS) +ifeq ($(SYSTEM),Darwin) + $(Q) ranlib -no_warning_for_no_symbols $(LIBDIR)/$(CONFIG)/libgrpc++_error_details.a +endif + + + +ifeq ($(SYSTEM),MINGW32) +$(LIBDIR)/$(CONFIG)/grpc++_error_details$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP): $(LIBGRPC++_ERROR_DETAILS_OBJS) $(ZLIB_DEP) $(CARES_DEP) $(PROTOBUF_DEP) $(LIBDIR)/$(CONFIG)/grpc++$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(OPENSSL_DEP) + $(E) "[LD] Linking $@" + $(Q) mkdir -p `dirname $@` + $(Q) $(LDXX) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -shared -Wl,--output-def=$(LIBDIR)/$(CONFIG)/grpc++_error_details$(SHARED_VERSION_CPP).def -Wl,--out-implib=$(LIBDIR)/$(CONFIG)/libgrpc++_error_details$(SHARED_VERSION_CPP)-dll.a -o $(LIBDIR)/$(CONFIG)/grpc++_error_details$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(LIBGRPC++_ERROR_DETAILS_OBJS) $(ZLIB_MERGE_LIBS) $(CARES_MERGE_LIBS) $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) -lgrpc++$(SHARED_VERSION_CPP)-dll +else +$(LIBDIR)/$(CONFIG)/libgrpc++_error_details$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP): $(LIBGRPC++_ERROR_DETAILS_OBJS) $(ZLIB_DEP) $(CARES_DEP) $(PROTOBUF_DEP) $(LIBDIR)/$(CONFIG)/libgrpc++.$(SHARED_EXT_CPP) $(OPENSSL_DEP) + $(E) "[LD] Linking $@" + $(Q) mkdir -p `dirname $@` +ifeq ($(SYSTEM),Darwin) + $(Q) $(LDXX) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -install_name $(SHARED_PREFIX)grpc++_error_details$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) -dynamiclib -o $(LIBDIR)/$(CONFIG)/libgrpc++_error_details$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(LIBGRPC++_ERROR_DETAILS_OBJS) $(ZLIB_MERGE_LIBS) $(CARES_MERGE_LIBS) $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) -lgrpc++ +else + $(Q) $(LDXX) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -shared -Wl,-soname,libgrpc++_error_details.so.3 -o $(LIBDIR)/$(CONFIG)/libgrpc++_error_details$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(LIBGRPC++_ERROR_DETAILS_OBJS) $(ZLIB_MERGE_LIBS) $(CARES_MERGE_LIBS) $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) -lgrpc++ + $(Q) ln -sf $(SHARED_PREFIX)grpc++_error_details$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(LIBDIR)/$(CONFIG)/libgrpc++_error_details$(SHARED_VERSION_CPP).so.1 + $(Q) ln -sf $(SHARED_PREFIX)grpc++_error_details$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(LIBDIR)/$(CONFIG)/libgrpc++_error_details$(SHARED_VERSION_CPP).so +endif +endif + +endif + +endif + +ifneq ($(NO_SECURE),true) +ifneq ($(NO_DEPS),true) +-include $(LIBGRPC++_ERROR_DETAILS_OBJS:.o=.dep) +endif +endif +$(OBJDIR)/$(CONFIG)/src/cpp/util/error_details.o: $(GENDIR)/src/proto/grpc/status/status.pb.cc $(GENDIR)/src/proto/grpc/status/status.grpc.pb.cc + + LIBGRPC++_PROTO_REFLECTION_DESC_DB_SRC = \ test/cpp/util/proto_reflection_descriptor_database.cc \ $(GENDIR)/src/proto/grpc/reflection/v1alpha/reflection.pb.cc $(GENDIR)/src/proto/grpc/reflection/v1alpha/reflection.grpc.pb.cc \ @@ -14319,6 +14426,53 @@ endif endif +ERROR_DETAILS_TEST_SRC = \ + $(GENDIR)/src/proto/grpc/testing/echo_messages.pb.cc $(GENDIR)/src/proto/grpc/testing/echo_messages.grpc.pb.cc \ + test/cpp/util/error_details_test.cc \ + +ERROR_DETAILS_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(ERROR_DETAILS_TEST_SRC)))) +ifeq ($(NO_SECURE),true) + +# You can't build secure targets if you don't have OpenSSL. + +$(BINDIR)/$(CONFIG)/error_details_test: openssl_dep_error + +else + + + + +ifeq ($(NO_PROTOBUF),true) + +# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.0.0+. + +$(BINDIR)/$(CONFIG)/error_details_test: protobuf_dep_error + +else + +$(BINDIR)/$(CONFIG)/error_details_test: $(PROTOBUF_DEP) $(ERROR_DETAILS_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_error_details.a $(LIBDIR)/$(CONFIG)/libgrpc++.a + $(E) "[LD] Linking $@" + $(Q) mkdir -p `dirname $@` + $(Q) $(LDXX) $(LDFLAGS) $(ERROR_DETAILS_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_error_details.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/error_details_test + +endif + +endif + +$(OBJDIR)/$(CONFIG)/src/proto/grpc/testing/echo_messages.o: $(LIBDIR)/$(CONFIG)/libgrpc++_error_details.a $(LIBDIR)/$(CONFIG)/libgrpc++.a + +$(OBJDIR)/$(CONFIG)/test/cpp/util/error_details_test.o: $(LIBDIR)/$(CONFIG)/libgrpc++_error_details.a $(LIBDIR)/$(CONFIG)/libgrpc++.a + +deps_error_details_test: $(ERROR_DETAILS_TEST_OBJS:.o=.dep) + +ifneq ($(NO_SECURE),true) +ifneq ($(NO_DEPS),true) +-include $(ERROR_DETAILS_TEST_OBJS:.o=.dep) +endif +endif +$(OBJDIR)/$(CONFIG)/test/cpp/util/error_details_test.o: $(GENDIR)/src/proto/grpc/testing/echo_messages.pb.cc $(GENDIR)/src/proto/grpc/testing/echo_messages.grpc.pb.cc + + FILTER_END2END_TEST_SRC = \ test/cpp/end2end/filter_end2end_test.cc \ @@ -19273,6 +19427,7 @@ src/cpp/common/secure_create_auth_context.cc: $(OPENSSL_DEP) src/cpp/ext/proto_server_reflection.cc: $(OPENSSL_DEP) src/cpp/ext/proto_server_reflection_plugin.cc: $(OPENSSL_DEP) src/cpp/server/secure_server_credentials.cc: $(OPENSSL_DEP) +src/cpp/util/error_details.cc: $(OPENSSL_DEP) src/csharp/ext/grpc_csharp_ext.c: $(OPENSSL_DEP) test/core/bad_client/bad_client.c: $(OPENSSL_DEP) test/core/bad_ssl/server_common.c: $(OPENSSL_DEP) diff --git a/build.yaml b/build.yaml index 2dca6526a67..1b3cd7e8d13 100644 --- a/build.yaml +++ b/build.yaml @@ -1175,6 +1175,18 @@ libs: platforms: - linux secure: true +- name: grpc++_error_details + build: all + language: c++ + public_headers: + - include/grpc++/support/error_details.h + src: + - src/proto/grpc/status/status.proto + - src/cpp/util/error_details.cc + deps: + - grpc++ + baselib: true + vs_project_guid: '{9F58AD72-49E1-4D10-B826-9E190AB0AAC0}' - name: grpc++_proto_reflection_desc_db build: private language: c++ @@ -3567,6 +3579,16 @@ targets: - grpc - gpr_test_util - gpr +- name: error_details_test + gtest: true + build: test + language: c++ + src: + - src/proto/grpc/testing/echo_messages.proto + - test/cpp/util/error_details_test.cc + deps: + - grpc++_error_details + - grpc++ - name: filter_end2end_test gtest: true build: test diff --git a/include/grpc++/impl/codegen/status.h b/include/grpc++/impl/codegen/status.h index 5cce3c1672e..31fd6cdbe78 100644 --- a/include/grpc++/impl/codegen/status.h +++ b/include/grpc++/impl/codegen/status.h @@ -53,7 +53,7 @@ class Status { /// Construct an instance with \a code, \a error_message and \a error_details Status(StatusCode code, const grpc::string& error_message, - const grpc::string error_details) + const grpc::string& error_details) : code_(code), error_message_(error_message), binary_error_details_(error_details) {} diff --git a/include/grpc++/support/error_details.h b/include/grpc++/support/error_details.h new file mode 100644 index 00000000000..411175fb46c --- /dev/null +++ b/include/grpc++/support/error_details.h @@ -0,0 +1,61 @@ +/* + * + * Copyright 2017, 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. + * + */ + +#ifndef GRPCXX_SUPPORT_ERROR_DETAILS_H +#define GRPCXX_SUPPORT_ERROR_DETAILS_H + +#include + +namespace google { +namespace rpc { +class Status; +} // namespace rpc +} // namespace google + +namespace grpc { + +// Maps a grpc::Status to a google::rpc::Status. +// The given \a to object will be cleared. +// On success, returns status with OK. +// Returns status with INVALID_ARGUMENT, if failed to deserialize. +// Returns status with FAILED_PRECONDITION, if \a to is nullptr. +Status ExtractErrorDetails(const Status& from, ::google::rpc::Status* to); + +// Maps google::rpc::Status to a grpc::Status. +// Returns OK on success. +// Returns status with FAILED_PRECONDITION if \a to is nullptr. +Status SetErrorDetails(const ::google::rpc::Status& from, Status* to); + +} // namespace grpc + +#endif // GRPCXX_SUPPORT_ERROR_DETAILS_H diff --git a/src/cpp/util/error_details.cc b/src/cpp/util/error_details.cc new file mode 100644 index 00000000000..8bba05ac7d6 --- /dev/null +++ b/src/cpp/util/error_details.cc @@ -0,0 +1,62 @@ +/* + * + * Copyright 2017, 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. + * + */ + +#include + +#include "src/proto/grpc/status/status.pb.h" + +namespace grpc { + +Status ExtractErrorDetails(const Status& from, ::google::rpc::Status* to) { + if (to == nullptr) { + return Status(StatusCode::FAILED_PRECONDITION, ""); + } + if (!to->ParseFromString(from.error_details())) { + return Status(StatusCode::INVALID_ARGUMENT, ""); + } + return Status::OK; +} + +Status SetErrorDetails(const ::google::rpc::Status& from, Status* to) { + if (to == nullptr) { + return Status(StatusCode::FAILED_PRECONDITION, ""); + } + StatusCode code = StatusCode::UNKNOWN; + if (from.code() >= StatusCode::OK && from.code() <= StatusCode::DATA_LOSS) { + code = static_cast(from.code()); + } + *to = Status(code, from.message(), from.SerializeAsString()); + return Status::OK; +} + +} // namespace grpc diff --git a/src/proto/grpc/status/BUILD b/src/proto/grpc/status/BUILD new file mode 100644 index 00000000000..c17f87eb3de --- /dev/null +++ b/src/proto/grpc/status/BUILD @@ -0,0 +1,43 @@ +# Copyright 2017, 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. + +licenses(["notice"]) # 3-clause BSD + +package(default_visibility = ["//visibility:public"]) + +load("//bazel:grpc_build_system.bzl", "grpc_proto_library") + +grpc_proto_library( + name = "status_proto", + srcs = ["status.proto"], + has_services = False, + well_known_protos = "@submodule_protobuf//:well_known_protos", +) + + diff --git a/src/proto/grpc/status/README b/src/proto/grpc/status/README new file mode 100644 index 00000000000..34e588efac9 --- /dev/null +++ b/src/proto/grpc/status/README @@ -0,0 +1,2 @@ +The status.proto file is copied from +https://github.com/googleapis/googleapis/blob/master/google/rpc/status.proto. diff --git a/src/proto/grpc/status/status.proto b/src/proto/grpc/status/status.proto new file mode 100644 index 00000000000..bc6097b29fb --- /dev/null +++ b/src/proto/grpc/status/status.proto @@ -0,0 +1,92 @@ +// Copyright 2016 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +syntax = "proto3"; + +package google.rpc; + +import "google/protobuf/any.proto"; + +option go_package = "google.golang.org/genproto/googleapis/rpc/status;status"; +option java_multiple_files = true; +option java_outer_classname = "StatusProto"; +option java_package = "com.google.rpc"; +option objc_class_prefix = "RPC"; + + +// The `Status` type defines a logical error model that is suitable for different +// programming environments, including REST APIs and RPC APIs. It is used by +// [gRPC](https://github.com/grpc). The error model is designed to be: +// +// - Simple to use and understand for most users +// - Flexible enough to meet unexpected needs +// +// # Overview +// +// The `Status` message contains three pieces of data: error code, error message, +// and error details. The error code should be an enum value of +// [google.rpc.Code][google.rpc.Code], but it may accept additional error codes if needed. The +// error message should be a developer-facing English message that helps +// developers *understand* and *resolve* the error. If a localized user-facing +// error message is needed, put the localized message in the error details or +// localize it in the client. The optional error details may contain arbitrary +// information about the error. There is a predefined set of error detail types +// in the package `google.rpc` which can be used for common error conditions. +// +// # Language mapping +// +// The `Status` message is the logical representation of the error model, but it +// is not necessarily the actual wire format. When the `Status` message is +// exposed in different client libraries and different wire protocols, it can be +// mapped differently. For example, it will likely be mapped to some exceptions +// in Java, but more likely mapped to some error codes in C. +// +// # Other uses +// +// The error model and the `Status` message can be used in a variety of +// environments, either with or without APIs, to provide a +// consistent developer experience across different environments. +// +// Example uses of this error model include: +// +// - Partial errors. If a service needs to return partial errors to the client, +// it may embed the `Status` in the normal response to indicate the partial +// errors. +// +// - Workflow errors. A typical workflow has multiple steps. Each step may +// have a `Status` message for error reporting purpose. +// +// - Batch operations. If a client uses batch request and batch response, the +// `Status` message should be used directly inside batch response, one for +// each error sub-response. +// +// - Asynchronous operations. If an API call embeds asynchronous operation +// results in its response, the status of those operations should be +// represented directly using the `Status` message. +// +// - Logging. If some API errors are stored in logs, the message `Status` could +// be used directly after any stripping needed for security/privacy reasons. +message Status { + // The status code, which should be an enum value of [google.rpc.Code][google.rpc.Code]. + int32 code = 1; + + // A developer-facing error message, which should be in English. Any + // user-facing error message should be localized and sent in the + // [google.rpc.Status.details][google.rpc.Status.details] field, or localized by the client. + string message = 2; + + // A list of messages that carry the error details. There will be a + // common set of message types for APIs to use. + repeated google.protobuf.Any details = 3; +} diff --git a/test/cpp/util/BUILD b/test/cpp/util/BUILD index dc90a4e172c..7471ce75dd3 100644 --- a/test/cpp/util/BUILD +++ b/test/cpp/util/BUILD @@ -62,7 +62,6 @@ cc_library( cc_library( name = "test_util", srcs = [ - # "test/cpp/end2end/test_service_impl.cc", "byte_buffer_proto_helper.cc", "create_test_channel.cc", "string_ref_helper.cc", @@ -83,3 +82,17 @@ cc_library( "//test/core/util:gpr_test_util", ], ) + +cc_test( + name = "error_details_test", + srcs = [ + "error_details_test.cc", + ], + deps = [ + "//external:gtest", + "//:grpc++_error_details", + ], +) + + + diff --git a/test/cpp/util/error_details_test.cc b/test/cpp/util/error_details_test.cc new file mode 100644 index 00000000000..d01fd3b0870 --- /dev/null +++ b/test/cpp/util/error_details_test.cc @@ -0,0 +1,120 @@ +/* + * + * Copyright 2017, 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. + * + */ + +#include +#include + +#include "src/proto/grpc/status/status.pb.h" +#include "src/proto/grpc/testing/echo_messages.pb.h" + +namespace grpc { +namespace { + +TEST(ExtractTest, Success) { + google::rpc::Status expected; + expected.set_code(13); // INTERNAL + expected.set_message("I am an error message"); + testing::EchoRequest expected_details; + expected_details.set_message(grpc::string(100, '\0')); + expected.add_details()->PackFrom(expected_details); + + google::rpc::Status to; + grpc::string error_details = expected.SerializeAsString(); + Status from(static_cast(expected.code()), expected.message(), + error_details); + EXPECT_TRUE(ExtractErrorDetails(from, &to).ok()); + EXPECT_EQ(expected.code(), to.code()); + EXPECT_EQ(expected.message(), to.message()); + EXPECT_EQ(1, to.details_size()); + testing::EchoRequest details; + to.details(0).UnpackTo(&details); + EXPECT_EQ(expected_details.message(), details.message()); +} + +TEST(ExtractTest, NullInput) { + EXPECT_EQ(StatusCode::FAILED_PRECONDITION, + ExtractErrorDetails(Status(), nullptr).error_code()); +} + +TEST(ExtractTest, Unparsable) { + grpc::string error_details("I am not a status object"); + Status from(StatusCode::INTERNAL, "", error_details); + google::rpc::Status to; + EXPECT_EQ(StatusCode::INVALID_ARGUMENT, + ExtractErrorDetails(from, &to).error_code()); +} + +TEST(SetTest, Success) { + google::rpc::Status expected; + expected.set_code(13); // INTERNAL + expected.set_message("I am an error message"); + testing::EchoRequest expected_details; + expected_details.set_message(grpc::string(100, '\0')); + expected.add_details()->PackFrom(expected_details); + + Status to; + Status s = SetErrorDetails(expected, &to); + EXPECT_TRUE(s.ok()); + EXPECT_EQ(expected.code(), to.error_code()); + EXPECT_EQ(expected.message(), to.error_message()); + EXPECT_EQ(expected.SerializeAsString(), to.error_details()); +} + +TEST(SetTest, NullInput) { + EXPECT_EQ(StatusCode::FAILED_PRECONDITION, + SetErrorDetails(google::rpc::Status(), nullptr).error_code()); +} + +TEST(SetTest, OutOfScopeErrorCode) { + google::rpc::Status expected; + expected.set_code(20); // Out of scope (DATA_LOSS is 15). + expected.set_message("I am an error message"); + testing::EchoRequest expected_details; + expected_details.set_message(grpc::string(100, '\0')); + expected.add_details()->PackFrom(expected_details); + + Status to; + Status s = SetErrorDetails(expected, &to); + EXPECT_TRUE(s.ok()); + EXPECT_EQ(StatusCode::UNKNOWN, to.error_code()); + EXPECT_EQ(expected.message(), to.error_message()); + EXPECT_EQ(expected.SerializeAsString(), to.error_details()); +} + +} // namespace +} // namespace grpc + +int main(int argc, char** argv) { + ::testing::InitGoogleTest(&argc, argv); + return RUN_ALL_TESTS(); +} diff --git a/tools/run_tests/generated/sources_and_headers.json b/tools/run_tests/generated/sources_and_headers.json index 5ee5d0be90a..35e82409822 100644 --- a/tools/run_tests/generated/sources_and_headers.json +++ b/tools/run_tests/generated/sources_and_headers.json @@ -2967,6 +2967,24 @@ "third_party": false, "type": "target" }, + { + "deps": [ + "grpc++", + "grpc++_error_details" + ], + "headers": [ + "src/proto/grpc/testing/echo_messages.grpc.pb.h", + "src/proto/grpc/testing/echo_messages.pb.h" + ], + "is_filegroup": false, + "language": "c++", + "name": "error_details_test", + "src": [ + "test/cpp/util/error_details_test.cc" + ], + "third_party": false, + "type": "target" + }, { "deps": [ "gpr", @@ -5818,6 +5836,25 @@ "third_party": false, "type": "lib" }, + { + "deps": [ + "grpc++" + ], + "headers": [ + "include/grpc++/support/error_details.h", + "src/proto/grpc/status/status.grpc.pb.h", + "src/proto/grpc/status/status.pb.h" + ], + "is_filegroup": false, + "language": "c++", + "name": "grpc++_error_details", + "src": [ + "include/grpc++/support/error_details.h", + "src/cpp/util/error_details.cc" + ], + "third_party": false, + "type": "lib" + }, { "deps": [ "grpc++", diff --git a/tools/run_tests/generated/tests.json b/tools/run_tests/generated/tests.json index 12d48f219d7..530cd2d6b56 100644 --- a/tools/run_tests/generated/tests.json +++ b/tools/run_tests/generated/tests.json @@ -3195,6 +3195,28 @@ "windows" ] }, + { + "args": [], + "ci_platforms": [ + "linux", + "mac", + "posix", + "windows" + ], + "cpu_cost": 1.0, + "exclude_configs": [], + "exclude_iomgrs": [], + "flaky": false, + "gtest": true, + "language": "c++", + "name": "error_details_test", + "platforms": [ + "linux", + "mac", + "posix", + "windows" + ] + }, { "args": [], "ci_platforms": [ diff --git a/vsprojects/grpc.sln b/vsprojects/grpc.sln index fbb19c2de6e..97378e0a0f8 100644 --- a/vsprojects/grpc.sln +++ b/vsprojects/grpc.sln @@ -57,6 +57,14 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "grpc++", "vcxproj\.\grpc++\ {B23D3D1A-9438-4EDA-BEB6-9A0A03D17792} = {B23D3D1A-9438-4EDA-BEB6-9A0A03D17792} EndProjectSection EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "grpc++_error_details", "vcxproj\.\grpc++_error_details\grpc++_error_details.vcxproj", "{9F58AD72-49E1-4D10-B826-9E190AB0AAC0}" + ProjectSection(myProperties) = preProject + lib = "True" + EndProjectSection + ProjectSection(ProjectDependencies) = postProject + {C187A093-A0FE-489D-A40A-6E33DE0F9FEB} = {C187A093-A0FE-489D-A40A-6E33DE0F9FEB} + EndProjectSection +EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "grpc++_unsecure", "vcxproj\.\grpc++_unsecure\grpc++_unsecure.vcxproj", "{6EE56155-DF7C-4F6E-BFC4-F6F776BEB211}" ProjectSection(myProperties) = preProject lib = "True" @@ -294,6 +302,22 @@ Global {C187A093-A0FE-489D-A40A-6E33DE0F9FEB}.Release-DLL|Win32.Build.0 = Release-DLL|Win32 {C187A093-A0FE-489D-A40A-6E33DE0F9FEB}.Release-DLL|x64.ActiveCfg = Release-DLL|x64 {C187A093-A0FE-489D-A40A-6E33DE0F9FEB}.Release-DLL|x64.Build.0 = Release-DLL|x64 + {9F58AD72-49E1-4D10-B826-9E190AB0AAC0}.Debug|Win32.ActiveCfg = Debug|Win32 + {9F58AD72-49E1-4D10-B826-9E190AB0AAC0}.Debug|x64.ActiveCfg = Debug|x64 + {9F58AD72-49E1-4D10-B826-9E190AB0AAC0}.Release|Win32.ActiveCfg = Release|Win32 + {9F58AD72-49E1-4D10-B826-9E190AB0AAC0}.Release|x64.ActiveCfg = Release|x64 + {9F58AD72-49E1-4D10-B826-9E190AB0AAC0}.Debug|Win32.Build.0 = Debug|Win32 + {9F58AD72-49E1-4D10-B826-9E190AB0AAC0}.Debug|x64.Build.0 = Debug|x64 + {9F58AD72-49E1-4D10-B826-9E190AB0AAC0}.Release|Win32.Build.0 = Release|Win32 + {9F58AD72-49E1-4D10-B826-9E190AB0AAC0}.Release|x64.Build.0 = Release|x64 + {9F58AD72-49E1-4D10-B826-9E190AB0AAC0}.Debug-DLL|Win32.ActiveCfg = Debug|Win32 + {9F58AD72-49E1-4D10-B826-9E190AB0AAC0}.Debug-DLL|Win32.Build.0 = Debug|Win32 + {9F58AD72-49E1-4D10-B826-9E190AB0AAC0}.Debug-DLL|x64.ActiveCfg = Debug|x64 + {9F58AD72-49E1-4D10-B826-9E190AB0AAC0}.Debug-DLL|x64.Build.0 = Debug|x64 + {9F58AD72-49E1-4D10-B826-9E190AB0AAC0}.Release-DLL|Win32.ActiveCfg = Release|Win32 + {9F58AD72-49E1-4D10-B826-9E190AB0AAC0}.Release-DLL|Win32.Build.0 = Release|Win32 + {9F58AD72-49E1-4D10-B826-9E190AB0AAC0}.Release-DLL|x64.ActiveCfg = Release|x64 + {9F58AD72-49E1-4D10-B826-9E190AB0AAC0}.Release-DLL|x64.Build.0 = Release|x64 {6EE56155-DF7C-4F6E-BFC4-F6F776BEB211}.Debug|Win32.ActiveCfg = Debug|Win32 {6EE56155-DF7C-4F6E-BFC4-F6F776BEB211}.Debug|x64.ActiveCfg = Debug|x64 {6EE56155-DF7C-4F6E-BFC4-F6F776BEB211}.Release|Win32.ActiveCfg = Release|Win32 diff --git a/vsprojects/vcxproj/grpc++_error_details/grpc++_error_details.vcxproj b/vsprojects/vcxproj/grpc++_error_details/grpc++_error_details.vcxproj new file mode 100644 index 00000000000..6bb3d4783a6 --- /dev/null +++ b/vsprojects/vcxproj/grpc++_error_details/grpc++_error_details.vcxproj @@ -0,0 +1,178 @@ + + + + + Debug + Win32 + + + Debug + x64 + + + Release + Win32 + + + Release + x64 + + + + {9F58AD72-49E1-4D10-B826-9E190AB0AAC0} + true + $(SolutionDir)IntDir\$(MSBuildProjectName)\ + + + + v100 + + + v110 + + + v120 + + + v140 + + + StaticLibrary + true + Unicode + + + StaticLibrary + false + true + Unicode + + + + + + + + + + + + grpc++_error_details + + + grpc++_error_details + + + + NotUsing + Level3 + Disabled + WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions) + true + MultiThreadedDebug + true + None + false + + + Windows + true + false + + + + + + NotUsing + Level3 + Disabled + WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions) + true + MultiThreadedDebug + true + None + false + + + Windows + true + false + + + + + + NotUsing + Level3 + MaxSpeed + WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions) + true + true + true + MultiThreaded + true + None + false + + + Windows + true + false + true + true + + + + + + NotUsing + Level3 + MaxSpeed + WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions) + true + true + true + MultiThreaded + true + None + false + + + Windows + true + false + true + true + + + + + + + + + + + + + + + + + + + + + {C187A093-A0FE-489D-A40A-6E33DE0F9FEB} + + + + + + + + This project references NuGet package(s) that are missing on this computer. Enable NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. + + + + diff --git a/vsprojects/vcxproj/grpc++_error_details/grpc++_error_details.vcxproj.filters b/vsprojects/vcxproj/grpc++_error_details/grpc++_error_details.vcxproj.filters new file mode 100644 index 00000000000..e1814eeceac --- /dev/null +++ b/vsprojects/vcxproj/grpc++_error_details/grpc++_error_details.vcxproj.filters @@ -0,0 +1,47 @@ + + + + + src\proto\grpc\status + + + src\cpp\util + + + + + include\grpc++\support + + + + + + {013272b5-4742-ba38-7cb6-25ff3484ac1d} + + + {f589296d-1ee4-913f-0345-7d8bf51f657b} + + + {3455fa30-ad44-8790-9dc2-ff4ac7dd9e6c} + + + {cf07aafe-1d45-af88-81fb-0bbd5afd247f} + + + {00726556-da02-06d8-bb32-902f55133c6b} + + + {fd90d13e-cc1f-e8cc-56ee-650231b08f56} + + + {ec6be373-4683-335e-03d9-dc636e34d7ef} + + + {8200edf2-9498-6cd9-d8f3-81ad881ca82c} + + + {79c5c1ea-19a8-bf5a-5e0a-3de6ad3a0465} + + + + diff --git a/vsprojects/vcxproj/test/error_details_test/error_details_test.vcxproj b/vsprojects/vcxproj/test/error_details_test/error_details_test.vcxproj new file mode 100644 index 00000000000..e146d9c8d21 --- /dev/null +++ b/vsprojects/vcxproj/test/error_details_test/error_details_test.vcxproj @@ -0,0 +1,203 @@ + + + + + + Debug + Win32 + + + Debug + x64 + + + Release + Win32 + + + Release + x64 + + + + {2DE1AE9E-D53C-5854-9122-317E34F90C31} + true + $(SolutionDir)IntDir\$(MSBuildProjectName)\ + + + + v100 + + + v110 + + + v120 + + + v140 + + + Application + true + Unicode + + + Application + false + true + Unicode + + + + + + + + + + + + + + + + error_details_test + static + Debug + static + Debug + + + error_details_test + static + Release + static + Release + + + + NotUsing + Level3 + Disabled + WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions) + true + MultiThreadedDebug + true + None + false + + + Console + true + false + + + + + + NotUsing + Level3 + Disabled + WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions) + true + MultiThreadedDebug + true + None + false + + + Console + true + false + + + + + + NotUsing + Level3 + MaxSpeed + WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions) + true + true + true + MultiThreaded + true + None + false + + + Console + true + false + true + true + + + + + + NotUsing + Level3 + MaxSpeed + WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions) + true + true + true + MultiThreaded + true + None + false + + + Console + true + false + true + true + + + + + + + + + + + + + + + + + + {9F58AD72-49E1-4D10-B826-9E190AB0AAC0} + + + {C187A093-A0FE-489D-A40A-6E33DE0F9FEB} + + + + + + + + + + + + + + + This project references NuGet package(s) that are missing on this computer. Enable NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. + + + + + + + + + diff --git a/vsprojects/vcxproj/test/error_details_test/error_details_test.vcxproj.filters b/vsprojects/vcxproj/test/error_details_test/error_details_test.vcxproj.filters new file mode 100644 index 00000000000..c83e0ae0d76 --- /dev/null +++ b/vsprojects/vcxproj/test/error_details_test/error_details_test.vcxproj.filters @@ -0,0 +1,36 @@ + + + + + src\proto\grpc\testing + + + test\cpp\util + + + + + + {35c957dd-436b-c57a-791d-2737bc179e41} + + + {c8721123-0390-f97d-5aad-0dd4979d5030} + + + {6dbad4a6-6b97-b25a-4f89-6edb20a1e7e0} + + + {5f343032-7701-4924-a1d2-06f46d52d1b3} + + + {688e4f7d-b9aa-342c-ffa7-2ee3ca51cd42} + + + {a4e0ed0a-c1bb-60d6-003b-91c3989f6e6e} + + + {60a99fd3-4904-d29f-b456-7f601092d055} + + + + From a03d204dd73621f87043b0f63ab646ba92169a8d Mon Sep 17 00:00:00 2001 From: David Garcia Quintas Date: Tue, 11 Apr 2017 16:09:31 -0700 Subject: [PATCH 115/127] Update credentials test after #9328 --- test/core/security/credentials_test.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/core/security/credentials_test.c b/test/core/security/credentials_test.c index c0933c64a68..9bdce71ba0c 100644 --- a/test/core/security/credentials_test.c +++ b/test/core/security/credentials_test.c @@ -582,7 +582,7 @@ static void on_oauth2_creds_get_metadata_failure( static void validate_compute_engine_http_request( const grpc_httpcli_request *request) { GPR_ASSERT(request->handshaker != &grpc_httpcli_ssl); - GPR_ASSERT(strcmp(request->host, "metadata") == 0); + GPR_ASSERT(strcmp(request->host, "metadata.google.internal") == 0); GPR_ASSERT( strcmp(request->http.path, "/computeMetadata/v1/instance/service-accounts/default/token") == From 95909bb3930136f31fd0493c9911234e766fc5cc Mon Sep 17 00:00:00 2001 From: Matt Kwong Date: Tue, 11 Apr 2017 12:44:46 -0700 Subject: [PATCH 116/127] Add individual sanitizer suites to Kokoro --- tools/internal_ci/README.md | 2 +- tools/internal_ci/linux/grpc_portability.cfg | 2 +- .../grpc_c_asan.cfg} | 2 +- .../grpc_c_asan.sh} | 4 +- .../linux/sanitizer/grpc_c_msan.cfg | 39 ++++++++++++++++++ .../linux/sanitizer/grpc_c_msan.sh | 40 +++++++++++++++++++ .../linux/sanitizer/grpc_c_tsan.cfg | 39 ++++++++++++++++++ .../linux/sanitizer/grpc_c_tsan.sh | 40 +++++++++++++++++++ .../linux/sanitizer/grpc_cpp_asan.cfg | 39 ++++++++++++++++++ .../linux/sanitizer/grpc_cpp_asan.sh | 40 +++++++++++++++++++ .../linux/sanitizer/grpc_cpp_tsan.cfg | 39 ++++++++++++++++++ .../linux/sanitizer/grpc_cpp_tsan.sh | 40 +++++++++++++++++++ 12 files changed, 321 insertions(+), 5 deletions(-) rename tools/internal_ci/linux/{grpc_master_sanitizers.cfg => sanitizer/grpc_c_asan.cfg} (96%) rename tools/internal_ci/linux/{grpc_master_sanitizers.sh => sanitizer/grpc_c_asan.sh} (95%) create mode 100644 tools/internal_ci/linux/sanitizer/grpc_c_msan.cfg create mode 100755 tools/internal_ci/linux/sanitizer/grpc_c_msan.sh create mode 100644 tools/internal_ci/linux/sanitizer/grpc_c_tsan.cfg create mode 100755 tools/internal_ci/linux/sanitizer/grpc_c_tsan.sh create mode 100644 tools/internal_ci/linux/sanitizer/grpc_cpp_asan.cfg create mode 100755 tools/internal_ci/linux/sanitizer/grpc_cpp_asan.sh create mode 100644 tools/internal_ci/linux/sanitizer/grpc_cpp_tsan.cfg create mode 100755 tools/internal_ci/linux/sanitizer/grpc_cpp_tsan.sh diff --git a/tools/internal_ci/README.md b/tools/internal_ci/README.md index 8bed6ca782b..e80e342dcd3 100644 --- a/tools/internal_ci/README.md +++ b/tools/internal_ci/README.md @@ -1,4 +1,4 @@ -#Internal continuous integration +# Internal continuous integration gRPC's externally facing testing is managed by Jenkins CI (see `tools/jenkins` directory). Nevertheless, some of the tests are better suited for being run diff --git a/tools/internal_ci/linux/grpc_portability.cfg b/tools/internal_ci/linux/grpc_portability.cfg index 5cc49f10462..92efda80ff6 100644 --- a/tools/internal_ci/linux/grpc_portability.cfg +++ b/tools/internal_ci/linux/grpc_portability.cfg @@ -31,7 +31,7 @@ # Location of the continuous shell script in repository. build_file: "grpc/tools/internal_ci/linux/grpc_portability.sh" -timeout_mins: 720 +timeout_mins: 1440 action { define_artifacts { regex: "**/*sponge_log.xml" diff --git a/tools/internal_ci/linux/grpc_master_sanitizers.cfg b/tools/internal_ci/linux/sanitizer/grpc_c_asan.cfg similarity index 96% rename from tools/internal_ci/linux/grpc_master_sanitizers.cfg rename to tools/internal_ci/linux/sanitizer/grpc_c_asan.cfg index a2a9407128b..8f2be8b59c6 100644 --- a/tools/internal_ci/linux/grpc_master_sanitizers.cfg +++ b/tools/internal_ci/linux/sanitizer/grpc_c_asan.cfg @@ -30,7 +30,7 @@ # Config file for the internal CI (in protobuf text format) # Location of the continuous shell script in repository. -build_file: "grpc/tools/internal_ci/linux/grpc_master_sanitizers.sh" +build_file: "grpc/tools/internal_ci/linux/sanitizer/grpc_c_asan.sh" timeout_mins: 1440 action { define_artifacts { diff --git a/tools/internal_ci/linux/grpc_master_sanitizers.sh b/tools/internal_ci/linux/sanitizer/grpc_c_asan.sh similarity index 95% rename from tools/internal_ci/linux/grpc_master_sanitizers.sh rename to tools/internal_ci/linux/sanitizer/grpc_c_asan.sh index d22387fb203..335d47af85f 100755 --- a/tools/internal_ci/linux/grpc_master_sanitizers.sh +++ b/tools/internal_ci/linux/sanitizer/grpc_c_asan.sh @@ -31,10 +31,10 @@ set -ex # change to grpc repo root -cd $(dirname $0)/../../.. +cd $(dirname $0)/../../../.. git submodule update --init # download docker images from dockerhub export DOCKERHUB_ORGANIZATION=grpctesting -tools/run_tests/run_tests_matrix.py -f sanitizers linux +tools/run_tests/run_tests_matrix.py -f c asan diff --git a/tools/internal_ci/linux/sanitizer/grpc_c_msan.cfg b/tools/internal_ci/linux/sanitizer/grpc_c_msan.cfg new file mode 100644 index 00000000000..2fd19974843 --- /dev/null +++ b/tools/internal_ci/linux/sanitizer/grpc_c_msan.cfg @@ -0,0 +1,39 @@ +# Copyright 2017, 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. + +# Config file for the internal CI (in protobuf text format) + +# Location of the continuous shell script in repository. +build_file: "grpc/tools/internal_ci/linux/sanitizer/grpc_c_msan.sh" +timeout_mins: 1440 +action { + define_artifacts { + regex: "**/*sponge_log.xml" + } +} diff --git a/tools/internal_ci/linux/sanitizer/grpc_c_msan.sh b/tools/internal_ci/linux/sanitizer/grpc_c_msan.sh new file mode 100755 index 00000000000..fe9565ecbdd --- /dev/null +++ b/tools/internal_ci/linux/sanitizer/grpc_c_msan.sh @@ -0,0 +1,40 @@ +#!/bin/bash +# Copyright 2017, 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. + +set -ex + +# change to grpc repo root +cd $(dirname $0)/../../../.. + +git submodule update --init + +# download docker images from dockerhub +export DOCKERHUB_ORGANIZATION=grpctesting +tools/run_tests/run_tests_matrix.py -f c msan diff --git a/tools/internal_ci/linux/sanitizer/grpc_c_tsan.cfg b/tools/internal_ci/linux/sanitizer/grpc_c_tsan.cfg new file mode 100644 index 00000000000..1ba01211b9f --- /dev/null +++ b/tools/internal_ci/linux/sanitizer/grpc_c_tsan.cfg @@ -0,0 +1,39 @@ +# Copyright 2017, 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. + +# Config file for the internal CI (in protobuf text format) + +# Location of the continuous shell script in repository. +build_file: "grpc/tools/internal_ci/linux/sanitizer/grpc_c_tsan.sh" +timeout_mins: 1440 +action { + define_artifacts { + regex: "**/*sponge_log.xml" + } +} diff --git a/tools/internal_ci/linux/sanitizer/grpc_c_tsan.sh b/tools/internal_ci/linux/sanitizer/grpc_c_tsan.sh new file mode 100755 index 00000000000..49bbbee8594 --- /dev/null +++ b/tools/internal_ci/linux/sanitizer/grpc_c_tsan.sh @@ -0,0 +1,40 @@ +#!/bin/bash +# Copyright 2017, 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. + +set -ex + +# change to grpc repo root +cd $(dirname $0)/../../../.. + +git submodule update --init + +# download docker images from dockerhub +export DOCKERHUB_ORGANIZATION=grpctesting +tools/run_tests/run_tests_matrix.py -f c tsan diff --git a/tools/internal_ci/linux/sanitizer/grpc_cpp_asan.cfg b/tools/internal_ci/linux/sanitizer/grpc_cpp_asan.cfg new file mode 100644 index 00000000000..49b7f123195 --- /dev/null +++ b/tools/internal_ci/linux/sanitizer/grpc_cpp_asan.cfg @@ -0,0 +1,39 @@ +# Copyright 2017, 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. + +# Config file for the internal CI (in protobuf text format) + +# Location of the continuous shell script in repository. +build_file: "grpc/tools/internal_ci/linux/sanitizer/grpc_cpp_asan.sh" +timeout_mins: 1440 +action { + define_artifacts { + regex: "**/*sponge_log.xml" + } +} diff --git a/tools/internal_ci/linux/sanitizer/grpc_cpp_asan.sh b/tools/internal_ci/linux/sanitizer/grpc_cpp_asan.sh new file mode 100755 index 00000000000..c3bf79b1fb5 --- /dev/null +++ b/tools/internal_ci/linux/sanitizer/grpc_cpp_asan.sh @@ -0,0 +1,40 @@ +#!/bin/bash +# Copyright 2017, 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. + +set -ex + +# change to grpc repo root +cd $(dirname $0)/../../../.. + +git submodule update --init + +# download docker images from dockerhub +export DOCKERHUB_ORGANIZATION=grpctesting +tools/run_tests/run_tests_matrix.py -f cpp asan diff --git a/tools/internal_ci/linux/sanitizer/grpc_cpp_tsan.cfg b/tools/internal_ci/linux/sanitizer/grpc_cpp_tsan.cfg new file mode 100644 index 00000000000..97c818b5571 --- /dev/null +++ b/tools/internal_ci/linux/sanitizer/grpc_cpp_tsan.cfg @@ -0,0 +1,39 @@ +# Copyright 2017, 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. + +# Config file for the internal CI (in protobuf text format) + +# Location of the continuous shell script in repository. +build_file: "grpc/tools/internal_ci/linux/sanitizer/grpc_cpp_tsan.sh" +timeout_mins: 1440 +action { + define_artifacts { + regex: "**/*sponge_log.xml" + } +} diff --git a/tools/internal_ci/linux/sanitizer/grpc_cpp_tsan.sh b/tools/internal_ci/linux/sanitizer/grpc_cpp_tsan.sh new file mode 100755 index 00000000000..c72a106c91a --- /dev/null +++ b/tools/internal_ci/linux/sanitizer/grpc_cpp_tsan.sh @@ -0,0 +1,40 @@ +#!/bin/bash +# Copyright 2017, 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. + +set -ex + +# change to grpc repo root +cd $(dirname $0)/../../../.. + +git submodule update --init + +# download docker images from dockerhub +export DOCKERHUB_ORGANIZATION=grpctesting +tools/run_tests/run_tests_matrix.py -f cpp tsan From 8be866eed78b28d59c3f61d54a907b0b11b31d1c Mon Sep 17 00:00:00 2001 From: Craig Tiller Date: Wed, 12 Apr 2017 08:43:18 -0700 Subject: [PATCH 117/127] fix test --- test/core/transport/chttp2/hpack_encoder_test.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/core/transport/chttp2/hpack_encoder_test.c b/test/core/transport/chttp2/hpack_encoder_test.c index 701d663cbbc..f4ccc71b395 100644 --- a/test/core/transport/chttp2/hpack_encoder_test.c +++ b/test/core/transport/chttp2/hpack_encoder_test.c @@ -106,7 +106,7 @@ static void verify(grpc_exec_ctx *exec_ctx, size_t window_available, bool eof, grpc_encode_header_options hopt = { .stream_id = 0xdeadbeef, .is_eof = eof, - .use_true_binary_metadata = false, + .use_true_binary_metadata = use_true_binary_metadata, .max_frame_size = 16384, .stats = &stats, }; From 08aea10d02adc49041d6fb1c6ea31553c97af72d Mon Sep 17 00:00:00 2001 From: Craig Tiller Date: Wed, 12 Apr 2017 08:45:36 -0700 Subject: [PATCH 118/127] document --- include/grpc/impl/codegen/grpc_types.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/include/grpc/impl/codegen/grpc_types.h b/include/grpc/impl/codegen/grpc_types.h index 4380aceaf13..8fa76fc0328 100644 --- a/include/grpc/impl/codegen/grpc_types.h +++ b/include/grpc/impl/codegen/grpc_types.h @@ -217,7 +217,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? */ +/** Should we allow receipt of true-binary data on http2 connections? + Defaults to on (1) */ #define GRPC_ARG_HTTP2_ENABLE_TRUE_BINARY "grpc.http2.true_binary" /** After a duration of this time the client/server pings its peer to see if the transport is still alive. Int valued, milliseconds. */ From 12d716c88ce3b4f81d1d4c7a8fdbcddf65134b62 Mon Sep 17 00:00:00 2001 From: Craig Tiller Date: Wed, 12 Apr 2017 09:00:41 -0700 Subject: [PATCH 119/127] 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(-) diff --git a/src/core/ext/transport/chttp2/transport/http2_settings.c b/src/core/ext/transport/chttp2/transport/http2_settings.c index bca3834b55f..d4905107efe 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 29c67956c70..a9861383371 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): From dc3806c672ab8cd4ec0e03add1cf138c69cfd444 Mon Sep 17 00:00:00 2001 From: Craig Tiller Date: Wed, 12 Apr 2017 09:08:31 -0700 Subject: [PATCH 120/127] Fix a noise creating bug in bm_json (for bm_diff) --- tools/profiling/microbenchmarks/bm_json.py | 1 + 1 file changed, 1 insertion(+) diff --git a/tools/profiling/microbenchmarks/bm_json.py b/tools/profiling/microbenchmarks/bm_json.py index e885444f410..917269823d0 100644 --- a/tools/profiling/microbenchmarks/bm_json.py +++ b/tools/profiling/microbenchmarks/bm_json.py @@ -203,4 +203,5 @@ def expand_json(js, js2 = None): row['real_time'] = bm2['real_time'] row['iterations'] = bm2['iterations'] bm2['already_used'] = True + break yield row From d835aa39d3f5a9ad247ea4dafa28da493f8352be Mon Sep 17 00:00:00 2001 From: Craig Tiller Date: Wed, 12 Apr 2017 09:09:17 -0700 Subject: [PATCH 121/127] Cleanup output: omit unnecessary columns --- tools/profiling/microbenchmarks/bm_diff.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/profiling/microbenchmarks/bm_diff.py b/tools/profiling/microbenchmarks/bm_diff.py index 2337f2b282e..35a79593b41 100755 --- a/tools/profiling/microbenchmarks/bm_diff.py +++ b/tools/profiling/microbenchmarks/bm_diff.py @@ -226,7 +226,7 @@ really_interesting = set() for name, bm in benchmarks.items(): print name really_interesting.update(bm.process()) -fields = [f for f in args.track if f in args.track] +fields = [f for f in args.track if f in really_interesting] headers = ['Benchmark'] + fields rows = [] From ca3b32f67d2dcce8cf09612a24fee93aa69c5a7f Mon Sep 17 00:00:00 2001 From: Craig Tiller Date: Wed, 12 Apr 2017 09:36:40 -0700 Subject: [PATCH 122/127] Handle div0 --- src/core/lib/transport/pid_controller.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/core/lib/transport/pid_controller.c b/src/core/lib/transport/pid_controller.c index 19cb1c0b367..c851564201f 100644 --- a/src/core/lib/transport/pid_controller.c +++ b/src/core/lib/transport/pid_controller.c @@ -49,6 +49,7 @@ void grpc_pid_controller_reset(grpc_pid_controller *pid_controller) { double grpc_pid_controller_update(grpc_pid_controller *pid_controller, double error, double dt) { + if (dt == 0) return pid_controller->last_control_value; /* integrate error using the trapezoid rule */ pid_controller->error_integral += dt * (pid_controller->last_error + error) * 0.5; From 9f99c303d01c706306eb54a5cfd0a23e1e76c6e3 Mon Sep 17 00:00:00 2001 From: Craig Tiller Date: Wed, 12 Apr 2017 09:37:47 -0700 Subject: [PATCH 123/127] Handle 0-length --- src/core/lib/slice/slice.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/core/lib/slice/slice.c b/src/core/lib/slice/slice.c index 1cddf062cd4..da5dc3e52af 100644 --- a/src/core/lib/slice/slice.c +++ b/src/core/lib/slice/slice.c @@ -197,6 +197,7 @@ grpc_slice grpc_slice_new_with_len(void *p, size_t len, } grpc_slice grpc_slice_from_copied_buffer(const char *source, size_t length) { + if (length == 0) return grpc_empty_slice(); grpc_slice slice = grpc_slice_malloc(length); memcpy(GRPC_SLICE_START_PTR(slice), source, length); return slice; From 7fea75125846a0326dfa907c5a310f62d5f8e567 Mon Sep 17 00:00:00 2001 From: Craig Tiller Date: Wed, 12 Apr 2017 09:43:34 -0700 Subject: [PATCH 124/127] ubsan fixes --- src/core/lib/iomgr/sockaddr_utils.c | 4 +++- src/core/lib/slice/slice.c | 5 +++-- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/src/core/lib/iomgr/sockaddr_utils.c b/src/core/lib/iomgr/sockaddr_utils.c index 9d2732666b2..a6a4cac3e29 100644 --- a/src/core/lib/iomgr/sockaddr_utils.c +++ b/src/core/lib/iomgr/sockaddr_utils.c @@ -55,7 +55,9 @@ int grpc_sockaddr_is_v4mapped(const grpc_resolved_address *resolved_addr, GPR_ASSERT(resolved_addr != resolved_addr4_out); const struct sockaddr *addr = (const struct sockaddr *)resolved_addr->addr; struct sockaddr_in *addr4_out = - (struct sockaddr_in *)resolved_addr4_out->addr; + resolved_addr4_out == NULL + ? NULL + : (struct sockaddr_in *)resolved_addr4_out->addr; if (addr->sa_family == AF_INET6) { const struct sockaddr_in6 *addr6 = (const struct sockaddr_in6 *)addr; if (memcmp(addr6->sin6_addr.s6_addr, kV4MappedPrefix, diff --git a/src/core/lib/slice/slice.c b/src/core/lib/slice/slice.c index da5dc3e52af..a2fcbbdbdf5 100644 --- a/src/core/lib/slice/slice.c +++ b/src/core/lib/slice/slice.c @@ -383,8 +383,9 @@ grpc_slice grpc_slice_split_head(grpc_slice *source, size_t split) { } int grpc_slice_default_eq_impl(grpc_slice a, grpc_slice b) { - return GRPC_SLICE_LENGTH(a) == GRPC_SLICE_LENGTH(b) && - 0 == memcmp(GRPC_SLICE_START_PTR(a), GRPC_SLICE_START_PTR(b), + if (GRPC_SLICE_LENGTH(a) != GRPC_SLICE_LENGTH(b)) return false; + if (GRPC_SLICE_LENGTH(a) == 0) return true; + return 0 == memcmp(GRPC_SLICE_START_PTR(a), GRPC_SLICE_START_PTR(b), GRPC_SLICE_LENGTH(a)); } From 66d40c63f7bf004623dcc4dbafda96b69fc46094 Mon Sep 17 00:00:00 2001 From: yang-g Date: Wed, 12 Apr 2017 10:18:10 -0700 Subject: [PATCH 125/127] Fix BUILD dependency, copyright and cmake --- CMakeLists.txt | 4 +++- templates/CMakeLists.txt.template | 4 +++- test/cpp/util/BUILD | 3 ++- tools/distrib/check_copyright.py | 2 ++ 4 files changed, 10 insertions(+), 3 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 08bf646c823..0869c3a8c30 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -167,6 +167,7 @@ if("${gRPC_PROTOBUF_PROVIDER}" STREQUAL "module") if(NOT PROTOBUF_ROOT_DIR) set(PROTOBUF_ROOT_DIR ${CMAKE_CURRENT_SOURCE_DIR}/third_party/protobuf) endif() + set(PROTOBUF_WELLKNOWN_IMPORT_DIR ${PROTOBUF_ROOT_DIR}/src) if(EXISTS "${PROTOBUF_ROOT_DIR}/cmake/CMakeLists.txt") set(protobuf_MSVC_STATIC_RUNTIME OFF CACHE BOOL "Link static runtime libraries") add_subdirectory(${PROTOBUF_ROOT_DIR}/cmake third_party/protobuf) @@ -199,6 +200,7 @@ elseif("${gRPC_PROTOBUF_PROVIDER}" STREQUAL "package") find_package(Protobuf MODULE) set(_gRPC_FIND_PROTOBUF "if(NOT Protobuf_FOUND)\n find_package(Protobuf)\nendif()") endif() + set(PROTOBUF_WELLKNOWN_IMPORT_DIR /usr/local/include) endif() if("${gRPC_SSL_PROVIDER}" STREQUAL "module") @@ -301,7 +303,7 @@ function(protobuf_generate_grpc_cpp) return() endif() - set(_protobuf_include_path -I .) + set(_protobuf_include_path -I . -I ${PROTOBUF_WELLKNOWN_IMPORT_DIR}) foreach(FIL ${ARGN}) get_filename_component(ABS_FIL ${FIL} ABSOLUTE) get_filename_component(FIL_WE ${FIL} NAME_WE) diff --git a/templates/CMakeLists.txt.template b/templates/CMakeLists.txt.template index cf69f0cc06f..c647ea57072 100644 --- a/templates/CMakeLists.txt.template +++ b/templates/CMakeLists.txt.template @@ -212,6 +212,7 @@ if(NOT PROTOBUF_ROOT_DIR) set(PROTOBUF_ROOT_DIR <%text>${CMAKE_CURRENT_SOURCE_DIR}/third_party/protobuf) endif() + set(PROTOBUF_WELLKNOWN_IMPORT_DIR <%text>${PROTOBUF_ROOT_DIR}/src) if(EXISTS "<%text>${PROTOBUF_ROOT_DIR}/cmake/CMakeLists.txt") set(protobuf_MSVC_STATIC_RUNTIME OFF CACHE BOOL "Link static runtime libraries") add_subdirectory(<%text>${PROTOBUF_ROOT_DIR}/cmake third_party/protobuf) @@ -244,6 +245,7 @@ find_package(Protobuf MODULE) set(_gRPC_FIND_PROTOBUF "if(NOT Protobuf_FOUND)\n find_package(Protobuf)\nendif()") endif() + set(PROTOBUF_WELLKNOWN_IMPORT_DIR /usr/local/include) endif() if("<%text>${gRPC_SSL_PROVIDER}" STREQUAL "module") @@ -346,7 +348,7 @@ return() endif() - set(_protobuf_include_path -I .) + set(_protobuf_include_path -I . -I <%text>${PROTOBUF_WELLKNOWN_IMPORT_DIR}) foreach(FIL <%text>${ARGN}) get_filename_component(ABS_FIL <%text>${FIL} ABSOLUTE) get_filename_component(FIL_WE <%text>${FIL} NAME_WE) diff --git a/test/cpp/util/BUILD b/test/cpp/util/BUILD index 7471ce75dd3..38f804ffd40 100644 --- a/test/cpp/util/BUILD +++ b/test/cpp/util/BUILD @@ -89,8 +89,9 @@ cc_test( "error_details_test.cc", ], deps = [ - "//external:gtest", "//:grpc++_error_details", + "//external:gtest", + "//src/proto/grpc/testing:echo_messages_proto", ], ) diff --git a/tools/distrib/check_copyright.py b/tools/distrib/check_copyright.py index 42005e3bd3a..0a58adf2f0a 100755 --- a/tools/distrib/check_copyright.py +++ b/tools/distrib/check_copyright.py @@ -113,6 +113,8 @@ _EXEMPT = frozenset(( 'src/php/tests/bootstrap.php', # census.proto copied from github 'tools/grpcz/census.proto', + # status.proto copied from googleapis + 'src/proto/grpc/status/status.proto', )) From 66db5a70851049465c00df6e55b6b2e7dc7c1db4 Mon Sep 17 00:00:00 2001 From: Alexander Polcyn Date: Wed, 12 Apr 2017 14:31:31 -0700 Subject: [PATCH 126/127] remove src/csharp/global.json --- src/csharp/global.json | 5 ----- 1 file changed, 5 deletions(-) delete mode 100644 src/csharp/global.json diff --git a/src/csharp/global.json b/src/csharp/global.json deleted file mode 100644 index f3c33cef6a5..00000000000 --- a/src/csharp/global.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "sdk": { - "version": "1.0.0-preview2-003131" - } -} \ No newline at end of file From c71e6a6ad689c10df0981fa43ab7d3e6776dcb08 Mon Sep 17 00:00:00 2001 From: Craig Tiller Date: Wed, 12 Apr 2017 15:49:39 -0700 Subject: [PATCH 127/127] Revert "Implement lazy deframe" --- .../chttp2/transport/chttp2_transport.c | 338 ++++++---------- .../transport/chttp2/transport/frame_data.c | 365 ++++++++---------- .../transport/chttp2/transport/frame_data.h | 24 +- .../ext/transport/chttp2/transport/internal.h | 51 +-- .../ext/transport/chttp2/transport/parsing.c | 5 +- .../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 +- .../microbenchmarks/bm_chttp2_transport.cc | 9 +- 12 files changed, 350 insertions(+), 584 deletions(-) diff --git a/src/core/ext/transport/chttp2/transport/chttp2_transport.c b/src/core/ext/transport/chttp2/transport/chttp2_transport.c index 29ed4bf90e5..a7d047d6e7a 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 5d382d80a8b..6e9258ee7ee 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 2fb8983c38e..264ad146085 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 a10e3886ea1..6eb848b8d77 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 638b137316f..7e457ced270 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 7896c70f9eb..88335ecd0be 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 764524b24d1..4625cba0d25 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 151fb9885de..4e47c5c658f 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 3e96d097985..97d50a91be5 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 5800c70ef44..4d4206189e7 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 381c65fb044..1fdd5b4d775 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 8c5413b5fda..c89f349ca7f 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);