summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorcdgill <cdgill@ae88bc3d-4319-0410-8dbf-d08b4c9d3795>1998-09-21 23:35:56 +0000
committercdgill <cdgill@ae88bc3d-4319-0410-8dbf-d08b4c9d3795>1998-09-21 23:35:56 +0000
commit2c6cfcd0fc9ef621c4cc893eed64d0f670f89371 (patch)
treeb74e8a66c80000cbbca4d502b460d4aceaef41c1
parentea7a5f4c3fbaa4dd4aeac4eff2e6f5166aa129dd (diff)
downloadATCD-2c6cfcd0fc9ef621c4cc893eed64d0f670f89371.tar.gz
testing fixes, factored out templates
-rw-r--r--examples/Bounded_Packet_Relay/BPR_Drivers.cpp407
-rw-r--r--examples/Bounded_Packet_Relay/BPR_Drivers.h189
-rw-r--r--examples/Bounded_Packet_Relay/BPR_Drivers_T.cpp576
-rw-r--r--examples/Bounded_Packet_Relay/BPR_Drivers_T.h295
-rw-r--r--examples/Bounded_Packet_Relay/Thread_Bounded_Packet_Relay.cpp92
-rw-r--r--examples/Bounded_Packet_Relay/Thread_Bounded_Packet_Relay.h45
-rw-r--r--examples/Bounded_Packet_Relay/bpr_thread.cpp19
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;