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 perform_transport_op(grpc_transport *gt, grpc_transport_op *op) { grpc_chttp2_transport *t = (grpc_chttp2_transport *)gt; int close_transport = 0; lock(t); if (op->on_consumed) { grpc_chttp2_schedule_closure(&t->global, op->on_consumed, 1); } if (op->on_connectivity_state_change) { grpc_connectivity_state_notify_on_state_change( &t->channel_callback.state_tracker, op->connectivity_state, op->on_connectivity_state_change); } if (op->send_goaway) { t->global.sent_goaway = 1; grpc_chttp2_goaway_append( t->global.last_incoming_stream_id, grpc_chttp2_grpc_status_to_http2_error(op->goaway_status), gpr_slice_ref(*op->goaway_message), &t->global.qbuf); close_transport = !grpc_chttp2_has_streams(t); } if (op->set_accept_stream != NULL) { t->channel_callback.accept_stream = op->set_accept_stream; t->channel_callback.accept_stream_user_data = op->set_accept_stream_user_data; } if (op->bind_pollset) { add_to_pollset_locked(t, op->bind_pollset); } if (op->bind_pollset_set) { add_to_pollset_set_locked(t, op->bind_pollset_set); } if (op->send_ping) { send_ping_locked(t, op->send_ping); } if (op->disconnect) { close_transport_locked(t); } unlock(t); if (close_transport) { lock(t); close_transport_locked(t); unlock(t); } }
static void add_to_pollset(grpc_transport *gt, grpc_pollset *pollset) { grpc_chttp2_transport *t = (grpc_chttp2_transport *)gt; lock(t); add_to_pollset_locked(t, pollset); unlock(t); }
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); }