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_vtable
  • grpc_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額外開闢的空間


GRPC-C++源碼分析(五)--ServerCompletionQueue續

  • 可以這樣理解,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>


GRPC-C++源碼分析(五)--ServerCompletionQueue續

  • 沒啥好說的,代碼很清晰

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_的結構


GRPC-C++源碼分析(五)--ServerCompletionQueue續

  • 明確一點,CompletionQueue中得到的cq_已經不是一個“單純”的grpc_completion_queue類型,還包括一個cq_next_data類型和一個grpc_pollset類型
  • 整個第3節,除了獲得一個cq_變量,更重要的是獲得了一個全局變量:grpc_event_engine_vtable* g_event_engine,一起回顧下慣用套路


GRPC-C++源碼分析(五)--ServerCompletionQueue續

  • 黑色箭頭1-3說明了pollset.cc文件中的grpc_pollset_impl指針是如何被賦值的
  • 紅色箭頭1-3說明了外部調用時候,是如何最終轉到g_event_engine變量中的


分享到:


相關文章: