@ -25,6 +25,7 @@
# include <grpc/support/log.h>
# include "src/core/lib/compression/stream_compression.h"
# include "src/core/lib/debug/stats.h"
# include "src/core/lib/profiling/timers.h"
# include "src/core/lib/slice/slice_internal.h"
@ -150,7 +151,11 @@ static void report_stall(grpc_chttp2_transport* t, grpc_chttp2_stream* s,
" :flowed=% " PRId64 " :peer_initwin=%d:t_win=% " PRId64
" :s_win=%d:s_delta=% " PRId64 " ] " ,
t - > peer_string , t , s - > id , staller , s - > flow_controlled_buffer . length ,
s - > compressed_data_buffer . length , s - > flow_controlled_bytes_flowed ,
s - > stream_compression_method = =
GRPC_STREAM_COMPRESSION_IDENTITY_COMPRESS
? 0
: s - > compressed_data_buffer . length ,
s - > flow_controlled_bytes_flowed ,
t - > settings [ GRPC_ACKED_SETTINGS ]
[ GRPC_CHTTP2_SETTINGS_INITIAL_WINDOW_SIZE ] ,
t - > flow_control - > remote_window ( ) ,
@ -325,7 +330,23 @@ class DataSendContext {
bool AnyOutgoing ( ) const { return max_outgoing ( ) > 0 ; }
void FlushUncompressedBytes ( ) {
uint32_t send_bytes = static_cast < uint32_t > GPR_MIN (
max_outgoing ( ) , s_ - > flow_controlled_buffer . length ) ;
is_last_frame_ = send_bytes = = s_ - > flow_controlled_buffer . length & &
s_ - > fetching_send_message = = nullptr & &
s_ - > send_trailing_metadata ! = nullptr & &
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 ) ;
s_ - > flow_control - > SentData ( send_bytes ) ;
s_ - > sending_bytes + = send_bytes ;
}
void FlushCompressedBytes ( ) {
GPR_DEBUG_ASSERT ( s_ - > stream_compression_method ! =
GRPC_STREAM_COMPRESSION_IDENTITY_COMPRESS ) ;
uint32_t send_bytes = static_cast < uint32_t > GPR_MIN (
max_outgoing ( ) , s_ - > compressed_data_buffer . length ) ;
bool is_last_data_frame =
@ -360,6 +381,9 @@ class DataSendContext {
}
void CompressMoreBytes ( ) {
GPR_DEBUG_ASSERT ( s_ - > stream_compression_method ! =
GRPC_STREAM_COMPRESSION_IDENTITY_COMPRESS ) ;
if ( s_ - > stream_compression_ctx = = nullptr ) {
s_ - > stream_compression_ctx =
grpc_stream_compression_context_create ( s_ - > stream_compression_method ) ;
@ -417,7 +441,7 @@ class StreamWriteContext {
// https://github.com/grpc/proposal/blob/master/A6-client-retries.md#when-retries-are-valid
if ( ! t_ - > is_client & & s_ - > fetching_send_message = = nullptr & &
s_ - > flow_controlled_buffer . length = = 0 & &
s_ - > compressed_data_buffer . length = = 0 & &
compressed_data_buffer_len ( ) = = 0 & &
s_ - > send_trailing_metadata ! = nullptr & &
is_default_initial_metadata ( s_ - > send_initial_metadata ) ) {
ConvertInitialMetadataToTrailingMetadata ( ) ;
@ -446,6 +470,13 @@ class StreamWriteContext {
" send_initial_metadata_finished " ) ;
}
bool compressed_data_buffer_len ( ) {
return s_ - > stream_compression_method = =
GRPC_STREAM_COMPRESSION_IDENTITY_COMPRESS
? 0
: s_ - > compressed_data_buffer . length ;
}
void FlushWindowUpdates ( ) {
/* send any window updates */
const uint32_t stream_announce = s_ - > flow_control - > MaybeSendUpdate ( ) ;
@ -462,7 +493,7 @@ class StreamWriteContext {
if ( ! s_ - > sent_initial_metadata ) return ;
if ( s_ - > flow_controlled_buffer . length = = 0 & &
s_ - > compressed_data_buffer . length = = 0 ) {
compressed_data_buffer_len ( ) = = 0 ) {
return ; // early out: nothing to do
}
@ -479,13 +510,21 @@ class StreamWriteContext {
return ; // early out: nothing to do
}
while ( ( s_ - > flow_controlled_buffer . length > 0 | |
s_ - > compressed_data_buffer . length > 0 ) & &
data_send_context . max_outgoing ( ) > 0 ) {
if ( s_ - > compressed_data_buffer . length > 0 ) {
data_send_context . FlushCompressedBytes ( ) ;
} else {
data_send_context . CompressMoreBytes ( ) ;
if ( s_ - > stream_compression_method = =
GRPC_STREAM_COMPRESSION_IDENTITY_COMPRESS ) {
while ( s_ - > flow_controlled_buffer . length > 0 & &
data_send_context . max_outgoing ( ) > 0 ) {
data_send_context . FlushUncompressedBytes ( ) ;
}
} else {
while ( ( s_ - > flow_controlled_buffer . length > 0 | |
s_ - > compressed_data_buffer . length > 0 ) & &
data_send_context . max_outgoing ( ) > 0 ) {
if ( s_ - > compressed_data_buffer . length > 0 ) {
data_send_context . FlushCompressedBytes ( ) ;
} else {
data_send_context . CompressMoreBytes ( ) ;
}
}
}
write_context_ - > ResetPingClock ( ) ;
@ -495,7 +534,7 @@ class StreamWriteContext {
data_send_context . CallCallbacks ( ) ;
stream_became_writable_ = true ;
if ( s_ - > flow_controlled_buffer . length > 0 | |
s_ - > compressed_data_buffer . length > 0 ) {
compressed_data_buffer_len ( ) > 0 ) {
GRPC_CHTTP2_STREAM_REF ( s_ , " chttp2_writing:fork " ) ;
grpc_chttp2_list_add_writable_stream ( t_ , s_ ) ;
}
@ -508,7 +547,7 @@ class StreamWriteContext {
if ( s_ - > send_trailing_metadata = = nullptr ) return ;
if ( s_ - > fetching_send_message ! = nullptr ) return ;
if ( s_ - > flow_controlled_buffer . length ! = 0 ) return ;
if ( s_ - > compressed_data_buffer . length ! = 0 ) return ;
if ( compressed_data_buffer_len ( ) ! = 0 ) return ;
GRPC_CHTTP2_IF_TRACING ( gpr_log ( GPR_INFO , " sending trailing_metadata " ) ) ;
if ( grpc_metadata_batch_is_empty ( s_ - > send_trailing_metadata ) ) {