日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

ACE_Service_Handler类的理解和使用

發(fā)布時(shí)間:2025/3/21 编程问答 29 豆豆
生活随笔 收集整理的這篇文章主要介紹了 ACE_Service_Handler类的理解和使用 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
CE_Service_Handler和ACE_Svc_Handler是類似的,不同的是使用在proactor中。
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顯然脫不了干系。

00360 ACE_Proactor * 00361 ACE_Proactor::instance (size_t /* threads */) 00362 { 00363 ACE_TRACE ("ACE_Proactor::instance"); 00364 00365 if (ACE_Proactor::proactor_ == 0) 00366 { 00367 // Perform Double-Checked Locking Optimization. 00368 ACE_MT (ACE_GUARD_RETURN (ACE_Recursive_Thread_Mutex, ace_mon, 00369 *ACE_Static_Object_Lock::instance (), 00370 0)); 00371 00372 if (ACE_Proactor::proactor_ == 0) 00373 { 00374 ACE_NEW_RETURN (ACE_Proactor::proactor_, 00375 ACE_Proactor, 00376 0); 00377 00378 ACE_Proactor::delete_proactor_ = 1; 00379 ACE_REGISTER_FRAMEWORK_COMPONENT(ACE_Proactor, ACE_Proactor::proactor_); 00380 } 00381 } 00382 return ACE_Proactor::proactor_;
  • 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)中,

00077 template <class HANDLER> void 00078 ACE_Asynch_Connector<HANDLER>::handle_connect (const ACE_Asynch_Connect::Result &result) 00079 { 00080 // Variable for error tracking 00081 int error = 0; 00082 00083 // If the asynchronous connect fails. 00084 if (!result.success () || 00085 result.connect_handle () == ACE_INVALID_HANDLE) 00086 { 00087 error = 1; 00088 } 00089 00090 if (result.error () != 0) 00091 { 00092 error = 1; 00093 } 00094 00095 // set blocking mode 00096 if (!error && 00097 ACE::clr_flags 00098 (result.connect_handle (), ACE_NONBLOCK) != 0) 00099 { 00100 error = 1; 00101 ACE_ERROR ((LM_ERROR, 00102 ACE_LIB_TEXT ("%p\n"), 00103 ACE_LIB_TEXT ("ACE_Asynch_Connector::handle_connect : Set blocking mode"))); 00104 } 00105 00106 // Parse the addresses. 00107 ACE_INET_Addr local_address; 00108 ACE_INET_Addr remote_address; 00109 if (!error && 00110 (this->validate_new_connection_ || this->pass_addresses_)) 00111 this->parse_address (result, 00112 remote_address, 00113 local_address); 00114 00115 // Call validate_connection even if there was an error - it's the only 00116 // way the application can learn the connect disposition. 00117 if (this->validate_new_connection_ && 00118 this->validate_connection (result, remote_address, local_address) == -1) 00119 { 00120 error = 1; 00121 } 00122 00123 HANDLER *new_handler = 0; 00124 if (!error) 00125 { 00126 // The Template method 00127 new_handler = this->make_handler (); 00128 if (new_handler == 0) 00129 { 00130 error = 1; 00131 ACE_ERROR ((LM_ERROR, 00132 ACE_LIB_TEXT ("%p\n"), 00133 ACE_LIB_TEXT ("ACE_Asynch_Connector::handle_connect : Making of new handler failed"))); 00134 } 00135 } 00136 00137 // If no errors 00138 if (!error) 00139 { 00140 // Update the Proactor. 00141 new_handler->proactor (this->proactor ()); 00142 00143 // Pass the addresses 00144 if (this->pass_addresses_) 00145 new_handler->addresses (remote_address, 00146 local_address); 00147 00148 // Pass the ACT 00149 if (result.act () != 0) 00150 new_handler->act (result.act ()); 00151 00152 // Set up the handler's new handle value 00153 new_handler->handle (result.connect_handle ()); 00154 00155 ACE_Message_Block mb; 00156 00157 // Initiate the handler with empty message block; 00158 new_handler->open (result.connect_handle (), mb); 00159 } 00160 00161 // On failure, no choice but to close the socket 00162 if (error && 00163 result.connect_handle() != ACE_INVALID_HANDLE) 00164 ACE_OS::closesocket (result.connect_handle ()); 00165 }
  • 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)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。

主站蜘蛛池模板: 一区二区三区精品 | 伊人久久狼人 | 一区二区欧美在线观看 | 日本黄色动态图 | 国产理论 | 亚洲一区二区三区四区在线 | 初尝人妻少妇中文字幕 | 成人毛片在线视频 | 欧美韩国日本一区 | 日韩喷潮| 欧洲一区二区 | 香蕉av在线 | 午夜激情在线观看视频 | 老牛影视av一区二区在线观看 | 亚洲日本激情 | 成年人在线免费观看视频网站 | 婷婷激情五月综合 | 女性向av免费网站 | 国产丝袜一区二区三区 | h片在线播放 | 午夜色网 | 香蕉一区二区三区四区 | 色噜噜亚洲 | 夜夜撸网站 | 国产一区二区三区亚洲 | 久久国产免费视频 | 大胸奶汁乳流奶水出来h | 草视频在线观看 | va视频在线观看 | 五十路毛片 | 一区二区三区视频网站 | 玖玖在线视频 | av免费看网址 | 在线看黄网址 | 免费观看h片 | 337p日本大胆噜噜噜鲁 | 国产成人精品在线视频 | 91色伦| 久青草视频在线 | 在线免费看黄网站 | 老熟女重囗味hdxx69 | 国产91传媒| 国产乱码久久久久久 | 国产精品资源在线观看 | 日韩精品一区二区三区高清免费 | 色乱码一区二区三区熟女 | 88国产精品视频一区二区三区 | 五月激情婷婷综合 | 超碰人人超碰 | 亚洲天堂av影院 | 日韩欧美国产激情 | 91久久精品一区二区别 | 亚洲一区二区国产 | 美女被变态侵犯 | 精品一区二区三区视频在线观看 | 一二三四区视频 | 男人的天堂99 | 日韩av免费看 | wwwsss在线观看 | 国产成人无码一区二区在线播放 | 国产一区二区在线视频观看 | 日本美女久久 | 美丽的小蜜桃2:美丽人生 | 午夜一区二区三区免费 | 中文字幕乱码在线人视频 | 波多野吉衣一区 | 国产一级片在线播放 | 国产免费内射又粗又爽密桃视频 | 日本中文字幕在线观看视频 | 国产成人精品免高潮费视频 | 五月婷婷综合久久 | 挪威xxxx性hd极品 | 秘密基地电影免费版观看国语 | 91免费国产在线观看 | 亚洲欧美一二三区 | 国产精品久久久久久免费免熟 | 五月婷婷丁香综合 | av日韩在线免费观看 | 成人午夜视频在线播放 | 欧美成人免费网站 | 久久午夜夜伦鲁鲁片无码免费 | 免费级毛片 | 爱爱综合| 天天干少妇 | 欧美毛片免费看 | 韩国成人免费视频 | av一级在线观看 | 99人妻少妇精品视频一区 | 亚洲色成人www永久在线观看 | 131mm少妇做爰视频 | 欧美123区| 欧美少妇色图 | 国产crm系统91在线 | 色一情一区二区三区四区 | 国产精品xxx在线 | 国产伦精品一区二区三区视频痴汉 | 一区二区三区欧美 | 亚洲在线综合 | 日韩中文字幕不卡 |