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额外开辟的空间
再来看第二句
<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_的结构