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

3.2.1 cq初始化

<code>cq = static_cast<grpc>(
gpr_zalloc(sizeof(grpc_completion_queue) + vtable->data_size +


poller_vtable->size()));/<grpc>/<code>vtable->data_size为 sizeof(cq_next_data)poller_vtable->size为 grpc_pollset_size

稍微解释下grpc_pollset_size:

<code>size_t grpc_pollset_size(void) { return grpc_pollset_impl->pollset_size(); }/<code>这里的grpc_pollset_impl的值来自2.1.2节 grpc_determine_iomgr_platform中定义的方法grpc_set_pollset_vtablegrpc_pollset_impl->pollset_size()调用的是下面代码中的pollset_size

<code>//ev_posix.cc
grpc_pollset_vtable grpc_posix_pollset_vtable = {
pollset_global_init, pollset_global_shutdown,
pollset_init, pollset_shutdown,
pollset_destroy, pollset_work,
pollset_kick, pollset_size};/<code>蛋疼的是这还不算完事儿,pollset_size也是个方法

<code>static size_t pollset_size(void) { return g_event_engine->pollset_size; }/<code>是不是终于看到了熟悉的面孔:g_event_engine,是的,它就是2.1.4节 grpc_iomgr_platform_init方法后得到的全局变量所以最终 grpc_pollset_size的取值是sizeof(grpc_pollset)

<code>//ev_epollex_linux.cc
static const grpc_event_engine_vtable vtable = {
sizeof(grpc_pollset),//第一个
………………/<code>

3.2.2 vtable的初始化

先来看第一句:

<code>poller_vtable->init(POLLSET_FROM_CQ(cq), &cq->mu);/<code>POLLSET_FROM_CQ本质是个grpc_pollset* pollset,指向的是cq额外开辟的空间


可以这样理解,poller_vtable->init其实是在初始化cq中的grpc_pollset箭头3中又遇到了3.2.1节中老朋友grpc_pollset_impl,所以调用关系参看上图就可以了poller_vtable->init最终调用的是ev_epollex_linux.cc文件中的pollset_init方法

再来看第二句

<code>vtable->init(DATA_FROM_CQ(cq), shutdown_callback);/<code>


没啥好说的,代码很清晰

3.3 小结

还是回到开头CompletionQueue类的构造函数

<code> 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
}/<code>

看下最终得到的grpc_completion_queue* cq_的结构


明确一点,CompletionQueue中得到的cq_已经不是一个“单纯”的grpc_completion_queue类型,还包括一个cq_next_data类型和一个grpc_pollset类型整个第3节,除了获得一个cq_变量,更重要的是获得了一个全局变量:grpc_event_engine_vtable* g_event_engine,一起回顾下惯用套路


黑色箭头1-3说明了pollset.cc文件中的grpc_pollset_impl指针是如何被赋值的红色箭头1-3说明了外部调用时候,是如何最终转到g_event_engine变量中的