diff options
Diffstat (limited to 'src/core/lib/surface/init.cc')
-rw-r--r-- | src/core/lib/surface/init.cc | 209 |
1 files changed, 209 insertions, 0 deletions
diff --git a/src/core/lib/surface/init.cc b/src/core/lib/surface/init.cc new file mode 100644 index 0000000000..b089da2c54 --- /dev/null +++ b/src/core/lib/surface/init.cc @@ -0,0 +1,209 @@ +/* + * + * Copyright 2015 gRPC authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#include <grpc/support/port_platform.h> + +#include <limits.h> +#include <memory.h> + +#include <grpc/grpc.h> +#include <grpc/support/alloc.h> +#include <grpc/support/log.h> +#include <grpc/support/time.h> +#include "src/core/lib/channel/channel_stack.h" +#include "src/core/lib/channel/connected_channel.h" +#include "src/core/lib/channel/handshaker_registry.h" +#include "src/core/lib/debug/stats.h" +#include "src/core/lib/debug/trace.h" +#include "src/core/lib/http/parser.h" +#include "src/core/lib/iomgr/call_combiner.h" +#include "src/core/lib/iomgr/combiner.h" +#include "src/core/lib/iomgr/executor.h" +#include "src/core/lib/iomgr/iomgr.h" +#include "src/core/lib/iomgr/resource_quota.h" +#include "src/core/lib/iomgr/timer_manager.h" +#include "src/core/lib/profiling/timers.h" +#include "src/core/lib/slice/slice_internal.h" +#include "src/core/lib/surface/alarm_internal.h" +#include "src/core/lib/surface/api_trace.h" +#include "src/core/lib/surface/call.h" +#include "src/core/lib/surface/channel_init.h" +#include "src/core/lib/surface/completion_queue.h" +#include "src/core/lib/surface/init.h" +#include "src/core/lib/surface/lame_client.h" +#include "src/core/lib/surface/server.h" +#include "src/core/lib/transport/bdp_estimator.h" +#include "src/core/lib/transport/connectivity_state.h" +#include "src/core/lib/transport/transport_impl.h" + +/* (generated) built in registry of plugins */ +extern void grpc_register_built_in_plugins(void); + +#define MAX_PLUGINS 128 + +static gpr_once g_basic_init = GPR_ONCE_INIT; +static gpr_mu g_init_mu; +static int g_initializations; + +static void do_basic_init(void) { + gpr_log_verbosity_init(); + gpr_mu_init(&g_init_mu); + grpc_register_built_in_plugins(); + g_initializations = 0; +} + +static bool append_filter(grpc_exec_ctx *exec_ctx, + grpc_channel_stack_builder *builder, void *arg) { + return grpc_channel_stack_builder_append_filter( + builder, (const grpc_channel_filter *)arg, NULL, NULL); +} + +static bool prepend_filter(grpc_exec_ctx *exec_ctx, + grpc_channel_stack_builder *builder, void *arg) { + return grpc_channel_stack_builder_prepend_filter( + builder, (const grpc_channel_filter *)arg, NULL, NULL); +} + +static void register_builtin_channel_init() { + grpc_channel_init_register_stage(GRPC_CLIENT_SUBCHANNEL, + GRPC_CHANNEL_INIT_BUILTIN_PRIORITY, + grpc_add_connected_filter, NULL); + grpc_channel_init_register_stage(GRPC_CLIENT_DIRECT_CHANNEL, + GRPC_CHANNEL_INIT_BUILTIN_PRIORITY, + grpc_add_connected_filter, NULL); + grpc_channel_init_register_stage(GRPC_SERVER_CHANNEL, + GRPC_CHANNEL_INIT_BUILTIN_PRIORITY, + grpc_add_connected_filter, NULL); + grpc_channel_init_register_stage(GRPC_CLIENT_LAME_CHANNEL, + GRPC_CHANNEL_INIT_BUILTIN_PRIORITY, + append_filter, (void *)&grpc_lame_filter); + grpc_channel_init_register_stage(GRPC_SERVER_CHANNEL, INT_MAX, prepend_filter, + (void *)&grpc_server_top_filter); +} + +typedef struct grpc_plugin { + void (*init)(); + void (*destroy)(); +} grpc_plugin; + +static grpc_plugin g_all_of_the_plugins[MAX_PLUGINS]; +static int g_number_of_plugins = 0; + +void grpc_register_plugin(void (*init)(void), void (*destroy)(void)) { + GRPC_API_TRACE("grpc_register_plugin(init=%p, destroy=%p)", 2, + ((void *)(intptr_t)init, (void *)(intptr_t)destroy)); + GPR_ASSERT(g_number_of_plugins != MAX_PLUGINS); + g_all_of_the_plugins[g_number_of_plugins].init = init; + g_all_of_the_plugins[g_number_of_plugins].destroy = destroy; + g_number_of_plugins++; +} + +void grpc_init(void) { + int i; + gpr_once_init(&g_basic_init, do_basic_init); + + grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT; + gpr_mu_lock(&g_init_mu); + if (++g_initializations == 1) { + gpr_time_init(); + grpc_stats_init(); + grpc_slice_intern_init(); + grpc_mdctx_global_init(); + grpc_channel_init_init(); + grpc_register_tracer(&grpc_api_trace); + grpc_register_tracer(&grpc_trace_channel); + grpc_register_tracer(&grpc_connectivity_state_trace); + grpc_register_tracer(&grpc_trace_channel_stack_builder); + grpc_register_tracer(&grpc_http1_trace); + grpc_register_tracer(&grpc_cq_pluck_trace); // default on + grpc_register_tracer(&grpc_call_combiner_trace); + grpc_register_tracer(&grpc_combiner_trace); + grpc_register_tracer(&grpc_server_channel_trace); + grpc_register_tracer(&grpc_bdp_estimator_trace); + grpc_register_tracer(&grpc_cq_event_timeout_trace); // default on + grpc_register_tracer(&grpc_trace_operation_failures); + grpc_register_tracer(&grpc_resource_quota_trace); + grpc_register_tracer(&grpc_call_error_trace); +#ifndef NDEBUG + grpc_register_tracer(&grpc_trace_pending_tags); + grpc_register_tracer(&grpc_trace_alarm_refcount); + grpc_register_tracer(&grpc_trace_cq_refcount); + grpc_register_tracer(&grpc_trace_closure); + grpc_register_tracer(&grpc_trace_error_refcount); + grpc_register_tracer(&grpc_trace_stream_refcount); + grpc_register_tracer(&grpc_trace_fd_refcount); + grpc_register_tracer(&grpc_trace_metadata); +#endif + grpc_security_pre_init(); + grpc_iomgr_init(&exec_ctx); + gpr_timers_global_init(); + grpc_handshaker_factory_registry_init(); + grpc_security_init(); + for (i = 0; i < g_number_of_plugins; i++) { + if (g_all_of_the_plugins[i].init != NULL) { + g_all_of_the_plugins[i].init(); + } + } + /* register channel finalization AFTER all plugins, to ensure that it's run + * at the appropriate time */ + grpc_register_security_filters(); + register_builtin_channel_init(); + grpc_tracer_init("GRPC_TRACE"); + /* no more changes to channel init pipelines */ + grpc_channel_init_finalize(); + grpc_iomgr_start(&exec_ctx); + } + gpr_mu_unlock(&g_init_mu); + grpc_exec_ctx_finish(&exec_ctx); + GRPC_API_TRACE("grpc_init(void)", 0, ()); +} + +void grpc_shutdown(void) { + int i; + GRPC_API_TRACE("grpc_shutdown(void)", 0, ()); + grpc_exec_ctx exec_ctx = + GRPC_EXEC_CTX_INITIALIZER(0, grpc_never_ready_to_finish, NULL); + gpr_mu_lock(&g_init_mu); + if (--g_initializations == 0) { + grpc_executor_shutdown(&exec_ctx); + grpc_timer_manager_set_threading(false); // shutdown timer_manager thread + for (i = g_number_of_plugins; i >= 0; i--) { + if (g_all_of_the_plugins[i].destroy != NULL) { + g_all_of_the_plugins[i].destroy(); + } + } + grpc_iomgr_shutdown(&exec_ctx); + gpr_timers_global_destroy(); + grpc_tracer_shutdown(); + grpc_mdctx_global_shutdown(&exec_ctx); + grpc_handshaker_factory_registry_shutdown(&exec_ctx); + grpc_slice_intern_shutdown(); + grpc_stats_shutdown(); + } + gpr_mu_unlock(&g_init_mu); + grpc_exec_ctx_finish(&exec_ctx); +} + +int grpc_is_initialized(void) { + int r; + gpr_once_init(&g_basic_init, do_basic_init); + gpr_mu_lock(&g_init_mu); + r = g_initializations > 0; + gpr_mu_unlock(&g_init_mu); + return r; +} |