ACE_Service_Handler类的理解和使用
ACE_Service_Handler類從代碼的接口中直接可以看到很多相關(guān)的回調(diào),例如
handle_write_stream ,那么它們是什么時(shí)候被調(diào)的呢?看下代碼: 00369 void 00370 ACE_POSIX_Asynch_Write_Stream_Result::complete (size_t bytes_transferred, 00371 int success, 00372 const void *completion_key, 00373 u_long error) 00374 { 00375 // Get all the data copied. 00376 this->bytes_transferred_ = bytes_transferred; 00377 this->success_ = success; 00378 this->completion_key_ = completion_key; 00379 this->error_ = error; 00380 00381 // <errno> is available in the aiocb. 00382 ACE_UNUSED_ARG (error); 00383 00384 // Appropriately move the pointers in the message block. 00385 this->message_block_.rd_ptr (bytes_transferred); 00386 00387 // Create the interface result class. 00388 ACE_Asynch_Write_Stream::Result result (this); 00389 00390 // Call the application handler. 00391 ACE_Handler *handler = this->handler_proxy_.get ()->handler (); 00392 if (handler != 0) 00393 handler->handle_write_stream (result); 00394 }
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
在上述的393行,而這里的complete的調(diào)用位置是:
00556 void 00557 ACE_POSIX_Proactor::application_specific_code (ACE_POSIX_Asynch_Result *asynch_result, 00558 size_t bytes_transferred, 00559 const void */* completion_key*/, 00560 u_long error) 00561 { 00562 ACE_SEH_TRY 00563 { 00564 // Call completion hook 00565 asynch_result->complete (bytes_transferred, 00566 error ? 0 : 1, 00567 0, // No completion key. 00568 error); 00569 } 00570 ACE_SEH_FINALLY 00571 { 00572 // This is crucial to prevent memory leaks 00573 delete asynch_result; 00574 } 00575 } 00576- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
但是看過這個(gè)函數(shù)的調(diào)用之后,會(huì)發(fā)現(xiàn)無(wú)論是在windows還是posix的實(shí)現(xiàn)中,這個(gè)函數(shù)都再handel_events中被調(diào)用。而且這里在ACE_Proactor中,run_event_loop都是空實(shí)現(xiàn),其handle_events是在proactor_run_event_loop函數(shù)中被調(diào)用的,這點(diǎn)尤其需要注意。
另外的一個(gè)問題是,ACE_Asynch_Connector/Acceptor《handler》這些實(shí)際處理事件的模板類,是如何將handler和proactor聯(lián)系起來(lái)的?
1.先看看ACE_Proactor是何時(shí)產(chǎn)生的。
通過堆棧查看到,ACE_Asynch_Connector的open函數(shù)會(huì)調(diào)用其私有成員變量ACE_Asynch_Connect類型的asynch_connect_的open函數(shù),在這個(gè)函數(shù)中會(huì)調(diào)用get_proactor接口為user獲取一個(gè)proactor,ACE_Proactor的第一個(gè)實(shí)例就在這里實(shí)例化了,至于為什么ACE_Proactor的實(shí)例會(huì)是ACE_POSIX_AIOCB_Proactor,和這里的ACE_REGISTER_FRAMEWORK_COMPONENT顯然脫不了干系。
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
2.proactor如何和Handler綁定在一起的。需要明白的是Handler本身是有有一個(gè)proactor類型的指針專門用于保存綁定的proactor的,所以關(guān)鍵就是這個(gè)指針是何時(shí)填充賦值的。
在ACE_Asynch_Connector的handle_connect回調(diào)中,
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
- 68
- 69
- 70
- 71
- 72
- 73
- 74
- 75
- 76
- 77
- 78
- 79
- 80
- 81
- 82
- 83
- 84
- 85
- 86
- 87
- 88
- 89
開始使用HANDLER 類型,而實(shí)際的處理器回調(diào)函數(shù)都是在HANDLER 類型中的。這里的make_handler默認(rèn)實(shí)現(xiàn)實(shí)際也只是調(diào)用了ACE_NEW_RETURN宏,該宏只是簡(jiǎn)單的new了一個(gè)HANDLER 類型的處理器,調(diào)用了其構(gòu)造函數(shù)而已。
再來(lái)看第141行,這一行很明顯是將新構(gòu)造的HANDLER 類型的處理器handler的和當(dāng)前的proactor掛接起來(lái)。
3.那么handler的handle是如何注冊(cè)到proactor中去的呢?
如果沒有注冊(cè)動(dòng)作,顯然proactor是沒法檢測(cè)到事件。這點(diǎn)需要我們手動(dòng)去完成,
再上述代碼的158行,說(shuō)明了handler需要實(shí)現(xiàn)open接口,而在open接口中,有必要將ACE_Aysnch_Read_Stream和ACE_Aysnch_Write_Stream類型的對(duì)象作為handler的成員變量,并且在handler的這個(gè)open中打開即調(diào)用open。為甚?
因?yàn)锳CE_Aysnch_Read/Write_Stream的open接口中,實(shí)際是調(diào)用了其基類的open即ACE_Asynch_Operation::open,其實(shí)現(xiàn)是調(diào)用implementation的open,將handler,handle和proactor真正的綁定,比如ACE_WIN32_Aysnch_Operation的open,就會(huì)調(diào)用ACE_WIN32_Proactor的register_handle接口,將handle注冊(cè)到監(jiān)聽中。
換句話說(shuō),158行的代碼中的handle即我們需要實(shí)際檢測(cè)的handle,而其處理的handler就是調(diào)用open的handler。不過處理登記handle上的數(shù)據(jù)操作完成和實(shí)際數(shù)據(jù)處理,依賴于ACE_Message_Block ,且登記數(shù)據(jù)操作和處理數(shù)據(jù)實(shí)際上是由ACE_Aysnch_Read/Write_Stream來(lái)完成的,處理完成后的則是handler的回調(diào)。
所以這里有幾個(gè)步驟:
- 建立連接,獲取handle,這是Connector的handle_connect完成的
- 將handle加入proactor的檢測(cè)隊(duì)列,并將ACE_Message_Block和其綁定,用于數(shù)據(jù)處理,這是由ACE_Aysnch_Read/Write_Stream的open及相關(guān)接口完成(需要我們負(fù)責(zé)手動(dòng)去完成他們的綁定即調(diào)open接口(在handler的open接口中))
- 獲取handle上處理完成,并將最終結(jié)果的ACE_Message_Block通知并進(jìn)行通知處理,則是由Handler中的virtual void handle_read_stream 等回調(diào)來(lái)完成。(負(fù)責(zé)實(shí)現(xiàn)回調(diào))
總結(jié)
以上是生活随笔為你收集整理的ACE_Service_Handler类的理解和使用的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 魅族C++协程框架(Kiev)技术内幕
- 下一篇: ACE框架解读 - 源码篇