Public Member Functions | Private Attributes | Static Private Attributes | List of all members
gov::fnal::cd::rms::provider::EpicsMessenger Class Reference

#include "/cvmfs/nova-development.opensciencegrid.org/novasoft/releases/N21-01-18/rms/cxx/include/provider/EpicsMessenger.h"

Public Member Functions

 EpicsMessenger (std::string pvName, struct ca_client_context *caContext, int maxSize, util::UUIDGenerator *uuidGenerator)
 
 ~EpicsMessenger ()
 
std::string getName () const
 
void sendMessage (const std::string &messageText)
 
void addListener (ProviderListener *listener)
 
void removeListener (ProviderListener *listener)
 
void monitorChanged (char *data)
 
void notifyListeners (std::string messageText)
 
void close ()
 

Private Attributes

bool _firstListener
 
struct ca_client_context * _caContext
 
chid _pvChannel
 
evid _pvSubscription
 
std::string _pvName
 
int _maxMessageSize
 
std::vector< ProviderListener * > _listenerList
 
std::vector< MessageAssembler * > _assemblerList
 
util::UUIDGenerator_uuidGenerator
 

Static Private Attributes

static const double _PEND_OP_TIMEOUT = 2.0
 

Detailed Description

This class provides functionality to communicate with EPICS waveform process variables. It automatically splits up messages that are too long into the necessary number of fragments and automatically assembles fragments into messages on input.

Note that this class is NOT thread safe.

Author
Kurt Biery
Steve Foulkes
Version
Revision
1.1.1.1
Date
2009/10/09 20:03:00

Definition at line 46 of file EpicsMessenger.h.

Constructor & Destructor Documentation

gov::fnal::cd::rms::provider::EpicsMessenger::EpicsMessenger ( std::string  pvName,
struct ca_client_context *  caContext,
int  maxSize,
util::UUIDGenerator uuidGenerator 
)

Constructs an instance of this class for the specified EPICS process variable (which is expected to a waveform record).

Parameters
pvNameThe name of the PV to connect to
caContextThe EPICS context
maxSizeThe maximum size of messages that should be posted to the PV
uuidGeneratorA UUID Generator to add UUIDs to messages

Definition at line 40 of file EpicsMessenger.cpp.

References _caContext, _firstListener, _maxMessageSize, _PEND_OP_TIMEOUT, _pvChannel, _pvName, _uuidGenerator, ca_detach_context(), om::cout, allTimeWatchdog::endl, and fillBadChanDBTables::result.

43  {
44  int result;
45 
46  _pvName = pvName;
47  _caContext = caContext;
48  _maxMessageSize = maxSize;
49  _uuidGenerator = uuidGenerator;
50 
51  ca_attach_context(_caContext);
52  ca_create_channel(_pvName.c_str(), NULL, NULL, 10, &_pvChannel);
53  result = ca_pend_io(_PEND_OP_TIMEOUT);
55 
56  if (result != ECA_NORMAL) {
57  std::cout << "Failed to connect to " << pvName;
58  std::cout << " in " << _PEND_OP_TIMEOUT;
59  std::cout << " seconds..." << std::endl;
60  }
61 
62  _firstListener = true;
63 }
void epicsShareAPI ca_detach_context()
OStream cout
Definition: OStream.cxx:6
gov::fnal::cd::rms::provider::EpicsMessenger::~EpicsMessenger ( )

Destructor, just call close() which frees any allocated memory and clears out open channels.

Definition at line 69 of file EpicsMessenger.cpp.

References close().

Member Function Documentation

void gov::fnal::cd::rms::provider::EpicsMessenger::addListener ( ProviderListener listener)

Adds the specified listener to this messenger.

Parameters
listenerThe ProviderListener that will be called when updates to this PV occur.

Definition at line 120 of file EpicsMessenger.cpp.

References _caContext, _firstListener, _listenerList, _PEND_OP_TIMEOUT, _pvChannel, _pvSubscription, ca_detach_context(), gov::fnal::cd::rms::provider::EpicsMessengerCallback(), and MECModelEnuComparisons::i.

Referenced by gov::fnal::cd::rms::provider::EpicsConnection::addListener().

120  {
121  if (_firstListener) {
122  ca_attach_context(_caContext);
123  ca_create_subscription(DBR_CHAR, 0, _pvChannel, DBE_VALUE,
124  EpicsMessengerCallback, (void *)this, &_pvSubscription);
125  ca_pend_io(_PEND_OP_TIMEOUT);
127  _firstListener = false;
128  }
129 
130  for (unsigned int i = 0; i < _listenerList.size(); i++) {
131  if (listener == _listenerList[i]) {
132  return;
133  }
134  }
135 
136  _listenerList.push_back(listener);
137 }
void epicsShareAPI ca_detach_context()
std::vector< ProviderListener * > _listenerList
static void EpicsMessengerCallback(struct event_handler_args eventHandlerArgs)
void gov::fnal::cd::rms::provider::EpicsMessenger::close ( )

Close down all the EPICS connections and free any memory that has been allocated. This includes all assemblers, the channel access subscription and the channel itself.

Definition at line 219 of file EpicsMessenger.cpp.

References _assemblerList, _caContext, _firstListener, _PEND_OP_TIMEOUT, _pvChannel, _pvSubscription, and ca_detach_context().

Referenced by ~EpicsMessenger().

219  {
220  std::vector <MessageAssembler *>::iterator assemblerIterator;
221 
222  ca_attach_context(_caContext);
223 
224  ca_flush_io();
225  ca_pend_io(_PEND_OP_TIMEOUT);
226 
227  if (!_firstListener) {
228  ca_clear_subscription(_pvSubscription);
229  }
230 
231  ca_clear_channel(_pvChannel);
233 
234  assemblerIterator = _assemblerList.begin();
235 
236  while (assemblerIterator != _assemblerList.end()) {
237  delete *assemblerIterator;
238  assemblerIterator++;
239  }
240 }
void epicsShareAPI ca_detach_context()
std::vector< MessageAssembler * > _assemblerList
std::string gov::fnal::cd::rms::provider::EpicsMessenger::getName ( ) const

Get the name of the PV that this class connects to.

Returns
The name of the PV that this class connects to.

Definition at line 78 of file EpicsMessenger.cpp.

References _pvName.

78  {
79  return _pvName;
80 }
void gov::fnal::cd::rms::provider::EpicsMessenger::monitorChanged ( char *  data)

Processes changes to the PV value. This method is called by the static callback function when the PV value changes.

Parameters
dataThe new value of the PV

Definition at line 164 of file EpicsMessenger.cpp.

References _assemblerList, gov::fnal::cd::rms::provider::MessageAssembler::getMessage(), gov::fnal::cd::rms::provider::MessageAssembler::hasCompleteMessage(), MECModelEnuComparisons::i, notifyListeners(), and string.

Referenced by gov::fnal::cd::rms::provider::EpicsMessengerCallback().

164  {
165  std::vector <MessageAssembler *>::iterator i;
166  MessageFragment *fragment = new MessageFragment(data);
167 
168  i = _assemblerList.begin();
169 
170  while (i != _assemblerList.end()) {
171  if ((*i)->addFragment(fragment)) {
172  if ((*i)->hasCompleteMessage()) {
173  std::string messageText = (*i)->getMessage();
174  _assemblerList.erase(i);
175  notifyListeners(messageText);
176  delete *i;
177  }
178 
179  return;
180  }
181  i++;
182  }
183 
184  // Didn't find an assmbler for the message. Make a new one..
185  MessageAssembler *newAssembler = new MessageAssembler(fragment);
186 
187  if (newAssembler->hasCompleteMessage()) {
188  std::string messageText = newAssembler->getMessage();
189  notifyListeners(messageText);
190 
191  delete newAssembler;
192 
193  return;
194  }
195 
196  _assemblerList.push_back(newAssembler);
197 }
std::vector< MessageAssembler * > _assemblerList
const XML_Char const XML_Char * data
Definition: expat.h:268
void notifyListeners(std::string messageText)
enum BeamMode string
void gov::fnal::cd::rms::provider::EpicsMessenger::notifyListeners ( std::string  messageText)

Go through all the listeners that have expressed interest in this PV and post the message to them.

Parameters
messageTextA message to send to all the listeners.

Definition at line 205 of file EpicsMessenger.cpp.

References _listenerList, MECModelEnuComparisons::i, datagram_client::message, and string.

Referenced by monitorChanged().

205  {
206  boost::shared_ptr<std::string> message(new std::string(messageText));
207 
208  for (unsigned int i = 0; i < _listenerList.size(); i++) {
209  _listenerList[i]->textReceived(message);
210  }
211 }
std::vector< ProviderListener * > _listenerList
enum BeamMode string
void gov::fnal::cd::rms::provider::EpicsMessenger::removeListener ( ProviderListener listener)

Removes the specified listener from this messenger.

Parameters
listenerThe listener to remove

Definition at line 144 of file EpicsMessenger.cpp.

References _listenerList, and MECModelEnuComparisons::i.

Referenced by gov::fnal::cd::rms::provider::EpicsConnection::removeListener().

144  {
145  std::vector <ProviderListener *>::iterator i;
146 
147  i = _listenerList.begin();
148 
149  while (i != _listenerList.end()) {
150  if (*i == listener) {
151  _listenerList.erase(i);
152  return;
153  }
154  i++;
155  }
156 }
std::vector< ProviderListener * > _listenerList
void gov::fnal::cd::rms::provider::EpicsMessenger::sendMessage ( const std::string messageText)

Post a message to the PV. This method will split up the message so that it can be reassembled by each process that receives it.

Parameters
messageTextThe message to send

Definition at line 89 of file EpicsMessenger.cpp.

References _caContext, _maxMessageSize, _PEND_OP_TIMEOUT, _pvChannel, _uuidGenerator, ca_detach_context(), gov::fnal::cd::rms::util::UUIDGenerator::getUUID(), MECModelEnuComparisons::i, gen_hdf5record::size, and gov::fnal::cd::rms::provider::MessageSplitter::splitMessage().

Referenced by gov::fnal::cd::rms::provider::EpicsConnection::sendMessage(), and gov::fnal::cd::rms::provider::EpicsConnection::sendString().

89  {
90  std::vector <MessageFragment *> fragments;
91  MessageSplitter splitter;
92  char *fragment;
93  const char *uuid;
94  int size;
95 
96  uuid = _uuidGenerator->getUUID();
97 
98  fragments = splitter.splitMessage(messageText, _maxMessageSize,
99  uuid);
100 
101  delete[] uuid;
102 
103  ca_attach_context(_caContext);
104  for (unsigned int i = 0; i < fragments.size(); i++) {
105  fragments[i]->getBytes(&fragment, &size);
106  ca_array_put(DBR_CHAR, size, _pvChannel, fragment);
107  ca_pend_io(_PEND_OP_TIMEOUT);
108  delete [] fragment;
109  delete fragments[i];
110  }
112 }
void epicsShareAPI ca_detach_context()

Member Data Documentation

std::vector<MessageAssembler *> gov::fnal::cd::rms::provider::EpicsMessenger::_assemblerList
private

The list of message assemblers that are active.

Definition at line 112 of file EpicsMessenger.h.

Referenced by close(), and monitorChanged().

struct ca_client_context* gov::fnal::cd::rms::provider::EpicsMessenger::_caContext
private

The channel access context that we're using for communication.

Definition at line 80 of file EpicsMessenger.h.

Referenced by addListener(), close(), EpicsMessenger(), and sendMessage().

bool gov::fnal::cd::rms::provider::EpicsMessenger::_firstListener
private

Flag to indicate the first time that a listener is added.

Definition at line 69 of file EpicsMessenger.h.

Referenced by addListener(), close(), and EpicsMessenger().

std::vector<ProviderListener *> gov::fnal::cd::rms::provider::EpicsMessenger::_listenerList
private

The list of listeners interested in being notified when the process variable value changes.

Definition at line 107 of file EpicsMessenger.h.

Referenced by addListener(), notifyListeners(), and removeListener().

int gov::fnal::cd::rms::provider::EpicsMessenger::_maxMessageSize
private

The maximum number of bytes that we can write to an underlying EPICS waveform record at one time.

Definition at line 101 of file EpicsMessenger.h.

Referenced by EpicsMessenger(), and sendMessage().

const double gov::fnal::cd::rms::provider::EpicsMessenger::_PEND_OP_TIMEOUT = 2.0
staticprivate

The length of time (in seconds) to use when waiting for pending operations to complete.

Definition at line 75 of file EpicsMessenger.h.

Referenced by addListener(), close(), EpicsMessenger(), and sendMessage().

chid gov::fnal::cd::rms::provider::EpicsMessenger::_pvChannel
private

The channel that we'll use to access the process variable.

Definition at line 85 of file EpicsMessenger.h.

Referenced by addListener(), close(), EpicsMessenger(), and sendMessage().

std::string gov::fnal::cd::rms::provider::EpicsMessenger::_pvName
private

The name of the process variable.

Definition at line 95 of file EpicsMessenger.h.

Referenced by EpicsMessenger(), and getName().

evid gov::fnal::cd::rms::provider::EpicsMessenger::_pvSubscription
private

Handle to the channel subscription.

Definition at line 90 of file EpicsMessenger.h.

Referenced by addListener(), and close().

util::UUIDGenerator* gov::fnal::cd::rms::provider::EpicsMessenger::_uuidGenerator
private

Generator UUIDs for messages

Definition at line 117 of file EpicsMessenger.h.

Referenced by EpicsMessenger(), and sendMessage().


The documentation for this class was generated from the following files: