前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >GRPC-C++源码分析(五)--ServerCompletionQueue续

GRPC-C++源码分析(五)--ServerCompletionQueue续

原创
作者头像
路小饭
修改2019-04-22 14:24:35
1.7K0
修改2019-04-22 14:24:35
举报

2.1.2 grpc_determine_iomgr_platform

看下调用逻辑:

代码语言:txt
复制
//iomgr_internal.cc
void grpc_determine_iomgr_platform() {
  if (iomgr_platform_vtable == nullptr) {
    grpc_set_default_iomgr_platform();
  }
}

grpc_set_default_iomgr_platform的实现:

代码语言:txt
复制
//iomgr_posix.cc
void grpc_set_default_iomgr_platform() {
  grpc_set_tcp_client_impl(&grpc_posix_tcp_client_vtable);
  grpc_set_tcp_server_impl(&grpc_posix_tcp_server_vtable);
  grpc_set_timer_impl(&grpc_generic_timer_vtable);
  grpc_set_pollset_vtable(&grpc_posix_pollset_vtable);
  grpc_set_pollset_set_vtable(&grpc_posix_pollset_set_vtable);
  grpc_set_resolver_impl(&grpc_posix_resolver_vtable);
  grpc_set_iomgr_platform_vtable(&vtable);
}
  • 先关注grpc_set_iomgr_platform_vtable,从名字上就能看出set了一个叫&vtable的东西
  • 关注它的原因是接下来的grpc_iomgr_platform_init方法马上就会用到
  • 其他的grpc_set_方法也同样很重要,会在后面看到它们的用处

2.1.3 grpc_iomgr_platform_init

代码语言:txt
复制
void grpc_iomgr_platform_init() { iomgr_platform_vtable->init(); }
  • 关注点:iomgr_platform_vtable,而这个iomgr_platform_vtable就是由2.1.2节中的grpc_set_iomgr_platform_vtable方法赋值的
  • 线索转移到了iomgr_platform_vtable->init()

2.1.4 grpc_iomgr_platform_init----iomgr_platform_vtable->init

iomgr_platform_vtable定义在:

代码语言:txt
复制
static grpc_iomgr_platform_vtable vtable = {
    iomgr_platform_init, iomgr_platform_flush, iomgr_platform_shutdown,
    iomgr_platform_shutdown_background_closure,
    iomgr_platform_is_any_background_poller_thread};
  • iomgr_platform_vtable->init调用的是iomgr_platform_init方法,下面给出了调用路径
  • 上图明确了grpc_iomgr_platform_init方法的终极意义在于赋值给全局变量grpc_event_engine_vtable* g_event_engine
代码语言:txt
复制
//ev_posix.cc
static const grpc_event_engine_vtable* g_event_engine = nullptr;
  • try_engine调用了g_factoriesi.factory的方法,返回值赋给了grpc_event_engine_vtable* g_event_engine
  • g_factories定义在ev_posix.cc中
代码语言:txt
复制
//ev_posix.cc
static event_engine_factory g_factories[] = {
    {ENGINE_HEAD_CUSTOM, nullptr},        {ENGINE_HEAD_CUSTOM, nullptr},
    {ENGINE_HEAD_CUSTOM, nullptr},        {ENGINE_HEAD_CUSTOM, nullptr},
    {"epollex", grpc_init_epollex_linux}, {"epoll1", grpc_init_epoll1_linux},
    {"poll", grpc_init_poll_posix},       {"none", init_non_polling},
    {ENGINE_TAIL_CUSTOM, nullptr},        {ENGINE_TAIL_CUSTOM, nullptr},
    {ENGINE_TAIL_CUSTOM, nullptr},        {ENGINE_TAIL_CUSTOM, nullptr},
};
  • 具体选取那个factory是GRPC_POLL_STRATEGY环境变量决定的,它是在grpc_event_engine_init中获取的
代码语言:txt
复制
//ev_posix.cc
  void grpc_event_engine_init(void) {
  char* s = gpr_getenv("GRPC_POLL_STRATEGY");
  if (s == nullptr) {
    s = gpr_strdup("all");
  }
  • 在我的centos7.5上,默认选取的g_factories是:"epollex", grpc_init_epollex_linux
  • grpc_init_epollex_linux方法中return了一个vtable
代码语言:txt
复制
//ev_epollex_linux.cc
const grpc_event_engine_vtable* grpc_init_epollex_linux(
    bool explicitly_requested) {
………………
  return &vtable;
}
  • 一起看下这个vtable的定义
代码语言:txt
复制
//ev_epollex_linux.cc
static const grpc_event_engine_vtable vtable = {
    sizeof(grpc_pollset),
    true,
    false,

    fd_create,
    fd_wrapped_fd,
    fd_orphan,
    fd_shutdown,
    fd_notify_on_read,
    fd_notify_on_write,
    fd_notify_on_error,
    fd_become_readable,
    fd_become_writable,
    fd_has_errors,
    fd_is_shutdown,

    pollset_init,
    pollset_shutdown,
    pollset_destroy,
    pollset_work,
    pollset_kick,
    pollset_add_fd,

    pollset_set_create,
    pollset_set_unref,  // destroy ==> unref 1 public ref
    pollset_set_add_pollset,
    pollset_set_del_pollset,
    pollset_set_add_pollset_set,
    pollset_set_del_pollset_set,
    pollset_set_add_fd,
    pollset_set_del_fd,

    is_any_background_poller_thread,
    shutdown_background_closure,
    shutdown_engine,
};

如果整个2.1节都没理解也没关系,记住我们有了一个grpc_event_engine_vtable* g_event_engine指针就可以了,这个指针的内容就是上面的static const grpc_event_engine_vtable vtable

2.2 grpc::g_core_codegen_interface

把思路回到第二节开头,不仅g_glip在GrpcLibraryInitializer 中完成了初始化,还有一个全局变量grpc::g_core_codegen_interface也在其中完成了初始化,它会在CompletionQueue的构造函数中用到,再贴一次代码:

代码语言:txt
复制
//grpc_library.h
 class GrpcLibraryInitializer final {
 public:
  GrpcLibraryInitializer() {
    if (grpc::g_glip == nullptr) {
      static auto* const g_gli = new GrpcLibrary();
      grpc::g_glip = g_gli;
    }
    if (grpc::g_core_codegen_interface == nullptr) {
      static auto* const g_core_codegen = new CoreCodegen();
      grpc::g_core_codegen_interface = g_core_codegen;
    }
  }

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 2.1.2 grpc_determine_iomgr_platform
  • 2.1.3 grpc_iomgr_platform_init
  • 2.1.4 grpc_iomgr_platform_init----iomgr_platform_vtable->init
  • 2.2 grpc::g_core_codegen_interface
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档