|  | @@ -66,11 +66,9 @@ int grpc_chttp2_unlocking_check_writes(
 | 
	
		
			
				|  |  |    /* 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 (transport_global->outgoing_window &&
 | 
	
		
			
				|  |  | -         grpc_chttp2_list_pop_writable_stream(transport_global,
 | 
	
		
			
				|  |  | +  while (grpc_chttp2_list_pop_writable_stream(transport_global,
 | 
	
		
			
				|  |  |                                                transport_writing, &stream_global,
 | 
	
		
			
				|  |  | -                                              &stream_writing) &&
 | 
	
		
			
				|  |  | -         stream_global->outgoing_window > 0) {
 | 
	
		
			
				|  |  | +                                              &stream_writing)) {
 | 
	
		
			
				|  |  |      stream_writing->id = stream_global->id;
 | 
	
		
			
				|  |  |      window_delta = grpc_chttp2_preencode(
 | 
	
		
			
				|  |  |          stream_global->outgoing_sopb->ops, &stream_global->outgoing_sopb->nops,
 | 
	
	
		
			
				|  | @@ -106,20 +104,21 @@ int grpc_chttp2_unlocking_check_writes(
 | 
	
		
			
				|  |  |    /* for each grpc_chttp2_stream that wants to update its window, add that
 | 
	
		
			
				|  |  |     * window here */
 | 
	
		
			
				|  |  |    while (grpc_chttp2_list_pop_writable_window_update_stream(transport_global,
 | 
	
		
			
				|  |  | -                                                            &stream_global)) {
 | 
	
		
			
				|  |  | -    window_delta =
 | 
	
		
			
				|  |  | -        transport_global->settings[GRPC_LOCAL_SETTINGS]
 | 
	
		
			
				|  |  | -                                  [GRPC_CHTTP2_SETTINGS_INITIAL_WINDOW_SIZE] -
 | 
	
		
			
				|  |  | -        stream_global->incoming_window;
 | 
	
		
			
				|  |  | -    if (!stream_global->read_closed && window_delta > 0) {
 | 
	
		
			
				|  |  | -      gpr_slice_buffer_add(
 | 
	
		
			
				|  |  | -          &transport_writing->outbuf,
 | 
	
		
			
				|  |  | -          grpc_chttp2_window_update_create(stream_global->id, window_delta));
 | 
	
		
			
				|  |  | +                                                            transport_writing,
 | 
	
		
			
				|  |  | +                                                            &stream_global,
 | 
	
		
			
				|  |  | +                                                            &stream_writing)) {
 | 
	
		
			
				|  |  | +    stream_writing->id = stream_global->id;
 | 
	
		
			
				|  |  | +    if (!stream_global->read_closed && stream_global->unannounced_incoming_window > 0) {
 | 
	
		
			
				|  |  | +      stream_writing->announce_window = stream_global->unannounced_incoming_window;
 | 
	
		
			
				|  |  |        GRPC_CHTTP2_FLOWCTL_TRACE_STREAM("write", transport_global, stream_global,
 | 
	
		
			
				|  |  | -                                       incoming_window, window_delta);
 | 
	
		
			
				|  |  | -      stream_global->incoming_window += window_delta;
 | 
	
		
			
				|  |  | +                                       incoming_window, stream_global->unannounced_incoming_window);
 | 
	
		
			
				|  |  | +      GRPC_CHTTP2_FLOWCTL_TRACE_STREAM("write", transport_global, stream_global,
 | 
	
		
			
				|  |  | +                                       unannounced_incoming_window, -(gpr_int64)stream_global->unannounced_incoming_window);
 | 
	
		
			
				|  |  | +      stream_global->incoming_window += stream_global->unannounced_incoming_window;
 | 
	
		
			
				|  |  | +      stream_global->unannounced_incoming_window = 0;
 | 
	
		
			
				|  |  |        grpc_chttp2_list_add_incoming_window_updated(transport_global,
 | 
	
		
			
				|  |  |                                                     stream_global);
 | 
	
		
			
				|  |  | +      grpc_chttp2_list_add_writing_stream(transport_writing, stream_writing);
 | 
	
		
			
				|  |  |      }
 | 
	
		
			
				|  |  |    }
 | 
	
		
			
				|  |  |  
 | 
	
	
		
			
				|  | @@ -169,10 +168,19 @@ static void finalize_outbuf(grpc_chttp2_transport_writing *transport_writing) {
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |    while (
 | 
	
		
			
				|  |  |        grpc_chttp2_list_pop_writing_stream(transport_writing, &stream_writing)) {
 | 
	
		
			
				|  |  | -    grpc_chttp2_encode(stream_writing->sopb.ops, stream_writing->sopb.nops,
 | 
	
		
			
				|  |  | -                       stream_writing->send_closed != GRPC_DONT_SEND_CLOSED,
 | 
	
		
			
				|  |  | -                       stream_writing->id, &transport_writing->hpack_compressor,
 | 
	
		
			
				|  |  | -                       &transport_writing->outbuf);
 | 
	
		
			
				|  |  | +    if (stream_writing->sopb.nops > 0 || stream_writing->send_closed != GRPC_DONT_SEND_CLOSED) {
 | 
	
		
			
				|  |  | +      grpc_chttp2_encode(stream_writing->sopb.ops, stream_writing->sopb.nops,
 | 
	
		
			
				|  |  | +                         stream_writing->send_closed != GRPC_DONT_SEND_CLOSED,
 | 
	
		
			
				|  |  | +                         stream_writing->id, &transport_writing->hpack_compressor,
 | 
	
		
			
				|  |  | +                         &transport_writing->outbuf);
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +    if (stream_writing->announce_window > 0) {
 | 
	
		
			
				|  |  | +      gpr_slice_buffer_add(
 | 
	
		
			
				|  |  | +          &transport_writing->outbuf,
 | 
	
		
			
				|  |  | +          grpc_chttp2_window_update_create(
 | 
	
		
			
				|  |  | +              stream_writing->id, stream_writing->announce_window));
 | 
	
		
			
				|  |  | +      stream_writing->announce_window = 0;
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  |      stream_writing->sopb.nops = 0;
 | 
	
		
			
				|  |  |      if (stream_writing->send_closed == GRPC_SEND_CLOSED_WITH_RST_STREAM) {
 | 
	
		
			
				|  |  |        gpr_slice_buffer_add(&transport_writing->outbuf,
 | 
	
	
		
			
				|  | @@ -197,7 +205,8 @@ void grpc_chttp2_cleanup_writing(
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |    while (grpc_chttp2_list_pop_written_stream(
 | 
	
		
			
				|  |  |        transport_global, transport_writing, &stream_global, &stream_writing)) {
 | 
	
		
			
				|  |  | -    if (stream_global->outgoing_sopb->nops == 0) {
 | 
	
		
			
				|  |  | +    if (stream_global->outgoing_sopb != NULL &&
 | 
	
		
			
				|  |  | +        stream_global->outgoing_sopb->nops == 0) {
 | 
	
		
			
				|  |  |        stream_global->outgoing_sopb = NULL;
 | 
	
		
			
				|  |  |        grpc_chttp2_schedule_closure(transport_global,
 | 
	
		
			
				|  |  |                                     stream_global->send_done_closure, 1);
 |