ACE_Service_Handler类的理解和使用

ACE_Service_Handler和ACE_Svc_Handler是类似的,不同的是使用在proactor中。
ACE_Service_Handler类从代码的接口中直接可以看到很多相关的回调,例如
handle_write_stream ,那么它们是什么时候被调的呢?看下代码:

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 }

在上述的393行,而这里的complete的调用位置是:

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 

但是看过这个函数的调用之后,会发现无论是在windows还是posix的实现中,这个函数都再handel_events中被调用。而且这里在ACE_Proactor中,run_event_loop都是空实现,其handle_events是在proactor_run_event_loop函数中被调用的,这点尤其需要注意。

另外的一个问题是,ACE_Asynch_Connector/Acceptor《handler》这些实际处理事件的模板类,是如何将handler和proactor联系起来的?
1.先看看ACE_Proactor是何时产生的。
通过堆栈查看到,ACE_Asynch_Connector的open函数会调用其私有成员变量ACE_Asynch_Connect类型的asynch_connect_的open函数,在这个函数中会调用get_proactor接口为user获取一个proactor,ACE_Proactor的第一个实例就在这里实例化了,至于为什么ACE_Proactor的实例会是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_;

2.proactor如何和Handler绑定在一起的。需要明白的是Handler本身是有有一个proactor类型的指针专门用于保存绑定的proactor的,所以关键就是这个指针是何时填充赋值的。
在ACE_Asynch_Connector的handle_connect回调中,

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 }

开始使用HANDLER 类型,而实际的处理器回调函数都是在HANDLER 类型中的。这里的make_handler默认实现实际也只是调用了ACE_NEW_RETURN宏,该宏只是简单的new了一个HANDLER 类型的处理器,调用了其构造函数而已。
再来看第141行,这一行很明显是将新构造的HANDLER 类型的处理器handler的和当前的proactor挂接起来。

3.那么handler的handle是如何注册到proactor中去的呢?
如果没有注册动作,显然proactor是没法检测到事件。这点需要我们手动去完成,
再上述代码的158行,说明了handler需要实现open接口,而在open接口中,有必要将ACE_Aysnch_Read_Stream和ACE_Aysnch_Write_Stream类型的对象作为handler的成员变量,并且在handler的这个open中打开即调用open。为甚?
因为ACE_Aysnch_Read/Write_Stream的open接口中,实际是调用了其基类的open即ACE_Asynch_Operation::open,其实现是调用implementation的open,将handler,handle和proactor真正的绑定,比如ACE_WIN32_Aysnch_Operation的open,就会调用ACE_WIN32_Proactor的register_handle接口,将handle注册到监听中。
换句话说,158行的代码中的handle即我们需要实际检测的handle,而其处理的handler就是调用open的handler。不过处理登记handle上的数据操作完成和实际数据处理,依赖于ACE_Message_Block ,且登记数据操作和处理数据实际上是由ACE_Aysnch_Read/Write_Stream来完成的,处理完成后的则是handler的回调。
所以这里有几个步骤:

  • 建立连接,获取handle,这是Connector的handle_connect完成的
  • 将handle加入proactor的检测队列,并将ACE_Message_Block和其绑定,用于数据处理,这是由ACE_Aysnch_Read/Write_Stream的open及相关接口完成(需要我们负责手动去完成他们的绑定即调open接口(在handler的open接口中))
  • 获取handle上处理完成,并将最终结果的ACE_Message_Block通知并进行通知处理,则是由Handler中的virtual void handle_read_stream 等回调来完成。(负责实现回调)
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值