調試C++NPv2_Select_Reactor_Log_Server例子,main函數中定義ACE_Select_Reactor select_reactor;變量,在該例子中ACE_Select_Reactor被定義爲ACE_Select_Reactor_T<ACE_Reactor_Token_T<ACE_Token>>。定義該變量會調用模板類的構造函數,構造函數中調用模板類的open函數即ACE_Select_Reactor_T<ACE_Reactor_Token_T<ACE_Token> >::open,進而經過定義在模板類ACE_Select_Reactor_T的父類ACE_Select_Reactor_Impl中的成員變量ACE_Reactor_Notify *notify_handler_;,來調用ACE_Select_Reactor_Notify::open函數,在該函數中分別調用其成員ACE_Pipe notification_pipe_;、ACE_Notification_Queue notification_queue_;的open函數,在該函數的開始將ACE_Select_Reactor_T模板對象賦值給其成員ACE_Select_Reactor_Impl *select_reactor_;,而後經過該成員調用模板類的register_handler函數,在這裏即ACE_Select_Reactor_T<ACE_Reactor_Token_T<ACE_Token> >::register_handler函數,將ACE_Select_Reactor_Notify類的成員ACE_Pipe notification_pipe_;的讀端句柄註冊給模板類的成員ACE_Select_Reactor_Handler_Repository handler_rep_;,該成員定義在父類ACE_Select_Reactor_Impl中。node
函數ACE_Select_Reactor_T<ACE_Reactor_Token_T<ACE_Token> >::register_handler會調用this->register_handler_函數,進而調用ACE_Select_Reactor_Handler_Repository::bind函數,一樣註冊到ACE_Select_Reactor_Handler_Repository的還有監聽套接口,在examples\C++NPv2\Logging_Acceptor.cpp文件的Logging_Acceptor::open函數中調用ACE_Reactor::register_handler函數,進而調用ACE_Select_Reactor_T<ACE_Reactor_Token_T<ACE_Token> >::register_handler函數,最終調用ACE_Select_Reactor_Handler_Repository::bind函數。react
模板類函數ACE_Select_Reactor_T<ACE_SELECT_REACTOR_TOKEN>::handle_events_i調用執行this->wait_for_multiple_events函數,該函數中調用ACE_OS::select函數,用select模型來監測觸發事件。ace\OS_NS_sys_select.inl文件中定義的ACE_OS::select函數的參數包含fd_set *類型,這裏調用以ACE_Handle_Set類型做爲實參,因此須要ACE_Handle_Set類的類型轉換。ace\OS_NS_sys_select.inl文件中定義的ACE_OS::select函數中用到了const timeval *指針,該指針當ACE_OS::select函數的最後一個參數onst ACE_Time_Value *非空時,將該參數轉換爲const timeval *指針。這裏也用到了ACE_Time_Value類的類型轉換,由於參數爲指針,因此先解引用,而後默認執行類的類型轉換函數。 數組
根據以上分析,當main函數調用ACE_Reactor::run_reactor_event_loop函數,進而調用ACE_Select_Reactor_T<ACE_Reactor_Token_T<ACE_Token> >::handle_events函數,最終調用ACE_Select_Reactor_T<ACE_Reactor_Token_T<ACE_Token> >::wait_for_multiple_events函數,該函數中調用ACE_OS::select函數,在該函數中會阻塞在::select系統調用上,等待客戶端的鏈接或者ACE_Select_Reactor_Notify類的成員變量ACE_Pipe notification_pipe_;的讀端,而ACE_Reactor_Notify *notify_handler_;對象則包含在模板類ACE_Select_Reactor_T的基類ACE_Select_Reactor_Impl中,該成員在類ACE_Select_Reactor_Impl中用protected來修飾。當服務端啓動後輸入quit退出則會調用ACE_Reactor::notify函數,該函數又調用ACE_Select_Reactor_T<ACE_Reactor_Token_T<ACE_Token> >::notify函數,進而調用ACE_Select_Reactor_Notify::notify函數,在該函數中經過其成員ACE_Pipe notification_pipe_;的寫端發送數據,這樣前面的event_loop線程調用ACE_OS::select函數就會返回。 函數
函數ACE_Select_Reactor_Notify::handle_input中讀到ACE_Notification_Buffer變量後調用ACE_Select_Reactor_Notify::dispatch_notify函數,進而調用Quit_Handler::handle_exception函數,該函數中調用ACE_Reactor::end_reactor_event_loop函數結束事件循環。 工具
服務端啓動後輸入quit退出,在ACE_Select_Reactor_Notify::notify函數中構造一個ACE_Notification_Buffer buffer變量後,調用ACE_Notification_Queue::push_new_notification函數將其放入通知隊列,而後再調用ACE::send經過管道的寫端發送到管道的讀端。因此在ACE_Select_Reactor_Notify::handle_input函數中先調用ACE_Select_Reactor_Notify::read_notify_pipe函數讀到ACE_Notification_Buffer buffer變量,而後再調用ACE_Select_Reactor_Notify::dispatch_notify函數,該函數中將以前的ACE_Notification_Buffer buffer變量做爲引用參數的實參。而這個函數調用ACE_Notification_Queue::pop_next_notification函數讀出一個ACE_Notification_Buffer變量來對參數賦值,其實這個地方調試發現這兩個ACE_Notification_Buffer buffer變量是同樣的。ACE_Select_Reactor_Notify::dispatch_notify函數的後面會根據ACE_Event_Handler類的枚舉變量來分別處理,此處因爲默認爲EXCEPT_MASK,因此調用執行event_handler->handle_exception函數,此處即Quit_Handler::handle_exception。 oop
模板類ACE_Select_Reactor_T的基類ACE_Select_Reactor_Impl中定義了成員變量ACE_Reactor_Notify *notify_handler_;,模板類的構造函數中調用其open成員方法,該方法中初始化該成員爲繼承自ACE_Reactor_Notify類的ACE_Select_Reactor_Notify類型,該類包含成員變量ACE_Notification_Queue notification_queue_;。ui
類ACE_Notification_Queue包含成員變量Buffer_List notify_queue_;(//Keeps track of all pending notifications.)、Buffer_List free_queue_;(//Keeps track of all free buffers.)及ACE_Unbounded_Queue <ACE_Notification_Queue_Node*> alloc_queue_;,其中聲明類型:typedef ACE_Intrusive_List<ACE_Notification_Queue_Node> Buffer_List;。關於alloc_queue_變量註釋爲「爲了跟蹤已分配的ACE_Notification_Buffer類型數組,經過一次分配多個ACE_Notification_Buffer對象來下降分配成本」。基類ACE_Select_Reactor_T的open方法中調用ACE_Select_Reactor_Notify::open函數,該函數中又調用ACE_Notification_Queue::open函數,該方法調用成員函數allocate_more_buffers函數,該函數中先建立ACE_REACTOR_NOTIFICATION_ARRAY_SIZE(默認爲1024)個ACE_Notification_Queue_Node對象,而後經過其成員變量ACE_Unbounded_Queue <ACE_Notification_Queue_Node*> alloc_queue_;調用ACE_Unbounded_Queue<T>::enqueue_head函數。this
再回到ACE_Notification_Queue::allocate_more_buffers函數,初始化類成員變量ACE_Intrusive_List<ACE_Notification_Queue_Node> free_queue_;。模板類ACE_Intrusive_List包含成員變量 T *head_;(//Head of the list)和T *tail_;(//Tail of the list)。此處將建立的1024個ACE_Notification_Queue_Node對象用模板類ACE_Intrusive_List的成員變量 T *head_;和T *tail_;串起來。spa
當調用ACE_Select_Reactor_Notify::notify函數,該函數會調用ACE_Notification_Queue::push_new_notification函數,該函數先取出空閒隊列的頭,即ACE_Notification_Queue_Node *對象,而後以ACE_Notification_Queue::push_new_notification函數的參數調用ACE_Notification_Queue_Node::set函數,而後經過調用ACE_Intrusive_List<T>::push_back函數,將該ACE_Notification_Queue_Node *對象串接在通知隊列notify_queue_的結尾。線程
當調用ACE_Select_Reactor_Notify::dispatch_notify函數時,先調用ACE_Notification_Queue::pop_next_notification函數取出ACE_Notification_Buffer對象,而後根據這個對象進行相應的處理。ACE_Notification_Queue::pop_next_notification函數經過調用ACE_Intrusive_List<T>::pop_front函數,取出通知隊列notify_queue_的頭部,同時將其增長到空閒隊列free_queue_中。
當調用模板類的方法ACE_Select_Reactor_T<ACE_SELECT_REACTOR_TOKEN>::register_handler,在這裏是ACE_Select_Reactor_T<ACE_Reactor_Token_T<ACE_Token> >::register_handler函數,該函數調用this->register_handler_i,進而調用ACE_Select_Reactor_Handler_Repository::bind函數,該類中定義成員變量map_type event_handlers_;。而map_type類型則在類頭部用typedef關鍵字定義,若是是ACE_WIN32平臺則定義爲模板類ACE_Hash_Map_Manager_Ex的某個實例,不然定義爲ACE_Array_Base<ACE_Event_Handler*>。在ACE_Select_Reactor_Handler_Repository::open函數中若是是ACE_WIN32平臺,調用this->event_handlers_.open函數,不然調用this->event_handlers_.size函數,這個地方一開始想固然,覺得模板類ACE_Hash_Map_Manager_Ex也定義了size函數,後來才明白這個是模板類ACE_Array_Base中定義的函數。
模板類ACE_Select_Reactor_T的構造函數中調用其open成員函數,由於該模板類的基類ACE_Select_Reactor_Impl中定義成員變量ACE_Select_Reactor_Handler_Repository handler_rep_;,因此在該函數中執行this->handler_rep_.open來調用ACE_Select_Reactor_Handler_Repository::open函數,在該函數中執行this->event_handlers_.open即調用ACE_Hash_Map_Manager_Ex<EXT_ID, INT_ID, HASH_KEY, COMPARE_KEYS, ACE_LOCK>::open函數。模板類ACE_Hash_Map_Manager_Ex的這個open方法中根據傳遞的參數1024調用其成員函數create_buckets,這個1024即模板類ACE_Select_Reactor_T的構造函數中指定的ACE_Select_Reactor_T<ACE_SELECT_REACTOR_TOKEN>::DEFAULT_SIZE,即模板類的基類ACE_Select_Reactor_Impl中定義的枚舉變量。
模板類ACE_Hash_Map_Manager_Ex的對象event_handlers_做爲ACE_Select_Reactor_Handler_Repository類的成員變量。文件ace\Hash_Map_Manager_T.cpp中的ACE_Select_Reactor_Handler_Repository::open函數執行了兩次,一次是在類構造函數中被調用,一次是ACE_Select_Reactor_Handler_Repository::open函數中執行(this->event_handlers_.open語句。ACE_Hash_Map_Manager_Ex<EXT_ID, INT_ID, HASH_KEY, COMPARE_KEYS, ACE_LOCK>::open函數首先調用close_i成員函數,而後再調用create_buckets成員函數。調用close_i成員函數的註釋爲(Calling this->close_i () to ensure we release previous allocated memory before allocating new one.)。create_buckets函數首先分配1024個ACE_Hash_Map_Entry大小的空間,模板類ACE_Hash_Map_Manager_Ex的成員變量ACE_Hash_Map_Entry<EXT_ID, INT_ID> *table_;指向這個空間,而後for循環建立ACE_Hash_Map_Entry<EXT_ID, INT_ID>對象,ACE_Hash_Map_Entry模板類包含成員變量ACE_Hash_Map_Entry<EXT_ID, INT_ID> *next_;、ACE_Hash_Map_Entry<EXT_ID, INT_ID> *prev_;此處的構造函數中將這兩個指針賦值爲指向本身。
模板類ACE_Hash_Map_Manager_Ex的close_i函數會先判斷類成員變量ACE_Hash_Map_Entry<EXT_ID, INT_ID> *table_;是否爲空,若是不空則調用成員函數this->unbind_all_i(),該函數中外層for循環遍歷成員變量table_的每個元素,由於每個元素都爲ACE_Hash_Map_Entry對象,而該類包含了指向下一個對象的成員變量ACE_Hash_Map_Entry<EXT_ID, INT_ID> *next_;因此內層for循環進行遍歷刪除。兩層for循環能夠當作是寬度不等的不規則二維數組形式。close_i函數調用完this->unbind_all_i ()(//Remove all the entries.),再for循環遍歷entr析構掉create_buckets函數中建立的entry即入口(//Iterate through the buckets cleaning up the sentinels.)、(//Destroy the dummy entry.)。create_buckets函數中for循環建立ACE_Hash_Map_Entry對象(//初始化hash表中每一個入口爲在頭部帶有做爲哨兵的虛假結點的環形鏈)。
調用ACE_Select_Reactor_T類的register_handler函數,最終調用ACE_Select_Reactor_Handler_Repository::bind函數,該函數調用模板類ACE_Hash_Map_Manager_Ex的bind函數,進而調用其成員函數bind_i,該函數中調用執行this->shared_find,在ACE_Hash_Map_Manager_Ex<EXT_ID, INT_ID, HASH_KEY, COMPARE_KEYS, ACE_LOCK>::shared_find函數中,先調用執行this->hash函數獲取hash值,HASH_KEY hash_key_;做爲模板類的成員變量,註釋爲(//Function object used for hashing keys.)。HASH_KEY是模板類ACE_Hash_Map_Manager_Ex的第三個模板參數,在這裏爲 ACE_Hash<void *>,由註釋可知,hash_key_做爲函數對象,其類型ACE_Hash<void *>必定重載了函數運算符(),具體的函數定義是在ace\Functor.inl文件中,在ace\Functor_T.h文件中聲明模板類ACE_Hash,對該模板的特化聲明在ace\Functor.h文件和ace\Functor_String.h文件中,對應的cpp文件中進行函數實現。
在ace\Time_Value.h頭文件中對ACE_Time_Value類定義了前自增和後自增運算符,在對應的cpp文件中進行實現,實現文件中對前自增進行實現,前自增返回類型爲引用類型,並且是返回本身因此用return *this;來實現;後自增的函數實現中先ACE_Time_Value tv (*this);構造返回值,而後調用前自增的實現,而後return tv;返回。
在ace\Select_Reactor_Base.cpp文件中定義了ACE_Select_Reactor_Handler_Repository_Iterator類的實現,該類包含成員變量map_type event_handlers_;(//Underlying table of event handlers.),map_type爲類內部typedef關鍵字聲明的模板類ACE_Hash_Map_Manager_Ex的某一具體實例化類型。在類ACE_Select_Reactor_Handler_Repository_Iterator的實現中對成員變量event_handlers_的操做可能是調用其begin()和end()函數。模板類ACE_Hash_Map_Manager_Ex的這兩個函數返回ACE_Hash_Map_Iterator_Ex模板類對象,根據名字可知該類相似於標準庫容器的一個迭代器,該類的構造函數中tail參數默認爲0,默認構造的正向迭代器,若是調用ACE_Hash_Map_Manager_Ex模板類的end()函數則傳遞1來構造該對象,表示構造的是反響迭代器。
模板類ACE_Hash_Map_Iterator_Ex繼承自模板類ACE_Hash_Map_Iterator_Base_Ex,在ACE_Hash_Map_Iterator_Ex模板類的構造函數中會判斷若是是返回CE_Hash_Map_Manager_Ex模板類的正向迭代器,即調用CE_Hash_Map_Manager_Ex模板類的begin函數,則會調用this->forward_i函數,該函數繼承自其父模板類,在ACE_Hash_Map_Iterator_Base_Ex<EXT_ID, INT_ID, HASH_KEY, COMPARE_KEYS, ACE_LOCK>::forward_i函數中,會對其成員變量ACE_Hash_Map_Manager_Ex<EXT_ID, INT_ID, HASH_KEY, COMPARE_KEYS, ACE_LOCK> *map_man_;(//Map we are iterating over.)進行操做。主要就是如名字所述往前移動一個位置,該函數的註釋爲(//Move forward by one element in the set.)。