1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288
|
/* -*- C++ -*- */
//=============================================================================
/**
* @file BPR_Drivers.h
*
* $Id: BPR_Drivers.h 93639 2011-03-24 13:32:13Z johnnyw $
*
* This code builds abstractions to factor out common code from
* the different possible implementations of the Timer_Queue based
* bounded packet relay example.
*
*
* @author 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>
*/
//=============================================================================
#ifndef _BPR_DRIVERS_H_
#define _BPR_DRIVERS_H_
#include "ace/Functor.h"
#if !defined (ACE_LACKS_PRAGMA_ONCE)
# pragma once
#endif /* ACE_LACKS_PRAGMA_ONCE */
#include "ace/Reactor.h"
#include "ace/Task.h"
// forward declarations
class Input_Device_Wrapper_Base;
class Output_Device_Wrapper_Base;
/**
* @class Bounded_Packet_Relay
*
* @brief 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.
*
* 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.
*/
class Bounded_Packet_Relay
{
public:
// = Enumerates possible status values for a transmission.
enum Transmission_Status
{
UN_INITIALIZED,
STARTED,
COMPLETED,
TIMED_OUT,
CANCELLED,
ERROR_DETECTED
};
enum Queue_Defaults
{
DEFAULT_HWM = 0x7FFFFFFF,
DEFAULT_LWM = 0x7FFFFFFF
};
/// Command entry point type definition.
typedef int (Bounded_Packet_Relay::*ACTION) (void *);
// = Initialization method
/// Constructor.
Bounded_Packet_Relay (ACE_Thread_Manager *input_task_mgr,
Input_Device_Wrapper_Base *input_wrapper,
Output_Device_Wrapper_Base *output_wrapper);
/// Destructor.
virtual ~Bounded_Packet_Relay (void);
/// Requests output be sent to output device.
int send_input (void);
/// Requests a transmission be started.
int start_transmission (u_long packet_count,
u_long arrival_period,
int logging_level);
/// Requests a transmission be ended.
int end_transmission (Transmission_Status status);
/// Requests a report of statistics from the last transmission.
int report_statistics (void);
// = Command accessible entry points.
/// Public entry point to which to push input.
int receive_input (void *);
// = Accessors and mutators for relay settings
/// Get high water mark for relay queue.
ACE_UINT32 queue_hwm (void);
/// Set high water mark for relay queue.
void queue_hwm (ACE_UINT32 hwm);
/// Get low water mark for relay queue.
ACE_UINT32 queue_lwm (void);
/// Set low water mark for relay queue.
void queue_lwm (ACE_UINT32 lwm);
private:
// = Concurrency Management.
/// flag for whether or not a transmission is active
int is_active_;
/// Thread manager for the input device task.
ACE_Thread_Manager * input_task_mgr_;
/// Pointer to the input device wrapper.
Input_Device_Wrapper_Base * input_wrapper_;
/// Pointer to the output device wrapper.
Output_Device_Wrapper_Base * output_wrapper_;
/// Queue used to buffer input messages.
ACE_Message_Queue<ACE_SYNCH> queue_;
/// High water mark for relay queue.
ACE_UINT32 queue_hwm_;
/// Low water mark for relay queue.
ACE_UINT32 queue_lwm_;
/// Lock for thread-safe synchronization of transmission startup and
/// termination.
ACE_SYNCH_MUTEX transmission_lock_;
// = Transmission Statistics
/// Returns string corresponding to current status.
const char *status_msg (void);
/// Number of transmissions sent.
u_long transmission_number_;
/// Count of packets sent in the most recent transmission.
u_long packets_sent_;
/// Status of the current or most recent transmission.
Transmission_Status status_;
/// Start time of the most recent transmission.
ACE_Time_Value transmission_start_;
/// Ending time of the most recent transmission.
ACE_Time_Value transmission_end_;
};
/**
* @class Input_Device_Wrapper_Base
*
* @brief This class defines an abstract base class for an input device
* wrapper that hides the details of the specific device and
* provides a consistent message passing interface without
* knowing anything about the implementation of the input device
* or the message receiver.
* The abstract base class ctor takes a command template object
* that is instantiated with the correct receiver and action
* types. This command object is used to send newly created input
* messages to the receiver.
* The abstract base class is designed to operate in an active
* "push" mode, sending input data to the receiver whenever the
* data is ready. The underlying device may be active, notifying
* the wrapper when data is ready, or may be passive in which
* case the wrapper must rely on a reactive and/or polling
* mechanism.
*
* Derived classes are responsible for filling in concrete
* definitions for the abstract message creation method and the
* svc method.
*/
class Input_Device_Wrapper_Base : public ACE_Task_Base
{
public:
// = Initialization and termination methods.
/// Constructor.
Input_Device_Wrapper_Base (ACE_Thread_Manager *input_task_mgr);
/// Destructor.
virtual ~Input_Device_Wrapper_Base ();
/// Sets send input message command in the input device driver
/// object.
int set_send_input_msg_cmd (ACE_Command_Base *send_input_msg_cmd);
/// Sets period (in usecs) between when inputs are created.
int set_input_period (u_long input_period);
/// Sets count of messages to send.
int set_send_count (long count);
/**
* Requests that the input device stop sending messages and
* terminate its thread. Should return 1 if it will do so, 0 if it
* has already done so, or -1 if there is a problem doing so.
*/
int request_stop (void);
/// This method runs the input device loop in the new thread.
virtual int svc (void);
/// Provides an abstract interface to allow modifying device
/// settings.
virtual int modify_device_settings (void *) = 0;
protected:
/// Creates a new message block, carrying data read from the
/// underlying input device.
virtual ACE_Message_Block *create_input_message (void) = 0;
/**
* Sends a newly created message block, carrying data read from the
* underlying input device, by passing a pointer to the message
* block to its command execution.
*/
virtual int send_input_message (ACE_Message_Block *);
/// Send newly created input message.
ACE_Command_Base *send_input_msg_cmd_;
/// Period between when input values are produced (usecs).
u_long input_period_;
/// Reactor used to multiplex input streams, timeouts.
ACE_Reactor reactor_;
/// Flag to indicate whether or not input object is
/// (and should remain) active.
int is_active_;
/// Count of messages to send before stopping (-1 indicates the
/// device should not stop).
long send_count_;
/// Currently remaining count of messages to send before stopping
/// (-1 indicates the device should not stop).
long current_count_;
};
/**
* @class Output_Device_Wrapper_Base
*
* @brief This class defines an abstract base class for an output device
* wrapper that hides the details of the specific device and
* provides a consistent write method interface without knowing
* anything about the implementation.
*
* The abstract methods write_output_message () and
* modify_device_settings () are defined in derived classes to
* write the contents of the passed message out the underlying
* output device, and update device settings, respectively.
*/
class Output_Device_Wrapper_Base
{
public:
virtual ~Output_Device_Wrapper_Base (void);
/// Writes contents of the passed message block out to the underlying
/// output device.
virtual int write_output_message (void *) = 0;
/// Provides an abstract interface to allow modifying device
/// settings.
virtual int modify_device_settings (void *) = 0;
};
// include the templates
#include "BPR_Drivers_T.h"
#endif /* _BPR_DRIVERS_H_ */
|