用ACE的Reactor模式实现网络通讯时,ACE内部用 WSAEventSelect 函数把网络事件与一个事件对象关联起来,目的是为了后面用WaitForMultipleObjects函数统一处理。
下面是ACE 的 ACE_WFMO_Reactor::register_handler_i 函数的代码,里面调用了WSAEventSelect 函数。
int ACE_WFMO_Reactor::register_handler_i (ACE_HANDLE event_handle,ACE_HANDLE io_handle,ACE_Event_Handler *event_handler,ACE_Reactor_Mask new_masks) { // If this is a Winsock 1 system,the underlying event assignment will // not work,so don't try. Winsock 1 must use ACE_Select_Reactor for // reacting to socket activity. #if !defined (ACE_HAS_WINSOCK2) || (ACE_HAS_WINSOCK2 == 0) ACE_UNUSED_ARG (event_handle); ACE_UNUSED_ARG (io_handle); ACE_UNUSED_ARG (event_handler); ACE_UNUSED_ARG (new_masks); ACE_NOTSUP_RETURN (-1); #else // Make sure that the <handle> is valid if (io_handle == ACE_INVALID_HANDLE) io_handle = event_handler->get_handle (); if (this->handler_rep_.invalid_handle (io_handle)) { errno = ERROR_INVALID_HANDLE; return -1; } long new_network_events = 0; bool delete_event = false; auto_ptr <ACE_Auto_Event> event; // Look up the repository to see if the <event_handler> is already // there. ACE_Reactor_Mask old_masks; int found = this->handler_rep_.modify_network_events_i (io_handle,new_masks,old_masks,new_network_events,event_handle,delete_event,ACE_Reactor::ADD_MASK); // Check to see if the user passed us a valid event; If not then we // need to create one if (event_handle == ACE_INVALID_HANDLE) { // Note: don't change this since some C++ compilers have // <auto_ptr>s that don't work properly... auto_ptr<ACE_Auto_Event> tmp (new ACE_Auto_Event); event = tmp; event_handle = event->handle (); delete_event = true; } int result = ::WSAEventSelect ((SOCKET) io_handle,new_network_events); // If we had found the <Event_Handler> there is nothing more to do if (found) return result; else if (result != SOCKET_ERROR && this->handler_rep_.bind_i (1,event_handler,io_handle,delete_event) != -1) { // The <event_handler> was not found in the repository,add to // the repository. if (delete_event) { // Clear out the handle in the ACE_Auto_Event so that when // it is destroyed,the handle isn't closed out from under // the reactor. After setting it,running down the event // (via auto_ptr<> event,above) at function return will // cause an error because it'll try to close an invalid handle. // To avoid that smashing the errno value,save the errno // here,explicitly remove the event so the dtor won't do it // again,then restore errno. ACE_Errno_Guard guard (errno); event->handle (ACE_INVALID_HANDLE); event->remove (); } return 0; } else return -1; #endif /* ACE_HAS_WINSOCK2 || ACE_HAS_WINSOCK2 == 0 */ }原文链接:/react/308131.html