天天看点

ACE_Service_Handler类的理解和使用

CE_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_;      
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      
  • 建立连接,获取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 等回调来完成。(负责实现回调)

继续阅读