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

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

Inheritance diagram for gov::fnal::cd::rms::provider::EpicsConnection:
gov::fnal::cd::rms::provider::RmsConnection

Public Member Functions

 EpicsConnection (const std::string applicationName, const int applicationPartition)
 
 ~EpicsConnection ()
 
bool supportsDestination (const base::RmsDestination &candidateDestination)
 
void sendString (const base::RmsDestination &dest, const std::string &messageString)
 
void sendMessage (const base::RmsDestination &dest, const base::RmsMessage &message)
 
void addListener (const base::RmsDestination &dest, ProviderListener *listener)
 
void removeListener (const base::RmsDestination &dest, ProviderListener *listener)
 
bool ping (const base::RmsDestination &pingDestination)
 
void close ()
 
base::RmsDestination getMessageSource ()
 
const std::string getUUID ()
 

Static Public Attributes

static const std::string PV_DELIMITER
 

Protected Attributes

util::UUIDGenerator_uuidGenerator
 
base::RmsDestination _messageSource
 

Private Member Functions

std::string getDestinationPVFromDest (const base::RmsDestination &dest) const
 
std::string getMonitoringPVFromDest (const base::RmsDestination &dest) const
 
EpicsMessengergetPVHandle (std::string pvName)
 

Private Attributes

std::map< std::string, EpicsMessenger * > _cachedPVs
 
struct ca_client_context * _caCurrentContext
 
boost::mutex _epicsLock
 

Detailed Description

Manages the interface to EPICS. Responsibilities include registering listeners with EPICS, creating EpicsMessengers objects when needed to talk to PVs and translating destination objects into PV names.

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

Definition at line 41 of file EpicsConnection.h.

Constructor & Destructor Documentation

gov::fnal::cd::rms::provider::EpicsConnection::EpicsConnection ( const std::string  applicationName,
const int  applicationPartition 
)

Create a new EpicsConnection given the application name and partition.

Parameters
applicationNameThe name of the application generating/receiving messages.
applicationPartitionThe partition of the application that is generating/receiving messages.

Definition at line 27 of file EpicsConnection.cpp.

References _caCurrentContext, gov::fnal::cd::rms::provider::RmsConnection::_messageSource, gov::fnal::cd::rms::provider::RmsConnection::_uuidGenerator, and gov::fnal::cd::rms::base::RmsDestination::TARGET_PROPERTY_NAME.

28  {
29  char hostname[20];
30 
31  ca_context_create(ca_enable_preemptive_callback);
32  _caCurrentContext = ca_current_context();
33 
34  _messageSource.setProperty(base::RmsDestination::TARGET_PROPERTY_NAME, applicationName);
35  _messageSource.setPartitionProperty(applicationPartition);
36 
37  if (gethostname(hostname, 20) == 0) {
38  _uuidGenerator = new util::UUIDGenerator(hostname);
39  }
40  else {
41  _uuidGenerator = new util::UUIDGenerator("C++EpicsConnection");
42  }
43 }
struct ca_client_context * _caCurrentContext
static const std::string TARGET_PROPERTY_NAME
gov::fnal::cd::rms::provider::EpicsConnection::~EpicsConnection ( )

Destructor, call close() and have it clean up everything.

Definition at line 49 of file EpicsConnection.cpp.

References close().

Member Function Documentation

void gov::fnal::cd::rms::provider::EpicsConnection::addListener ( const base::RmsDestination &  dest,
ProviderListener listener 
)
virtual

Add a listener to a particular PV represented by a destination.

Parameters
destThe destination that we will be listening to.
listenerThe listener that will be called when messages are posted to the PV.

If the target is empty, return the PV for the monitoring outbox.

Implements gov::fnal::cd::rms::provider::RmsConnection.

Definition at line 164 of file EpicsConnection.cpp.

References _epicsLock, gov::fnal::cd::rms::provider::EpicsMessenger::addListener(), om::cout, allTimeWatchdog::endl, getDestinationPVFromDest(), getMonitoringPVFromDest(), getPVHandle(), string, and gov::fnal::cd::rms::base::RmsDestination::TARGET_PROPERTY_NAME.

165  {
166  std::string destinationPV;
167  EpicsMessenger *pvHandle;
168 
169  /**
170  * If the target is empty, return the PV for the monitoring
171  * outbox.
172  */
174  std::string("")) {
175  destinationPV = getDestinationPVFromDest(dest);
176  }
177  else {
178  destinationPV = getMonitoringPVFromDest(dest);
179  }
180 
181  pvHandle = getPVHandle(destinationPV);
182 
183  if (pvHandle) {
184  boost::mutex::scoped_lock lk(_epicsLock);
185  pvHandle->addListener(listener);
186  }
187  else {
188  std::cout << "Unable to create PV handle for:" << std::endl;
189  std::cout << destinationPV << std::endl;
190  std::cout << "in EpicsConnection.addListener()" << std::endl;
191  }
192 
193  return;
194 }
std::string getMonitoringPVFromDest(const base::RmsDestination &dest) const
OStream cout
Definition: OStream.cxx:6
std::string getDestinationPVFromDest(const base::RmsDestination &dest) const
EpicsMessenger * getPVHandle(std::string pvName)
static const std::string TARGET_PROPERTY_NAME
enum BeamMode string
void gov::fnal::cd::rms::provider::EpicsConnection::close ( )
virtual

Free the memory allocated for the UUID generator and delete any instances of the EpicsMessenger class that were created. Finally, call ca_context_destroy().

Implements gov::fnal::cd::rms::provider::RmsConnection.

Definition at line 266 of file EpicsConnection.cpp.

References _cachedPVs, _caCurrentContext, _epicsLock, gov::fnal::cd::rms::provider::RmsConnection::_uuidGenerator, and string.

Referenced by ~EpicsConnection().

266  {
267  std::map <std::string, EpicsMessenger *>::iterator cacheIterator;
268 
269  if (_uuidGenerator) {
270  delete _uuidGenerator;
271  _uuidGenerator = NULL;
272  }
273 
274  boost::mutex::scoped_lock lk(_epicsLock);
275 
276  cacheIterator = _cachedPVs.begin();
277 
278  while (cacheIterator != _cachedPVs.end()) {
279  delete cacheIterator->second;
280  cacheIterator++;
281  }
282 
283  _cachedPVs.clear();
284 
285  if (_caCurrentContext) {
286  ca_attach_context(_caCurrentContext);
287  ca_context_destroy();
288  _caCurrentContext = NULL;
289  }
290 }
std::map< std::string, EpicsMessenger * > _cachedPVs
struct ca_client_context * _caCurrentContext
std::string gov::fnal::cd::rms::provider::EpicsConnection::getDestinationPVFromDest ( const base::RmsDestination &  dest) const
private

Translate a destination object into an Epics PV.

Parameters
destThe destination object that will be translated into a PV.
Returns
The name of the PV for the location that the destination object represents.

The heartbeat channel is a special case. For each target, their will be one heartbeat channel. All heartbeat messages will be pushed out to the outbox.

Definition at line 302 of file EpicsConnection.cpp.

References gov::fnal::cd::rms::base::RmsDestination::CHANNEL_PROPERTY_NAME, gov::fnal::cd::rms::base::RmsDestination::ENVIRONMENT_PROPERTY_NAME, gov::fnal::cd::rms::base::RmsDestination::HEARTBEAT_CHANNEL, gov::fnal::cd::rms::base::RmsDestination::PARTITION_PROPERTY_NAME, PV_DELIMITER, string, and gov::fnal::cd::rms::base::RmsDestination::TARGET_PROPERTY_NAME.

Referenced by addListener(), ping(), removeListener(), sendMessage(), sendString(), and supportsDestination().

302  {
303  std::string destinationPV;
304 
305  std::string destinationTarget =
307  std::string destinationChannel =
309  std::string destinationPartition =
311  std::string destinationEnvironment =
313 
314  /**
315  * The heartbeat channel is a special case. For each target, their will
316  * be one heartbeat channel. All heartbeat messages will be pushed out
317  * to the outbox.
318  */
319  if(destinationChannel == base::RmsDestination::HEARTBEAT_CHANNEL) {
320  if (destinationEnvironment != "") {
321  destinationPV.append(destinationEnvironment + "_");
322  }
323 
324  destinationPV.append(destinationTarget);
325  destinationPV.append(EpicsConnection::PV_DELIMITER);
326  destinationPV.append(destinationChannel);
327  destinationPV.append(EpicsConnection::PV_DELIMITER);
328  destinationPV.append("outbox");
329  return destinationPV;
330  }
331 
332  if (destinationEnvironment != "") {
333  destinationPV.append(destinationEnvironment + "_");
334  }
335 
336  destinationPV.append(destinationTarget);
337  destinationPV.append(EpicsConnection::PV_DELIMITER);
338  destinationPV.append(destinationPartition);
339  destinationPV.append(EpicsConnection::PV_DELIMITER);
340  destinationPV.append(destinationChannel);
341  destinationPV.append(EpicsConnection::PV_DELIMITER);
342  destinationPV.append("inbox");
343 
344  return destinationPV;
345 }
static const std::string PARTITION_PROPERTY_NAME
static const std::string HEARTBEAT_CHANNEL
static const std::string CHANNEL_PROPERTY_NAME
static const std::string ENVIRONMENT_PROPERTY_NAME
static const std::string TARGET_PROPERTY_NAME
enum BeamMode string
base::RmsDestination gov::fnal::cd::rms::provider::RmsConnection::getMessageSource ( )
inlineinherited

Get a copy of the message source.

Returns
A destination object that contains the source of messages for this connection.

Definition at line 112 of file RmsConnection.h.

References gov::fnal::cd::rms::provider::RmsConnection::_messageSource.

112  {
113  return _messageSource;
114  }
std::string gov::fnal::cd::rms::provider::EpicsConnection::getMonitoringPVFromDest ( const base::RmsDestination &  dest) const
private

Find the name of the monitoring outbox that a message should be posted to when sending to a particular destination.

Parameters
destThe destination that the message is going to
Returns
This will return the name of the PV for the monitoring outbox that the message should be posted to.

There is no monitoring outbox for the heartbeat channel

Definition at line 357 of file EpicsConnection.cpp.

References gov::fnal::cd::rms::base::RmsDestination::CHANNEL_PROPERTY_NAME, gov::fnal::cd::rms::base::RmsDestination::ENVIRONMENT_PROPERTY_NAME, gov::fnal::cd::rms::base::RmsDestination::HEARTBEAT_CHANNEL, gov::fnal::cd::rms::base::RmsDestination::PARTITION_PROPERTY_NAME, PV_DELIMITER, gov::fnal::cd::rms::base::RmsDestination::SOURCE_PROPERTY_NAME, string, and gov::fnal::cd::rms::base::RmsDestination::TARGET_PROPERTY_NAME.

Referenced by addListener(), removeListener(), sendMessage(), and supportsDestination().

357  {
358  std::string targetName =
360  std::string destinationPartition =
362  std::string destinationChannel =
364 
365  /**
366  * There is no monitoring outbox for the heartbeat channel
367  */
368  if (destinationChannel == base::RmsDestination::HEARTBEAT_CHANNEL) {
369  return std::string("");
370  }
371 
372  if (targetName == std::string("")) {
373  targetName = dest.getProperty(base::RmsDestination::SOURCE_PROPERTY_NAME);
374  }
375 
376  targetName.append(EpicsConnection::PV_DELIMITER);
377  targetName.append(destinationPartition);
378  targetName.append(EpicsConnection::PV_DELIMITER);
379  targetName.append(destinationChannel);
380  targetName.append(EpicsConnection::PV_DELIMITER);
381  targetName.append("monitoringOutbox");
382 
383  std::string destinationEnvironment =
385 
386  if (destinationEnvironment != "") {
387  targetName.insert(0, destinationEnvironment + "_");
388  }
389 
390  return targetName;
391 }
static const std::string PARTITION_PROPERTY_NAME
static const std::string SOURCE_PROPERTY_NAME
static const std::string HEARTBEAT_CHANNEL
static const std::string CHANNEL_PROPERTY_NAME
static const std::string ENVIRONMENT_PROPERTY_NAME
static const std::string TARGET_PROPERTY_NAME
enum BeamMode string
EpicsMessenger * gov::fnal::cd::rms::provider::EpicsConnection::getPVHandle ( std::string  pvName)
private

Obtain a handle to a particular PV. If the handle has already been created, find it in the _cachedPVs table and return it. Otherwise, create a new one and insert it into the _cachedPVs table.

Parameters
pvNameThe name of the PV to get a handle for.
Returns
An EpicsMessenger for a particular PV.

Definition at line 403 of file EpicsConnection.cpp.

References _cachedPVs, _caCurrentContext, _epicsLock, and gov::fnal::cd::rms::provider::RmsConnection::_uuidGenerator.

Referenced by addListener(), removeListener(), sendMessage(), sendString(), and supportsDestination().

403  {
404  EpicsMessenger *pvHandle;
405  std::map <std::string, EpicsMessenger *>::iterator cacheIterator;
406 
407  boost::mutex::scoped_lock lk(_epicsLock);
408 
409  cacheIterator = _cachedPVs.find(pvName);
410 
411  if (cacheIterator == _cachedPVs.end()) {
412  pvHandle =
413  new EpicsMessenger(pvName, _caCurrentContext,
414  1024, _uuidGenerator);
415  _cachedPVs.insert(std::pair<std::string, EpicsMessenger *>
416  (pvName, pvHandle));
417  }
418  else {
419  return cacheIterator->second;
420  }
421 
422  return pvHandle;
423 }
std::map< std::string, EpicsMessenger * > _cachedPVs
struct ca_client_context * _caCurrentContext
const std::string gov::fnal::cd::rms::provider::RmsConnection::getUUID ( )
inlineinherited

Get a new human readbale UUID from the UUID generator.

Returns
A new UUID.

Definition at line 121 of file RmsConnection.h.

References gov::fnal::cd::rms::provider::RmsConnection::_uuidGenerator, gov::fnal::cd::rms::provider::RmsConnection::close(), and gov::fnal::cd::rms::util::UUIDGenerator::getUUIDHex().

121  {
122  return _uuidGenerator->getUUIDHex();
123  }
bool gov::fnal::cd::rms::provider::EpicsConnection::ping ( const base::RmsDestination &  pingDestination)
virtual

Try to connect to a PV to verify that it exists and is runing.

Parameters
pingDestinationThe destination that we are going to ping.
Returns
True is the PV exists and is running, false otherwise.

Implements gov::fnal::cd::rms::provider::RmsConnection.

Definition at line 241 of file EpicsConnection.cpp.

References _caCurrentContext, _epicsLock, getDestinationPVFromDest(), fillBadChanDBTables::result, and string.

241  {
242  chid channelID;
243  int result;
244 
245  std::string destinationPV = getDestinationPVFromDest(pingDestination);
246 
247  boost::mutex::scoped_lock lk(_epicsLock);
248  ca_attach_context(_caCurrentContext);
249 
250  ca_create_channel(destinationPV.c_str(), NULL, NULL, 10, &channelID);
251  result = ca_pend_io(0.5);
252  ca_clear_channel(channelID);
253 
254  if (result != ECA_NORMAL) {
255  return false;
256  }
257 
258  return true;
259 }
struct ca_client_context * _caCurrentContext
std::string getDestinationPVFromDest(const base::RmsDestination &dest) const
enum BeamMode string
void gov::fnal::cd::rms::provider::EpicsConnection::removeListener ( const base::RmsDestination &  dest,
ProviderListener listener 
)
virtual

Remove a listener from the EpicsConnection so that it no longer receives messages.

Parameters
destThe destination to remove.
listenerThe listener to remove.

If the target is empty, return the PV for the monitoring outbox.

Implements gov::fnal::cd::rms::provider::RmsConnection.

Definition at line 203 of file EpicsConnection.cpp.

References _epicsLock, om::cout, allTimeWatchdog::endl, getDestinationPVFromDest(), getMonitoringPVFromDest(), getPVHandle(), gov::fnal::cd::rms::provider::EpicsMessenger::removeListener(), string, and gov::fnal::cd::rms::base::RmsDestination::TARGET_PROPERTY_NAME.

203  {
204  std::string destinationPV;
205  EpicsMessenger *pvHandle;
206 
207  /**
208  * If the target is empty, return the PV for the monitoring
209  * outbox.
210  */
212  std::string("")) {
213  destinationPV = getDestinationPVFromDest(dest);
214  }
215  else {
216  destinationPV = getMonitoringPVFromDest(dest);
217  }
218 
219  pvHandle = getPVHandle(destinationPV);
220 
221  if (pvHandle) {
222  boost::mutex::scoped_lock lk(_epicsLock);
223  pvHandle->removeListener(listener);
224  }
225  else {
226  std::cout << "Unable to create PV handle for:" << std::endl;
227  std::cout << destinationPV << std::endl;
228  std::cout << "in EpicsConnection.removeListener()" << std::endl;
229  }
230 
231  return;
232 }
std::string getMonitoringPVFromDest(const base::RmsDestination &dest) const
OStream cout
Definition: OStream.cxx:6
std::string getDestinationPVFromDest(const base::RmsDestination &dest) const
EpicsMessenger * getPVHandle(std::string pvName)
static const std::string TARGET_PROPERTY_NAME
enum BeamMode string
void gov::fnal::cd::rms::provider::EpicsConnection::sendMessage ( const base::RmsDestination &  dest,
const base::RmsMessage &  message 
)
virtual

Send an RmsMessage to a particular destination.

Parameters
destThe destination that the message is going to
messageThe RmsMessage that is being sent

Implements gov::fnal::cd::rms::provider::RmsConnection.

Definition at line 118 of file EpicsConnection.cpp.

References _epicsLock, om::cout, allTimeWatchdog::endl, getDestinationPVFromDest(), getMonitoringPVFromDest(), getPVHandle(), gov::fnal::cd::rms::provider::EpicsMessenger::sendMessage(), and string.

119  {
120  std::string destinationPV;
121  std::string monitoringOutboxPV;
122  EpicsMessenger *pvHandle;
123 
124  destinationPV = getDestinationPVFromDest(dest);
125  monitoringOutboxPV = getMonitoringPVFromDest(message.getReplyDestination());
126  std::string serializedMessage = message.serialize();
127 
128  pvHandle = getPVHandle(destinationPV);
129 
130  if (pvHandle) {
131  boost::mutex::scoped_lock lk(_epicsLock);
132  pvHandle->sendMessage(serializedMessage);
133  }
134  else {
135  std::cout << "Unable to create PV handler for:" << std::endl;
136  std::cout << destinationPV << std::endl;
137  std::cout << "in EpicsConnection.sendMessage()" << std::endl;
138  return;
139  }
140 
141  pvHandle = getPVHandle(monitoringOutboxPV);
142 
143  if (pvHandle) {
144  boost::mutex::scoped_lock lk(_epicsLock);
145  pvHandle->sendMessage(serializedMessage);
146  }
147  else {
148  std::cout << "Unable to create PV handler for:" << std::endl;
149  std::cout << monitoringOutboxPV << std::endl;
150  std::cout << "in EpicsConnection.sendMessage()" << std::endl;
151  return;
152  }
153 
154  return;
155 }
std::string getMonitoringPVFromDest(const base::RmsDestination &dest) const
OStream cout
Definition: OStream.cxx:6
std::string getDestinationPVFromDest(const base::RmsDestination &dest) const
EpicsMessenger * getPVHandle(std::string pvName)
enum BeamMode string
void gov::fnal::cd::rms::provider::EpicsConnection::sendString ( const base::RmsDestination &  dest,
const std::string messageString 
)
virtual

Send a string to a particular destination.

Parameters
destThe destination that the message is going to
messageStringThe string that is being sent

Implements gov::fnal::cd::rms::provider::RmsConnection.

Definition at line 91 of file EpicsConnection.cpp.

References _epicsLock, om::cout, allTimeWatchdog::endl, getDestinationPVFromDest(), getPVHandle(), gov::fnal::cd::rms::provider::EpicsMessenger::sendMessage(), and string.

92  {
93  std::string destinationPV;
94  EpicsMessenger *pvHandle;
95 
96  destinationPV = getDestinationPVFromDest(dest);
97  pvHandle = getPVHandle(destinationPV);
98 
99  if (pvHandle) {
100  boost::mutex::scoped_lock lk(_epicsLock);
101  pvHandle->sendMessage(messageString);
102  }
103  else {
104  std::cout << "Unable to create PV handler for:" << std::endl;
105  std::cout << destinationPV << std::endl;
106  std::cout << "in EpicsConnection.sendMessage()" << std::endl;
107  }
108 
109  return;
110 }
OStream cout
Definition: OStream.cxx:6
std::string getDestinationPVFromDest(const base::RmsDestination &dest) const
EpicsMessenger * getPVHandle(std::string pvName)
enum BeamMode string
bool gov::fnal::cd::rms::provider::EpicsConnection::supportsDestination ( const base::RmsDestination &  dest)
virtual

Determine if the given destination can be reached with the EPICS provider.

Parameters
destThe destination to check to see if messages can be sent to it.
Returns
True if the destination can be reached, false otherwise.

Implements gov::fnal::cd::rms::provider::RmsConnection.

Definition at line 62 of file EpicsConnection.cpp.

References getDestinationPVFromDest(), getMonitoringPVFromDest(), getPVHandle(), and string.

62  {
63  std::string destinationPV;
64  std::string monitoringOutboxPV;
65  EpicsMessenger *pvHandle;
66 
67  destinationPV = getDestinationPVFromDest(dest);
68  monitoringOutboxPV = getMonitoringPVFromDest(dest);
69 
70  pvHandle = getPVHandle(destinationPV);
71 
72  if (!pvHandle) {
73  return false;
74  }
75 
76  pvHandle = getPVHandle(monitoringOutboxPV);
77 
78  if (!pvHandle) {
79  return false;
80  }
81 
82  return true;
83 }
std::string getMonitoringPVFromDest(const base::RmsDestination &dest) const
std::string getDestinationPVFromDest(const base::RmsDestination &dest) const
EpicsMessenger * getPVHandle(std::string pvName)
enum BeamMode string

Member Data Documentation

std::map<std::string, EpicsMessenger *> gov::fnal::cd::rms::provider::EpicsConnection::_cachedPVs
private

A set of handles to PVs that have been used.

Definition at line 67 of file EpicsConnection.h.

Referenced by close(), and getPVHandle().

struct ca_client_context* gov::fnal::cd::rms::provider::EpicsConnection::_caCurrentContext
private

The EPICS context.

Definition at line 72 of file EpicsConnection.h.

Referenced by close(), EpicsConnection(), getPVHandle(), and ping().

boost::mutex gov::fnal::cd::rms::provider::EpicsConnection::_epicsLock
private

Lock for the EPICS code as EpicsMessenger is not thread safe.

Definition at line 78 of file EpicsConnection.h.

Referenced by addListener(), close(), getPVHandle(), ping(), removeListener(), sendMessage(), and sendString().

base::RmsDestination gov::fnal::cd::rms::provider::RmsConnection::_messageSource
protectedinherited

A destination to hold the application name and application partition that is passed into the constructor.

Definition at line 141 of file RmsConnection.h.

Referenced by EpicsConnection(), gov::fnal::cd::rms::provider::RmsConnection::getMessageSource(), and gov::fnal::cd::rms::provider::LocalhostConnection::LocalhostConnection().

util::UUIDGenerator* gov::fnal::cd::rms::provider::RmsConnection::_uuidGenerator
protectedinherited
const std::string gov::fnal::cd::rms::provider::EpicsConnection::PV_DELIMITER
static

The character that is to be used as a delimiter in PV names.

The character that is used a delimiter is PV names.

Definition at line 47 of file EpicsConnection.h.

Referenced by getDestinationPVFromDest(), and getMonitoringPVFromDest().


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