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

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

原创
作者头像
路小饭
修改2019-04-22 17:20:55
2K0
修改2019-04-22 17:20:55
举报

3 CompletionQueue

回到第一节的图:

  • 第2节已经分析了GrpcLibraryCodegen
  • 本节开始分析CompletionQueue

再来看看CompletionQueue的构造方法实现:

代码语言:txt
复制
  CompletionQueue(const grpc_completion_queue_attributes& attributes) {
    cq_ = g_core_codegen_interface->grpc_completion_queue_create(
        g_core_codegen_interface->grpc_completion_queue_factory_lookup(
            &attributes),
        &attributes, NULL);
    InitialAvalanching();  // reserve this for the future shutdown
  }
  • 终极目的是返回一个cq_
  • 先调用g_core_codegen_interface->grpc_completion_queue_factory_lookup返回一个grpc_completion_queue_factory* factory
  • 再调用g_core_codegen_interface->grpc_completion_queue_create返回cq_

3.1 grpc_completion_queue_factory_lookup

2.2节中已经看到g_core_codegen_interface的初始化,grpc_completion_queue_factory_lookup在父类CoreCodegenInterface中是个纯虚函数,具体实现在CoreCodegen类中

代码语言:txt
复制
//core_codegen.h
 class CoreCodegen final : public CoreCodegenInterface {
 private:
  virtual const grpc_completion_queue_factory*
  grpc_completion_queue_factory_lookup(
      const grpc_completion_queue_attributes* attributes) override;
  virtual grpc_completion_queue* grpc_completion_queue_create(
      const grpc_completion_queue_factory* factory,
      const grpc_completion_queue_attributes* attributes,
      void* reserved) override;
  • lookup方法最终返回一个grpc_completion_queue_factory g_default_cq_factory变量

3.2 grpc_completion_queue_create

  • grpc_completion_queue_create中调用了factory->vtable->create,其中factory就是3.1节中grpc_completion_queue_factory_lookup返回的变量g_default_cq_factory
  • 图中看到grpc_completion_queue_create最终调用的是grpc_completion_queue_create_internal方法
代码语言:txt
复制
//completion_queue.cc
grpc_completion_queue* grpc_completion_queue_create_internal(
    grpc_cq_completion_type completion_type, grpc_cq_polling_type polling_type,
    grpc_experimental_completion_queue_functor* shutdown_callback) {
  GPR_TIMER_SCOPE("grpc_completion_queue_create_internal", 0);

//最终返回的的那个cq
  grpc_completion_queue* cq;

  GRPC_API_TRACE(
      "grpc_completion_queue_create_internal(completion_type=%d, "
      "polling_type=%d)",
      2, (completion_type, polling_type));

//这两个vtable是cq的核心内容
  const cq_vtable* vtable = &g_cq_vtable[completion_type];
  const cq_poller_vtable* poller_vtable =
      &g_poller_vtable_by_poller_type[polling_type];

  grpc_core::ExecCtx exec_ctx;
  GRPC_STATS_INC_CQS_CREATED();

//cq的初始化也很魔性,除了本身的大小,还额外预留了vtable->data_size + poller_vtable->size()
  cq = static_cast<grpc_completion_queue*>(
      gpr_zalloc(sizeof(grpc_completion_queue) + vtable->data_size +
                 poller_vtable->size()));

  //赋值给了cq里的变量
  cq->vtable = vtable;
  cq->poller_vtable = poller_vtable;

  /* One for destroy(), one for pollset_shutdown */
  gpr_ref_init(&cq->owning_refs, 2);

  //vtable的初始化
  poller_vtable->init(POLLSET_FROM_CQ(cq), &cq->mu);
  vtable->init(DATA_FROM_CQ(cq), shutdown_callback);

  GRPC_CLOSURE_INIT(&cq->pollset_shutdown_done, on_pollset_shutdown_done, cq,
                    grpc_schedule_on_exec_ctx);
  return cq;
}
  • completion_type和polling_type都是0,,是在1.1 节初始化ServerCompletionQueue时候定义的
  • g_cq_vtable和g_poller_vtable_by_poller_type都定义在completion_queue.cc文件中,很容易定位到
  • 这里需要解释的是cq的初始化和两个vtable的init调用(poller_vtable->init和vtable->init)

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

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

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

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

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 3 CompletionQueue
    • 3.1 grpc_completion_queue_factory_lookup
      • 3.2 grpc_completion_queue_create
      领券
      问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档