Use ACE Reactor framework programming
High song
The code download according to my understanding, I roughly tell the principles under the Windows platform. The implementation class of the ACE_RAAAAAAAAAAAAAACTOR in the Windows platform is achieved by WaitFormultiObject and WSaEventselect, two functions. The function of WaitFormultiobject is to wait for a set of (64) Handle or all of the operating system activation, the program returns, and the function is used to see the MSDN. The function of WSAEventSelect is to specify an event object Event Object to associate with a socket FD_xxx network event. After the ACE_WMFO_REACTOR object is constructed, we call Run_Event_Loop (), and the multi-channel separation thread of the event will begin.
INTACE_RAAACTOR :: Run_REACTOR_EVENT_LOOP (Reactor_Event_Hook EH) {ACE_TRACE ("ACE_REAAAAACTOR :: Run_Reactor_Event_LOOP");
IF (this-> Reactor_event_loop_done ()) Return 0;
While (1) {int result = this-> meansmentation _-> handle_events (); // loop call implementation class Handle_Events;
IF (EH! = 0 && (* EH) (this)) Continue; Else IF (Result == -1 && this-> Implementation_-> deactivated ()) Return 0; Else IF (Result == -1) Return - 1; }
ACE_NOTREACHED (return 0;)}
Here is the Handle_Events call process
ACE_WFMO_Reactor :: handle_events (ACE_Time_Value * how_long) -ACE_WFMO_Reactor :: event_handling (ACE_Time_Value * max_wait_time, int alertable) - ACE_WFMO_Reactor :: ok_to_wait (ACE_Time_Value * max_wait_time, int alertable) - ACE_WFMO_Reactor :: ok_to_wait (ACE_Time_Value * max_wait_time, int alertable) --ACE_WFMO_Reactor :: calculate_timeout (ACE_Time_Value * max_wait_time) - ACE_WFMO_Reactor :: calculate_timeout (ACE_Time_Value * max_wait_time) - ACE_WFMO_Reactor :: wait_for_multiple_events (int timeout, int alertable)
The above function is the key multi-channel separation function. How does Reactor know that the event processor should be called (Event_Handler), please see the function below,
ACE_WFMO_RACTOR:: Register_Handler (ACE_EVENT_HANDAL * Event_Handler, ACE_RAACTAL * Event_Handler, ACE_REACTOR_MASK MASK) This is a simple event processor's registration function, because we can derive a class from ACE_EVENT_HANDLER, and overload GET_HANDE () in this class The function provides an IO handle. as follows
class Server_Acceptor: public ACE_Event_Handler {public: virtual int open (const ACE_INET_Addr & local_addr); virtual ACE_HANDLE get_handle (void) const {return acceptor_.get_handle ();}; virtual int handle_close (ACE_HANDLE = ACE_INVALID_HANDLE, ACE_Reactor_Mask = 0); virtual int handle_input (ACE_HANDLE = ACE_INVALID_HANDLE); protected: ace_sock_acceptor acceptor_;};
This registration process is ultimately through the member function of Register_Handler_i,
intACE_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 do not 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
IF (this-> handler_rep_.invalid_handle (io_handle)) {errno = error_INVALID_HANDLE; RETURN-1;}
Long new_network_events = 0; int delete_event = 0; auto_ptr
// Look up the repository to see if the
// check to see if the user passed us a valid; if not the weight (event_handle == ace_invalid_handle) {// Note: Don't change this Since Some C Compilers Have //
#ENDIF / * ACE_HAS_WINSOCK2 || ACE_HAS_WINSOCK2 == 0 * /
}
This function first calls WSAEventselect to register for Event_Handler, and then call Handler_rep_.bind_i to modify the handle related information. Handler_rep is a handle warehouse for ACE_WFMO_REACTOR. I have encountered such a few questions when using ACE_WFMO_REACTOR.
How do I secure ends RUN_EVENT_LOOP thread?
Define into the next class
Class quit_handler: public ace_event_handler {friend class ace_dewarn_gplusplus; public: quit_handler (ACE_REACTOR * R): ACE_EVENT_HANDLER (R) {}
Virtual INT HANDLE_EXCEPTION (ACE_HANDLE) {Reactor () -> End_reactor_event_loop (); return -1; // trigger call to handle_close () method () method.
Virtual Int Handle_Close (ACE_HANDLE, ACE_RAACTOR_MASK) {delete this; return 0;}
Private:
// private destructor ensures dynamic allocation.virtual ~ quit_handler () {}};
Then call
Quit_handler * quit_handler_; ace_reactor * r = ace_reactor :: instance (); quit_handler_ = new quit_handler (r); r-> notify (quit_handler_);
How to securely delete an event processor?
ACE_RACTAN :: Instance () -> transove_handler (acceptor_.get_handle (), ACE_EVENT_HANDLER :: Read_Mask
Don't call Handle_Close directly
How to end workers, consumer threads?
If the thread synchronous queue, then the following message may be inserted, the end of the thread ACE_Message_Block * shutdown_message = 0; ACE_NEW_RETURN (shutdown_message, ACE_Message_Block (0, ACE_Message_Block :: MB_STOP), -1); if (my_card_queue.enqueue_tail (shutdown_message) == -1 Shutdown_message-> release ();
How to use ACE programming in MFC?
When the program starts running, it is called Ace :: init (), and then calls ACE: Fini ().
The problem in Reactor is that WaitFormultiobject can only be incorporated into 64 charters, which will be solved in the previous framework.
I am also a beginner, I can only write this.