天天看點

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 等回調來完成。(負責實作回調)

繼續閱讀