|
|
|
@ -194,6 +194,8 @@ struct call_data { |
|
|
|
|
static void begin_call(grpc_server *server, call_data *calld, |
|
|
|
|
requested_call *rc); |
|
|
|
|
static void fail_call(grpc_server *server, requested_call *rc); |
|
|
|
|
static void shutdown_channel(channel_data *chand, int send_goaway, |
|
|
|
|
int send_disconnect); |
|
|
|
|
|
|
|
|
|
static int call_list_join(call_data **root, call_data *call, call_list list) { |
|
|
|
|
GPR_ASSERT(!call->root[list]); |
|
|
|
@ -391,15 +393,28 @@ static int num_listeners(grpc_server *server) { |
|
|
|
|
|
|
|
|
|
static void maybe_finish_shutdown(grpc_server *server) { |
|
|
|
|
size_t i; |
|
|
|
|
if (server->shutdown && !server->shutdown_published && |
|
|
|
|
server->root_channel_data.next == &server->root_channel_data && |
|
|
|
|
server->lists[ALL_CALLS] == NULL && |
|
|
|
|
server->listeners_destroyed == num_listeners(server)) { |
|
|
|
|
server->shutdown_published = 1; |
|
|
|
|
for (i = 0; i < server->num_shutdown_tags; i++) { |
|
|
|
|
grpc_cq_end_op(server->shutdown_tags[i].cq, server->shutdown_tags[i].tag, |
|
|
|
|
NULL, 1); |
|
|
|
|
} |
|
|
|
|
if (!server->shutdown || server->shutdown_published) { |
|
|
|
|
return; |
|
|
|
|
} |
|
|
|
|
if (server->lists[ALL_CALLS] != NULL) { |
|
|
|
|
gpr_log(GPR_DEBUG, |
|
|
|
|
"Waiting for all calls to finish before destroying server"); |
|
|
|
|
return; |
|
|
|
|
} |
|
|
|
|
if (server->root_channel_data.next != &server->root_channel_data) { |
|
|
|
|
gpr_log(GPR_DEBUG, |
|
|
|
|
"Waiting for all channels to close before destroy server"); |
|
|
|
|
return; |
|
|
|
|
} |
|
|
|
|
if (server->listeners_destroyed < num_listeners(server)) { |
|
|
|
|
gpr_log(GPR_DEBUG, "Waiting for all listeners to be destroyed (@ %d/%d)", |
|
|
|
|
server->listeners_destroyed, num_listeners(server)); |
|
|
|
|
return; |
|
|
|
|
} |
|
|
|
|
server->shutdown_published = 1; |
|
|
|
|
for (i = 0; i < server->num_shutdown_tags; i++) { |
|
|
|
|
grpc_cq_end_op(server->shutdown_tags[i].cq, server->shutdown_tags[i].tag, |
|
|
|
|
NULL, 1); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
@ -417,6 +432,14 @@ static grpc_mdelem *server_filter(void *user_data, grpc_mdelem *md) { |
|
|
|
|
return md; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static void decrement_call_count(channel_data *chand) { |
|
|
|
|
chand->num_calls--; |
|
|
|
|
if (0 == chand->num_calls && chand->server->shutdown) { |
|
|
|
|
shutdown_channel(chand, 0, 1); |
|
|
|
|
} |
|
|
|
|
maybe_finish_shutdown(chand->server); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static void server_on_recv(void *ptr, int success) { |
|
|
|
|
grpc_call_element *elem = ptr; |
|
|
|
|
call_data *calld = elem->call_data; |
|
|
|
@ -463,7 +486,7 @@ static void server_on_recv(void *ptr, int success) { |
|
|
|
|
grpc_iomgr_add_callback(kill_zombie, elem); |
|
|
|
|
} |
|
|
|
|
if (call_list_remove(calld, ALL_CALLS)) { |
|
|
|
|
maybe_finish_shutdown(chand->server); |
|
|
|
|
decrement_call_count(chand); |
|
|
|
|
} |
|
|
|
|
gpr_mu_unlock(&chand->server->mu); |
|
|
|
|
break; |
|
|
|
@ -556,6 +579,7 @@ static void finish_shutdown_channel(void *p, int success) { |
|
|
|
|
static void shutdown_channel(channel_data *chand, int send_goaway, |
|
|
|
|
int send_disconnect) { |
|
|
|
|
shutdown_channel_args *sca; |
|
|
|
|
gpr_log(GPR_DEBUG, "shutdown_channel: %p %d %d", chand, send_goaway, send_disconnect); |
|
|
|
|
grpc_channel_internal_ref(chand->channel); |
|
|
|
|
sca = gpr_malloc(sizeof(shutdown_channel_args)); |
|
|
|
|
sca->chand = chand; |
|
|
|
@ -593,12 +617,8 @@ static void destroy_call_elem(grpc_call_element *elem) { |
|
|
|
|
for (i = 0; i < CALL_LIST_COUNT; i++) { |
|
|
|
|
removed[i] = call_list_remove(elem->call_data, i); |
|
|
|
|
} |
|
|
|
|
chand->num_calls--; |
|
|
|
|
if (0 == chand->num_calls && chand->server->shutdown) { |
|
|
|
|
shutdown_channel(chand, 0, 1); |
|
|
|
|
} |
|
|
|
|
if (removed[ALL_CALLS]) { |
|
|
|
|
maybe_finish_shutdown(chand->server); |
|
|
|
|
decrement_call_count(chand); |
|
|
|
|
} |
|
|
|
|
gpr_mu_unlock(&chand->server->mu); |
|
|
|
|
|
|
|
|
|