|
|
@ -303,7 +303,8 @@ grpc_chttp2_begin_write_result grpc_chttp2_begin_write( |
|
|
|
} |
|
|
|
} |
|
|
|
if (sent_initial_metadata) { |
|
|
|
if (sent_initial_metadata) { |
|
|
|
/* send any body bytes, if allowed by flow control */ |
|
|
|
/* send any body bytes, if allowed by flow control */ |
|
|
|
if (s->flow_controlled_buffer.length > 0) { |
|
|
|
if (s->flow_controlled_buffer.length > 0 || |
|
|
|
|
|
|
|
s->compressed_data_buffer.length > 0) { |
|
|
|
uint32_t stream_outgoing_window = (uint32_t)GPR_MAX( |
|
|
|
uint32_t stream_outgoing_window = (uint32_t)GPR_MAX( |
|
|
|
0, |
|
|
|
0, |
|
|
|
s->outgoing_window_delta + |
|
|
|
s->outgoing_window_delta + |
|
|
@ -314,21 +315,63 @@ grpc_chttp2_begin_write_result grpc_chttp2_begin_write( |
|
|
|
[GRPC_CHTTP2_SETTINGS_MAX_FRAME_SIZE], |
|
|
|
[GRPC_CHTTP2_SETTINGS_MAX_FRAME_SIZE], |
|
|
|
GPR_MIN(stream_outgoing_window, t->outgoing_window)); |
|
|
|
GPR_MIN(stream_outgoing_window, t->outgoing_window)); |
|
|
|
if (max_outgoing > 0) { |
|
|
|
if (max_outgoing > 0) { |
|
|
|
uint32_t send_bytes = |
|
|
|
bool is_last_data_frame; |
|
|
|
(uint32_t)GPR_MIN(max_outgoing, s->flow_controlled_buffer.length); |
|
|
|
bool is_last_frame; |
|
|
|
bool is_last_data_frame = |
|
|
|
if (s->stream_compression_send_enabled) { |
|
|
|
s->fetching_send_message == NULL && |
|
|
|
while ((s->flow_controlled_buffer.length > 0 || |
|
|
|
send_bytes == s->flow_controlled_buffer.length; |
|
|
|
s->compressed_data_buffer.length > 0) && |
|
|
|
bool is_last_frame = |
|
|
|
max_outgoing > 0) { |
|
|
|
is_last_data_frame && s->send_trailing_metadata != NULL && |
|
|
|
if (s->compressed_data_buffer.length > 0) { |
|
|
|
grpc_metadata_batch_is_empty(s->send_trailing_metadata); |
|
|
|
uint32_t send_bytes = (uint32_t)GPR_MIN( |
|
|
|
grpc_chttp2_encode_data(s->id, &s->flow_controlled_buffer, send_bytes, |
|
|
|
max_outgoing, s->compressed_data_buffer.length); |
|
|
|
is_last_frame, &s->stats.outgoing, |
|
|
|
is_last_data_frame = |
|
|
|
&t->outbuf); |
|
|
|
(send_bytes == s->compressed_data_buffer.length && |
|
|
|
GRPC_CHTTP2_FLOW_DEBIT_STREAM("write", t, s, outgoing_window_delta, |
|
|
|
s->flow_controlled_buffer.length == 0 && |
|
|
|
send_bytes); |
|
|
|
s->fetching_send_message == NULL); |
|
|
|
GRPC_CHTTP2_FLOW_DEBIT_TRANSPORT("write", t, outgoing_window, |
|
|
|
is_last_frame = |
|
|
|
send_bytes); |
|
|
|
is_last_data_frame && s->send_trailing_metadata != NULL && |
|
|
|
|
|
|
|
grpc_metadata_batch_is_empty(s->send_trailing_metadata); |
|
|
|
|
|
|
|
grpc_chttp2_encode_data(s->id, &s->compressed_data_buffer, |
|
|
|
|
|
|
|
send_bytes, is_last_frame, |
|
|
|
|
|
|
|
&s->stats.outgoing, &t->outbuf); |
|
|
|
|
|
|
|
GRPC_CHTTP2_FLOW_DEBIT_STREAM( |
|
|
|
|
|
|
|
"write", t, s, outgoing_window_delta, send_bytes); |
|
|
|
|
|
|
|
GRPC_CHTTP2_FLOW_DEBIT_TRANSPORT("write", t, outgoing_window, |
|
|
|
|
|
|
|
send_bytes); |
|
|
|
|
|
|
|
max_outgoing -= send_bytes; |
|
|
|
|
|
|
|
if (s->compressed_data_buffer.length == 0) { |
|
|
|
|
|
|
|
s->sending_bytes += s->uncompressed_data_size; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} else { |
|
|
|
|
|
|
|
if (s->stream_compression_ctx == NULL) { |
|
|
|
|
|
|
|
s->stream_compression_ctx = |
|
|
|
|
|
|
|
grpc_stream_compression_context_create( |
|
|
|
|
|
|
|
GRPC_STREAM_COMPRESSION_COMPRESS); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
s->uncompressed_data_size = s->flow_controlled_buffer.length; |
|
|
|
|
|
|
|
GPR_ASSERT(grpc_stream_compress( |
|
|
|
|
|
|
|
s->stream_compression_ctx, &s->flow_controlled_buffer, |
|
|
|
|
|
|
|
&s->compressed_data_buffer, NULL, ~(size_t)0, |
|
|
|
|
|
|
|
GRPC_STREAM_COMPRESSION_FLUSH_SYNC)); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} else { |
|
|
|
|
|
|
|
uint32_t send_bytes = (uint32_t)GPR_MIN( |
|
|
|
|
|
|
|
max_outgoing, s->flow_controlled_buffer.length); |
|
|
|
|
|
|
|
is_last_data_frame = s->fetching_send_message == NULL && |
|
|
|
|
|
|
|
send_bytes == s->flow_controlled_buffer.length; |
|
|
|
|
|
|
|
is_last_frame = |
|
|
|
|
|
|
|
is_last_data_frame && s->send_trailing_metadata != NULL && |
|
|
|
|
|
|
|
grpc_metadata_batch_is_empty(s->send_trailing_metadata); |
|
|
|
|
|
|
|
grpc_chttp2_encode_data(s->id, &s->flow_controlled_buffer, |
|
|
|
|
|
|
|
send_bytes, is_last_frame, |
|
|
|
|
|
|
|
&s->stats.outgoing, &t->outbuf); |
|
|
|
|
|
|
|
GRPC_CHTTP2_FLOW_DEBIT_STREAM("write", t, s, outgoing_window_delta, |
|
|
|
|
|
|
|
send_bytes); |
|
|
|
|
|
|
|
GRPC_CHTTP2_FLOW_DEBIT_TRANSPORT("write", t, outgoing_window, |
|
|
|
|
|
|
|
send_bytes); |
|
|
|
|
|
|
|
s->sending_bytes += send_bytes; |
|
|
|
|
|
|
|
} |
|
|
|
t->ping_state.pings_before_data_required = |
|
|
|
t->ping_state.pings_before_data_required = |
|
|
|
t->ping_policy.max_pings_without_data; |
|
|
|
t->ping_policy.max_pings_without_data; |
|
|
|
if (!t->is_client) { |
|
|
|
if (!t->is_client) { |
|
|
@ -345,9 +388,9 @@ grpc_chttp2_begin_write_result grpc_chttp2_begin_write( |
|
|
|
&s->stats.outgoing)); |
|
|
|
&s->stats.outgoing)); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
s->sending_bytes += send_bytes; |
|
|
|
|
|
|
|
now_writing = true; |
|
|
|
now_writing = true; |
|
|
|
if (s->flow_controlled_buffer.length > 0) { |
|
|
|
if (s->flow_controlled_buffer.length > 0 || |
|
|
|
|
|
|
|
s->compressed_data_buffer.length > 0) { |
|
|
|
GRPC_CHTTP2_STREAM_REF(s, "chttp2_writing:fork"); |
|
|
|
GRPC_CHTTP2_STREAM_REF(s, "chttp2_writing:fork"); |
|
|
|
grpc_chttp2_list_add_writable_stream(t, s); |
|
|
|
grpc_chttp2_list_add_writable_stream(t, s); |
|
|
|
} |
|
|
|
} |
|
|
@ -361,7 +404,8 @@ grpc_chttp2_begin_write_result grpc_chttp2_begin_write( |
|
|
|
} |
|
|
|
} |
|
|
|
if (s->send_trailing_metadata != NULL && |
|
|
|
if (s->send_trailing_metadata != NULL && |
|
|
|
s->fetching_send_message == NULL && |
|
|
|
s->fetching_send_message == NULL && |
|
|
|
s->flow_controlled_buffer.length == 0) { |
|
|
|
s->flow_controlled_buffer.length == 0 && |
|
|
|
|
|
|
|
s->compressed_data_buffer.length == 0) { |
|
|
|
GRPC_CHTTP2_IF_TRACING(gpr_log(GPR_INFO, "sending trailing_metadata")); |
|
|
|
GRPC_CHTTP2_IF_TRACING(gpr_log(GPR_INFO, "sending trailing_metadata")); |
|
|
|
if (grpc_metadata_batch_is_empty(s->send_trailing_metadata)) { |
|
|
|
if (grpc_metadata_batch_is_empty(s->send_trailing_metadata)) { |
|
|
|
grpc_chttp2_encode_data(s->id, &s->flow_controlled_buffer, 0, true, |
|
|
|
grpc_chttp2_encode_data(s->id, &s->flow_controlled_buffer, 0, true, |
|
|
|