diff --git a/src/core/ext/filters/max_age/max_age_filter.cc b/src/core/ext/filters/max_age/max_age_filter.cc index a514c8a1bf5..330cfff02fe 100644 --- a/src/core/ext/filters/max_age/max_age_filter.cc +++ b/src/core/ext/filters/max_age/max_age_filter.cc @@ -91,7 +91,35 @@ struct channel_data { grpc_connectivity_state connectivity_state; /* Number of active calls */ gpr_atm call_count; - /* Current state of channel idleness and max_idle_timer */ + /* 'idle_state' holds the states of max_idle_timer and channel idleness. + It can contain one of the following values: + +--------------------------------+----------------+---------+ + | idle_state | max_idle_timer | channel | + +--------------------------------+----------------+---------+ + | MAX_IDLE_STATE_INIT | unset | busy | + | MAX_IDLE_STATE_TIMER_SET | set, valid | idle | + | MAX_IDLE_STATE_SEEN_EXIT_IDLE | set, invalid | busy | + | MAX_IDLE_STATE_SEEN_ENTER_IDLE | set, invalid | idle | + +--------------------------------+----------------+---------+ + + max_idle_timer will not be cancelled (unless the channel is shutting down). + If the timer callback is called when the max_idle_timer is valid (i.e. + idle_state is MAX_IDLE_STATE_TIMER_SET), the channel will be closed due to + idleness, otherwise the channel won't be changed. + + State transitions: + + MAX_IDLE_STATE_INIT <-------3------ MAX_IDLE_STATE_SEEN_EXIT_IDLE + ^ | ^ ^ | + | | | | | + 1 2 +-----------4------------+ 6 7 + | | | | | + | v | | v + MAX_IDLE_STATE_TIMER_SET <----5------ MAX_IDLE_STATE_SEEN_ENTER_IDLE + + For 1, 3, 5 : See max_idle_timer_cb() function + For 2, 7 : See decrease_call_count() function + For 4, 6 : See increase_call_count() function */ gpr_atm idle_state; /* Time when the channel finished its last outstanding call, in grpc_millis */ gpr_atm last_enter_idle_time_millis; @@ -101,6 +129,7 @@ struct channel_data { /* Increase the nubmer of active calls. Before the increasement, if there are no calls, the max_idle_timer should be cancelled. */ static void increase_call_count(channel_data* chand) { + /* Exit idle */ if (gpr_atm_full_fetch_add(&chand->call_count, 1) == 0) { while (true) { gpr_atm idle_state = gpr_atm_acq_load(&chand->idle_state); @@ -126,6 +155,7 @@ static void increase_call_count(channel_data* chand) { /* Decrease the nubmer of active calls. After the decrement, if there are no calls, the max_idle_timer should be started. */ static void decrease_call_count(channel_data* chand) { + /* Enter idle */ if (gpr_atm_full_fetch_add(&chand->call_count, -1) == 1) { gpr_atm_no_barrier_store(&chand->last_enter_idle_time_millis, (gpr_atm)grpc_exec_ctx_now(exec_ctx));