ATS代碼分析概述

ats代碼有幾十萬行之多,與請求流程相關的代碼主要集中在HttpSM.cc中。文件中包含了三個重要的函數:HttpSM::handle_api_return和HttpSM::set_next_state和HttpSM::call_transact_and_set_next_state,前面兩個函數配合實現了狀態機的運轉,第三個函數是大多數狀態要做的事情,並且間接決定了下一個state是什麼。

HttpSM::handle_api_return函數是狀態機的入口,是一個巨大的switch,每個case是一個state,大多數state最終都會執行到HttpSM::call_transact_and_set_next_state。

這個函數就像其名字一樣,做了兩件事請:call和set_next_state,call了一個請求在相應state下的處理函數。分兩種可能,如果這個函數帶了一個參數,參數就是一個函數,就執行這個函數,如果沒有帶參數,就執行在其他地方設置好的函數。call操作執行的函數一般最後會執行TRANSACT_RETURN函數,這個函數有兩個參數,第一個參數是一個state,被賦值於HttpSM::next_action,用於HttpSM::set_next_state中的switch判斷,第二個參數是一個函數,被用於下一個state執行是call的函數,也就是說下一次HttpSM::call_transact_and_set_next_state函數的時候如果沒有帶參數,就會執行上個state的TRANSACT_RETURN函數中第二個參數指向的函數。

根據處理函數的執行情況來執行set_next_state函數,set_next_state函數決定下一個state是什麼,可能會直接執行下一個state的HttpSM::call_transact_and_set_next_state也可能回到HttpSM::handle_api_return。

請求第一次進入到HttpSM::handle_api_return時的堆棧信息如下:


Breakpoint 1, HttpSM::handle_api_return (this=0x2ae89f600000) at HttpSM.cc:1580

1580      switch (t_state.api_next_action) {

(gdb) bt

#0  HttpSM::handle_api_return (this=0x2ae89f600000) at HttpSM.cc:1580

#1  0x0000000000596b54 in HttpSM::state_api_callout (this=0x2ae89f600000, event=0, data=0x0) at HttpSM.cc:1541

#2  0x00000000005a23cd in HttpSM::do_api_callout_internal (this=0x2ae89f600000) at HttpSM.cc:4750

#3  0x00000000005afba0 in HttpSM::do_api_callout (this=0x2ae89f600000) at HttpSM.cc:571

#4  0x00000000005936b4 in HttpSM::state_add_to_list (this=0x2ae89f600000, event=0, data=0x0) at HttpSM.cc:599

#5  0x0000000000593d23 in HttpSM::attach_client_session (this=0x2ae89f600000, client_vc=0x2ae89dbe0000, buffer_reader=0x2ae89dbc4018) at HttpSM.cc:705

#6  0x00000000005826f9 in HttpClientSession::new_transaction (this=0x2ae89dbe0000) at HttpClientSession.cc:164

#7  0x0000000000583db3 in HttpClientSession::handle_api_return (this=0x2ae89dbe0000, event=0) at HttpClientSession.cc:535

#8  0x0000000000583cf5 in HttpClientSession::state_api_callout (this=0x2ae89dbe0000, event=0, data=0x0) at HttpClientSession.cc:511

#9  0x00000000005849d6 in HttpClientSession::do_api_callout (this=0x2ae89dbe0000, id=TS_HTTP_SSN_START_HOOK) at HttpClientSession.cc:178

#10 0x0000000000582ab5 in HttpClientSession::new_connection (this=0x2ae89dbe0000, new_vc=0x2ae897f60000, backdoor=false) at HttpClientSession.cc:244

#11 0x000000000057d95b in HttpAcceptCont::mainEvent (this=0x2e8d060, event=202, data=0x2ae897f60000) at HttpAcceptCont.cc:72

#12 0x0000000000508bf8 in Continuation::handleEvent (this=0x2e8d060, event=202, data=0x2ae897f60000) at ../iocore/eventsystem/I_Continuation.h:146

#13 0x0000000000726af2 in ProtocolAcceptCont::mainEvent (this=0x2e8d140, event=202, netvc=0x2ae897f60000) at ProtocolAcceptCont.cc:49

#14 0x0000000000508bf8 in Continuation::handleEvent (this=0x2e8d140, event=202, data=0x2ae897f60000) at ../iocore/eventsystem/I_Continuation.h:146

#15 0x000000000073bc49 in SpdyProberCont::mainEvent (this=0x2ae89dae0000, event=102, e=0x2ae897f60118) at UnixNetVConnection.cc:101

#16 0x0000000000508bf8 in Continuation::handleEvent (this=0x2ae89dae0000, event=102, data=0x2ae897f60118) at ../iocore/eventsystem/I_Continuation.h:146

#17 0x00000000007375dc in read_signal_and_update (event=102, vc=0x2ae897f60000) at UnixNetVConnection.cc:215

#18 0x000000000073778e in read_signal_done (event=102, nh=0x2ae888cdd2c8, vc=0x2ae897f60000) at UnixNetVConnection.cc:245

#19 0x0000000000737f34 in read_from_net (nh=0x2ae888cdd2c8, vc=0x2ae897f60000, thread=0x2ae888cda010) at UnixNetVConnection.cc:397

#20 0x000000000073a0a3 in UnixNetVConnection::net_read_io (this=0x2ae897f60000, nh=0x2ae888cdd2c8, lthread=0x2ae888cda010) at UnixNetVConnection.cc:944

#21 0x00000000007341f0 in NetHandler::mainNetEvent (this=0x2ae888cdd2c8, event=5, e=0x2ae8899ec5c0) at UnixNet.cc:372

#22 0x0000000000508bf8 in Continuation::handleEvent (this=0x2ae888cdd2c8, event=5, data=0x2ae8899ec5c0) at ../iocore/eventsystem/I_Continuation.h:146

#23 0x0000000000761d88 in EThread::process_event (this=0x2ae888cda010, e=0x2ae8899ec5c0, calling_code=5) at UnixEThread.cc:142

#24 0x000000000076235d in EThread::execute (this=0x2ae888cda010) at UnixEThread.cc:266

#25 0x0000000000760f36 in spawn_thread_internal (a=0x2cdf5a0) at Thread.cc:88

#26 0x0000003ce7207aa1 in start_thread () from /lib64/libpthread.so.0

#27 0x0000003ce6ee893d in clone () from /lib64/libc.so.6


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章