diff options
Diffstat (limited to 'src/core/ext/transport/chttp2/server/secure/server_secure_chttp2.c')
-rw-r--r-- | src/core/ext/transport/chttp2/server/secure/server_secure_chttp2.c | 44 |
1 files changed, 24 insertions, 20 deletions
diff --git a/src/core/ext/transport/chttp2/server/secure/server_secure_chttp2.c b/src/core/ext/transport/chttp2/server/secure/server_secure_chttp2.c index afdf93398f..19aa22c7c4 100644 --- a/src/core/ext/transport/chttp2/server/secure/server_secure_chttp2.c +++ b/src/core/ext/transport/chttp2/server/secure/server_secure_chttp2.c @@ -117,34 +117,38 @@ static void on_handshake_done(grpc_exec_ctx *exec_ctx, void *arg, grpc_error *error) { grpc_handshaker_args *args = arg; server_secure_connection_state *connection_state = args->user_data; - if (error != GRPC_ERROR_NONE) { + gpr_mu_lock(&connection_state->server_state->mu); + if (error != GRPC_ERROR_NONE || connection_state->server_state->shutdown) { const char *error_str = grpc_error_string(error); gpr_log(GPR_ERROR, "Handshaking failed: %s", error_str); grpc_error_free_string(error_str); - gpr_mu_lock(&connection_state->server_state->mu); - } else { - gpr_mu_lock(&connection_state->server_state->mu); - if (!connection_state->server_state->shutdown) { - grpc_arg channel_arg = grpc_server_credentials_to_arg( - connection_state->server_state->creds); - grpc_channel_args *args_copy = - grpc_channel_args_copy_and_add(args->args, &channel_arg, 1); - grpc_transport *transport = - grpc_create_chttp2_transport(exec_ctx, args_copy, args->endpoint, 0); - grpc_server_setup_transport( - exec_ctx, connection_state->server_state->server, transport, - connection_state->accepting_pollset, args_copy); - grpc_channel_args_destroy(args_copy); - grpc_chttp2_transport_start_reading(exec_ctx, transport, - args->read_buffer); - } else { - // Need to destroy this here, because the server may have already - // gone away. + if (error == GRPC_ERROR_NONE) { + // We were shut down after handshaking completed successfully, so + // destroy the endpoint here. + // TODO(ctiller): It is currently necessary to shutdown endpoints + // before destroying them, even if we know that there are no + // pending read/write callbacks. This should be fixed, at which + // point this can be removed. + grpc_endpoint_shutdown(exec_ctx, args->endpoint); grpc_endpoint_destroy(exec_ctx, args->endpoint); + grpc_channel_args_destroy(args->args); grpc_slice_buffer_destroy(args->read_buffer); gpr_free(args->read_buffer); } + } else { + grpc_arg channel_arg = grpc_server_credentials_to_arg( + connection_state->server_state->creds); + grpc_channel_args *args_copy = + grpc_channel_args_copy_and_add(args->args, &channel_arg, 1); grpc_channel_args_destroy(args->args); + grpc_transport *transport = + grpc_create_chttp2_transport(exec_ctx, args_copy, args->endpoint, 0); + grpc_server_setup_transport( + exec_ctx, connection_state->server_state->server, transport, + connection_state->accepting_pollset, args_copy); + grpc_channel_args_destroy(args_copy); + grpc_chttp2_transport_start_reading(exec_ctx, transport, + args->read_buffer); } pending_handshake_manager_remove_locked(connection_state->server_state, connection_state->handshake_mgr); |