调试C++NPv2_Select_Reactor_Log_Server程序
调试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中。
函数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函数。
模板类函数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。
模板类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_;。
类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函数。
再回到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_;串起来。
当调用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.)。