diff options
author | cdgill <cdgill@ae88bc3d-4319-0410-8dbf-d08b4c9d3795> | 1998-09-21 23:35:56 +0000 |
---|---|---|
committer | cdgill <cdgill@ae88bc3d-4319-0410-8dbf-d08b4c9d3795> | 1998-09-21 23:35:56 +0000 |
commit | 81f4d31154fd1d72737cbb122cd99d3f29892de8 (patch) | |
tree | b74e8a66c80000cbbca4d502b460d4aceaef41c1 /examples | |
parent | 048270596b0360b2b86e9bd9fc2a6955a42b45fb (diff) | |
download | ATCD-81f4d31154fd1d72737cbb122cd99d3f29892de8.tar.gz |
testing fixes, factored out templates
Diffstat (limited to 'examples')
-rw-r--r-- | examples/Bounded_Packet_Relay/BPR_Drivers.cpp | 407 | ||||
-rw-r--r-- | examples/Bounded_Packet_Relay/BPR_Drivers.h | 189 | ||||
-rw-r--r-- | examples/Bounded_Packet_Relay/BPR_Drivers_T.cpp | 576 | ||||
-rw-r--r-- | examples/Bounded_Packet_Relay/BPR_Drivers_T.h | 295 | ||||
-rw-r--r-- | examples/Bounded_Packet_Relay/Thread_Bounded_Packet_Relay.cpp | 92 | ||||
-rw-r--r-- | examples/Bounded_Packet_Relay/Thread_Bounded_Packet_Relay.h | 45 | ||||
-rw-r--r-- | examples/Bounded_Packet_Relay/bpr_thread.cpp | 19 |
7 files changed, 954 insertions, 669 deletions
diff --git a/examples/Bounded_Packet_Relay/BPR_Drivers.cpp b/examples/Bounded_Packet_Relay/BPR_Drivers.cpp index 0b56bd384d6..d576e6feb66 100644 --- a/examples/Bounded_Packet_Relay/BPR_Drivers.cpp +++ b/examples/Bounded_Packet_Relay/BPR_Drivers.cpp @@ -26,232 +26,9 @@ #if !defined (_BPR_DRIVER_CPP_) #define _BPR_DRIVER_CPP_ -#include "ace/Auto_Ptr.h" #include "BPR_Drivers.h" -ACE_RCSID(Bounded_Packet_Relay, BPR_Driver, "$Id$") - -// Constructor. - -template <ACE_SYNCH_DECL> -Bounded_Packet_Relay<ACE_SYNCH_USE>::Bounded_Packet_Relay (ACE_Thread_Manager *input_task_mgr, - Input_Device_Wrapper_Base *input_wrapper, - Output_Device_Wrapper_Base *output_wrapper) - : input_task_mgr_ (input_task_mgr), - input_wrapper_ (input_wrapper), - output_wrapper_ (output_wrapper), - transmission_number_ (0), - packets_sent_ (0), - status_ (Bounded_Packet_Relay_Base::UN_INITIALIZED), - transmission_start_ (0, 0), - transmission_end_ (0, 0) -{ - if (input_task_mgr_ == 0) - input_task_mgr_ = ACE_Thread_Manager::instance (); -} - -// Destructor. - -template <ACE_SYNCH_DECL> -Bounded_Packet_Relay<ACE_SYNCH_USE>::~Bounded_Packet_Relay (void) -{ -} - -// Requests output be sent to output device. - -template <ACE_SYNCH_DECL> int -Bounded_Packet_Relay<ACE_SYNCH_USE>::send_input (void) -{ - // Don't block, return immediately if queue is empty. - ACE_Message_Block *item; - - if (queue_.dequeue_head (item, - &ACE_Time_Value::zero) < 0) - return 1; - - // If a message block was dequeued, send it to the output device. - - if (output_wrapper_->write_output_message ((void *) item) < 0) - ACE_ERROR_RETURN ((LM_ERROR, - "%t %p\n", - "failed to write to output device object"), - -1); - // If all went OK, increase count of packets sent. - ++packets_sent_; - return 0; -} - -// Requests a transmission be started. - -template <ACE_SYNCH_DECL> int -Bounded_Packet_Relay<ACE_SYNCH_USE>::start_transmission (u_long packet_count, - u_long arrival_period, - u_long logging_level) -{ - // Serialize access to start and end transmission calls, statistics - // reporting calls. - ACE_GUARD_RETURN (ACE_SYNCH_MUTEX_T, ace_mon, this->transmission_lock_, -1); - - // If a transmission is already in progress, just return. - if (status_ == STARTED) - return 1; - - // Update statistics for a new transmission. - ++transmission_number_; - packets_sent_ = 0; - status_ = STARTED; - transmission_start_ = ACE_OS::gettimeofday (); - - // Initialize the output device. - if (output_wrapper_->modify_device_settings ((void *) &logging_level) < 0) - { - status_ = ERROR; - transmission_end_ = ACE_OS::gettimeofday (); - ACE_ERROR_RETURN ((LM_ERROR, "%t %p\n", - "failed to initialize output device object"), - -1); - } - - // Initialize the input device. - if (input_wrapper_->set_input_period (arrival_period) < 0) - { - status_ = ERROR; - transmission_end_ = ACE_OS::gettimeofday (); - ACE_ERROR_RETURN ((LM_ERROR, "%t %p\n", - "failed to initialize input device object"), - -1); - } - - // Activate the input device and save a handle to the new thread. - if (input_wrapper_->activate () < 0) - { - status_ = ERROR; - transmission_end_ = ACE_OS::gettimeofday (); - ACE_ERROR_RETURN ((LM_ERROR, "%t %p\n", - "failed to activate input device object"), - -1); - } - - // If all went well, return success. - return 0; -} - -// Requests a transmission be ended. - -template <ACE_SYNCH_DECL> int -Bounded_Packet_Relay<ACE_SYNCH_USE>::end_transmission (Transmission_Status status) -{ - // Serialize access to start and end transmission calls, - // statistics reporting calls. - ACE_GUARD_RETURN (ACE_SYNCH_MUTEX_T, ace_mon, this->transmission_lock_, -1); - - // If a transmission is not already in progress, just return. - if (status_ != STARTED) - return 1; - - // Ask the the input thread to stop. - if (input_wrapper_->request_stop () < 0) - { - status_ = ERROR; - transmission_end_ = ACE_OS::gettimeofday (); - ACE_ERROR_RETURN ((LM_ERROR, "%t %p\n", - "failed asking input device thread to stop"), - -1); - } - - // Wait for input thread to stop. - if (input_task_mgr_->wait_task (input_wrapper_) < 0) - { - status_ = ERROR; - transmission_end_ = ACE_OS::gettimeofday (); - ACE_ERROR_RETURN ((LM_ERROR, "%t %p\n", - "failed waiting for input device thread to stop"), - -1); - } - - // If all went well, set passed status, stamp end time, return - // success. - status_ = status; - transmission_end_ = ACE_OS::gettimeofday (); - return 0; -} - -// Requests a report of statistics from the last transmission. - -template <ACE_SYNCH_DECL> int -Bounded_Packet_Relay<ACE_SYNCH_USE>::report_statistics (void) -{ - // Serialize access to start and end transmission calls, - // statistics reporting calls. - ACE_GUARD_RETURN (ACE_SYNCH_MUTEX_T, ace_mon, this->transmission_lock_, -1); - - // If a transmission is already in progress, just return. - if (status_ == STARTED) - return 1; - - const char *status_msg; - switch (status_) - { - case UN_INITIALIZED: - status_msg = "Uninitialized"; - break; - case STARTED: - // NOT REACHED: user should never see this ;-) - status_msg = "In progress"; - break; - case COMPLETED: - status_msg = "Completed with all packets sent"; - break; - case TIMED_OUT: - status_msg = "Terminated by transmission duration timer"; - break; - case CANCELLED: - status_msg = "Cancelled by external control"; - break; - case ERROR: - status_msg = "Error was detected"; - break; - default: - status_msg = "Unknown"; - break; - } - - // Calculate duration of trasmission. - ACE_Time_Value duration (transmission_end_); - duration -= transmission_start_; - - // Report transmission statistics. - ACE_DEBUG ((LM_DEBUG, - "\n\nStatisics for transmission %lu:\n\n" - "Transmission status: %s\n" - "Start time: %d (sec) %d (usec)\n" - "End time: %d (sec) %d (usec)\n" - "Duration: %d (sec) %d (usec)\n" - "Packets relayed: %u\n\n", - transmission_number_, status_msg, - transmission_start_.sec (), - transmission_start_.usec (), - transmission_end_.sec (), - transmission_end_.usec (), - duration.sec (), - duration.usec (), - packets_sent_)); - return 0; -} - -// Public entry point to which to push input. - -template <ACE_SYNCH_DECL> int -Bounded_Packet_Relay<ACE_SYNCH_USE>::receive_input (void * arg) -{ - ACE_Message_Block *message = ACE_static_cast (ACE_Message_Block *, - arg); - if (queue_.enqueue_tail (message) < 0) - ACE_ERROR_RETURN ((LM_ERROR, "%t %p\n", - "Bounded_Packet_Relay<ACE_SYNCH_USE>::receive_input failed"), - -1); - return 0; -} +ACE_RCSID(Bounded_Packet_Relay, BPR_Drivers, "$Id$") // Constructor. @@ -259,7 +36,8 @@ Input_Device_Wrapper_Base::Input_Device_Wrapper_Base (ACE_Thread_Manager *input_ : ACE_Task_Base (input_task_mgr), send_input_msg_cmd_ (0), input_period_ (ACE_ONE_SECOND_IN_USECS), - is_active_ (0) + is_active_ (0), + send_count_ (0) { } @@ -267,7 +45,6 @@ Input_Device_Wrapper_Base::Input_Device_Wrapper_Base (ACE_Thread_Manager *input_ Input_Device_Wrapper_Base::~Input_Device_Wrapper_Base (void) { - delete send_input_msg_cmd_; } // Sets send input message command in the input device driver object. @@ -275,8 +52,8 @@ Input_Device_Wrapper_Base::~Input_Device_Wrapper_Base (void) int Input_Device_Wrapper_Base::set_send_input_msg_cmd (Command_Base *send_input_msg_cmd) { - // Delete the old command (if any), then set the new command. - delete send_input_msg_cmd_; + // Set the new command. Input device is not responsible + // for deleting the old command, if any. send_input_msg_cmd_ = send_input_msg_cmd; return 0; } @@ -320,7 +97,6 @@ Input_Device_Wrapper_Base::request_stop (void) int Input_Device_Wrapper_Base::svc (void) { - long count; ACE_Time_Value timeout; ACE_Message_Block *message; @@ -328,9 +104,9 @@ Input_Device_Wrapper_Base::svc (void) is_active_ = 1; // Start with the total count of messages to send. - for (count = send_count_; + for (current_count_ = send_count_; // While we're still marked active, and there are packets to send. - is_active_ && count != 0; + (is_active_) && (current_count_ != 0); ) { // Make sure there is a send command object. @@ -365,8 +141,8 @@ Input_Device_Wrapper_Base::svc (void) // If all went well, decrement count of messages to send, and // run the reactor event loop unti we get a timeout or something // happens in a registered upcall. - if (count > 0) - --count; + if (current_count_ > 0) + --current_count_; timeout = ACE_Time_Value (0, input_period_); reactor_.run_event_loop (timeout); @@ -393,169 +169,4 @@ Input_Device_Wrapper_Base::send_input_message (ACE_Message_Block *amb) -1); } -// Parse the input and execute the corresponding command. - -template <class TQ> int -Bounded_Packet_Relay_Driver<TQ>::parse_commands (const char *buf) -{ - int option; - - if (::sscanf (buf, "%d", &option) <= 0) - // If there was an error reading the option simply try on the next - // line. - return 0; - - switch (option) - { - case 1: // set packet count - { - u_long count; - - // We just reread the option, this simplies parsing (since - // sscanf can do it for us). - if (::sscanf (buf, "%d %lu", &option, &count) < 2) - // If there was not enough information on the line, ignore - // option and try the next line. - return 0; - if (packet_count_cmd_->execute ((void *) &count) == -1) - ACE_ERROR_RETURN ((LM_ERROR, - "%t %p\n", - "set packet count failed"), - -1); - break; - } - case 2: // Set the arrival period. - { - u_long usec; - - // We just reread the option, this simplies parsing (since - // sscanf can do it for us). - if (::sscanf (buf, "%d %lu", &option, &usec) < 2) - // If there was not enough information on the line, ignore - // option and try the next line. - return 0; - if (arrival_period_cmd_->execute ((void *) &usec) == -1) - ACE_ERROR_RETURN ((LM_ERROR, - "%t %p\n", - "set arrival period failed"), - -1); - break; - } - case 3: // Set transmit period. - { - u_long usec; - - // We just reread the option, this simplies parsing (since - // sscanf can do it for us). - if (::sscanf (buf, "%d %lu", &option, &usec) < 2) - // If there was not enough information on the line, ignore - // option and try the next line. - return 0; - if (transmit_period_cmd_->execute ((void *) &usec) == -1) - ACE_ERROR_RETURN ((LM_ERROR, - "%t %p\n", - "set transmit period failed"), - -1); - break; - } - case 4: // Set duration limit. - { - u_long usec; - - // We just reread the option, this simplies parsing (since - // sscanf can do it for us). - if (::sscanf (buf, "%d %lu", &option, &usec) < 2) - // If there was not enough information on the line, ignore - // option and try the next line. - return 0; - if (duration_limit_cmd_->execute ((void *) &usec) == -1) - ACE_ERROR_RETURN ((LM_ERROR, - "%t %p\n", - "set duration limit failed"), - -1); - break; - } - case 5: // Set logging level. - { - u_long level; - - // We just reread the option, this simplies parsing (since - // sscanf can do it for us). - if (::sscanf (buf, "%d %lu", &option, &level) < 2) - // If there was not enough information on the line, ignore - // option and try the next line. - return 0; - if (logging_level_cmd_->execute ((void *) &level) == -1) - ACE_ERROR_RETURN ((LM_ERROR, - "%t %p\n", - "set logging level failed"), - -1); - break; - } - case 6: // Run one transmission. - return run_transmission_cmd_->execute (0); - /* NOTREACHED */ - case 7: // Report statistics. - return report_stats_cmd_->execute (0); - /* NOTREACHED */ - case 8: // Shut down the driver. - return shutdown_cmd_->execute (0); - /* NOTREACHED */ - default: - // Display an error message. - ACE_ERROR_RETURN ((LM_ERROR, "invalid input %s\n", buf), 0); - ACE_NOTREACHED (break); - /* NOTREACHED */ - } /* ENDSWITCH */ - return 0; -} - -// Runs the test. - -template <class TQ> int -Bounded_Packet_Relay_Driver<TQ>::run (void) -{ - this->init (); - - // Process all the incoming events. - - for (;;) - if (this->get_next_request () == -1) - return -1; - - ACE_NOTREACHED (return 0); -} - -// Gets the next request from the user input. - -template <class TQ> int -Bounded_Packet_Relay_Driver<TQ>::get_next_request (void) -{ - char buf[BUFSIZ]; - - this->display_menu (); - - ACE_DEBUG ((LM_DEBUG, - "Please enter your choice: ")); - - // Reads input from the user. - if (this->read_input (buf, sizeof buf) <= 0) - return -1; - - // Parse and run the command. - return this->parse_commands (buf); -} - -// Reads input from the user from ACE_STDIN into the buffer specified. - -template <class TQ> ssize_t -Bounded_Packet_Relay_Driver<TQ>::read_input (char *buf, size_t bufsiz) -{ - ACE_OS::memset (buf, 0, bufsiz); - - // Wait for user to type commands. This call is automatically - // restarted when SIGINT or SIGALRM signals occur. - return ACE_OS::read (ACE_STDIN, buf, bufsiz); -} - #endif /* _BPR_DRIVER_CPP_ */ diff --git a/examples/Bounded_Packet_Relay/BPR_Drivers.h b/examples/Bounded_Packet_Relay/BPR_Drivers.h index f558d5061a2..81e7197adf0 100644 --- a/examples/Bounded_Packet_Relay/BPR_Drivers.h +++ b/examples/Bounded_Packet_Relay/BPR_Drivers.h @@ -7,10 +7,10 @@ // examples // // = FILENAME -// BPR_Driver.h +// BPR_Drivers.h // // = DESCRIPTION -// This code builds an abstraction to factor out common code from +// This code builds abstractions to factor out common code from // the different possible implementations of the Timer_Queue based // bounded packet relay example. // @@ -26,8 +26,8 @@ // // ============================================================================ -#if !defined (_BPR_DRIVER_H_) -#define _BPR_DRIVER_H_ +#if !defined (_BPR_DRIVERS_H_) +#define _BPR_DRIVERS_H_ #include "ace/Task.h" @@ -67,97 +67,10 @@ public: COMPLETED, TIMED_OUT, CANCELLED, - ERROR + ERROR_DETECTED }; }; -template <ACE_SYNCH_DECL> -class Bounded_Packet_Relay : public Bounded_Packet_Relay_Base -{ - // = TITLE - // This class defines a packet relay abstraction for a - // transmission bounded external commands to start and end the - // transmission. The transmission may be bounded by the number - // of packets to send, the dration of the transmission, or any - // other factors. - // - // = DESCRIPTION - // The relay abstraction implemented by this class registers a - // callback command with an input device wrapper, and relays - // input to an output device at a pace specified in the start - // transmission call. -public: - - typedef int (Bounded_Packet_Relay::*ACTION) (void *); - // Command entry point type definition. - - // = Initialization method - - Bounded_Packet_Relay (ACE_Thread_Manager *input_task_mgr, - Input_Device_Wrapper_Base *input_wrapper, - Output_Device_Wrapper_Base *output_wrapper); - // Constructor. - - virtual ~Bounded_Packet_Relay (void); - // Destructor. - - int send_input (void); - // Requests output be sent to output device. - - int start_transmission (u_long packet_count, - u_long arrival_period, - u_long logging_level); - // Requests a transmission be started. - - int end_transmission (Transmission_Status status); - // Requests a transmission be ended. - - int report_statistics (void); - // Requests a report of statistics from the last transmission. - - // = Command Accessible Entry Points. - - int receive_input (void *); - // Public entry point to which to push input. - -private: - // = Concurrency Management. - - ACE_Thread_Manager * input_task_mgr_; - // Thread manager for the input device task. - - Input_Device_Wrapper_Base * input_wrapper_; - // Pointer to the input device wrapper. - - Output_Device_Wrapper_Base * output_wrapper_; - // Pointer to the output device wrapper. - - ACE_Message_Queue<ACE_SYNCH_USE> queue_; - // Queue used to buffer input messages. - - ACE_SYNCH_MUTEX_T transmission_lock_; - // Lock for thread-safe synchronization - // of transmission startup and termination. - - // = Transmission Statistics - - u_long transmission_number_; - // Number of transmissions sent. - - u_long packets_sent_; - // Count of packets sent in the most recent transmission. - - Transmission_Status status_; - // Status of the current or most recent transmission. - - ACE_Time_Value transmission_start_; - // Start time of the most recent transmission. - - ACE_Time_Value transmission_end_; - // Ending time of the most recent transmission. - -}; - class Input_Device_Wrapper_Base : public ACE_Task_Base { // = TITLE @@ -235,6 +148,11 @@ protected: long send_count_; // Count of messages to send before stopping (-1 indicates the // device should not stop). + + long current_count_; + // Currently remaining count of messages to send before stopping + // (-1 indicates the device should not stop). + }; class Output_Device_Wrapper_Base @@ -260,88 +178,7 @@ public: // settings. }; -template <class TQ> -class Bounded_Packet_Relay_Driver -{ - // = TITLE - // This abstract base class provides a simple abstraction for a - // test driver for the bounded packet relay example. - // - // = DESCRIPTION - // This is the place where the common code to test the different - // implementations of the timer queue resides. This class has - // the logic for the parse_commands () method, the run (), - // read_input () and get_next_request () methods. Subclasses can - // override these methods if there is some logic that is specific - // to that implementation. -public: - virtual int parse_commands (const char *buf); - // Breaks up the input string buffer into pieces and executes the - // appropriate method to handle that operation. - - virtual int run (void); - // This is the main entry point for the driver. The user of the - // class should normally invoke this method. Returns 0 when - // successful, or 0 otherwise. - - virtual int get_next_request (void); - // This internal method gets the next request from the user. - // Returns -1 when user wants to exit. Returns 0 otherwise. - - virtual ssize_t read_input (char *buf, size_t bufsiz); - // Reads input from the user into the buffer <buf> with a maximum of - // <bufsiz> bytes. Returns the amount of bytes actually read - // Otherwise, a -1 is returned and errno is set to indicate the - // error. - - virtual int display_menu (void)=0; - // Prints the user interface for the driver to STDERR. - - virtual int init (void)=0; - // Initializes values and operations for the driver. - -protected: - // = Major Driver Mechanisms - - TQ timer_queue_; - // Timer queue for transmission timeouts. - - // = Set of <Command>s to be executed. - - Command_Base *packet_count_cmd_; - // Set packet count command. - - Command_Base *arrival_period_cmd_; - // Set arrival period command. - - Command_Base *transmit_period_cmd_; - // Set transmit period command. - - Command_Base *duration_limit_cmd_; - // Set duration limit command. - - Command_Base *logging_level_cmd_; - // Set logging level command. - - Command_Base *run_transmission_cmd_; - // Run transmission command. - - Command_Base *cancel_transmission_cmd_; - // Cancel transmission command. - - Command_Base *report_stats_cmd_; - // Report statistics command. - - Command_Base *shutdown_cmd_; - // Shut down the driver. -}; - -#if defined (ACE_TEMPLATES_REQUIRE_SOURCE) -#include "Driver.cpp" -#endif /* ACE_TEMPLATES_REQUIRE_SOURCE */ - -#if defined (ACE_TEMPLATES_REQUIRE_PRAGMA) -#pragma implementation ("Driver.cpp") -#endif /* ACE_TEMPLATES_REQUIRE_PRAGMA */ +// include the templates +#include "BPR_Drivers_T.h" -#endif /* _BPR_DRIVER_H_ */ +#endif /* _BPR_DRIVERS_H_ */ diff --git a/examples/Bounded_Packet_Relay/BPR_Drivers_T.cpp b/examples/Bounded_Packet_Relay/BPR_Drivers_T.cpp new file mode 100644 index 00000000000..ba441fea6c6 --- /dev/null +++ b/examples/Bounded_Packet_Relay/BPR_Drivers_T.cpp @@ -0,0 +1,576 @@ +// $Id$ + +// ============================================================================ +// = LIBRARY +// examples +// +// = FILENAME +// BPR_Driver.cpp +// +// = DESCRIPTION +// This code builds an abstraction to factor out common code for +// the different implementations of the Timer_Queue. +// +// = AUTHORS +// Chris Gill <cdgill@cs.wustl.edu> and +// Douglas C. Schmidt <schmidt@cs.wustl.edu> +// +// Based on the Timer Queue Test example written by +// +// Carlos O'Ryan <coryan@cs.wustl.edu> and +// Douglas C. Schmidt <schmidt@cs.wustl.edu> and +// Sergio Flores-Gaitan <sergio@cs.wustl.edu> +// +// ============================================================================ + +#if !defined (_BPR_DRIVER_T_CPP_) +#define _BPR_DRIVER_T_CPP_ + +// #include BPR_Drivers.h instead of BPR_Drivers_T.h +// to avoid problems with circular includes +#include "BPR_Drivers.h" + +ACE_RCSID(Bounded_Packet_Relay, BPR_Drivers_T, "$Id$") + +// Constructor. + +template <class RECEIVER, class ACTION> +Command<RECEIVER, ACTION>::Command (RECEIVER &recvr, + ACTION action) + : receiver_ (recvr), + action_ (action) +{ +} + +// Invokes an operation. + +template <class RECEIVER, class ACTION> int +Command<RECEIVER, ACTION>::execute (void *arg) +{ + return (receiver_.*action_) (arg); +} + + +// Constructor. + +template <ACE_SYNCH_DECL> +Bounded_Packet_Relay<ACE_SYNCH_USE>::Bounded_Packet_Relay (ACE_Thread_Manager *input_task_mgr, + Input_Device_Wrapper_Base *input_wrapper, + Output_Device_Wrapper_Base *output_wrapper) + : input_task_mgr_ (input_task_mgr), + input_wrapper_ (input_wrapper), + output_wrapper_ (output_wrapper), + transmission_number_ (0), + packets_sent_ (0), + status_ (Bounded_Packet_Relay_Base::UN_INITIALIZED), + transmission_start_ (ACE_Time_Value::zero), + transmission_end_ (ACE_Time_Value::zero) +{ + if (input_task_mgr_ == 0) + input_task_mgr_ = ACE_Thread_Manager::instance (); +} + +// Destructor. + +template <ACE_SYNCH_DECL> +Bounded_Packet_Relay<ACE_SYNCH_USE>::~Bounded_Packet_Relay (void) +{ +} + +// Requests output be sent to output device. + +template <ACE_SYNCH_DECL> int +Bounded_Packet_Relay<ACE_SYNCH_USE>::send_input (void) +{ + // Don't block, return immediately if queue is empty. + ACE_Message_Block *item; + + // Using a separate (non-const) time value + // is necessary on some platforms + ACE_Time_Value immediate (ACE_Time_Value::zero); + + if (queue_.dequeue_head (item, + &immediate) < 0) + return 1; + + // If a message block was dequeued, send it to the output device. + + if (output_wrapper_->write_output_message ((void *) item) < 0) + ACE_ERROR_RETURN ((LM_ERROR, + "%t %p\n", + "failed to write to output device object"), + -1); + // If all went OK, increase count of packets sent. + ++packets_sent_; + return 0; +} + +// Requests a transmission be started. + +template <ACE_SYNCH_DECL> int +Bounded_Packet_Relay<ACE_SYNCH_USE>::start_transmission (u_long packet_count, + u_long arrival_period, + u_long logging_level) +{ + // Serialize access to start and end transmission calls, statistics + // reporting calls. + ACE_GUARD_RETURN (ACE_SYNCH_MUTEX_T, ace_mon, this->transmission_lock_, -1); + + // If a transmission is already in progress, just return. + if (status_ == STARTED) + return 1; + + // Update statistics for a new transmission. + ++transmission_number_; + packets_sent_ = 0; + status_ = STARTED; + transmission_start_ = ACE_OS::gettimeofday (); + + // Initialize the output device. + if (output_wrapper_->modify_device_settings ((void *) &logging_level) < 0) + { + status_ = ERROR_DETECTED; + transmission_end_ = ACE_OS::gettimeofday (); + ACE_ERROR_RETURN ((LM_ERROR, "%t %p\n", + "failed to initialize output device object"), + -1); + } + + // Initialize the input device. + if (input_wrapper_->set_input_period (arrival_period) < 0) + { + status_ = ERROR_DETECTED; + transmission_end_ = ACE_OS::gettimeofday (); + ACE_ERROR_RETURN ((LM_ERROR, "%t %p\n", + "failed to initialize input device object"), + -1); + } + if (input_wrapper_->set_send_count (packet_count) < 0) + { + status_ = ERROR_DETECTED; + transmission_end_ = ACE_OS::gettimeofday (); + ACE_ERROR_RETURN ((LM_ERROR, "%t %p\n", + "failed to initialize input device object"), + -1); + } + + // Activate the input device. + if (input_wrapper_->activate () < 0) + { + status_ = ERROR_DETECTED; + transmission_end_ = ACE_OS::gettimeofday (); + ACE_ERROR_RETURN ((LM_ERROR, "%t %p\n", + "failed to activate input device object"), + -1); + } + + // If all went well, print a startup message and return success. + ACE_DEBUG ((LM_DEBUG, + "\n\nTransmission %u started\n\n", + transmission_number_)); + return 0; +} + +// Requests a transmission be ended. + +template <ACE_SYNCH_DECL> int +Bounded_Packet_Relay<ACE_SYNCH_USE>::end_transmission (Transmission_Status status) +{ + // Serialize access to start and end transmission calls, + // statistics reporting calls. + ACE_GUARD_RETURN (ACE_SYNCH_MUTEX_T, ace_mon, this->transmission_lock_, -1); + + // If a transmission is not already in progress, just return. + if (status_ != STARTED) + return 1; + + // Ask the the input thread to stop. + if (input_wrapper_->request_stop () < 0) + { + status_ = ERROR_DETECTED; + transmission_end_ = ACE_OS::gettimeofday (); + ACE_ERROR_RETURN ((LM_ERROR, "%t %p\n", + "failed asking input device thread to stop"), + -1); + } + + // Deactivate the queue, allowing all waiting threads to continue. + queue_.deactivate (); + + // Wait for input thread to stop. + if (input_task_mgr_->wait_task (input_wrapper_) < 0) + { + status_ = ERROR_DETECTED; + transmission_end_ = ACE_OS::gettimeofday (); + ACE_ERROR_RETURN ((LM_ERROR, "%t %p\n", + "failed waiting for input device thread to stop"), + -1); + } + + // Reactivate the queue, and then clear it. + queue_.activate (); + while (! queue_.is_empty ()) + { + ACE_Message_Block *msg; + queue_.dequeue_head (msg); + delete msg; + } + + // If all went well, set passed status, stamp end time, + // print a termination message, and return success. + status_ = status; + transmission_end_ = ACE_OS::gettimeofday (); + ACE_DEBUG ((LM_DEBUG, + "\n\nTransmission %u ended with status: %s\n\n", + transmission_number_, status_msg ())); + + return 0; +} + +// Requests a report of statistics from the last transmission. + +template <ACE_SYNCH_DECL> int +Bounded_Packet_Relay<ACE_SYNCH_USE>::report_statistics (void) +{ + // Serialize access to start and end transmission calls, + // statistics reporting calls. + ACE_GUARD_RETURN (ACE_SYNCH_MUTEX_T, ace_mon, this->transmission_lock_, -1); + + // If a transmission is already in progress, just return. + if (status_ == STARTED) + return 1; + + // Calculate duration of trasmission. + ACE_Time_Value duration (transmission_end_); + duration -= transmission_start_; + + // Report transmission statistics. + ACE_DEBUG ((LM_DEBUG, + "\n\nStatisics for transmission %u:\n\n" + "Transmission status: %s\n" + "Start time: %d (sec) %d (usec)\n" + "End time: %d (sec) %d (usec)\n" + "Duration: %d (sec) %d (usec)\n" + "Packets relayed: %u\n\n", + transmission_number_, status_msg (), + transmission_start_.sec (), + transmission_start_.usec (), + transmission_end_.sec (), + transmission_end_.usec (), + duration.sec (), + duration.usec (), + packets_sent_)); + return 0; +} + +// Public entry point to which to push input. + +template <ACE_SYNCH_DECL> int +Bounded_Packet_Relay<ACE_SYNCH_USE>::receive_input (void * arg) +{ + ACE_Message_Block *message = ACE_static_cast (ACE_Message_Block *, + arg); + if (queue_.enqueue_tail (message) < 0) + ACE_ERROR_RETURN ((LM_ERROR, "%t %p\n", + "Bounded_Packet_Relay<ACE_SYNCH_USE>::receive_input failed"), + -1); + return 0; +} + + +// Returns string corresponding to current status. + +template <ACE_SYNCH_DECL> const char * +Bounded_Packet_Relay<ACE_SYNCH_USE>::status_msg () +{ + const char *status_msg; + switch (status_) + { + case UN_INITIALIZED: + status_msg = "uninitialized"; + break; + case STARTED: + status_msg = "in progress"; + break; + case COMPLETED: + status_msg = "completed with all packets sent"; + break; + case TIMED_OUT: + status_msg = "terminated by transmission duration timer"; + break; + case CANCELLED: + status_msg = "cancelled by external control"; + break; + case ERROR_DETECTED: + status_msg = "error was detected"; + break; + default: + status_msg = "unknown transmission status"; + break; + } + + return status_msg; +} + +// Constructor. + +template <class TQ> +Bounded_Packet_Relay_Driver<TQ>::Bounded_Packet_Relay_Driver (void) + : packet_count_ (1000), + arrival_period_ (500), + send_period_ (1000), + duration_limit_ (1500000), + logging_level_ (0) +{ +} + +// Parse the input and execute the corresponding command. + +template <class TQ> int +Bounded_Packet_Relay_Driver<TQ>::parse_commands (const char *buf) +{ + int option; + + if (::sscanf (buf, "%d", &option) <= 0) + // If there was an error reading the option simply try on the next + // line. + return 0; + + switch (option) + { + case 1: // set packet count + { + u_long count; + + // We just reread the option, this simplies parsing (since + // sscanf can do it for us). + if (::sscanf (buf, "%d %lu", &option, &count) < 2) + // If there was not enough information on the line, ignore + // option and try the next line. + return 0; + if (packet_count_cmd_->execute ((void *) &count) == -1) + ACE_ERROR_RETURN ((LM_ERROR, + "%t %p\n", + "set packet count failed"), + -1); + break; + } + case 2: // Set the arrival period. + { + u_long usec; + + // We just reread the option, this simplies parsing (since + // sscanf can do it for us). + if (::sscanf (buf, "%d %lu", &option, &usec) < 2) + // If there was not enough information on the line, ignore + // option and try the next line. + return 0; + if (arrival_period_cmd_->execute ((void *) &usec) == -1) + ACE_ERROR_RETURN ((LM_ERROR, + "%t %p\n", + "set arrival period failed"), + -1); + break; + } + case 3: // Set transmit period. + { + u_long usec; + + // We just reread the option, this simplies parsing (since + // sscanf can do it for us). + if (::sscanf (buf, "%d %lu", &option, &usec) < 2) + // If there was not enough information on the line, ignore + // option and try the next line. + return 0; + if (transmit_period_cmd_->execute ((void *) &usec) == -1) + ACE_ERROR_RETURN ((LM_ERROR, + "%t %p\n", + "set transmit period failed"), + -1); + break; + } + case 4: // Set duration limit. + { + u_long usec; + + // We just reread the option, this simplies parsing (since + // sscanf can do it for us). + if (::sscanf (buf, "%d %lu", &option, &usec) < 2) + // If there was not enough information on the line, ignore + // option and try the next line. + return 0; + if (duration_limit_cmd_->execute ((void *) &usec) == -1) + ACE_ERROR_RETURN ((LM_ERROR, + "%t %p\n", + "set duration limit failed"), + -1); + break; + } + case 5: // Set logging level. + { + u_long level; + + // We just reread the option, this simplies parsing (since + // sscanf can do it for us). + if (::sscanf (buf, "%d %lu", &option, &level) < 2) + // If there was not enough information on the line, ignore + // option and try the next line. + return 0; + if (logging_level_cmd_->execute ((void *) &level) == -1) + ACE_ERROR_RETURN ((LM_ERROR, + "%t %p\n", + "set logging level failed"), + -1); + break; + } + case 6: // Run one transmission. + return run_transmission_cmd_->execute (0); + /* NOTREACHED */ + case 7: // Cancel current transmission. + return cancel_transmission_cmd_->execute (0); + /* NOTREACHED */ + case 8: // Report statistics. + return report_stats_cmd_->execute (0); + /* NOTREACHED */ + case 9: // Shut down the driver. + return shutdown_cmd_->execute (0); + /* NOTREACHED */ + default: + // Display an error message. + ACE_ERROR_RETURN ((LM_ERROR, "invalid input %s\n", buf), 0); + ACE_NOTREACHED (break); + /* NOTREACHED */ + } /* ENDSWITCH */ + return 0; +} + +// Runs the test. + +template <class TQ> int +Bounded_Packet_Relay_Driver<TQ>::run (void) +{ + this->init (); + + // Process all the incoming events. + + for (;;) + if (this->get_next_request () == -1) + return -1; + + ACE_NOTREACHED (return 0); +} + +// Gets the next request from the user input. + +template <class TQ> int +Bounded_Packet_Relay_Driver<TQ>::get_next_request (void) +{ + char buf[BUFSIZ]; + + this->display_menu (); + + ACE_DEBUG ((LM_DEBUG, + "Please enter your choice: ")); + + // Reads input from the user. + if (this->read_input (buf, sizeof buf) <= 0) + return -1; + + // Parse and run the command. + return this->parse_commands (buf); +} + +// Reads input from the user from ACE_STDIN into the buffer specified. + +template <class TQ> ssize_t +Bounded_Packet_Relay_Driver<TQ>::read_input (char *buf, size_t bufsiz) +{ + ACE_OS::memset (buf, 0, bufsiz); + + // Wait for user to type commands. This call is automatically + // restarted when SIGINT or SIGALRM signals occur. + return ACE_OS::read (ACE_STDIN, buf, bufsiz); +} + + +// Get count of packets to send in a transmission. + +template <class TQ> u_long +Bounded_Packet_Relay_Driver<TQ>::packet_count (void) +{ + return packet_count_; +} + +// Set count of packets to send in a transmission. + +template <class TQ> void +Bounded_Packet_Relay_Driver<TQ>::packet_count (u_long pc) +{ + packet_count_ = pc; +} + +// Get rate at which input packets are to arrive. + +template <class TQ> u_long +Bounded_Packet_Relay_Driver<TQ>::arrival_period (void) +{ + return arrival_period_; +} + +// Set rate at which input packets are to arrive. + +template <class TQ> void +Bounded_Packet_Relay_Driver<TQ>::arrival_period (u_long ap) +{ + arrival_period_ = ap; +} + +// Get rate at which packets are to be relayed (usec). + +template <class TQ> u_long +Bounded_Packet_Relay_Driver<TQ>::send_period (void) +{ + return send_period_; +} + +// Set rate at which packets are to be relayed (usec). + +template <class TQ> void +Bounded_Packet_Relay_Driver<TQ>::send_period (u_long sp) +{ + send_period_ = sp; +} + +// Get limit on the duration of the transmission (usec). + +template <class TQ> u_long +Bounded_Packet_Relay_Driver<TQ>::duration_limit (void) +{ + return duration_limit_; +} + +// Set limit on the duration of the transmission (usec). + +template <class TQ> void +Bounded_Packet_Relay_Driver<TQ>::duration_limit (u_long dl) +{ + duration_limit_ = dl; +} +// Get logging level. + +template <class TQ> u_long +Bounded_Packet_Relay_Driver<TQ>::logging_level (void) +{ + return logging_level_; +} + +// Set logging level. + +template <class TQ> void +Bounded_Packet_Relay_Driver<TQ>::logging_level (u_long ll) +{ + logging_level_ = ll; +} +#endif /* _BPR_DRIVER_T_CPP_ */ + + diff --git a/examples/Bounded_Packet_Relay/BPR_Drivers_T.h b/examples/Bounded_Packet_Relay/BPR_Drivers_T.h new file mode 100644 index 00000000000..e8f85543689 --- /dev/null +++ b/examples/Bounded_Packet_Relay/BPR_Drivers_T.h @@ -0,0 +1,295 @@ +/* -*- C++ -*- */ +// $Id$ + +// ============================================================================ +// +// = LIBRARY +// examples +// +// = FILENAME +// BPR_Drivers_T.h +// +// = DESCRIPTION +// This code factors out common class templates for use in +// the different possible implementations of the Timer_Queue +// based bounded packet relay example. +// +// = AUTHORS +// Chris Gill <cdgill@cs.wustl.edu> and +// Douglas C. Schmidt <schmidt@cs.wustl.edu> +// +// Based on the Timer Queue Test example written by +// +// Carlos O'Ryan <coryan@cs.wustl.edu> and +// Douglas C. Schmidt <schmidt@cs.wustl.edu> and +// Sergio Flores-Gaitan <sergio@cs.wustl.edu> +// +// ============================================================================ + +#if !defined (_BPR_DRIVERS_T_H_) +#define _BPR_DRIVERS_T_H_ + +// forward declarations +class Input_Device_Wrapper_Base; +class Output_Device_Wrapper_Base; + +template <class RECEIVER, class ACTION> +class Command : public Command_Base +{ + // = TITLE + // Defines an abstract class that allows us to invoke commands + // without knowing anything about the implementation. This class + // is used in the <Bounded_Packet_Relay_Driver> to invoke + // operations of the driver. + // + // = DESCRIPTION + // This class declares an interface to execute operations, + // binding a RECEIVER object with an ACTION. The RECEIVER knows + // how to implement the operation. A class can invoke operations + // without knowing anything about it, or how it was implemented. +public: + Command (RECEIVER &recvr, ACTION action); + // Sets the <receiver_> of the Command to recvr, and the <action_> + // of the Command to <action>. + + virtual int execute (void *arg); + // Invokes the method <action_> from the object <receiver_>. + +private: + RECEIVER &receiver_; + // Object where the method resides. + + ACTION action_; + // Method that is going to be invoked. +}; + + +template <ACE_SYNCH_DECL> +class Bounded_Packet_Relay : public Bounded_Packet_Relay_Base +{ + // = TITLE + // This class defines a packet relay abstraction for a + // transmission bounded external commands to start and end the + // transmission. The transmission may be bounded by the number + // of packets to send, the dration of the transmission, or any + // other factors. + // + // = DESCRIPTION + // The relay abstraction implemented by this class registers a + // callback command with an input device wrapper, and relays + // input to an output device at a pace specified in the start + // transmission call. +public: + + typedef int (Bounded_Packet_Relay<ACE_SYNCH_USE>::*ACTION) (void *); + // Command entry point type definition. + + // = Initialization method + + Bounded_Packet_Relay (ACE_Thread_Manager *input_task_mgr, + Input_Device_Wrapper_Base *input_wrapper, + Output_Device_Wrapper_Base *output_wrapper); + // Constructor. + + virtual ~Bounded_Packet_Relay (void); + // Destructor. + + int send_input (void); + // Requests output be sent to output device. + + int start_transmission (u_long packet_count, + u_long arrival_period, + u_long logging_level); + // Requests a transmission be started. + + int end_transmission (Transmission_Status status); + // Requests a transmission be ended. + + int report_statistics (void); + // Requests a report of statistics from the last transmission. + + // = Command Accessible Entry Points. + + int receive_input (void *); + // Public entry point to which to push input. + +private: + // = Concurrency Management. + + ACE_Thread_Manager * input_task_mgr_; + // Thread manager for the input device task. + + Input_Device_Wrapper_Base * input_wrapper_; + // Pointer to the input device wrapper. + + Output_Device_Wrapper_Base * output_wrapper_; + // Pointer to the output device wrapper. + + ACE_Message_Queue<ACE_SYNCH_USE> queue_; + // Queue used to buffer input messages. + + ACE_SYNCH_MUTEX_T transmission_lock_; + // Lock for thread-safe synchronization + // of transmission startup and termination. + + // = Transmission Statistics + + const char * status_msg (void); + // Returns string corresponding to current status. + + u_long transmission_number_; + // Number of transmissions sent. + + u_long packets_sent_; + // Count of packets sent in the most recent transmission. + + Transmission_Status status_; + // Status of the current or most recent transmission. + + ACE_Time_Value transmission_start_; + // Start time of the most recent transmission. + + ACE_Time_Value transmission_end_; + // Ending time of the most recent transmission. + +}; + + +template <class TQ> +class Bounded_Packet_Relay_Driver +{ + // = TITLE + // This abstract base class provides a simple abstraction for a + // test driver for the bounded packet relay example. + // + // = DESCRIPTION + // This is the place where the common code to test the different + // implementations of the timer queue resides. This class has + // the logic for the parse_commands () method, the run (), + // read_input () and get_next_request () methods. Subclasses can + // override these methods if there is some logic that is specific + // to that implementation. +public: + + Bounded_Packet_Relay_Driver (void); + // Constructor. + + virtual int parse_commands (const char *buf); + // Breaks up the input string buffer into pieces and executes the + // appropriate method to handle that operation. + + virtual int run (void); + // This is the main entry point for the driver. The user of the + // class should normally invoke this method. Returns 0 when + // successful, or 0 otherwise. + + virtual int get_next_request (void); + // This internal method gets the next request from the user. + // Returns -1 when user wants to exit. Returns 0 otherwise. + + virtual ssize_t read_input (char *buf, size_t bufsiz); + // Reads input from the user into the buffer <buf> with a maximum of + // <bufsiz> bytes. Returns the amount of bytes actually read + // Otherwise, a -1 is returned and errno is set to indicate the + // error. + + virtual int display_menu (void)=0; + // Prints the user interface for the driver to STDERR. + + virtual int init (void)=0; + // Initializes values and operations for the driver. + + u_long packet_count (void); + // Get count of packets to send in a transmission. + + void packet_count (u_long pc); + // Set count of packets to send in a transmission. + + u_long arrival_period (void); + // Get rate at which input packets are to arrive. + + void arrival_period (u_long ap); + // Set rate at which input packets are to arrive. + + u_long send_period (void); + // Get rate at which packets are to be relayed (usec). + + void send_period (u_long sp); + // Set rate at which packets are to be relayed (usec). + + u_long duration_limit (void); + // Get limit on the duration of the transmission (usec). + + void duration_limit (u_long dl); + // Set limit on the duration of the transmission (usec). + + u_long logging_level (void); + // Get logging level. + + void logging_level (u_long ll); + // Set logging level. + +protected: + // = Major Driver Mechanisms + + TQ timer_queue_; + // Timer queue for transmission timeouts. + + // = Set of <Command>s to be executed. + + Command_Base *packet_count_cmd_; + // Set packet count command. + + Command_Base *arrival_period_cmd_; + // Set arrival period command. + + Command_Base *transmit_period_cmd_; + // Set transmit period command. + + Command_Base *duration_limit_cmd_; + // Set duration limit command. + + Command_Base *logging_level_cmd_; + // Set logging level command. + + Command_Base *run_transmission_cmd_; + // Run transmission command. + + Command_Base *cancel_transmission_cmd_; + // Cancel transmission command. + + Command_Base *report_stats_cmd_; + // Report statistics command. + + Command_Base *shutdown_cmd_; + // Shut down the driver. + +private: + + u_long packet_count_; + // Count of packets to send in a transmission. + + u_long arrival_period_; + // Rate at which input packets are to arrive. + + u_long send_period_; + // Rate at which packets are to be relayed (usec). + + u_long duration_limit_; + // Limit on the duration of the transmission (usec). + + u_long logging_level_; + // Logging level. + +}; + +#if defined (ACE_TEMPLATES_REQUIRE_SOURCE) +#include "BPR_Drivers_T.cpp" +#endif /* ACE_TEMPLATES_REQUIRE_SOURCE */ + +#if defined (ACE_TEMPLATES_REQUIRE_PRAGMA) +#pragma implementation ("BPR_Drivers_T.cpp") +#endif /* ACE_TEMPLATES_REQUIRE_PRAGMA */ + +#endif /* _BPR_DRIVERS_T_H_ */ + diff --git a/examples/Bounded_Packet_Relay/Thread_Bounded_Packet_Relay.cpp b/examples/Bounded_Packet_Relay/Thread_Bounded_Packet_Relay.cpp index 006ad251991..4585f515630 100644 --- a/examples/Bounded_Packet_Relay/Thread_Bounded_Packet_Relay.cpp +++ b/examples/Bounded_Packet_Relay/Thread_Bounded_Packet_Relay.cpp @@ -34,24 +34,6 @@ ACE_RCSID(Bounded_Packet_Relay, Thread_Bounded_Packet_Relay, "$Id$") // Constructor. -template <class RECEIVER, class ACTION> -Command<RECEIVER, ACTION>::Command (RECEIVER &recvr, - ACTION action) - : receiver_ (recvr), - action_ (action) -{ -} - -// Invokes an operation. - -template <class RECEIVER, class ACTION> int -Command<RECEIVER, ACTION>::execute (void *arg) -{ - return (receiver_.*action_) (arg); -} - -// Constructor. - Text_Input_Device_Wrapper::Text_Input_Device_Wrapper (ACE_Thread_Manager *input_task_mgr, size_t read_length, const char* text) @@ -119,18 +101,19 @@ Text_Output_Device_Wrapper::write_output_message (void *message) if (message) { if (logging_) - { -// CDG - TBD - print (also fix other printfs to use ACE_DEBUG, ACE_ERROR) -// ACE_DEBUG (); - } + { + ACE_DEBUG ((LM_DEBUG, "%s", + ACE_static_cast (ACE_Message_Block *, message)-> + rd_ptr ())); + } delete ACE_static_cast (ACE_Message_Block *, message); + return 0; } ACE_ERROR_RETURN ((LM_ERROR, "Text_Output_Device_Wrapper::" "write_output_message: null argument"), -1); - return 0; } // Modifies device settings based on passed pointer to a u_long turns @@ -146,6 +129,7 @@ Text_Output_Device_Wrapper::modify_device_settings (void *logging) ACE_ERROR_RETURN ((LM_ERROR, "null logging level pointer"), -1); + return 0; } // Constructor. @@ -176,7 +160,7 @@ User_Input_Task::svc (void) this->relay_->end_transmission (Bounded_Packet_Relay_Base::CANCELLED); this->queue_->deactivate (); ACE_DEBUG ((LM_DEBUG, - "terminating input thread\n")); + "terminating user input thread\n")); return 0; } @@ -187,7 +171,7 @@ User_Input_Task::set_packet_count (void *argument) { if (argument) { - packet_count_ = *ACE_static_cast (int *, argument); + driver_.packet_count (*ACE_static_cast (int *, argument)); return 0; } ACE_ERROR_RETURN ((LM_ERROR, @@ -203,7 +187,7 @@ User_Input_Task::set_arrival_period (void *argument) { if (argument) { - arrival_period_ = *ACE_static_cast (int *, argument); + driver_.arrival_period (*ACE_static_cast (int *, argument)); return 0; } ACE_ERROR_RETURN ((LM_ERROR, @@ -219,7 +203,7 @@ User_Input_Task::set_send_period (void *argument) { if (argument) { - send_period_ = *ACE_static_cast (int *, argument); + driver_.send_period (*ACE_static_cast (int *, argument)); return 0; } ACE_ERROR_RETURN ((LM_ERROR, @@ -234,7 +218,7 @@ User_Input_Task::set_duration_limit (void *argument) { if (argument) { - duration_limit_ = *ACE_static_cast (int *, argument); + driver_.duration_limit (*ACE_static_cast (int *, argument)); return 0; } ACE_ERROR_RETURN ((LM_ERROR, @@ -250,7 +234,7 @@ User_Input_Task::set_logging_level (void *argument) { if (argument) { - logging_level_ = *ACE_static_cast (int *, argument); + driver_.logging_level (*ACE_static_cast (int *, argument)); return 0; } ACE_ERROR_RETURN ((LM_ERROR, @@ -265,9 +249,9 @@ User_Input_Task::run_transmission (void *) { if (relay_) { - switch (relay_->start_transmission (packet_count_, - arrival_period_, - logging_level_)) + switch (relay_->start_transmission (driver_.packet_count (), + driver_.arrival_period (), + driver_.logging_level ())) { case 1: ACE_DEBUG ((LM_DEBUG, @@ -278,12 +262,12 @@ User_Input_Task::run_transmission (void *) case 0: { ACE_Time_Value now = ACE_OS::gettimeofday (); - ACE_Time_Value send_every (0, send_period_); + ACE_Time_Value send_every (0, driver_.send_period ()); ACE_Time_Value send_at (send_every + now); Send_Handler *send_handler; ACE_NEW_RETURN (send_handler, - Send_Handler (packet_count_, + Send_Handler (driver_.packet_count (), send_every, *relay_, *queue_), @@ -293,9 +277,9 @@ User_Input_Task::run_transmission (void *) "User_Input_Task::run_transmission: " "failed to schedule send handler"), -1); - if (duration_limit_) + if (driver_.duration_limit ()) { - ACE_Time_Value terminate_at (0, duration_limit_); + ACE_Time_Value terminate_at (0, driver_.duration_limit ()); terminate_at += now; Termination_Handler *termination_handler; @@ -573,23 +557,31 @@ Thread_Bounded_Packet_Relay_Driver::display_menu (void) { static char menu[] = "\n\n Options:\n" - " -------\n" - " 1 <number of packets to relay in one transmission>\n" - " min = 1 packet, default = 1000.\n" - " 2 <input packet arrival period (in usec)>\n" - " min = 1, default = 500.\n" - " 3 <output packet transmission period (in usec)>\n" - " min = 1, default = 1000.\n" - " 4 <limit on duration of transmission (in usec)>\n" - " min = 1, default = 1500000, no limit = 0.\n" - " 5 <logging level>\n" - " no logging = 0 (default), logging = 1.\n" + " ----------------------------------------------------------------------\n" + " 1 <number of packets to relay in one transmission = %d>\n" + " min = 1 packet.\n" + " 2 <input packet arrival period (in usec) = %d>\n" + " min = 1.\n" + " 3 <output packet transmission period (in usec) = %d>\n" + " min = 1.\n" + " 4 <limit on duration of transmission (in usec) = %d>\n" + " min = 1, no limit = 0.\n" + " 5 <logging level = %d>\n" + " no logging = 0, logging = non-zero.\n" + " ----------------------------------------------------------------------\n" " 6 - run a transmission using the current settings\n" " 7 - cancel transmission (if there is one running)\n" " 8 - report statistics from the most recent transmission\n" - " 9 - quit the program\n"; - - ACE_DEBUG ((LM_DEBUG, "%s", menu)); + " 9 - quit the program\n" + " ----------------------------------------------------------------------\n"; + + ACE_DEBUG ((LM_DEBUG, + menu, + this->packet_count (), + this->arrival_period (), + this->send_period (), + this->duration_limit (), + this->logging_level ())); return 0; } diff --git a/examples/Bounded_Packet_Relay/Thread_Bounded_Packet_Relay.h b/examples/Bounded_Packet_Relay/Thread_Bounded_Packet_Relay.h index 1347b44c96e..d7c63f0e4c6 100644 --- a/examples/Bounded_Packet_Relay/Thread_Bounded_Packet_Relay.h +++ b/examples/Bounded_Packet_Relay/Thread_Bounded_Packet_Relay.h @@ -51,36 +51,6 @@ typedef ACE_Thread_Timer_Queue_Adapter<Timer_Heap> // Forward declaration. class Thread_Bounded_Packet_Relay_Driver; -template <class RECEIVER, class ACTION> -class Command : public Command_Base -{ - // = TITLE - // Defines an abstract class that allows us to invoke commands - // without knowing anything about the implementation. This class - // is used in the <Bounded_Packet_Relay_Driver> to invoke - // operations of the driver. - // - // = DESCRIPTION - // This class declares an interface to execute operations, - // binding a RECEIVER object with an ACTION. The RECEIVER knows - // how to implement the operation. A class can invoke operations - // without knowing anything about it, or how it was implemented. -public: - Command (RECEIVER &recvr, ACTION action); - // Sets the <receiver_> of the Command to recvr, and the <action_> - // of the Command to <action>. - - virtual int execute (void *arg); - // Invokes the method <action_> from the object <receiver_>. - -private: - RECEIVER &receiver_; - // Object where the method resides. - - ACTION action_; - // Method that is going to be invoked. -}; - class Text_Input_Device_Wrapper : public Input_Device_Wrapper_Base { // = TITLE @@ -223,21 +193,6 @@ private: Thread_Bounded_Packet_Relay_Driver &driver_; // The thread timer queue test driver. - u_long packet_count_; - // Count of packets to send in a transmission. - - u_long arrival_period_; - // Rate at which input packets are to arrive. - - u_long send_period_; - // Rate at which packets are to be relayed (usec). - - u_long duration_limit_; - // Limit on the duration of the transmission (usec). - - u_long logging_level_; - // Logging level. - }; class BPR_Handler_Base : public ACE_Event_Handler diff --git a/examples/Bounded_Packet_Relay/bpr_thread.cpp b/examples/Bounded_Packet_Relay/bpr_thread.cpp index bc9f5c4d464..d5982c14d86 100644 --- a/examples/Bounded_Packet_Relay/bpr_thread.cpp +++ b/examples/Bounded_Packet_Relay/bpr_thread.cpp @@ -34,6 +34,9 @@ typedef Bounded_Packet_Relay_Driver<Thread_Timer_Queue> typedef Bounded_Packet_Relay<ACE_MT_SYNCH> BOUNDED_PACKET_RELAY; +typedef Command<BOUNDED_PACKET_RELAY, BOUNDED_PACKET_RELAY::ACTION> + INPUT_CALLBACK; + // A snippet from Andrew Marvell (Oliver Cromwell's poet laureate) static const char input_text [] = "But ever at my back I hear\n" @@ -78,6 +81,22 @@ main (int, char *[]) -1); auto_ptr <BOUNDED_PACKET_RELAY> relay (packet_relay); + // Construct a receive input callback command for the relay, and register + // it with the input device. Auto ptr ensures memory is freed when we exit + // this scope. + INPUT_CALLBACK *input_callback; + ACE_NEW_RETURN (input_callback, + INPUT_CALLBACK (*packet_relay, + &BOUNDED_PACKET_RELAY::receive_input), + -1); + auto_ptr <INPUT_CALLBACK> callback (input_callback); + if (input_device->set_send_input_msg_cmd (input_callback) < 0) + { + ACE_ERROR_RETURN ((LM_ERROR, + "failed to register input callback"), + -1); + } + // Construct a new bounded packet relay driver. Auto ptr ensures // memory is freed when we exit this scope. THREAD_BOUNDED_PACKET_RELAY_DRIVER *tbprd; |