This is Unofficial EPICS BASE Doxygen Site
PDBProvider Struct Reference

#include "pdb.h"

+ Inheritance diagram for PDBProvider:
+ Collaboration diagram for PDBProvider:

Public Types

typedef std::map< std::string, PDBPV::shared_pointer > persist_pv_map_t
 
typedef weak_value_map< std::string, PDBPVtransient_pv_map_t
 
- Public Types inherited from epics::pvAccess::ChannelFind
typedef ChannelFindRequester requester_type
 

Public Member Functions

 POINTER_DEFINITIONS (PDBProvider)
 
 PDBProvider (const epics::pvAccess::Configuration::const_shared_pointer &=epics::pvAccess::Configuration::const_shared_pointer())
 
virtual ~PDBProvider ()
 
virtual void destroy () OVERRIDE FINAL
 
virtual std::string getProviderName () OVERRIDE FINAL
 
virtual epics::pvAccess::ChannelFind::shared_pointer channelFind (std::string const &channelName, epics::pvAccess::ChannelFindRequester::shared_pointer const &channelFindRequester) OVERRIDE FINAL
 
virtual epics::pvAccess::ChannelFind::shared_pointer channelList (epics::pvAccess::ChannelListRequester::shared_pointer const &channelListRequester) OVERRIDE FINAL
 
virtual epics::pvAccess::Channel::shared_pointer createChannel (std::string const &channelName, epics::pvAccess::ChannelRequester::shared_pointer const &channelRequester, short priority=PRIORITY_DEFAULT) OVERRIDE FINAL
 
virtual epics::pvAccess::Channel::shared_pointer createChannel (std::string const &channelName, epics::pvAccess::ChannelRequester::shared_pointer const &channelRequester, short priority, std::string const &address) OVERRIDE FINAL
 
virtual std::tr1::shared_ptr< ChannelProvidergetChannelProvider () OVERRIDE FINAL
 
virtual void cancel () OVERRIDE FINAL
 
- Public Member Functions inherited from epics::pvAccess::ChannelProvider
 POINTER_DEFINITIONS (ChannelProvider)
 
 ChannelProvider ()
 
virtual ~ChannelProvider ()
 
virtual ChannelFind::shared_pointer channelFind (std::string const &name, ChannelFindRequester::shared_pointer const &requester)=0
 
virtual ChannelFind::shared_pointer channelList (ChannelListRequester::shared_pointer const &requester)
 
virtual Channel::shared_pointer createChannel (std::string const &name, ChannelRequester::shared_pointer const &requester=DefaultChannelRequester::build(), short priority=PRIORITY_DEFAULT)
 
virtual Channel::shared_pointer createChannel (std::string const &name, ChannelRequester::shared_pointer const &requester, short priority, std::string const &address)=0
 
- Public Member Functions inherited from epics::pvAccess::Destroyable
 POINTER_DEFINITIONS (Destroyable)
 
- Public Member Functions inherited from epics::pvAccess::ChannelFind
 POINTER_DEFINITIONS (ChannelFind)
 
 ChannelFind ()
 
virtual ~ChannelFind ()
 

Public Attributes

persist_pv_map_t persist_pv_map
 
transient_pv_map_t transient_pv_map
 
dbEventCtx event_context
 

Static Public Attributes

static size_t num_instances
 
- Static Public Attributes inherited from epics::pvAccess::ChannelProvider
static const short PRIORITY_MIN = 0
 
static const short PRIORITY_MAX = 99
 
static const short PRIORITY_DEFAULT = PRIORITY_MIN
 
static const short PRIORITY_LINKS_DB = PRIORITY_MAX
 
static const short PRIORITY_ARCHIVE = (PRIORITY_MAX + PRIORITY_MIN) / 2
 
static const short PRIORITY_OPI = PRIORITY_MIN
 
static size_t num_instances
 

Additional Inherited Members

- Static Public Member Functions inherited from epics::pvAccess::ChannelFind
static ChannelFind::shared_pointer buildDummy (const std::tr1::shared_ptr< ChannelProvider > &provider)
 
- Protected Member Functions inherited from epics::pvAccess::Destroyable
virtual ~Destroyable ()
 

Detailed Description

Definition at line 33 of file pdb.h.

Member Typedef Documentation

typedef std::map<std::string, PDBPV::shared_pointer> PDBProvider::persist_pv_map_t

Definition at line 59 of file pdb.h.

Definition at line 62 of file pdb.h.

Constructor & Destructor Documentation

PDBProvider::PDBProvider ( const epics::pvAccess::Configuration::const_shared_pointer &  = epics::pvAccess::Configuration::const_shared_pointer())
explicit

Definition at line 321 of file pdb.cpp.

322 {
323  /* Long view
324  * 1. PDBProcessor collects info() tags and builds config of groups and group fields
325  * (including those w/o a dbChannel)
326  * 2. Build pvd::Structure and discard those w/o dbChannel
327  * 3. Build the lockers for the triggers of each group field
328  */
329  PDBProcessor proc;
332 
333  pvd::StructureConstPtr _options(fcreate->createFieldBuilder()
334  ->addNestedStructure("_options")
335  ->add("queueSize", pvd::pvUInt)
336  ->add("atomic", pvd::pvBoolean)
337  ->endNested()
338  ->createStructure());
339 
340 #ifdef USE_MULTILOCK
341  // assemble group PVD structure definitions and build dbLockers
342  FOREACH(PDBProcessor::groups_t::const_iterator, it, end, proc.groups)
343  {
344  const GroupInfo &info=it->second;
345  try{
346  if(persist_pv_map.find(info.name)!=persist_pv_map.end())
347  throw std::runtime_error("name already in used");
348 
349  PDBGroupPV::shared_pointer pv(new PDBGroupPV());
350  pv->weakself = pv;
351  pv->name = info.name;
352 
353  pv->pgatomic = info.atomic!=GroupInfo::False; // default true if Unset
354  pv->monatomic = info.hastriggers;
355 
356  // some gymnastics because Info isn't copyable
358  typedef std::map<std::string, size_t> members_map_t;
359  members_map_t members_map;
360  {
361  size_t nchans = 0;
362  for(size_t i=0, N=info.members.size(); i<N; i++)
363  if(!info.members[i].pvname.empty())
364  nchans++;
366  members.swap(temp);
367  }
368 
369  std::vector<dbCommon*> records(members.size());
370 
371  pvd::FieldBuilderPtr builder(fcreate->createFieldBuilder());
372  builder = builder->add("record", _options);
373 
374  if(!info.structID.empty())
375  builder = builder->setId(info.structID);
376 
377  for(size_t i=0, J=0, N=info.members.size(); i<N; i++)
378  {
379  const GroupMemberInfo &mem = info.members[i];
380 
381  // parse down attachment point to build/traverse structure
382  FieldName parts(mem.pvfldname);
383 
384  if(!parts.empty()) {
385  for(size_t j=0; j<parts.size()-1; j++) {
386  if(parts[j].isArray())
387  builder = builder->addNestedStructureArray(parts[j].name);
388  else
389  builder = builder->addNestedStructure(parts[j].name);
390  }
391  }
392 
393  if(!mem.structID.empty())
394  builder = builder->setId(mem.structID);
395 
396  DBCH chan;
397  if(!mem.pvname.empty()) {
398  DBCH temp(mem.pvname);
399  unsigned ftype = dbChannelFieldType(temp);
400 
401  // can't include in multi-locking
402  if(ftype>=DBF_INLINK && ftype<=DBF_FWDLINK)
403  throw std::runtime_error("Can't include link fields in group");
404 
405  chan.swap(temp);
406  }
407 
408  if(!parts.empty())
409  builder = mem.builder->dtype(builder, parts.back().name, chan);
410  else
411  builder = mem.builder->dtype(builder, "", chan);
412 
413  if(!parts.empty()) {
414  for(size_t j=0; j<parts.size()-1; j++)
415  builder = builder->endNested();
416  }
417 
418  if(!mem.pvname.empty()) {
419  members_map[mem.pvfldname] = J;
420  PDBGroupPV::Info& info = members[J];
421 
422  info.allowProc = mem.putorder != std::numeric_limits<int>::min();
423  info.builder = PTRMOVE(mem.builder);
424  assert(info.builder.get());
425 
426  info.attachment.swap(parts);
427  info.chan.swap(chan);
428 
429  // info.triggers populated below
430 
431  assert(info.chan);
432  records[J] = dbChannelRecord(info.chan);
433 
434  J++;
435  }
436  }
437  pv->members.swap(members);
438 
439  pv->fielddesc = builder->createStructure();
440  pv->complete = pvbuilder->createPVStructure(pv->fielddesc);
441 
442  pv->complete->getSubFieldT<pvd::PVBoolean>("record._options.atomic")->put(pv->monatomic);
443 
444  DBManyLock L(&records[0], records.size(), 0);
445  pv->locker.swap(L);
446 
447  // construct locker for records triggered by each member
448  for(size_t i=0, J=0, N=info.members.size(); i<N; i++)
449  {
450  const GroupMemberInfo &mem = info.members[i];
451  if(mem.pvname.empty()) continue;
452  PDBGroupPV::Info& info = pv->members[J++];
453 
454  if(mem.triggers.empty()) continue;
455 
456  std::vector<dbCommon*> trig_records;
457  trig_records.reserve(mem.triggers.size());
458 
459  FOREACH(GroupMemberInfo::triggers_t::const_iterator, it, end, mem.triggers) {
460  members_map_t::const_iterator imap(members_map.find(*it));
461  if(imap==members_map.end())
462  throw std::logic_error("trigger resolution missed map to non-dbChannel");
463 
464  info.triggers.push_back(imap->second);
465  trig_records.push_back(records[imap->second]);
466  }
467 
468  DBManyLock L(&trig_records[0], trig_records.size(), 0);
469  info.locker.swap(L);
470  }
471 
472  persist_pv_map[info.name] = pv;
473 
474  }catch(std::exception& e){
475  fprintf(stderr, "%s: Error Group not created: %s\n", info.name.c_str(), e.what());
476  }
477  }
478 #else
479  if(!proc.groups.empty()) {
480  fprintf(stderr, "Group(s) were defined, but need Base >=3.16.0.2 to function. Ignoring.\n");
481  }
482 #endif // USE_MULTILOCK
483 
484  event_context = db_init_events();
485  if(!event_context)
486  throw std::runtime_error("Failed to create dbEvent context");
487  int ret = db_start_events(event_context, "PDB-event", NULL, NULL, epicsThreadPriorityCAServerLow-1);
488  if(ret!=DB_EVENT_OK)
489  throw std::runtime_error("Failed to stsart dbEvent context");
490 
491  // setup group monitors
492 #ifdef USE_MULTILOCK
493  for(persist_pv_map_t::iterator next = persist_pv_map.begin(),
494  end = persist_pv_map.end(),
495  it = next!=end ? next++ : end;
496  it != end; it = next==end ? end : next++)
497  {
498  const PDBPV::shared_pointer& ppv = it->second;
499  PDBGroupPV *pv = dynamic_cast<PDBGroupPV*>(ppv.get());
500  if(!pv)
501  continue;
502  try {
503 
504  // prepare for monitor
505 
506  size_t i=0;
508  {
509  PDBGroupPV::Info& info = *it2;
510  info.evt_VALUE.index = info.evt_PROPERTY.index = i++;
511  info.evt_VALUE.self = info.evt_PROPERTY.self = pv;
512  assert(info.chan);
513 
514  info.pvif.reset(info.builder->attach(info.chan, pv->complete, info.attachment));
515 
516  // TODO: don't need evt_PROPERTY for PVIF plain
518 
519  if(!info.triggers.empty()) {
521  }
522  }
523  }catch(std::exception& e){
524  fprintf(stderr, "%s: Error during dbEvent setup : %s\n", pv->name.c_str(), e.what());
525  persist_pv_map.erase(it);
526  }
527  }
528 #endif // USE_MULTILOCK
529  epics::atomic::increment(num_instances);
530 }
DBManyLock locker
Definition: pdbgroup.h:96
members_t members
Definition: pdbgroup.h:104
void * self
Definition: pvif.h:218
#define assert(exp)
Declare that a condition should be true.
Definition: epicsAssert.h:70
std::tr1::shared_ptr< detail::SharedPut > put
A holder for a contiguous piece of memory.
Definition: sharedVector.h:27
dbEventCtx event_context
Definition: pdb.h:65
void swap(FieldName &o)
Definition: pvif.h:329
#define FOREACH(ITERTYPE, IT, END, C)
Definition: helper.h:6
int i
Definition: scan.c:967
void pdb_group_event(void *user_arg, struct dbChannel *chan, int eventsRemaining, struct db_field_log *pfl)
Definition: pdbgroup.cpp:30
#define min(x, y)
Definition: flexdef.h:78
Definition: tool_lib.h:67
std::tr1::shared_ptr< const Structure > StructureConstPtr
Definition: pvIntrospect.h:162
#define NULL
Definition: catime.c:38
#define DBE_ALARM
Definition: caeventmask.h:41
std::tr1::shared_ptr< FieldBuilder > FieldBuilderPtr
void swap(DBCH &)
Definition: pvif.cpp:67
static size_t num_instances
Definition: pdb.h:67
std::tr1::shared_ptr< PVDataCreate > PVDataCreatePtr
Definition: pvData.h:124
epics::pvData::PVStructurePtr complete
Definition: pdbgroup.h:108
#define DBE_VALUE
Definition: caeventmask.h:38
void create(dbEventCtx ctx, dbChannel *ch, EVENTFUNC *fn, unsigned mask)
Definition: pvif.h:224
void swap(shared_vector_base &o)
Swap the contents of this vector with another.
Definition: sharedVector.h:199
std::string name
Definition: pdbgroup.h:88
size_t size() const
Number of elements visible through this vector.
Definition: sharedVector.h:220
FORCE_INLINE const FieldCreatePtr & getFieldCreate()
Definition: pvif.h:72
#define DBE_PROPERTY
Definition: caeventmask.h:42
#define epicsThreadPriorityCAServerLow
Definition: epicsThread.h:80
unsigned index
Definition: pvif.h:219
Class that holds the data for each possible scalar type.
Definition: pvData.h:54
std::tr1::shared_ptr< FieldCreate > FieldCreatePtr
FieldName attachment
Definition: pdbgroup.h:93
DBEvent evt_VALUE
Definition: pdbgroup.h:98
triggers_t triggers
Definition: pdbgroup.h:95
p2p::auto_ptr< PVIF > pvif
Definition: pdbgroup.h:97
#define stderr
Definition: epicsStdio.h:32
#define PTRMOVE(AUTO)
Definition: helper.h:15
char * name
Definition: tool_lib.h:69
persist_pv_map_t persist_pv_map
Definition: pdb.h:60
std::tr1::shared_ptr< PVIFBuilder > builder
Definition: pdbgroup.h:92
DBEvent evt_PROPERTY
Definition: pdbgroup.h:98
FORCE_INLINE const PVDataCreatePtr & getPVDataCreate()
Definition: pvData.h:1648
PDBProvider::~PDBProvider ( )
virtual

Definition at line 532 of file pdb.cpp.

533 {
534  epics::atomic::decrement(num_instances);
535 
536  destroy();
537 }
virtual void destroy() OVERRIDE FINAL
Definition: pdb.cpp:539
static size_t num_instances
Definition: pdb.h:67

Member Function Documentation

virtual void PDBProvider::cancel ( )
inlinevirtual

Implements epics::pvAccess::ChannelFind.

Definition at line 57 of file pdb.h.

57 {/* our channelFind() is synchronous, so nothing to cancel */}
pva::ChannelFind::shared_pointer PDBProvider::channelFind ( std::string const &  channelName,
epics::pvAccess::ChannelFindRequester::shared_pointer const &  channelFindRequester 
)
virtual

Definition at line 568 of file pdb.cpp.

569 {
570  pva::ChannelFind::shared_pointer ret(new ChannelFindRequesterNOOP(shared_from_this()));
571 
572  bool found = false;
573  {
575  if(persist_pv_map.find(channelName)!=persist_pv_map.end()
576  || transient_pv_map.find(channelName)
577  || dbChannelTest(channelName.c_str())==0)
578  found = true;
579  }
580  requester->channelFindResult(pvd::Status(), ret, found);
581  return ret;
582 }
transient_pv_map_t transient_pv_map
Definition: pdb.h:63
epicsMutex & mutex() const
Definition: weakmap.h:276
value_pointer find(const K &k) const
Definition: weakmap.h:215
const ChannelProcessRequester::weak_pointer requester
Definition: pvAccess.cpp:68
persist_pv_map_t persist_pv_map
Definition: pdb.h:60
pva::ChannelFind::shared_pointer PDBProvider::channelList ( epics::pvAccess::ChannelListRequester::shared_pointer const &  channelListRequester)
virtual

Definition at line 585 of file pdb.cpp.

586 {
587  pva::ChannelFind::shared_pointer ret;
589  for(pdbRecordIterator rec; !rec.done(); rec.next())
590  {
591  names.push_back(rec.name());
592  }
593  {
595 
596  for(persist_pv_map_t::const_iterator it=persist_pv_map.begin(), end=persist_pv_map.end();
597  it != end; ++it)
598  {
599  names.push_back(it->first);
600  }
601  }
602  // check for duplicates?
603  requester->channelListResult(pvd::Status::Ok,
604  shared_from_this(),
605  pvd::freeze(names), false);
606  return ret;
607 }
::epics::pvData::shared_vector< T > svector
Definition: pvData.h:1184
static Status Ok
Definition: status.h:47
transient_pv_map_t transient_pv_map
Definition: pdb.h:63
epicsMutex & mutex() const
Definition: weakmap.h:276
const ChannelProcessRequester::weak_pointer requester
Definition: pvAccess.cpp:68
persist_pv_map_t persist_pv_map
Definition: pdb.h:60
bool done() const
Definition: pvif.h:164
virtual epics::pvAccess::Channel::shared_pointer PDBProvider::createChannel ( std::string const &  channelName,
epics::pvAccess::ChannelRequester::shared_pointer const &  channelRequester,
short  priority = PRIORITY_DEFAULT 
)
virtual
virtual epics::pvAccess::Channel::shared_pointer PDBProvider::createChannel ( std::string const &  channelName,
epics::pvAccess::ChannelRequester::shared_pointer const &  channelRequester,
short  priority,
std::string const &  address 
)
virtual
void PDBProvider::destroy ( )
virtual

Destroy this instance.

Implements epics::pvAccess::Destroyable.

Definition at line 539 of file pdb.cpp.

540 {
541  dbEventCtx ctxt = NULL;
542 
543  persist_pv_map_t ppv;
544  {
546  persist_pv_map.swap(ppv);
547  std::swap(ctxt, event_context);
548  }
549  ppv.clear(); // indirectly calls all db_cancel_events()
550  if(ctxt) db_close_events(ctxt);
551 }
dbEventCtx event_context
Definition: pdb.h:65
transient_pv_map_t transient_pv_map
Definition: pdb.h:63
#define NULL
Definition: catime.c:38
epicsMutex & mutex() const
Definition: weakmap.h:276
std::map< std::string, PDBPV::shared_pointer > persist_pv_map_t
Definition: pdb.h:59
void swap(shared_ptr< T > &a, shared_ptr< T > &b) BOOST_NOEXCEPT
Definition: shared_ptr.hpp:783
persist_pv_map_t persist_pv_map
Definition: pdb.h:60
virtual std::tr1::shared_ptr<ChannelProvider> PDBProvider::getChannelProvider ( )
inlinevirtual

Implements epics::pvAccess::ChannelFind.

Definition at line 56 of file pdb.h.

56 { return shared_from_this(); }
std::string PDBProvider::getProviderName ( )
virtual

Get the provider name.

Returns
The name.

Implements epics::pvAccess::ChannelProvider.

Definition at line 553 of file pdb.cpp.

553 { return "QSRV"; }
PDBProvider::POINTER_DEFINITIONS ( PDBProvider  )

Member Data Documentation

dbEventCtx PDBProvider::event_context

Definition at line 65 of file pdb.h.

size_t PDBProvider::num_instances
static

Definition at line 67 of file pdb.h.

persist_pv_map_t PDBProvider::persist_pv_map

Definition at line 60 of file pdb.h.

transient_pv_map_t PDBProvider::transient_pv_map

Definition at line 63 of file pdb.h.


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