예제 #1
0
void grpc_chttp2_list_add_writing_stalled_by_transport(
    grpc_chttp2_transport_writing *transport_writing,
    grpc_chttp2_stream_writing *stream_writing) {
  grpc_chttp2_stream *stream = STREAM_FROM_WRITING(stream_writing);
  gpr_log(GPR_DEBUG, "writing stalled %d", stream->global.id);
  if (!stream->included[GRPC_CHTTP2_LIST_WRITING_STALLED_BY_TRANSPORT]) {
    GRPC_CHTTP2_STREAM_REF(&stream->global, "chttp2_writing_stalled");
  }
  stream_list_add(TRANSPORT_FROM_WRITING(transport_writing), stream,
                  GRPC_CHTTP2_LIST_WRITING_STALLED_BY_TRANSPORT);
}
예제 #2
0
파일: writing.c 프로젝트: CydeWeys/bazel
int grpc_chttp2_unlocking_check_writes(
    grpc_chttp2_transport_global *transport_global,
    grpc_chttp2_transport_writing *transport_writing, int is_parsing) {
    grpc_chttp2_stream_global *stream_global;
    grpc_chttp2_stream_writing *stream_writing;

    GPR_TIMER_BEGIN("grpc_chttp2_unlocking_check_writes", 0);

    /* simple writes are queued to qbuf, and flushed here */
    gpr_slice_buffer_swap(&transport_global->qbuf, &transport_writing->outbuf);
    GPR_ASSERT(transport_global->qbuf.count == 0);

    grpc_chttp2_hpack_compressor_set_max_table_size(
        &transport_writing->hpack_compressor,
        transport_global->settings[GRPC_PEER_SETTINGS]
        [GRPC_CHTTP2_SETTINGS_HEADER_TABLE_SIZE]);

    if (transport_global->dirtied_local_settings &&
            !transport_global->sent_local_settings && !is_parsing) {
        gpr_slice_buffer_add(
            &transport_writing->outbuf,
            grpc_chttp2_settings_create(
                transport_global->settings[GRPC_SENT_SETTINGS],
                transport_global->settings[GRPC_LOCAL_SETTINGS],
                transport_global->force_send_settings, GRPC_CHTTP2_NUM_SETTINGS));
        transport_global->force_send_settings = 0;
        transport_global->dirtied_local_settings = 0;
        transport_global->sent_local_settings = 1;
    }

    GRPC_CHTTP2_FLOW_MOVE_TRANSPORT("write", transport_writing, outgoing_window,
                                    transport_global, outgoing_window);
    bool is_window_available = transport_writing->outgoing_window > 0;
    grpc_chttp2_list_flush_writing_stalled_by_transport(transport_writing,
            is_window_available);

    /* for each grpc_chttp2_stream that's become writable, frame it's data
       (according to available window sizes) and add to the output buffer */
    while (grpc_chttp2_list_pop_writable_stream(
                transport_global, transport_writing, &stream_global, &stream_writing)) {
        uint8_t sent_initial_metadata;

        stream_writing->id = stream_global->id;
        stream_writing->read_closed = stream_global->read_closed;

        GRPC_CHTTP2_FLOW_MOVE_STREAM("write", transport_writing, stream_writing,
                                     outgoing_window, stream_global,
                                     outgoing_window);

        sent_initial_metadata = stream_writing->sent_initial_metadata;
        if (!sent_initial_metadata && stream_global->send_initial_metadata) {
            stream_writing->send_initial_metadata =
                stream_global->send_initial_metadata;
            stream_global->send_initial_metadata = NULL;
            if (grpc_chttp2_list_add_writing_stream(transport_writing,
                                                    stream_writing)) {
                GRPC_CHTTP2_STREAM_REF(stream_global, "chttp2_writing");
            }
            sent_initial_metadata = 1;
        }
        if (sent_initial_metadata) {
            if (stream_global->send_message != NULL) {
                gpr_slice hdr = gpr_slice_malloc(5);
                uint8_t *p = GPR_SLICE_START_PTR(hdr);
                uint32_t len = stream_global->send_message->length;
                GPR_ASSERT(stream_writing->send_message == NULL);
                p[0] = (stream_global->send_message->flags &
                        GRPC_WRITE_INTERNAL_COMPRESS) != 0;
                p[1] = (uint8_t)(len >> 24);
                p[2] = (uint8_t)(len >> 16);
                p[3] = (uint8_t)(len >> 8);
                p[4] = (uint8_t)(len);
                gpr_slice_buffer_add(&stream_writing->flow_controlled_buffer, hdr);
                if (stream_global->send_message->length > 0) {
                    stream_writing->send_message = stream_global->send_message;
                } else {
                    stream_writing->send_message = NULL;
                }
                stream_writing->stream_fetched = 0;
                stream_global->send_message = NULL;
            }
            if ((stream_writing->send_message != NULL ||
                    stream_writing->flow_controlled_buffer.length > 0) &&
                    stream_writing->outgoing_window > 0) {
                if (transport_writing->outgoing_window > 0) {
                    if (grpc_chttp2_list_add_writing_stream(transport_writing,
                                                            stream_writing)) {
                        GRPC_CHTTP2_STREAM_REF(stream_global, "chttp2_writing");
                    }
                } else {
                    grpc_chttp2_list_add_writing_stalled_by_transport(transport_writing,
                            stream_writing);
                }
            }
            if (stream_global->send_trailing_metadata) {
                stream_writing->send_trailing_metadata =
                    stream_global->send_trailing_metadata;
                stream_global->send_trailing_metadata = NULL;
                if (grpc_chttp2_list_add_writing_stream(transport_writing,
                                                        stream_writing)) {
                    GRPC_CHTTP2_STREAM_REF(stream_global, "chttp2_writing");
                }
            }
        }

        if (!stream_global->read_closed &&
                stream_global->unannounced_incoming_window_for_writing > 1024) {
            GRPC_CHTTP2_FLOW_MOVE_STREAM("write", transport_global, stream_writing,
                                         announce_window, stream_global,
                                         unannounced_incoming_window_for_writing);
            if (grpc_chttp2_list_add_writing_stream(transport_writing,
                                                    stream_writing)) {
                GRPC_CHTTP2_STREAM_REF(stream_global, "chttp2_writing");
            }
        }
    }