static void perform_op_locked(grpc_chttp2_transport_global *transport_global, grpc_chttp2_stream_global *stream_global, grpc_transport_op *op) { if (op->cancel_with_status != GRPC_STATUS_OK) { cancel_from_api(transport_global, stream_global, op->cancel_with_status); } if (op->send_ops) { GPR_ASSERT(stream_global->outgoing_sopb == NULL); stream_global->send_done_closure = op->on_done_send; if (!stream_global->cancelled) { stream_global->outgoing_sopb = op->send_ops; if (op->is_last_send && stream_global->write_state == GRPC_WRITE_STATE_OPEN) { stream_global->write_state = GRPC_WRITE_STATE_QUEUED_CLOSE; } if (stream_global->id == 0) { GRPC_CHTTP2_IF_TRACING(gpr_log( GPR_DEBUG, "HTTP:%s: New grpc_chttp2_stream %p waiting for concurrency", transport_global->is_client ? "CLI" : "SVR", stream_global)); grpc_chttp2_list_add_waiting_for_concurrency(transport_global, stream_global); maybe_start_some_streams(transport_global); } else if (stream_global->outgoing_window > 0) { grpc_chttp2_list_add_writable_stream(transport_global, stream_global); } } else { grpc_sopb_reset(op->send_ops); grpc_chttp2_schedule_closure(transport_global, stream_global->send_done_closure, 0); } } if (op->recv_ops) { GPR_ASSERT(stream_global->publish_sopb == NULL); GPR_ASSERT(stream_global->published_state != GRPC_STREAM_CLOSED); stream_global->recv_done_closure = op->on_done_recv; stream_global->publish_sopb = op->recv_ops; stream_global->publish_sopb->nops = 0; stream_global->publish_state = op->recv_state; grpc_chttp2_incoming_metadata_live_op_buffer_end( &stream_global->outstanding_metadata); grpc_chttp2_list_add_read_write_state_changed(transport_global, stream_global); grpc_chttp2_list_add_writable_window_update_stream(transport_global, stream_global); } if (op->bind_pollset) { add_to_pollset_locked(TRANSPORT_FROM_GLOBAL(transport_global), op->bind_pollset); } if (op->on_consumed) { grpc_chttp2_schedule_closure(transport_global, op->on_consumed, 1); } }
static void destroy_stream(grpc_exec_ctx *exec_ctx, grpc_transport *gt, grpc_stream *gs) { grpc_chttp2_transport *t = (grpc_chttp2_transport *)gt; grpc_chttp2_stream *s = (grpc_chttp2_stream *)gs; int i; gpr_mu_lock(&t->mu); GPR_ASSERT(s->global.published_state == GRPC_STREAM_CLOSED || s->global.id == 0); GPR_ASSERT(!s->global.in_stream_map); if (grpc_chttp2_unregister_stream(t, s) && t->global.sent_goaway) { close_transport_locked(exec_ctx, t); } if (!t->parsing_active && s->global.id) { GPR_ASSERT(grpc_chttp2_stream_map_find(&t->parsing_stream_map, s->global.id) == NULL); } grpc_chttp2_list_remove_incoming_window_updated(&t->global, &s->global); grpc_chttp2_list_remove_writable_stream(&t->global, &s->global); gpr_mu_unlock(&t->mu); for (i = 0; i < STREAM_LIST_COUNT; i++) { if (s->included[i]) { gpr_log(GPR_ERROR, "%s stream %d still included in list %d", t->global.is_client ? "client" : "server", s->global.id, i); abort(); } } GPR_ASSERT(s->global.outgoing_sopb == NULL); GPR_ASSERT(s->global.publish_sopb == NULL); grpc_sopb_destroy(&s->writing.sopb); grpc_sopb_destroy(&s->global.incoming_sopb); grpc_chttp2_data_parser_destroy(&s->parsing.data_parser); grpc_chttp2_incoming_metadata_buffer_destroy(&s->parsing.incoming_metadata); grpc_chttp2_incoming_metadata_buffer_destroy(&s->global.incoming_metadata); grpc_chttp2_incoming_metadata_live_op_buffer_end( &s->global.outstanding_metadata); UNREF_TRANSPORT(exec_ctx, t, "stream"); }
static void destroy_stream(grpc_transport *gt, grpc_stream *gs) { grpc_chttp2_transport *t = (grpc_chttp2_transport *)gt; grpc_chttp2_stream *s = (grpc_chttp2_stream *)gs; int i; gpr_mu_lock(&t->mu); GPR_ASSERT(s->global.published_state == GRPC_STREAM_CLOSED || s->global.id == 0); GPR_ASSERT(!s->global.in_stream_map); grpc_chttp2_unregister_stream(t, s); if (!t->parsing_active && s->global.id) { GPR_ASSERT(grpc_chttp2_stream_map_find(&t->parsing_stream_map, s->global.id) == NULL); } grpc_chttp2_list_remove_incoming_window_updated(&t->global, &s->global); grpc_chttp2_list_remove_writable_window_update_stream(&t->global, &s->global); gpr_mu_unlock(&t->mu); for (i = 0; i < STREAM_LIST_COUNT; i++) { GPR_ASSERT(!s->included[i]); } GPR_ASSERT(s->global.outgoing_sopb == NULL); GPR_ASSERT(s->global.publish_sopb == NULL); grpc_sopb_destroy(&s->writing.sopb); grpc_sopb_destroy(&s->global.incoming_sopb); grpc_chttp2_data_parser_destroy(&s->parsing.data_parser); grpc_chttp2_incoming_metadata_buffer_destroy(&s->parsing.incoming_metadata); grpc_chttp2_incoming_metadata_buffer_destroy(&s->global.incoming_metadata); grpc_chttp2_incoming_metadata_live_op_buffer_end( &s->global.outstanding_metadata); UNREF_TRANSPORT(t, "stream"); }
static void perform_stream_op_locked( grpc_exec_ctx *exec_ctx, grpc_chttp2_transport_global *transport_global, grpc_chttp2_stream_global *stream_global, grpc_transport_stream_op *op) { if (op->cancel_with_status != GRPC_STATUS_OK) { cancel_from_api(transport_global, stream_global, op->cancel_with_status); } if (op->close_with_status != GRPC_STATUS_OK) { close_from_api(transport_global, stream_global, op->close_with_status, op->optional_close_message); } if (op->send_ops) { GPR_ASSERT(stream_global->outgoing_sopb == NULL); stream_global->send_done_closure = op->on_done_send; if (!stream_global->cancelled) { stream_global->written_anything = 1; stream_global->outgoing_sopb = op->send_ops; if (op->is_last_send && stream_global->write_state == GRPC_WRITE_STATE_OPEN) { stream_global->write_state = GRPC_WRITE_STATE_QUEUED_CLOSE; } if (stream_global->id == 0) { GRPC_CHTTP2_IF_TRACING(gpr_log( GPR_DEBUG, "HTTP:%s: New grpc_chttp2_stream %p waiting for concurrency", transport_global->is_client ? "CLI" : "SVR", stream_global)); grpc_chttp2_list_add_waiting_for_concurrency(transport_global, stream_global); maybe_start_some_streams(exec_ctx, transport_global); } else if (stream_global->outgoing_window > 0) { grpc_chttp2_list_add_writable_stream(transport_global, stream_global); } } else { grpc_sopb_reset(op->send_ops); grpc_exec_ctx_enqueue(exec_ctx, stream_global->send_done_closure, 0); } } if (op->recv_ops) { GPR_ASSERT(stream_global->publish_sopb == NULL); GPR_ASSERT(stream_global->published_state != GRPC_STREAM_CLOSED); stream_global->recv_done_closure = op->on_done_recv; stream_global->publish_sopb = op->recv_ops; stream_global->publish_sopb->nops = 0; stream_global->publish_state = op->recv_state; /* clamp max recv bytes */ op->max_recv_bytes = GPR_MIN(op->max_recv_bytes, GPR_UINT32_MAX); if (stream_global->max_recv_bytes < op->max_recv_bytes) { GRPC_CHTTP2_FLOWCTL_TRACE_STREAM( "op", transport_global, stream_global, max_recv_bytes, op->max_recv_bytes - stream_global->max_recv_bytes); GRPC_CHTTP2_FLOWCTL_TRACE_STREAM( "op", transport_global, stream_global, unannounced_incoming_window, op->max_recv_bytes - stream_global->max_recv_bytes); stream_global->unannounced_incoming_window += (gpr_uint32)op->max_recv_bytes - stream_global->max_recv_bytes; stream_global->max_recv_bytes = (gpr_uint32)op->max_recv_bytes; } grpc_chttp2_incoming_metadata_live_op_buffer_end( &stream_global->outstanding_metadata); grpc_chttp2_list_add_read_write_state_changed(transport_global, stream_global); if (stream_global->id != 0) { grpc_chttp2_list_add_writable_stream(transport_global, stream_global); } } if (op->bind_pollset) { add_to_pollset_locked(exec_ctx, TRANSPORT_FROM_GLOBAL(transport_global), op->bind_pollset); } grpc_exec_ctx_enqueue(exec_ctx, op->on_consumed, 1); }