diff options
Diffstat (limited to 'ACE/examples/Reactor/WFMO_Reactor/Talker.cpp')
-rw-r--r-- | ACE/examples/Reactor/WFMO_Reactor/Talker.cpp | 372 |
1 files changed, 192 insertions, 180 deletions
diff --git a/ACE/examples/Reactor/WFMO_Reactor/Talker.cpp b/ACE/examples/Reactor/WFMO_Reactor/Talker.cpp index 12bf5e32eaa..09d863b7fc8 100644 --- a/ACE/examples/Reactor/WFMO_Reactor/Talker.cpp +++ b/ACE/examples/Reactor/WFMO_Reactor/Talker.cpp @@ -1,136 +1,132 @@ -// $Id$ - -// ============================================================================ -// -// = LIBRARY -// examples -// -// = FILENAME -// Talker.cpp -// -// = DESCRIPTION -// -// This test application tests a wide range of events that can be -// demultiplexed using various ACE utilities. Events used include -// ^C events, reading from STDIN, vanilla Win32 events, thread -// exits, Reactor notifications, proactive reads, and proactive -// writes. -// -// The proactive I/O events are demultiplexed by the ACE_Proactor. -// The thread exits, notications, and vanilla Win32 events are -// demultiplexed by the ACE_Reactor. To enable a single thread -// to run all these events, the Proactor is integrated with the -// Reactor. -// -// The test application prototypes a simple talk program. Two -// instances of the application connect. Input from either console -// is displayed on the others console also. Because of the evils -// of Win32 STDIN, a separate thread is used to read from STDIN. -// To test the Proactor and Reactor, I/O between the remote -// processes is performed proactively and interactions between the -// STDIN thread and the main thread are performed reactively. -// -// The following description of the test application is in two -// parts. The participants section explains the main components -// involved in the application. The collaboration section -// describes how the partipants interact in response to the -// multiple event types which occur. -// -// The Reactor test application has the following participants: -// -// . Reactor -- The Reactor demultiplexes Win32 "waitable" -// events using WaitForMultipleObjects. -// -// . Proactor -- The proactor initiates and demultiplexes -// overlapped I/O operations. The Proactor registers with the -// Reactor so that a single-thread can demultiplex all -// application events. -// -// . STDIN_Handler -- STDIN_Handler is an Active Object which reads -// from STDIN and forwards the input to the Peer_Handler. This -// runs in a separate thread to make the test more interesting. -// However, STDIN is "waitable", so in general it can be waited on -// by the ACE Reactor, thanks MicroSlush! -// -// . Peer_Handler -- The Peer_Handler connects to another instance -// of test_reactor. It Proactively reads and writes data to the -// peer. When the STDIN_Handler gives it messages, it fowards them -// to the remote peer. When it receives messages from the remote -// peer, it prints the output to the console. -// -// The collaborations of the participants are as follows: -// -// . Initialization -// -// Peer_Handler -- connects to the remote peer. It then begins -// proactively reading from the remote connection. Note that it -// will be notified by the Proactor when a read completes. It -// also registers a notification strategy with message queue so -// that it is notified when the STDIN_Handler posts a message -// onto the queue. -// -// STDIN_Handler -- STDIN_Handler registers a signal handler for -// SIGINT. This just captures the exception so that the kernel -// doesn't kill our process; We want to exit gracefully. It also -// creates an Exit_Hook object which registers the -// STDIN_Handler's thread handle with the Reactor. The -// Exit_Hook will get called back when the STDIN_Handler thread -// exits. After registering these, it blocks reading from STDIN. -// -// Proactor -- is registered with the Reactor. -// -// The main thread of control waits in the Reactor. -// -// . STDIN events -- When the STDIN_Handler thread reads from -// STDIN, it puts the message on Peer_Handler's message queue. It -// then returns to reading from STDIN. -// -// . Message enqueue -- The Reactor thread wakes up and calls -// Peer_Handler::handle_output. The Peer_Handler then tries to -// dequeue a message from its message queue. If it can, the -// message is Proactively sent to the remote peer. Note that the -// Peer_Handler will be notified with this operation is complete. -// The Peer_Handler then falls back into the Reactor event loop. -// -// . Send complete event -- When a proactive send is complete, the -// Proactor is notified by the Reactor. The Proactor, in turn, -// notifies the Peer_Handler. The Peer_Handler then checks for -// more messages from the message queue. If there are any, it -// tries to send them. If there are not, it returns to the -// Reactor event loop. -// -// . Read complete event -- When a proactive read is complete (the -// Peer_Handler initiated a proactive read when it connected to the -// remote peer), the Proactor is notified by the Reactor. The -// Proactor, in turn notifies the Peer_Handler. If the read was -// successful the Peer_Handler just displays the received msg to -// the console and reinvokes a proactive read from the network -// connection. If the read failed (i.e. the remote peer exited), -// the Peer_Handler sets a flag to end the event loop and returns. -// This will cause the application to exit. -// -// . ^C events -- When the user types ^C at the console, the -// STDIN_Handler's signal handler will be called. It does nothing, -// but as a result of the signal, the STDIN_Handler thread will -// exit. -// -// . STDIN_Handler thread exits -- The Exit_Hook will get called -// back from the Reactor. Exit_Hook::handle_signal sets a flag -// to end the event loop and returns. This will cause the -// application to exit. -// -// -// To run example, start an instance of the test with an optional -// local port argument (as the acceptor). Start the other instance -// with -h <hostname> and -p <server port>. Type in either the -// client or server windows and your message should show up in the -// other window. Control C to exit. -// -// = AUTHOR -// Tim Harrison -// Irfan Pyarali -// -// ============================================================================ + +//============================================================================= +/** + * @file Talker.cpp + * + * $Id$ + * + * + * This test application tests a wide range of events that can be + * demultiplexed using various ACE utilities. Events used include + * ^C events, reading from STDIN, vanilla Win32 events, thread + * exits, Reactor notifications, proactive reads, and proactive + * writes. + * + * The proactive I/O events are demultiplexed by the ACE_Proactor. + * The thread exits, notications, and vanilla Win32 events are + * demultiplexed by the ACE_Reactor. To enable a single thread + * to run all these events, the Proactor is integrated with the + * Reactor. + * + * The test application prototypes a simple talk program. Two + * instances of the application connect. Input from either console + * is displayed on the others console also. Because of the evils + * of Win32 STDIN, a separate thread is used to read from STDIN. + * To test the Proactor and Reactor, I/O between the remote + * processes is performed proactively and interactions between the + * STDIN thread and the main thread are performed reactively. + * + * The following description of the test application is in two + * parts. The participants section explains the main components + * involved in the application. The collaboration section + * describes how the partipants interact in response to the + * multiple event types which occur. + * + * The Reactor test application has the following participants: + * + * . Reactor -- The Reactor demultiplexes Win32 "waitable" + * events using WaitForMultipleObjects. + * + * . Proactor -- The proactor initiates and demultiplexes + * overlapped I/O operations. The Proactor registers with the + * Reactor so that a single-thread can demultiplex all + * application events. + * + * . STDIN_Handler -- STDIN_Handler is an Active Object which reads + * from STDIN and forwards the input to the Peer_Handler. This + * runs in a separate thread to make the test more interesting. + * However, STDIN is "waitable", so in general it can be waited on + * by the ACE Reactor, thanks MicroSlush! + * + * . Peer_Handler -- The Peer_Handler connects to another instance + * of test_reactor. It Proactively reads and writes data to the + * peer. When the STDIN_Handler gives it messages, it fowards them + * to the remote peer. When it receives messages from the remote + * peer, it prints the output to the console. + * + * The collaborations of the participants are as follows: + * + * . Initialization + * + * Peer_Handler -- connects to the remote peer. It then begins + * proactively reading from the remote connection. Note that it + * will be notified by the Proactor when a read completes. It + * also registers a notification strategy with message queue so + * that it is notified when the STDIN_Handler posts a message + * onto the queue. + * + * STDIN_Handler -- STDIN_Handler registers a signal handler for + * SIGINT. This just captures the exception so that the kernel + * doesn't kill our process; We want to exit gracefully. It also + * creates an Exit_Hook object which registers the + * STDIN_Handler's thread handle with the Reactor. The + * Exit_Hook will get called back when the STDIN_Handler thread + * exits. After registering these, it blocks reading from STDIN. + * + * Proactor -- is registered with the Reactor. + * + * The main thread of control waits in the Reactor. + * + * . STDIN events -- When the STDIN_Handler thread reads from + * STDIN, it puts the message on Peer_Handler's message queue. It + * then returns to reading from STDIN. + * + * . Message enqueue -- The Reactor thread wakes up and calls + * Peer_Handler::handle_output. The Peer_Handler then tries to + * dequeue a message from its message queue. If it can, the + * message is Proactively sent to the remote peer. Note that the + * Peer_Handler will be notified with this operation is complete. + * The Peer_Handler then falls back into the Reactor event loop. + * + * . Send complete event -- When a proactive send is complete, the + * Proactor is notified by the Reactor. The Proactor, in turn, + * notifies the Peer_Handler. The Peer_Handler then checks for + * more messages from the message queue. If there are any, it + * tries to send them. If there are not, it returns to the + * Reactor event loop. + * + * . Read complete event -- When a proactive read is complete (the + * Peer_Handler initiated a proactive read when it connected to the + * remote peer), the Proactor is notified by the Reactor. The + * Proactor, in turn notifies the Peer_Handler. If the read was + * successful the Peer_Handler just displays the received msg to + * the console and reinvokes a proactive read from the network + * connection. If the read failed (i.e. the remote peer exited), + * the Peer_Handler sets a flag to end the event loop and returns. + * This will cause the application to exit. + * + * . ^C events -- When the user types ^C at the console, the + * STDIN_Handler's signal handler will be called. It does nothing, + * but as a result of the signal, the STDIN_Handler thread will + * exit. + * + * . STDIN_Handler thread exits -- The Exit_Hook will get called + * back from the Reactor. Exit_Hook::handle_signal sets a flag + * to end the event loop and returns. This will cause the + * application to exit. + * + * + * To run example, start an instance of the test with an optional + * local port argument (as the acceptor). Start the other instance + * with -h <hostname> and -p <server port>. Type in either the + * client or server windows and your message should show up in the + * other window. Control C to exit. + * + * + * @author Tim Harrison Irfan Pyarali + */ +//============================================================================= + #include "ace/OS_main.h" @@ -147,14 +143,17 @@ #include "ace/Task.h" #include "ace/OS_NS_unistd.h" -ACE_RCSID(WFMO_Reactor, Talker, "$Id$") + typedef ACE_Task<ACE_MT_SYNCH> MT_TASK; +/** + * @class Peer_Handler + * + * @brief Connect to a server. Receive messages from STDIN_Handler + * and forward them to the server using proactive I/O. + */ class Peer_Handler : public MT_TASK, public ACE_Handler -// = TITLE -// Connect to a server. Receive messages from STDIN_Handler -// and forward them to the server using proactive I/O. { public: // = Initialization methods. @@ -162,104 +161,117 @@ public: ~Peer_Handler (void); //FUZZ: disable check_for_lack_ACE_OS + /** + * This method creates the network connection to the remote peer. + * It does blocking connects and accepts depending on whether a + * hostname was specified from the command line. + *FUZZ: enable check_for_lack_ACE_OS + */ int open (void * =0); - // This method creates the network connection to the remote peer. - // It does blocking connects and accepts depending on whether a - // hostname was specified from the command line. - //FUZZ: enable check_for_lack_ACE_OS + /** + * This method will be called when an asynchronous read completes on a stream. + * The remote peer has sent us something. If it succeeded, print + * out the message and reinitiate a read. Otherwise, fail. In both + * cases, delete the message sent. + */ virtual void handle_read_stream (const ACE_Asynch_Read_Stream::Result &result); - // This method will be called when an asynchronous read completes on a stream. - // The remote peer has sent us something. If it succeeded, print - // out the message and reinitiate a read. Otherwise, fail. In both - // cases, delete the message sent. + /** + * This method will be called when an asynchronous write completes on a strea_m. + * One of our asynchronous writes to the remote peer has completed. + * Make sure it succeeded and then delete the message. + */ virtual void handle_write_stream (const ACE_Asynch_Write_Stream::Result &result); - // This method will be called when an asynchronous write completes on a strea_m. - // One of our asynchronous writes to the remote peer has completed. - // Make sure it succeeded and then delete the message. + /** + * Get the I/O handle used by this <handler>. This method will be + * called by the ACE_Asynch_* classes when an ACE_INVALID_HANDLE is + * passed to <open>. + */ virtual ACE_HANDLE handle (void) const; - // Get the I/O handle used by this <handler>. This method will be - // called by the ACE_Asynch_* classes when an ACE_INVALID_HANDLE is - // passed to <open>. + /// Set the ACE_HANDLE value for this Handler. void handle (ACE_HANDLE); - // Set the ACE_HANDLE value for this Handler. + /// We've been removed from the Reactor. virtual int handle_close (ACE_HANDLE, ACE_Reactor_Mask); - // We've been removed from the Reactor. + /** + * Called when output events should start. Note that this is + * automatically invoked by the + * <ACE_Reactor_Notificiation_Strategy>. + */ virtual int handle_output (ACE_HANDLE fd); - // Called when output events should start. Note that this is - // automatically invoked by the - // <ACE_Reactor_Notificiation_Strategy>. private: + /// Socket that we have connected to the server. ACE_SOCK_Stream stream_; - // Socket that we have connected to the server. + /// The strategy object that the reactor uses to notify us when + /// something is added to the queue. ACE_Reactor_Notification_Strategy strategy_; - // The strategy object that the reactor uses to notify us when - // something is added to the queue. // = Remote peer info. + /// Name of remote host. ACE_TCHAR *host_; - // Name of remote host. + /// Port number for remote host. u_short port_; - // Port number for remote host. + /// Read stream ACE_Asynch_Read_Stream rd_stream_; - // Read stream + /// Write stream ACE_Asynch_Write_Stream wr_stream_; - // Write stream + /// Message Block for reading from the network ACE_Message_Block mb_; - // Message Block for reading from the network }; +/** + * @class STDIN_Handler + * + * @brief Active Object. Reads from STDIN and passes message blocks to + * the peer handler. + */ class STDIN_Handler : public ACE_Task<ACE_NULL_SYNCH> -// = TITLE -// Active Object. Reads from STDIN and passes message blocks to -// the peer handler. { public: + /// Initialization. STDIN_Handler (MT_TASK &ph); - // Initialization. //FUZZ: disable check_for_lack_ACE_OS + /// Activate object. virtual int open (void * = 0); - // Activate object. + /// Shut down. + ///FUZZ: enable check_for_lack_ACE_OS virtual int close (u_long = 0); - // Shut down. - //FUZZ: enable check_for_lack_ACE_OS + /// Thread runs here as an active object. int svc (void); - // Thread runs here as an active object. int handle_close (ACE_HANDLE, ACE_Reactor_Mask); private: + /// Handle a ^C. (Do nothing, this just illustrates how we can catch + /// signals along with the other things). static void handler (int signum); - // Handle a ^C. (Do nothing, this just illustrates how we can catch - // signals along with the other things). + /// Helper function to register with the Reactor for thread exit. void register_thread_exit_hook (void); - // Helper function to register with the Reactor for thread exit. + /// The STDIN thread has exited. This means the user hit ^C. We can + /// end the event loop. virtual int handle_signal (int index, siginfo_t *, ucontext_t *); - // The STDIN thread has exited. This means the user hit ^C. We can - // end the event loop. + /// Send all input to ph_. MT_TASK &ph_; - // Send all input to ph_. + /// Handle of our thread. ACE_HANDLE thr_handle_; - // Handle of our thread. }; Peer_Handler::Peer_Handler (int argc, ACE_TCHAR *argv[]) @@ -412,7 +424,7 @@ Peer_Handler::handle_close (ACE_HANDLE, ACE_Reactor_Mask) int Peer_Handler::handle_output (ACE_HANDLE) { - ACE_Message_Block *mb; + ACE_Message_Block *mb = 0; ACE_Time_Value tv (ACE_Time_Value::zero); |