grpc_error *grpc_chttp2_window_update_parser_parse( grpc_exec_ctx *exec_ctx, void *parser, grpc_chttp2_transport *t, grpc_chttp2_stream *s, grpc_slice slice, int is_last) { uint8_t *const beg = GRPC_SLICE_START_PTR(slice); uint8_t *const end = GRPC_SLICE_END_PTR(slice); uint8_t *cur = beg; grpc_chttp2_window_update_parser *p = parser; while (p->byte != 4 && cur != end) { p->amount |= ((uint32_t)*cur) << (8 * (3 - p->byte)); cur++; p->byte++; } if (s != NULL) { s->stats.incoming.framing_bytes += (uint32_t)(end - cur); } if (p->byte == 4) { uint32_t received_update = p->amount; if (received_update == 0 || (received_update & 0x80000000u)) { char *msg; gpr_asprintf(&msg, "invalid window update bytes: %d", p->amount); grpc_error *err = GRPC_ERROR_CREATE_FROM_COPIED_STRING(msg); gpr_free(msg); return err; } GPR_ASSERT(is_last); if (t->incoming_stream_id != 0) { if (s != NULL) { GRPC_CHTTP2_FLOW_CREDIT_STREAM("parse", t, s, outgoing_window_delta, received_update); if (grpc_chttp2_list_remove_stalled_by_stream(t, s)) { grpc_chttp2_become_writable( exec_ctx, t, s, GRPC_CHTTP2_STREAM_WRITE_INITIATE_UNCOVERED, "stream.read_flow_control"); } } } else { bool was_zero = t->outgoing_window <= 0; GRPC_CHTTP2_FLOW_CREDIT_TRANSPORT("parse", t, outgoing_window, received_update); bool is_zero = t->outgoing_window <= 0; if (was_zero && !is_zero) { grpc_chttp2_initiate_write(exec_ctx, t, "new_global_flow_control"); } } } return GRPC_ERROR_NONE; }
grpc_chttp2_parse_error grpc_chttp2_window_update_parser_parse( grpc_exec_ctx *exec_ctx, void *parser, grpc_chttp2_transport_parsing *transport_parsing, grpc_chttp2_stream_parsing *stream_parsing, gpr_slice slice, int is_last) { uint8_t *const beg = GPR_SLICE_START_PTR(slice); uint8_t *const end = GPR_SLICE_END_PTR(slice); uint8_t *cur = beg; grpc_chttp2_window_update_parser *p = parser; while (p->byte != 4 && cur != end) { p->amount |= ((uint32_t)*cur) << (8 * (3 - p->byte)); cur++; p->byte++; } if (stream_parsing != NULL) { stream_parsing->stats.incoming.framing_bytes += (uint32_t)(end - cur); } if (p->byte == 4) { uint32_t received_update = p->amount; if (received_update == 0 || (received_update & 0x80000000u)) { gpr_log(GPR_ERROR, "invalid window update bytes: %d", p->amount); return GRPC_CHTTP2_CONNECTION_ERROR; } GPR_ASSERT(is_last); if (transport_parsing->incoming_stream_id != 0) { if (stream_parsing != NULL) { GRPC_CHTTP2_FLOW_CREDIT_STREAM("parse", transport_parsing, stream_parsing, outgoing_window, received_update); grpc_chttp2_list_add_parsing_seen_stream(transport_parsing, stream_parsing); } } else { GRPC_CHTTP2_FLOW_CREDIT_TRANSPORT("parse", transport_parsing, outgoing_window, received_update); } } return GRPC_CHTTP2_PARSE_OK; }