|
|
|
@ -212,6 +212,11 @@ struct grpc_server { |
|
|
|
|
gpr_mu mu_global; /* mutex for server and channel state */ |
|
|
|
|
gpr_mu mu_call; /* mutex for call-specific state */ |
|
|
|
|
|
|
|
|
|
/* startup synchronization: flag is protected by mu_global, signals whether
|
|
|
|
|
we are doing the listener start routine or not */ |
|
|
|
|
bool starting; |
|
|
|
|
gpr_cv starting_cv; |
|
|
|
|
|
|
|
|
|
registered_method *registered_methods; |
|
|
|
|
/** one request matcher for unregistered methods */ |
|
|
|
|
request_matcher unregistered_request_matcher; |
|
|
|
@ -389,6 +394,7 @@ static void server_delete(grpc_exec_ctx *exec_ctx, grpc_server *server) { |
|
|
|
|
grpc_channel_args_destroy(exec_ctx, server->channel_args); |
|
|
|
|
gpr_mu_destroy(&server->mu_global); |
|
|
|
|
gpr_mu_destroy(&server->mu_call); |
|
|
|
|
gpr_cv_destroy(&server->starting_cv); |
|
|
|
|
while ((rm = server->registered_methods) != NULL) { |
|
|
|
|
server->registered_methods = rm->next; |
|
|
|
|
if (server->started) { |
|
|
|
@ -1022,6 +1028,7 @@ grpc_server *grpc_server_create(const grpc_channel_args *args, void *reserved) { |
|
|
|
|
|
|
|
|
|
gpr_mu_init(&server->mu_global); |
|
|
|
|
gpr_mu_init(&server->mu_call); |
|
|
|
|
gpr_cv_init(&server->starting_cv); |
|
|
|
|
|
|
|
|
|
/* decremented by grpc_server_destroy */ |
|
|
|
|
gpr_ref_init(&server->internal_refcount, 1); |
|
|
|
@ -1084,6 +1091,12 @@ static void start_listeners(grpc_exec_ctx *exec_ctx, void *s, |
|
|
|
|
for (listener *l = server->listeners; l; l = l->next) { |
|
|
|
|
l->start(exec_ctx, server, l->arg, server->pollsets, server->pollset_count); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
gpr_mu_lock(&server->mu_global); |
|
|
|
|
server->starting = false; |
|
|
|
|
gpr_cv_signal(&server->starting_cv); |
|
|
|
|
gpr_mu_unlock(&server->mu_global); |
|
|
|
|
|
|
|
|
|
server_unref(exec_ctx, server); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
@ -1122,6 +1135,7 @@ void grpc_server_start(grpc_server *server) { |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
server_ref(server); |
|
|
|
|
server->starting = true; |
|
|
|
|
grpc_closure_sched(&exec_ctx, grpc_closure_create(start_listeners, server, |
|
|
|
|
grpc_executor_scheduler), |
|
|
|
|
GRPC_ERROR_NONE); |
|
|
|
@ -1258,8 +1272,14 @@ void grpc_server_shutdown_and_notify(grpc_server *server, |
|
|
|
|
GRPC_API_TRACE("grpc_server_shutdown_and_notify(server=%p, cq=%p, tag=%p)", 3, |
|
|
|
|
(server, cq, tag)); |
|
|
|
|
|
|
|
|
|
/* lock, and gather up some stuff to do */ |
|
|
|
|
/* wait for startup to be finished: locks mu_global */ |
|
|
|
|
gpr_mu_lock(&server->mu_global); |
|
|
|
|
while (server->starting) { |
|
|
|
|
gpr_cv_wait(&server->starting_cv, &server->mu_global, |
|
|
|
|
gpr_inf_future(GPR_CLOCK_REALTIME)); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/* stay locked, and gather up some stuff to do */ |
|
|
|
|
grpc_cq_begin_op(cq, tag); |
|
|
|
|
if (server->shutdown_published) { |
|
|
|
|
grpc_cq_end_op(&exec_ctx, cq, tag, GRPC_ERROR_NONE, done_published_shutdown, |
|
|
|
|