|  | @@ -69,10 +69,16 @@
 | 
	
		
			
				|  |  |  #define MAX_WRITE_BUFFER_SIZE (64 * 1024 * 1024)
 | 
	
		
			
				|  |  |  #define DEFAULT_MAX_HEADER_LIST_SIZE (16 * 1024)
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -#define DEFAULT_KEEPALIVE_TIME_SECOND INT_MAX
 | 
	
		
			
				|  |  | -#define DEFAULT_KEEPALIVE_TIMEOUT_SECOND 20
 | 
	
		
			
				|  |  | +#define DEFAULT_CLIENT_KEEPALIVE_TIME_S INT_MAX
 | 
	
		
			
				|  |  | +#define DEFAULT_CLIENT_KEEPALIVE_TIMEOUT_S 20
 | 
	
		
			
				|  |  |  #define DEFAULT_KEEPALIVE_PERMIT_WITHOUT_CALLS false
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | +static int g_default_client_keepalive_time_s = DEFAULT_CLIENT_KEEPALIVE_TIME_S;
 | 
	
		
			
				|  |  | +static int g_default_client_keepalive_timeout_s =
 | 
	
		
			
				|  |  | +    DEFAULT_CLIENT_KEEPALIVE_TIMEOUT_S;
 | 
	
		
			
				|  |  | +static bool g_default_keepalive_permit_without_calls =
 | 
	
		
			
				|  |  | +    DEFAULT_KEEPALIVE_PERMIT_WITHOUT_CALLS;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  |  #define MAX_CLIENT_STREAM_ID 0x7fffffffu
 | 
	
		
			
				|  |  |  int grpc_http_trace = 0;
 | 
	
		
			
				|  |  |  int grpc_flowctl_trace = 0;
 | 
	
	
		
			
				|  | @@ -142,6 +148,8 @@ static void send_ping_locked(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t,
 | 
	
		
			
				|  |  |                               grpc_chttp2_ping_type ping_type,
 | 
	
		
			
				|  |  |                               grpc_closure *on_initiate,
 | 
	
		
			
				|  |  |                               grpc_closure *on_complete);
 | 
	
		
			
				|  |  | +static void retry_initiate_ping_locked(grpc_exec_ctx *exec_ctx, void *tp,
 | 
	
		
			
				|  |  | +                                       grpc_error *error);
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  #define DEFAULT_MIN_TIME_BETWEEN_PINGS_MS 0
 | 
	
		
			
				|  |  |  #define DEFAULT_MAX_PINGS_BETWEEN_DATA 3
 | 
	
	
		
			
				|  | @@ -267,6 +275,8 @@ static void init_transport(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t,
 | 
	
		
			
				|  |  |    grpc_closure_init(&t->destructive_reclaimer_locked,
 | 
	
		
			
				|  |  |                      destructive_reclaimer_locked, t,
 | 
	
		
			
				|  |  |                      grpc_combiner_scheduler(t->combiner, false));
 | 
	
		
			
				|  |  | +  grpc_closure_init(&t->retry_initiate_ping_locked, retry_initiate_ping_locked,
 | 
	
		
			
				|  |  | +                    t, grpc_combiner_scheduler(t->combiner, false));
 | 
	
		
			
				|  |  |    grpc_closure_init(&t->start_bdp_ping_locked, start_bdp_ping_locked, t,
 | 
	
		
			
				|  |  |                      grpc_combiner_scheduler(t->combiner, false));
 | 
	
		
			
				|  |  |    grpc_closure_init(&t->finish_bdp_ping_locked, finish_bdp_ping_locked, t,
 | 
	
	
		
			
				|  | @@ -345,15 +355,16 @@ static void init_transport(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t,
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |    /* client-side keepalive setting */
 | 
	
		
			
				|  |  |    t->keepalive_time =
 | 
	
		
			
				|  |  | -      DEFAULT_KEEPALIVE_TIME_SECOND == INT_MAX
 | 
	
		
			
				|  |  | +      g_default_client_keepalive_time_s == INT_MAX
 | 
	
		
			
				|  |  |            ? gpr_inf_future(GPR_TIMESPAN)
 | 
	
		
			
				|  |  | -          : gpr_time_from_seconds(DEFAULT_KEEPALIVE_TIME_SECOND, GPR_TIMESPAN);
 | 
	
		
			
				|  |  | +          : gpr_time_from_seconds(g_default_client_keepalive_time_s,
 | 
	
		
			
				|  |  | +                                  GPR_TIMESPAN);
 | 
	
		
			
				|  |  |    t->keepalive_timeout =
 | 
	
		
			
				|  |  | -      DEFAULT_KEEPALIVE_TIMEOUT_SECOND == INT_MAX
 | 
	
		
			
				|  |  | +      g_default_client_keepalive_timeout_s == INT_MAX
 | 
	
		
			
				|  |  |            ? gpr_inf_future(GPR_TIMESPAN)
 | 
	
		
			
				|  |  | -          : gpr_time_from_seconds(DEFAULT_KEEPALIVE_TIMEOUT_SECOND,
 | 
	
		
			
				|  |  | +          : gpr_time_from_seconds(g_default_client_keepalive_timeout_s,
 | 
	
		
			
				|  |  |                                    GPR_TIMESPAN);
 | 
	
		
			
				|  |  | -  t->keepalive_permit_without_calls = DEFAULT_KEEPALIVE_PERMIT_WITHOUT_CALLS;
 | 
	
		
			
				|  |  | +  t->keepalive_permit_without_calls = g_default_keepalive_permit_without_calls;
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |    if (channel_args) {
 | 
	
		
			
				|  |  |      for (i = 0; i < channel_args->num_args; i++) {
 | 
	
	
		
			
				|  | @@ -403,24 +414,25 @@ static void init_transport(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t,
 | 
	
		
			
				|  |  |          t->enable_bdp_probe = grpc_channel_arg_get_integer(
 | 
	
		
			
				|  |  |              &channel_args->args[i], (grpc_integer_options){1, 0, 1});
 | 
	
		
			
				|  |  |        } else if (0 == strcmp(channel_args->args[i].key,
 | 
	
		
			
				|  |  | -                             GRPC_ARG_HTTP2_KEEPALIVE_TIME)) {
 | 
	
		
			
				|  |  | +                             GRPC_ARG_CLIENT_KEEPALIVE_TIME_S)) {
 | 
	
		
			
				|  |  |          const int value = grpc_channel_arg_get_integer(
 | 
	
		
			
				|  |  |              &channel_args->args[i],
 | 
	
		
			
				|  |  | -            (grpc_integer_options){DEFAULT_KEEPALIVE_TIME_SECOND, 1, INT_MAX});
 | 
	
		
			
				|  |  | +            (grpc_integer_options){g_default_client_keepalive_time_s, 1,
 | 
	
		
			
				|  |  | +                                   INT_MAX});
 | 
	
		
			
				|  |  |          t->keepalive_time = value == INT_MAX
 | 
	
		
			
				|  |  |                                  ? gpr_inf_future(GPR_TIMESPAN)
 | 
	
		
			
				|  |  |                                  : gpr_time_from_seconds(value, GPR_TIMESPAN);
 | 
	
		
			
				|  |  |        } else if (0 == strcmp(channel_args->args[i].key,
 | 
	
		
			
				|  |  | -                             GRPC_ARG_HTTP2_KEEPALIVE_TIMEOUT)) {
 | 
	
		
			
				|  |  | +                             GRPC_ARG_CLIENT_KEEPALIVE_TIMEOUT_S)) {
 | 
	
		
			
				|  |  |          const int value = grpc_channel_arg_get_integer(
 | 
	
		
			
				|  |  |              &channel_args->args[i],
 | 
	
		
			
				|  |  | -            (grpc_integer_options){DEFAULT_KEEPALIVE_TIMEOUT_SECOND, 0,
 | 
	
		
			
				|  |  | +            (grpc_integer_options){g_default_client_keepalive_timeout_s, 0,
 | 
	
		
			
				|  |  |                                     INT_MAX});
 | 
	
		
			
				|  |  |          t->keepalive_timeout = value == INT_MAX
 | 
	
		
			
				|  |  |                                     ? gpr_inf_future(GPR_TIMESPAN)
 | 
	
		
			
				|  |  |                                     : gpr_time_from_seconds(value, GPR_TIMESPAN);
 | 
	
		
			
				|  |  |        } else if (0 == strcmp(channel_args->args[i].key,
 | 
	
		
			
				|  |  | -                             GRPC_ARG_HTTP2_KEEPALIVE_PERMIT_WITHOUT_CALLS)) {
 | 
	
		
			
				|  |  | +                             GRPC_ARG_KEEPALIVE_PERMIT_WITHOUT_CALLS)) {
 | 
	
		
			
				|  |  |          t->keepalive_permit_without_calls =
 | 
	
		
			
				|  |  |              (uint32_t)grpc_channel_arg_get_integer(
 | 
	
		
			
				|  |  |                  &channel_args->args[i], (grpc_integer_options){0, 0, 1});
 | 
	
	
		
			
				|  | @@ -474,6 +486,7 @@ static void init_transport(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t,
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |    t->ping_state.pings_before_data_required =
 | 
	
		
			
				|  |  |        t->ping_policy.max_pings_without_data;
 | 
	
		
			
				|  |  | +  t->ping_state.is_delayed_ping_timer_set = false;
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |    /** Start client-side keepalive pings */
 | 
	
		
			
				|  |  |    if (t->is_client) {
 | 
	
	
		
			
				|  | @@ -1399,6 +1412,13 @@ static void send_ping_locked(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t,
 | 
	
		
			
				|  |  |    }
 | 
	
		
			
				|  |  |  }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | +static void retry_initiate_ping_locked(grpc_exec_ctx *exec_ctx, void *tp,
 | 
	
		
			
				|  |  | +                                       grpc_error *error) {
 | 
	
		
			
				|  |  | +  grpc_chttp2_transport *t = tp;
 | 
	
		
			
				|  |  | +  t->ping_state.is_delayed_ping_timer_set = false;
 | 
	
		
			
				|  |  | +  grpc_chttp2_initiate_write(exec_ctx, t, false, "retry_send_ping");
 | 
	
		
			
				|  |  | +}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  |  void grpc_chttp2_ack_ping(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t,
 | 
	
		
			
				|  |  |                            uint64_t id) {
 | 
	
		
			
				|  |  |    grpc_chttp2_ping_queue *pq =
 | 
	
	
		
			
				|  | @@ -2108,6 +2128,32 @@ static void finish_bdp_ping_locked(grpc_exec_ctx *exec_ctx, void *tp,
 | 
	
		
			
				|  |  |    GRPC_CHTTP2_UNREF_TRANSPORT(exec_ctx, t, "bdp_ping");
 | 
	
		
			
				|  |  |  }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | +void grpc_chttp2_config_default_keepalive_args(grpc_channel_args *args) {
 | 
	
		
			
				|  |  | +  size_t i;
 | 
	
		
			
				|  |  | +  if (args) {
 | 
	
		
			
				|  |  | +    for (i = 0; i < args->num_args; i++) {
 | 
	
		
			
				|  |  | +      if (0 == strcmp(args->args[i].key, GRPC_ARG_CLIENT_KEEPALIVE_TIME_S)) {
 | 
	
		
			
				|  |  | +        g_default_client_keepalive_time_s = grpc_channel_arg_get_integer(
 | 
	
		
			
				|  |  | +            &args->args[i], (grpc_integer_options){
 | 
	
		
			
				|  |  | +                                g_default_client_keepalive_time_s, 1, INT_MAX});
 | 
	
		
			
				|  |  | +      } else if (0 == strcmp(args->args[i].key,
 | 
	
		
			
				|  |  | +                             GRPC_ARG_CLIENT_KEEPALIVE_TIMEOUT_S)) {
 | 
	
		
			
				|  |  | +        g_default_client_keepalive_timeout_s = grpc_channel_arg_get_integer(
 | 
	
		
			
				|  |  | +            &args->args[i],
 | 
	
		
			
				|  |  | +            (grpc_integer_options){g_default_client_keepalive_timeout_s, 0,
 | 
	
		
			
				|  |  | +                                   INT_MAX});
 | 
	
		
			
				|  |  | +      } else if (0 == strcmp(args->args[i].key,
 | 
	
		
			
				|  |  | +                             GRPC_ARG_KEEPALIVE_PERMIT_WITHOUT_CALLS)) {
 | 
	
		
			
				|  |  | +        g_default_keepalive_permit_without_calls =
 | 
	
		
			
				|  |  | +            (uint32_t)grpc_channel_arg_get_integer(
 | 
	
		
			
				|  |  | +                &args->args[i],
 | 
	
		
			
				|  |  | +                (grpc_integer_options){g_default_keepalive_permit_without_calls,
 | 
	
		
			
				|  |  | +                                       0, 1});
 | 
	
		
			
				|  |  | +      }
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +  }
 | 
	
		
			
				|  |  | +}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  |  static void init_keepalive_ping_locked(grpc_exec_ctx *exec_ctx, void *arg,
 | 
	
		
			
				|  |  |                                         grpc_error *error) {
 | 
	
		
			
				|  |  |    grpc_chttp2_transport *t = arg;
 | 
	
	
		
			
				|  | @@ -2151,9 +2197,7 @@ static void finish_keepalive_ping_locked(grpc_exec_ctx *exec_ctx, void *arg,
 | 
	
		
			
				|  |  |        grpc_timer_init(
 | 
	
		
			
				|  |  |            exec_ctx, &t->keepalive_ping_timer,
 | 
	
		
			
				|  |  |            gpr_time_add(gpr_now(GPR_CLOCK_MONOTONIC), t->keepalive_time),
 | 
	
		
			
				|  |  | -          grpc_closure_create(init_keepalive_ping_locked, t,
 | 
	
		
			
				|  |  | -                              grpc_combiner_scheduler(t->combiner, false)),
 | 
	
		
			
				|  |  | -          gpr_now(GPR_CLOCK_MONOTONIC));
 | 
	
		
			
				|  |  | +          &t->init_keepalive_ping_locked, gpr_now(GPR_CLOCK_MONOTONIC));
 | 
	
		
			
				|  |  |      }
 | 
	
		
			
				|  |  |    }
 | 
	
		
			
				|  |  |    GRPC_CHTTP2_UNREF_TRANSPORT(exec_ctx, t, "keepalive ping end");
 |