diff --git a/.nojekyll b/.nojekyll new file mode 100644 index 0000000..e69de29 diff --git a/annotated.html b/annotated.html new file mode 100644 index 0000000..826422f --- /dev/null +++ b/annotated.html @@ -0,0 +1,170 @@ + + + + + + +pva2pva: Class List + + + + + + + + + +
+
+ + + + + + +
+
pva2pva +  1.4.1 +
+
+
+ + + + + +
+ +
+ All Classes Functions Variables Pages
+ + +
+ +
+ +
+
+
Class List
+
+
+
Here are the classes, structs, unions and interfaces with brief descriptions:
+
[detail level 123]
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
oNpvalink
|oCpvaLinkConfig
|oCpvaGlobal_t
|oCpvaLinkChannel
||oCAfterPut
||\CLinkSort
|\CpvaLink
oCASCLIENT
oCASCred
oCAsWritePvt
oCBaseChannel
oCBaseChannelProviderFactory
oCBaseMonitor
|\Cno_overflow
oCChannelCache
|\CcacheClean
oCChannelCacheEntry
|\CCRequester
oCDBCH
oCDBEvent
oCdbrbuf
oCDBScanLocker
oCFieldName
|\CComponent
oCGroupConfig
|oCField
|\CGroup
oCGWChannel
oCGWServerChannelProvider
oCjlif
oCLocalFL
oCMonitorCacheEntry
oCMonitorUser
oCPDBGroupChannel
oCPDBGroupMonitor
oCPDBGroupPut
oCPDBGroupPV
|\CInfo
oCpdbInfoIterator
oCPDBProvider
oCPDBPV
oCpdbRecordInfo
oCpdbRecordIterator
oCPDBSingleChannel
oCPDBSingleMonitor
oCPDBSinglePut
oCPDBSinglePV
oCPVIF
oCPVIFBuilder
oCSB
oCScalarAccessor
oCScalarBuilder
oCServerConfig
oCTestChannelFieldRequester
oCTestChannelGetRequester
oCTestChannelMonitorRequester
oCTestChannelPutRequester
oCTestChannelRequester
oCTestIOC
oCTestProvider
oCTestPV
oCTestPVChannel
oCTestPVMonitor
oCweak_setStd::set-ish container where entries are removed when ref. counts fall to zero
|\CXIteratorIterator-ish object which also locks the set during iteration
oCweak_value_mapAn associative map where a weak_ptr to the value is stored
|\Celement_proxy
\CWorkQueue
+
+
+ + + + diff --git a/bc_s.png b/bc_s.png new file mode 100644 index 0000000..224b29a Binary files /dev/null and b/bc_s.png differ diff --git a/bdwn.png b/bdwn.png new file mode 100644 index 0000000..940a0b9 Binary files /dev/null and b/bdwn.png differ diff --git a/chancache_8cpp_source.html b/chancache_8cpp_source.html new file mode 100644 index 0000000..e92aabf --- /dev/null +++ b/chancache_8cpp_source.html @@ -0,0 +1,313 @@ + + + + + + +pva2pva: p2pApp/chancache.cpp Source File + + + + + + + + + +
+
+ + + + + + +
+
pva2pva +  1.4.1 +
+
+
+ + + + + + +
+ All Classes Functions Variables Pages
+ + +
+ +
+ + +
+
+
+
chancache.cpp
+
+
+
1 #include <stdio.h>
+
2 
+
3 #include <epicsAtomic.h>
+
4 #include <errlog.h>
+
5 
+
6 #include <epicsMutex.h>
+
7 #include <epicsTimer.h>
+
8 
+
9 #include <pv/epicsException.h>
+
10 #include <pv/serverContext.h>
+
11 #include <pv/pvAccess.h>
+
12 
+
13 #define epicsExportSharedSymbols
+
14 #include "pva2pva.h"
+
15 #include "helper.h"
+
16 #include "chancache.h"
+
17 #include "channel.h"
+
18 
+
19 namespace pvd = epics::pvData;
+
20 namespace pva = epics::pvAccess;
+
21 
+
22 size_t ChannelCacheEntry::num_instances;
+
23 
+
24 ChannelCacheEntry::ChannelCacheEntry(ChannelCache* c, const std::string& n)
+
25  :channelName(n), cache(c), dropPoke(true)
+
26 {
+
27  epicsAtomicIncrSizeT(&num_instances);
+
28 }
+
29 
+
30 ChannelCacheEntry::~ChannelCacheEntry()
+
31 {
+
32  // Should *not* be holding cache->cacheLock
+
33  if(channel.get())
+
34  channel->destroy(); // calls channelStateChange() w/ DESTROY
+
35  epicsAtomicDecrSizeT(&num_instances);
+
36 }
+
37 
+
38 std::string
+
39 ChannelCacheEntry::CRequester::getRequesterName()
+
40 {
+
41  return "GWClient";
+
42 }
+
43 
+
44 size_t ChannelCacheEntry::CRequester::num_instances;
+
45 
+
46 ChannelCacheEntry::CRequester::CRequester(const ChannelCacheEntry::shared_pointer& p)
+
47  :chan(p)
+
48 {
+
49  epicsAtomicIncrSizeT(&num_instances);
+
50 }
+
51 
+
52 ChannelCacheEntry::CRequester::~CRequester()
+
53 {
+
54  epicsAtomicDecrSizeT(&num_instances);
+
55 }
+
56 
+
57 // for ChannelRequester
+
58 void
+
59 ChannelCacheEntry::CRequester::channelCreated(const pvd::Status& status,
+
60  pva::Channel::shared_pointer const & channel)
+
61 {}
+
62 
+
63 void
+
64 ChannelCacheEntry::CRequester::channelStateChange(pva::Channel::shared_pointer const & channel,
+
65  pva::Channel::ConnectionState connectionState)
+
66 {
+
67  ChannelCacheEntry::shared_pointer chan(this->chan.lock());
+
68  if(!chan)
+
69  return;
+
70 
+
71  {
+
72  Guard G(chan->cache->cacheLock);
+
73 
+
74  assert(chan->channel.get()==channel.get());
+
75 
+
76  switch(connectionState)
+
77  {
+
78  case pva::Channel::DISCONNECTED:
+
79  case pva::Channel::DESTROYED:
+
80  // Drop from cache
+
81  chan->cache->entries.erase(chan->channelName);
+
82  // keep 'chan' as a reference so that actual destruction doesn't happen which cacheLock is held
+
83  break;
+
84  default:
+
85  break;
+
86  }
+
87  }
+
88 
+
89  // fanout notification
+
90  ChannelCacheEntry::interested_t::vector_type interested(chan->interested.lock_vector()); // Copy
+
91 
+
92  FOREACH(ChannelCacheEntry::interested_t::vector_type::const_iterator, it, end, interested)
+
93  {
+
94  GWChannel *chan = it->get();
+
95  pva::ChannelRequester::shared_pointer req(chan->requester.lock());
+
96  if(req)
+
97  req->channelStateChange(*it, connectionState);
+
98  }
+
99 }
+
100 
+
101 
+
102 struct ChannelCache::cacheClean : public epicsTimerNotify
+
103 {
+
104  ChannelCache *cache;
+
105  cacheClean(ChannelCache *c) : cache(c) {}
+
106  epicsTimerNotify::expireStatus expire(const epicsTime &currentTime)
+
107  {
+
108  // keep a reference to any cache entrys being removed so they
+
109  // aren't destroyed while cacheLock is held
+
110  std::set<ChannelCacheEntry::shared_pointer> cleaned;
+
111 
+
112  {
+
113  Guard G(cache->cacheLock);
+
114  cache->cleanerRuns++;
+
115 
+
116  ChannelCache::entries_t::iterator cur=cache->entries.begin(), next, end=cache->entries.end();
+
117  while(cur!=end) {
+
118  next = cur;
+
119  ++next;
+
120 
+
121  if(!cur->second->dropPoke && cur->second->interested.empty()) {
+
122  cleaned.insert(cur->second);
+
123  cache->entries.erase(cur);
+
124  cache->cleanerDust++;
+
125  } else {
+
126  cur->second->dropPoke = false;
+
127  }
+
128 
+
129  cur = next;
+
130  }
+
131  }
+
132  return epicsTimerNotify::expireStatus(epicsTimerNotify::restart, 30.0);
+
133  }
+
134 };
+
135 
+
136 ChannelCache::ChannelCache(const pva::ChannelProvider::shared_pointer& prov)
+
137  :provider(prov)
+
138  ,timerQueue(&epicsTimerQueueActive::allocate(1, epicsThreadPriorityCAServerLow-2))
+
139  ,cleaner(new cacheClean(this))
+
140  ,cleanerRuns(0)
+
141  ,cleanerDust(0)
+
142 {
+
143  if(!provider)
+
144  throw std::logic_error("Missing 'pva' provider");
+
145  assert(timerQueue);
+
146  cleanTimer = &timerQueue->createTimer();
+
147  cleanTimer->start(*cleaner, 30.0);
+
148 }
+
149 
+
150 ChannelCache::~ChannelCache()
+
151 {
+
152  entries_t E;
+
153  {
+
154  Guard G(cacheLock);
+
155 
+
156  cleanTimer->destroy();
+
157  timerQueue->release();
+
158  delete cleaner;
+
159 
+
160  entries_t E;
+
161  E.swap(entries);
+
162  }
+
163 }
+
164 
+
165 ChannelCacheEntry::shared_pointer
+
166 ChannelCache::lookup(const std::string& newName)
+
167 {
+
168  ChannelCacheEntry::shared_pointer ret;
+
169 
+
170  Guard G(cacheLock);
+
171 
+
172  entries_t::const_iterator it = entries.find(newName);
+
173 
+
174  if(it==entries.end()) {
+
175  // first request, create ChannelCacheEntry
+
176  //TODO: async lookup
+
177 
+
178  ChannelCacheEntry::shared_pointer ent(new ChannelCacheEntry(this, newName));
+
179  ent->requester.reset(new ChannelCacheEntry::CRequester(ent));
+
180 
+
181  entries[newName] = ent;
+
182 
+
183  pva::Channel::shared_pointer M;
+
184  {
+
185  // unlock to call createChannel()
+
186  epicsGuardRelease<epicsMutex> U(G);
+
187 
+
188  M = provider->createChannel(newName, ent->requester);
+
189  if(!M)
+
190  THROW_EXCEPTION2(std::runtime_error, "Failed to createChannel");
+
191  }
+
192  ent->channel = M;
+
193 
+
194  if(M->isConnected())
+
195  ret = ent; // immediate connect, mostly for unit-tests (thus delayed connect not covered)
+
196 
+
197  } else if(it->second->channel && it->second->channel->isConnected()) {
+
198  // another request, and hey we're connected this time
+
199 
+
200  ret = it->second;
+
201  it->second->dropPoke = true;
+
202 
+
203  } else {
+
204  // not connected yet, but a client is still interested
+
205  it->second->dropPoke = true;
+
206  }
+
207 
+
208  return ret;
+
209 }
+
Definition: chancache.h:132
+
Definition: chancache.h:103
+ + + +
+ + + + diff --git a/chancache_8h_source.html b/chancache_8h_source.html new file mode 100644 index 0000000..1aa6774 --- /dev/null +++ b/chancache_8h_source.html @@ -0,0 +1,281 @@ + + + + + + +pva2pva: p2pApp/chancache.h Source File + + + + + + + + + +
+
+ + + + + + +
+
pva2pva +  1.4.1 +
+
+
+ + + + + + +
+ All Classes Functions Variables Pages
+ + +
+ +
+ + +
+
+
+
chancache.h
+
+
+
1 #ifndef CHANCACHE_H
+
2 #define CHANCACHE_H
+
3 
+
4 #include <string>
+
5 #include <map>
+
6 #include <set>
+
7 #include <deque>
+
8 
+
9 #include <epicsMutex.h>
+
10 #include <epicsTimer.h>
+
11 
+
12 #include <pv/pvAccess.h>
+
13 
+
14 #include "weakmap.h"
+
15 #include "weakset.h"
+
16 
+
17 struct ChannelCache;
+
18 struct ChannelCacheEntry;
+
19 struct MonitorUser;
+
20 struct GWChannel;
+
21 
+
22 struct MonitorCacheEntry : public epics::pvData::MonitorRequester
+
23 {
+
24  POINTER_DEFINITIONS(MonitorCacheEntry);
+
25  static size_t num_instances;
+
26  weak_pointer weakref;
+
27 
+
28  ChannelCacheEntry * const chan;
+
29 
+
30  const size_t bufferSize; // DS requested buffer size
+
31 
+
32  // to avoid yet another mutex borrow interested.mutex() for our members
+
33  inline epicsMutex& mutex() const { return interested.mutex(); }
+
34 
+
35  typedef std::vector<epicsUInt8> pvrequest_t;
+
36 
+
37  bool havedata; // set when initial update is received
+
38  bool done; // set when unlisten() is received
+
39  size_t nwakeups; // # of upstream monitorEvent() calls
+
40  size_t nevents; // # of upstream events poll()'d
+
41 
+
42  epics::pvData::StructureConstPtr typedesc;
+
46  epics::pvData::MonitorElement::shared_pointer lastelem;
+
47  epics::pvData::MonitorPtr mon;
+
48  epics::pvData::Status startresult;
+
49 
+ +
51  interested_t interested;
+
52 
+
53  MonitorCacheEntry(ChannelCacheEntry *ent, const epics::pvData::PVStructure::shared_pointer& pvr);
+
54  virtual ~MonitorCacheEntry();
+
55 
+
56  virtual void monitorConnect(epics::pvData::Status const & status,
+
57  epics::pvData::MonitorPtr const & monitor,
+
58  epics::pvData::StructureConstPtr const & structure);
+
59  virtual void monitorEvent(epics::pvData::MonitorPtr const & monitor);
+
60  virtual void unlisten(epics::pvData::MonitorPtr const & monitor);
+
61 
+
62  virtual std::string getRequesterName();
+
63 };
+
64 
+
65 struct MonitorUser : public epics::pvData::Monitor
+
66 {
+
67  POINTER_DEFINITIONS(MonitorUser);
+
68  static size_t num_instances;
+
69  weak_pointer weakref;
+
70 
+
71  inline epicsMutex& mutex() const { return entry->mutex(); }
+
72 
+
73  MonitorCacheEntry::shared_pointer entry;
+
74  epics::pvData::MonitorRequester::weak_pointer req;
+
75  std::tr1::weak_ptr<GWChannel> srvchan;
+
76 
+
77  // guards queues and member variables
+
78  bool initial;
+
79  bool running;
+
80  bool inoverflow;
+
81  size_t nwakeups; // # of monitorEvent() calls to req
+
82  size_t nevents; // total # events queued
+
83  size_t ndropped; // # of events drop because our queue was full
+
84 
+
85  std::deque<epics::pvData::MonitorElementPtr> filled, empty;
+
86  std::set<epics::pvData::MonitorElementPtr> inuse;
+
87 
+
88  epics::pvData::MonitorElementPtr overflowElement;
+
89 
+
90  MonitorUser(const MonitorCacheEntry::shared_pointer&);
+
91  virtual ~MonitorUser();
+
92 
+
93  virtual void destroy();
+
94 
+
95  virtual epics::pvData::Status start();
+
96  virtual epics::pvData::Status stop();
+
97  virtual epics::pvData::MonitorElementPtr poll();
+
98  virtual void release(epics::pvData::MonitorElementPtr const & monitorElement);
+
99 
+
100  virtual std::string getRequesterName();
+
101 };
+
102 
+ +
104 {
+
105  POINTER_DEFINITIONS(ChannelCacheEntry);
+
106  static size_t num_instances;
+
107 
+
108  const std::string channelName;
+
109  ChannelCache * const cache;
+
110 
+
111  // to avoid yet another mutex borrow interested.mutex() for our members
+
112  inline epicsMutex& mutex() const { return interested.mutex(); }
+
113 
+
114  // clientChannel
+
115  epics::pvAccess::Channel::shared_pointer channel;
+
116  epics::pvAccess::ChannelRequester::shared_pointer requester;
+
117 
+
118  bool dropPoke;
+
119 
+ +
121  interested_t interested;
+
122 
+
123  typedef MonitorCacheEntry::pvrequest_t pvrequest_t;
+ +
125  mon_entries_t mon_entries;
+
126 
+
127  ChannelCacheEntry(ChannelCache*, const std::string& n);
+
128  virtual ~ChannelCacheEntry();
+
129 
+
130  // this exists as a seperate object to prevent a reference loop
+
131  // ChannelCacheEntry -> pva::Channel -> CRequester
+
132  struct CRequester : public epics::pvAccess::ChannelRequester
+
133  {
+
134  static size_t num_instances;
+
135 
+
136  CRequester(const ChannelCacheEntry::shared_pointer& p);
+
137  virtual ~CRequester();
+
138  ChannelCacheEntry::weak_pointer chan;
+
139  // for Requester
+
140  virtual std::string getRequesterName();
+
141  // for ChannelRequester
+
142  virtual void channelCreated(const epics::pvData::Status& status,
+
143  epics::pvAccess::Channel::shared_pointer const & channel);
+
144  virtual void channelStateChange(epics::pvAccess::Channel::shared_pointer const & channel,
+
145  epics::pvAccess::Channel::ConnectionState connectionState);
+
146  };
+
147 };
+
148 
+ +
152 {
+
153  typedef std::map<std::string, ChannelCacheEntry::shared_pointer > entries_t;
+
154 
+
155  // cacheLock should not be held while calling *Requester methods
+
156  epicsMutex cacheLock;
+
157 
+
158  entries_t entries;
+
159 
+
160  epics::pvAccess::ChannelProvider::shared_pointer provider; // client Provider
+
161 
+
162  epicsTimerQueueActive *timerQueue;
+
163  epicsTimer *cleanTimer;
+
164  struct cacheClean;
+
165  cacheClean *cleaner;
+
166  size_t cleanerRuns;
+
167  size_t cleanerDust;
+
168 
+
169  ChannelCache(const epics::pvAccess::ChannelProvider::shared_pointer& prov);
+
170  ~ChannelCache();
+
171 
+
172  ChannelCacheEntry::shared_pointer lookup(const std::string& name);
+
173 };
+
174 
+
175 #endif // CHANCACHE_H
+
176 
+
epics::pvData::MonitorElement::shared_pointer lastelem
Definition: chancache.h:46
+
Definition: chancache.h:132
+
Definition: chancache.h:103
+ + +
epicsMutex & mutex() const
Definition: weakset.h:199
+ + +
Definition: chancache.h:22
+ + +
+ + + + diff --git a/channel_8cpp_source.html b/channel_8cpp_source.html new file mode 100644 index 0000000..0699055 --- /dev/null +++ b/channel_8cpp_source.html @@ -0,0 +1,346 @@ + + + + + + +pva2pva: p2pApp/channel.cpp Source File + + + + + + + + + +
+
+ + + + + + +
+
pva2pva +  1.4.1 +
+
+
+ + + + + + +
+ All Classes Functions Variables Pages
+ + +
+ +
+ + +
+
+
+
channel.cpp
+
+
+
1 
+
2 #include <epicsAtomic.h>
+
3 
+
4 #include <epicsTimer.h>
+
5 #include <epicsMutex.h>
+
6 #include <epicsGuard.h>
+
7 #include <epicsEndian.h>
+
8 
+
9 #include <pv/iocshelper.h>
+
10 
+
11 #include <pv/pvAccess.h>
+
12 
+
13 #define epicsExportSharedSymbols
+
14 #include "helper.h"
+
15 #include "pva2pva.h"
+
16 #include "channel.h"
+
17 
+
18 namespace pva = epics::pvAccess;
+
19 namespace pvd = epics::pvData;
+
20 
+
21 int p2pReadOnly = 0;
+
22 
+
23 size_t GWChannel::num_instances;
+
24 
+
25 GWChannel::GWChannel(const ChannelCacheEntry::shared_pointer& e,
+
26  const epics::pvAccess::ChannelProvider::weak_pointer& srvprov,
+
27  const epics::pvAccess::ChannelRequester::weak_pointer &r,
+
28  const std::string& addr)
+
29  :entry(e)
+
30  ,requester(r)
+
31  ,address(addr)
+
32  ,server_provder(srvprov)
+
33 {
+
34  epicsAtomicIncrSizeT(&num_instances);
+
35 }
+
36 
+
37 GWChannel::~GWChannel()
+
38 {
+
39  epicsAtomicDecrSizeT(&num_instances);
+
40 }
+
41 
+
42 std::string
+
43 GWChannel::getRequesterName()
+
44 {
+
45  return "GWChannel";
+
46 }
+
47 
+
48 void
+
49 GWChannel::destroy()
+
50 {}
+
51 
+
52 std::tr1::shared_ptr<pva::ChannelProvider>
+
53 GWChannel::getProvider()
+
54 {
+
55  return pva::ChannelProvider::shared_pointer(server_provder);
+
56 }
+
57 
+
58 std::string
+
59 GWChannel::getRemoteAddress()
+
60 {
+
61  // pass through address of origin server (information leak?)
+
62  return entry->channel->getRemoteAddress();
+
63 }
+
64 
+
65 pva::Channel::ConnectionState
+
66 GWChannel::getConnectionState()
+
67 {
+
68  return entry->channel->getConnectionState();
+
69 }
+
70 
+
71 std::string
+
72 GWChannel::getChannelName()
+
73 {
+
74  return entry->channelName;
+
75 }
+
76 
+
77 std::tr1::shared_ptr<pva::ChannelRequester>
+
78 GWChannel::getChannelRequester()
+
79 {
+
80  return pva::ChannelRequester::shared_pointer(requester);
+
81 }
+
82 
+
83 
+
84 void
+
85 GWChannel::getField(pva::GetFieldRequester::shared_pointer const & requester,
+
86  std::string const & subField)
+
87 {
+
88  //TODO: cache for top level field?
+
89  entry->channel->getField(requester, subField);
+
90 }
+
91 
+
92 pva::AccessRights
+
93 GWChannel::getAccessRights(pvd::PVField::shared_pointer const & pvField)
+
94 {
+
95  return entry->channel->getAccessRights(pvField);
+
96 }
+
97 
+
98 pva::ChannelProcess::shared_pointer
+
99 GWChannel::createChannelProcess(
+
100  pva::ChannelProcessRequester::shared_pointer const & channelProcessRequester,
+
101  pvd::PVStructure::shared_pointer const & pvRequest)
+
102 {
+
103  if(!p2pReadOnly)
+
104  return entry->channel->createChannelProcess(channelProcessRequester, pvRequest);
+
105  else
+
106  return Channel::createChannelProcess(channelProcessRequester, pvRequest);
+
107 }
+
108 
+
109 pva::ChannelGet::shared_pointer
+
110 GWChannel::createChannelGet(
+
111  pva::ChannelGetRequester::shared_pointer const & channelGetRequester,
+
112  pvd::PVStructure::shared_pointer const & pvRequest)
+
113 {
+
114  return entry->channel->createChannelGet(channelGetRequester, pvRequest);
+
115 }
+
116 
+
117 pva::ChannelPut::shared_pointer
+
118 GWChannel::createChannelPut(
+
119  pva::ChannelPutRequester::shared_pointer const & channelPutRequester,
+
120  pvd::PVStructure::shared_pointer const & pvRequest)
+
121 {
+
122  //TODO: allow ChannelPut::get()
+
123  if(!p2pReadOnly)
+
124  return entry->channel->createChannelPut(channelPutRequester, pvRequest);
+
125  else
+
126  return Channel::createChannelPut(channelPutRequester, pvRequest);
+
127 }
+
128 
+
129 pva::ChannelPutGet::shared_pointer
+
130 GWChannel::createChannelPutGet(
+
131  pva::ChannelPutGetRequester::shared_pointer const & channelPutGetRequester,
+
132  pvd::PVStructure::shared_pointer const & pvRequest)
+
133 {
+
134  if(!p2pReadOnly)
+
135  return entry->channel->createChannelPutGet(channelPutGetRequester, pvRequest);
+
136  else
+
137  return Channel::createChannelPutGet(channelPutGetRequester, pvRequest);
+
138 }
+
139 
+
140 pva::ChannelRPC::shared_pointer
+
141 GWChannel::createChannelRPC(
+
142  pva::ChannelRPCRequester::shared_pointer const & channelRPCRequester,
+
143  pvd::PVStructure::shared_pointer const & pvRequest)
+
144 {
+
145  if(!p2pReadOnly)
+
146  return entry->channel->createChannelRPC(channelRPCRequester, pvRequest);
+
147  else
+
148  return Channel::createChannelRPC(channelRPCRequester, pvRequest);
+
149 }
+
150 
+
151 namespace {
+
152 struct noclean {
+
153  void operator()(MonitorCacheEntry *) {}
+
154 };
+
155 }
+
156 
+
157 pvd::Monitor::shared_pointer
+
158 GWChannel::createMonitor(
+
159  pvd::MonitorRequester::shared_pointer const & monitorRequester,
+
160  pvd::PVStructure::shared_pointer const & pvRequest)
+
161 {
+
162  ChannelCacheEntry::pvrequest_t ser;
+
163  // serialize request struct to string using host byte order (only used for local comparison)
+
164  pvd::serializeToVector(pvRequest.get(), EPICS_BYTE_ORDER, ser);
+
165 
+
166  MonitorCacheEntry::shared_pointer ment;
+
167  MonitorUser::shared_pointer mon;
+
168 
+
169  pvd::Status startresult;
+
170  pvd::StructureConstPtr typedesc;
+
171 
+
172  try {
+
173  {
+
174  Guard G(entry->mutex());
+
175 
+
176  // TODO: no-cache/no-share flag in pvRequest
+
177 
+
178  ment = entry->mon_entries.find(ser);
+
179  if(!ment) {
+
180  ment.reset(new MonitorCacheEntry(entry.get(), pvRequest));
+
181  entry->mon_entries[ser] = ment; // ref. wrapped
+
182  ment->weakref = ment;
+
183 
+
184  // We've added an incomplete entry (no Monitor)
+
185  // so MonitorUser must check validity before de-ref.
+
186  // in this case we use !!typedesc as this also indicates
+
187  // that the upstream monitor is connected
+
188  pvd::MonitorPtr M;
+
189  {
+
190  UnGuard U(G);
+
191 
+
192  M = entry->channel->createMonitor(ment, pvRequest);
+
193  }
+
194  ment->mon = M;
+
195  }
+
196  }
+
197 
+
198  Guard G(ment->mutex());
+
199 
+
200  mon.reset(new MonitorUser(ment));
+
201  ment->interested.insert(mon);
+
202  mon->weakref = mon;
+
203  mon->srvchan = shared_pointer(weakref);
+
204  mon->req = monitorRequester;
+
205 
+
206  typedesc = ment->typedesc;
+
207  startresult = ment->startresult;
+
208 
+
209  } catch(std::exception& e) {
+
210  mon.reset();
+
211  std::cerr<<"Exception in GWChannel::createMonitor()\n"
+
212  "is "<<e.what()<<"\n";
+
213  startresult = pvd::Status(pvd::Status::STATUSTYPE_FATAL, "Error during GWChannel setup");
+
214  }
+
215 
+
216  // unlock for callback
+
217 
+
218  if(typedesc || !startresult.isSuccess()) {
+
219  // upstream monitor already connected, or never will be.
+
220  monitorRequester->monitorConnect(startresult, mon, typedesc);
+
221  }
+
222 
+
223  return mon;
+
224 }
+
225 
+
226 pva::ChannelArray::shared_pointer
+
227 GWChannel::createChannelArray(
+
228  pva::ChannelArrayRequester::shared_pointer const & channelArrayRequester,
+
229  pvd::PVStructure::shared_pointer const & pvRequest)
+
230 {
+
231  return entry->channel->createChannelArray(channelArrayRequester, pvRequest);
+
232 }
+
233 
+
234 
+
235 void
+
236 GWChannel::printInfo(std::ostream& out)
+
237 {
+
238  out<<"GWChannel for "<<entry->channelName<<"\n";
+
239 }
+
240 
+
241 
+
242 void registerReadOnly()
+
243 {
+
244  epics::iocshVariable<int, &p2pReadOnly>("p2pReadOnly");
+
245 }
+
Definition: chancache.h:22
+ +
+ + + + diff --git a/channel_8h_source.html b/channel_8h_source.html new file mode 100644 index 0000000..f13a535 --- /dev/null +++ b/channel_8h_source.html @@ -0,0 +1,169 @@ + + + + + + +pva2pva: p2pApp/channel.h Source File + + + + + + + + + +
+
+ + + + + + +
+
pva2pva +  1.4.1 +
+
+
+ + + + + + +
+ All Classes Functions Variables Pages
+ + +
+ +
+ + +
+
+
+
channel.h
+
+
+
1 #ifndef CHANNEL_H
+
2 #define CHANNEL_H
+
3 
+
4 #include <pv/pvAccess.h>
+
5 
+
6 #include "chancache.h"
+
7 
+
8 struct GWChannel : public epics::pvAccess::Channel
+
9 {
+
10  POINTER_DEFINITIONS(GWChannel);
+
11  static size_t num_instances;
+
12  weak_pointer weakref;
+
13 
+
14  const ChannelCacheEntry::shared_pointer entry;
+
15  const requester_type::weak_pointer requester;
+
16  const std::string address; // address of client on GW server side
+
17  const epics::pvAccess::ChannelProvider::weak_pointer server_provder;
+
18 
+
19  GWChannel(const ChannelCacheEntry::shared_pointer& e,
+
20  const epics::pvAccess::ChannelProvider::weak_pointer& srvprov,
+
21  const requester_type::weak_pointer&,
+
22  const std::string& addr);
+
23  virtual ~GWChannel();
+
24 
+
25 
+
26  // for Requester
+
27  virtual std::string getRequesterName();
+
28 
+
29  // for Destroyable
+
30  virtual void destroy();
+
31 
+
32  // for Channel
+
33  virtual std::tr1::shared_ptr<epics::pvAccess::ChannelProvider> getProvider();
+
34  virtual std::string getRemoteAddress();
+
35 
+
36  virtual ConnectionState getConnectionState();
+
37  virtual std::string getChannelName();
+
38  virtual std::tr1::shared_ptr<epics::pvAccess::ChannelRequester> getChannelRequester();
+
39 
+
40  virtual void getField(epics::pvAccess::GetFieldRequester::shared_pointer const & requester,
+
41  std::string const & subField);
+
42  virtual epics::pvAccess::AccessRights getAccessRights(epics::pvData::PVField::shared_pointer const & pvField);
+
43  virtual epics::pvAccess::ChannelProcess::shared_pointer createChannelProcess(
+
44  epics::pvAccess::ChannelProcessRequester::shared_pointer const & channelProcessRequester,
+
45  epics::pvData::PVStructure::shared_pointer const & pvRequest);
+
46  virtual epics::pvAccess::ChannelGet::shared_pointer createChannelGet(
+
47  epics::pvAccess::ChannelGetRequester::shared_pointer const & channelGetRequester,
+
48  epics::pvData::PVStructure::shared_pointer const & pvRequest);
+
49  virtual epics::pvAccess::ChannelPut::shared_pointer createChannelPut(
+
50  epics::pvAccess::ChannelPutRequester::shared_pointer const & channelPutRequester,
+
51  epics::pvData::PVStructure::shared_pointer const & pvRequest);
+
52  virtual epics::pvAccess::ChannelPutGet::shared_pointer createChannelPutGet(
+
53  epics::pvAccess::ChannelPutGetRequester::shared_pointer const & channelPutGetRequester,
+
54  epics::pvData::PVStructure::shared_pointer const & pvRequest);
+
55  virtual epics::pvAccess::ChannelRPC::shared_pointer createChannelRPC(
+
56  epics::pvAccess::ChannelRPCRequester::shared_pointer const & channelRPCRequester,
+
57  epics::pvData::PVStructure::shared_pointer const & pvRequest);
+
58  virtual epics::pvData::Monitor::shared_pointer createMonitor(
+
59  epics::pvData::MonitorRequester::shared_pointer const & monitorRequester,
+
60  epics::pvData::PVStructure::shared_pointer const & pvRequest);
+
61  virtual epics::pvAccess::ChannelArray::shared_pointer createChannelArray(
+
62  epics::pvAccess::ChannelArrayRequester::shared_pointer const & channelArrayRequester,
+
63  epics::pvData::PVStructure::shared_pointer const & pvRequest);
+
64 
+
65  virtual void printInfo(std::ostream& out);
+
66 
+
67 };
+
68 
+
69 #endif // CHANNEL_H
+ +
+ + + + diff --git a/class_as_write_pvt-members.html b/class_as_write_pvt-members.html new file mode 100644 index 0000000..772b0a4 --- /dev/null +++ b/class_as_write_pvt-members.html @@ -0,0 +1,105 @@ + + + + + + +pva2pva: Member List + + + + + + + + + +
+
+ + + + + + +
+
pva2pva +  1.4.1 +
+
+
+ + + + + + +
+ All Classes Functions Variables Pages
+ + +
+ +
+ +
+
+
+
AsWritePvt Member List
+
+
+ +

This is the complete list of members for AsWritePvt, including all inherited members.

+ + + + + +
AsWritePvt() (defined in AsWritePvt)AsWritePvtinline
AsWritePvt(void *pvt) (defined in AsWritePvt)AsWritePvtinlineexplicit
swap(AsWritePvt &o) (defined in AsWritePvt)AsWritePvtinline
~AsWritePvt() (defined in AsWritePvt)AsWritePvtinline
+ + + + diff --git a/class_as_write_pvt.html b/class_as_write_pvt.html new file mode 100644 index 0000000..bda8a9d --- /dev/null +++ b/class_as_write_pvt.html @@ -0,0 +1,117 @@ + + + + + + +pva2pva: AsWritePvt Class Reference + + + + + + + + + +
+
+ + + + + + +
+
pva2pva +  1.4.1 +
+
+
+ + + + + + +
+ All Classes Functions Variables Pages
+ + +
+ +
+ +
+
+
+Public Member Functions | +List of all members
+
+
AsWritePvt Class Reference
+
+
+ + + + + + +

+Public Member Functions

AsWritePvt (void *pvt)
 
+void swap (AsWritePvt &o)
 
+

Detailed Description

+
+

Definition at line 77 of file pdb.h.

+

The documentation for this class was generated from the following file: +
+ + + + diff --git a/classes.html b/classes.html new file mode 100644 index 0000000..ed393ee --- /dev/null +++ b/classes.html @@ -0,0 +1,142 @@ + + + + + + +pva2pva: Class Index + + + + + + + + + +
+
+ + + + + + +
+
pva2pva +  1.4.1 +
+
+
+ + + + + +
+ +
+ All Classes Functions Variables Pages
+ + +
+ +
+ +
+
+
Class Index
+
+
+
A | B | C | D | E | F | G | I | J | L | M | N | P | S | T | W | X
+ + + + + + + + + + + + + + + + + + + + + + + + +
  A  
+
DBEvent   
  L  
+
pdbRecordIterator   TestChannelMonitorRequester   
dbrbuf   PDBSingleChannel   TestChannelPutRequester   
pvaLinkChannel::AfterPut (pvalink)   DBScanLocker   pvaLinkChannel::LinkSort (pvalink)   PDBSingleMonitor   TestChannelRequester   
ASCLIENT   
  E  
+
LocalFL   PDBSinglePut   TestIOC   
ASCred   
  M  
+
PDBSinglePV   TestProvider   
AsWritePvt   weak_value_map::element_proxy   pvaGlobal_t (pvalink)   TestPV   
  B  
+
  F  
+
MonitorCacheEntry   pvaLink (pvalink)   TestPVChannel   
MonitorUser   pvaLinkChannel (pvalink)   TestPVMonitor   
BaseChannel   GroupConfig::Field   
  N  
+
pvaLinkConfig (pvalink)   
  W  
+
BaseChannelProviderFactory   FieldName   PVIF   
BaseMonitor   
  G  
+
BaseMonitor::no_overflow   PVIFBuilder   weak_set   
  C  
+
  P  
+
  S  
+
weak_value_map   
GroupConfig::Group   WorkQueue   
ChannelCache::cacheClean   GroupConfig   PDBGroupChannel   SB   
  X  
+
ChannelCache   GWChannel   PDBGroupMonitor   ScalarAccessor   
ChannelCacheEntry   GWServerChannelProvider   PDBGroupPut   ScalarBuilder   weak_set::XIterator   
FieldName::Component   
  I  
+
PDBGroupPV   ServerConfig   
ChannelCacheEntry::CRequester   pdbInfoIterator   
  T  
+
  D  
+
PDBGroupPV::Info   PDBProvider   
  J  
+
PDBPV   TestChannelFieldRequester   
DBCH   pdbRecordInfo   TestChannelGetRequester   
jlif   
+
A | B | C | D | E | F | G | I | J | L | M | N | P | S | T | W | X
+
+ + + + diff --git a/classweak__set-members.html b/classweak__set-members.html new file mode 100644 index 0000000..74b2c43 --- /dev/null +++ b/classweak__set-members.html @@ -0,0 +1,121 @@ + + + + + + +pva2pva: Member List + + + + + + + + + +
+
+ + + + + + +
+
pva2pva +  1.4.1 +
+
+
+ + + + + + +
+ All Classes Functions Variables Pages
+ + +
+ +
+ +
+
+
+
weak_set< T > Member List
+
+
+ +

This is the complete list of members for weak_set< T >, including all inherited members.

+ + + + + + + + + + + + + + + + + + + + + +
clear()weak_set< T >inline
empty() const weak_set< T >inline
erase(value_pointer &v)weak_set< T >inline
guard_type typedef (defined in weak_set< T >)weak_set< T >
insert(value_pointer &)weak_set< T >
iterator typedef (defined in weak_set< T >)weak_set< T >
lock_set() const weak_set< T >
lock_vector() const weak_set< T >
lock_vector(vector_type &) const (defined in weak_set< T >)weak_set< T >
mutex() const weak_set< T >inline
mutex_type typedef (defined in weak_set< T >)weak_set< T >
release_type typedef (defined in weak_set< T >)weak_set< T >
set_type typedef (defined in weak_set< T >)weak_set< T >
size() const weak_set< T >inline
swap(weak_set &O)weak_set< T >inline
value_pointer typedef (defined in weak_set< T >)weak_set< T >
value_type typedef (defined in weak_set< T >)weak_set< T >
value_weak_pointer typedef (defined in weak_set< T >)weak_set< T >
vector_type typedef (defined in weak_set< T >)weak_set< T >
weak_set()weak_set< T >inline
+ + + + diff --git a/classweak__set.html b/classweak__set.html new file mode 100644 index 0000000..5eb4c27 --- /dev/null +++ b/classweak__set.html @@ -0,0 +1,515 @@ + + + + + + +pva2pva: weak_set< T > Class Template Reference + + + + + + + + + +
+
+ + + + + + +
+
pva2pva +  1.4.1 +
+
+
+ + + + + + +
+ All Classes Functions Variables Pages
+ + +
+ +
+ +
+
+
+Classes | +Public Types | +Public Member Functions | +List of all members
+
+
weak_set< T > Class Template Reference
+
+
+ +

a std::set-ish container where entries are removed when ref. counts fall to zero + More...

+ +

#include <weakset.h>

+ + + + + +

+Classes

struct  XIterator
 an iterator-ish object which also locks the set during iteration More...
 
+ + + + + + + + + + + + + + + + + + + +

+Public Types

+typedef T value_type
 
+typedef std::tr1::shared_ptr< T > value_pointer
 
+typedef std::tr1::weak_ptr< T > value_weak_pointer
 
+typedef std::set< value_pointer > set_type
 
+typedef std::vector
+< value_pointer > 
vector_type
 
+typedef epicsMutex mutex_type
 
+typedef epicsGuard< epicsMutex > guard_type
 
+typedef epicsGuardRelease
+< epicsMutex > 
release_type
 
+typedef XIterator iterator
 
+ + + + + + + + + + + + + + + + + + + + + + + + +

+Public Member Functions

weak_set ()
 Construct a new empty set.
 
void swap (weak_set &O)
 
void clear ()
 
bool empty () const
 
size_t size () const
 
void insert (value_pointer &)
 
size_t erase (value_pointer &v)
 
set_type lock_set () const
 
vector_type lock_vector () const
 
+void lock_vector (vector_type &) const
 
epicsMutex & mutex () const
 
+

Detailed Description

+

template<typename T>
+class weak_set< T >

+ +

a std::set-ish container where entries are removed when ref. counts fall to zero

+

A container of ref. counted (by shared_ptr) entries where an entry may be present zero or one times in the set.

+

Meant to be used in situations where an object must hold some weak references of entries which it can iterate.

+

Note that the insert() method replaces the reference pass to it with a "wrapped" reference which removes from the set then releases the original ref. The reference passed in must be unique() or std::invalid_argument is thrown. While this can't be enforced, no weak_ptr to this object should exist.

+

A reference loop will exist if the object owning the weak_set also holds strong references to entries in this set.

+
Note
With the exception of swap() all methods are thread-safe
+
Warning
Use caution when storing types deriving from enabled_shared_from_this<> As the implict weak reference they contain will not be wrapped.
struct Owner;
+
struct Entry {
+
shared_ptr<Owner> O;
+
};
+
struct Owner {
+ +
};
+
shared_ptr<Entry> build(const shared_ptr<Owner>& own) {
+
shared_ptr<Owner> N(new Entry);
+
N.O = own;
+
own.S.insert(N); // modifies 'N'
+
return N;
+
}
+
void example()
+
{
+
shared_ptr<Owner> O(new Owner);
+
shared_ptr<Entry> E(build(O));
+
assert(!O.S.empty());
+
E.reset(); // Entry is removed from the set and free'd
+
assert(O.S.empty());
+
}
+
+ +

Definition at line 57 of file weakset.h.

+

Member Function Documentation

+ +
+
+
+template<typename T>
+ + + + + +
+ + + + + + + +
void weak_set< T >::clear ()
+
+inline
+
+

Remove all (weak) entries from the set

+
Note
Thread safe
+ +

Definition at line 151 of file weakset.h.

+
151  {
+
152  guard_type G(_data->mutex);
+
153  return _data->store.clear();
+
154  }
+
+
+
+ +
+
+
+template<typename T>
+ + + + + +
+ + + + + + + +
bool weak_set< T >::empty () const
+
+inline
+
+

Test if set is empty

+
Note
Thread safe
+
Warning
see size()
+ +

Definition at line 159 of file weakset.h.

+
159  {
+
160  guard_type G(_data->mutex);
+
161  return _data->store.empty();
+
162  }
+
+
+
+ +
+
+
+template<typename T>
+ + + + + +
+ + + + + + + + +
size_t weak_set< T >::erase (value_pointer & v)
+
+inline
+
+

Remove any (weak) ref to this object from the set

+
Returns
the number of objects removed (0 or 1)
+ +

Definition at line 180 of file weakset.h.

+
180  {
+
181  guard_type G(_data->mutex);
+
182  return _data->store.erase(v);
+
183  }
+
+
+
+ +
+
+
+template<typename T >
+ + + + + + + + +
void weak_set< T >::insert (value_pointer & v)
+
+

Insert a new entry into the set The callers shared_ptr must be unique() and is (transparently) replaced with another

+ +

Definition at line 227 of file weakset.h.

+
228 {
+
229  if(!v.unique())
+
230  throw std::invalid_argument("Only unique() references may be inserted");
+
231 
+
232  guard_type G(_data->mutex);
+
233  typename store_t::const_iterator it = _data->store.find(v);
+
234  if(it==_data->store.end()) { // new object
+
235 
+
236  // wrapped strong ref. which removes from our map
+
237  value_pointer chainptr(v.get(), dtor(_data, v));
+
238 
+
239  _data->store.insert(chainptr);
+
240 
+
241  v.swap(chainptr); // we only keep the chained pointer
+
242  } else {
+
243  // already stored, no-op
+
244 
+
245  // paranoia, if already inserted then this should be a wrapped ref.
+
246  // but not sure how to check this so update arg. with known wrapped ref.
+
247  v = value_pointer(*it); // could throw bad_weak_ptr, but really never should
+
248  }
+
249 }
+
+
+
+ +
+
+
+template<typename T >
+ + + + + + + +
weak_set< T >::set_type weak_set< T >::lock_set () const
+
+

Return a set of strong references to all entries

+
Note
that this allocates a new std::set and copies all entries
+ +

Definition at line 253 of file weakset.h.

+
254 {
+
255  set_type ret;
+
256  guard_type G(_data->mutex);
+
257  for(typename store_t::const_iterator it=_data->store.begin(),
+
258  end=_data->store.end(); it!=end; ++it)
+
259  {
+
260  value_pointer P(it->lock());
+
261  if(P) ret.insert(P);
+
262  }
+
263  return ret;
+
264 }
+
+
+
+ +
+
+
+template<typename T >
+ + + + + + + +
weak_set< T >::vector_type weak_set< T >::lock_vector () const
+
+

Return a vector of strong references to all entries Useful for iteration

+
Note
that this allocates a new std::set and copies all entries
+ +

Definition at line 268 of file weakset.h.

+
269 {
+
270  vector_type ret;
+
271  lock_vector(ret);
+
272  return ret;
+
273 }
+
vector_type lock_vector() const
Definition: weakset.h:268
+
+
+
+ +
+
+
+template<typename T>
+ + + + + +
+ + + + + + + +
epicsMutex& weak_set< T >::mutex () const
+
+inline
+
+

Access to the weak_set internal lock for use with batch operations.

+
Warning
Use caution when swap()ing while holding this lock!
+ +

Definition at line 199 of file weakset.h.

+
199  {
+
200  return _data->mutex;
+
201  }
+
+
+
+ +
+
+
+template<typename T>
+ + + + + +
+ + + + + + + +
size_t weak_set< T >::size () const
+
+inline
+
+

number of entries in the set at this moment

+
Note
Thread safe
+
Warning
May be momentarily inaccurate (larger) due to dead refs. which have not yet been removed.
+ +

Definition at line 168 of file weakset.h.

+
168  {
+
169  guard_type G(_data->mutex);
+
170  return _data->store.size();
+
171  }
+
+
+
+ +
+
+
+template<typename T>
+ + + + + +
+ + + + + + + + +
void weak_set< T >::swap (weak_set< T > & O)
+
+inline
+
+

exchange the two sets.

+
Warning
Not thread safe (exchanges mutexes as well)
+ +

Definition at line 145 of file weakset.h.

+
145  {
+
146  _data.swap(O._data);
+
147  }
+
+
+
+
The documentation for this class was generated from the following file: +
+ + + + diff --git a/classweak__value__map-members.html b/classweak__value__map-members.html new file mode 100644 index 0000000..4b84f2a --- /dev/null +++ b/classweak__value__map-members.html @@ -0,0 +1,123 @@ + + + + + + +pva2pva: Member List + + + + + + + + + +
+
+ + + + + + +
+
pva2pva +  1.4.1 +
+
+
+ + + + + + +
+ All Classes Functions Variables Pages
+ + +
+ +
+ +
+
+
+
weak_value_map< K, V, C > Member List
+
+
+ +

This is the complete list of members for weak_value_map< K, V, C >, including all inherited members.

+ + + + + + + + + + + + + + + + + + + + + + + +
clear()weak_value_map< K, V, C >inline
empty() const weak_value_map< K, V, C >inline
find(const K &k) const weak_value_map< K, V, C >inline
guard_type typedef (defined in weak_value_map< K, V, C >)weak_value_map< K, V, C >
insert(const K &k, value_pointer &v)weak_value_map< K, V, C >inline
key_type typedef (defined in weak_value_map< K, V, C >)weak_value_map< K, V, C >
lock_map() const weak_value_map< K, V, C >inline
lock_map_type typedef (defined in weak_value_map< K, V, C >)weak_value_map< K, V, C >
lock_vector() const weak_value_map< K, V, C >inline
lock_vector_type typedef (defined in weak_value_map< K, V, C >)weak_value_map< K, V, C >
mutex() const weak_value_map< K, V, C >inline
mutex_type typedef (defined in weak_value_map< K, V, C >)weak_value_map< K, V, C >
operator[](const K &k) (defined in weak_value_map< K, V, C >)weak_value_map< K, V, C >inline
operator[](const K &k) const (defined in weak_value_map< K, V, C >)weak_value_map< K, V, C >inline
release_type typedef (defined in weak_value_map< K, V, C >)weak_value_map< K, V, C >
set_type typedef (defined in weak_value_map< K, V, C >)weak_value_map< K, V, C >
size() const weak_value_map< K, V, C >inline
swap(weak_value_map &O)weak_value_map< K, V, C >inline
value_pointer typedef (defined in weak_value_map< K, V, C >)weak_value_map< K, V, C >
value_type typedef (defined in weak_value_map< K, V, C >)weak_value_map< K, V, C >
value_weak_pointer typedef (defined in weak_value_map< K, V, C >)weak_value_map< K, V, C >
weak_value_map()weak_value_map< K, V, C >inline
+ + + + diff --git a/classweak__value__map.html b/classweak__value__map.html new file mode 100644 index 0000000..8ac01ba --- /dev/null +++ b/classweak__value__map.html @@ -0,0 +1,518 @@ + + + + + + +pva2pva: weak_value_map< K, V, C > Class Template Reference + + + + + + + + + +
+
+ + + + + + +
+
pva2pva +  1.4.1 +
+
+
+ + + + + + +
+ All Classes Functions Variables Pages
+ + +
+ +
+ +
+
+
+Classes | +Public Types | +Public Member Functions | +List of all members
+
+
weak_value_map< K, V, C > Class Template Reference
+
+
+ +

An associative map where a weak_ptr to the value is stored. + More...

+ +

#include <weakmap.h>

+ + + + +

+Classes

class  element_proxy
 
+ + + + + + + + + + + + + + + + + + + + + +

+Public Types

+typedef K key_type
 
+typedef V value_type
 
+typedef std::tr1::shared_ptr< V > value_pointer
 
+typedef std::tr1::weak_ptr< V > value_weak_pointer
 
+typedef std::set< value_pointer > set_type
 
+typedef epicsMutex mutex_type
 
+typedef epicsGuard< epicsMutex > guard_type
 
+typedef epicsGuardRelease
+< epicsMutex > 
release_type
 
+typedef std::map< K,
+value_pointer, C > 
lock_map_type
 
+typedef std::vector< std::pair
+< K, value_pointer > > 
lock_vector_type
 
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Public Member Functions

weak_value_map ()
 Construct a new empty set.
 
void swap (weak_value_map &O)
 
void clear ()
 
bool empty () const
 
size_t size () const
 
+element_proxy operator[] (const K &k)
 
+value_pointer operator[] (const K &k) const
 
value_pointer find (const K &k) const
 
value_pointer insert (const K &k, value_pointer &v)
 
+lock_map_type lock_map () const
 Return an equivalent map with strong value references.
 
lock_vector_type lock_vector () const
 
epicsMutex & mutex () const
 
+

Detailed Description

+

template<typename K, typename V, typename C = std::less<K>>
+class weak_value_map< K, V, C >

+ +

An associative map where a weak_ptr to the value is stored.

+

Acts like std::map<K, weak_ptr<V> > where entries are automatically removed when no longer referenced.

+

Meant to be used in situations where an object must hold some weak references of entries which it can iterate.

+

Note that insert() and operator[] w/ assignment replaces the reference pass in with a "wrapped" reference which removes from the set then releases the original ref. The reference passed in must be unique() or std::invalid_argument is thrown. While this can't be enforced, no weak_ptr to this object should exist.

+

A reference loop will exist if the object owning the weak_set also holds strong references to entries in this set.

+
Note
With the exception of swap() all methods are thread-safe
+
Warning
Use caution when storing types deriving from enabled_shared_from_this<> As the implict weak reference they contain will not be wrapped.
struct Owner;
+
struct Entry {
+
shared_ptr<Owner> O;
+
};
+
struct Owner {
+
weak_map<string, Entry> M;
+
};
+
shared_ptr<Entry> build(const shared_ptr<Owner>& own, const std::string& k) {
+
shared_ptr<Owner> N(new Entry);
+
N.O = own;
+
own.M[k] = N; // modifies 'N'
+
return N;
+
}
+
void example()
+
{
+
shared_ptr<Owner> O(new Owner);
+
shared_ptr<Entry> E(build(O, "test"));
+
assert(!O.M.empty());
+
assert(O.M["test"]==E);
+
E.reset(); // Entry is removed from the set and free'd
+
assert(O.M.empty());
+
}
+
+ +

Definition at line 59 of file weakmap.h.

+

Member Function Documentation

+ +
+
+
+template<typename K, typename V, typename C = std::less<K>>
+ + + + + +
+ + + + + + + +
void weak_value_map< K, V, C >::clear ()
+
+inline
+
+

Remove all (weak) entries from the set

+
Note
Thread safe
+ +

Definition at line 130 of file weakmap.h.

+
130  {
+
131  guard_type G(_data->mutex);
+
132  return _data->store.clear();
+
133  }
+
+
+
+ +
+
+
+template<typename K, typename V, typename C = std::less<K>>
+ + + + + +
+ + + + + + + +
bool weak_value_map< K, V, C >::empty () const
+
+inline
+
+

Test if set is empty at this moment

+
Note
Thread safe
+
Warning
see size()
+ +

Definition at line 138 of file weakmap.h.

+
138  {
+
139  guard_type G(_data->mutex);
+
140  return _data->store.empty();
+
141  }
+
+
+
+ +
+
+
+template<typename K, typename V, typename C = std::less<K>>
+ + + + + +
+ + + + + + + + +
value_pointer weak_value_map< K, V, C >::find (const K & k) const
+
+inline
+
+

Lookup key 'k'

+
Returns
a strong reference or nullptr if 'k' is not present
+ +

Definition at line 215 of file weakmap.h.

+
216  {
+
217  value_pointer ret;
+
218  guard_type G(_data->mutex);
+
219  typename store_t::const_iterator it(_data->store.find(k));
+
220  if(it!=_data->store.end()) {
+
221  // may be nullptr if we race destruction
+
222  // as ref. count falls to zero before we can remove it
+
223  ret = it->second.lock();
+
224  }
+
225  return ret;
+
226  }
+
+
+
+ +
+
+
+template<typename K, typename V, typename C = std::less<K>>
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
value_pointer weak_value_map< K, V, C >::insert (const K & k,
value_pointer & v 
)
+
+inline
+
+

Insert or replace

+
Returns
previous value of key k (may be nullptr).
+ +

Definition at line 230 of file weakmap.h.

+
231  {
+
232  value_pointer ret;
+
233  guard_type G(_data->mutex);
+
234  typename store_t::const_iterator it = _data->store.find(k);
+
235  if(it!=_data->store.end())
+
236  ret = it->second.lock();
+
237  (*this)[k] = v;
+
238  return ret;
+
239  }
+
+
+
+ +
+
+
+template<typename K, typename V, typename C = std::less<K>>
+ + + + + +
+ + + + + + + +
lock_vector_type weak_value_map< K, V, C >::lock_vector () const
+
+inline
+
+

Return a vector of pairs of keys and strong value references. useful for iteration

+ +

Definition at line 259 of file weakmap.h.

+
260  {
+
261  lock_vector_type ret;
+
262  guard_type G(_data->mutex);
+
263  ret.reserve(_data->store.size());
+
264  for(typename store_t::const_iterator it = _data->store.begin(),
+
265  end = _data->store.end(); it!=end; ++it)
+
266  {
+
267  value_pointer P(it->second.lock());
+
268  if(P) ret.push_back(std::make_pair(it->first, P));
+
269  }
+
270  return ret;
+
271  }
+
+
+
+ +
+
+
+template<typename K, typename V, typename C = std::less<K>>
+ + + + + +
+ + + + + + + +
epicsMutex& weak_value_map< K, V, C >::mutex () const
+
+inline
+
+

Access to the weak_set internal lock for use with batch operations.

+
Warning
Use caution when swap()ing while holding this lock!
+ +

Definition at line 276 of file weakmap.h.

+
276  {
+
277  return _data->mutex;
+
278  }
+
+
+
+ +
+
+
+template<typename K, typename V, typename C = std::less<K>>
+ + + + + +
+ + + + + + + +
size_t weak_value_map< K, V, C >::size () const
+
+inline
+
+

number of entries in the set at this moment

+
Note
Thread safe
+
Warning
May be momentarily inaccurate (larger) due to dead refs. which have not yet been removed.
+ +

Definition at line 147 of file weakmap.h.

+
147  {
+
148  guard_type G(_data->mutex);
+
149  return _data->store.size();
+
150  }
+
+
+
+ +
+
+
+template<typename K, typename V, typename C = std::less<K>>
+ + + + + +
+ + + + + + + + +
void weak_value_map< K, V, C >::swap (weak_value_map< K, V, C > & O)
+
+inline
+
+

exchange the two sets.

+
Warning
Not thread safe (exchanges mutexes as well)
+ +

Definition at line 124 of file weakmap.h.

+
124  {
+
125  _data.swap(O._data);
+
126  }
+
+
+
+
The documentation for this class was generated from the following file: +
+ + + + diff --git a/classweak__value__map_1_1element__proxy-members.html b/classweak__value__map_1_1element__proxy-members.html new file mode 100644 index 0000000..8d331f4 --- /dev/null +++ b/classweak__value__map_1_1element__proxy-members.html @@ -0,0 +1,113 @@ + + + + + + +pva2pva: Member List + + + + + + + + + +
+
+ + + + + + +
+
pva2pva +  1.4.1 +
+
+
+ + + + + + +
+ All Classes Functions Variables Pages
+ + +
+ +
+ + +
+
+
+
weak_value_map< K, V, C >::element_proxy Member List
+
+
+ +

This is the complete list of members for weak_value_map< K, V, C >::element_proxy, including all inherited members.

+ + + + + + + + + +
operator value_pointer() const weak_value_map< K, V, C >::element_proxyinline
operator!=(const value_pointer &v) const (defined in weak_value_map< K, V, C >::element_proxy)weak_value_map< K, V, C >::element_proxyinline
operator*() const weak_value_map< K, V, C >::element_proxyinline
operator->() const weak_value_map< K, V, C >::element_proxyinline
operator=(value_pointer &v)weak_value_map< K, V, C >::element_proxyinline
operator==(const value_pointer &v) const (defined in weak_value_map< K, V, C >::element_proxy)weak_value_map< K, V, C >::element_proxyinline
weak_value_map (defined in weak_value_map< K, V, C >::element_proxy)weak_value_map< K, V, C >::element_proxyfriend
~element_proxy() (defined in weak_value_map< K, V, C >::element_proxy)weak_value_map< K, V, C >::element_proxyinline
+ + + + diff --git a/classweak__value__map_1_1element__proxy.html b/classweak__value__map_1_1element__proxy.html new file mode 100644 index 0000000..cfef5a0 --- /dev/null +++ b/classweak__value__map_1_1element__proxy.html @@ -0,0 +1,187 @@ + + + + + + +pva2pva: weak_value_map< K, V, C >::element_proxy Class Reference + + + + + + + + + +
+
+ + + + + + +
+
pva2pva +  1.4.1 +
+
+
+ + + + + + +
+ All Classes Functions Variables Pages
+ + +
+ +
+ + +
+
+
+Public Member Functions | +Friends | +List of all members
+
+
weak_value_map< K, V, C >::element_proxy Class Reference
+
+
+ +

#include <weakmap.h>

+ + + + + + + + + + + + + + + + + +

+Public Member Functions

value_pointer & operator= (value_pointer &v)
 
+V & operator* () const
 Support: *map[k].
 
+V * operator-> () const
 Support: map[k]->mem.
 
operator value_pointer () const
 Support: value_pointer V(map[k])
 
+bool operator== (const value_pointer &v) const
 
+bool operator!= (const value_pointer &v) const
 
+ + + +

+Friends

+class weak_value_map
 
+

Detailed Description

+

template<typename K, typename V, typename C = std::less<K>>
+class weak_value_map< K, V, C >::element_proxy

+ +

proxy class for lookup of non-const Supports assignment and deref. implicitly castable to value_pointer (aka shared_ptr<V>)

+ +

Definition at line 155 of file weakmap.h.

+

Member Function Documentation

+ +
+
+
+template<typename K, typename V, typename C = std::less<K>>
+ + + + + +
+ + + + + + + + +
value_pointer& weak_value_map< K, V, C >::element_proxy::operator= (value_pointer & v)
+
+inline
+
+

Support: map[k] = v The value_pointer passed in will be replaced with a wrapped reference

+
Returns
the argument
+ +

Definition at line 166 of file weakmap.h.

+
167  {
+
168  if(!v.unique())
+
169  throw std::invalid_argument("Only unique() references may be inserted");
+
170  value_pointer chainptr(v.get(), dtor(M._data, k, v));
+
171  M._data->store[k] = chainptr;
+
172  v.swap(chainptr);
+
173  return v;
+
174  }
+
+
+
+
The documentation for this class was generated from the following file: +
+ + + + diff --git a/closed.png b/closed.png new file mode 100644 index 0000000..98cc2c9 Binary files /dev/null and b/closed.png differ diff --git a/conf_8py_source.html b/conf_8py_source.html new file mode 100644 index 0000000..9686d06 --- /dev/null +++ b/conf_8py_source.html @@ -0,0 +1,177 @@ + + + + + + +pva2pva: documentation/conf.py Source File + + + + + + + + + +
+
+ + + + + + +
+
pva2pva +  1.4.1 +
+
+
+ + + + + + +
+ All Classes Functions Variables Pages
+ + +
+ +
+ + +
+
+
+
conf.py
+
+
+
1 # Configuration file for the Sphinx documentation builder.
+
2 #
+
3 # This file only contains a selection of the most common options. For a full
+
4 # list see the documentation:
+
5 # http://www.sphinx-doc.org/en/master/config
+
6 
+
7 # -- Path setup --------------------------------------------------------------
+
8 
+
9 # If extensions (or modules to document with autodoc) are in another directory,
+
10 # add these directories to sys.path here. If the directory is relative to the
+
11 # documentation root, use os.path.abspath to make it absolute, like shown here.
+
12 #
+
13 # import os
+
14 # import sys
+
15 # sys.path.insert(0, os.path.abspath('.'))
+
16 
+
17 
+
18 # -- Project information -----------------------------------------------------
+
19 
+
20 project = 'EPICS Documentation'
+
21 copyright = '2019, EPICS Controls.'
+
22 author = 'EPICS'
+
23 
+
24 
+
25 # -- General configuration ---------------------------------------------------
+
26 
+
27 # Add any Sphinx extension module names here, as strings. They can be
+
28 # extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
+
29 # ones.
+
30 extensions = [
+
31  'sphinx.ext.intersphinx',
+
32 ]
+
33 
+
34 # Add any paths that contain templates here, relative to this directory.
+
35 templates_path = ['_templates']
+
36 
+
37 # List of patterns, relative to source directory, that match files and
+
38 # directories to ignore when looking for source files.
+
39 # This pattern also affects html_static_path and html_extra_path.
+
40 exclude_patterns = ['_build', 'Thumbs.db', '.DS_Store']
+
41 
+
42 # Intersphinx links to subprojects
+
43 intersphinx_mapping = {
+
44  'how-tos': ('https://docs.epics-controls.org/projects/how-tos/en/latest', None),
+
45 }
+
46 
+
47 
+
48 # -- Options for HTML output -------------------------------------------------
+
49 
+
50 # The theme to use for HTML and HTML Help pages. See the documentation for
+
51 # a list of builtin themes.
+
52 #
+
53 html_theme = 'sphinx_rtd_theme'
+
54 
+
55 
+
56 # Add any paths that contain custom static files (such as style sheets) here,
+
57 # relative to this directory. They are copied after the builtin static files,
+
58 # so a file named "default.css" will overwrite the builtin "default.css".
+
59 html_static_path = ['_static']
+
60 
+
61 html_css_files = [
+
62  'css/custom.css',
+
63 ]
+
64 
+
65 master_doc = 'index'
+
66 
+
67 html_theme_options = {
+
68  'logo_only': True,
+
69 }
+
70 html_logo = "images/EPICS_white_logo_v02.png"
+
71 
+
72 html_extra_path = ['../html']
+
73 
+
74 
+
75 # -- Run Doxygen ------------------------------------------------------------
+
76 
+
77 import subprocess
+
78 subprocess.call('cd ..; mkdir -p html/doxygen; doxygen', shell=True)
+
+ + + + diff --git a/configparse_8cpp_source.html b/configparse_8cpp_source.html new file mode 100644 index 0000000..b72f648 --- /dev/null +++ b/configparse_8cpp_source.html @@ -0,0 +1,356 @@ + + + + + + +pva2pva: pdbApp/configparse.cpp Source File + + + + + + + + + +
+
+ + + + + + +
+
pva2pva +  1.4.1 +
+
+
+ + + + + + +
+ All Classes Functions Variables Pages
+ + +
+ +
+ + +
+
+
+
configparse.cpp
+
+
+
1 
+
2 #include <sstream>
+
3 
+
4 #include <dbAccess.h>
+
5 
+
6 #include <dbAccess.h>
+
7 #include <dbChannel.h>
+
8 #include <dbStaticLib.h>
+
9 #include <dbEvent.h>
+
10 #include <dbLock.h>
+
11 
+
12 #include <pv/pvIntrospect.h>
+
13 #include <pv/pvAccess.h>
+
14 #include <pv/configuration.h>
+
15 #include <pv/json.h>
+
16 
+
17 #include "pdbgroup.h"
+
18 
+
19 namespace {
+
20 
+
21 namespace pvd = epics::pvData;
+
22 using pvd::yajl::integer_arg;
+
23 using pvd::yajl::size_arg;
+
24 
+
25 typedef std::map<std::string, pvd::AnyScalar> options_t;
+
26 typedef std::map<std::string, options_t> config_t;
+
27 
+
28 struct context {
+
29  const std::string chanprefix;
+
30  std::string msg;
+
31  std::string group, field, key;
+
32  unsigned depth; // number of '{'s
+
33  // depth 0 - invalid
+
34  // depth 1 - top Object
+
35  // depth 2 - Group
+
36  // depth 3 - field
+
37 
+
38  context(const std::string& chanprefix, GroupConfig& conf)
+
39  :chanprefix(chanprefix)
+
40  ,depth(0u)
+
41  ,conf(conf)
+
42  {}
+
43 
+
44  GroupConfig& conf;
+
45 
+
46  void can_assign()
+
47  {
+
48  if(depth<2 || depth>3)
+
49  throw std::runtime_error("Can't assign value in this context");
+
50  }
+
51 
+
52  void assign(const pvd::AnyScalar& value) {
+
53  can_assign();
+
54  GroupConfig::Group& grp = conf.groups[group];
+
55 
+
56  if(depth==2) {
+
57  if(field=="+atomic") {
+
58  grp.atomic = value.as<pvd::boolean>();
+
59  grp.atomic_set = true;
+
60 
+
61  } else if(field=="+id") {
+
62  grp.id = value.as<std::string>();
+
63 
+
64  } else {
+
65  conf.warning += "Unknown group option ";
+
66  conf.warning += field;
+
67  }
+
68  field.clear();
+
69 
+
70  } else if(depth==3) {
+
71  GroupConfig::Field& fld = grp.fields[field];
+
72 
+
73  if(key=="+type") {
+
74  fld.type = value.ref<std::string>();
+
75 
+
76  } else if(key=="+channel") {
+
77  fld.channel = chanprefix + value.ref<std::string>();
+
78 
+
79  } else if(key=="+id") {
+
80  fld.id = value.ref<std::string>();
+
81 
+
82  } else if(key=="+trigger") {
+
83  fld.trigger = value.ref<std::string>();
+
84 
+
85  } else if(key=="+putorder") {
+
86  fld.putorder = value.as<pvd::int32>();
+
87 
+
88  } else {
+
89  conf.warning += "Unknown group field option ";
+
90  conf.warning += field;
+
91  }
+
92  key.clear();
+
93  }
+
94  }
+
95 };
+
96 
+
97 #define TRY context *self = (context*)ctx; try
+
98 
+
99 #define CATCH() catch(std::exception& e) { if(self->msg.empty()) self->msg = e.what(); return 0; }
+
100 
+
101 int conf_null(void * ctx)
+
102 {
+
103  TRY {
+
104  self->assign(pvd::AnyScalar());
+
105  return 1;
+
106  }CATCH()
+
107 }
+
108 
+
109 
+
110 int conf_boolean(void * ctx, int boolVal)
+
111 {
+
112  TRY {
+
113  self->assign(pvd::AnyScalar(pvd::boolean(boolVal)));
+
114  return 1;
+
115  }CATCH()
+
116 }
+
117 
+
118 int conf_integer(void * ctx, integer_arg integerVal)
+
119 {
+
120  TRY {
+
121  self->assign(pvd::AnyScalar(pvd::int64(integerVal)));
+
122  return 1;
+
123  }CATCH()
+
124 }
+
125 
+
126 int conf_double(void * ctx, double doubleVal)
+
127 {
+
128  TRY {
+
129  self->assign(pvd::AnyScalar(doubleVal));
+
130  return 1;
+
131  }CATCH()
+
132 }
+
133 
+
134 int conf_string(void * ctx, const unsigned char * stringVal,
+
135  size_arg stringLen)
+
136 {
+
137  TRY {
+
138  std::string val((const char*)stringVal, stringLen);
+
139  self->assign(pvd::AnyScalar(val));
+
140  return 1;
+
141  }CATCH()
+
142 }
+
143 
+
144 int conf_start_map(void * ctx)
+
145 {
+
146  TRY {
+
147  self->depth++;
+
148  if(self->depth>3)
+
149  throw std::runtime_error("Group field def. can't contain Object (too deep)");
+
150  return 1;
+
151  }CATCH()
+
152 }
+
153 
+
154 int conf_map_key(void * ctx, const unsigned char * key,
+
155  size_arg stringLen)
+
156 {
+
157  TRY {
+
158  if(stringLen==0 && self->depth!=2)
+
159  throw std::runtime_error("empty group or key name not allowed");
+
160 
+
161  std::string name((const char*)key, stringLen);
+
162 
+
163  if(self->depth==1)
+
164  self->group.swap(name);
+
165  else if(self->depth==2)
+
166  self->field.swap(name);
+
167  else if(self->depth==3)
+
168  self->key.swap(name);
+
169  else
+
170  throw std::logic_error("Too deep!!");
+
171 
+
172  return 1;
+
173  }CATCH()
+
174 }
+
175 
+
176 int conf_end_map(void * ctx)
+
177 {
+
178  TRY {
+
179  assert(self->key.empty()); // cleared in assign()
+
180 
+
181  if(self->depth==3)
+
182  self->key.clear();
+
183  else if(self->depth==2)
+
184  self->field.clear();
+
185  else if(self->depth==1)
+
186  self->group.clear();
+
187  else
+
188  throw std::logic_error("Invalid depth");
+
189  self->depth--;
+
190 
+
191  return 1;
+
192  }CATCH()
+
193 }
+
194 
+
195 yajl_callbacks conf_cbs = {
+
196  &conf_null,
+
197  &conf_boolean,
+
198  &conf_integer,
+
199  &conf_double,
+
200  NULL, // number
+
201  &conf_string,
+
202  &conf_start_map,
+
203  &conf_map_key,
+
204  &conf_end_map,
+
205  NULL, // start_array,
+
206  NULL, // end_array,
+
207 };
+
208 
+
209 struct handler {
+
210  yajl_handle handle;
+
211  handler(yajl_handle handle) :handle(handle)
+
212  {
+
213  if(!handle)
+
214  throw std::runtime_error("Failed to allocate yajl handle");
+
215  }
+
216  ~handler() {
+
217  yajl_free(handle);
+
218  }
+
219  operator yajl_handle() { return handle; }
+
220 };
+
221 
+
222 }// namespace
+
223 
+
224 void GroupConfig::parse(const char *txt,
+
225  const char *recname,
+
226  GroupConfig& result)
+
227 {
+
228 #ifndef EPICS_YAJL_VERSION
+
229  yajl_parser_config conf;
+
230  memset(&conf, 0, sizeof(conf));
+
231  conf.allowComments = 1;
+
232  conf.checkUTF8 = 1;
+
233 #endif
+
234 
+
235  std::istringstream strm(txt);
+
236 
+
237  std::string chanprefix;
+
238  if(recname) {
+
239  chanprefix = recname;
+
240  chanprefix += '.';
+
241  }
+
242  context ctxt(chanprefix, result);
+
243 
+
244 #ifndef EPICS_YAJL_VERSION
+
245  handler handle(yajl_alloc(&conf_cbs, &conf, NULL, &ctxt));
+
246 #else
+
247  handler handle(yajl_alloc(&conf_cbs, NULL, &ctxt));
+
248 
+
249  yajl_config(handle, yajl_allow_comments, 1);
+
250 #endif
+
251 
+
252  if(!pvd::yajl_parse_helper(strm, handle))
+
253  throw std::runtime_error(ctxt.msg);
+
254 }
+ + + +
+ + + + diff --git a/dbf__copy_8cpp_source.html b/dbf__copy_8cpp_source.html new file mode 100644 index 0000000..6b4f1ee --- /dev/null +++ b/dbf__copy_8cpp_source.html @@ -0,0 +1,344 @@ + + + + + + +pva2pva: pdbApp/dbf_copy.cpp Source File + + + + + + + + + +
+
+ + + + + + +
+
pva2pva +  1.4.1 +
+
+
+ + + + + + +
+ All Classes Functions Variables Pages
+ + +
+ +
+ + +
+
+
+
dbf_copy.cpp
+
+
+
1 
+
2 #include <epicsStdio.h>
+
3 #include <dbAccess.h>
+
4 #include <dbChannel.h>
+
5 #include <dbStaticLib.h>
+
6 #include <dbLock.h>
+
7 #include <dbEvent.h>
+
8 #include <epicsString.h>
+
9 #include <epicsVersion.h>
+
10 
+
11 #include <pv/status.h>
+
12 #include <pv/bitSet.h>
+
13 #include <pv/pvData.h>
+
14 #include <pv/anyscalar.h>
+
15 
+
16 #include "pvif.h"
+
17 
+
18 namespace pvd = epics::pvData;
+
19 
+
20 // note that we handle DBF_ENUM differently than in pvif.cpp
+
21 static
+
22 pvd::ScalarType DBR2PVD(short dbr)
+
23 {
+
24  switch(dbr) {
+
25 #define CASE(BASETYPE, PVATYPE, DBFTYPE, PVACODE) case DBR_##DBFTYPE: return pvd::pv##PVACODE;
+
26 #define CASE_SKIP_BOOL
+
27 #define CASE_REAL_INT64
+
28 #include "pv/typemap.h"
+
29 #undef CASE_SKIP_BOOL
+
30 #undef CASE_REAL_INT64
+
31 #undef CASE
+
32  case DBF_ENUM: return pvd::pvUShort;
+
33  case DBF_STRING: return pvd::pvString;
+
34  }
+
35  throw std::invalid_argument("Unsupported DBR code");
+
36 }
+
37 
+
38 long copyPVD2DBF(const pvd::PVField::const_shared_pointer& inraw,
+
39  void *outbuf, short outdbf, long *outnReq)
+
40 {
+
41  long nreq = outnReq ? *outnReq : 1;
+
42  if(!inraw || nreq <= 0 || INVALID_DB_REQ(outdbf)) return S_db_errArg;
+
43 
+
44  pvd::ScalarType outpvd = DBR2PVD(outdbf);
+
45 
+
46  pvd::PVField::const_shared_pointer in(inraw);
+
47 
+
48  if(outdbf != DBF_STRING && in->getField()->getType() == pvd::structure) {
+
49  // assume NTEnum.
+
50  // index to string not requested, so attempt to treat .index as plain integer
+
51  in = static_cast<const pvd::PVStructure*>(in.get())->getSubField("index");
+
52  if(!in) return S_db_errArg;
+
53  }
+
54 
+
55  if(in->getField()->getType() == pvd::structure) {
+
56  assert(outdbf == DBF_STRING);
+
57  char *outsbuf = (char*)outbuf;
+
58 
+
59  // maybe NTEnum
+
60  // try index -> string
+
61  const pvd::PVStructure* sin = static_cast<const pvd::PVStructure*>(in.get());
+
62 
+
63  pvd::PVScalar::const_shared_pointer index(sin->getSubField<pvd::PVScalar>("index"));
+
64  if(!index) return S_db_badField; // Not NTEnum, don't know how to handle...
+
65 
+
66  // we will have an answer.
+
67  if(outnReq)
+
68  *outnReq = 1;
+
69 
+
70  pvd::uint16 ival = index->getAs<pvd::uint16>();
+
71 
+
72 
+
73  pvd::PVStringArray::const_shared_pointer choices(sin->getSubField<pvd::PVStringArray>("choices"));
+
74 
+
75  if(choices) {
+
76  pvd::PVStringArray::const_svector strs(choices->view());
+
77 
+
78  if(ival < strs.size()) {
+
79  // found it!
+
80 
+
81  const std::string& sval = strs[ival];
+
82  size_t slen = std::min(sval.size(), size_t(MAX_STRING_SIZE-1));
+
83  memcpy(outbuf, sval.c_str(), slen);
+
84  outsbuf[slen] = '\0';
+
85  return 0;
+
86  }
+
87  }
+
88  // didn't find it. either no choices or index is out of range
+
89 
+
90  // print numeric index
+
91  epicsSnprintf(outsbuf, MAX_STRING_SIZE, "%u", ival);
+
92  return 0;
+
93 
+
94  } else if(in->getField()->getType() == pvd::scalarArray) {
+
95  const pvd::PVScalarArray* sarr = static_cast<const pvd::PVScalarArray*>(in.get());
+
96  pvd::shared_vector<const void> arr;
+
97  sarr->getAs(arr);
+
98  size_t elemsize = pvd::ScalarTypeFunc::elementSize(arr.original_type());
+
99 
+
100  arr.slice(0, nreq*elemsize);
+
101  nreq = arr.size()/elemsize;
+
102 
+
103  if(outdbf == DBF_STRING) {
+
104  char *outsbuf = (char*)outbuf;
+
105 
+
106  // allocate a temp buffer of string[], ick...
+
107  pvd::shared_vector<std::string> strs(nreq); // alloc
+
108 
+
109  pvd::castUnsafeV(nreq, pvd::pvString, strs.data(), arr.original_type(), arr.data());
+
110 
+
111  for(long i =0; i<nreq; i++, outsbuf += MAX_STRING_SIZE) {
+
112  size_t slen = std::min(strs[i].size(), size_t(MAX_STRING_SIZE-1));
+
113  memcpy(outsbuf, strs[i].c_str(), slen);
+
114  outsbuf[slen] = '\0';
+
115  }
+
116 
+
117  } else {
+
118  pvd::castUnsafeV(nreq, outpvd, outbuf, arr.original_type(), arr.data());
+
119  }
+
120 
+
121  if(outnReq)
+
122  *outnReq = nreq;
+
123  return 0;
+
124 
+
125  } else if(in->getField()->getType() == pvd::scalar) {
+
126  char *outsbuf = (char*)outbuf;
+
127  const pvd::PVScalar* sval = static_cast<const pvd::PVScalar*>(in.get());
+
128  pvd::AnyScalar val;
+
129  sval->getAs(val);
+
130 
+
131  if(outdbf == DBF_STRING && val.type()==pvd::pvString) {
+
132  // std::string to char*
+
133  size_t len = std::min(val.as<std::string>().size(), size_t(MAX_STRING_SIZE-1));
+
134 
+
135  memcpy(outbuf, val.as<std::string>().c_str(), len);
+
136  outsbuf[len] = '\0';
+
137 
+
138  } else if(outdbf == DBF_STRING) {
+
139  // non-string to char*
+
140  std::string temp;
+
141 
+
142  pvd::castUnsafeV(1, pvd::pvString, &temp, val.type(), val.unsafe());
+
143 
+
144  size_t len = std::min(temp.size(), size_t(MAX_STRING_SIZE-1));
+
145 
+
146  memcpy(outbuf, temp.c_str(), len);
+
147  outsbuf[len] = '\0';
+
148 
+
149  } else {
+
150  // non-string to any
+
151  pvd::castUnsafeV(1, outpvd, outbuf, val.type(), val.unsafe());
+
152  }
+
153 
+
154  if(outnReq)
+
155  *outnReq = 1;
+
156  return 0;
+
157 
+
158  } else {
+
159  // struct array or other strangeness which I don't know how to handle
+
160  return S_dbLib_badField;
+
161  }
+
162 }
+
163 
+
164 long copyDBF2PVD(const pvd::shared_vector<const void> &inbuf,
+
165  const pvd::PVField::shared_pointer& outraw,
+
166  pvd::BitSet& changed,
+
167  const pvd::PVStringArray::const_svector &choices)
+
168 {
+
169 
+
170  pvd::ScalarType inpvd = inbuf.original_type();
+
171  size_t incnt = inbuf.size()/pvd::ScalarTypeFunc::elementSize(inpvd);
+
172 
+
173  if(!outraw) return S_db_errArg;
+
174 
+
175  pvd::PVField::shared_pointer out(outraw);
+
176 
+
177  if(inpvd != pvd::pvString && out->getField()->getType() == pvd::structure) {
+
178  // assume NTEnum.
+
179  // string to index not requested, so attempt to treat .index as plain integer
+
180  out = static_cast<pvd::PVStructure*>(out.get())->getSubField("index");
+
181  if(!out) return S_db_errArg;
+
182  }
+
183 
+
184  if(out->getField()->getType() == pvd::structure) {
+
185  assert(inpvd == pvd::pvString);
+
186 
+
187  if(incnt==0)
+
188  return S_db_errArg; // Need at least one string
+
189 
+
190  const pvd::shared_vector<const std::string> insbuf(pvd::static_shared_vector_cast<const std::string>(inbuf));
+
191  const std::string& instr(insbuf[0]);
+
192 
+
193  // assume NTEnum
+
194  // try string to index, then parse
+
195  pvd::PVStructure* sout = static_cast<pvd::PVStructure*>(out.get());
+
196 
+
197  pvd::PVScalar::shared_pointer index(sout->getSubField<pvd::PVScalar>("index"));
+
198  if(!index) return S_db_badField; // Not NTEnum, don't know how to handle...
+
199 
+
200  pvd::uint16 result = pvd::uint16(-1);
+
201  bool match = false;
+
202 
+
203  for(size_t i=0, N=std::min(size_t(0xffff), choices.size()); i<N; i++) {
+
204  if(choices[i] == instr) {
+
205  match = true;
+
206  result = pvd::uint16(i);
+
207  }
+
208  }
+
209 
+
210  if(!match) {
+
211  // no choice string matched, so try to parse as integer
+
212 
+
213  try{
+
214  result = pvd::castUnsafe<pvd::uint16>(instr);
+
215  }catch(std::exception&){
+
216  return S_db_errArg;
+
217  }
+
218  }
+
219 
+
220  index->putFrom(result);
+
221 
+
222  out = index;
+
223 
+
224  } else if(out->getField()->getType() == pvd::scalarArray) {
+
225  pvd::PVScalarArray* sarr = static_cast<pvd::PVScalarArray*>(out.get());
+
226 
+
227  sarr->putFrom(inbuf);
+
228 
+
229  } else if(out->getField()->getType() == pvd::scalar) {
+
230  pvd::PVScalar* sval = static_cast<pvd::PVScalar*>(out.get());
+
231 
+
232  if(incnt==0) return S_db_errArg;
+
233 
+
234  pvd::AnyScalar val(inpvd, inbuf.data());
+
235 
+
236  sval->putFrom(val);
+
237 
+
238  } else {
+
239  // struct array or other strangeness which I don't know how to handle
+
240  return S_db_badField;
+
241  }
+
242 
+
243  changed.set(out->getFieldOffset());
+
244  return 0;
+
245 }
+
+ + + + diff --git a/demo_8cpp_source.html b/demo_8cpp_source.html new file mode 100644 index 0000000..69b5c0b --- /dev/null +++ b/demo_8cpp_source.html @@ -0,0 +1,215 @@ + + + + + + +pva2pva: pdbApp/demo.cpp Source File + + + + + + + + + +
+
+ + + + + + +
+
pva2pva +  1.4.1 +
+
+
+ + + + + + +
+ All Classes Functions Variables Pages
+ + +
+ +
+ + +
+
+
+
demo.cpp
+
+
+
1 
+
2 #include <epicsMath.h>
+
3 #include <dbAccess.h>
+
4 #include <dbScan.h>
+
5 #include <dbLink.h>
+
6 #include <recGbl.h>
+
7 #include <alarm.h>
+
8 
+
9 #include <longinRecord.h>
+
10 #include <waveformRecord.h>
+
11 #include <menuFtype.h>
+
12 
+
13 #include <epicsExport.h>
+
14 
+
15 namespace {
+
16 
+
17 // pi/180
+
18 static const double pi_180 = 0.017453292519943295;
+
19 
+
20 int dummy;
+
21 
+
22 long init_spin(waveformRecord *prec)
+
23 {
+
24  if(prec->ftvl==menuFtypeDOUBLE)
+
25  prec->dpvt = &dummy;
+
26  return 0;
+
27 }
+
28 
+
29 long process_spin(waveformRecord *prec)
+
30 {
+
31  if(prec->dpvt != &dummy) {
+
32  (void)recGblSetSevr(prec, COMM_ALARM, INVALID_ALARM);
+
33  return 0;
+
34  }
+
35 
+
36  const double freq = 360.0*pi_180/100; // rad/sample
+
37  double phase = 0;
+
38  double *val = static_cast<double*>(prec->bptr);
+
39 
+
40  long ret = dbGetLink(&prec->inp, DBF_DOUBLE, &phase, 0, 0);
+
41  if(ret) {
+
42  (void)recGblSetSevr(prec, LINK_ALARM, INVALID_ALARM);
+
43  return ret;
+
44  }
+
45 
+
46  phase *= pi_180; // deg -> rad
+
47 
+
48  for(size_t i=0, N=prec->nelm; i<N; i++)
+
49  val[i] = sin(freq*i+phase);
+
50 
+
51  prec->nord = prec->nelm;
+
52 
+
53 #ifdef DBRutag
+
54  prec->utag = (prec->utag+1u)&0x7fffffff;
+
55 #endif
+
56 
+
57  return 0;
+
58 }
+
59 
+
60 long process_repeat(waveformRecord *prec)
+
61 {
+
62  long ret;
+
63  if(prec->ftvl!=menuFtypeULONG) {
+
64  recGblSetSevr(prec, READ_ALARM, INVALID_ALARM);
+
65  return S_db_badDbrtype;
+
66  }
+
67 
+
68  epicsUInt32 iv=0;
+
69  if(!!(ret = dbGetLink(&prec->inp, DBF_ULONG, &iv, NULL, NULL))) {
+
70  recGblSetSevr(prec, READ_ALARM, INVALID_ALARM);
+
71  return ret;
+
72  }
+
73 
+
74  epicsUInt32 *val = (epicsUInt32*)prec->bptr;
+
75  for(size_t i=0, N=prec->nelm; i<N; i++) {
+
76  val[i] = iv;
+
77  }
+
78 
+
79  prec->nord = iv;
+
80 
+
81  return 0;
+
82 }
+
83 
+
84 long process_utag(longinRecord *prec)
+
85 {
+
86  long status = dbGetLink(&prec->inp, DBR_LONG, &prec->val, 0, 0);
+
87 #ifdef DBRutag
+
88  prec->utag = prec->val;
+
89 #else
+
90  (void)recGblSetSevr(prec, COMM_ALARM, INVALID_ALARM);
+
91 #endif
+
92  return status;
+
93 }
+
94 
+
95 template<typename REC>
+
96 struct dset5
+
97 {
+
98  long count;
+
99  long (*report)(int);
+
100  long (*init)(int);
+
101  long (*init_record)(REC *);
+
102  long (*get_ioint_info)(int, REC *, IOSCANPVT*);
+
103  long (*process)(REC *);
+
104 };
+
105 
+
106 dset5<waveformRecord> devWfPDBDemo = {5,0,0,&init_spin,0,&process_spin};
+
107 dset5<waveformRecord> devWfPDBDemoRepeat = {5,0,0,0,0,&process_repeat};
+
108 dset5<longinRecord> devLoPDBUTag = {5,0,0,0,0,&process_utag};
+
109 
+
110 } // namespace
+
111 
+
112 extern "C" {
+
113 epicsExportAddress(dset, devWfPDBDemo);
+
114 epicsExportAddress(dset, devWfPDBDemoRepeat);
+
115 epicsExportAddress(dset, devLoPDBUTag);
+
116 }
+
+ + + + diff --git a/dir_138aff360eb965c43b94267b8d1ce09e.html b/dir_138aff360eb965c43b94267b8d1ce09e.html new file mode 100644 index 0000000..5e0758b --- /dev/null +++ b/dir_138aff360eb965c43b94267b8d1ce09e.html @@ -0,0 +1,107 @@ + + + + + + +pva2pva: documentation Directory Reference + + + + + + + + + +
+
+ + + + + + +
+
pva2pva +  1.4.1 +
+
+
+ + + + + +
+ All Classes Functions Variables Pages
+ + +
+ +
+ + +
+
+
+
documentation Directory Reference
+
+
+
+Directory dependency graph for documentation:
+
+
documentation
+ + +
+ + + + +

+Files

file  conf.py [code]
 
+
+ + + + diff --git a/dir_138aff360eb965c43b94267b8d1ce09e_dep.map b/dir_138aff360eb965c43b94267b8d1ce09e_dep.map new file mode 100644 index 0000000..d242842 --- /dev/null +++ b/dir_138aff360eb965c43b94267b8d1ce09e_dep.map @@ -0,0 +1,3 @@ + + + diff --git a/dir_138aff360eb965c43b94267b8d1ce09e_dep.md5 b/dir_138aff360eb965c43b94267b8d1ce09e_dep.md5 new file mode 100644 index 0000000..e0fe439 --- /dev/null +++ b/dir_138aff360eb965c43b94267b8d1ce09e_dep.md5 @@ -0,0 +1 @@ +4d7e5d296be37a928a2c3a5c39e80340 \ No newline at end of file diff --git a/dir_138aff360eb965c43b94267b8d1ce09e_dep.png b/dir_138aff360eb965c43b94267b8d1ce09e_dep.png new file mode 100644 index 0000000..3b8c8c8 Binary files /dev/null and b/dir_138aff360eb965c43b94267b8d1ce09e_dep.png differ diff --git a/dir_46f976b0973771c28afc7d2dbc59236d.html b/dir_46f976b0973771c28afc7d2dbc59236d.html new file mode 100644 index 0000000..bb93e7b --- /dev/null +++ b/dir_46f976b0973771c28afc7d2dbc59236d.html @@ -0,0 +1,151 @@ + + + + + + +pva2pva: pdbApp Directory Reference + + + + + + + + + +
+
+ + + + + + +
+
pva2pva +  1.4.1 +
+
+
+ + + + + +
+ All Classes Functions Variables Pages
+ + +
+ +
+ + +
+
+
+
pdbApp Directory Reference
+
+
+
+Directory dependency graph for pdbApp:
+
+
pdbApp
+ + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Files

file  configparse.cpp [code]
 
file  dbf_copy.cpp [code]
 
file  demo.cpp [code]
 
file  imagedemo.c [code]
 
file  pdb.cpp [code]
 
file  pdb.h [code]
 
file  pdbgroup.cpp [code]
 
file  pdbgroup.h [code]
 
file  pdbsingle.cpp [code]
 
file  pdbsingle.h [code]
 
 
 
 
 
 
 
 
file  pvif.cpp [code]
 
file  pvif.h [code]
 
file  qsrv.cpp [code]
 
file  softMain.cpp [code]
 
file  tpool.cpp [code]
 
file  tpool.h [code]
 
+
+ + + + diff --git a/dir_46f976b0973771c28afc7d2dbc59236d_dep.map b/dir_46f976b0973771c28afc7d2dbc59236d_dep.map new file mode 100644 index 0000000..c31ba95 --- /dev/null +++ b/dir_46f976b0973771c28afc7d2dbc59236d_dep.map @@ -0,0 +1,3 @@ + + + diff --git a/dir_46f976b0973771c28afc7d2dbc59236d_dep.md5 b/dir_46f976b0973771c28afc7d2dbc59236d_dep.md5 new file mode 100644 index 0000000..12b3ff2 --- /dev/null +++ b/dir_46f976b0973771c28afc7d2dbc59236d_dep.md5 @@ -0,0 +1 @@ +bd163614b44dd8222685dd3ce3de05b9 \ No newline at end of file diff --git a/dir_46f976b0973771c28afc7d2dbc59236d_dep.png b/dir_46f976b0973771c28afc7d2dbc59236d_dep.png new file mode 100644 index 0000000..316dbe6 Binary files /dev/null and b/dir_46f976b0973771c28afc7d2dbc59236d_dep.png differ diff --git a/dir_aa611b0b6017302a0b5c69f5fe6608dd.html b/dir_aa611b0b6017302a0b5c69f5fe6608dd.html new file mode 100644 index 0000000..8beca74 --- /dev/null +++ b/dir_aa611b0b6017302a0b5c69f5fe6608dd.html @@ -0,0 +1,133 @@ + + + + + + +pva2pva: p2pApp Directory Reference + + + + + + + + + +
+
+ + + + + + +
+
pva2pva +  1.4.1 +
+
+
+ + + + + +
+ All Classes Functions Variables Pages
+ + +
+ +
+ + +
+
+
+
p2pApp Directory Reference
+
+
+
+Directory dependency graph for p2pApp:
+
+
p2pApp
+ + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Files

file  chancache.cpp [code]
 
file  chancache.h [code]
 
file  channel.cpp [code]
 
file  channel.h [code]
 
file  gwmain.cpp [code]
 
file  helper.h [code]
 
file  moncache.cpp [code]
 
file  pva2pva.h [code]
 
file  server.cpp [code]
 
file  server.h [code]
 
file  testmon.cpp [code]
 
file  utilitiesx.cpp [code]
 
file  weakmap.h [code]
 
file  weakset.h [code]
 
+
+ + + + diff --git a/dir_aa611b0b6017302a0b5c69f5fe6608dd_dep.map b/dir_aa611b0b6017302a0b5c69f5fe6608dd_dep.map new file mode 100644 index 0000000..4e339c9 --- /dev/null +++ b/dir_aa611b0b6017302a0b5c69f5fe6608dd_dep.map @@ -0,0 +1,3 @@ + + + diff --git a/dir_aa611b0b6017302a0b5c69f5fe6608dd_dep.md5 b/dir_aa611b0b6017302a0b5c69f5fe6608dd_dep.md5 new file mode 100644 index 0000000..0ac1cb3 --- /dev/null +++ b/dir_aa611b0b6017302a0b5c69f5fe6608dd_dep.md5 @@ -0,0 +1 @@ +39540a6dfad90207eeccb1e903c8d9a0 \ No newline at end of file diff --git a/dir_aa611b0b6017302a0b5c69f5fe6608dd_dep.png b/dir_aa611b0b6017302a0b5c69f5fe6608dd_dep.png new file mode 100644 index 0000000..7b000ac Binary files /dev/null and b/dir_aa611b0b6017302a0b5c69f5fe6608dd_dep.png differ diff --git a/dir_bdd9a5d540de89e9fe90efdfc6973a4f.html b/dir_bdd9a5d540de89e9fe90efdfc6973a4f.html new file mode 100644 index 0000000..891f7ed --- /dev/null +++ b/dir_bdd9a5d540de89e9fe90efdfc6973a4f.html @@ -0,0 +1,113 @@ + + + + + + +pva2pva: common Directory Reference + + + + + + + + + +
+
+ + + + + + +
+
pva2pva +  1.4.1 +
+
+
+ + + + + +
+ All Classes Functions Variables Pages
+ + +
+ +
+ + +
+
+
+
common Directory Reference
+
+
+
+Directory dependency graph for common:
+
+
common
+ + +
+ + + + + + + + + + +

+Files

file  pvahelper.h [code]
 
file  sb.h [code]
 
file  utilities.cpp [code]
 
file  utilities.h [code]
 
+
+ + + + diff --git a/dir_bdd9a5d540de89e9fe90efdfc6973a4f_dep.map b/dir_bdd9a5d540de89e9fe90efdfc6973a4f_dep.map new file mode 100644 index 0000000..2bd78d4 --- /dev/null +++ b/dir_bdd9a5d540de89e9fe90efdfc6973a4f_dep.map @@ -0,0 +1,3 @@ + + + diff --git a/dir_bdd9a5d540de89e9fe90efdfc6973a4f_dep.md5 b/dir_bdd9a5d540de89e9fe90efdfc6973a4f_dep.md5 new file mode 100644 index 0000000..56e514d --- /dev/null +++ b/dir_bdd9a5d540de89e9fe90efdfc6973a4f_dep.md5 @@ -0,0 +1 @@ +415a2e4a9767d2d3b960388655ebead4 \ No newline at end of file diff --git a/dir_bdd9a5d540de89e9fe90efdfc6973a4f_dep.png b/dir_bdd9a5d540de89e9fe90efdfc6973a4f_dep.png new file mode 100644 index 0000000..88b3ffd Binary files /dev/null and b/dir_bdd9a5d540de89e9fe90efdfc6973a4f_dep.png differ diff --git a/doxygen.css b/doxygen.css new file mode 100644 index 0000000..4699e69 --- /dev/null +++ b/doxygen.css @@ -0,0 +1,1357 @@ +/* The standard CSS for doxygen 1.8.5 */ + +body, table, div, p, dl { + font: 400 14px/22px Roboto,sans-serif; +} + +/* @group Heading Levels */ + +h1.groupheader { + font-size: 150%; +} + +.title { + font: 400 14px/28px Roboto,sans-serif; + font-size: 150%; + font-weight: bold; + margin: 10px 2px; +} + +h2.groupheader { + border-bottom: 1px solid #879ECB; + color: #354C7B; + font-size: 150%; + font-weight: normal; + margin-top: 1.75em; + padding-top: 8px; + padding-bottom: 4px; + width: 100%; +} + +h3.groupheader { + font-size: 100%; +} + +h1, h2, h3, h4, h5, h6 { + -webkit-transition: text-shadow 0.5s linear; + -moz-transition: text-shadow 0.5s linear; + -ms-transition: text-shadow 0.5s linear; + -o-transition: text-shadow 0.5s linear; + transition: text-shadow 0.5s linear; + margin-right: 15px; +} + +h1.glow, h2.glow, h3.glow, h4.glow, h5.glow, h6.glow { + text-shadow: 0 0 15px cyan; +} + +dt { + font-weight: bold; +} + +div.multicol { + -moz-column-gap: 1em; + -webkit-column-gap: 1em; + -moz-column-count: 3; + -webkit-column-count: 3; +} + +p.startli, p.startdd, p.starttd { + margin-top: 2px; +} + +p.endli { + margin-bottom: 0px; +} + +p.enddd { + margin-bottom: 4px; +} + +p.endtd { + margin-bottom: 2px; +} + +/* @end */ + +caption { + font-weight: bold; +} + +span.legend { + font-size: 70%; + text-align: center; +} + +h3.version { + font-size: 90%; + text-align: center; +} + +div.qindex, div.navtab{ + background-color: #EBEFF6; + border: 1px solid #A3B4D7; + text-align: center; +} + +div.qindex, div.navpath { + width: 100%; + line-height: 140%; +} + +div.navtab { + margin-right: 15px; +} + +/* @group Link Styling */ + +a { + color: #3D578C; + font-weight: normal; + text-decoration: none; +} + +.contents a:visited { + color: #4665A2; +} + +a:hover { + text-decoration: underline; +} + +a.qindex { + font-weight: bold; +} + +a.qindexHL { + font-weight: bold; + background-color: #9CAFD4; + color: #ffffff; + border: 1px double #869DCA; +} + +.contents a.qindexHL:visited { + color: #ffffff; +} + +a.el { + font-weight: bold; +} + +a.elRef { +} + +a.code, a.code:visited, a.line, a.line:visited { + color: #4665A2; +} + +a.codeRef, a.codeRef:visited, a.lineRef, a.lineRef:visited { + color: #4665A2; +} + +/* @end */ + +dl.el { + margin-left: -1cm; +} + +pre.fragment { + border: 1px solid #C4CFE5; + background-color: #FBFCFD; + padding: 4px 6px; + margin: 4px 8px 4px 2px; + overflow: auto; + word-wrap: break-word; + font-size: 9pt; + line-height: 125%; + font-family: monospace, fixed; + font-size: 105%; +} + +div.fragment { + padding: 0px; + margin: 0px; + background-color: #FBFCFD; + border: 1px solid #C4CFE5; +} + +div.line { + font-family: monospace, fixed; + font-size: 13px; + min-height: 13px; + line-height: 1.0; + text-wrap: unrestricted; + white-space: -moz-pre-wrap; /* Moz */ + white-space: -pre-wrap; /* Opera 4-6 */ + white-space: -o-pre-wrap; /* Opera 7 */ + white-space: pre-wrap; /* CSS3 */ + word-wrap: break-word; /* IE 5.5+ */ + text-indent: -53px; + padding-left: 53px; + padding-bottom: 0px; + margin: 0px; + -webkit-transition-property: background-color, box-shadow; + -webkit-transition-duration: 0.5s; + -moz-transition-property: background-color, box-shadow; + -moz-transition-duration: 0.5s; + -ms-transition-property: background-color, box-shadow; + -ms-transition-duration: 0.5s; + -o-transition-property: background-color, box-shadow; + -o-transition-duration: 0.5s; + transition-property: background-color, box-shadow; + transition-duration: 0.5s; +} + +div.line.glow { + background-color: cyan; + box-shadow: 0 0 10px cyan; +} + + +span.lineno { + padding-right: 4px; + text-align: right; + border-right: 2px solid #0F0; + background-color: #E8E8E8; + white-space: pre; +} +span.lineno a { + background-color: #D8D8D8; +} + +span.lineno a:hover { + background-color: #C8C8C8; +} + +div.ah { + background-color: black; + font-weight: bold; + color: #ffffff; + margin-bottom: 3px; + margin-top: 3px; + padding: 0.2em; + border: solid thin #333; + border-radius: 0.5em; + -webkit-border-radius: .5em; + -moz-border-radius: .5em; + box-shadow: 2px 2px 3px #999; + -webkit-box-shadow: 2px 2px 3px #999; + -moz-box-shadow: rgba(0, 0, 0, 0.15) 2px 2px 2px; + background-image: -webkit-gradient(linear, left top, left bottom, from(#eee), to(#000),color-stop(0.3, #444)); + background-image: -moz-linear-gradient(center top, #eee 0%, #444 40%, #000); +} + +div.groupHeader { + margin-left: 16px; + margin-top: 12px; + font-weight: bold; +} + +div.groupText { + margin-left: 16px; + font-style: italic; +} + +body { + background-color: white; + color: black; + margin: 0; +} + +div.contents { + margin-top: 10px; + margin-left: 12px; + margin-right: 8px; +} + +td.indexkey { + background-color: #EBEFF6; + font-weight: bold; + border: 1px solid #C4CFE5; + margin: 2px 0px 2px 0; + padding: 2px 10px; + white-space: nowrap; + vertical-align: top; +} + +td.indexvalue { + background-color: #EBEFF6; + border: 1px solid #C4CFE5; + padding: 2px 10px; + margin: 2px 0px; +} + +tr.memlist { + background-color: #EEF1F7; +} + +p.formulaDsp { + text-align: center; +} + +img.formulaDsp { + +} + +img.formulaInl { + vertical-align: middle; +} + +div.center { + text-align: center; + margin-top: 0px; + margin-bottom: 0px; + padding: 0px; +} + +div.center img { + border: 0px; +} + +address.footer { + text-align: right; + padding-right: 12px; +} + +img.footer { + border: 0px; + vertical-align: middle; +} + +/* @group Code Colorization */ + +span.keyword { + color: #008000 +} + +span.keywordtype { + color: #604020 +} + +span.keywordflow { + color: #e08000 +} + +span.comment { + color: #800000 +} + +span.preprocessor { + color: #806020 +} + +span.stringliteral { + color: #002080 +} + +span.charliteral { + color: #008080 +} + +span.vhdldigit { + color: #ff00ff +} + +span.vhdlchar { + color: #000000 +} + +span.vhdlkeyword { + color: #700070 +} + +span.vhdllogic { + color: #ff0000 +} + +blockquote { + background-color: #F7F8FB; + border-left: 2px solid #9CAFD4; + margin: 0 24px 0 4px; + padding: 0 12px 0 16px; +} + +/* @end */ + +/* +.search { + color: #003399; + font-weight: bold; +} + +form.search { + margin-bottom: 0px; + margin-top: 0px; +} + +input.search { + font-size: 75%; + color: #000080; + font-weight: normal; + background-color: #e8eef2; +} +*/ + +td.tiny { + font-size: 75%; +} + +.dirtab { + padding: 4px; + border-collapse: collapse; + border: 1px solid #A3B4D7; +} + +th.dirtab { + background: #EBEFF6; + font-weight: bold; +} + +hr { + height: 0px; + border: none; + border-top: 1px solid #4A6AAA; +} + +hr.footer { + height: 1px; +} + +/* @group Member Descriptions */ + +table.memberdecls { + border-spacing: 0px; + padding: 0px; +} + +.memberdecls td, .fieldtable tr { + -webkit-transition-property: background-color, box-shadow; + -webkit-transition-duration: 0.5s; + -moz-transition-property: background-color, box-shadow; + -moz-transition-duration: 0.5s; + -ms-transition-property: background-color, box-shadow; + -ms-transition-duration: 0.5s; + -o-transition-property: background-color, box-shadow; + -o-transition-duration: 0.5s; + transition-property: background-color, box-shadow; + transition-duration: 0.5s; +} + +.memberdecls td.glow, .fieldtable tr.glow { + background-color: cyan; + box-shadow: 0 0 15px cyan; +} + +.mdescLeft, .mdescRight, +.memItemLeft, .memItemRight, +.memTemplItemLeft, .memTemplItemRight, .memTemplParams { + background-color: #F9FAFC; + border: none; + margin: 4px; + padding: 1px 0 0 8px; +} + +.mdescLeft, .mdescRight { + padding: 0px 8px 4px 8px; + color: #555; +} + +.memSeparator { + border-bottom: 1px solid #DEE4F0; + line-height: 1px; + margin: 0px; + padding: 0px; +} + +.memItemLeft, .memTemplItemLeft { + white-space: nowrap; +} + +.memItemRight { + width: 100%; +} + +.memTemplParams { + color: #4665A2; + white-space: nowrap; + font-size: 80%; +} + +/* @end */ + +/* @group Member Details */ + +/* Styles for detailed member documentation */ + +.memtemplate { + font-size: 80%; + color: #4665A2; + font-weight: normal; + margin-left: 9px; +} + +.memnav { + background-color: #EBEFF6; + border: 1px solid #A3B4D7; + text-align: center; + margin: 2px; + margin-right: 15px; + padding: 2px; +} + +.mempage { + width: 100%; +} + +.memitem { + padding: 0; + margin-bottom: 10px; + margin-right: 5px; + -webkit-transition: box-shadow 0.5s linear; + -moz-transition: box-shadow 0.5s linear; + -ms-transition: box-shadow 0.5s linear; + -o-transition: box-shadow 0.5s linear; + transition: box-shadow 0.5s linear; + display: table !important; + width: 100%; +} + +.memitem.glow { + box-shadow: 0 0 15px cyan; +} + +.memname { + font-weight: bold; + margin-left: 6px; +} + +.memname td { + vertical-align: bottom; +} + +.memproto, dl.reflist dt { + border-top: 1px solid #A8B8D9; + border-left: 1px solid #A8B8D9; + border-right: 1px solid #A8B8D9; + padding: 6px 0px 6px 0px; + color: #253555; + font-weight: bold; + text-shadow: 0px 1px 1px rgba(255, 255, 255, 0.9); + background-image:url('nav_f.png'); + background-repeat:repeat-x; + background-color: #E2E8F2; + /* opera specific markup */ + box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.15); + border-top-right-radius: 4px; + border-top-left-radius: 4px; + /* firefox specific markup */ + -moz-box-shadow: rgba(0, 0, 0, 0.15) 5px 5px 5px; + -moz-border-radius-topright: 4px; + -moz-border-radius-topleft: 4px; + /* webkit specific markup */ + -webkit-box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.15); + -webkit-border-top-right-radius: 4px; + -webkit-border-top-left-radius: 4px; + +} + +.memdoc, dl.reflist dd { + border-bottom: 1px solid #A8B8D9; + border-left: 1px solid #A8B8D9; + border-right: 1px solid #A8B8D9; + padding: 6px 10px 2px 10px; + background-color: #FBFCFD; + border-top-width: 0; + background-image:url('nav_g.png'); + background-repeat:repeat-x; + background-color: #FFFFFF; + /* opera specific markup */ + border-bottom-left-radius: 4px; + border-bottom-right-radius: 4px; + box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.15); + /* firefox specific markup */ + -moz-border-radius-bottomleft: 4px; + -moz-border-radius-bottomright: 4px; + -moz-box-shadow: rgba(0, 0, 0, 0.15) 5px 5px 5px; + /* webkit specific markup */ + -webkit-border-bottom-left-radius: 4px; + -webkit-border-bottom-right-radius: 4px; + -webkit-box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.15); +} + +dl.reflist dt { + padding: 5px; +} + +dl.reflist dd { + margin: 0px 0px 10px 0px; + padding: 5px; +} + +.paramkey { + text-align: right; +} + +.paramtype { + white-space: nowrap; +} + +.paramname { + color: #602020; + white-space: nowrap; +} +.paramname em { + font-style: normal; +} +.paramname code { + line-height: 14px; +} + +.params, .retval, .exception, .tparams { + margin-left: 0px; + padding-left: 0px; +} + +.params .paramname, .retval .paramname { + font-weight: bold; + vertical-align: top; +} + +.params .paramtype { + font-style: italic; + vertical-align: top; +} + +.params .paramdir { + font-family: "courier new",courier,monospace; + vertical-align: top; +} + +table.mlabels { + border-spacing: 0px; +} + +td.mlabels-left { + width: 100%; + padding: 0px; +} + +td.mlabels-right { + vertical-align: bottom; + padding: 0px; + white-space: nowrap; +} + +span.mlabels { + margin-left: 8px; +} + +span.mlabel { + background-color: #728DC1; + border-top:1px solid #5373B4; + border-left:1px solid #5373B4; + border-right:1px solid #C4CFE5; + border-bottom:1px solid #C4CFE5; + text-shadow: none; + color: white; + margin-right: 4px; + padding: 2px 3px; + border-radius: 3px; + font-size: 7pt; + white-space: nowrap; + vertical-align: middle; +} + + + +/* @end */ + +/* these are for tree view when not used as main index */ + +div.directory { + margin: 10px 0px; + border-top: 1px solid #A8B8D9; + border-bottom: 1px solid #A8B8D9; + width: 100%; +} + +.directory table { + border-collapse:collapse; +} + +.directory td { + margin: 0px; + padding: 0px; + vertical-align: top; +} + +.directory td.entry { + white-space: nowrap; + padding-right: 6px; + padding-top: 3px; +} + +.directory td.entry a { + outline:none; +} + +.directory td.entry a img { + border: none; +} + +.directory td.desc { + width: 100%; + padding-left: 6px; + padding-right: 6px; + padding-top: 3px; + border-left: 1px solid rgba(0,0,0,0.05); +} + +.directory tr.even { + padding-left: 6px; + background-color: #F7F8FB; +} + +.directory img { + vertical-align: -30%; +} + +.directory .levels { + white-space: nowrap; + width: 100%; + text-align: right; + font-size: 9pt; +} + +.directory .levels span { + cursor: pointer; + padding-left: 2px; + padding-right: 2px; + color: #3D578C; +} + +div.dynheader { + margin-top: 8px; + -webkit-touch-callout: none; + -webkit-user-select: none; + -khtml-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; +} + +address { + font-style: normal; + color: #2A3D61; +} + +table.doxtable { + border-collapse:collapse; + margin-top: 4px; + margin-bottom: 4px; +} + +table.doxtable td, table.doxtable th { + border: 1px solid #2D4068; + padding: 3px 7px 2px; +} + +table.doxtable th { + background-color: #374F7F; + color: #FFFFFF; + font-size: 110%; + padding-bottom: 4px; + padding-top: 5px; +} + +table.fieldtable { + /*width: 100%;*/ + margin-bottom: 10px; + border: 1px solid #A8B8D9; + border-spacing: 0px; + -moz-border-radius: 4px; + -webkit-border-radius: 4px; + border-radius: 4px; + -moz-box-shadow: rgba(0, 0, 0, 0.15) 2px 2px 2px; + -webkit-box-shadow: 2px 2px 2px rgba(0, 0, 0, 0.15); + box-shadow: 2px 2px 2px rgba(0, 0, 0, 0.15); +} + +.fieldtable td, .fieldtable th { + padding: 3px 7px 2px; +} + +.fieldtable td.fieldtype, .fieldtable td.fieldname { + white-space: nowrap; + border-right: 1px solid #A8B8D9; + border-bottom: 1px solid #A8B8D9; + vertical-align: top; +} + +.fieldtable td.fieldname { + padding-top: 3px; +} + +.fieldtable td.fielddoc { + border-bottom: 1px solid #A8B8D9; + /*width: 100%;*/ +} + +.fieldtable td.fielddoc p:first-child { + margin-top: 0px; +} + +.fieldtable td.fielddoc p:last-child { + margin-bottom: 2px; +} + +.fieldtable tr:last-child td { + border-bottom: none; +} + +.fieldtable th { + background-image:url('nav_f.png'); + background-repeat:repeat-x; + background-color: #E2E8F2; + font-size: 90%; + color: #253555; + padding-bottom: 4px; + padding-top: 5px; + text-align:left; + -moz-border-radius-topleft: 4px; + -moz-border-radius-topright: 4px; + -webkit-border-top-left-radius: 4px; + -webkit-border-top-right-radius: 4px; + border-top-left-radius: 4px; + border-top-right-radius: 4px; + border-bottom: 1px solid #A8B8D9; +} + + +.tabsearch { + top: 0px; + left: 10px; + height: 36px; + background-image: url('tab_b.png'); + z-index: 101; + overflow: hidden; + font-size: 13px; +} + +.navpath ul +{ + font-size: 11px; + background-image:url('tab_b.png'); + background-repeat:repeat-x; + background-position: 0 -5px; + height:30px; + line-height:30px; + color:#8AA0CC; + border:solid 1px #C2CDE4; + overflow:hidden; + margin:0px; + padding:0px; +} + +.navpath li +{ + list-style-type:none; + float:left; + padding-left:10px; + padding-right:15px; + background-image:url('bc_s.png'); + background-repeat:no-repeat; + background-position:right; + color:#364D7C; +} + +.navpath li.navelem a +{ + height:32px; + display:block; + text-decoration: none; + outline: none; + color: #283A5D; + font-family: 'Lucida Grande',Geneva,Helvetica,Arial,sans-serif; + text-shadow: 0px 1px 1px rgba(255, 255, 255, 0.9); + text-decoration: none; +} + +.navpath li.navelem a:hover +{ + color:#6884BD; +} + +.navpath li.footer +{ + list-style-type:none; + float:right; + padding-left:10px; + padding-right:15px; + background-image:none; + background-repeat:no-repeat; + background-position:right; + color:#364D7C; + font-size: 8pt; +} + + +div.summary +{ + float: right; + font-size: 8pt; + padding-right: 5px; + width: 50%; + text-align: right; +} + +div.summary a +{ + white-space: nowrap; +} + +div.ingroups +{ + font-size: 8pt; + width: 50%; + text-align: left; +} + +div.ingroups a +{ + white-space: nowrap; +} + +div.header +{ + background-image:url('nav_h.png'); + background-repeat:repeat-x; + background-color: #F9FAFC; + margin: 0px; + border-bottom: 1px solid #C4CFE5; +} + +div.headertitle +{ + padding: 5px 5px 5px 10px; +} + +dl +{ + padding: 0 0 0 10px; +} + +/* dl.note, dl.warning, dl.attention, dl.pre, dl.post, dl.invariant, dl.deprecated, dl.todo, dl.test, dl.bug */ +dl.section +{ + margin-left: 0px; + padding-left: 0px; +} + +dl.note +{ + margin-left:-7px; + padding-left: 3px; + border-left:4px solid; + border-color: #D0C000; +} + +dl.warning, dl.attention +{ + margin-left:-7px; + padding-left: 3px; + border-left:4px solid; + border-color: #FF0000; +} + +dl.pre, dl.post, dl.invariant +{ + margin-left:-7px; + padding-left: 3px; + border-left:4px solid; + border-color: #00D000; +} + +dl.deprecated +{ + margin-left:-7px; + padding-left: 3px; + border-left:4px solid; + border-color: #505050; +} + +dl.todo +{ + margin-left:-7px; + padding-left: 3px; + border-left:4px solid; + border-color: #00C0E0; +} + +dl.test +{ + margin-left:-7px; + padding-left: 3px; + border-left:4px solid; + border-color: #3030E0; +} + +dl.bug +{ + margin-left:-7px; + padding-left: 3px; + border-left:4px solid; + border-color: #C08050; +} + +dl.section dd { + margin-bottom: 6px; +} + + +#projectlogo +{ + text-align: center; + vertical-align: bottom; + border-collapse: separate; +} + +#projectlogo img +{ + border: 0px none; +} + +#projectname +{ + font: 300% Tahoma, Arial,sans-serif; + margin: 0px; + padding: 2px 0px; +} + +#projectbrief +{ + font: 120% Tahoma, Arial,sans-serif; + margin: 0px; + padding: 0px; +} + +#projectnumber +{ + font: 50% Tahoma, Arial,sans-serif; + margin: 0px; + padding: 0px; +} + +#titlearea +{ + padding: 0px; + margin: 0px; + width: 100%; + border-bottom: 1px solid #5373B4; +} + +.image +{ + text-align: center; +} + +.dotgraph +{ + text-align: center; +} + +.mscgraph +{ + text-align: center; +} + +.caption +{ + font-weight: bold; +} + +div.zoom +{ + border: 1px solid #90A5CE; +} + +dl.citelist { + margin-bottom:50px; +} + +dl.citelist dt { + color:#334975; + float:left; + font-weight:bold; + margin-right:10px; + padding:5px; +} + +dl.citelist dd { + margin:2px 0; + padding:5px 0; +} + +div.toc { + padding: 14px 25px; + background-color: #F4F6FA; + border: 1px solid #D8DFEE; + border-radius: 7px 7px 7px 7px; + float: right; + height: auto; + margin: 0 20px 10px 10px; + width: 200px; +} + +div.toc li { + background: url("bdwn.png") no-repeat scroll 0 5px transparent; + font: 10px/1.2 Verdana,DejaVu Sans,Geneva,sans-serif; + margin-top: 5px; + padding-left: 10px; + padding-top: 2px; +} + +div.toc h3 { + font: bold 12px/1.2 Arial,FreeSans,sans-serif; + color: #4665A2; + border-bottom: 0 none; + margin: 0; +} + +div.toc ul { + list-style: none outside none; + border: medium none; + padding: 0px; +} + +div.toc li.level1 { + margin-left: 0px; +} + +div.toc li.level2 { + margin-left: 15px; +} + +div.toc li.level3 { + margin-left: 30px; +} + +div.toc li.level4 { + margin-left: 45px; +} + +.inherit_header { + font-weight: bold; + color: gray; + cursor: pointer; + -webkit-touch-callout: none; + -webkit-user-select: none; + -khtml-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; +} + +.inherit_header td { + padding: 6px 0px 2px 5px; +} + +.inherit { + display: none; +} + +tr.heading h2 { + margin-top: 12px; + margin-bottom: 4px; +} + +/* tooltip related style info */ + +.ttc { + position: absolute; + display: none; +} + +#powerTip { + cursor: default; + white-space: nowrap; + background-color: white; + border: 1px solid gray; + border-radius: 4px 4px 4px 4px; + box-shadow: 1px 1px 7px gray; + display: none; + font-size: smaller; + max-width: 80%; + opacity: 0.9; + padding: 1ex 1em 1em; + position: absolute; + z-index: 2147483647; +} + +#powerTip div.ttdoc { + color: grey; + font-style: italic; +} + +#powerTip div.ttname a { + font-weight: bold; +} + +#powerTip div.ttname { + font-weight: bold; +} + +#powerTip div.ttdeci { + color: #006318; +} + +#powerTip div { + margin: 0px; + padding: 0px; + font: 12px/16px Roboto,sans-serif; +} + +#powerTip:before, #powerTip:after { + content: ""; + position: absolute; + margin: 0px; +} + +#powerTip.n:after, #powerTip.n:before, +#powerTip.s:after, #powerTip.s:before, +#powerTip.w:after, #powerTip.w:before, +#powerTip.e:after, #powerTip.e:before, +#powerTip.ne:after, #powerTip.ne:before, +#powerTip.se:after, #powerTip.se:before, +#powerTip.nw:after, #powerTip.nw:before, +#powerTip.sw:after, #powerTip.sw:before { + border: solid transparent; + content: " "; + height: 0; + width: 0; + position: absolute; +} + +#powerTip.n:after, #powerTip.s:after, +#powerTip.w:after, #powerTip.e:after, +#powerTip.nw:after, #powerTip.ne:after, +#powerTip.sw:after, #powerTip.se:after { + border-color: rgba(255, 255, 255, 0); +} + +#powerTip.n:before, #powerTip.s:before, +#powerTip.w:before, #powerTip.e:before, +#powerTip.nw:before, #powerTip.ne:before, +#powerTip.sw:before, #powerTip.se:before { + border-color: rgba(128, 128, 128, 0); +} + +#powerTip.n:after, #powerTip.n:before, +#powerTip.ne:after, #powerTip.ne:before, +#powerTip.nw:after, #powerTip.nw:before { + top: 100%; +} + +#powerTip.n:after, #powerTip.ne:after, #powerTip.nw:after { + border-top-color: #ffffff; + border-width: 10px; + margin: 0px -10px; +} +#powerTip.n:before { + border-top-color: #808080; + border-width: 11px; + margin: 0px -11px; +} +#powerTip.n:after, #powerTip.n:before { + left: 50%; +} + +#powerTip.nw:after, #powerTip.nw:before { + right: 14px; +} + +#powerTip.ne:after, #powerTip.ne:before { + left: 14px; +} + +#powerTip.s:after, #powerTip.s:before, +#powerTip.se:after, #powerTip.se:before, +#powerTip.sw:after, #powerTip.sw:before { + bottom: 100%; +} + +#powerTip.s:after, #powerTip.se:after, #powerTip.sw:after { + border-bottom-color: #ffffff; + border-width: 10px; + margin: 0px -10px; +} + +#powerTip.s:before, #powerTip.se:before, #powerTip.sw:before { + border-bottom-color: #808080; + border-width: 11px; + margin: 0px -11px; +} + +#powerTip.s:after, #powerTip.s:before { + left: 50%; +} + +#powerTip.sw:after, #powerTip.sw:before { + right: 14px; +} + +#powerTip.se:after, #powerTip.se:before { + left: 14px; +} + +#powerTip.e:after, #powerTip.e:before { + left: 100%; +} +#powerTip.e:after { + border-left-color: #ffffff; + border-width: 10px; + top: 50%; + margin-top: -10px; +} +#powerTip.e:before { + border-left-color: #808080; + border-width: 11px; + top: 50%; + margin-top: -11px; +} + +#powerTip.w:after, #powerTip.w:before { + right: 100%; +} +#powerTip.w:after { + border-right-color: #ffffff; + border-width: 10px; + top: 50%; + margin-top: -10px; +} +#powerTip.w:before { + border-right-color: #808080; + border-width: 11px; + top: 50%; + margin-top: -11px; +} + +@media print +{ + #top { display: none; } + #side-nav { display: none; } + #nav-path { display: none; } + body { overflow:visible; } + h1, h2, h3, h4, h5, h6 { page-break-after: avoid; } + .summary { display: none; } + .memitem { page-break-inside: avoid; } + #doc-content + { + margin-left:0 !important; + height:auto !important; + width:auto !important; + overflow:inherit; + display:inline; + } +} + diff --git a/doxygen.png b/doxygen.png new file mode 100644 index 0000000..3ff17d8 Binary files /dev/null and b/doxygen.png differ diff --git a/dynsections.js b/dynsections.js new file mode 100644 index 0000000..2f15470 --- /dev/null +++ b/dynsections.js @@ -0,0 +1,104 @@ +function toggleVisibility(linkObj) +{ + var base = $(linkObj).attr('id'); + var summary = $('#'+base+'-summary'); + var content = $('#'+base+'-content'); + var trigger = $('#'+base+'-trigger'); + var src=$(trigger).attr('src'); + if (content.is(':visible')===true) { + content.hide(); + summary.show(); + $(linkObj).addClass('closed').removeClass('opened'); + $(trigger).attr('src',src.substring(0,src.length-8)+'closed.png'); + } else { + content.show(); + summary.hide(); + $(linkObj).removeClass('closed').addClass('opened'); + $(trigger).attr('src',src.substring(0,src.length-10)+'open.png'); + } + return false; +} + +function updateStripes() +{ + $('table.directory tr'). + removeClass('even').filter(':visible:even').addClass('even'); +} +function toggleLevel(level) +{ + $('table.directory tr').each(function(){ + var l = this.id.split('_').length-1; + var i = $('#img'+this.id.substring(3)); + var a = $('#arr'+this.id.substring(3)); + if (l + + + + + +pva2pva: File List + + + + + + + + + +
+
+ + + + + + +
+
pva2pva +  1.4.1 +
+
+
+ + + + + +
+ +
+ All Classes Functions Variables Pages
+ + +
+ +
+ +
+
+
File List
+
+
+
Here is a list of all documented files with brief descriptions:
+
[detail level 12]
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
o-common
|o*pvahelper.h
|o*sb.h
|o*utilities.cpp
|\*utilities.h
o-documentation
|\*conf.py
o-p2pApp
|o*chancache.cpp
|o*chancache.h
|o*channel.cpp
|o*channel.h
|o*gwmain.cpp
|o*helper.h
|o*moncache.cpp
|o*pva2pva.h
|o*server.cpp
|o*server.h
|o*testmon.cpp
|o*utilitiesx.cpp
|o*weakmap.h
|\*weakset.h
\-pdbApp
 o*configparse.cpp
 o*dbf_copy.cpp
 o*demo.cpp
 o*imagedemo.c
 o*pdb.cpp
 o*pdb.h
 o*pdbgroup.cpp
 o*pdbgroup.h
 o*pdbsingle.cpp
 o*pdbsingle.h
 o*pvalink.cpp
 o*pvalink.h
 o*pvalink_channel.cpp
 o*pvalink_jlif.cpp
 o*pvalink_link.cpp
 o*pvalink_lset.cpp
 o*pvalink_null.cpp
 o*pvif.cpp
 o*pvif.h
 o*qsrv.cpp
 o*softMain.cpp
 o*tpool.cpp
 \*tpool.h
+
+
+ + + + diff --git a/ftv2blank.png b/ftv2blank.png new file mode 100644 index 0000000..63c605b Binary files /dev/null and b/ftv2blank.png differ diff --git a/ftv2cl.png b/ftv2cl.png new file mode 100644 index 0000000..132f657 Binary files /dev/null and b/ftv2cl.png differ diff --git a/ftv2doc.png b/ftv2doc.png new file mode 100644 index 0000000..17edabf Binary files /dev/null and b/ftv2doc.png differ diff --git a/ftv2folderclosed.png b/ftv2folderclosed.png new file mode 100644 index 0000000..bb8ab35 Binary files /dev/null and b/ftv2folderclosed.png differ diff --git a/ftv2folderopen.png b/ftv2folderopen.png new file mode 100644 index 0000000..d6c7f67 Binary files /dev/null and b/ftv2folderopen.png differ diff --git a/ftv2lastnode.png b/ftv2lastnode.png new file mode 100644 index 0000000..63c605b Binary files /dev/null and b/ftv2lastnode.png differ diff --git a/ftv2link.png b/ftv2link.png new file mode 100644 index 0000000..17edabf Binary files /dev/null and b/ftv2link.png differ diff --git a/ftv2mlastnode.png b/ftv2mlastnode.png new file mode 100644 index 0000000..0b63f6d Binary files /dev/null and b/ftv2mlastnode.png differ diff --git a/ftv2mnode.png b/ftv2mnode.png new file mode 100644 index 0000000..0b63f6d Binary files /dev/null and b/ftv2mnode.png differ diff --git a/ftv2mo.png b/ftv2mo.png new file mode 100644 index 0000000..4bfb80f Binary files /dev/null and b/ftv2mo.png differ diff --git a/ftv2node.png b/ftv2node.png new file mode 100644 index 0000000..63c605b Binary files /dev/null and b/ftv2node.png differ diff --git a/ftv2ns.png b/ftv2ns.png new file mode 100644 index 0000000..72e3d71 Binary files /dev/null and b/ftv2ns.png differ diff --git a/ftv2plastnode.png b/ftv2plastnode.png new file mode 100644 index 0000000..c6ee22f Binary files /dev/null and b/ftv2plastnode.png differ diff --git a/ftv2pnode.png b/ftv2pnode.png new file mode 100644 index 0000000..c6ee22f Binary files /dev/null and b/ftv2pnode.png differ diff --git a/ftv2splitbar.png b/ftv2splitbar.png new file mode 100644 index 0000000..fe895f2 Binary files /dev/null and b/ftv2splitbar.png differ diff --git a/ftv2vertline.png b/ftv2vertline.png new file mode 100644 index 0000000..63c605b Binary files /dev/null and b/ftv2vertline.png differ diff --git a/functions.html b/functions.html new file mode 100644 index 0000000..fc01ed3 --- /dev/null +++ b/functions.html @@ -0,0 +1,265 @@ + + + + + + +pva2pva: Class Members + + + + + + + + + +
+
+ + + + + + +
+
pva2pva +  1.4.1 +
+
+
+ + + + + + + +
+ +
+ All Classes Functions Variables Pages
+ + +
+ +
+ +
+
Here is a list of all documented class members with links to the class documentation for each member:
+ +

- c -

+ + +

- d -

+ + +

- e -

+ + +

- f -

+ + +

- g -

+ + +

- i -

+ + +

- l -

+ + +

- m -

+ + +

- n -

+ + +

- o -

+ + +

- p -

+ + +

- r -

+ + +

- s -

+ + +

- w -

+
+ + + + diff --git a/functions_func.html b/functions_func.html new file mode 100644 index 0000000..77b8ded --- /dev/null +++ b/functions_func.html @@ -0,0 +1,256 @@ + + + + + + +pva2pva: Class Members - Functions + + + + + + + + + +
+
+ + + + + + +
+
pva2pva +  1.4.1 +
+
+
+ + + + + + + +
+ +
+ All Classes Functions Variables Pages
+ + +
+ +
+ +
+  + +

- c -

+ + +

- d -

+ + +

- e -

+ + +

- f -

+ + +

- g -

+ + +

- i -

+ + +

- l -

+ + +

- m -

+ + +

- n -

+ + +

- o -

+ + +

- p -

+ + +

- r -

+ + +

- s -

+ + +

- w -

+
+ + + + diff --git a/functions_vars.html b/functions_vars.html new file mode 100644 index 0000000..7acba93 --- /dev/null +++ b/functions_vars.html @@ -0,0 +1,112 @@ + + + + + + +pva2pva: Class Members - Variables + + + + + + + + + +
+
+ + + + + + +
+
pva2pva +  1.4.1 +
+
+
+ + + + + + +
+ +
+ All Classes Functions Variables Pages
+ + +
+ +
+ +
+
+ + + + diff --git a/graph_legend.html b/graph_legend.html new file mode 100644 index 0000000..29f0841 --- /dev/null +++ b/graph_legend.html @@ -0,0 +1,154 @@ + + + + + + +pva2pva: Graph Legend + + + + + + + + + +
+
+ + + + + + +
+
pva2pva +  1.4.1 +
+
+
+ + + + +
+ +
+ All Classes Functions Variables Pages
+ + +
+ +
+ +
+
+
Graph Legend
+
+
+

This page explains how to interpret the graphs that are generated by doxygen.

+

Consider the following example:

+
/*! Invisible class because of truncation */
+
class Invisible { };
+
+
/*! Truncated class, inheritance relation is hidden */
+
class Truncated : public Invisible { };
+
+
/* Class not documented with doxygen comments */
+
class Undocumented { };
+
+
/*! Class that is inherited using public inheritance */
+
class PublicBase : public Truncated { };
+
+
/*! A template class */
+
template<class T> class Templ { };
+
+
/*! Class that is inherited using protected inheritance */
+
class ProtectedBase { };
+
+
/*! Class that is inherited using private inheritance */
+
class PrivateBase { };
+
+
/*! Class that is used by the Inherited class */
+
class Used { };
+
+
/*! Super class that inherits a number of other classes */
+
class Inherited : public PublicBase,
+
protected ProtectedBase,
+
private PrivateBase,
+
public Undocumented,
+
public Templ<int>
+
{
+
private:
+
Used *m_usedClass;
+
};
+

This will result in the following graph:

+
+ +
+

The boxes in the above graph have the following meaning:

+ +

The arrows have the following meaning:

+ +
+ + + + diff --git a/graph_legend.md5 b/graph_legend.md5 new file mode 100644 index 0000000..a06ed05 --- /dev/null +++ b/graph_legend.md5 @@ -0,0 +1 @@ +387ff8eb65306fa251338d3c9bd7bfff \ No newline at end of file diff --git a/graph_legend.png b/graph_legend.png new file mode 100644 index 0000000..e901097 Binary files /dev/null and b/graph_legend.png differ diff --git a/gwmain_8cpp_source.html b/gwmain_8cpp_source.html new file mode 100644 index 0000000..e486a52 --- /dev/null +++ b/gwmain_8cpp_source.html @@ -0,0 +1,448 @@ + + + + + + +pva2pva: p2pApp/gwmain.cpp Source File + + + + + + + + + +
+
+ + + + + + +
+
pva2pva +  1.4.1 +
+
+
+ + + + + + + + + +
+ +
+ + +
+
+
+
gwmain.cpp
+
+
+
1 
+
2 #include <iostream>
+
3 #include <fstream>
+
4 #include <stdexcept>
+
5 #include <map>
+
6 
+
7 #if !defined(_WIN32)
+
8 #include <signal.h>
+
9 #define USE_SIGNAL
+
10 #endif
+
11 
+
12 #include <epicsStdlib.h>
+
13 #include <epicsGetopt.h>
+
14 #include <iocsh.h>
+
15 #include <epicsTimer.h>
+
16 #include <libComRegister.h>
+
17 
+
18 #include <pv/json.h>
+
19 
+
20 #include <pv/pvAccess.h>
+
21 #include <pv/clientFactory.h>
+
22 #include <pv/configuration.h>
+
23 #include <pv/serverContext.h>
+
24 #include <pv/reftrack.h>
+
25 #include <pv/iocreftrack.h>
+
26 #include <pv/iocshelper.h>
+
27 #include <pv/logger.h>
+
28 
+
29 #include "server.h"
+
30 #include "pva2pva.h"
+
31 
+
32 namespace pvd = epics::pvData;
+
33 namespace pva = epics::pvAccess;
+
34 
+
35 extern int p2pReadOnly;
+
36 
+
37 namespace {
+
38 
+
39 pvd::StructureConstPtr schema(pvd::getFieldCreate()->createFieldBuilder()
+
40  ->add("version", pvd::pvUInt)
+
41  ->add("readOnly", pvd::pvBoolean)
+
42  ->addNestedStructureArray("clients")
+
43  ->add("name", pvd::pvString)
+
44  ->add("provider", pvd::pvString)
+
45  ->add("addrlist", pvd::pvString)
+
46  ->add("autoaddrlist", pvd::pvBoolean)
+
47  ->add("serverport", pvd::pvUShort)
+
48  ->add("bcastport", pvd::pvUShort)
+
49  ->endNested()
+
50  ->addNestedStructureArray("servers")
+
51  ->add("name", pvd::pvString)
+
52  ->addArray("clients", pvd::pvString)
+
53  ->add("interface", pvd::pvString)
+
54  ->add("addrlist", pvd::pvString)
+
55  ->add("autoaddrlist", pvd::pvBoolean)
+
56  ->add("serverport", pvd::pvUShort)
+
57  ->add("bcastport", pvd::pvUShort)
+
58  ->add("control_prefix", pvd::pvString)
+
59  ->endNested()
+
60  ->createStructure());
+
61 
+
62 
+
63 void usage(const char *me)
+
64 {
+
65  std::cerr<<"Usage: "<<me<<" [-vhiIC] <config file>\n";
+
66 }
+
67 
+
68 void getargs(ServerConfig& arg, int argc, char *argv[])
+
69 {
+
70  int opt;
+
71  bool checkonly = false;
+
72 
+
73  while( (opt=getopt(argc, argv, "qvhiIC"))!=-1)
+
74  {
+
75  switch(opt) {
+
76  case 'q':
+
77  arg.debug--;
+
78  break;
+
79  case 'v':
+
80  arg.debug++;
+
81  break;
+
82  case 'I':
+
83  arg.interactive = true;
+
84  break;
+
85  case 'i':
+
86  arg.interactive = false;
+
87  break;
+
88  case 'C':
+
89  checkonly = true;
+
90  break;
+
91  default:
+
92  std::cerr<<"Unknown argument -"<<char(opt)<<"\n";
+
93  case 'h':
+
94  usage(argv[0]);
+
95  exit(1);
+
96  }
+
97  }
+
98 
+
99  if(optind!=argc-1) {
+
100  std::cerr<<"Exactly one positional argument expected\n";
+
101  usage(argv[0]);
+
102  exit(1);
+
103  }
+
104 
+
105  arg.conf = pvd::getPVDataCreate()->createPVStructure(schema);
+
106  std::ifstream strm(argv[optind]);
+
107  pvd::parseJSON(strm, arg.conf);
+
108 
+
109  p2pReadOnly = arg.conf->getSubFieldT<pvd::PVScalar>("readOnly")->getAs<pvd::boolean>();
+
110 
+
111  unsigned version = arg.conf->getSubFieldT<pvd::PVUInt>("version")->get();
+
112  if(version==0) {
+
113  std::cerr<<"Warning: config file missing \"version\" key. Assuming 1\n";
+
114  } else if(version!=1) {
+
115  std::cerr<<"config file version mis-match. expect 1 found "<<version<<"\n";
+
116  exit(1);
+
117  }
+
118  if(arg.conf->getSubFieldT<pvd::PVStructureArray>("clients")->view().empty()) {
+
119  std::cerr<<"No clients configured\n";
+
120  exit(1);
+
121  }
+
122  if(arg.conf->getSubFieldT<pvd::PVStructureArray>("servers")->view().empty()) {
+
123  std::cerr<<"No servers configured\n";
+
124  exit(1);
+
125  }
+
126 
+
127  if(checkonly) {
+
128  std::cerr<<"Config file OK\n";
+
129  exit(0);
+
130  }
+
131 }
+
132 
+
133 GWServerChannelProvider::shared_pointer configure_client(ServerConfig& arg, const pvd::PVStructurePtr& conf)
+
134 {
+
135  std::string name(conf->getSubFieldT<pvd::PVString>("name")->get());
+
136  std::string provider(conf->getSubFieldT<pvd::PVString>("provider")->get());
+
137 
+
138  LOG(pva::logLevelInfo, "Configure client '%s' with provider '%s'", name.c_str(), provider.c_str());
+
139 
+
140  pva::Configuration::shared_pointer C(pva::ConfigurationBuilder()
+
141  .add("EPICS_PVA_ADDR_LIST", conf->getSubFieldT<pvd::PVString>("addrlist")->get())
+
142  .add("EPICS_PVA_AUTO_ADDR_LIST", conf->getSubFieldT<pvd::PVScalar>("autoaddrlist")->getAs<std::string>())
+
143  .add("EPICS_PVA_SERVER_PORT", conf->getSubFieldT<pvd::PVScalar>("serverport")->getAs<pvd::uint16>())
+
144  .add("EPICS_PVA_BROADCAST_PORT", conf->getSubFieldT<pvd::PVScalar>("bcastport")->getAs<pvd::uint16>())
+
145  .add("EPICS_PVA_DEBUG", arg.debug>=5 ? 5 : 0)
+
146  .push_map()
+
147  .build());
+
148 
+
149  pva::ChannelProvider::shared_pointer base(pva::ChannelProviderRegistry::clients()->createProvider(provider, C));
+
150  if(!base)
+
151  throw std::runtime_error("Can't create ChannelProvider");
+
152 
+
153  GWServerChannelProvider::shared_pointer ret(new GWServerChannelProvider(base));
+
154  return ret;
+
155 }
+
156 
+
157 pva::ServerContext::shared_pointer configure_server(ServerConfig& arg, const pvd::PVStructurePtr& conf)
+
158 {
+
159  std::string name(conf->getSubFieldT<pvd::PVString>("name")->get());
+
160 
+
161  LOG(pva::logLevelInfo, "Configure server '%s'", name.c_str());
+
162 
+
163  pva::Configuration::shared_pointer C(pva::ConfigurationBuilder()
+
164  .add("EPICS_PVAS_INTF_ADDR_LIST", conf->getSubFieldT<pvd::PVString>("interface")->get())
+
165  .add("EPICS_PVAS_BEACON_ADDR_LIST", conf->getSubFieldT<pvd::PVString>("addrlist")->get())
+
166  .add("EPICS_PVAS_AUTO_BEACON_ADDR_LIST", conf->getSubFieldT<pvd::PVScalar>("autoaddrlist")->getAs<std::string>())
+
167  .add("EPICS_PVAS_SERVER_PORT", conf->getSubFieldT<pvd::PVScalar>("serverport")->getAs<pvd::uint16>())
+
168  .add("EPICS_PVAS_BROADCAST_PORT", conf->getSubFieldT<pvd::PVScalar>("bcastport")->getAs<pvd::uint16>())
+
169  .add("EPICS_PVA_DEBUG", arg.debug>=5 ? 5 : 0)
+
170  .push_map()
+
171  .build());
+
172 
+
173  pvd::PVStringArray::shared_pointer clients(conf->getSubFieldT<pvd::PVStringArray>("clients"));
+
174  pvd::PVStringArray::const_svector names(clients->view());
+
175  std::vector<pva::ChannelProvider::shared_pointer> providers;
+
176 
+
177  for(pvd::PVStringArray::const_svector::const_iterator it(names.begin()), end(names.end()); it!=end; ++it)
+
178  {
+
179  ServerConfig::clients_t::const_iterator it2(arg.clients.find(*it));
+
180  if(it2==arg.clients.end())
+
181  throw std::runtime_error("Server references non-existant client");
+
182  providers.push_back(it2->second);
+
183  }
+
184 
+
185  pva::ServerContext::shared_pointer ret(pva::ServerContext::create(pva::ServerContext::Config()
+
186  .config(C)
+
187  .providers(providers)));
+
188  return ret;
+
189 }
+
190 
+
191 volatile int quit;
+
192 epicsEvent done;
+
193 
+
194 #ifdef USE_SIGNAL
+
195 void sigdone(int num)
+
196 {
+
197  (void)num;
+
198  quit = 1;
+
199  done.signal();
+
200 }
+
201 #endif
+
202 
+
203 ServerConfig* volatile theserver;
+
204 
+
205 void iocsh_drop(const char *client, const char *channel)
+
206 {
+
207  if(!theserver)
+
208  return;
+
209  try {
+
210  theserver->drop(client, channel);
+
211  }catch(std::exception& e){
+
212  std::cout<<"Error: "<<e.what()<<"\n";
+
213  }
+
214 }
+
215 
+
216 void gwsr(int lvl, const char *server)
+
217 {
+
218  if(!theserver)
+
219  return;
+
220  try {
+
221  theserver->status_server(lvl, server);
+
222  }catch(std::exception& e){
+
223  std::cout<<"Error: "<<e.what()<<"\n";
+
224  }
+
225 }
+
226 
+
227 void gwcr(int lvl, const char *client, const char *channel)
+
228 {
+
229  if(!theserver)
+
230  return;
+
231  try {
+
232  theserver->status_client(lvl, client, channel);
+
233  }catch(std::exception& e){
+
234  std::cout<<"Error: "<<e.what()<<"\n";
+
235  }
+
236 }
+
237 
+
238 }// namespace
+
239 
+
240 int main(int argc, char *argv[])
+
241 {
+
242  try {
+
243  pva::refTrackRegistrar();
+
244 
+
245  epics::iocshRegister<const char*, const char*, &iocsh_drop>("drop", "client", "channel");
+
246  epics::iocshRegister<int, const char*, &gwsr>("gwsr", "level", "channel");
+
247  epics::iocshRegister<int, const char*, const char*, &gwcr>("gwcr", "level", "client", "channel");
+
248 
+
249  libComRegister();
+
250  registerReadOnly();
+
251  epics::registerRefCounter("ChannelCacheEntry", &ChannelCacheEntry::num_instances);
+
252  epics::registerRefCounter("ChannelCacheEntry::CRequester", &ChannelCacheEntry::CRequester::num_instances);
+
253  epics::registerRefCounter("GWChannel", &GWChannel::num_instances);
+
254  epics::registerRefCounter("MonitorCacheEntry", &MonitorCacheEntry::num_instances);
+
255  epics::registerRefCounter("MonitorUser", &MonitorUser::num_instances);
+
256 
+
257  ServerConfig arg;
+
258  theserver = &arg;
+
259  getargs(arg, argc, argv);
+
260 
+
261  if(arg.debug>0)
+
262  std::cout<<"Notice: This p2p gateway prototype has been superceded by the p4p.gw gateway\n"
+
263  " which has exciting new features including granular access control,\n"
+
264  " and status PVs including bandwidth usage reports.\n"
+
265  " p2p is considered deprecated by its author, and will receive\n"
+
266  " minimal maintainance effort going forward.\n"
+
267  " Users are encouraged to migrate to p4p.gw.\n"
+
268  "\n"
+
269  " https://mdavidsaver.github.io/p4p/gw.html\n"
+
270  "\n";
+
271 
+
272  pva::pvAccessLogLevel lvl;
+
273  if(arg.debug<0)
+
274  lvl = pva::logLevelError;
+
275  else if(arg.debug==0)
+
276  lvl = pva::logLevelWarn;
+
277  else if(arg.debug==1)
+
278  lvl = pva::logLevelInfo;
+
279  else if(arg.debug==2)
+
280  lvl = pva::logLevelDebug;
+
281  else if(arg.debug==3)
+
282  lvl = pva::logLevelTrace;
+
283  else if(arg.debug>=4)
+
284  lvl = pva::logLevelAll;
+
285  SET_LOG_LEVEL(lvl);
+
286 
+
287  pva::ClientFactory::start();
+
288 
+
289  pvd::PVStructureArray::const_svector arr;
+
290 
+
291  arr = arg.conf->getSubFieldT<pvd::PVStructureArray>("clients")->view();
+
292 
+
293  for(size_t i=0; i<arr.size(); i++) {
+
294  if(!arr[i]) continue;
+
295  const pvd::PVStructurePtr& client = arr[i];
+
296 
+
297  std::string name(client->getSubFieldT<pvd::PVString>("name")->get());
+
298  if(name.empty())
+
299  throw std::runtime_error("Client with empty name not allowed");
+
300 
+
301  ServerConfig::clients_t::const_iterator it(arg.clients.find(name));
+
302  if(it!=arg.clients.end())
+
303  throw std::runtime_error(std::string("Duplicate client name not allowed : ")+name);
+
304 
+
305  arg.clients[name] = configure_client(arg, client);
+
306  }
+
307 
+
308  arr = arg.conf->getSubFieldT<pvd::PVStructureArray>("servers")->view();
+
309 
+
310  for(size_t i=0; i<arr.size(); i++) {
+
311  if(!arr[i]) continue;
+
312  const pvd::PVStructurePtr& server = arr[i];
+
313 
+
314  std::string name(server->getSubFieldT<pvd::PVString>("name")->get());
+
315  if(name.empty())
+
316  throw std::runtime_error("Server with empty name not allowed");
+
317 
+
318  ServerConfig::servers_t::const_iterator it(arg.servers.find(name));
+
319  if(it!=arg.servers.end())
+
320  throw std::runtime_error(std::string("Duplicate server name not allowed : ")+name);
+
321 
+
322  arg.servers[name] = configure_server(arg, server);
+
323  }
+
324 
+
325  int ret = 0;
+
326  if(arg.interactive) {
+
327  ret = iocsh(NULL);
+
328  } else {
+
329 #ifdef USE_SIGNAL
+
330  signal(SIGINT, sigdone);
+
331  signal(SIGTERM, sigdone);
+
332  signal(SIGQUIT, sigdone);
+
333 #endif
+
334 
+
335  while(!quit) {
+
336  done.wait();
+
337  }
+
338  }
+
339 
+
340  theserver = 0;
+
341 
+
342  return ret;
+
343  }catch(std::exception& e){
+
344  std::cerr<<"Fatal Error : "<<e.what()<<"\n";
+
345  return 1;
+
346  }
+
347 }
+ + +
+ + + + diff --git a/helper_8h_source.html b/helper_8h_source.html new file mode 100644 index 0000000..a99e497 --- /dev/null +++ b/helper_8h_source.html @@ -0,0 +1,118 @@ + + + + + + +pva2pva: p2pApp/helper.h Source File + + + + + + + + + +
+
+ + + + + + +
+
pva2pva +  1.4.1 +
+
+
+ + + + + + + + + +
+ +
+ + +
+
+
+
helper.h
+
+
+
1 #ifndef HELPER_H
+
2 #define HELPER_H
+
3 
+
4 #include <memory>
+
5 
+
6 #define FOREACH(ITERTYPE, IT,END,C) for(ITERTYPE IT=(C).begin(), END=(C).end(); IT!=END; ++IT)
+
7 
+
8 namespace p2p {
+
9 #if __cplusplus>=201103L
+
10 template<typename T>
+
11 using auto_ptr = std::unique_ptr<T>;
+
12 #define PTRMOVE(AUTO) std::move(AUTO)
+
13 #else
+
14 using std::auto_ptr;
+
15 #define PTRMOVE(AUTO) (AUTO)
+
16 #endif
+
17 }
+
18 
+
19 #endif // HELPER_H
+
+ + + + diff --git a/hierarchy.html b/hierarchy.html new file mode 100644 index 0000000..127b1c9 --- /dev/null +++ b/hierarchy.html @@ -0,0 +1,208 @@ + + + + + + +pva2pva: Class Hierarchy + + + + + + + + + +
+
+ + + + + + +
+
pva2pva +  1.4.1 +
+
+
+ + + + + +
+ +
+ All Classes Functions Variables Pages
+ + +
+ +
+ +
+
+
Class Hierarchy
+
+
+
+

Go to the graphical class hierarchy

+This inheritance list is sorted roughly, but not completely, alphabetically:
+
[detail level 123]
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
oCASCLIENT
oCASCred
oCAsWritePvt
oCChannel
|oCBaseChannel
|\CGWChannel
oCChannelCache
oCChannelCacheEntry
oCChannelFind
|oCGWServerChannelProvider
|\CPDBProvider
oCChannelGetRequester
|\CTestChannelGetRequester
oCChannelProvider
|oCGWServerChannelProvider
|oCPDBProvider
|\CTestProvider
oCChannelProviderFactory
|\CBaseChannelProviderFactory< CP >
oCChannelPut
|oCPDBGroupPut
|\CPDBSinglePut
oCChannelPutRequester
|\CTestChannelPutRequester
oCChannelRequester
|oCChannelCacheEntry::CRequester
|\CTestChannelRequester
oCFieldName::Component
oCDBCH
oCDBEvent
oCdbrbuf
oCDBScanLocker
oCweak_value_map< K, V, C >::element_proxy
oCenable_shared_from_this
|oCGWServerChannelProvider
|oCPDBGroupChannel
|oCPDBGroupPut
|oCPDBProvider
|oCPDBSingleChannel
|oCPDBSinglePut
|oCpvalink::pvaLinkChannel
|\CTestProvider
oCepicsThreadRunable
|oCpvalink::pvaLinkChannel
|oCpvalink::pvaLinkChannel::AfterPut
|\CWorkQueue
oCepicsTimerNotify
|\CChannelCache::cacheClean
oCGroupConfig::Field
oCFieldName
oCGetFieldRequester
|\CTestChannelFieldRequester
oCGroupConfig::Group
oCGroupConfig
oCPDBGroupPV::Info
oCjlif
oCjlink
|\Cpvalink::pvaLinkConfig
oCpvalink::pvaLinkChannel::LinkSort
oCLocalFL
oCMonitor
|\CBaseMonitor
oCMonitor
|oCMonitorUser
|\CTestPVMonitor
oCMonitorCallback
|\Cpvalink::pvaLinkChannel
oCMonitorRequester
|oCMonitorCacheEntry
|\CTestChannelMonitorRequester
oCBaseMonitor::no_overflow
oCpdbInfoIterator
oCPDBPV
|oCPDBGroupPV
|\CPDBSinglePV
oCpdbRecordInfo
oCpdbRecordIterator
oCPutCallback
|\Cpvalink::pvaLinkChannel
oCpvalink::pvaGlobal_t
oCPVIF
oCPVIFBuilder
|\CScalarBuilder
oCSB
oCScalarAccessor< T >
oCServerConfig
oCTestIOC
oCTestPV
oCweak_set< T >Std::set-ish container where entries are removed when ref. counts fall to zero
oCweak_set< GWChannel >
oCweak_set< MonitorUser >
oCweak_set< TestPVChannel >
oCweak_set< TestPVMonitor >
oCweak_value_map< K, V, C >An associative map where a weak_ptr to the value is stored
oCweak_value_map< pvrequest_t, MonitorCacheEntry >
oCweak_value_map< std::string, PDBPV >
oCweak_value_map< std::string, TestPV >
\Cweak_set< T >::XIteratorIterator-ish object which also locks the set during iteration
+
+
+ + + + diff --git a/imagedemo_8c_source.html b/imagedemo_8c_source.html new file mode 100644 index 0000000..f751e13 --- /dev/null +++ b/imagedemo_8c_source.html @@ -0,0 +1,140 @@ + + + + + + +pva2pva: pdbApp/imagedemo.c Source File + + + + + + + + + +
+
+ + + + + + +
+
pva2pva +  1.4.1 +
+
+
+ + + + + + + + + +
+ +
+ + +
+
+
+
imagedemo.c
+
+
+
1 
+
2 #include <stdlib.h>
+
3 
+
4 #include <epicsMath.h>
+
5 #include <dbAccess.h>
+
6 #include <dbScan.h>
+
7 #include <recGbl.h>
+
8 #include <alarm.h>
+
9 #include <registryFunction.h>
+
10 
+
11 #include <aSubRecord.h>
+
12 
+
13 #include <epicsExport.h>
+
14 
+
21 static
+
22 long QSRV_image_demo(aSubRecord *prec)
+
23 {
+
24  epicsUInt32 H = *(epicsUInt32*)prec->a,
+
25  W = *(epicsUInt32*)prec->b;
+
26  epicsUInt16 *I = (epicsUInt16*)prec->vala;
+
27  epicsUInt32 i, j;
+
28 
+
29  if(W*H>prec->nova) {
+
30  (void)recGblSetSevr(prec, READ_ALARM, INVALID_ALARM);
+
31  return 0;
+
32  }
+
33 
+
34  for(i=0; i<W; i++) {
+
35  for(j=0; j<H; j++) {
+
36  if(i%50==49 || j%50==49)
+
37  I[i*H+j] = 65535;
+
38  else
+
39  I[i*H+j] = ((epicsUInt32)j)*65535/H;
+
40  }
+
41  }
+
42 
+
43  prec->neva = W*H;
+
44  return 0;
+
45 }
+
46 
+
47 epicsRegisterFunction(QSRV_image_demo);
+
+ + + + diff --git a/index.html b/index.html new file mode 100644 index 0000000..7e88b75 --- /dev/null +++ b/index.html @@ -0,0 +1,148 @@ + + + + + + +pva2pva: pva2pva Home of QSRV and pvAccess 2 pvAccess gateway + + + + + + + + + +
+
+ + + + + + +
+
pva2pva +  1.4.1 +
+
+
+ + + + +
+ +
+ All Classes Functions Variables Pages
+ + +
+ +
+ +
+
+
pva2pva Home of QSRV and pvAccess 2 pvAccess gateway
+
+
+
+

+QSRV

+

QSRV is a network server using the PVAccess protocol which runs inside an EPICS IOC process and allows clients to make requests to access the Process Variables (PVs) within.

+

Documentation of QSRV Configuration including Group PV definitions , Access Security and PVAccess Links configuration.

+ +

+Building

+

To build the latest from version control

+
git clone --recursive --branch core/master https://github.com/epics-base/epics-base.git
+
cd epics-base
+
make
+

+Quick Start

+

The pva2pva module builds an executable 'softIocPVA' which function like the 'softIoc' executable built by EPICS Base, with QSRV included as well.

+
cd modules/pva2pva
+
cat <<EOF > p2pexample.db
+
record(calc, "p2p:example:counter") {
+
field(INPA, "p2p:example:counter")
+
field(CALC, "A+1")
+
field(SCAN, "1 second")
+
}
+
EOF
+
./bin/linux-x86_64/softIocPVA -d p2pexample.db
+

Then in another shell run:

+
cd modules/pvAccess
+
./bin/linux-x86_64/pvget p2p:example:counter
+

+Adding QSRV to your IOC

+

QSRV is added to an IOC just like any other EPICS support module. In the Makefile which produces an IOC executable (eg. "myiocname") add:

+
PROD_HOST += myiocname
+
# include QSRV
+
myiocname_DBD += base.dbd
+
myiocname_DBD += PVAServerRegister.dbd
+
myiocname_DBD += qsrv.dbd
+
myiocname_LIBS += qsrv
+
myiocname_LIBS += $(EPICS_BASE_PVA_CORE_LIBS)
+
myiocname_LIBS += $(EPICS_BASE_IOC_LIBS)
+

Now run your IOC and QSRV starts automatically.

+

+Status monitoring

+

In a running IOC w/ QSRV, run the "pvasr" in the IOC shell and verify that "QSRV" is among the "PROVIDER_NAMES".

+
epics> pvasr
+
VERSION : pvAccess Server v6.0.0-SNAPSHOT
+
PROVIDER_NAMES : QSRV,
+
BEACON_ADDR_LIST :
+
AUTO_BEACON_ADDR_LIST : 1
+
BEACON_PERIOD : 15
+
BROADCAST_PORT : 5076
+
SERVER_PORT : 5075
+
RCV_BUFFER_SIZE : 16384
+
IGNORE_ADDR_LIST:
+
INTF_ADDR_LIST : 0.0.0.0
+
+ + + + diff --git a/inherit_graph_0.map b/inherit_graph_0.map new file mode 100644 index 0000000..fd60004 --- /dev/null +++ b/inherit_graph_0.map @@ -0,0 +1,3 @@ + + + diff --git a/inherit_graph_0.md5 b/inherit_graph_0.md5 new file mode 100644 index 0000000..e638fae --- /dev/null +++ b/inherit_graph_0.md5 @@ -0,0 +1 @@ +006a52c9b2eee557f754631f5c7b750b \ No newline at end of file diff --git a/inherit_graph_0.png b/inherit_graph_0.png new file mode 100644 index 0000000..05a06fd Binary files /dev/null and b/inherit_graph_0.png differ diff --git a/inherit_graph_1.map b/inherit_graph_1.map new file mode 100644 index 0000000..d742955 --- /dev/null +++ b/inherit_graph_1.map @@ -0,0 +1,3 @@ + + + diff --git a/inherit_graph_1.md5 b/inherit_graph_1.md5 new file mode 100644 index 0000000..ea7fad1 --- /dev/null +++ b/inherit_graph_1.md5 @@ -0,0 +1 @@ +19bf3bf8f78c6a4d1d70ea7acc84ba2f \ No newline at end of file diff --git a/inherit_graph_1.png b/inherit_graph_1.png new file mode 100644 index 0000000..b8a9a4f Binary files /dev/null and b/inherit_graph_1.png differ diff --git a/inherit_graph_10.map b/inherit_graph_10.map new file mode 100644 index 0000000..3a3c763 --- /dev/null +++ b/inherit_graph_10.map @@ -0,0 +1,3 @@ + + + diff --git a/inherit_graph_10.md5 b/inherit_graph_10.md5 new file mode 100644 index 0000000..5a26b4d --- /dev/null +++ b/inherit_graph_10.md5 @@ -0,0 +1 @@ +2f46d8bfcf499913c5da18134990582b \ No newline at end of file diff --git a/inherit_graph_10.png b/inherit_graph_10.png new file mode 100644 index 0000000..f446964 Binary files /dev/null and b/inherit_graph_10.png differ diff --git a/inherit_graph_11.map b/inherit_graph_11.map new file mode 100644 index 0000000..1c5d2a0 --- /dev/null +++ b/inherit_graph_11.map @@ -0,0 +1,3 @@ + + + diff --git a/inherit_graph_11.md5 b/inherit_graph_11.md5 new file mode 100644 index 0000000..b0bc89d --- /dev/null +++ b/inherit_graph_11.md5 @@ -0,0 +1 @@ +c99081f3f37a407e610617427b30e12e \ No newline at end of file diff --git a/inherit_graph_11.png b/inherit_graph_11.png new file mode 100644 index 0000000..9967c0e Binary files /dev/null and b/inherit_graph_11.png differ diff --git a/inherit_graph_12.map b/inherit_graph_12.map new file mode 100644 index 0000000..643b90f --- /dev/null +++ b/inherit_graph_12.map @@ -0,0 +1,3 @@ + + + diff --git a/inherit_graph_12.md5 b/inherit_graph_12.md5 new file mode 100644 index 0000000..7dafa4a --- /dev/null +++ b/inherit_graph_12.md5 @@ -0,0 +1 @@ +6501511ae6aadfcefd600391f2807354 \ No newline at end of file diff --git a/inherit_graph_12.png b/inherit_graph_12.png new file mode 100644 index 0000000..17ad1f7 Binary files /dev/null and b/inherit_graph_12.png differ diff --git a/inherit_graph_13.map b/inherit_graph_13.map new file mode 100644 index 0000000..efd06ca --- /dev/null +++ b/inherit_graph_13.map @@ -0,0 +1,3 @@ + + + diff --git a/inherit_graph_13.md5 b/inherit_graph_13.md5 new file mode 100644 index 0000000..0834ee2 --- /dev/null +++ b/inherit_graph_13.md5 @@ -0,0 +1 @@ +f0ddaf3b618e706a9bb1a699d0564f3c \ No newline at end of file diff --git a/inherit_graph_13.png b/inherit_graph_13.png new file mode 100644 index 0000000..5cc3d66 Binary files /dev/null and b/inherit_graph_13.png differ diff --git a/inherit_graph_14.map b/inherit_graph_14.map new file mode 100644 index 0000000..742a574 --- /dev/null +++ b/inherit_graph_14.map @@ -0,0 +1,3 @@ + + + diff --git a/inherit_graph_14.md5 b/inherit_graph_14.md5 new file mode 100644 index 0000000..b1b59fd --- /dev/null +++ b/inherit_graph_14.md5 @@ -0,0 +1 @@ +36db58357b58099ff9c44006acc4c546 \ No newline at end of file diff --git a/inherit_graph_14.png b/inherit_graph_14.png new file mode 100644 index 0000000..b737a96 Binary files /dev/null and b/inherit_graph_14.png differ diff --git a/inherit_graph_15.map b/inherit_graph_15.map new file mode 100644 index 0000000..3c396b0 --- /dev/null +++ b/inherit_graph_15.map @@ -0,0 +1,3 @@ + + + diff --git a/inherit_graph_15.md5 b/inherit_graph_15.md5 new file mode 100644 index 0000000..7d22f2d --- /dev/null +++ b/inherit_graph_15.md5 @@ -0,0 +1 @@ +5d0e80f886e4d98ce758a0014a304dd2 \ No newline at end of file diff --git a/inherit_graph_15.png b/inherit_graph_15.png new file mode 100644 index 0000000..6db5850 Binary files /dev/null and b/inherit_graph_15.png differ diff --git a/inherit_graph_16.map b/inherit_graph_16.map new file mode 100644 index 0000000..0f79daa --- /dev/null +++ b/inherit_graph_16.map @@ -0,0 +1,3 @@ + + + diff --git a/inherit_graph_16.md5 b/inherit_graph_16.md5 new file mode 100644 index 0000000..c2c5040 --- /dev/null +++ b/inherit_graph_16.md5 @@ -0,0 +1 @@ +d369f3338266e5d31e49f00403aee6d8 \ No newline at end of file diff --git a/inherit_graph_16.png b/inherit_graph_16.png new file mode 100644 index 0000000..d44ba2d Binary files /dev/null and b/inherit_graph_16.png differ diff --git a/inherit_graph_17.map b/inherit_graph_17.map new file mode 100644 index 0000000..07d49cc --- /dev/null +++ b/inherit_graph_17.map @@ -0,0 +1,3 @@ + + + diff --git a/inherit_graph_17.md5 b/inherit_graph_17.md5 new file mode 100644 index 0000000..1c78d69 --- /dev/null +++ b/inherit_graph_17.md5 @@ -0,0 +1 @@ +d84217e741abeb4238da65b47fc149c9 \ No newline at end of file diff --git a/inherit_graph_17.png b/inherit_graph_17.png new file mode 100644 index 0000000..dbb9dc0 Binary files /dev/null and b/inherit_graph_17.png differ diff --git a/inherit_graph_18.map b/inherit_graph_18.map new file mode 100644 index 0000000..824728c --- /dev/null +++ b/inherit_graph_18.map @@ -0,0 +1,3 @@ + + + diff --git a/inherit_graph_18.md5 b/inherit_graph_18.md5 new file mode 100644 index 0000000..b474caa --- /dev/null +++ b/inherit_graph_18.md5 @@ -0,0 +1 @@ +92c73fb74a2c593a52281561feb03506 \ No newline at end of file diff --git a/inherit_graph_18.png b/inherit_graph_18.png new file mode 100644 index 0000000..3ade1d7 Binary files /dev/null and b/inherit_graph_18.png differ diff --git a/inherit_graph_19.map b/inherit_graph_19.map new file mode 100644 index 0000000..67d5fac --- /dev/null +++ b/inherit_graph_19.map @@ -0,0 +1,3 @@ + + + diff --git a/inherit_graph_19.md5 b/inherit_graph_19.md5 new file mode 100644 index 0000000..186cb6a --- /dev/null +++ b/inherit_graph_19.md5 @@ -0,0 +1 @@ +416e149021283c7b3d63c689bea7aa61 \ No newline at end of file diff --git a/inherit_graph_19.png b/inherit_graph_19.png new file mode 100644 index 0000000..9b1b258 Binary files /dev/null and b/inherit_graph_19.png differ diff --git a/inherit_graph_2.map b/inherit_graph_2.map new file mode 100644 index 0000000..5bd4842 --- /dev/null +++ b/inherit_graph_2.map @@ -0,0 +1,3 @@ + + + diff --git a/inherit_graph_2.md5 b/inherit_graph_2.md5 new file mode 100644 index 0000000..a53bf4a --- /dev/null +++ b/inherit_graph_2.md5 @@ -0,0 +1 @@ +2dd21bcaad60a36612c1b336879e976a \ No newline at end of file diff --git a/inherit_graph_2.png b/inherit_graph_2.png new file mode 100644 index 0000000..e13dce4 Binary files /dev/null and b/inherit_graph_2.png differ diff --git a/inherit_graph_20.map b/inherit_graph_20.map new file mode 100644 index 0000000..ccabb0e --- /dev/null +++ b/inherit_graph_20.map @@ -0,0 +1,3 @@ + + + diff --git a/inherit_graph_20.md5 b/inherit_graph_20.md5 new file mode 100644 index 0000000..7d7b2a4 --- /dev/null +++ b/inherit_graph_20.md5 @@ -0,0 +1 @@ +a46c800c63b1aa14d523419f4d20a6d7 \ No newline at end of file diff --git a/inherit_graph_20.png b/inherit_graph_20.png new file mode 100644 index 0000000..d2349db Binary files /dev/null and b/inherit_graph_20.png differ diff --git a/inherit_graph_21.map b/inherit_graph_21.map new file mode 100644 index 0000000..21619c1 --- /dev/null +++ b/inherit_graph_21.map @@ -0,0 +1,4 @@ + + + + diff --git a/inherit_graph_21.md5 b/inherit_graph_21.md5 new file mode 100644 index 0000000..9a913d4 --- /dev/null +++ b/inherit_graph_21.md5 @@ -0,0 +1 @@ +0029cbae1b0f67ddc2d1cfde8d44ba11 \ No newline at end of file diff --git a/inherit_graph_21.png b/inherit_graph_21.png new file mode 100644 index 0000000..6720dda Binary files /dev/null and b/inherit_graph_21.png differ diff --git a/inherit_graph_22.map b/inherit_graph_22.map new file mode 100644 index 0000000..079925e --- /dev/null +++ b/inherit_graph_22.map @@ -0,0 +1,4 @@ + + + + diff --git a/inherit_graph_22.md5 b/inherit_graph_22.md5 new file mode 100644 index 0000000..d204cf9 --- /dev/null +++ b/inherit_graph_22.md5 @@ -0,0 +1 @@ +f2fa53f87d5b79c3032fa721cce5f740 \ No newline at end of file diff --git a/inherit_graph_22.png b/inherit_graph_22.png new file mode 100644 index 0000000..a14cc39 Binary files /dev/null and b/inherit_graph_22.png differ diff --git a/inherit_graph_23.map b/inherit_graph_23.map new file mode 100644 index 0000000..5c83626 --- /dev/null +++ b/inherit_graph_23.map @@ -0,0 +1,3 @@ + + + diff --git a/inherit_graph_23.md5 b/inherit_graph_23.md5 new file mode 100644 index 0000000..f7457d9 --- /dev/null +++ b/inherit_graph_23.md5 @@ -0,0 +1 @@ +db21679bf78993100ba77b4f1457bcb2 \ No newline at end of file diff --git a/inherit_graph_23.png b/inherit_graph_23.png new file mode 100644 index 0000000..59c48e4 Binary files /dev/null and b/inherit_graph_23.png differ diff --git a/inherit_graph_24.map b/inherit_graph_24.map new file mode 100644 index 0000000..b7d0647 --- /dev/null +++ b/inherit_graph_24.map @@ -0,0 +1,3 @@ + + + diff --git a/inherit_graph_24.md5 b/inherit_graph_24.md5 new file mode 100644 index 0000000..c7ce3a3 --- /dev/null +++ b/inherit_graph_24.md5 @@ -0,0 +1 @@ +d820e8d12a4d955e85f7874c73a79cc4 \ No newline at end of file diff --git a/inherit_graph_24.png b/inherit_graph_24.png new file mode 100644 index 0000000..d099c89 Binary files /dev/null and b/inherit_graph_24.png differ diff --git a/inherit_graph_25.map b/inherit_graph_25.map new file mode 100644 index 0000000..bcfa73b --- /dev/null +++ b/inherit_graph_25.map @@ -0,0 +1,5 @@ + + + + + diff --git a/inherit_graph_25.md5 b/inherit_graph_25.md5 new file mode 100644 index 0000000..edd18ab --- /dev/null +++ b/inherit_graph_25.md5 @@ -0,0 +1 @@ +ac433ee416e184ec5f152c1597286d7d \ No newline at end of file diff --git a/inherit_graph_25.png b/inherit_graph_25.png new file mode 100644 index 0000000..72c4e33 Binary files /dev/null and b/inherit_graph_25.png differ diff --git a/inherit_graph_26.map b/inherit_graph_26.map new file mode 100644 index 0000000..2db7ee9 --- /dev/null +++ b/inherit_graph_26.map @@ -0,0 +1,3 @@ + + + diff --git a/inherit_graph_26.md5 b/inherit_graph_26.md5 new file mode 100644 index 0000000..514a65f --- /dev/null +++ b/inherit_graph_26.md5 @@ -0,0 +1 @@ +da9562353d3cd24cf4d47a18eda668fa \ No newline at end of file diff --git a/inherit_graph_26.png b/inherit_graph_26.png new file mode 100644 index 0000000..91c0b2d Binary files /dev/null and b/inherit_graph_26.png differ diff --git a/inherit_graph_27.map b/inherit_graph_27.map new file mode 100644 index 0000000..358e898 --- /dev/null +++ b/inherit_graph_27.map @@ -0,0 +1,3 @@ + + + diff --git a/inherit_graph_27.md5 b/inherit_graph_27.md5 new file mode 100644 index 0000000..f003dc4 --- /dev/null +++ b/inherit_graph_27.md5 @@ -0,0 +1 @@ +e22a36491802b8b88fecfe46ed152203 \ No newline at end of file diff --git a/inherit_graph_27.png b/inherit_graph_27.png new file mode 100644 index 0000000..0ebd415 Binary files /dev/null and b/inherit_graph_27.png differ diff --git a/inherit_graph_28.map b/inherit_graph_28.map new file mode 100644 index 0000000..aa4bb20 --- /dev/null +++ b/inherit_graph_28.map @@ -0,0 +1,3 @@ + + + diff --git a/inherit_graph_28.md5 b/inherit_graph_28.md5 new file mode 100644 index 0000000..6b6e410 --- /dev/null +++ b/inherit_graph_28.md5 @@ -0,0 +1 @@ +78d61cd652279b4082ce36b8c86d2030 \ No newline at end of file diff --git a/inherit_graph_28.png b/inherit_graph_28.png new file mode 100644 index 0000000..2726325 Binary files /dev/null and b/inherit_graph_28.png differ diff --git a/inherit_graph_29.map b/inherit_graph_29.map new file mode 100644 index 0000000..3d0a912 --- /dev/null +++ b/inherit_graph_29.map @@ -0,0 +1,15 @@ + + + + + + + + + + + + + + + diff --git a/inherit_graph_29.md5 b/inherit_graph_29.md5 new file mode 100644 index 0000000..9b6cd40 --- /dev/null +++ b/inherit_graph_29.md5 @@ -0,0 +1 @@ +a633ab3a1e2af46dd782dcf80878dd11 \ No newline at end of file diff --git a/inherit_graph_29.png b/inherit_graph_29.png new file mode 100644 index 0000000..c3cabd4 Binary files /dev/null and b/inherit_graph_29.png differ diff --git a/inherit_graph_3.map b/inherit_graph_3.map new file mode 100644 index 0000000..21f63a0 --- /dev/null +++ b/inherit_graph_3.map @@ -0,0 +1,3 @@ + + + diff --git a/inherit_graph_3.md5 b/inherit_graph_3.md5 new file mode 100644 index 0000000..d22d7cb --- /dev/null +++ b/inherit_graph_3.md5 @@ -0,0 +1 @@ +42058951619dd7e2e8c75f3382f37490 \ No newline at end of file diff --git a/inherit_graph_3.png b/inherit_graph_3.png new file mode 100644 index 0000000..fc5254b Binary files /dev/null and b/inherit_graph_3.png differ diff --git a/inherit_graph_30.map b/inherit_graph_30.map new file mode 100644 index 0000000..303a2c5 --- /dev/null +++ b/inherit_graph_30.map @@ -0,0 +1,3 @@ + + + diff --git a/inherit_graph_30.md5 b/inherit_graph_30.md5 new file mode 100644 index 0000000..b6cfe0b --- /dev/null +++ b/inherit_graph_30.md5 @@ -0,0 +1 @@ +59608fb5c8e6c768a0ed998ce174b1c5 \ No newline at end of file diff --git a/inherit_graph_30.png b/inherit_graph_30.png new file mode 100644 index 0000000..803dc17 Binary files /dev/null and b/inherit_graph_30.png differ diff --git a/inherit_graph_31.map b/inherit_graph_31.map new file mode 100644 index 0000000..f548800 --- /dev/null +++ b/inherit_graph_31.map @@ -0,0 +1,4 @@ + + + + diff --git a/inherit_graph_31.md5 b/inherit_graph_31.md5 new file mode 100644 index 0000000..7bdb663 --- /dev/null +++ b/inherit_graph_31.md5 @@ -0,0 +1 @@ +203570c3d90675da56dbc1e017b76fc8 \ No newline at end of file diff --git a/inherit_graph_31.png b/inherit_graph_31.png new file mode 100644 index 0000000..3bf243f Binary files /dev/null and b/inherit_graph_31.png differ diff --git a/inherit_graph_32.map b/inherit_graph_32.map new file mode 100644 index 0000000..1831722 --- /dev/null +++ b/inherit_graph_32.map @@ -0,0 +1,3 @@ + + + diff --git a/inherit_graph_32.md5 b/inherit_graph_32.md5 new file mode 100644 index 0000000..485828e --- /dev/null +++ b/inherit_graph_32.md5 @@ -0,0 +1 @@ +e63f73fe26720dab0c9e39b1a4166447 \ No newline at end of file diff --git a/inherit_graph_32.png b/inherit_graph_32.png new file mode 100644 index 0000000..9df2467 Binary files /dev/null and b/inherit_graph_32.png differ diff --git a/inherit_graph_33.map b/inherit_graph_33.map new file mode 100644 index 0000000..065df4b --- /dev/null +++ b/inherit_graph_33.map @@ -0,0 +1,4 @@ + + + + diff --git a/inherit_graph_33.md5 b/inherit_graph_33.md5 new file mode 100644 index 0000000..df7fbab --- /dev/null +++ b/inherit_graph_33.md5 @@ -0,0 +1 @@ +ed3aa1e264dabbafd9a8aad87e1bb128 \ No newline at end of file diff --git a/inherit_graph_33.png b/inherit_graph_33.png new file mode 100644 index 0000000..d3aec35 Binary files /dev/null and b/inherit_graph_33.png differ diff --git a/inherit_graph_34.map b/inherit_graph_34.map new file mode 100644 index 0000000..ffff3fe --- /dev/null +++ b/inherit_graph_34.map @@ -0,0 +1,3 @@ + + + diff --git a/inherit_graph_34.md5 b/inherit_graph_34.md5 new file mode 100644 index 0000000..36cf35f --- /dev/null +++ b/inherit_graph_34.md5 @@ -0,0 +1 @@ +9615f1662eb6ca37be912093de4f0cde \ No newline at end of file diff --git a/inherit_graph_34.png b/inherit_graph_34.png new file mode 100644 index 0000000..43576a4 Binary files /dev/null and b/inherit_graph_34.png differ diff --git a/inherit_graph_35.map b/inherit_graph_35.map new file mode 100644 index 0000000..af2fdaf --- /dev/null +++ b/inherit_graph_35.map @@ -0,0 +1,3 @@ + + + diff --git a/inherit_graph_35.md5 b/inherit_graph_35.md5 new file mode 100644 index 0000000..6220c9d --- /dev/null +++ b/inherit_graph_35.md5 @@ -0,0 +1 @@ +3e3db6c320cf4f41b3a66674f8cdd9d0 \ No newline at end of file diff --git a/inherit_graph_35.png b/inherit_graph_35.png new file mode 100644 index 0000000..e660286 Binary files /dev/null and b/inherit_graph_35.png differ diff --git a/inherit_graph_36.map b/inherit_graph_36.map new file mode 100644 index 0000000..54dc669 --- /dev/null +++ b/inherit_graph_36.map @@ -0,0 +1,3 @@ + + + diff --git a/inherit_graph_36.md5 b/inherit_graph_36.md5 new file mode 100644 index 0000000..30d138d --- /dev/null +++ b/inherit_graph_36.md5 @@ -0,0 +1 @@ +bf9c68b08e23ac5961d55b9b462f2968 \ No newline at end of file diff --git a/inherit_graph_36.png b/inherit_graph_36.png new file mode 100644 index 0000000..955f7b6 Binary files /dev/null and b/inherit_graph_36.png differ diff --git a/inherit_graph_37.map b/inherit_graph_37.map new file mode 100644 index 0000000..96b409f --- /dev/null +++ b/inherit_graph_37.map @@ -0,0 +1,3 @@ + + + diff --git a/inherit_graph_37.md5 b/inherit_graph_37.md5 new file mode 100644 index 0000000..0e593c2 --- /dev/null +++ b/inherit_graph_37.md5 @@ -0,0 +1 @@ +14ec6982db3f5730c212802ce681dd26 \ No newline at end of file diff --git a/inherit_graph_37.png b/inherit_graph_37.png new file mode 100644 index 0000000..bb37ec8 Binary files /dev/null and b/inherit_graph_37.png differ diff --git a/inherit_graph_38.map b/inherit_graph_38.map new file mode 100644 index 0000000..f16d929 --- /dev/null +++ b/inherit_graph_38.map @@ -0,0 +1,3 @@ + + + diff --git a/inherit_graph_38.md5 b/inherit_graph_38.md5 new file mode 100644 index 0000000..9187fad --- /dev/null +++ b/inherit_graph_38.md5 @@ -0,0 +1 @@ +235285ce35f87d073e59f4c193ce77a6 \ No newline at end of file diff --git a/inherit_graph_38.png b/inherit_graph_38.png new file mode 100644 index 0000000..b6d3007 Binary files /dev/null and b/inherit_graph_38.png differ diff --git a/inherit_graph_39.map b/inherit_graph_39.map new file mode 100644 index 0000000..f194eb0 --- /dev/null +++ b/inherit_graph_39.map @@ -0,0 +1,3 @@ + + + diff --git a/inherit_graph_39.md5 b/inherit_graph_39.md5 new file mode 100644 index 0000000..1244909 --- /dev/null +++ b/inherit_graph_39.md5 @@ -0,0 +1 @@ +564bade42e8980a7e7466d2b71c27f19 \ No newline at end of file diff --git a/inherit_graph_39.png b/inherit_graph_39.png new file mode 100644 index 0000000..820b25c Binary files /dev/null and b/inherit_graph_39.png differ diff --git a/inherit_graph_4.map b/inherit_graph_4.map new file mode 100644 index 0000000..985f214 --- /dev/null +++ b/inherit_graph_4.map @@ -0,0 +1,5 @@ + + + + + diff --git a/inherit_graph_4.md5 b/inherit_graph_4.md5 new file mode 100644 index 0000000..8445ee8 --- /dev/null +++ b/inherit_graph_4.md5 @@ -0,0 +1 @@ +5e3af3208cce39aa393d90cc6d689566 \ No newline at end of file diff --git a/inherit_graph_4.png b/inherit_graph_4.png new file mode 100644 index 0000000..bcfa533 Binary files /dev/null and b/inherit_graph_4.png differ diff --git a/inherit_graph_40.map b/inherit_graph_40.map new file mode 100644 index 0000000..ff90ea1 --- /dev/null +++ b/inherit_graph_40.map @@ -0,0 +1,3 @@ + + + diff --git a/inherit_graph_40.md5 b/inherit_graph_40.md5 new file mode 100644 index 0000000..41cd459 --- /dev/null +++ b/inherit_graph_40.md5 @@ -0,0 +1 @@ +c724637d2324bd8a02fac18ee2e53ac1 \ No newline at end of file diff --git a/inherit_graph_40.png b/inherit_graph_40.png new file mode 100644 index 0000000..58e1b0c Binary files /dev/null and b/inherit_graph_40.png differ diff --git a/inherit_graph_41.map b/inherit_graph_41.map new file mode 100644 index 0000000..a587891 --- /dev/null +++ b/inherit_graph_41.map @@ -0,0 +1,3 @@ + + + diff --git a/inherit_graph_41.md5 b/inherit_graph_41.md5 new file mode 100644 index 0000000..66490b8 --- /dev/null +++ b/inherit_graph_41.md5 @@ -0,0 +1 @@ +dedf3140ec164fdb1a04e13876aecbd0 \ No newline at end of file diff --git a/inherit_graph_41.png b/inherit_graph_41.png new file mode 100644 index 0000000..6fea021 Binary files /dev/null and b/inherit_graph_41.png differ diff --git a/inherit_graph_42.map b/inherit_graph_42.map new file mode 100644 index 0000000..8305050 --- /dev/null +++ b/inherit_graph_42.map @@ -0,0 +1,3 @@ + + + diff --git a/inherit_graph_42.md5 b/inherit_graph_42.md5 new file mode 100644 index 0000000..06f1e8d --- /dev/null +++ b/inherit_graph_42.md5 @@ -0,0 +1 @@ +4b3d92f6d0dec22f13142fb899c6c203 \ No newline at end of file diff --git a/inherit_graph_42.png b/inherit_graph_42.png new file mode 100644 index 0000000..84ab76e Binary files /dev/null and b/inherit_graph_42.png differ diff --git a/inherit_graph_43.map b/inherit_graph_43.map new file mode 100644 index 0000000..ec9e250 --- /dev/null +++ b/inherit_graph_43.map @@ -0,0 +1,3 @@ + + + diff --git a/inherit_graph_43.md5 b/inherit_graph_43.md5 new file mode 100644 index 0000000..3470b5f --- /dev/null +++ b/inherit_graph_43.md5 @@ -0,0 +1 @@ +cb2e519a256766e1af0e3ef2f796e97e \ No newline at end of file diff --git a/inherit_graph_43.png b/inherit_graph_43.png new file mode 100644 index 0000000..80d3375 Binary files /dev/null and b/inherit_graph_43.png differ diff --git a/inherit_graph_44.map b/inherit_graph_44.map new file mode 100644 index 0000000..900f65f --- /dev/null +++ b/inherit_graph_44.map @@ -0,0 +1,3 @@ + + + diff --git a/inherit_graph_44.md5 b/inherit_graph_44.md5 new file mode 100644 index 0000000..39c5c67 --- /dev/null +++ b/inherit_graph_44.md5 @@ -0,0 +1 @@ +a19df58ed0dc8df639d2248c2e7d10a5 \ No newline at end of file diff --git a/inherit_graph_44.png b/inherit_graph_44.png new file mode 100644 index 0000000..df268b8 Binary files /dev/null and b/inherit_graph_44.png differ diff --git a/inherit_graph_45.map b/inherit_graph_45.map new file mode 100644 index 0000000..12adb10 --- /dev/null +++ b/inherit_graph_45.map @@ -0,0 +1,3 @@ + + + diff --git a/inherit_graph_45.md5 b/inherit_graph_45.md5 new file mode 100644 index 0000000..96d6ffd --- /dev/null +++ b/inherit_graph_45.md5 @@ -0,0 +1 @@ +f39a3440900a5c521490b24585d2beed \ No newline at end of file diff --git a/inherit_graph_45.png b/inherit_graph_45.png new file mode 100644 index 0000000..8695d37 Binary files /dev/null and b/inherit_graph_45.png differ diff --git a/inherit_graph_46.map b/inherit_graph_46.map new file mode 100644 index 0000000..19fba37 --- /dev/null +++ b/inherit_graph_46.map @@ -0,0 +1,3 @@ + + + diff --git a/inherit_graph_46.md5 b/inherit_graph_46.md5 new file mode 100644 index 0000000..9573419 --- /dev/null +++ b/inherit_graph_46.md5 @@ -0,0 +1 @@ +4189533f0ab757d6f78471793fd1f9ee \ No newline at end of file diff --git a/inherit_graph_46.png b/inherit_graph_46.png new file mode 100644 index 0000000..da459c0 Binary files /dev/null and b/inherit_graph_46.png differ diff --git a/inherit_graph_47.map b/inherit_graph_47.map new file mode 100644 index 0000000..2555fa1 --- /dev/null +++ b/inherit_graph_47.map @@ -0,0 +1,3 @@ + + + diff --git a/inherit_graph_47.md5 b/inherit_graph_47.md5 new file mode 100644 index 0000000..8d6401c --- /dev/null +++ b/inherit_graph_47.md5 @@ -0,0 +1 @@ +5443b2b92177fbfeb5790dc756add82a \ No newline at end of file diff --git a/inherit_graph_47.png b/inherit_graph_47.png new file mode 100644 index 0000000..435807d Binary files /dev/null and b/inherit_graph_47.png differ diff --git a/inherit_graph_48.map b/inherit_graph_48.map new file mode 100644 index 0000000..240b985 --- /dev/null +++ b/inherit_graph_48.map @@ -0,0 +1,3 @@ + + + diff --git a/inherit_graph_48.md5 b/inherit_graph_48.md5 new file mode 100644 index 0000000..26e7fdc --- /dev/null +++ b/inherit_graph_48.md5 @@ -0,0 +1 @@ +50270a9006b250377a8be83e7181b55b \ No newline at end of file diff --git a/inherit_graph_48.png b/inherit_graph_48.png new file mode 100644 index 0000000..45bb9d6 Binary files /dev/null and b/inherit_graph_48.png differ diff --git a/inherit_graph_49.map b/inherit_graph_49.map new file mode 100644 index 0000000..40df4da --- /dev/null +++ b/inherit_graph_49.map @@ -0,0 +1,3 @@ + + + diff --git a/inherit_graph_49.md5 b/inherit_graph_49.md5 new file mode 100644 index 0000000..3df297b --- /dev/null +++ b/inherit_graph_49.md5 @@ -0,0 +1 @@ +c3254044cc1a4c35fbc40b39fa800bfd \ No newline at end of file diff --git a/inherit_graph_49.png b/inherit_graph_49.png new file mode 100644 index 0000000..b5a51d3 Binary files /dev/null and b/inherit_graph_49.png differ diff --git a/inherit_graph_5.map b/inherit_graph_5.map new file mode 100644 index 0000000..5721674 --- /dev/null +++ b/inherit_graph_5.map @@ -0,0 +1,3 @@ + + + diff --git a/inherit_graph_5.md5 b/inherit_graph_5.md5 new file mode 100644 index 0000000..7e4620b --- /dev/null +++ b/inherit_graph_5.md5 @@ -0,0 +1 @@ +819332fb6a15cacd05ee5a64d7f1ed45 \ No newline at end of file diff --git a/inherit_graph_5.png b/inherit_graph_5.png new file mode 100644 index 0000000..e4a8f0d Binary files /dev/null and b/inherit_graph_5.png differ diff --git a/inherit_graph_50.map b/inherit_graph_50.map new file mode 100644 index 0000000..cc4d0ce --- /dev/null +++ b/inherit_graph_50.map @@ -0,0 +1,3 @@ + + + diff --git a/inherit_graph_50.md5 b/inherit_graph_50.md5 new file mode 100644 index 0000000..01e4af8 --- /dev/null +++ b/inherit_graph_50.md5 @@ -0,0 +1 @@ +a2be34e67d8817ca0d059dfe95f67feb \ No newline at end of file diff --git a/inherit_graph_50.png b/inherit_graph_50.png new file mode 100644 index 0000000..af2cb46 Binary files /dev/null and b/inherit_graph_50.png differ diff --git a/inherit_graph_51.map b/inherit_graph_51.map new file mode 100644 index 0000000..c92f611 --- /dev/null +++ b/inherit_graph_51.map @@ -0,0 +1,3 @@ + + + diff --git a/inherit_graph_51.md5 b/inherit_graph_51.md5 new file mode 100644 index 0000000..67bbc53 --- /dev/null +++ b/inherit_graph_51.md5 @@ -0,0 +1 @@ +1eaf4645af3433987a9ca561a0597116 \ No newline at end of file diff --git a/inherit_graph_51.png b/inherit_graph_51.png new file mode 100644 index 0000000..066673d Binary files /dev/null and b/inherit_graph_51.png differ diff --git a/inherit_graph_52.map b/inherit_graph_52.map new file mode 100644 index 0000000..2b978ba --- /dev/null +++ b/inherit_graph_52.map @@ -0,0 +1,3 @@ + + + diff --git a/inherit_graph_52.md5 b/inherit_graph_52.md5 new file mode 100644 index 0000000..13f6a75 --- /dev/null +++ b/inherit_graph_52.md5 @@ -0,0 +1 @@ +46d1d1edc349b0a0674d17de8260963a \ No newline at end of file diff --git a/inherit_graph_52.png b/inherit_graph_52.png new file mode 100644 index 0000000..302ecc1 Binary files /dev/null and b/inherit_graph_52.png differ diff --git a/inherit_graph_6.map b/inherit_graph_6.map new file mode 100644 index 0000000..086ad4b --- /dev/null +++ b/inherit_graph_6.map @@ -0,0 +1,3 @@ + + + diff --git a/inherit_graph_6.md5 b/inherit_graph_6.md5 new file mode 100644 index 0000000..d063e78 --- /dev/null +++ b/inherit_graph_6.md5 @@ -0,0 +1 @@ +f9646379e4ba7725650d12f7edea56b9 \ No newline at end of file diff --git a/inherit_graph_6.png b/inherit_graph_6.png new file mode 100644 index 0000000..7c2db30 Binary files /dev/null and b/inherit_graph_6.png differ diff --git a/inherit_graph_7.map b/inherit_graph_7.map new file mode 100644 index 0000000..5562403 --- /dev/null +++ b/inherit_graph_7.map @@ -0,0 +1,3 @@ + + + diff --git a/inherit_graph_7.md5 b/inherit_graph_7.md5 new file mode 100644 index 0000000..610259c --- /dev/null +++ b/inherit_graph_7.md5 @@ -0,0 +1 @@ +6611ce124b6223068f56ef46c070d98f \ No newline at end of file diff --git a/inherit_graph_7.png b/inherit_graph_7.png new file mode 100644 index 0000000..4dc2e27 Binary files /dev/null and b/inherit_graph_7.png differ diff --git a/inherit_graph_8.map b/inherit_graph_8.map new file mode 100644 index 0000000..23e55d0 --- /dev/null +++ b/inherit_graph_8.map @@ -0,0 +1,3 @@ + + + diff --git a/inherit_graph_8.md5 b/inherit_graph_8.md5 new file mode 100644 index 0000000..5cc2e69 --- /dev/null +++ b/inherit_graph_8.md5 @@ -0,0 +1 @@ +934365cc2a581e1a565849cc841c9588 \ No newline at end of file diff --git a/inherit_graph_8.png b/inherit_graph_8.png new file mode 100644 index 0000000..61ad7b2 Binary files /dev/null and b/inherit_graph_8.png differ diff --git a/inherit_graph_9.map b/inherit_graph_9.map new file mode 100644 index 0000000..7f92c36 --- /dev/null +++ b/inherit_graph_9.map @@ -0,0 +1,4 @@ + + + + diff --git a/inherit_graph_9.md5 b/inherit_graph_9.md5 new file mode 100644 index 0000000..8218d78 --- /dev/null +++ b/inherit_graph_9.md5 @@ -0,0 +1 @@ +e3ea96f4510b8c814b5b4d9a90f2894d \ No newline at end of file diff --git a/inherit_graph_9.png b/inherit_graph_9.png new file mode 100644 index 0000000..5b5f6ad Binary files /dev/null and b/inherit_graph_9.png differ diff --git a/inherits.html b/inherits.html new file mode 100644 index 0000000..bcf646f --- /dev/null +++ b/inherits.html @@ -0,0 +1,314 @@ + + + + + + +pva2pva: Class Hierarchy + + + + + + + + + +
+
+ + + + + + +
+
pva2pva +  1.4.1 +
+
+
+ + + + + +
+ +
+ All Classes Functions Variables Pages
+ + +
+ +
+ +
+
+
Class Hierarchy
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ + +
+ + +
+ + +
+ + +
+ + +
+ + +
+ + +
+ + +
+ + +
+ + +
+ + +
+ + +
+ + +
+ + +
+ + +
+ + +
+ + +
+ + +
+ + +
+ + +
+ + +
+ + +
+ + +
+ + +
+ + +
+ + +
+ + +
+ + +
+ + +
+ + +
+ + +
+ + +
+ + +
+ + +
+ + +
+ + +
+ + +
+ + +
+ + +
+ + +
+ + +
+ + +
+ + +
+ + +
+ + +
+ + +
+ + +
+ + +
+ + +
+ + +
+ + +
+ + +
+
+ + + + diff --git a/jquery.js b/jquery.js new file mode 100644 index 0000000..6aa2e4c --- /dev/null +++ b/jquery.js @@ -0,0 +1,39 @@ +/*! + * jQuery JavaScript Library v1.7.1 + * http://jquery.com/ + * + * Copyright 2011, John Resig + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + * + * Includes Sizzle.js + * http://sizzlejs.com/ + * Copyright 2011, The Dojo Foundation + * Released under the MIT, BSD, and GPL Licenses. + * + * Date: Mon Nov 21 21:11:03 2011 -0500 + */ +(function(bb,L){var av=bb.document,bu=bb.navigator,bl=bb.location;var b=(function(){var bF=function(b0,b1){return new bF.fn.init(b0,b1,bD)},bU=bb.jQuery,bH=bb.$,bD,bY=/^(?:[^#<]*(<[\w\W]+>)[^>]*$|#([\w\-]*)$)/,bM=/\S/,bI=/^\s+/,bE=/\s+$/,bA=/^<(\w+)\s*\/?>(?:<\/\1>)?$/,bN=/^[\],:{}\s]*$/,bW=/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g,bP=/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g,bJ=/(?:^|:|,)(?:\s*\[)+/g,by=/(webkit)[ \/]([\w.]+)/,bR=/(opera)(?:.*version)?[ \/]([\w.]+)/,bQ=/(msie) ([\w.]+)/,bS=/(mozilla)(?:.*? rv:([\w.]+))?/,bB=/-([a-z]|[0-9])/ig,bZ=/^-ms-/,bT=function(b0,b1){return(b1+"").toUpperCase()},bX=bu.userAgent,bV,bC,e,bL=Object.prototype.toString,bG=Object.prototype.hasOwnProperty,bz=Array.prototype.push,bK=Array.prototype.slice,bO=String.prototype.trim,bv=Array.prototype.indexOf,bx={};bF.fn=bF.prototype={constructor:bF,init:function(b0,b4,b3){var b2,b5,b1,b6;if(!b0){return this}if(b0.nodeType){this.context=this[0]=b0;this.length=1;return this}if(b0==="body"&&!b4&&av.body){this.context=av;this[0]=av.body;this.selector=b0;this.length=1;return this}if(typeof b0==="string"){if(b0.charAt(0)==="<"&&b0.charAt(b0.length-1)===">"&&b0.length>=3){b2=[null,b0,null]}else{b2=bY.exec(b0)}if(b2&&(b2[1]||!b4)){if(b2[1]){b4=b4 instanceof bF?b4[0]:b4;b6=(b4?b4.ownerDocument||b4:av);b1=bA.exec(b0);if(b1){if(bF.isPlainObject(b4)){b0=[av.createElement(b1[1])];bF.fn.attr.call(b0,b4,true)}else{b0=[b6.createElement(b1[1])]}}else{b1=bF.buildFragment([b2[1]],[b6]);b0=(b1.cacheable?bF.clone(b1.fragment):b1.fragment).childNodes}return bF.merge(this,b0)}else{b5=av.getElementById(b2[2]);if(b5&&b5.parentNode){if(b5.id!==b2[2]){return b3.find(b0)}this.length=1;this[0]=b5}this.context=av;this.selector=b0;return this}}else{if(!b4||b4.jquery){return(b4||b3).find(b0)}else{return this.constructor(b4).find(b0)}}}else{if(bF.isFunction(b0)){return b3.ready(b0)}}if(b0.selector!==L){this.selector=b0.selector;this.context=b0.context}return bF.makeArray(b0,this)},selector:"",jquery:"1.7.1",length:0,size:function(){return this.length},toArray:function(){return bK.call(this,0)},get:function(b0){return b0==null?this.toArray():(b0<0?this[this.length+b0]:this[b0])},pushStack:function(b1,b3,b0){var b2=this.constructor();if(bF.isArray(b1)){bz.apply(b2,b1)}else{bF.merge(b2,b1)}b2.prevObject=this;b2.context=this.context;if(b3==="find"){b2.selector=this.selector+(this.selector?" ":"")+b0}else{if(b3){b2.selector=this.selector+"."+b3+"("+b0+")"}}return b2},each:function(b1,b0){return bF.each(this,b1,b0)},ready:function(b0){bF.bindReady();bC.add(b0);return this},eq:function(b0){b0=+b0;return b0===-1?this.slice(b0):this.slice(b0,b0+1)},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},slice:function(){return this.pushStack(bK.apply(this,arguments),"slice",bK.call(arguments).join(","))},map:function(b0){return this.pushStack(bF.map(this,function(b2,b1){return b0.call(b2,b1,b2)}))},end:function(){return this.prevObject||this.constructor(null)},push:bz,sort:[].sort,splice:[].splice};bF.fn.init.prototype=bF.fn;bF.extend=bF.fn.extend=function(){var b9,b2,b0,b1,b6,b7,b5=arguments[0]||{},b4=1,b3=arguments.length,b8=false;if(typeof b5==="boolean"){b8=b5;b5=arguments[1]||{};b4=2}if(typeof b5!=="object"&&!bF.isFunction(b5)){b5={}}if(b3===b4){b5=this;--b4}for(;b40){return}bC.fireWith(av,[bF]);if(bF.fn.trigger){bF(av).trigger("ready").off("ready")}}},bindReady:function(){if(bC){return}bC=bF.Callbacks("once memory");if(av.readyState==="complete"){return setTimeout(bF.ready,1)}if(av.addEventListener){av.addEventListener("DOMContentLoaded",e,false);bb.addEventListener("load",bF.ready,false)}else{if(av.attachEvent){av.attachEvent("onreadystatechange",e);bb.attachEvent("onload",bF.ready);var b0=false;try{b0=bb.frameElement==null}catch(b1){}if(av.documentElement.doScroll&&b0){bw()}}}},isFunction:function(b0){return bF.type(b0)==="function"},isArray:Array.isArray||function(b0){return bF.type(b0)==="array"},isWindow:function(b0){return b0&&typeof b0==="object"&&"setInterval" in b0},isNumeric:function(b0){return !isNaN(parseFloat(b0))&&isFinite(b0)},type:function(b0){return b0==null?String(b0):bx[bL.call(b0)]||"object"},isPlainObject:function(b2){if(!b2||bF.type(b2)!=="object"||b2.nodeType||bF.isWindow(b2)){return false}try{if(b2.constructor&&!bG.call(b2,"constructor")&&!bG.call(b2.constructor.prototype,"isPrototypeOf")){return false}}catch(b1){return false}var b0;for(b0 in b2){}return b0===L||bG.call(b2,b0)},isEmptyObject:function(b1){for(var b0 in b1){return false}return true},error:function(b0){throw new Error(b0)},parseJSON:function(b0){if(typeof b0!=="string"||!b0){return null}b0=bF.trim(b0);if(bb.JSON&&bb.JSON.parse){return bb.JSON.parse(b0)}if(bN.test(b0.replace(bW,"@").replace(bP,"]").replace(bJ,""))){return(new Function("return "+b0))()}bF.error("Invalid JSON: "+b0)},parseXML:function(b2){var b0,b1;try{if(bb.DOMParser){b1=new DOMParser();b0=b1.parseFromString(b2,"text/xml")}else{b0=new ActiveXObject("Microsoft.XMLDOM");b0.async="false";b0.loadXML(b2)}}catch(b3){b0=L}if(!b0||!b0.documentElement||b0.getElementsByTagName("parsererror").length){bF.error("Invalid XML: "+b2)}return b0},noop:function(){},globalEval:function(b0){if(b0&&bM.test(b0)){(bb.execScript||function(b1){bb["eval"].call(bb,b1)})(b0)}},camelCase:function(b0){return b0.replace(bZ,"ms-").replace(bB,bT)},nodeName:function(b1,b0){return b1.nodeName&&b1.nodeName.toUpperCase()===b0.toUpperCase()},each:function(b3,b6,b2){var b1,b4=0,b5=b3.length,b0=b5===L||bF.isFunction(b3);if(b2){if(b0){for(b1 in b3){if(b6.apply(b3[b1],b2)===false){break}}}else{for(;b40&&b0[0]&&b0[b1-1])||b1===0||bF.isArray(b0));if(b3){for(;b21?aJ.call(arguments,0):bG;if(!(--bw)){bC.resolveWith(bC,bx)}}}function bz(bF){return function(bG){bB[bF]=arguments.length>1?aJ.call(arguments,0):bG;bC.notifyWith(bE,bB)}}if(e>1){for(;bv
a";bI=bv.getElementsByTagName("*");bF=bv.getElementsByTagName("a")[0];if(!bI||!bI.length||!bF){return{}}bG=av.createElement("select");bx=bG.appendChild(av.createElement("option"));bE=bv.getElementsByTagName("input")[0];bJ={leadingWhitespace:(bv.firstChild.nodeType===3),tbody:!bv.getElementsByTagName("tbody").length,htmlSerialize:!!bv.getElementsByTagName("link").length,style:/top/.test(bF.getAttribute("style")),hrefNormalized:(bF.getAttribute("href")==="/a"),opacity:/^0.55/.test(bF.style.opacity),cssFloat:!!bF.style.cssFloat,checkOn:(bE.value==="on"),optSelected:bx.selected,getSetAttribute:bv.className!=="t",enctype:!!av.createElement("form").enctype,html5Clone:av.createElement("nav").cloneNode(true).outerHTML!=="<:nav>",submitBubbles:true,changeBubbles:true,focusinBubbles:false,deleteExpando:true,noCloneEvent:true,inlineBlockNeedsLayout:false,shrinkWrapBlocks:false,reliableMarginRight:true};bE.checked=true;bJ.noCloneChecked=bE.cloneNode(true).checked;bG.disabled=true;bJ.optDisabled=!bx.disabled;try{delete bv.test}catch(bC){bJ.deleteExpando=false}if(!bv.addEventListener&&bv.attachEvent&&bv.fireEvent){bv.attachEvent("onclick",function(){bJ.noCloneEvent=false});bv.cloneNode(true).fireEvent("onclick")}bE=av.createElement("input");bE.value="t";bE.setAttribute("type","radio");bJ.radioValue=bE.value==="t";bE.setAttribute("checked","checked");bv.appendChild(bE);bD=av.createDocumentFragment();bD.appendChild(bv.lastChild);bJ.checkClone=bD.cloneNode(true).cloneNode(true).lastChild.checked;bJ.appendChecked=bE.checked;bD.removeChild(bE);bD.appendChild(bv);bv.innerHTML="";if(bb.getComputedStyle){bA=av.createElement("div");bA.style.width="0";bA.style.marginRight="0";bv.style.width="2px";bv.appendChild(bA);bJ.reliableMarginRight=(parseInt((bb.getComputedStyle(bA,null)||{marginRight:0}).marginRight,10)||0)===0}if(bv.attachEvent){for(by in {submit:1,change:1,focusin:1}){bB="on"+by;bw=(bB in bv);if(!bw){bv.setAttribute(bB,"return;");bw=(typeof bv[bB]==="function")}bJ[by+"Bubbles"]=bw}}bD.removeChild(bv);bD=bG=bx=bA=bv=bE=null;b(function(){var bM,bU,bV,bT,bN,bO,bL,bS,bR,e,bP,bQ=av.getElementsByTagName("body")[0];if(!bQ){return}bL=1;bS="position:absolute;top:0;left:0;width:1px;height:1px;margin:0;";bR="visibility:hidden;border:0;";e="style='"+bS+"border:5px solid #000;padding:0;'";bP="
";bM=av.createElement("div");bM.style.cssText=bR+"width:0;height:0;position:static;top:0;margin-top:"+bL+"px";bQ.insertBefore(bM,bQ.firstChild);bv=av.createElement("div");bM.appendChild(bv);bv.innerHTML="
t
";bz=bv.getElementsByTagName("td");bw=(bz[0].offsetHeight===0);bz[0].style.display="";bz[1].style.display="none";bJ.reliableHiddenOffsets=bw&&(bz[0].offsetHeight===0);bv.innerHTML="";bv.style.width=bv.style.paddingLeft="1px";b.boxModel=bJ.boxModel=bv.offsetWidth===2;if(typeof bv.style.zoom!=="undefined"){bv.style.display="inline";bv.style.zoom=1;bJ.inlineBlockNeedsLayout=(bv.offsetWidth===2);bv.style.display="";bv.innerHTML="
";bJ.shrinkWrapBlocks=(bv.offsetWidth!==2)}bv.style.cssText=bS+bR;bv.innerHTML=bP;bU=bv.firstChild;bV=bU.firstChild;bN=bU.nextSibling.firstChild.firstChild;bO={doesNotAddBorder:(bV.offsetTop!==5),doesAddBorderForTableAndCells:(bN.offsetTop===5)};bV.style.position="fixed";bV.style.top="20px";bO.fixedPosition=(bV.offsetTop===20||bV.offsetTop===15);bV.style.position=bV.style.top="";bU.style.overflow="hidden";bU.style.position="relative";bO.subtractsBorderForOverflowNotVisible=(bV.offsetTop===-5);bO.doesNotIncludeMarginInBodyOffset=(bQ.offsetTop!==bL);bQ.removeChild(bM);bv=bM=null;b.extend(bJ,bO)});return bJ})();var aS=/^(?:\{.*\}|\[.*\])$/,aA=/([A-Z])/g;b.extend({cache:{},uuid:0,expando:"jQuery"+(b.fn.jquery+Math.random()).replace(/\D/g,""),noData:{embed:true,object:"clsid:D27CDB6E-AE6D-11cf-96B8-444553540000",applet:true},hasData:function(e){e=e.nodeType?b.cache[e[b.expando]]:e[b.expando];return !!e&&!S(e)},data:function(bx,bv,bz,by){if(!b.acceptData(bx)){return}var bG,bA,bD,bE=b.expando,bC=typeof bv==="string",bF=bx.nodeType,e=bF?b.cache:bx,bw=bF?bx[bE]:bx[bE]&&bE,bB=bv==="events";if((!bw||!e[bw]||(!bB&&!by&&!e[bw].data))&&bC&&bz===L){return}if(!bw){if(bF){bx[bE]=bw=++b.uuid}else{bw=bE}}if(!e[bw]){e[bw]={};if(!bF){e[bw].toJSON=b.noop}}if(typeof bv==="object"||typeof bv==="function"){if(by){e[bw]=b.extend(e[bw],bv)}else{e[bw].data=b.extend(e[bw].data,bv)}}bG=bA=e[bw];if(!by){if(!bA.data){bA.data={}}bA=bA.data}if(bz!==L){bA[b.camelCase(bv)]=bz}if(bB&&!bA[bv]){return bG.events}if(bC){bD=bA[bv];if(bD==null){bD=bA[b.camelCase(bv)]}}else{bD=bA}return bD},removeData:function(bx,bv,by){if(!b.acceptData(bx)){return}var bB,bA,bz,bC=b.expando,bD=bx.nodeType,e=bD?b.cache:bx,bw=bD?bx[bC]:bC;if(!e[bw]){return}if(bv){bB=by?e[bw]:e[bw].data;if(bB){if(!b.isArray(bv)){if(bv in bB){bv=[bv]}else{bv=b.camelCase(bv);if(bv in bB){bv=[bv]}else{bv=bv.split(" ")}}}for(bA=0,bz=bv.length;bA-1){return true}}return false},val:function(bx){var e,bv,by,bw=this[0];if(!arguments.length){if(bw){e=b.valHooks[bw.nodeName.toLowerCase()]||b.valHooks[bw.type];if(e&&"get" in e&&(bv=e.get(bw,"value"))!==L){return bv}bv=bw.value;return typeof bv==="string"?bv.replace(aU,""):bv==null?"":bv}return}by=b.isFunction(bx);return this.each(function(bA){var bz=b(this),bB;if(this.nodeType!==1){return}if(by){bB=bx.call(this,bA,bz.val())}else{bB=bx}if(bB==null){bB=""}else{if(typeof bB==="number"){bB+=""}else{if(b.isArray(bB)){bB=b.map(bB,function(bC){return bC==null?"":bC+""})}}}e=b.valHooks[this.nodeName.toLowerCase()]||b.valHooks[this.type];if(!e||!("set" in e)||e.set(this,bB,"value")===L){this.value=bB}})}});b.extend({valHooks:{option:{get:function(e){var bv=e.attributes.value;return !bv||bv.specified?e.value:e.text}},select:{get:function(e){var bA,bv,bz,bx,by=e.selectedIndex,bB=[],bC=e.options,bw=e.type==="select-one";if(by<0){return null}bv=bw?by:0;bz=bw?by+1:bC.length;for(;bv=0});if(!e.length){bv.selectedIndex=-1}return e}}},attrFn:{val:true,css:true,html:true,text:true,data:true,width:true,height:true,offset:true},attr:function(bA,bx,bB,bz){var bw,e,by,bv=bA.nodeType; +if(!bA||bv===3||bv===8||bv===2){return}if(bz&&bx in b.attrFn){return b(bA)[bx](bB)}if(typeof bA.getAttribute==="undefined"){return b.prop(bA,bx,bB)}by=bv!==1||!b.isXMLDoc(bA);if(by){bx=bx.toLowerCase();e=b.attrHooks[bx]||(ao.test(bx)?aY:be)}if(bB!==L){if(bB===null){b.removeAttr(bA,bx);return}else{if(e&&"set" in e&&by&&(bw=e.set(bA,bB,bx))!==L){return bw}else{bA.setAttribute(bx,""+bB);return bB}}}else{if(e&&"get" in e&&by&&(bw=e.get(bA,bx))!==null){return bw}else{bw=bA.getAttribute(bx);return bw===null?L:bw}}},removeAttr:function(bx,bz){var by,bA,bv,e,bw=0;if(bz&&bx.nodeType===1){bA=bz.toLowerCase().split(af);e=bA.length;for(;bw=0)}}})});var bd=/^(?:textarea|input|select)$/i,n=/^([^\.]*)?(?:\.(.+))?$/,J=/\bhover(\.\S+)?\b/,aO=/^key/,bf=/^(?:mouse|contextmenu)|click/,T=/^(?:focusinfocus|focusoutblur)$/,U=/^(\w*)(?:#([\w\-]+))?(?:\.([\w\-]+))?$/,Y=function(e){var bv=U.exec(e);if(bv){bv[1]=(bv[1]||"").toLowerCase();bv[3]=bv[3]&&new RegExp("(?:^|\\s)"+bv[3]+"(?:\\s|$)")}return bv},j=function(bw,e){var bv=bw.attributes||{};return((!e[1]||bw.nodeName.toLowerCase()===e[1])&&(!e[2]||(bv.id||{}).value===e[2])&&(!e[3]||e[3].test((bv["class"]||{}).value)))},bt=function(e){return b.event.special.hover?e:e.replace(J,"mouseenter$1 mouseleave$1")};b.event={add:function(bx,bC,bJ,bA,by){var bD,bB,bK,bI,bH,bF,e,bG,bv,bz,bw,bE;if(bx.nodeType===3||bx.nodeType===8||!bC||!bJ||!(bD=b._data(bx))){return}if(bJ.handler){bv=bJ;bJ=bv.handler}if(!bJ.guid){bJ.guid=b.guid++}bK=bD.events;if(!bK){bD.events=bK={}}bB=bD.handle;if(!bB){bD.handle=bB=function(bL){return typeof b!=="undefined"&&(!bL||b.event.triggered!==bL.type)?b.event.dispatch.apply(bB.elem,arguments):L};bB.elem=bx}bC=b.trim(bt(bC)).split(" ");for(bI=0;bI=0){bG=bG.slice(0,-1);bw=true}if(bG.indexOf(".")>=0){bx=bG.split(".");bG=bx.shift();bx.sort()}if((!bA||b.event.customEvent[bG])&&!b.event.global[bG]){return}bv=typeof bv==="object"?bv[b.expando]?bv:new b.Event(bG,bv):new b.Event(bG);bv.type=bG;bv.isTrigger=true;bv.exclusive=bw;bv.namespace=bx.join(".");bv.namespace_re=bv.namespace?new RegExp("(^|\\.)"+bx.join("\\.(?:.*\\.)?")+"(\\.|$)"):null;by=bG.indexOf(":")<0?"on"+bG:"";if(!bA){e=b.cache;for(bC in e){if(e[bC].events&&e[bC].events[bG]){b.event.trigger(bv,bD,e[bC].handle.elem,true)}}return}bv.result=L;if(!bv.target){bv.target=bA}bD=bD!=null?b.makeArray(bD):[];bD.unshift(bv);bF=b.event.special[bG]||{};if(bF.trigger&&bF.trigger.apply(bA,bD)===false){return}bB=[[bA,bF.bindType||bG]];if(!bJ&&!bF.noBubble&&!b.isWindow(bA)){bI=bF.delegateType||bG;bH=T.test(bI+bG)?bA:bA.parentNode;bz=null;for(;bH;bH=bH.parentNode){bB.push([bH,bI]);bz=bH}if(bz&&bz===bA.ownerDocument){bB.push([bz.defaultView||bz.parentWindow||bb,bI])}}for(bC=0;bCbA){bH.push({elem:this,matches:bz.slice(bA)})}for(bC=0;bC0?this.on(e,null,bx,bw):this.trigger(e)};if(b.attrFn){b.attrFn[e]=true}if(aO.test(e)){b.event.fixHooks[e]=b.event.keyHooks}if(bf.test(e)){b.event.fixHooks[e]=b.event.mouseHooks}}); +/*! + * Sizzle CSS Selector Engine + * Copyright 2011, The Dojo Foundation + * Released under the MIT, BSD, and GPL Licenses. + * More information: http://sizzlejs.com/ + */ +(function(){var bH=/((?:\((?:\([^()]+\)|[^()]+)+\)|\[(?:\[[^\[\]]*\]|['"][^'"]*['"]|[^\[\]'"]+)+\]|\\.|[^ >+~,(\[\\]+)+|[>+~])(\s*,\s*)?((?:.|\r|\n)*)/g,bC="sizcache"+(Math.random()+"").replace(".",""),bI=0,bL=Object.prototype.toString,bB=false,bA=true,bK=/\\/g,bO=/\r\n/g,bQ=/\W/;[0,0].sort(function(){bA=false;return 0});var by=function(bV,e,bY,bZ){bY=bY||[];e=e||av;var b1=e;if(e.nodeType!==1&&e.nodeType!==9){return[]}if(!bV||typeof bV!=="string"){return bY}var bS,b3,b6,bR,b2,b5,b4,bX,bU=true,bT=by.isXML(e),bW=[],b0=bV;do{bH.exec("");bS=bH.exec(b0);if(bS){b0=bS[3];bW.push(bS[1]);if(bS[2]){bR=bS[3];break}}}while(bS);if(bW.length>1&&bD.exec(bV)){if(bW.length===2&&bE.relative[bW[0]]){b3=bM(bW[0]+bW[1],e,bZ)}else{b3=bE.relative[bW[0]]?[e]:by(bW.shift(),e);while(bW.length){bV=bW.shift();if(bE.relative[bV]){bV+=bW.shift()}b3=bM(bV,b3,bZ)}}}else{if(!bZ&&bW.length>1&&e.nodeType===9&&!bT&&bE.match.ID.test(bW[0])&&!bE.match.ID.test(bW[bW.length-1])){b2=by.find(bW.shift(),e,bT);e=b2.expr?by.filter(b2.expr,b2.set)[0]:b2.set[0]}if(e){b2=bZ?{expr:bW.pop(),set:bF(bZ)}:by.find(bW.pop(),bW.length===1&&(bW[0]==="~"||bW[0]==="+")&&e.parentNode?e.parentNode:e,bT);b3=b2.expr?by.filter(b2.expr,b2.set):b2.set;if(bW.length>0){b6=bF(b3)}else{bU=false}while(bW.length){b5=bW.pop();b4=b5;if(!bE.relative[b5]){b5=""}else{b4=bW.pop()}if(b4==null){b4=e}bE.relative[b5](b6,b4,bT)}}else{b6=bW=[]}}if(!b6){b6=b3}if(!b6){by.error(b5||bV)}if(bL.call(b6)==="[object Array]"){if(!bU){bY.push.apply(bY,b6)}else{if(e&&e.nodeType===1){for(bX=0;b6[bX]!=null;bX++){if(b6[bX]&&(b6[bX]===true||b6[bX].nodeType===1&&by.contains(e,b6[bX]))){bY.push(b3[bX])}}}else{for(bX=0;b6[bX]!=null;bX++){if(b6[bX]&&b6[bX].nodeType===1){bY.push(b3[bX])}}}}}else{bF(b6,bY)}if(bR){by(bR,b1,bY,bZ);by.uniqueSort(bY)}return bY};by.uniqueSort=function(bR){if(bJ){bB=bA;bR.sort(bJ);if(bB){for(var e=1;e0};by.find=function(bX,e,bY){var bW,bS,bU,bT,bV,bR;if(!bX){return[]}for(bS=0,bU=bE.order.length;bS":function(bW,bR){var bV,bU=typeof bR==="string",bS=0,e=bW.length;if(bU&&!bQ.test(bR)){bR=bR.toLowerCase();for(;bS=0)){if(!bS){e.push(bV)}}else{if(bS){bR[bU]=false}}}}return false},ID:function(e){return e[1].replace(bK,"")},TAG:function(bR,e){return bR[1].replace(bK,"").toLowerCase()},CHILD:function(e){if(e[1]==="nth"){if(!e[2]){by.error(e[0])}e[2]=e[2].replace(/^\+|\s*/g,"");var bR=/(-?)(\d*)(?:n([+\-]?\d*))?/.exec(e[2]==="even"&&"2n"||e[2]==="odd"&&"2n+1"||!/\D/.test(e[2])&&"0n+"+e[2]||e[2]);e[2]=(bR[1]+(bR[2]||1))-0;e[3]=bR[3]-0}else{if(e[2]){by.error(e[0])}}e[0]=bI++;return e},ATTR:function(bU,bR,bS,e,bV,bW){var bT=bU[1]=bU[1].replace(bK,"");if(!bW&&bE.attrMap[bT]){bU[1]=bE.attrMap[bT]}bU[4]=(bU[4]||bU[5]||"").replace(bK,"");if(bU[2]==="~="){bU[4]=" "+bU[4]+" "}return bU},PSEUDO:function(bU,bR,bS,e,bV){if(bU[1]==="not"){if((bH.exec(bU[3])||"").length>1||/^\w/.test(bU[3])){bU[3]=by(bU[3],null,null,bR)}else{var bT=by.filter(bU[3],bR,bS,true^bV);if(!bS){e.push.apply(e,bT)}return false}}else{if(bE.match.POS.test(bU[0])||bE.match.CHILD.test(bU[0])){return true}}return bU},POS:function(e){e.unshift(true);return e}},filters:{enabled:function(e){return e.disabled===false&&e.type!=="hidden"},disabled:function(e){return e.disabled===true},checked:function(e){return e.checked===true},selected:function(e){if(e.parentNode){e.parentNode.selectedIndex}return e.selected===true},parent:function(e){return !!e.firstChild},empty:function(e){return !e.firstChild},has:function(bS,bR,e){return !!by(e[3],bS).length},header:function(e){return(/h\d/i).test(e.nodeName)},text:function(bS){var e=bS.getAttribute("type"),bR=bS.type;return bS.nodeName.toLowerCase()==="input"&&"text"===bR&&(e===bR||e===null)},radio:function(e){return e.nodeName.toLowerCase()==="input"&&"radio"===e.type},checkbox:function(e){return e.nodeName.toLowerCase()==="input"&&"checkbox"===e.type},file:function(e){return e.nodeName.toLowerCase()==="input"&&"file"===e.type},password:function(e){return e.nodeName.toLowerCase()==="input"&&"password"===e.type},submit:function(bR){var e=bR.nodeName.toLowerCase();return(e==="input"||e==="button")&&"submit"===bR.type},image:function(e){return e.nodeName.toLowerCase()==="input"&&"image"===e.type},reset:function(bR){var e=bR.nodeName.toLowerCase();return(e==="input"||e==="button")&&"reset"===bR.type},button:function(bR){var e=bR.nodeName.toLowerCase();return e==="input"&&"button"===bR.type||e==="button"},input:function(e){return(/input|select|textarea|button/i).test(e.nodeName)},focus:function(e){return e===e.ownerDocument.activeElement}},setFilters:{first:function(bR,e){return e===0},last:function(bS,bR,e,bT){return bR===bT.length-1},even:function(bR,e){return e%2===0},odd:function(bR,e){return e%2===1 +},lt:function(bS,bR,e){return bRe[3]-0},nth:function(bS,bR,e){return e[3]-0===bR},eq:function(bS,bR,e){return e[3]-0===bR}},filter:{PSEUDO:function(bS,bX,bW,bY){var e=bX[1],bR=bE.filters[e];if(bR){return bR(bS,bW,bX,bY)}else{if(e==="contains"){return(bS.textContent||bS.innerText||bw([bS])||"").indexOf(bX[3])>=0}else{if(e==="not"){var bT=bX[3];for(var bV=0,bU=bT.length;bV=0)}}},ID:function(bR,e){return bR.nodeType===1&&bR.getAttribute("id")===e},TAG:function(bR,e){return(e==="*"&&bR.nodeType===1)||!!bR.nodeName&&bR.nodeName.toLowerCase()===e},CLASS:function(bR,e){return(" "+(bR.className||bR.getAttribute("class"))+" ").indexOf(e)>-1},ATTR:function(bV,bT){var bS=bT[1],e=by.attr?by.attr(bV,bS):bE.attrHandle[bS]?bE.attrHandle[bS](bV):bV[bS]!=null?bV[bS]:bV.getAttribute(bS),bW=e+"",bU=bT[2],bR=bT[4];return e==null?bU==="!=":!bU&&by.attr?e!=null:bU==="="?bW===bR:bU==="*="?bW.indexOf(bR)>=0:bU==="~="?(" "+bW+" ").indexOf(bR)>=0:!bR?bW&&e!==false:bU==="!="?bW!==bR:bU==="^="?bW.indexOf(bR)===0:bU==="$="?bW.substr(bW.length-bR.length)===bR:bU==="|="?bW===bR||bW.substr(0,bR.length+1)===bR+"-":false},POS:function(bU,bR,bS,bV){var e=bR[2],bT=bE.setFilters[e];if(bT){return bT(bU,bS,bR,bV)}}}};var bD=bE.match.POS,bx=function(bR,e){return"\\"+(e-0+1)};for(var bz in bE.match){bE.match[bz]=new RegExp(bE.match[bz].source+(/(?![^\[]*\])(?![^\(]*\))/.source));bE.leftMatch[bz]=new RegExp(/(^(?:.|\r|\n)*?)/.source+bE.match[bz].source.replace(/\\(\d+)/g,bx))}var bF=function(bR,e){bR=Array.prototype.slice.call(bR,0);if(e){e.push.apply(e,bR);return e}return bR};try{Array.prototype.slice.call(av.documentElement.childNodes,0)[0].nodeType}catch(bP){bF=function(bU,bT){var bS=0,bR=bT||[];if(bL.call(bU)==="[object Array]"){Array.prototype.push.apply(bR,bU)}else{if(typeof bU.length==="number"){for(var e=bU.length;bS";e.insertBefore(bR,e.firstChild);if(av.getElementById(bS)){bE.find.ID=function(bU,bV,bW){if(typeof bV.getElementById!=="undefined"&&!bW){var bT=bV.getElementById(bU[1]);return bT?bT.id===bU[1]||typeof bT.getAttributeNode!=="undefined"&&bT.getAttributeNode("id").nodeValue===bU[1]?[bT]:L:[]}};bE.filter.ID=function(bV,bT){var bU=typeof bV.getAttributeNode!=="undefined"&&bV.getAttributeNode("id");return bV.nodeType===1&&bU&&bU.nodeValue===bT}}e.removeChild(bR);e=bR=null})();(function(){var e=av.createElement("div");e.appendChild(av.createComment(""));if(e.getElementsByTagName("*").length>0){bE.find.TAG=function(bR,bV){var bU=bV.getElementsByTagName(bR[1]);if(bR[1]==="*"){var bT=[];for(var bS=0;bU[bS];bS++){if(bU[bS].nodeType===1){bT.push(bU[bS])}}bU=bT}return bU}}e.innerHTML="";if(e.firstChild&&typeof e.firstChild.getAttribute!=="undefined"&&e.firstChild.getAttribute("href")!=="#"){bE.attrHandle.href=function(bR){return bR.getAttribute("href",2)}}e=null})();if(av.querySelectorAll){(function(){var e=by,bT=av.createElement("div"),bS="__sizzle__";bT.innerHTML="

";if(bT.querySelectorAll&&bT.querySelectorAll(".TEST").length===0){return}by=function(b4,bV,bZ,b3){bV=bV||av;if(!b3&&!by.isXML(bV)){var b2=/^(\w+$)|^\.([\w\-]+$)|^#([\w\-]+$)/.exec(b4);if(b2&&(bV.nodeType===1||bV.nodeType===9)){if(b2[1]){return bF(bV.getElementsByTagName(b4),bZ)}else{if(b2[2]&&bE.find.CLASS&&bV.getElementsByClassName){return bF(bV.getElementsByClassName(b2[2]),bZ)}}}if(bV.nodeType===9){if(b4==="body"&&bV.body){return bF([bV.body],bZ)}else{if(b2&&b2[3]){var bY=bV.getElementById(b2[3]);if(bY&&bY.parentNode){if(bY.id===b2[3]){return bF([bY],bZ)}}else{return bF([],bZ)}}}try{return bF(bV.querySelectorAll(b4),bZ)}catch(b0){}}else{if(bV.nodeType===1&&bV.nodeName.toLowerCase()!=="object"){var bW=bV,bX=bV.getAttribute("id"),bU=bX||bS,b6=bV.parentNode,b5=/^\s*[+~]/.test(b4);if(!bX){bV.setAttribute("id",bU)}else{bU=bU.replace(/'/g,"\\$&")}if(b5&&b6){bV=bV.parentNode}try{if(!b5||b6){return bF(bV.querySelectorAll("[id='"+bU+"'] "+b4),bZ)}}catch(b1){}finally{if(!bX){bW.removeAttribute("id")}}}}}return e(b4,bV,bZ,b3)};for(var bR in e){by[bR]=e[bR]}bT=null})()}(function(){var e=av.documentElement,bS=e.matchesSelector||e.mozMatchesSelector||e.webkitMatchesSelector||e.msMatchesSelector;if(bS){var bU=!bS.call(av.createElement("div"),"div"),bR=false;try{bS.call(av.documentElement,"[test!='']:sizzle")}catch(bT){bR=true}by.matchesSelector=function(bW,bY){bY=bY.replace(/\=\s*([^'"\]]*)\s*\]/g,"='$1']");if(!by.isXML(bW)){try{if(bR||!bE.match.PSEUDO.test(bY)&&!/!=/.test(bY)){var bV=bS.call(bW,bY);if(bV||!bU||bW.document&&bW.document.nodeType!==11){return bV}}}catch(bX){}}return by(bY,null,null,[bW]).length>0}}})();(function(){var e=av.createElement("div");e.innerHTML="
";if(!e.getElementsByClassName||e.getElementsByClassName("e").length===0){return}e.lastChild.className="e";if(e.getElementsByClassName("e").length===1){return}bE.order.splice(1,0,"CLASS");bE.find.CLASS=function(bR,bS,bT){if(typeof bS.getElementsByClassName!=="undefined"&&!bT){return bS.getElementsByClassName(bR[1])}};e=null})();function bv(bR,bW,bV,bZ,bX,bY){for(var bT=0,bS=bZ.length;bT0){bU=e;break}}}e=e[bR]}bZ[bT]=bU}}}if(av.documentElement.contains){by.contains=function(bR,e){return bR!==e&&(bR.contains?bR.contains(e):true)}}else{if(av.documentElement.compareDocumentPosition){by.contains=function(bR,e){return !!(bR.compareDocumentPosition(e)&16)}}else{by.contains=function(){return false}}}by.isXML=function(e){var bR=(e?e.ownerDocument||e:0).documentElement;return bR?bR.nodeName!=="HTML":false};var bM=function(bS,e,bW){var bV,bX=[],bU="",bY=e.nodeType?[e]:e;while((bV=bE.match.PSEUDO.exec(bS))){bU+=bV[0];bS=bS.replace(bE.match.PSEUDO,"")}bS=bE.relative[bS]?bS+"*":bS;for(var bT=0,bR=bY.length;bT0){for(bB=bA;bB=0:b.filter(e,this).length>0:this.filter(e).length>0)},closest:function(by,bx){var bv=[],bw,e,bz=this[0];if(b.isArray(by)){var bB=1;while(bz&&bz.ownerDocument&&bz!==bx){for(bw=0;bw-1:b.find.matchesSelector(bz,by)){bv.push(bz);break}else{bz=bz.parentNode;if(!bz||!bz.ownerDocument||bz===bx||bz.nodeType===11){break}}}}bv=bv.length>1?b.unique(bv):bv;return this.pushStack(bv,"closest",by)},index:function(e){if(!e){return(this[0]&&this[0].parentNode)?this.prevAll().length:-1}if(typeof e==="string"){return b.inArray(this[0],b(e))}return b.inArray(e.jquery?e[0]:e,this)},add:function(e,bv){var bx=typeof e==="string"?b(e,bv):b.makeArray(e&&e.nodeType?[e]:e),bw=b.merge(this.get(),bx);return this.pushStack(C(bx[0])||C(bw[0])?bw:b.unique(bw))},andSelf:function(){return this.add(this.prevObject)}});function C(e){return !e||!e.parentNode||e.parentNode.nodeType===11}b.each({parent:function(bv){var e=bv.parentNode;return e&&e.nodeType!==11?e:null},parents:function(e){return b.dir(e,"parentNode")},parentsUntil:function(bv,e,bw){return b.dir(bv,"parentNode",bw)},next:function(e){return b.nth(e,2,"nextSibling")},prev:function(e){return b.nth(e,2,"previousSibling")},nextAll:function(e){return b.dir(e,"nextSibling")},prevAll:function(e){return b.dir(e,"previousSibling")},nextUntil:function(bv,e,bw){return b.dir(bv,"nextSibling",bw)},prevUntil:function(bv,e,bw){return b.dir(bv,"previousSibling",bw)},siblings:function(e){return b.sibling(e.parentNode.firstChild,e)},children:function(e){return b.sibling(e.firstChild)},contents:function(e){return b.nodeName(e,"iframe")?e.contentDocument||e.contentWindow.document:b.makeArray(e.childNodes)}},function(e,bv){b.fn[e]=function(by,bw){var bx=b.map(this,bv,by);if(!ab.test(e)){bw=by}if(bw&&typeof bw==="string"){bx=b.filter(bw,bx)}bx=this.length>1&&!ay[e]?b.unique(bx):bx;if((this.length>1||a9.test(bw))&&aq.test(e)){bx=bx.reverse()}return this.pushStack(bx,e,P.call(arguments).join(","))}});b.extend({filter:function(bw,e,bv){if(bv){bw=":not("+bw+")"}return e.length===1?b.find.matchesSelector(e[0],bw)?[e[0]]:[]:b.find.matches(bw,e)},dir:function(bw,bv,by){var e=[],bx=bw[bv];while(bx&&bx.nodeType!==9&&(by===L||bx.nodeType!==1||!b(bx).is(by))){if(bx.nodeType===1){e.push(bx)}bx=bx[bv]}return e},nth:function(by,e,bw,bx){e=e||1;var bv=0;for(;by;by=by[bw]){if(by.nodeType===1&&++bv===e){break}}return by},sibling:function(bw,bv){var e=[];for(;bw;bw=bw.nextSibling){if(bw.nodeType===1&&bw!==bv){e.push(bw)}}return e}});function aG(bx,bw,e){bw=bw||0;if(b.isFunction(bw)){return b.grep(bx,function(bz,by){var bA=!!bw.call(bz,by,bz);return bA===e})}else{if(bw.nodeType){return b.grep(bx,function(bz,by){return(bz===bw)===e})}else{if(typeof bw==="string"){var bv=b.grep(bx,function(by){return by.nodeType===1});if(bp.test(bw)){return b.filter(bw,bv,!e)}else{bw=b.filter(bw,bv)}}}}return b.grep(bx,function(bz,by){return(b.inArray(bz,bw)>=0)===e})}function a(e){var bw=aR.split("|"),bv=e.createDocumentFragment();if(bv.createElement){while(bw.length){bv.createElement(bw.pop())}}return bv}var aR="abbr|article|aside|audio|canvas|datalist|details|figcaption|figure|footer|header|hgroup|mark|meter|nav|output|progress|section|summary|time|video",ag=/ jQuery\d+="(?:\d+|null)"/g,ar=/^\s+/,R=/<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/ig,d=/<([\w:]+)/,w=/",""],legend:[1,"
","
"],thead:[1,"","
"],tr:[2,"","
"],td:[3,"","
"],col:[2,"","
"],area:[1,"",""],_default:[0,"",""]},ac=a(av); +ax.optgroup=ax.option;ax.tbody=ax.tfoot=ax.colgroup=ax.caption=ax.thead;ax.th=ax.td;if(!b.support.htmlSerialize){ax._default=[1,"div
","
"]}b.fn.extend({text:function(e){if(b.isFunction(e)){return this.each(function(bw){var bv=b(this);bv.text(e.call(this,bw,bv.text()))})}if(typeof e!=="object"&&e!==L){return this.empty().append((this[0]&&this[0].ownerDocument||av).createTextNode(e))}return b.text(this)},wrapAll:function(e){if(b.isFunction(e)){return this.each(function(bw){b(this).wrapAll(e.call(this,bw))})}if(this[0]){var bv=b(e,this[0].ownerDocument).eq(0).clone(true);if(this[0].parentNode){bv.insertBefore(this[0])}bv.map(function(){var bw=this;while(bw.firstChild&&bw.firstChild.nodeType===1){bw=bw.firstChild}return bw}).append(this)}return this},wrapInner:function(e){if(b.isFunction(e)){return this.each(function(bv){b(this).wrapInner(e.call(this,bv))})}return this.each(function(){var bv=b(this),bw=bv.contents();if(bw.length){bw.wrapAll(e)}else{bv.append(e)}})},wrap:function(e){var bv=b.isFunction(e);return this.each(function(bw){b(this).wrapAll(bv?e.call(this,bw):e)})},unwrap:function(){return this.parent().each(function(){if(!b.nodeName(this,"body")){b(this).replaceWith(this.childNodes)}}).end()},append:function(){return this.domManip(arguments,true,function(e){if(this.nodeType===1){this.appendChild(e)}})},prepend:function(){return this.domManip(arguments,true,function(e){if(this.nodeType===1){this.insertBefore(e,this.firstChild)}})},before:function(){if(this[0]&&this[0].parentNode){return this.domManip(arguments,false,function(bv){this.parentNode.insertBefore(bv,this)})}else{if(arguments.length){var e=b.clean(arguments);e.push.apply(e,this.toArray());return this.pushStack(e,"before",arguments)}}},after:function(){if(this[0]&&this[0].parentNode){return this.domManip(arguments,false,function(bv){this.parentNode.insertBefore(bv,this.nextSibling)})}else{if(arguments.length){var e=this.pushStack(this,"after",arguments);e.push.apply(e,b.clean(arguments));return e}}},remove:function(e,bx){for(var bv=0,bw;(bw=this[bv])!=null;bv++){if(!e||b.filter(e,[bw]).length){if(!bx&&bw.nodeType===1){b.cleanData(bw.getElementsByTagName("*"));b.cleanData([bw])}if(bw.parentNode){bw.parentNode.removeChild(bw)}}}return this},empty:function(){for(var e=0,bv;(bv=this[e])!=null;e++){if(bv.nodeType===1){b.cleanData(bv.getElementsByTagName("*"))}while(bv.firstChild){bv.removeChild(bv.firstChild)}}return this},clone:function(bv,e){bv=bv==null?false:bv;e=e==null?bv:e;return this.map(function(){return b.clone(this,bv,e)})},html:function(bx){if(bx===L){return this[0]&&this[0].nodeType===1?this[0].innerHTML.replace(ag,""):null}else{if(typeof bx==="string"&&!ae.test(bx)&&(b.support.leadingWhitespace||!ar.test(bx))&&!ax[(d.exec(bx)||["",""])[1].toLowerCase()]){bx=bx.replace(R,"<$1>");try{for(var bw=0,bv=this.length;bw1&&bw0?this.clone(true):this).get();b(bC[bA])[bv](by);bz=bz.concat(by)}return this.pushStack(bz,e,bC.selector)}}});function bg(e){if(typeof e.getElementsByTagName!=="undefined"){return e.getElementsByTagName("*")}else{if(typeof e.querySelectorAll!=="undefined"){return e.querySelectorAll("*")}else{return[]}}}function az(e){if(e.type==="checkbox"||e.type==="radio"){e.defaultChecked=e.checked}}function E(e){var bv=(e.nodeName||"").toLowerCase();if(bv==="input"){az(e)}else{if(bv!=="script"&&typeof e.getElementsByTagName!=="undefined"){b.grep(e.getElementsByTagName("input"),az)}}}function al(e){var bv=av.createElement("div");ac.appendChild(bv);bv.innerHTML=e.outerHTML;return bv.firstChild}b.extend({clone:function(by,bA,bw){var e,bv,bx,bz=b.support.html5Clone||!ah.test("<"+by.nodeName)?by.cloneNode(true):al(by);if((!b.support.noCloneEvent||!b.support.noCloneChecked)&&(by.nodeType===1||by.nodeType===11)&&!b.isXMLDoc(by)){ai(by,bz);e=bg(by);bv=bg(bz);for(bx=0;e[bx];++bx){if(bv[bx]){ai(e[bx],bv[bx])}}}if(bA){t(by,bz);if(bw){e=bg(by);bv=bg(bz);for(bx=0;e[bx];++bx){t(e[bx],bv[bx])}}}e=bv=null;return bz},clean:function(bw,by,bH,bA){var bF;by=by||av;if(typeof by.createElement==="undefined"){by=by.ownerDocument||by[0]&&by[0].ownerDocument||av}var bI=[],bB;for(var bE=0,bz;(bz=bw[bE])!=null;bE++){if(typeof bz==="number"){bz+=""}if(!bz){continue}if(typeof bz==="string"){if(!W.test(bz)){bz=by.createTextNode(bz)}else{bz=bz.replace(R,"<$1>");var bK=(d.exec(bz)||["",""])[1].toLowerCase(),bx=ax[bK]||ax._default,bD=bx[0],bv=by.createElement("div");if(by===av){ac.appendChild(bv)}else{a(by).appendChild(bv)}bv.innerHTML=bx[1]+bz+bx[2];while(bD--){bv=bv.lastChild}if(!b.support.tbody){var e=w.test(bz),bC=bK==="table"&&!e?bv.firstChild&&bv.firstChild.childNodes:bx[1]===""&&!e?bv.childNodes:[];for(bB=bC.length-1;bB>=0;--bB){if(b.nodeName(bC[bB],"tbody")&&!bC[bB].childNodes.length){bC[bB].parentNode.removeChild(bC[bB])}}}if(!b.support.leadingWhitespace&&ar.test(bz)){bv.insertBefore(by.createTextNode(ar.exec(bz)[0]),bv.firstChild)}bz=bv.childNodes}}var bG;if(!b.support.appendChecked){if(bz[0]&&typeof(bG=bz.length)==="number"){for(bB=0;bB=0){return bx+"px"}}else{return bx}}}});if(!b.support.opacity){b.cssHooks.opacity={get:function(bv,e){return au.test((e&&bv.currentStyle?bv.currentStyle.filter:bv.style.filter)||"")?(parseFloat(RegExp.$1)/100)+"":e?"1":""},set:function(by,bz){var bx=by.style,bv=by.currentStyle,e=b.isNumeric(bz)?"alpha(opacity="+bz*100+")":"",bw=bv&&bv.filter||bx.filter||"";bx.zoom=1;if(bz>=1&&b.trim(bw.replace(ak,""))===""){bx.removeAttribute("filter");if(bv&&!bv.filter){return}}bx.filter=ak.test(bw)?bw.replace(ak,e):bw+" "+e}}}b(function(){if(!b.support.reliableMarginRight){b.cssHooks.marginRight={get:function(bw,bv){var e;b.swap(bw,{display:"inline-block"},function(){if(bv){e=Z(bw,"margin-right","marginRight")}else{e=bw.style.marginRight}});return e}}}});if(av.defaultView&&av.defaultView.getComputedStyle){aI=function(by,bw){var bv,bx,e;bw=bw.replace(z,"-$1").toLowerCase();if((bx=by.ownerDocument.defaultView)&&(e=bx.getComputedStyle(by,null))){bv=e.getPropertyValue(bw);if(bv===""&&!b.contains(by.ownerDocument.documentElement,by)){bv=b.style(by,bw)}}return bv}}if(av.documentElement.currentStyle){aX=function(bz,bw){var bA,e,by,bv=bz.currentStyle&&bz.currentStyle[bw],bx=bz.style;if(bv===null&&bx&&(by=bx[bw])){bv=by}if(!bc.test(bv)&&bn.test(bv)){bA=bx.left;e=bz.runtimeStyle&&bz.runtimeStyle.left;if(e){bz.runtimeStyle.left=bz.currentStyle.left}bx.left=bw==="fontSize"?"1em":(bv||0);bv=bx.pixelLeft+"px";bx.left=bA;if(e){bz.runtimeStyle.left=e}}return bv===""?"auto":bv}}Z=aI||aX;function p(by,bw,bv){var bA=bw==="width"?by.offsetWidth:by.offsetHeight,bz=bw==="width"?an:a1,bx=0,e=bz.length; +if(bA>0){if(bv!=="border"){for(;bx)<[^<]*)*<\/script>/gi,q=/^(?:select|textarea)/i,h=/\s+/,br=/([?&])_=[^&]*/,K=/^([\w\+\.\-]+:)(?:\/\/([^\/?#:]*)(?::(\d+))?)?/,A=b.fn.load,aa={},r={},aE,s,aV=["*/"]+["*"];try{aE=bl.href}catch(aw){aE=av.createElement("a");aE.href="";aE=aE.href}s=K.exec(aE.toLowerCase())||[];function f(e){return function(by,bA){if(typeof by!=="string"){bA=by;by="*"}if(b.isFunction(bA)){var bx=by.toLowerCase().split(h),bw=0,bz=bx.length,bv,bB,bC;for(;bw=0){var e=bw.slice(by,bw.length);bw=bw.slice(0,by)}var bx="GET";if(bz){if(b.isFunction(bz)){bA=bz;bz=L}else{if(typeof bz==="object"){bz=b.param(bz,b.ajaxSettings.traditional);bx="POST"}}}var bv=this;b.ajax({url:bw,type:bx,dataType:"html",data:bz,complete:function(bC,bB,bD){bD=bC.responseText;if(bC.isResolved()){bC.done(function(bE){bD=bE});bv.html(e?b("
").append(bD.replace(a6,"")).find(e):bD)}if(bA){bv.each(bA,[bD,bB,bC])}}});return this},serialize:function(){return b.param(this.serializeArray())},serializeArray:function(){return this.map(function(){return this.elements?b.makeArray(this.elements):this}).filter(function(){return this.name&&!this.disabled&&(this.checked||q.test(this.nodeName)||aZ.test(this.type))}).map(function(e,bv){var bw=b(this).val();return bw==null?null:b.isArray(bw)?b.map(bw,function(by,bx){return{name:bv.name,value:by.replace(bs,"\r\n")}}):{name:bv.name,value:bw.replace(bs,"\r\n")}}).get()}});b.each("ajaxStart ajaxStop ajaxComplete ajaxError ajaxSuccess ajaxSend".split(" "),function(e,bv){b.fn[bv]=function(bw){return this.on(bv,bw)}});b.each(["get","post"],function(e,bv){b[bv]=function(bw,by,bz,bx){if(b.isFunction(by)){bx=bx||bz;bz=by;by=L}return b.ajax({type:bv,url:bw,data:by,success:bz,dataType:bx})}});b.extend({getScript:function(e,bv){return b.get(e,L,bv,"script")},getJSON:function(e,bv,bw){return b.get(e,bv,bw,"json")},ajaxSetup:function(bv,e){if(e){am(bv,b.ajaxSettings)}else{e=bv;bv=b.ajaxSettings}am(bv,e);return bv},ajaxSettings:{url:aE,isLocal:aM.test(s[1]),global:true,type:"GET",contentType:"application/x-www-form-urlencoded",processData:true,async:true,accepts:{xml:"application/xml, text/xml",html:"text/html",text:"text/plain",json:"application/json, text/javascript","*":aV},contents:{xml:/xml/,html:/html/,json:/json/},responseFields:{xml:"responseXML",text:"responseText"},converters:{"* text":bb.String,"text html":true,"text json":b.parseJSON,"text xml":b.parseXML},flatOptions:{context:true,url:true}},ajaxPrefilter:f(aa),ajaxTransport:f(r),ajax:function(bz,bx){if(typeof bz==="object"){bx=bz;bz=L}bx=bx||{};var bD=b.ajaxSetup({},bx),bS=bD.context||bD,bG=bS!==bD&&(bS.nodeType||bS instanceof b)?b(bS):b.event,bR=b.Deferred(),bN=b.Callbacks("once memory"),bB=bD.statusCode||{},bC,bH={},bO={},bQ,by,bL,bE,bI,bA=0,bw,bK,bJ={readyState:0,setRequestHeader:function(bT,bU){if(!bA){var e=bT.toLowerCase();bT=bO[e]=bO[e]||bT;bH[bT]=bU}return this},getAllResponseHeaders:function(){return bA===2?bQ:null},getResponseHeader:function(bT){var e;if(bA===2){if(!by){by={};while((e=aD.exec(bQ))){by[e[1].toLowerCase()]=e[2]}}e=by[bT.toLowerCase()]}return e===L?null:e},overrideMimeType:function(e){if(!bA){bD.mimeType=e}return this},abort:function(e){e=e||"abort";if(bL){bL.abort(e)}bF(0,e);return this}};function bF(bZ,bU,b0,bW){if(bA===2){return}bA=2;if(bE){clearTimeout(bE)}bL=L;bQ=bW||"";bJ.readyState=bZ>0?4:0;var bT,b4,b3,bX=bU,bY=b0?bj(bD,bJ,b0):L,bV,b2;if(bZ>=200&&bZ<300||bZ===304){if(bD.ifModified){if((bV=bJ.getResponseHeader("Last-Modified"))){b.lastModified[bC]=bV}if((b2=bJ.getResponseHeader("Etag"))){b.etag[bC]=b2}}if(bZ===304){bX="notmodified";bT=true}else{try{b4=G(bD,bY);bX="success";bT=true}catch(b1){bX="parsererror";b3=b1}}}else{b3=bX;if(!bX||bZ){bX="error";if(bZ<0){bZ=0}}}bJ.status=bZ;bJ.statusText=""+(bU||bX);if(bT){bR.resolveWith(bS,[b4,bX,bJ])}else{bR.rejectWith(bS,[bJ,bX,b3])}bJ.statusCode(bB);bB=L;if(bw){bG.trigger("ajax"+(bT?"Success":"Error"),[bJ,bD,bT?b4:b3])}bN.fireWith(bS,[bJ,bX]);if(bw){bG.trigger("ajaxComplete",[bJ,bD]);if(!(--b.active)){b.event.trigger("ajaxStop")}}}bR.promise(bJ);bJ.success=bJ.done;bJ.error=bJ.fail;bJ.complete=bN.add;bJ.statusCode=function(bT){if(bT){var e;if(bA<2){for(e in bT){bB[e]=[bB[e],bT[e]]}}else{e=bT[bJ.status];bJ.then(e,e)}}return this};bD.url=((bz||bD.url)+"").replace(bq,"").replace(c,s[1]+"//");bD.dataTypes=b.trim(bD.dataType||"*").toLowerCase().split(h);if(bD.crossDomain==null){bI=K.exec(bD.url.toLowerCase());bD.crossDomain=!!(bI&&(bI[1]!=s[1]||bI[2]!=s[2]||(bI[3]||(bI[1]==="http:"?80:443))!=(s[3]||(s[1]==="http:"?80:443))))}if(bD.data&&bD.processData&&typeof bD.data!=="string"){bD.data=b.param(bD.data,bD.traditional)}aW(aa,bD,bx,bJ);if(bA===2){return false}bw=bD.global;bD.type=bD.type.toUpperCase();bD.hasContent=!aQ.test(bD.type);if(bw&&b.active++===0){b.event.trigger("ajaxStart")}if(!bD.hasContent){if(bD.data){bD.url+=(M.test(bD.url)?"&":"?")+bD.data;delete bD.data}bC=bD.url;if(bD.cache===false){var bv=b.now(),bP=bD.url.replace(br,"$1_="+bv);bD.url=bP+((bP===bD.url)?(M.test(bD.url)?"&":"?")+"_="+bv:"")}}if(bD.data&&bD.hasContent&&bD.contentType!==false||bx.contentType){bJ.setRequestHeader("Content-Type",bD.contentType)}if(bD.ifModified){bC=bC||bD.url;if(b.lastModified[bC]){bJ.setRequestHeader("If-Modified-Since",b.lastModified[bC])}if(b.etag[bC]){bJ.setRequestHeader("If-None-Match",b.etag[bC])}}bJ.setRequestHeader("Accept",bD.dataTypes[0]&&bD.accepts[bD.dataTypes[0]]?bD.accepts[bD.dataTypes[0]]+(bD.dataTypes[0]!=="*"?", "+aV+"; q=0.01":""):bD.accepts["*"]);for(bK in bD.headers){bJ.setRequestHeader(bK,bD.headers[bK])}if(bD.beforeSend&&(bD.beforeSend.call(bS,bJ,bD)===false||bA===2)){bJ.abort();return false}for(bK in {success:1,error:1,complete:1}){bJ[bK](bD[bK])}bL=aW(r,bD,bx,bJ);if(!bL){bF(-1,"No Transport")}else{bJ.readyState=1;if(bw){bG.trigger("ajaxSend",[bJ,bD])}if(bD.async&&bD.timeout>0){bE=setTimeout(function(){bJ.abort("timeout")},bD.timeout)}try{bA=1;bL.send(bH,bF)}catch(bM){if(bA<2){bF(-1,bM)}else{throw bM}}}return bJ},param:function(e,bw){var bv=[],by=function(bz,bA){bA=b.isFunction(bA)?bA():bA;bv[bv.length]=encodeURIComponent(bz)+"="+encodeURIComponent(bA)};if(bw===L){bw=b.ajaxSettings.traditional}if(b.isArray(e)||(e.jquery&&!b.isPlainObject(e))){b.each(e,function(){by(this.name,this.value)})}else{for(var bx in e){v(bx,e[bx],bw,by)}}return bv.join("&").replace(k,"+")}});function v(bw,by,bv,bx){if(b.isArray(by)){b.each(by,function(bA,bz){if(bv||ap.test(bw)){bx(bw,bz)}else{v(bw+"["+(typeof bz==="object"||b.isArray(bz)?bA:"")+"]",bz,bv,bx)}})}else{if(!bv&&by!=null&&typeof by==="object"){for(var e in by){v(bw+"["+e+"]",by[e],bv,bx)}}else{bx(bw,by)}}}b.extend({active:0,lastModified:{},etag:{}});function bj(bD,bC,bz){var bv=bD.contents,bB=bD.dataTypes,bw=bD.responseFields,by,bA,bx,e;for(bA in bw){if(bA in bz){bC[bw[bA]]=bz[bA]}}while(bB[0]==="*"){bB.shift();if(by===L){by=bD.mimeType||bC.getResponseHeader("content-type")}}if(by){for(bA in bv){if(bv[bA]&&bv[bA].test(by)){bB.unshift(bA);break}}}if(bB[0] in bz){bx=bB[0]}else{for(bA in bz){if(!bB[0]||bD.converters[bA+" "+bB[0]]){bx=bA;break}if(!e){e=bA}}bx=bx||e}if(bx){if(bx!==bB[0]){bB.unshift(bx)}return bz[bx]}}function G(bH,bz){if(bH.dataFilter){bz=bH.dataFilter(bz,bH.dataType)}var bD=bH.dataTypes,bG={},bA,bE,bw=bD.length,bB,bC=bD[0],bx,by,bF,bv,e;for(bA=1;bA=bw.duration+this.startTime){this.now=this.end;this.pos=this.state=1;this.update();bw.animatedProperties[this.prop]=true;for(bA in bw.animatedProperties){if(bw.animatedProperties[bA]!==true){e=false}}if(e){if(bw.overflow!=null&&!b.support.shrinkWrapBlocks){b.each(["","X","Y"],function(bC,bD){bz.style["overflow"+bD]=bw.overflow[bC]})}if(bw.hide){b(bz).hide()}if(bw.hide||bw.show){for(bA in bw.animatedProperties){b.style(bz,bA,bw.orig[bA]);b.removeData(bz,"fxshow"+bA,true);b.removeData(bz,"toggle"+bA,true)}}bv=bw.complete;if(bv){bw.complete=false;bv.call(bz)}}return false}else{if(bw.duration==Infinity){this.now=bx}else{bB=bx-this.startTime;this.state=bB/bw.duration;this.pos=b.easing[bw.animatedProperties[this.prop]](this.state,bB,0,1,bw.duration);this.now=this.start+((this.end-this.start)*this.pos)}this.update()}return true}};b.extend(b.fx,{tick:function(){var bw,bv=b.timers,e=0;for(;e").appendTo(e),bw=bv.css("display");bv.remove();if(bw==="none"||bw===""){if(!a8){a8=av.createElement("iframe");a8.frameBorder=a8.width=a8.height=0}e.appendChild(a8);if(!m||!a8.createElement){m=(a8.contentWindow||a8.contentDocument).document;m.write((av.compatMode==="CSS1Compat"?"":"")+"");m.close()}bv=m.createElement(bx);m.body.appendChild(bv);bw=b.css(bv,"display");e.removeChild(a8)}Q[bx]=bw}return Q[bx]}var V=/^t(?:able|d|h)$/i,ad=/^(?:body|html)$/i;if("getBoundingClientRect" in av.documentElement){b.fn.offset=function(bI){var by=this[0],bB;if(bI){return this.each(function(e){b.offset.setOffset(this,bI,e)})}if(!by||!by.ownerDocument){return null}if(by===by.ownerDocument.body){return b.offset.bodyOffset(by)}try{bB=by.getBoundingClientRect()}catch(bF){}var bH=by.ownerDocument,bw=bH.documentElement;if(!bB||!b.contains(bw,by)){return bB?{top:bB.top,left:bB.left}:{top:0,left:0}}var bC=bH.body,bD=aK(bH),bA=bw.clientTop||bC.clientTop||0,bE=bw.clientLeft||bC.clientLeft||0,bv=bD.pageYOffset||b.support.boxModel&&bw.scrollTop||bC.scrollTop,bz=bD.pageXOffset||b.support.boxModel&&bw.scrollLeft||bC.scrollLeft,bG=bB.top+bv-bA,bx=bB.left+bz-bE;return{top:bG,left:bx}}}else{b.fn.offset=function(bF){var bz=this[0];if(bF){return this.each(function(bG){b.offset.setOffset(this,bF,bG)})}if(!bz||!bz.ownerDocument){return null}if(bz===bz.ownerDocument.body){return b.offset.bodyOffset(bz)}var bC,bw=bz.offsetParent,bv=bz,bE=bz.ownerDocument,bx=bE.documentElement,bA=bE.body,bB=bE.defaultView,e=bB?bB.getComputedStyle(bz,null):bz.currentStyle,bD=bz.offsetTop,by=bz.offsetLeft;while((bz=bz.parentNode)&&bz!==bA&&bz!==bx){if(b.support.fixedPosition&&e.position==="fixed"){break}bC=bB?bB.getComputedStyle(bz,null):bz.currentStyle;bD-=bz.scrollTop;by-=bz.scrollLeft;if(bz===bw){bD+=bz.offsetTop;by+=bz.offsetLeft;if(b.support.doesNotAddBorder&&!(b.support.doesAddBorderForTableAndCells&&V.test(bz.nodeName))){bD+=parseFloat(bC.borderTopWidth)||0;by+=parseFloat(bC.borderLeftWidth)||0}bv=bw;bw=bz.offsetParent}if(b.support.subtractsBorderForOverflowNotVisible&&bC.overflow!=="visible"){bD+=parseFloat(bC.borderTopWidth)||0;by+=parseFloat(bC.borderLeftWidth)||0}e=bC}if(e.position==="relative"||e.position==="static"){bD+=bA.offsetTop;by+=bA.offsetLeft}if(b.support.fixedPosition&&e.position==="fixed"){bD+=Math.max(bx.scrollTop,bA.scrollTop);by+=Math.max(bx.scrollLeft,bA.scrollLeft)}return{top:bD,left:by}}}b.offset={bodyOffset:function(e){var bw=e.offsetTop,bv=e.offsetLeft;if(b.support.doesNotIncludeMarginInBodyOffset){bw+=parseFloat(b.css(e,"marginTop"))||0;bv+=parseFloat(b.css(e,"marginLeft"))||0}return{top:bw,left:bv}},setOffset:function(bx,bG,bA){var bB=b.css(bx,"position");if(bB==="static"){bx.style.position="relative"}var bz=b(bx),bv=bz.offset(),e=b.css(bx,"top"),bE=b.css(bx,"left"),bF=(bB==="absolute"||bB==="fixed")&&b.inArray("auto",[e,bE])>-1,bD={},bC={},bw,by;if(bF){bC=bz.position();bw=bC.top;by=bC.left}else{bw=parseFloat(e)||0;by=parseFloat(bE)||0}if(b.isFunction(bG)){bG=bG.call(bx,bA,bv)}if(bG.top!=null){bD.top=(bG.top-bv.top)+bw}if(bG.left!=null){bD.left=(bG.left-bv.left)+by}if("using" in bG){bG.using.call(bx,bD)}else{bz.css(bD)}}};b.fn.extend({position:function(){if(!this[0]){return null}var bw=this[0],bv=this.offsetParent(),bx=this.offset(),e=ad.test(bv[0].nodeName)?{top:0,left:0}:bv.offset();bx.top-=parseFloat(b.css(bw,"marginTop"))||0;bx.left-=parseFloat(b.css(bw,"marginLeft"))||0;e.top+=parseFloat(b.css(bv[0],"borderTopWidth"))||0;e.left+=parseFloat(b.css(bv[0],"borderLeftWidth"))||0;return{top:bx.top-e.top,left:bx.left-e.left}},offsetParent:function(){return this.map(function(){var e=this.offsetParent||av.body;while(e&&(!ad.test(e.nodeName)&&b.css(e,"position")==="static")){e=e.offsetParent}return e})}});b.each(["Left","Top"],function(bv,e){var bw="scroll"+e;b.fn[bw]=function(bz){var bx,by;if(bz===L){bx=this[0];if(!bx){return null}by=aK(bx);return by?("pageXOffset" in by)?by[bv?"pageYOffset":"pageXOffset"]:b.support.boxModel&&by.document.documentElement[bw]||by.document.body[bw]:bx[bw]}return this.each(function(){by=aK(this);if(by){by.scrollTo(!bv?bz:b(by).scrollLeft(),bv?bz:b(by).scrollTop())}else{this[bw]=bz}})}});function aK(e){return b.isWindow(e)?e:e.nodeType===9?e.defaultView||e.parentWindow:false}b.each(["Height","Width"],function(bv,e){var bw=e.toLowerCase();b.fn["inner"+e]=function(){var bx=this[0];return bx?bx.style?parseFloat(b.css(bx,bw,"padding")):this[bw]():null};b.fn["outer"+e]=function(by){var bx=this[0];return bx?bx.style?parseFloat(b.css(bx,bw,by?"margin":"border")):this[bw]():null};b.fn[bw]=function(bz){var bA=this[0];if(!bA){return bz==null?null:this}if(b.isFunction(bz)){return this.each(function(bE){var bD=b(this);bD[bw](bz.call(this,bE,bD[bw]()))})}if(b.isWindow(bA)){var bB=bA.document.documentElement["client"+e],bx=bA.document.body;return bA.document.compatMode==="CSS1Compat"&&bB||bx&&bx["client"+e]||bB}else{if(bA.nodeType===9){return Math.max(bA.documentElement["client"+e],bA.body["scroll"+e],bA.documentElement["scroll"+e],bA.body["offset"+e],bA.documentElement["offset"+e])}else{if(bz===L){var bC=b.css(bA,bw),by=parseFloat(bC);return b.isNumeric(by)?by:bC}else{return this.css(bw,typeof bz==="string"?bz:bz+"px")}}}}});bb.jQuery=bb.$=b;if(typeof define==="function"&&define.amd&&define.amd.jQuery){define("jquery",[],function(){return b +})}})(window); +/*! + PowerTip - v1.2.0 - 2013-04-03 + http://stevenbenner.github.com/jquery-powertip/ + Copyright (c) 2013 Steven Benner (http://stevenbenner.com/). + Released under MIT license. + https://raw.github.com/stevenbenner/jquery-powertip/master/LICENSE.txt +*/ +(function(a){if(typeof define==="function"&&define.amd){define(["jquery"],a)}else{a(jQuery)}}(function(k){var A=k(document),s=k(window),w=k("body");var n="displayController",e="hasActiveHover",d="forcedOpen",u="hasMouseMove",f="mouseOnToPopup",g="originalTitle",y="powertip",o="powertipjq",l="powertiptarget",E=180/Math.PI;var c={isTipOpen:false,isFixedTipOpen:false,isClosing:false,tipOpenImminent:false,activeHover:null,currentX:0,currentY:0,previousX:0,previousY:0,desyncTimeout:null,mouseTrackingActive:false,delayInProgress:false,windowWidth:0,windowHeight:0,scrollTop:0,scrollLeft:0};var p={none:0,top:1,bottom:2,left:4,right:8};k.fn.powerTip=function(F,N){if(!this.length){return this}if(k.type(F)==="string"&&k.powerTip[F]){return k.powerTip[F].call(this,this,N)}var O=k.extend({},k.fn.powerTip.defaults,F),G=new x(O);h();this.each(function M(){var R=k(this),Q=R.data(y),P=R.data(o),T=R.data(l),S;if(R.data(n)){k.powerTip.destroy(R)}S=R.attr("title");if(!Q&&!T&&!P&&S){R.data(y,S);R.data(g,S);R.removeAttr("title")}R.data(n,new t(R,O,G))});if(!O.manual){this.on({"mouseenter.powertip":function J(P){k.powerTip.show(this,P)},"mouseleave.powertip":function L(){k.powerTip.hide(this)},"focus.powertip":function K(){k.powerTip.show(this)},"blur.powertip":function H(){k.powerTip.hide(this,true)},"keydown.powertip":function I(P){if(P.keyCode===27){k.powerTip.hide(this,true)}}})}return this};k.fn.powerTip.defaults={fadeInTime:200,fadeOutTime:100,followMouse:false,popupId:"powerTip",intentSensitivity:7,intentPollInterval:100,closeDelay:100,placement:"n",smartPlacement:false,offset:10,mouseOnToPopup:false,manual:false};k.fn.powerTip.smartPlacementLists={n:["n","ne","nw","s"],e:["e","ne","se","w","nw","sw","n","s","e"],s:["s","se","sw","n"],w:["w","nw","sw","e","ne","se","n","s","w"],nw:["nw","w","sw","n","s","se","nw"],ne:["ne","e","se","n","s","sw","ne"],sw:["sw","w","nw","s","n","ne","sw"],se:["se","e","ne","s","n","nw","se"],"nw-alt":["nw-alt","n","ne-alt","sw-alt","s","se-alt","w","e"],"ne-alt":["ne-alt","n","nw-alt","se-alt","s","sw-alt","e","w"],"sw-alt":["sw-alt","s","se-alt","nw-alt","n","ne-alt","w","e"],"se-alt":["se-alt","s","sw-alt","ne-alt","n","nw-alt","e","w"]};k.powerTip={show:function z(F,G){if(G){i(G);c.previousX=G.pageX;c.previousY=G.pageY;k(F).data(n).show()}else{k(F).first().data(n).show(true,true)}return F},reposition:function r(F){k(F).first().data(n).resetPosition();return F},hide:function D(G,F){if(G){k(G).first().data(n).hide(F)}else{if(c.activeHover){c.activeHover.data(n).hide(true)}}return G},destroy:function C(G){k(G).off(".powertip").each(function F(){var I=k(this),H=[g,n,e,d];if(I.data(g)){I.attr("title",I.data(g));H.push(y)}I.removeData(H)});return G}};k.powerTip.showTip=k.powerTip.show;k.powerTip.closeTip=k.powerTip.hide;function b(){var F=this;F.top="auto";F.left="auto";F.right="auto";F.bottom="auto";F.set=function(H,G){if(k.isNumeric(G)){F[H]=Math.round(G)}}}function t(K,N,F){var J=null;function L(P,Q){M();if(!K.data(e)){if(!P){c.tipOpenImminent=true;J=setTimeout(function O(){J=null;I()},N.intentPollInterval)}else{if(Q){K.data(d,true)}F.showTip(K)}}}function G(P){M();c.tipOpenImminent=false;if(K.data(e)){K.data(d,false);if(!P){c.delayInProgress=true;J=setTimeout(function O(){J=null;F.hideTip(K);c.delayInProgress=false},N.closeDelay)}else{F.hideTip(K)}}}function I(){var Q=Math.abs(c.previousX-c.currentX),O=Math.abs(c.previousY-c.currentY),P=Q+O;if(P",{id:Q.popupId});if(w.length===0){w=k("body")}w.append(O)}if(Q.followMouse){if(!O.data(u)){A.on("mousemove",M);s.on("scroll",M);O.data(u,true)}}if(Q.mouseOnToPopup){O.on({mouseenter:function L(){if(O.data(f)){if(c.activeHover){c.activeHover.data(n).cancel()}}},mouseleave:function N(){if(c.activeHover){c.activeHover.data(n).hide()}}})}function I(S){S.data(e,true);O.queue(function R(T){H(S);T()})}function H(S){var U;if(!S.data(e)){return}if(c.isTipOpen){if(!c.isClosing){K(c.activeHover)}O.delay(100).queue(function R(V){H(S);V()});return}S.trigger("powerTipPreRender");U=B(S);if(U){O.empty().append(U)}else{return}S.trigger("powerTipRender");c.activeHover=S;c.isTipOpen=true;O.data(f,Q.mouseOnToPopup);if(!Q.followMouse){G(S);c.isFixedTipOpen=true}else{M()}O.fadeIn(Q.fadeInTime,function T(){if(!c.desyncTimeout){c.desyncTimeout=setInterval(J,500)}S.trigger("powerTipOpen")})}function K(R){c.isClosing=true;c.activeHover=null;c.isTipOpen=false;c.desyncTimeout=clearInterval(c.desyncTimeout);R.data(e,false);R.data(d,false);O.fadeOut(Q.fadeOutTime,function S(){var T=new b();c.isClosing=false;c.isFixedTipOpen=false;O.removeClass();T.set("top",c.currentY+Q.offset);T.set("left",c.currentX+Q.offset);O.css(T);R.trigger("powerTipClose")})}function M(){if(!c.isFixedTipOpen&&(c.isTipOpen||(c.tipOpenImminent&&O.data(u)))){var R=O.outerWidth(),V=O.outerHeight(),U=new b(),S,T;U.set("top",c.currentY+Q.offset);U.set("left",c.currentX+Q.offset);S=m(U,R,V);if(S!==p.none){T=a(S);if(T===1){if(S===p.right){U.set("left",c.windowWidth-R)}else{if(S===p.bottom){U.set("top",c.scrollTop+c.windowHeight-V)}}}else{U.set("left",c.currentX-R-Q.offset);U.set("top",c.currentY-V-Q.offset)}}O.css(U)}}function G(S){var R,T;if(Q.smartPlacement){R=k.fn.powerTip.smartPlacementLists[Q.placement];k.each(R,function(U,W){var V=m(F(S,W),O.outerWidth(),O.outerHeight());T=W;if(V===p.none){return false}})}else{F(S,Q.placement);T=Q.placement}O.addClass(T)}function F(U,T){var R=0,S,W,V=new b();V.set("top",0);V.set("left",0);O.css(V);do{S=O.outerWidth();W=O.outerHeight();V=P.compute(U,T,S,W,Q.offset);O.css(V)}while(++R<=5&&(S!==O.outerWidth()||W!==O.outerHeight()));return V}function J(){var R=false;if(c.isTipOpen&&!c.isClosing&&!c.delayInProgress){if(c.activeHover.data(e)===false||c.activeHover.is(":disabled")){R=true}else{if(!v(c.activeHover)&&!c.activeHover.is(":focus")&&!c.activeHover.data(d)){if(O.data(f)){if(!v(O)){R=true}}else{R=true}}}if(R){K(c.activeHover)}}}this.showTip=I;this.hideTip=K;this.resetPosition=G}function q(F){return window.SVGElement&&F[0] instanceof SVGElement}function h(){if(!c.mouseTrackingActive){c.mouseTrackingActive=true;k(function H(){c.scrollLeft=s.scrollLeft();c.scrollTop=s.scrollTop();c.windowWidth=s.width();c.windowHeight=s.height()});A.on("mousemove",i);s.on({resize:function G(){c.windowWidth=s.width();c.windowHeight=s.height()},scroll:function F(){var I=s.scrollLeft(),J=s.scrollTop();if(I!==c.scrollLeft){c.currentX+=I-c.scrollLeft;c.scrollLeft=I}if(J!==c.scrollTop){c.currentY+=J-c.scrollTop;c.scrollTop=J}}})}}function i(F){c.currentX=F.pageX;c.currentY=F.pageY}function v(F){var H=F.offset(),J=F[0].getBoundingClientRect(),I=J.right-J.left,G=J.bottom-J.top;return c.currentX>=H.left&&c.currentX<=H.left+I&&c.currentY>=H.top&&c.currentY<=H.top+G}function B(I){var G=I.data(y),F=I.data(o),K=I.data(l),H,J;if(G){if(k.isFunction(G)){G=G.call(I[0])}J=G}else{if(F){if(k.isFunction(F)){F=F.call(I[0])}if(F.length>0){J=F.clone(true,true)}}else{if(K){H=k("#"+K);if(H.length>0){J=H.html()}}}}return J}function m(M,L,K){var G=c.scrollTop,J=c.scrollLeft,I=G+c.windowHeight,F=J+c.windowWidth,H=p.none;if(M.topI||Math.abs(M.bottom-c.windowHeight)>I){H|=p.bottom}if(M.leftF){H|=p.left}if(M.left+L>F||M.right + + + + + +pva2pva: documentation/mainpage.h Source File + + + + + + + + + +
+
+
+ + + + + +
+
pva2pva +  0 +
+
+ + + + + + + + + + +
+ +
+ + + +
+
+
mainpage.h
+
+
+
1 
+
+ + + + diff --git a/moncache_8cpp_source.html b/moncache_8cpp_source.html new file mode 100644 index 0000000..5738463 --- /dev/null +++ b/moncache_8cpp_source.html @@ -0,0 +1,484 @@ + + + + + + +pva2pva: p2pApp/moncache.cpp Source File + + + + + + + + + +
+
+ + + + + + +
+
pva2pva +  1.4.1 +
+
+
+ + + + + + + + + +
+ +
+ + +
+
+
+
moncache.cpp
+
+
+
1 
+
2 #include <epicsAtomic.h>
+
3 #include <errlog.h>
+
4 
+
5 #include <epicsMutex.h>
+
6 #include <epicsTimer.h>
+
7 
+
8 #include <pv/pvAccess.h>
+
9 
+
10 #define epicsExportSharedSymbols
+
11 #include "helper.h"
+
12 #include "pva2pva.h"
+
13 #include "chancache.h"
+
14 
+
15 namespace pva = epics::pvAccess;
+
16 namespace pvd = epics::pvData;
+
17 
+
18 size_t MonitorCacheEntry::num_instances;
+
19 size_t MonitorUser::num_instances;
+
20 
+
21 namespace {
+
22 // fetch scalar value or default
+
23 template<typename T>
+
24 T getS(const pvd::PVStructurePtr& s, const char* name, T dft)
+
25 {
+
26  try{
+
27  return s->getSubFieldT<pvd::PVScalar>(name)->getAs<T>();
+
28  }catch(std::runtime_error& e){
+
29  return dft;
+
30  }
+
31 }
+
32 }
+
33 
+
34 MonitorCacheEntry::MonitorCacheEntry(ChannelCacheEntry *ent, const pvd::PVStructure::shared_pointer& pvr)
+
35  :chan(ent)
+
36  ,bufferSize(getS<pvd::uint32>(pvr, "record._options.queueSize", 2)) // should be same default as pvAccess, but not required
+
37  ,havedata(false)
+
38  ,done(false)
+
39  ,nwakeups(0)
+
40  ,nevents(0)
+
41 {
+
42  epicsAtomicIncrSizeT(&num_instances);
+
43 }
+
44 
+
45 MonitorCacheEntry::~MonitorCacheEntry()
+
46 {
+
47  pvd::Monitor::shared_pointer M;
+
48  M.swap(mon);
+
49  if(M) {
+
50  M->destroy();
+
51  }
+
52  epicsAtomicDecrSizeT(&num_instances);
+
53  const_cast<ChannelCacheEntry*&>(chan) = NULL; // spoil to fault use after free
+
54 }
+
55 
+
56 void
+
57 MonitorCacheEntry::monitorConnect(pvd::Status const & status,
+
58  pvd::MonitorPtr const & monitor,
+
59  pvd::StructureConstPtr const & structure)
+
60 {
+
61  interested_t::vector_type tonotify;
+
62  {
+
63  Guard G(mutex());
+
64  if(typedesc) {
+
65  // we shouldn't have to deal with monitor type change since we
+
66  // destroy() Monitors on Channel disconnect.
+
67  std::cerr<<"monitorConnect() w/ new type. Monitor has outlived it's connection.\n";
+
68  monitor->stop();
+
69  //TODO: unlisten()
+
70  return;
+
71  }
+
72  typedesc = structure;
+
73 
+
74  if(status.isSuccess()) {
+
75  startresult = monitor->start();
+
76  } else {
+
77  startresult = status;
+
78  }
+
79 
+
80  if(startresult.isSuccess()) {
+
81  lastelem.reset(new pvd::MonitorElement(pvd::getPVDataCreate()->createPVStructure(structure)));
+
82  }
+
83 
+
84  // set typedesc and startresult for futured MonitorUsers
+
85  // and copy snapshot of already interested MonitorUsers
+
86  tonotify = interested.lock_vector();
+
87  }
+
88 
+
89  if(!startresult.isSuccess())
+
90  std::cout<<"upstream monitor start() fails\n";
+
91 
+
92  shared_pointer self(weakref); // keeps us alive all MonitorUsers are destroy()ed
+
93 
+
94  for(interested_t::vector_type::const_iterator it = tonotify.begin(),
+
95  end = tonotify.end(); it!=end; ++it)
+
96  {
+
97  pvd::MonitorRequester::shared_pointer req((*it)->req);
+
98  if(req) {
+
99  req->monitorConnect(startresult, *it, structure);
+
100  }
+
101  }
+
102 }
+
103 
+
104 // notificaton from upstream client that its monitor queue has
+
105 // become not empty (transition from empty to not empty)
+
106 // will not be called again unless we completely empty the upstream queue.
+
107 // If we don't then it is our responsibly to schedule more poll().
+
108 // Note: this probably means this is a PVA client RX thread.
+
109 void
+
110 MonitorCacheEntry::monitorEvent(pvd::MonitorPtr const & monitor)
+
111 {
+
112  /* PVA is being tricky, the Monitor* passed to monitorConnect()
+
113  * isn't the same one we see here!
+
114  * The original was a ChannelMonitorImpl, we now see a MonitorStrategyQueue
+
115  * owned by the original, which delegates deserialization and accumulation
+
116  * of deltas into complete events for us.
+
117  * However, we don't want to keep the MonitorStrategyQueue as it's
+
118  * destroy() method is a no-op!
+
119  */
+
120 
+
121  epicsAtomicIncrSizeT(&nwakeups);
+
122 
+
123  shared_pointer self(weakref); // keeps us alive in case all MonitorUsers are destroy()ed
+
124 
+
125  pva::MonitorElementPtr update;
+
126 
+
127  typedef std::vector<MonitorUser::shared_pointer> dsnotify_t;
+
128  dsnotify_t dsnotify;
+
129 
+
130  {
+
131  Guard G(mutex()); // MCE and MU guarded by the same mutex
+
132  if(!havedata)
+
133  havedata = true;
+
134 
+
135  //TODO: flow control, if all MU buffers are full, break before poll()==NULL
+
136  while((update=monitor->poll()))
+
137  {
+
138  epicsAtomicIncrSizeT(&nevents);
+
139 
+
140  lastelem->pvStructurePtr->copyUnchecked(*update->pvStructurePtr,
+
141  *update->changedBitSet);
+
142  *lastelem->changedBitSet = *update->changedBitSet;
+
143  *lastelem->overrunBitSet = *update->overrunBitSet;
+
144  monitor->release(update);
+
145  update.reset();
+
146 
+
147  interested_t::iterator IIT(interested); // recursively locks interested.mutex() (assumes this->mutex() is interestd.mutex())
+
148  for(interested_t::value_pointer pusr = IIT.next(); pusr; pusr = IIT.next())
+
149  {
+
150  MonitorUser *usr = pusr.get();
+
151 
+
152  {
+
153  Guard G(usr->mutex());
+
154  if(usr->initial)
+
155  continue; // no start() yet
+
156  // TODO: track overflow when !running (after stop())?
+
157  if(!usr->running || usr->empty.empty()) {
+
158  usr->inoverflow = true;
+
159 
+
160  /* overrun |= lastelem->overrun // upstream overflows
+
161  * overrun |= changed & lastelem->changed // downstream overflows
+
162  * changed |= lastelem->changed // accumulate changes
+
163  */
+
164 
+
165  *usr->overflowElement->overrunBitSet |= *lastelem->overrunBitSet;
+
166  usr->overflowElement->overrunBitSet->or_and(*usr->overflowElement->changedBitSet,
+
167  *lastelem->changedBitSet);
+
168  *usr->overflowElement->changedBitSet |= *lastelem->changedBitSet;
+
169 
+
170  usr->overflowElement->pvStructurePtr->copyUnchecked(*lastelem->pvStructurePtr,
+
171  *lastelem->changedBitSet);
+
172 
+
173  epicsAtomicIncrSizeT(&usr->ndropped);
+
174  continue;
+
175  }
+
176  // we only come out of overflow when downstream release()s an element to us
+
177  // empty.empty() does not imply inoverflow,
+
178  // however inoverflow does imply empty.empty()
+
179  assert(!usr->inoverflow);
+
180 
+
181  if(usr->filled.empty())
+
182  dsnotify.push_back(pusr);
+
183 
+
184  pvd::MonitorElementPtr elem(usr->empty.front());
+
185 
+
186  *elem->overrunBitSet = *lastelem->overrunBitSet;
+
187  *elem->changedBitSet = *lastelem->changedBitSet;
+
188  // Note: can't use changed mask to optimize this copy since we don't know
+
189  // the state of the free element
+
190  elem->pvStructurePtr->copyUnchecked(*lastelem->pvStructurePtr);
+
191 
+
192  usr->filled.push_back(elem);
+
193  usr->empty.pop_front();
+
194 
+
195  epicsAtomicIncrSizeT(&usr->nevents);
+
196  }
+
197  }
+
198  }
+
199  }
+
200 
+
201  // unlock here, race w/ stop(), unlisten()?
+
202  //TODO: notify from worker thread
+
203 
+
204  FOREACH(dsnotify_t::iterator, it,end,dsnotify) {
+
205  MonitorUser *usr = (*it).get();
+
206  pvd::MonitorRequester::shared_pointer req(usr->req);
+
207  epicsAtomicIncrSizeT(&usr->nwakeups);
+
208  req->monitorEvent(*it); // notify when first item added to empty queue, may call poll(), release(), and others
+
209  }
+
210 }
+
211 
+
212 // notificaton from upstream client that no more monitor updates will come, ever
+
213 void
+
214 MonitorCacheEntry::unlisten(pvd::MonitorPtr const & monitor)
+
215 {
+
216  pvd::Monitor::shared_pointer M;
+
217  interested_t::vector_type tonotify;
+
218  {
+
219  Guard G(mutex());
+
220  M.swap(mon);
+
221  tonotify = interested.lock_vector();
+
222  // assume that upstream won't call monitorEvent() again
+
223 
+
224  // cause future downstream start() to error
+
225  startresult = pvd::Status(pvd::Status::STATUSTYPE_ERROR, "upstream unlisten()");
+
226  }
+
227  if(M) {
+
228  M->destroy();
+
229  }
+
230  FOREACH(interested_t::vector_type::iterator, it, end, tonotify) {
+
231  MonitorUser *usr = it->get();
+
232  pvd::MonitorRequester::shared_pointer req(usr->req);
+
233  if(usr->inuse.empty()) // TODO: what about stopped?
+
234  req->unlisten(*it);
+
235  }
+
236 }
+
237 
+
238 std::string
+
239 MonitorCacheEntry::getRequesterName()
+
240 {
+
241  return "MonitorCacheEntry";
+
242 }
+
243 
+
244 MonitorUser::MonitorUser(const MonitorCacheEntry::shared_pointer &e)
+
245  :entry(e)
+
246  ,initial(true)
+
247  ,running(false)
+
248  ,inoverflow(false)
+
249  ,nevents(0)
+
250  ,ndropped(0)
+
251 {
+
252  epicsAtomicIncrSizeT(&num_instances);
+
253 }
+
254 
+
255 MonitorUser::~MonitorUser()
+
256 {
+
257  epicsAtomicDecrSizeT(&num_instances);
+
258 }
+
259 
+
260 // downstream server closes monitor
+
261 void
+
262 MonitorUser::destroy()
+
263 {
+
264  {
+
265  Guard G(mutex());
+
266  running = false;
+
267  }
+
268 }
+
269 
+
270 pvd::Status
+
271 MonitorUser::start()
+
272 {
+
273  pvd::MonitorRequester::shared_pointer req(this->req.lock());
+
274  if(!req)
+
275  return pvd::Status(pvd::Status::STATUSTYPE_FATAL, "already dead");
+
276 
+
277  bool doEvt = false;
+
278  {
+
279  Guard G(entry->mutex()); // MCE and MU have share a lock
+
280 
+
281  if(!entry->startresult.isSuccess())
+
282  return entry->startresult;
+
283 
+
284  pvd::PVStructurePtr lval;
+
285  if(entry->havedata)
+
286  lval = entry->lastelem->pvStructurePtr;
+
287  pvd::StructureConstPtr typedesc(entry->typedesc);
+
288 
+
289  if(initial) {
+
290  initial = false;
+
291 
+
292  empty.resize(entry->bufferSize);
+
293  pvd::PVDataCreatePtr fact(pvd::getPVDataCreate());
+
294  for(unsigned i=0; i<empty.size(); i++) {
+
295  empty[i].reset(new pvd::MonitorElement(fact->createPVStructure(typedesc)));
+
296  }
+
297 
+
298  // extra element to accumulate updates during overflow
+
299  overflowElement.reset(new pvd::MonitorElement(fact->createPVStructure(typedesc)));
+
300  }
+
301 
+
302  doEvt = filled.empty();
+
303 
+
304  if(lval && !empty.empty()) {
+
305  //already running, notify of initial element
+
306 
+
307  const pva::MonitorElementPtr& elem(empty.front());
+
308  elem->pvStructurePtr->copy(*lval);
+
309  elem->changedBitSet->set(0); // indicate all changed
+
310  elem->overrunBitSet->clear();
+
311  filled.push_back(elem);
+
312  empty.pop_front();
+
313  }
+
314 
+
315  doEvt &= !filled.empty();
+
316  running = true;
+
317  }
+
318  if(doEvt)
+
319  req->monitorEvent(shared_pointer(weakref)); // TODO: worker thread?
+
320  return pvd::Status();
+
321 }
+
322 
+
323 pvd::Status
+
324 MonitorUser::stop()
+
325 {
+
326  Guard G(mutex());
+
327  running = false;
+
328  return pvd::Status::Ok;
+
329 }
+
330 
+
331 pva::MonitorElementPtr
+
332 MonitorUser::poll()
+
333 {
+
334  Guard G(mutex());
+
335  pva::MonitorElementPtr ret;
+
336  if(!filled.empty()) {
+
337  ret = filled.front();
+
338  inuse.insert(ret); // track which ones are out for client use
+
339  filled.pop_front();
+
340  //TODO: track lost buffers w/ wrapped shared_ptr?
+
341  }
+
342  return ret;
+
343 }
+
344 
+
345 void
+
346 MonitorUser::release(pva::MonitorElementPtr const & monitorElement)
+
347 {
+
348  Guard G(mutex());
+
349  //TODO: ifdef DEBUG? (only track inuse when debugging?)
+
350  std::set<epics::pvData::MonitorElementPtr>::iterator it = inuse.find(monitorElement);
+
351  if(it!=inuse.end()) {
+
352  inuse.erase(it);
+
353 
+
354  if(inoverflow) { // leaving overflow condition
+
355 
+
356  // to avoid copy, enqueue the current overflowElement
+
357  // and replace it with the element being release()d
+
358 
+
359  filled.push_back(overflowElement);
+
360  overflowElement = monitorElement;
+
361  overflowElement->changedBitSet->clear();
+
362  overflowElement->overrunBitSet->clear();
+
363 
+
364  inoverflow = false;
+
365  } else {
+
366  // push_back empty element
+
367  empty.push_back(monitorElement);
+
368  }
+
369  } else {
+
370  // oh no, we've been given an element which we didn't give to downstream
+
371  //TODO: check empty and filled lists to see if this is one of ours, of from somewhere else
+
372  throw std::invalid_argument("Can't release MonitorElement not in use");
+
373  }
+
374  // TODO: pipeline window update?
+
375 }
+
376 
+
377 std::string
+
378 MonitorUser::getRequesterName()
+
379 {
+
380  return "MonitorCacheEntry";
+
381 }
+
epics::pvData::MonitorElement::shared_pointer lastelem
Definition: chancache.h:46
+
Definition: chancache.h:103
+
vector_type lock_vector() const
Definition: weakset.h:268
+ +
+ + + + diff --git a/nav_f.png b/nav_f.png new file mode 100644 index 0000000..72a58a5 Binary files /dev/null and b/nav_f.png differ diff --git a/nav_g.png b/nav_g.png new file mode 100644 index 0000000..9681f15 Binary files /dev/null and b/nav_g.png differ diff --git a/nav_h.png b/nav_h.png new file mode 100644 index 0000000..33389b1 Binary files /dev/null and b/nav_h.png differ diff --git a/open.png b/open.png new file mode 100644 index 0000000..30f75c7 Binary files /dev/null and b/open.png differ diff --git a/pages.html b/pages.html new file mode 100644 index 0000000..67afbea --- /dev/null +++ b/pages.html @@ -0,0 +1,97 @@ + + + + + + +pva2pva: Related Pages + + + + + + + + + +
+
+ + + + + + +
+
pva2pva +  1.4.1 +
+
+
+ + + + +
+ + + + +
+ +
+ +
+
+
Related Pages
+
+
+
Here is a list of all related documentation pages:
+
+ + + + diff --git a/pdb_8cpp_source.html b/pdb_8cpp_source.html new file mode 100644 index 0000000..ad247f1 --- /dev/null +++ b/pdb_8cpp_source.html @@ -0,0 +1,936 @@ + + + + + + +pva2pva: pdbApp/pdb.cpp Source File + + + + + + + + + +
+
+ + + + + + +
+
pva2pva +  1.4.1 +
+
+
+ + + + + + + + + +
+ +
+ + +
+
+
+
pdb.cpp
+
+
+
1 
+
2 #include <vector>
+
3 #include <utility>
+
4 
+
5 #include <errlog.h>
+
6 #include <epicsString.h>
+
7 #include <epicsAtomic.h>
+
8 
+
9 // printfs in this file will be redirected for capture
+
10 #include <epicsStdio.h>
+
11 
+
12 #include <dbAccess.h>
+
13 #include <dbChannel.h>
+
14 #include <dbStaticLib.h>
+
15 #include <dbNotify.h>
+
16 
+
17 #include <dbEvent.h>
+
18 
+
19 #include <pv/pvAccess.h>
+
20 #include <pv/configuration.h>
+
21 
+
22 #include "helper.h"
+
23 #include "pdbsingle.h"
+
24 #include "pvif.h"
+
25 #ifdef USE_MULTILOCK
+
26 # include "pdbgroup.h"
+
27 #endif
+
28 
+
29 #include <epicsExport.h>
+
30 
+
31 namespace pvd = epics::pvData;
+
32 namespace pva = epics::pvAccess;
+
33 
+
34 int PDBProviderDebug;
+
35 
+
36 namespace {
+
37 
+
38 struct Splitter {
+
39  const char sep, *cur, *end;
+
40  Splitter(const char *s, char sep)
+
41  :sep(sep), cur(s)
+
42  {
+
43  assert(s);
+
44  end = strchr(cur, sep);
+
45  }
+
46  bool operator!() const { return !cur; }
+
47  bool snip(std::string& ret) {
+
48  if(!cur) return false;
+
49  if(end) ret = std::string(cur, end-cur);
+
50  else ret = std::string(cur);
+
51  if(end) {
+
52  cur = end+1;
+
53  end = strchr(cur, sep);
+
54  } else {
+
55  cur = NULL;
+
56  }
+
57  return true;
+
58  }
+
59 };
+
60 
+
61 struct GroupMemberInfo {
+
62  GroupMemberInfo() :putorder(0) {}
+
63 
+
64  std::string pvname, // aka. name passed to dbChannelOpen()
+
65  pvfldname; // PVStructure sub-field
+
66  std::string structID; // ID to assign to sub-field
+
67  std::string type; // mapping type
+
68  typedef std::set<std::string> triggers_t;
+
69  triggers_t triggers; // names in GroupInfo::members_names which are post()d on events from pvfldname
+
70  int putorder;
+
71 
+
72  bool operator<(const GroupMemberInfo& o) const {
+
73  return putorder<o.putorder;
+
74  }
+
75 };
+
76 
+
77 struct GroupInfo {
+
78  GroupInfo(const std::string& name) : name(name),atomic(Unset),hastriggers(false) {}
+
79  std::string name, structID;
+
80 
+
81  typedef std::vector<GroupMemberInfo> members_t;
+
82  members_t members;
+
83 
+
84  typedef std::map<std::string, size_t> members_map_t;
+
85  members_map_t members_map;
+
86 
+
87  typedef std::set<std::string> triggers_set_t;
+
88  typedef std::map<std::string, triggers_set_t> triggers_t;
+
89  triggers_t triggers;
+
90 
+
91  enum tribool {Unset,True,False} atomic;
+
92  bool hastriggers;
+
93 };
+
94 
+
95 // Iterates all PDB records and gathers info() to construct PDB groups
+
96 struct PDBProcessor
+
97 {
+
98  typedef std::map<std::string, GroupInfo> groups_t;
+
99  groups_t groups;
+
100 
+
101  // validate trigger mappings and process into bit map form
+
102  void resolveTriggers()
+
103  {
+
104  FOREACH(groups_t::iterator, it, end, groups) { // for each group
+
105  GroupInfo& info = it->second;
+
106 
+
107  if(info.hastriggers) {
+
108  FOREACH(GroupInfo::triggers_t::iterator, it2, end2, info.triggers) { // for each trigger source
+
109  const std::string& src = it2->first;
+
110  GroupInfo::triggers_set_t& targets = it2->second;
+
111 
+
112  GroupInfo::members_map_t::iterator it2x = info.members_map.find(src);
+
113  if(it2x==info.members_map.end()) {
+
114  fprintf(stderr, "Error: Group \"%s\" defines triggers from non-existant field \"%s\"\n",
+
115  info.name.c_str(), src.c_str());
+
116  continue;
+
117  }
+
118  GroupMemberInfo& srcmem = info.members[it2x->second];
+
119 
+
120  if(PDBProviderDebug>2)
+
121  fprintf(stderr, " pdb trg '%s.%s' -> ",
+
122  info.name.c_str(), src.c_str());
+
123 
+
124  FOREACH(GroupInfo::triggers_set_t::const_iterator, it3, end3, targets) { // for each trigger target
+
125  const std::string& target = *it3;
+
126 
+
127  if(target=="*") {
+
128  for(size_t i=0; i<info.members.size(); i++) {
+
129  if(info.members[i].pvname.empty())
+
130  continue;
+
131  srcmem.triggers.insert(info.members[i].pvfldname);
+
132  if(PDBProviderDebug>2)
+
133  fprintf(stderr, "%s, ", info.members[i].pvfldname.c_str());
+
134  }
+
135 
+
136  } else {
+
137 
+
138  GroupInfo::members_map_t::iterator it3x = info.members_map.find(target);
+
139  if(it3x==info.members_map.end()) {
+
140  fprintf(stderr, "Error: Group \"%s\" defines triggers to non-existant field \"%s\"\n",
+
141  info.name.c_str(), target.c_str());
+
142  continue;
+
143  }
+
144  const GroupMemberInfo& targetmem = info.members[it3x->second];
+
145 
+
146  if(targetmem.pvname.empty()) {
+
147  if(PDBProviderDebug>2)
+
148  fprintf(stderr, "<ignore: %s>, ", targetmem.pvfldname.c_str());
+
149 
+
150  } else {
+
151  // and finally, update source BitSet
+
152  srcmem.triggers.insert(targetmem.pvfldname);
+
153  if(PDBProviderDebug>2)
+
154  fprintf(stderr, "%s, ", targetmem.pvfldname.c_str());
+
155  }
+
156  }
+
157  }
+
158 
+
159  if(PDBProviderDebug>2) fprintf(stderr, "\n");
+
160  }
+
161  } else {
+
162  if(PDBProviderDebug>1) fprintf(stderr, " pdb default triggers for '%s'\n", info.name.c_str());
+
163 
+
164  FOREACH(GroupInfo::members_t::iterator, it2, end2, info.members) {
+
165  GroupMemberInfo& mem = *it2;
+
166  if(mem.pvname.empty())
+
167  continue;
+
168 
+
169  mem.triggers.insert(mem.pvfldname); // default is self trigger
+
170  }
+
171  }
+
172  }
+
173  }
+
174 
+
175  PDBProcessor()
+
176  {
+
177 #ifdef USE_MULTILOCK
+
178  GroupConfig conf;
+
179 #endif
+
180 
+
181  // process info(Q:Group, ...)
+
182  for(pdbRecordIterator rec; !rec.done(); rec.next())
+
183  {
+
184  const char *json = rec.info("Q:group");
+
185  if(!json) continue;
+
186 #ifndef USE_MULTILOCK
+
187  static bool warned;
+
188  if(!warned) {
+
189  warned = true;
+
190  fprintf(stderr, "%s: ignoring info(Q:Group, ...\n", rec.name());
+
191  }
+
192 #endif
+
193  if(PDBProviderDebug>2) {
+
194  fprintf(stderr, "%s: info(Q:Group, ...\n", rec.name());
+
195  }
+
196 
+
197 #ifdef USE_MULTILOCK
+
198  try {
+
199  GroupConfig::parse(json, rec.name(), conf);
+
200  if(!conf.warning.empty())
+
201  fprintf(stderr, "%s: warning(s) from info(Q:group, ...\n%s", rec.name(), conf.warning.c_str());
+
202  }catch(std::exception& e){
+
203  fprintf(stderr, "%s: Error parsing info(\"Q:group\", ... : %s\n",
+
204  rec.record()->name, e.what());
+
205  }
+
206 #endif
+
207  }
+
208 
+
209  // process group definition files
+
210  for(PDBProvider::group_files_t::const_iterator it(PDBProvider::group_files.begin()), end(PDBProvider::group_files.end());
+
211  it != end; ++it)
+
212  {
+
213  std::ifstream jfile(it->c_str());
+
214  if(!jfile.is_open()) {
+
215  fprintf(stderr, "Error opening \"%s\"\n", it->c_str());
+
216  continue;
+
217  }
+
218 
+
219  std::vector<char> contents;
+
220  size_t pos=0u;
+
221  while(true) {
+
222  contents.resize(pos+1024u);
+
223  if(!jfile.read(&contents[pos], contents.size()-pos))
+
224  break;
+
225  pos += jfile.gcount();
+
226  }
+
227 
+
228  if(jfile.bad() || !jfile.eof()) {
+
229  fprintf(stderr, "Error reading \"%s\"\n", it->c_str());
+
230  continue;
+
231  }
+
232 
+
233  contents.push_back('\0');
+
234  const char *json = &contents[0];
+
235 
+
236  if(PDBProviderDebug>2) {
+
237  fprintf(stderr, "Process dbGroup file \"%s\"\n", it->c_str());
+
238  }
+
239 
+
240 #ifdef USE_MULTILOCK
+
241  try {
+
242  GroupConfig::parse(json, NULL, conf);
+
243  if(!conf.warning.empty())
+
244  fprintf(stderr, "warning(s) from dbGroup file \"%s\"\n%s", it->c_str(), conf.warning.c_str());
+
245  }catch(std::exception& e){
+
246  fprintf(stderr, "Error from dbGroup file \"%s\"\n%s", it->c_str(), e.what());
+
247  }
+
248 #endif
+
249  }
+
250 
+
251 #ifdef USE_MULTILOCK
+
252  for(GroupConfig::groups_t::const_iterator git=conf.groups.begin(), gend=conf.groups.end();
+
253  git!=gend; ++git)
+
254  {
+
255  const std::string& grpname = git->first;
+
256  const GroupConfig::Group& grp = git->second;
+
257  try {
+
258 
+
259  if(dbChannelTest(grpname.c_str())==0) {
+
260  fprintf(stderr, "%s : Error: Group name conflicts with record name. Ignoring...\n", grpname.c_str());
+
261  continue;
+
262  }
+
263 
+
264  groups_t::iterator it = groups.find(grpname);
+
265  if(it==groups.end()) {
+
266  // lazy creation of group
+
267  std::pair<groups_t::iterator, bool> ins(groups.insert(std::make_pair(grpname, GroupInfo(grpname))));
+
268  it = ins.first;
+
269  }
+
270  GroupInfo *curgroup = &it->second;
+
271 
+
272  if(!grp.id.empty())
+
273  curgroup->structID = grp.id;
+
274 
+
275  for(GroupConfig::Group::fields_t::const_iterator fit=grp.fields.begin(), fend=grp.fields.end();
+
276  fit!=fend; ++fit)
+
277  {
+
278  const std::string& fldname = fit->first;
+
279  const GroupConfig::Field& fld = fit->second;
+
280 
+
281  if(curgroup->members_map.find(fldname) != curgroup->members_map.end()) {
+
282  fprintf(stderr, "%s.%s Warning: ignoring duplicate mapping %s\n",
+
283  grpname.c_str(), fldname.c_str(),
+
284  fld.channel.c_str());
+
285  continue;
+
286  }
+
287 
+
288  curgroup->members.push_back(GroupMemberInfo());
+
289  GroupMemberInfo& info = curgroup->members.back();
+
290  info.pvname = fld.channel;
+
291  info.pvfldname = fldname;
+
292  info.structID = fld.id;
+
293  info.putorder = fld.putorder;
+
294  info.type = fld.type;
+
295  curgroup->members_map[fldname] = (size_t)-1; // placeholder see below
+
296 
+
297  if(PDBProviderDebug>2) {
+
298  fprintf(stderr, " pdb map '%s.%s' <-> '%s'\n",
+
299  curgroup->name.c_str(),
+
300  curgroup->members.back().pvfldname.c_str(),
+
301  curgroup->members.back().pvname.c_str());
+
302  }
+
303 
+
304  if(!fld.trigger.empty()) {
+
305  GroupInfo::triggers_t::iterator it = curgroup->triggers.find(fldname);
+
306  if(it==curgroup->triggers.end()) {
+
307  std::pair<GroupInfo::triggers_t::iterator, bool> ins(curgroup->triggers.insert(
+
308  std::make_pair(fldname, GroupInfo::triggers_set_t())));
+
309  it = ins.first;
+
310  }
+
311 
+
312  Splitter sep(fld.trigger.c_str(), ',');
+
313  std::string target;
+
314 
+
315  while(sep.snip(target)) {
+
316  curgroup->hastriggers = true;
+
317  it->second.insert(target);
+
318  }
+
319  }
+
320  }
+
321 
+
322  if(grp.atomic_set) {
+
323  GroupInfo::tribool V = grp.atomic ? GroupInfo::True : GroupInfo::False;
+
324 
+
325  if(curgroup->atomic!=GroupInfo::Unset && curgroup->atomic!=V)
+
326  fprintf(stderr, "%s Warning: pdb atomic setting inconsistent '%s'\n",
+
327  grpname.c_str(), curgroup->name.c_str());
+
328 
+
329  curgroup->atomic=V;
+
330 
+
331  if(PDBProviderDebug>2)
+
332  fprintf(stderr, " pdb atomic '%s' %s\n",
+
333  curgroup->name.c_str(), curgroup->atomic ? "YES" : "NO");
+
334  }
+
335 
+
336  }catch(std::exception& e){
+
337  fprintf(stderr, "Error processing Q:group \"%s\" : %s\n",
+
338  grpname.c_str(), e.what());
+
339  }
+
340  }
+
341 
+
342  // re-sort GroupInfo::members to ensure the shorter names appear first
+
343  // allows use of 'existing' PVIFBuilder on leaves.
+
344  for(groups_t::iterator it = groups.begin(), end = groups.end(); it!=end; ++it)
+
345  {
+
346  GroupInfo& info = it->second;
+
347  std::sort(info.members.begin(),
+
348  info.members.end());
+
349 
+
350  info.members_map.clear();
+
351 
+
352  for(size_t i=0, N=info.members.size(); i<N; i++)
+
353  {
+
354  info.members_map[info.members[i].pvfldname] = i;
+
355  }
+
356  }
+
357 
+
358  resolveTriggers();
+
359  // must not re-sort members after this point as resolveTriggers()
+
360  // has stored array indicies.
+
361 #endif
+
362  }
+
363 
+
364 };
+
365 }
+
366 
+
367 size_t PDBProvider::num_instances;
+
368 
+
369 std::list<std::string> PDBProvider::group_files;
+
370 
+
371 PDBProvider::PDBProvider(const epics::pvAccess::Configuration::const_shared_pointer &)
+
372 {
+
373  /* Long view
+
374  * 1. PDBProcessor collects info() tags and builds config of groups and group fields
+
375  * (including those w/o a dbChannel)
+
376  * 2. Build pvd::Structure and discard those w/o dbChannel
+
377  * 3. Build the lockers for the triggers of each group field
+
378  */
+
379  PDBProcessor proc;
+
380  pvd::FieldCreatePtr fcreate(pvd::getFieldCreate());
+
381  pvd::PVDataCreatePtr pvbuilder(pvd::getPVDataCreate());
+
382 
+
383  pvd::StructureConstPtr _options(fcreate->createFieldBuilder()
+
384  ->addNestedStructure("_options")
+
385  ->add("queueSize", pvd::pvUInt)
+
386  ->add("atomic", pvd::pvBoolean)
+
387  ->endNested()
+
388  ->createStructure());
+
389 
+
390 #ifdef USE_MULTILOCK
+
391  // assemble group PVD structure definitions and build dbLockers
+
392  FOREACH(PDBProcessor::groups_t::const_iterator, it, end, proc.groups)
+
393  {
+
394  const GroupInfo &info=it->second;
+
395  try{
+
396  if(persist_pv_map.find(info.name)!=persist_pv_map.end())
+
397  throw std::runtime_error("name already in used");
+
398 
+
399  PDBGroupPV::shared_pointer pv(new PDBGroupPV());
+
400  pv->weakself = pv;
+
401  pv->name = info.name;
+
402 
+
403  pv->pgatomic = info.atomic!=GroupInfo::False; // default true if Unset
+
404  pv->monatomic = info.hastriggers;
+
405 
+
406  // some gymnastics because Info isn't copyable
+
407  pvd::shared_vector<PDBGroupPV::Info> members;
+
408  typedef std::map<std::string, size_t> members_map_t;
+
409  members_map_t members_map;
+
410  {
+
411  size_t nchans = 0;
+
412  for(size_t i=0, N=info.members.size(); i<N; i++)
+
413  if(!info.members[i].pvname.empty())
+
414  nchans++;
+
415  pvd::shared_vector<PDBGroupPV::Info> temp(nchans);
+
416  members.swap(temp);
+
417  }
+
418 
+
419  std::vector<dbCommon*> records(members.size());
+
420 
+
421  pvd::FieldBuilderPtr builder(fcreate->createFieldBuilder());
+
422  builder = builder->add("record", _options);
+
423 
+
424  if(!info.structID.empty())
+
425  builder = builder->setId(info.structID);
+
426 
+
427  for(size_t i=0, J=0, N=info.members.size(); i<N; i++)
+
428  {
+
429  const GroupMemberInfo &mem = info.members[i];
+
430 
+
431  // parse down attachment point to build/traverse structure
+
432  FieldName parts(mem.pvfldname);
+
433 
+
434  if(!parts.empty()) {
+
435  for(size_t j=0; j<parts.size()-1; j++) {
+
436  if(parts[j].isArray())
+
437  builder = builder->addNestedStructureArray(parts[j].name);
+
438  else
+
439  builder = builder->addNestedStructure(parts[j].name);
+
440  }
+
441  if(parts.back().isArray()) {
+
442  builder = builder->addNestedStructureArray(parts.back().name);
+
443  }
+
444  }
+
445 
+
446  if(!mem.structID.empty())
+
447  builder = builder->setId(mem.structID);
+
448 
+
449  DBCH chan;
+
450  if(!mem.pvname.empty()) {
+
451  DBCH temp(mem.pvname);
+
452  unsigned ftype = dbChannelFieldType(temp);
+
453 
+
454  // can't include in multi-locking
+
455  if(ftype>=DBF_INLINK && ftype<=DBF_FWDLINK)
+
456  throw std::runtime_error("Can't include link fields in group");
+
457 
+
458  chan.swap(temp);
+
459  }
+
460 
+
461  std::tr1::shared_ptr<PVIFBuilder> pvifbuilder(PVIFBuilder::create(mem.type, chan.chan));
+
462 
+
463  if(!parts.empty() && !parts.back().isArray())
+
464  builder = pvifbuilder->dtype(builder, parts.back().name);
+
465  else
+
466  builder = pvifbuilder->dtype(builder, "");
+
467 
+
468  if(!parts.empty()) {
+
469  for(size_t j=0; j<parts.size()-1; j++)
+
470  builder = builder->endNested();
+
471  if(parts.back().isArray())
+
472  builder = builder->endNested();
+
473  }
+
474 
+
475  if(!mem.pvname.empty()) {
+
476  members_map[mem.pvfldname] = J;
+
477  PDBGroupPV::Info& info = members[J];
+
478 
+
479  DBCH chan2;
+
480  if(chan.chan && (ellCount(&chan.chan->pre_chain)>0 || ellCount(&chan.chan->post_chain)>0)) {
+
481  DBCH temp(mem.pvname);
+
482  info.chan2.swap(chan2);
+
483  }
+
484 
+
485  info.allowProc = mem.putorder != std::numeric_limits<int>::min();
+
486  info.builder = PTRMOVE(pvifbuilder);
+
487  assert(info.builder.get());
+
488 
+
489  info.attachment.swap(parts);
+
490  info.chan.swap(chan);
+
491 
+
492  // info.triggers populated below
+
493 
+
494  assert(info.chan);
+
495  records[J] = dbChannelRecord(info.chan);
+
496 
+
497  J++;
+
498  }
+
499  }
+
500  pv->members.swap(members);
+
501 
+
502  pv->fielddesc = builder->createStructure();
+
503  pv->complete = pvbuilder->createPVStructure(pv->fielddesc);
+
504 
+
505  pv->complete->getSubFieldT<pvd::PVBoolean>("record._options.atomic")->put(pv->monatomic);
+
506 
+
507  DBManyLock L(&records[0], records.size(), 0);
+
508  pv->locker.swap(L);
+
509 
+
510  // construct locker for records triggered by each member
+
511  for(size_t i=0, J=0, N=info.members.size(); i<N; i++)
+
512  {
+
513  const GroupMemberInfo &mem = info.members[i];
+
514  if(mem.pvname.empty()) continue;
+
515  PDBGroupPV::Info& info = pv->members[J++];
+
516 
+
517  if(mem.triggers.empty()) continue;
+
518 
+
519  std::vector<dbCommon*> trig_records;
+
520  trig_records.reserve(mem.triggers.size());
+
521 
+
522  FOREACH(GroupMemberInfo::triggers_t::const_iterator, it, end, mem.triggers) {
+
523  members_map_t::const_iterator imap(members_map.find(*it));
+
524  if(imap==members_map.end())
+
525  throw std::logic_error("trigger resolution missed map to non-dbChannel");
+
526 
+
527  info.triggers.push_back(imap->second);
+
528  trig_records.push_back(records[imap->second]);
+
529  }
+
530 
+
531  DBManyLock L(&trig_records[0], trig_records.size(), 0);
+
532  info.locker.swap(L);
+
533  }
+
534 
+
535  persist_pv_map[info.name] = pv;
+
536 
+
537  }catch(std::exception& e){
+
538  fprintf(stderr, "%s: Error Group not created: %s\n", info.name.c_str(), e.what());
+
539  }
+
540  }
+
541 #else
+
542  if(!proc.groups.empty()) {
+
543  fprintf(stderr, "Group(s) were defined, but need Base >=3.16.0.2 to function. Ignoring.\n");
+
544  }
+
545 #endif // USE_MULTILOCK
+
546 
+
547  event_context = db_init_events();
+
548  if(!event_context)
+
549  throw std::runtime_error("Failed to create dbEvent context");
+
550  int ret = db_start_events(event_context, "PDB-event", NULL, NULL, epicsThreadPriorityCAServerLow-1);
+
551  if(ret!=DB_EVENT_OK)
+
552  throw std::runtime_error("Failed to stsart dbEvent context");
+
553 
+
554  // setup group monitors
+
555 #ifdef USE_MULTILOCK
+
556  for(persist_pv_map_t::iterator next = persist_pv_map.begin(),
+
557  end = persist_pv_map.end(),
+
558  it = next!=end ? next++ : end;
+
559  it != end; it = next==end ? end : next++)
+
560  {
+
561  const PDBPV::shared_pointer& ppv = it->second;
+
562  PDBGroupPV *pv = dynamic_cast<PDBGroupPV*>(ppv.get());
+
563  if(!pv)
+
564  continue;
+
565  try {
+
566 
+
567  // prepare for monitor
+
568 
+
569  size_t i=0;
+
570  FOREACH(PDBGroupPV::members_t::iterator, it2, end2, pv->members)
+
571  {
+
572  PDBGroupPV::Info& info = *it2;
+
573  info.evt_VALUE.index = info.evt_PROPERTY.index = i++;
+
574  info.evt_VALUE.self = info.evt_PROPERTY.self = pv;
+
575  assert(info.chan);
+
576 
+
577  info.pvif.reset(info.builder->attach(pv->complete, info.attachment));
+
578 
+
579  // TODO: don't need evt_PROPERTY for PVIF plain
+
580  dbChannel *pchan = info.chan2.chan ? info.chan2.chan : info.chan.chan;
+
581  info.evt_PROPERTY.create(event_context, pchan, &pdb_group_event, DBE_PROPERTY);
+
582 
+
583  if(!info.triggers.empty()) {
+
584  info.evt_VALUE.create(event_context, info.chan, &pdb_group_event, DBE_VALUE|DBE_ALARM);
+
585  }
+
586  }
+
587  }catch(std::exception& e){
+
588  fprintf(stderr, "%s: Error during dbEvent setup : %s\n", pv->name.c_str(), e.what());
+
589  persist_pv_map.erase(it);
+
590  }
+
591  }
+
592 #endif // USE_MULTILOCK
+
593  epics::atomic::increment(num_instances);
+
594 }
+
595 
+
596 PDBProvider::~PDBProvider()
+
597 {
+
598  epics::atomic::decrement(num_instances);
+
599 
+
600  destroy();
+
601 }
+
602 
+
603 void PDBProvider::destroy()
+
604 {
+
605  dbEventCtx ctxt = NULL;
+
606 
+
607  persist_pv_map_t ppv;
+
608  {
+
609  epicsGuard<epicsMutex> G(transient_pv_map.mutex());
+
610  persist_pv_map.swap(ppv);
+
611  std::swap(ctxt, event_context);
+
612  }
+
613  ppv.clear(); // indirectly calls all db_cancel_events()
+
614  if(ctxt) db_close_events(ctxt);
+
615 }
+
616 
+
617 std::string PDBProvider::getProviderName() { return "QSRV"; }
+
618 
+
619 namespace {
+
620 struct ChannelFindRequesterNOOP : public pva::ChannelFind
+
621 {
+
622  const pva::ChannelProvider::weak_pointer provider;
+
623  ChannelFindRequesterNOOP(const pva::ChannelProvider::shared_pointer& prov) : provider(prov) {}
+
624  virtual ~ChannelFindRequesterNOOP() {}
+
625  virtual void destroy() {}
+
626  virtual std::tr1::shared_ptr<pva::ChannelProvider> getChannelProvider() { return provider.lock(); }
+
627  virtual void cancel() {}
+
628 };
+
629 }
+
630 
+
631 pva::ChannelFind::shared_pointer
+
632 PDBProvider::channelFind(const std::string &channelName, const pva::ChannelFindRequester::shared_pointer &requester)
+
633 {
+
634  pva::ChannelFind::shared_pointer ret(new ChannelFindRequesterNOOP(shared_from_this()));
+
635 
+
636  bool found = false;
+
637  {
+
638  epicsGuard<epicsMutex> G(transient_pv_map.mutex());
+
639  if(persist_pv_map.find(channelName)!=persist_pv_map.end()
+
640  || transient_pv_map.find(channelName)
+
641  || dbChannelTest(channelName.c_str())==0)
+
642  found = true;
+
643  }
+
644  requester->channelFindResult(pvd::Status(), ret, found);
+
645  return ret;
+
646 }
+
647 
+
648 pva::ChannelFind::shared_pointer
+
649 PDBProvider::channelList(pva::ChannelListRequester::shared_pointer const & requester)
+
650 {
+
651  pva::ChannelFind::shared_pointer ret;
+
652  pvd::PVStringArray::svector names;
+
653  for(pdbRecordIterator rec; !rec.done(); rec.next())
+
654  {
+
655  names.push_back(rec.name());
+
656  }
+
657  {
+
658  epicsGuard<epicsMutex> G(transient_pv_map.mutex());
+
659 
+
660  for(persist_pv_map_t::const_iterator it=persist_pv_map.begin(), end=persist_pv_map.end();
+
661  it != end; ++it)
+
662  {
+
663  names.push_back(it->first);
+
664  }
+
665  }
+
666  // check for duplicates?
+
667  requester->channelListResult(pvd::Status::Ok,
+
668  shared_from_this(),
+
669  pvd::freeze(names), false);
+
670  return ret;
+
671 }
+
672 
+
673 pva::Channel::shared_pointer
+
674 PDBProvider::createChannel(std::string const & channelName,
+
675  pva::ChannelRequester::shared_pointer const & channelRequester,
+
676  short priority)
+
677 {
+
678  return createChannel(channelName, channelRequester, priority, "???");
+
679 }
+
680 
+
681 pva::Channel::shared_pointer
+
682 PDBProvider::createChannel(std::string const & channelName,
+
683  pva::ChannelRequester::shared_pointer const & requester,
+
684  short priority, std::string const & address)
+
685 {
+
686  pva::Channel::shared_pointer ret;
+
687  PDBPV::shared_pointer pv;
+
688  pvd::Status status;
+
689 
+
690  {
+
691  epicsGuard<epicsMutex> G(transient_pv_map.mutex());
+
692 
+
693  pv = transient_pv_map.find(channelName);
+
694  if(!pv) {
+
695  persist_pv_map_t::const_iterator it=persist_pv_map.find(channelName);
+
696  if(it!=persist_pv_map.end()) {
+
697  pv = it->second;
+
698  }
+
699  }
+
700  if(!pv) {
+
701  dbChannel *pchan = dbChannelCreate(channelName.c_str());
+
702  if(pchan) {
+
703  DBCH chan(pchan);
+
704  pv.reset(new PDBSinglePV(chan, shared_from_this()));
+
705  transient_pv_map.insert(channelName, pv);
+
706  PDBSinglePV::shared_pointer spv = std::tr1::static_pointer_cast<PDBSinglePV>(pv);
+
707  spv->weakself = spv;
+
708  spv->activate();
+
709  }
+
710  }
+
711  }
+
712  if(pv) {
+
713  ret = pv->connect(shared_from_this(), requester);
+
714  }
+
715  if(!ret) {
+
716  status = pvd::Status(pvd::Status::STATUSTYPE_ERROR, "not found");
+
717  }
+
718  requester->channelCreated(status, ret);
+
719  return ret;
+
720 }
+
721 
+
722 FieldName::FieldName(const std::string& pv)
+
723 {
+
724  if(pv.empty())
+
725  return;
+
726  Splitter S(pv.c_str(), '.');
+
727  std::string part;
+
728  while(S.snip(part)) {
+
729  if(part.empty())
+
730  throw std::runtime_error("Empty field component in: "+pv);
+
731 
+
732  if(part[part.size()-1]==']') {
+
733  const size_t open = part.find_last_of('['),
+
734  N = part.size();
+
735  bool ok = open!=part.npos;
+
736  epicsUInt32 index = 0;
+
737  for(size_t i=open+1; ok && i<(N-1); i++) {
+
738  ok &= part[i]>='0' && part[i]<='9';
+
739  index = 10*index + part[i] - '0';
+
740  }
+
741  if(!ok)
+
742  throw std::runtime_error("Invalid field array sub-script in : "+pv);
+
743 
+
744  parts.push_back(Component(part.substr(0, open), index));
+
745 
+
746  } else {
+
747  parts.push_back(Component(part));
+
748  }
+
749  }
+
750  if(parts.empty())
+
751  throw std::runtime_error("Empty field name");
+
752 }
+
753 
+
754 epics::pvData::PVFieldPtr
+
755 FieldName::lookup(const epics::pvData::PVStructurePtr& S, epics::pvData::PVField **ppsar) const
+
756 {
+
757  if(ppsar)
+
758  *ppsar = 0;
+
759 
+
760  pvd::PVFieldPtr ret = S;
+
761  for(size_t i=0, N=parts.size(); i<N; i++) {
+
762  pvd::PVStructure* parent = dynamic_cast<pvd::PVStructure*>(ret.get());
+
763  if(!parent)
+
764  throw std::runtime_error("mid-field is not structure");
+
765 
+
766  ret = parent->getSubFieldT(parts[i].name);
+
767 
+
768  if(parts[i].isArray()) {
+
769  pvd::PVStructureArray* sarr = dynamic_cast<pvd::PVStructureArray*>(ret.get());
+
770  if(!sarr)
+
771  throw std::runtime_error("indexed field is not structure array");
+
772 
+
773  if(ppsar && !*ppsar)
+
774  *ppsar = sarr;
+
775 
+
776  pvd::PVStructureArray::const_svector V(sarr->view());
+
777 
+
778  if(V.size()<=parts[i].index || !V[parts[i].index]) {
+
779  // automatic re-size and ensure non-null
+
780  V.clear(); // drop our extra ref so that reuse() might avoid a copy
+
781  pvd::PVStructureArray::svector E(sarr->reuse());
+
782 
+
783  if(E.size()<=parts[i].index)
+
784  E.resize(parts[i].index+1);
+
785 
+
786  if(!E[parts[i].index])
+
787  E[parts[i].index] = pvd::getPVDataCreate()->createPVStructure(sarr->getStructureArray()->getStructure());
+
788 
+
789  ret = E[parts[i].index];
+
790 
+
791  sarr->replace(pvd::freeze(E));
+
792 
+
793  } else {
+
794  ret = V[parts[i].index];
+
795  }
+
796  }
+
797  }
+
798  return ret;
+
799 }
+
800 
+
801 void FieldName::show() const
+
802 {
+
803  if(parts.empty()) {
+
804  printf("/");
+
805  return;
+
806  }
+
807 
+
808  bool first = true;
+
809  for(size_t i=0, N=parts.size(); i<N; i++)
+
810  {
+
811  if(!first) {
+
812  printf(".");
+
813  } else {
+
814  first = false;
+
815  }
+
816  if(parts[i].isArray())
+
817  printf("%s[%u]", parts[i].name.c_str(), (unsigned)parts[i].index);
+
818  else
+
819  printf("%s", parts[i].name.c_str());
+
820  }
+
821 }
+
822 
+
823 extern "C" {
+
824 epicsExportAddress(int, PDBProviderDebug);
+
825 }
+ +
Definition: pvif.h:81
+ +
epicsMutex & mutex() const
Definition: weakmap.h:276
+ +
value_pointer find(const K &k) const
Definition: weakmap.h:215
+ + +
value_pointer insert(const K &k, value_pointer &v)
Definition: weakmap.h:230
+ + + +
+ + + + diff --git a/pdb_8h_source.html b/pdb_8h_source.html new file mode 100644 index 0000000..9d8e393 --- /dev/null +++ b/pdb_8h_source.html @@ -0,0 +1,196 @@ + + + + + + +pva2pva: pdbApp/pdb.h Source File + + + + + + + + + +
+
+ + + + + + +
+
pva2pva +  1.4.1 +
+
+
+ + + + + + + + + +
+ +
+ + +
+
+
+
pdb.h
+
+
+
1 #ifndef PDB_H
+
2 #define PDB_H
+
3 
+
4 #include <dbEvent.h>
+
5 #include <asLib.h>
+
6 
+
7 #include <pv/configuration.h>
+
8 #include <pv/pvAccess.h>
+
9 
+
10 #include "weakmap.h"
+
11 
+
12 #include <pv/qsrv.h>
+
13 
+
14 struct PDBProvider;
+
15 
+
16 struct PDBPV
+
17 {
+
18  POINTER_DEFINITIONS(PDBPV);
+
19 
+
20  epics::pvData::StructureConstPtr fielddesc;
+
21 
+
22  PDBPV() {}
+
23  virtual ~PDBPV() {}
+
24 
+
25  virtual
+
26  epics::pvAccess::Channel::shared_pointer
+
27  connect(const std::tr1::shared_ptr<PDBProvider>& prov,
+
28  const epics::pvAccess::ChannelRequester::shared_pointer& req) =0;
+
29 
+
30  // print info to stdout (with iocsh redirection)
+
31  virtual void show(int lvl) {}
+
32 };
+
33 
+
34 struct QSRV_API PDBProvider : public epics::pvAccess::ChannelProvider,
+
35  public epics::pvAccess::ChannelFind,
+
36  public std::tr1::enable_shared_from_this<PDBProvider>
+
37 {
+
38  POINTER_DEFINITIONS(PDBProvider);
+
39 
+
40  explicit PDBProvider(const epics::pvAccess::Configuration::const_shared_pointer& =epics::pvAccess::Configuration::const_shared_pointer());
+
41  virtual ~PDBProvider();
+
42 
+
43  // ChannelProvider
+
44  virtual void destroy() OVERRIDE FINAL;
+
45  virtual std::string getProviderName() OVERRIDE FINAL;
+
46  virtual epics::pvAccess::ChannelFind::shared_pointer channelFind(std::string const & channelName,
+
47  epics::pvAccess::ChannelFindRequester::shared_pointer const & channelFindRequester) OVERRIDE FINAL;
+
48  virtual epics::pvAccess::ChannelFind::shared_pointer channelList(epics::pvAccess::ChannelListRequester::shared_pointer const & channelListRequester) OVERRIDE FINAL;
+
49  virtual epics::pvAccess::Channel::shared_pointer createChannel(std::string const & channelName,
+
50  epics::pvAccess::ChannelRequester::shared_pointer const & channelRequester,
+
51  short priority = PRIORITY_DEFAULT) OVERRIDE FINAL;
+
52  virtual epics::pvAccess::Channel::shared_pointer createChannel(std::string const & channelName,
+
53  epics::pvAccess::ChannelRequester::shared_pointer const & channelRequester,
+
54  short priority, std::string const & address) OVERRIDE FINAL;
+
55 
+
56  // ChannelFind
+
57  virtual std::tr1::shared_ptr<ChannelProvider> getChannelProvider() OVERRIDE FINAL { return shared_from_this(); }
+
58  virtual void cancel() OVERRIDE FINAL {/* our channelFind() is synchronous, so nothing to cancel */}
+
59 
+
60  typedef std::map<std::string, PDBPV::shared_pointer> persist_pv_map_t;
+
61  persist_pv_map_t persist_pv_map;
+
62 
+ +
64  transient_pv_map_t transient_pv_map;
+
65 
+
66  dbEventCtx event_context;
+
67 
+
68  typedef std::list<std::string> group_files_t;
+
69  static group_files_t group_files;
+
70 
+
71  static size_t num_instances;
+
72 };
+
73 
+
74 QSRV_API
+
75 void QSRVRegistrar_counters();
+
76 
+
77 class AsWritePvt {
+
78  void * pvt;
+
79 public:
+
80  AsWritePvt() :pvt(NULL) {}
+
81  explicit AsWritePvt(void * pvt): pvt(pvt) {}
+
82  ~AsWritePvt() {
+
83  asTrapWriteAfterWrite(pvt);
+
84  }
+
85  void swap(AsWritePvt& o) {
+
86  std::swap(pvt, o.pvt);
+
87  }
+
88 private:
+
89  AsWritePvt(const AsWritePvt&);
+
90  AsWritePvt& operator=(const AsWritePvt&);
+
91 };
+
92 
+
93 #endif // PDB_H
+
Definition: pdb.h:77
+
Definition: pdb.h:16
+ + +
+ + + + diff --git a/pdbgroup_8cpp_source.html b/pdbgroup_8cpp_source.html new file mode 100644 index 0000000..adc6fe2 --- /dev/null +++ b/pdbgroup_8cpp_source.html @@ -0,0 +1,587 @@ + + + + + + +pva2pva: pdbApp/pdbgroup.cpp Source File + + + + + + + + + +
+
+ + + + + + +
+
pva2pva +  1.4.1 +
+
+
+ + + + + + + + + +
+ +
+ + +
+
+
+
pdbgroup.cpp
+
+
+
1 
+
2 #include <stdio.h>
+
3 
+
4 // rediect stdio/stderr for iocsh
+
5 #include <epicsStdio.h>
+
6 
+
7 #include <epicsAtomic.h>
+
8 #include <dbAccess.h>
+
9 #include <dbChannel.h>
+
10 #include <dbStaticLib.h>
+
11 #include <asLib.h>
+
12 
+
13 #include <pv/pvAccess.h>
+
14 #include <pv/configuration.h>
+
15 #include <pv/epicsException.h>
+
16 
+
17 #include "helper.h"
+
18 #include "pdbgroup.h"
+
19 #include "pdb.h"
+
20 
+
21 namespace pvd = epics::pvData;
+
22 namespace pva = epics::pvAccess;
+
23 
+
24 size_t PDBGroupPV::num_instances;
+
25 size_t PDBGroupChannel::num_instances;
+
26 size_t PDBGroupPut::num_instances;
+
27 size_t PDBGroupMonitor::num_instances;
+
28 
+
29 typedef epicsGuard<epicsMutex> Guard;
+
30 
+
31 void pdb_group_event(void *user_arg, struct dbChannel *chan,
+
32  int eventsRemaining, struct db_field_log *pfl)
+
33 {
+
34  DBEvent *evt=(DBEvent*)user_arg;
+
35  unsigned idx = evt->index;
+
36  try{
+
37  PDBGroupPV::shared_pointer self(std::tr1::static_pointer_cast<PDBGroupPV>(((PDBGroupPV*)evt->self)->shared_from_this()));
+
38  PDBGroupPV::Info& info = self->members[idx];
+
39 
+
40  PDBGroupPV::interested_remove_t temp;
+
41  {
+
42 
+
43  Guard G(self->lock);
+
44 
+
45  self->scratch.clear();
+
46  if(evt->dbe_mask&DBE_PROPERTY || !self->monatomic)
+
47  {
+
48  DBScanLocker L(dbChannelRecord(info.chan));
+
49  self->members[idx].pvif->put(self->scratch, evt->dbe_mask, pfl);
+
50 
+
51  } else {
+
52  // we ignore 'pfl' (and the dbEvent queue) when collecting an atomic snapshot
+
53 
+
54  DBManyLocker L(info.locker); // lock only those records in the triggers list
+
55  FOREACH(PDBGroupPV::Info::triggers_t::const_iterator, it, end, info.triggers)
+
56  {
+
57  size_t i = *it;
+
58  // go get a consistent snapshot we must ignore the db_field_log which came through the dbEvent buffer
+
59  LocalFL FL(NULL, self->members[i].chan); // create a read fl if needed
+
60  self->members[i].pvif->put(self->scratch, evt->dbe_mask, FL.pfl);
+
61  }
+
62  }
+
63 
+
64  if(!(evt->dbe_mask&DBE_PROPERTY)) {
+
65  if(!info.had_initial_VALUE) {
+
66  info.had_initial_VALUE = true;
+
67  assert(self->initial_waits>0);
+
68  self->initial_waits--;
+
69  }
+
70  } else {
+
71  if(!info.had_initial_PROPERTY) {
+
72  info.had_initial_PROPERTY = true;
+
73  assert(self->initial_waits>0);
+
74  self->initial_waits--;
+
75  }
+
76  }
+
77 
+
78  if(self->initial_waits==0) {
+
79  self->interested_iterating = true;
+
80 
+
81  FOREACH(PDBGroupPV::interested_t::const_iterator, it, end, self->interested) {
+
82  PDBGroupMonitor& mon = **it;
+
83  mon.post(G, self->scratch); // G unlocked
+
84  }
+
85 
+
86  {
+
87  Guard G(self->lock);
+
88 
+
89  assert(self->interested_iterating);
+
90 
+
91  while(!self->interested_add.empty()) {
+
92  PDBGroupPV::interested_t::iterator first(self->interested_add.begin());
+
93  self->interested.insert(*first);
+
94  self->interested_add.erase(first);
+
95  }
+
96 
+
97  temp.swap(self->interested_remove);
+
98  for(PDBGroupPV::interested_remove_t::iterator it(temp.begin()),
+
99  end(temp.end()); it != end; ++it)
+
100  {
+
101  self->interested.erase(static_cast<PDBGroupMonitor*>(it->get()));
+
102  }
+
103 
+
104  self->interested_iterating = false;
+
105 
+
106  self->finalizeMonitor();
+
107  }
+
108  }
+
109  }
+
110 
+
111  }catch(std::tr1::bad_weak_ptr&){
+
112  /* We are racing destruction of the PDBGroupPV, but things are ok.
+
113  * The destructor is running, but has not completed db_cancel_event()
+
114  * so storage is still valid.
+
115  * Just do nothing
+
116  */
+
117  }catch(std::exception& e){
+
118  std::cerr<<"Unhandled exception in pdb_group_event(): "<<e.what()<<"\n"
+
119  <<SHOW_EXCEPTION(e)<<"\n";
+
120  }
+
121 }
+
122 
+
123 PDBGroupPV::PDBGroupPV()
+
124  :pgatomic(false)
+
125  ,monatomic(false)
+
126  ,interested_iterating(false)
+
127  ,initial_waits(0)
+
128 {
+
129  epics::atomic::increment(num_instances);
+
130 }
+
131 
+
132 PDBGroupPV::~PDBGroupPV()
+
133 {
+
134  epics::atomic::decrement(num_instances);
+
135 }
+
136 
+
137 pva::Channel::shared_pointer
+
138 PDBGroupPV::connect(const std::tr1::shared_ptr<PDBProvider>& prov,
+
139  const pva::ChannelRequester::shared_pointer& req)
+
140 {
+
141  PDBGroupChannel::shared_pointer ret(new PDBGroupChannel(shared_from_this(), prov, req));
+
142 
+
143  ret->cred.update(req);
+
144 
+
145  ret->aspvt.resize(members.size());
+
146  for(size_t i=0, N=members.size(); i<N; i++)
+
147  {
+
148  ret->aspvt[i].add(members[i].chan, ret->cred);
+
149  }
+
150 
+
151  return ret;
+
152 }
+
153 
+
154 // caller must not hold lock
+
155 void PDBGroupPV::addMonitor(PDBGroupMonitor *mon)
+
156 {
+
157  Guard G(lock);
+
158  if(interested.empty() && interested_add.empty()) {
+
159  // first monitor
+
160  // start subscriptions
+
161 
+
162  size_t ievts = 0;
+
163  for(size_t i=0; i<members.size(); i++) {
+
164  PDBGroupPV::Info& info = members[i];
+
165 
+
166  if(!!info.evt_VALUE) {
+
167  db_event_enable(info.evt_VALUE.subscript);
+
168  db_post_single_event(info.evt_VALUE.subscript);
+
169  ievts++;
+
170  info.had_initial_VALUE = false;
+
171  } else {
+
172  info.had_initial_VALUE = true;
+
173  }
+
174  assert(info.evt_PROPERTY.subscript);
+
175  db_event_enable(info.evt_PROPERTY.subscript);
+
176  db_post_single_event(info.evt_PROPERTY.subscript);
+
177  ievts++;
+
178  info.had_initial_PROPERTY = false;
+
179  }
+
180  initial_waits = ievts;
+
181 
+
182  } else if(initial_waits==0) {
+
183  // new subscriber and already had initial update
+
184  mon->post(G);
+
185  } // else new subscriber, but no initial update. so just wait
+
186 
+
187  if(interested_iterating)
+
188  interested_add.insert(mon);
+
189  else
+
190  interested.insert(mon);
+
191 }
+
192 
+
193 // caller must not hold lock
+
194 void PDBGroupPV::removeMonitor(PDBGroupMonitor *mon)
+
195 {
+
196  Guard G(lock);
+
197 
+
198  if(interested_add.erase(mon)) {
+
199  // and+remove while iterating. no-op
+
200 
+
201  } else if(interested_iterating) {
+
202  // keep the monitor alive until we've finished iterating
+
203  interested_remove.insert(mon->shared_from_this());
+
204 
+
205  } else {
+
206  interested.erase(mon);
+
207  finalizeMonitor();
+
208  }
+
209 }
+
210 
+
211 // must hold lock
+
212 void PDBGroupPV::finalizeMonitor()
+
213 {
+
214  assert(!interested_iterating);
+
215 
+
216  if(!interested.empty())
+
217  return;
+
218 
+
219  // last subscriber
+
220  for(size_t i=0; i<members.size(); i++) {
+
221  PDBGroupPV::Info& info = members[i];
+
222 
+
223  if(!!info.evt_VALUE) {
+
224  db_event_disable(info.evt_VALUE.subscript);
+
225  }
+
226  db_event_disable(info.evt_PROPERTY.subscript);
+
227  }
+
228 }
+
229 
+
230 void PDBGroupPV::show(int lvl)
+
231 {
+
232  // no locking as we only print things which are const after initialization
+
233 
+
234  printf(" Atomic Get/Put:%s Monitor:%s Members:%zu\n",
+
235  pgatomic?"yes":"no", monatomic?"yes":"no", members.size());
+
236 
+
237  if(lvl<=1)
+
238  return;
+
239 
+
240  for(members_t::const_iterator it(members.begin()), end(members.end());
+
241  it != end; ++it)
+
242  {
+
243  const Info& info = *it;
+
244  printf(" ");
+
245  info.attachment.show(); // printf()s
+
246  printf("\t<-> %s\n", dbChannelName(info.chan));
+
247  }
+
248 }
+
249 
+
250 
+
251 PDBGroupChannel::PDBGroupChannel(const PDBGroupPV::shared_pointer& pv,
+
252  const std::tr1::shared_ptr<pva::ChannelProvider>& prov,
+
253  const pva::ChannelRequester::shared_pointer& req)
+
254  :BaseChannel(pv->name, prov, req, pv->fielddesc)
+
255  ,pv(pv)
+
256 {
+
257  epics::atomic::increment(num_instances);
+
258 }
+
259 
+
260 PDBGroupChannel::~PDBGroupChannel()
+
261 {
+
262  epics::atomic::decrement(num_instances);
+
263 }
+
264 
+
265 void PDBGroupChannel::printInfo(std::ostream& out)
+
266 {
+
267  out<<"PDBGroupChannel";
+
268 }
+
269 
+
270 pva::ChannelPut::shared_pointer
+
271 PDBGroupChannel::createChannelPut(
+
272  pva::ChannelPutRequester::shared_pointer const & requester,
+
273  pvd::PVStructure::shared_pointer const & pvRequest)
+
274 {
+
275  PDBGroupPut::shared_pointer ret(new PDBGroupPut(shared_from_this(), requester, pvRequest));
+
276  requester->channelPutConnect(pvd::Status(), ret, fielddesc);
+
277  return ret;
+
278 }
+
279 
+
280 pva::Monitor::shared_pointer
+
281 PDBGroupChannel::createMonitor(
+
282  pva::MonitorRequester::shared_pointer const & requester,
+
283  pvd::PVStructure::shared_pointer const & pvRequest)
+
284 {
+
285  PDBGroupMonitor::shared_pointer ret(new PDBGroupMonitor(pv->shared_from_this(), requester, pvRequest));
+
286  ret->weakself = ret;
+
287  assert(!!pv->complete);
+
288  guard_t G(pv->lock);
+
289  ret->connect(G, pv->complete);
+
290  return ret;
+
291 }
+
292 
+
293 
+
294 
+
295 PDBGroupPut::PDBGroupPut(const PDBGroupChannel::shared_pointer& channel,
+
296  const requester_type::shared_pointer& requester,
+
297  const epics::pvData::PVStructure::shared_pointer &pvReq)
+
298  :channel(channel)
+
299  ,requester(requester)
+
300  ,atomic(channel->pv->pgatomic)
+
301  ,doWait(false)
+
302  ,doProc(PVIF::ProcPassive)
+
303  ,changed(new pvd::BitSet(channel->fielddesc->getNumberFields()))
+
304  ,pvf(pvd::getPVDataCreate()->createPVStructure(channel->fielddesc))
+
305 {
+
306  epics::atomic::increment(num_instances);
+
307  try {
+
308  getS<pvd::boolean>(pvReq, "record._options.atomic", atomic);
+
309 
+
310  getS<pvd::boolean>(pvReq, "record._options.block", doWait);
+
311 
+
312  std::string proccmd;
+
313  if(getS<std::string>(pvReq, "record._options.process", proccmd)) {
+
314  if(proccmd=="true") {
+
315  doProc = PVIF::ProcForce;
+
316  } else if(proccmd=="false") {
+
317  doProc = PVIF::ProcInhibit;
+
318  doWait = false; // no point in waiting
+
319  } else if(proccmd=="passive") {
+
320  doProc = PVIF::ProcPassive;
+
321  } else {
+
322  requester->message("process= expects: true|false|passive", pva::warningMessage);
+
323  }
+
324  }
+
325  }catch(std::exception& e){
+
326  requester->message(std::string("Error processing request options: ")+e.what());
+
327  }
+
328 
+
329  pvf->getSubFieldT<pvd::PVBoolean>("record._options.atomic")->put(atomic);
+
330 
+
331 
+
332  const size_t npvs = channel->pv->members.size();
+
333  pvif.resize(npvs);
+
334  for(size_t i=0; i<npvs; i++)
+
335  {
+
336  PDBGroupPV::Info& info = channel->pv->members[i];
+
337 
+
338  pvif[i].reset(info.builder->attach(pvf, info.attachment));
+
339  }
+
340 }
+
341 
+
342 PDBGroupPut::~PDBGroupPut()
+
343 {
+
344  epics::atomic::decrement(num_instances);
+
345 }
+
346 
+
347 void PDBGroupPut::put(pvd::PVStructure::shared_pointer const & value,
+
348  pvd::BitSet::shared_pointer const & changed)
+
349 {
+
350  // assume value may be a different struct each time... lot of wasted prep work
+
351  const size_t npvs = channel->pv->members.size();
+
352  std::vector<std::tr1::shared_ptr<PVIF> > putpvif(npvs);
+
353  pvd::shared_vector<AsWritePvt> asWritePvt(npvs);
+
354 
+
355  for(size_t i=0; i<npvs; i++)
+
356  {
+
357  PDBGroupPV::Info& info = channel->pv->members[i];
+
358 
+
359  AsWritePvt wrt(asTrapWriteWithData(
+
360  channel->aspvt.at(i).aspvt,
+
361  &channel->cred.user[0],
+
362  &channel->cred.host[0],
+
363  info.chan.chan,
+
364  info.chan->final_type,
+
365  info.chan->final_no_elements,
+
366  NULL
+
367  )
+
368  );
+
369  asWritePvt[i].swap(wrt);
+
370 
+
371  if(!info.allowProc) continue;
+
372  putpvif[i].reset(info.builder->attach(value, info.attachment));
+
373  }
+
374 
+
375  pvd::Status ret;
+
376  if(atomic) {
+
377  DBManyLocker L(channel->pv->locker);
+
378  for(size_t i=0; ret && i<npvs; i++) {
+
379  if(!putpvif[i].get()) continue;
+
380 
+
381  ret |= putpvif[i]->get(*changed, doProc, channel->aspvt[i].canWrite());
+
382  }
+
383 
+
384  } else {
+
385  for(size_t i=0; ret && i<npvs; i++)
+
386  {
+
387  if(!putpvif[i].get()) continue;
+
388 
+
389  PDBGroupPV::Info& info = channel->pv->members[i];
+
390 
+
391  DBScanLocker L(dbChannelRecord(info.chan));
+
392 
+
393  ret |= putpvif[i]->get(*changed,
+
394  info.allowProc ? doProc : PVIF::ProcInhibit,
+
395  channel->aspvt[i].canWrite());
+
396  }
+
397  }
+
398 
+
399  requester_type::shared_pointer req(requester.lock());
+
400  if(req)
+
401  req->putDone(ret, shared_from_this());
+
402 }
+
403 
+
404 void PDBGroupPut::get()
+
405 {
+
406  const size_t npvs = pvif.size();
+
407 
+
408  changed->clear();
+
409  if(atomic) {
+
410  DBManyLocker L(channel->pv->locker);
+
411  for(size_t i=0; i<npvs; i++) {
+
412  LocalFL FL(NULL, channel->pv->members[i].chan);
+
413  pvif[i]->put(*changed, DBE_VALUE|DBE_ALARM|DBE_PROPERTY, FL.pfl);
+
414  }
+
415  } else {
+
416 
+
417  for(size_t i=0; i<npvs; i++)
+
418  {
+
419  PDBGroupPV::Info& info = channel->pv->members[i];
+
420 
+
421  DBScanLocker L(dbChannelRecord(info.chan));
+
422  LocalFL FL(NULL, info.chan);
+
423  pvif[i]->put(*changed, DBE_VALUE|DBE_ALARM|DBE_PROPERTY, FL.pfl);
+
424  }
+
425  }
+
426  //TODO: report unused fields as changed?
+
427  changed->clear();
+
428  changed->set(0);
+
429 
+
430  requester_type::shared_pointer req(requester.lock());
+
431  if(req)
+
432  req->getDone(pvd::Status(), shared_from_this(), pvf, changed);
+
433 }
+
434 
+
435 PDBGroupMonitor::PDBGroupMonitor(const PDBGroupPV::shared_pointer& pv,
+
436  const epics::pvAccess::MonitorRequester::weak_pointer &requester,
+
437  const pvd::PVStructure::shared_pointer& pvReq)
+
438  :BaseMonitor(pv->lock, requester, pvReq)
+
439  ,pv(pv)
+
440 {
+
441  epics::atomic::increment(num_instances);
+
442 }
+
443 
+
444 PDBGroupMonitor::~PDBGroupMonitor()
+
445 {
+
446  destroy();
+
447  epics::atomic::decrement(num_instances);
+
448 }
+
449 
+
450 void PDBGroupMonitor::destroy()
+
451 {
+
452  BaseMonitor::destroy();
+
453  PDBGroupPV::shared_pointer pv;
+
454  {
+
455  Guard G(lock);
+
456  this->pv.swap(pv);
+
457  }
+
458 }
+
459 
+
460 void PDBGroupMonitor::onStart()
+
461 {
+
462  pv->addMonitor(this);
+
463 }
+
464 
+
465 void PDBGroupMonitor::onStop()
+
466 {
+
467  pv->removeMonitor(this);
+
468 }
+
469 
+ +
471 {
+
472  Guard G(pv->lock);
+
473  post(G);
+
474 }
+
bool post(guard_t &guard, const epics::pvData::BitSet &updated, no_overflow)
post update if queue not full, if full return false w/o overflow
Definition: pvahelper.h:136
+
Definition: pvif.h:365
+
Definition: pdb.h:77
+
virtual void requestUpdate() OVERRIDE FINAL
Definition: pdbgroup.cpp:470
+ + +
Definition: pvif.h:223
+ + + +
Definition: pvif.h:250
+ + + +
+ + + + diff --git a/pdbgroup_8h_source.html b/pdbgroup_8h_source.html new file mode 100644 index 0000000..9448320 --- /dev/null +++ b/pdbgroup_8h_source.html @@ -0,0 +1,334 @@ + + + + + + +pva2pva: pdbApp/pdbgroup.h Source File + + + + + + + + + +
+
+ + + + + + +
+
pva2pva +  1.4.1 +
+
+
+ + + + + + + + + +
+ +
+ + +
+
+
+
pdbgroup.h
+
+
+
1 #ifndef PDBGROUP_H
+
2 #define PDBGROUP_H
+
3 
+
4 #include <istream>
+
5 #include <map>
+
6 #include <limits>
+
7 
+
8 #include <dbAccess.h>
+
9 
+
10 #include <dbEvent.h>
+
11 #include <dbLock.h>
+
12 
+
13 #include <pv/pvAccess.h>
+
14 
+
15 #include "helper.h"
+
16 #include "pvahelper.h"
+
17 #include "pvif.h"
+
18 #include "pdb.h"
+
19 
+
20 struct QSRV_API GroupConfig
+
21 {
+
22  struct QSRV_API Field {
+
23  std::string type, channel, trigger, id;
+
24  int putorder;
+
25 
+
26  Field() :putorder(std::numeric_limits<int>::min()) {}
+
27 
+
28  void swap(Field& o) {
+
29  std::swap(type, o.type);
+
30  std::swap(channel, o.channel);
+
31  std::swap(trigger, o.trigger);
+
32  std::swap(putorder, o.putorder);
+
33  std::swap(id, o.id);
+
34  }
+
35  };
+
36 
+
37  struct QSRV_API Group {
+
38  typedef std::map<std::string, Field> fields_t;
+
39  fields_t fields;
+
40  bool atomic, atomic_set;
+
41  std::string id;
+
42 
+
43  Group() :atomic(true), atomic_set(false) {}
+
44 
+
45  void swap(Group& o) {
+
46  std::swap(fields, o.fields);
+
47  std::swap(atomic, o.atomic);
+
48  std::swap(atomic_set, o.atomic_set);
+
49  std::swap(id, o.id);
+
50  }
+
51  };
+
52 
+
53  typedef std::map<std::string, Group> groups_t;
+
54  groups_t groups;
+
55  std::string warning;
+
56 
+
57  void swap(GroupConfig& o) {
+
58  std::swap(groups, o.groups);
+
59  std::swap(warning, o.warning);
+
60  }
+
61 
+
62  static void parse(const char *txt, const char *recname,
+
63  GroupConfig& result);
+
64 };
+
65 
+
66 struct PDBGroupMonitor;
+
67 
+
68 void pdb_group_event(void *user_arg, struct dbChannel *chan,
+
69  int eventsRemaining, struct db_field_log *pfl);
+
70 
+
71 struct QSRV_API PDBGroupPV : public PDBPV
+
72 {
+
73  POINTER_DEFINITIONS(PDBGroupPV);
+
74  weak_pointer weakself;
+
75  inline shared_pointer shared_from_this() { return shared_pointer(weakself); }
+
76 
+
77  // only for use in pdb_single_event()
+
78  // which is not concurrent for all VALUE/PROPERTY.
+
79  epics::pvData::BitSet scratch;
+
80 
+
81  epicsMutex lock;
+
82 
+
83  bool pgatomic, monatomic;
+
84 
+
85  // get/put/monitor
+
86  std::string name;
+
87 
+
88  struct Info {
+
89  DBCH chan;
+
90  // used for DBE_PROPERTY subscription when chan has filters
+
91  DBCH chan2;
+
92  std::tr1::shared_ptr<PVIFBuilder> builder;
+
93  FieldName attachment;
+
94  typedef std::vector<size_t> triggers_t;
+
95  triggers_t triggers; // index in PDBGroupPV::members
+
96  DBManyLock locker; // lock only those channels being triggered
+
97  p2p::auto_ptr<PVIF> pvif;
+
98  DBEvent evt_VALUE, evt_PROPERTY;
+
99  bool had_initial_VALUE, had_initial_PROPERTY, allowProc;
+
100 
+
101  Info() :had_initial_VALUE(false), had_initial_PROPERTY(false), allowProc(false) {}
+
102  };
+
103  typedef epics::pvData::shared_vector<Info> members_t;
+
104  members_t members;
+
105 
+
106  DBManyLock locker; // all member channels
+
107 
+
108  epics::pvData::PVStructurePtr complete; // complete copy from subscription
+
109 
+
110  typedef std::set<PDBGroupMonitor*> interested_t;
+
111  bool interested_iterating;
+
112  interested_t interested, interested_add;
+
113 
+
114  typedef std::set<BaseMonitor::shared_pointer> interested_remove_t;
+
115  interested_remove_t interested_remove;
+
116 
+
117  size_t initial_waits;
+
118 
+
119  static size_t num_instances;
+
120 
+
121  PDBGroupPV();
+
122  virtual ~PDBGroupPV();
+
123 
+
124  virtual
+
125  epics::pvAccess::Channel::shared_pointer
+
126  connect(const std::tr1::shared_ptr<PDBProvider>& prov,
+
127  const epics::pvAccess::ChannelRequester::shared_pointer& req) OVERRIDE FINAL;
+
128 
+
129  void addMonitor(PDBGroupMonitor*);
+
130  void removeMonitor(PDBGroupMonitor*);
+
131  void finalizeMonitor();
+
132 
+
133  virtual void show(int lvl) OVERRIDE;
+
134 };
+
135 
+
136 struct QSRV_API PDBGroupChannel : public BaseChannel,
+
137  public std::tr1::enable_shared_from_this<PDBGroupChannel>
+
138 {
+
139  POINTER_DEFINITIONS(PDBGroupChannel);
+
140 
+
141  PDBGroupPV::shared_pointer pv;
+
142  std::vector<ASCLIENT> aspvt;
+
143  // storage referenced from aspvt
+
144  ASCred cred;
+
145 
+
146  static size_t num_instances;
+
147 
+
148  PDBGroupChannel(const PDBGroupPV::shared_pointer& pv,
+
149  const std::tr1::shared_ptr<epics::pvAccess::ChannelProvider>& prov,
+
150  const epics::pvAccess::ChannelRequester::shared_pointer& req);
+
151  virtual ~PDBGroupChannel();
+
152 
+
153  virtual epics::pvAccess::ChannelPut::shared_pointer createChannelPut(
+
154  epics::pvAccess::ChannelPutRequester::shared_pointer const & requester,
+
155  epics::pvData::PVStructure::shared_pointer const & pvRequest) OVERRIDE FINAL;
+
156  virtual epics::pvData::Monitor::shared_pointer createMonitor(
+
157  epics::pvData::MonitorRequester::shared_pointer const & requester,
+
158  epics::pvData::PVStructure::shared_pointer const & pvRequest) OVERRIDE FINAL;
+
159 
+
160  virtual void printInfo(std::ostream& out) OVERRIDE FINAL;
+
161 };
+
162 
+
163 struct PDBGroupPut : public epics::pvAccess::ChannelPut,
+
164  public std::tr1::enable_shared_from_this<PDBGroupPut>
+
165 {
+
166  POINTER_DEFINITIONS(PDBGroupPut);
+
167  typedef epics::pvAccess::ChannelPutRequester requester_t;
+
168  PDBGroupChannel::shared_pointer channel;
+
169  requester_type::weak_pointer requester;
+
170 
+
171  // effectively const after ctor
+
172  bool atomic, doWait;
+
173  PVIF::proc_t doProc;
+
174 
+
175  epics::pvData::BitSetPtr changed;
+
176  epics::pvData::PVStructurePtr pvf;
+
177  std::vector<std::tr1::shared_ptr<PVIF> > pvif;
+
178 
+
179  static size_t num_instances;
+
180 
+
181  PDBGroupPut(const PDBGroupChannel::shared_pointer &channel,
+
182  const epics::pvAccess::ChannelPutRequester::shared_pointer &requester,
+
183  const epics::pvData::PVStructure::shared_pointer& pvReq);
+
184  virtual ~PDBGroupPut();
+
185 
+
186  virtual void destroy() OVERRIDE FINAL { pvif.clear(); channel.reset(); requester.reset(); }
+
187  virtual std::tr1::shared_ptr<epics::pvAccess::Channel> getChannel() OVERRIDE FINAL { return channel; }
+
188  virtual void cancel() OVERRIDE FINAL {}
+
189  virtual void lastRequest() OVERRIDE FINAL {}
+
190  virtual void put(
+
191  epics::pvData::PVStructure::shared_pointer const & pvPutStructure,
+
192  epics::pvData::BitSet::shared_pointer const & putBitSet) OVERRIDE FINAL;
+
193  virtual void get() OVERRIDE FINAL;
+
194 };
+
195 
+ +
197 {
+
198  POINTER_DEFINITIONS(PDBGroupMonitor);
+
199 
+
200  PDBGroupPV::shared_pointer pv;
+
201 
+
202  bool atomic;
+
203 
+
204  static size_t num_instances;
+
205 
+
206  PDBGroupMonitor(const PDBGroupPV::shared_pointer& pv,
+
207  const requester_type::weak_pointer& requester,
+
208  const epics::pvData::PVStructure::shared_pointer& pvReq);
+
209  virtual ~PDBGroupMonitor();
+
210 
+
211  virtual void onStart() OVERRIDE FINAL;
+
212  virtual void onStop() OVERRIDE FINAL;
+
213  virtual void requestUpdate() OVERRIDE FINAL;
+
214 
+
215  virtual void destroy() OVERRIDE FINAL;
+
216 
+
217 };
+
218 
+
219 #endif // PDBGROUP_H
+ +
Definition: pvif.h:81
+
Definition: pvif.h:100
+
virtual void requestUpdate() OVERRIDE FINAL
Definition: pdbgroup.cpp:470
+ + + +
Definition: pdb.h:16
+
Definition: pvif.h:223
+ + + + + + + +
+ + + + diff --git a/pdbsingle_8cpp_source.html b/pdbsingle_8cpp_source.html new file mode 100644 index 0000000..37a88cf --- /dev/null +++ b/pdbsingle_8cpp_source.html @@ -0,0 +1,604 @@ + + + + + + +pva2pva: pdbApp/pdbsingle.cpp Source File + + + + + + + + + +
+
+ + + + + + +
+
pva2pva +  1.4.1 +
+
+
+ + + + + + + + + +
+ +
+ + +
+
+
+
pdbsingle.cpp
+
+
+
1 #include <sstream>
+
2 
+
3 #include <string.h>
+
4 
+
5 #include <asLib.h>
+
6 #include <dbAccess.h>
+
7 #include <dbChannel.h>
+
8 #include <dbStaticLib.h>
+
9 #include <errlog.h>
+
10 #include <dbNotify.h>
+
11 #include <osiSock.h>
+
12 #include <epicsAtomic.h>
+
13 
+
14 #include <pv/epicsException.h>
+
15 #include <pv/pvAccess.h>
+
16 #include <pv/security.h>
+
17 #include <pv/configuration.h>
+
18 
+
19 #include "helper.h"
+
20 #include "pdbsingle.h"
+
21 #include "pdb.h"
+
22 
+
23 namespace pvd = epics::pvData;
+
24 namespace pva = epics::pvAccess;
+
25 
+
26 size_t PDBSinglePV::num_instances;
+
27 size_t PDBSingleChannel::num_instances;
+
28 size_t PDBSinglePut::num_instances;
+
29 size_t PDBSingleMonitor::num_instances;
+
30 
+
31 typedef epicsGuard<epicsMutex> Guard;
+
32 
+
33 static
+
34 void pdb_single_event(void *user_arg, struct dbChannel *chan,
+
35  int eventsRemaining, struct db_field_log *pfl)
+
36 {
+
37  DBEvent *evt=(DBEvent*)user_arg;
+
38  try{
+
39  PDBSinglePV::shared_pointer self(std::tr1::static_pointer_cast<PDBSinglePV>(((PDBSinglePV*)evt->self)->shared_from_this()));
+
40  PDBSinglePV::interested_remove_t temp;
+
41  {
+
42  Guard G(self->lock);
+
43 
+
44  // we have exclusive use of self->scratch
+
45  self->scratch.clear();
+
46  {
+
47  DBScanLocker L(dbChannelRecord(self->chan));
+
48  // dbGet() into self->complete
+
49  self->pvif->put(self->scratch, evt->dbe_mask, pfl);
+
50  }
+
51 
+
52  if(evt->dbe_mask&DBE_PROPERTY)
+
53  self->hadevent_PROPERTY = true;
+
54  else
+
55  self->hadevent_VALUE = true;
+
56 
+
57  if(self->hadevent_VALUE && self->hadevent_PROPERTY) {
+
58  self->interested_iterating = true;
+
59 
+
60  FOREACH(PDBSinglePV::interested_t::const_iterator, it, end, self->interested) {
+
61  PDBSingleMonitor& mon = **it;
+
62  // from self->complete into monitor queue element
+
63  mon.post(G, self->scratch); // G unlocked during call
+
64  }
+
65 
+
66  while(!self->interested_add.empty()) {
+
67  PDBSinglePV::interested_t::iterator first(self->interested_add.begin());
+
68  self->interested.insert(*first);
+
69  self->interested_add.erase(first);
+
70  }
+
71 
+
72  temp.swap(self->interested_remove);
+
73  for(PDBSinglePV::interested_remove_t::iterator it(temp.begin()),
+
74  end(temp.end()); it != end; ++it)
+
75  {
+
76  self->interested.erase(static_cast<PDBSingleMonitor*>(it->get()));
+
77  }
+
78 
+
79  self->interested_iterating = false;
+
80 
+
81  self->finalizeMonitor();
+
82  }
+
83  }
+
84 
+
85  }catch(std::tr1::bad_weak_ptr&){
+
86  /* We are racing destruction of the PDBSinglePV, but things are ok.
+
87  * The destructor is running, but has not completed db_cancel_event()
+
88  * so storage is still valid.
+
89  * Just do nothing
+
90  */
+
91  }catch(std::exception& e){
+
92  std::cerr<<"Unhandled exception in pdb_single_event(): "<<e.what()<<"\n"
+
93  <<SHOW_EXCEPTION(e)<<"\n";
+
94  }
+
95 }
+
96 
+
97 PDBSinglePV::PDBSinglePV(DBCH& chan,
+
98  const PDBProvider::shared_pointer& prov)
+
99  :provider(prov)
+
100  ,builder(new ScalarBuilder(chan.chan))
+
101  ,interested_iterating(false)
+
102  ,evt_VALUE(this)
+
103  ,evt_PROPERTY(this)
+
104  ,hadevent_VALUE(false)
+
105  ,hadevent_PROPERTY(false)
+
106 {
+
107  if(ellCount(&chan.chan->pre_chain) || ellCount(&chan.chan->post_chain)) {
+
108  DBCH temp(dbChannelName(chan.chan));
+
109  this->chan2.swap(temp);
+
110  }
+
111  this->chan.swap(chan);
+
112  fielddesc = std::tr1::static_pointer_cast<const pvd::Structure>(builder->dtype());
+
113 
+
114  complete = pvd::getPVDataCreate()->createPVStructure(fielddesc);
+
115  FieldName temp;
+
116  pvif.reset(builder->attach(complete, temp));
+
117 
+
118  epics::atomic::increment(num_instances);
+
119 }
+
120 
+
121 PDBSinglePV::~PDBSinglePV()
+
122 {
+
123  epics::atomic::decrement(num_instances);
+
124 }
+
125 
+
126 void PDBSinglePV::activate()
+
127 {
+
128  dbChannel *pchan = this->chan2.chan ? this->chan2.chan : this->chan.chan;
+
129  evt_VALUE.create(provider->event_context, this->chan, &pdb_single_event, DBE_VALUE|DBE_ALARM);
+
130  evt_PROPERTY.create(provider->event_context, pchan, &pdb_single_event, DBE_PROPERTY);
+
131 }
+
132 
+
133 pva::Channel::shared_pointer
+
134 PDBSinglePV::connect(const std::tr1::shared_ptr<PDBProvider>& prov,
+
135  const pva::ChannelRequester::shared_pointer& req)
+
136 {
+
137  PDBSingleChannel::shared_pointer ret(new PDBSingleChannel(shared_from_this(), req));
+
138 
+
139  ret->cred.update(req);
+
140 
+
141  ret->aspvt.add(chan, ret->cred);
+
142 
+
143  return ret;
+
144 }
+
145 
+
146 void PDBSinglePV::addMonitor(PDBSingleMonitor* mon)
+
147 {
+
148  Guard G(lock);
+
149  if(interested.empty() && interested_add.empty()) {
+
150  // first monitor
+
151  // start subscription
+
152 
+
153  hadevent_VALUE = false;
+
154  hadevent_PROPERTY = false;
+
155  db_event_enable(evt_VALUE.subscript);
+
156  db_event_enable(evt_PROPERTY.subscript);
+
157  db_post_single_event(evt_VALUE.subscript);
+
158  db_post_single_event(evt_PROPERTY.subscript);
+
159 
+
160  } else if(hadevent_VALUE && hadevent_PROPERTY) {
+
161  // new subscriber and already had initial update
+
162  mon->post(G);
+
163  } // else new subscriber, but no initial update. so just wait
+
164 
+
165  if(interested_iterating) {
+
166  interested_add.insert(mon);
+
167  } else {
+
168  interested.insert(mon);
+
169  }
+
170 }
+
171 
+
172 void PDBSinglePV::removeMonitor(PDBSingleMonitor* mon)
+
173 {
+
174  Guard G(lock);
+
175 
+
176  if(interested_add.erase(mon)) {
+
177  // and+remove while iterating. no-op
+
178 
+
179  } else if(interested_iterating) {
+
180  // keep monitor alive while iterating
+
181  interested_remove.insert(mon->shared_from_this());
+
182 
+
183  } else {
+
184  interested.erase(mon);
+
185  finalizeMonitor();
+
186  }
+
187 }
+
188 
+
189 void PDBSinglePV::finalizeMonitor()
+
190 {
+
191  assert(!interested_iterating);
+
192 
+
193  if(interested.empty()) {
+
194  db_event_disable(evt_VALUE.subscript);
+
195  db_event_disable(evt_PROPERTY.subscript);
+
196  }
+
197 }
+
198 
+
199 PDBSingleChannel::PDBSingleChannel(const PDBSinglePV::shared_pointer& pv,
+
200  const pva::ChannelRequester::shared_pointer& req)
+
201  :BaseChannel(dbChannelName(pv->chan), pv->provider, req, pv->fielddesc)
+
202  ,pv(pv)
+
203 {
+
204  assert(!!this->pv);
+
205  epics::atomic::increment(num_instances);
+
206 }
+
207 
+
208 PDBSingleChannel::~PDBSingleChannel()
+
209 {
+
210  epics::atomic::decrement(num_instances);
+
211 }
+
212 
+
213 void PDBSingleChannel::printInfo(std::ostream& out)
+
214 {
+
215  if(aspvt.canWrite())
+
216  out << "RW ";
+
217  else
+
218  out << "RO ";
+
219  out<<(&cred.user[0])<<'@'<<(&cred.host[0]);
+
220  for(size_t i=0, N=cred.groups.size(); i<N; i++) {
+
221  out<<", "<<(&cred.groups[i][0]);
+
222  }
+
223  out<<"\n";
+
224 }
+
225 
+
226 pva::ChannelPut::shared_pointer
+
227 PDBSingleChannel::createChannelPut(
+
228  pva::ChannelPutRequester::shared_pointer const & requester,
+
229  pvd::PVStructure::shared_pointer const & pvRequest)
+
230 {
+
231  PDBSinglePut::shared_pointer ret(new PDBSinglePut(shared_from_this(), requester, pvRequest));
+
232  requester->channelPutConnect(pvd::Status(), ret, fielddesc);
+
233  return ret;
+
234 }
+
235 
+
236 
+
237 pva::Monitor::shared_pointer
+
238 PDBSingleChannel::createMonitor(
+
239  pva::MonitorRequester::shared_pointer const & requester,
+
240  pvd::PVStructure::shared_pointer const & pvRequest)
+
241 {
+
242  PDBSingleMonitor::shared_pointer ret(new PDBSingleMonitor(pv->shared_from_this(), requester, pvRequest));
+
243  ret->weakself = ret;
+
244  assert(!!pv->complete);
+
245  guard_t G(pv->lock);
+
246  ret->connect(G, pv->complete);
+
247  return ret;
+
248 }
+
249 
+
250 
+
251 static
+
252 int single_put_callback(struct processNotify *notify,notifyPutType type)
+
253 {
+
254  PDBSinglePut *self = (PDBSinglePut*)notify->usrPvt;
+
255 
+
256  if(notify->status!=notifyOK) return 0;
+
257 
+
258  // we've previously ensured that wait_changed&DBE_VALUE is true
+
259 
+
260  switch(type) {
+
261  case putDisabledType:
+
262  return 0;
+
263  case putFieldType:
+
264  {
+
265  DBScanLocker L(notify->chan);
+
266  self->wait_pvif->get(*self->wait_changed);
+
267  }
+
268  break;
+
269  case putType:
+
270  self->wait_pvif->get(*self->wait_changed);
+
271  break;
+
272  }
+
273  return 1;
+
274 }
+
275 
+
276 static
+
277 void single_done_callback(struct processNotify *notify)
+
278 {
+
279  PDBSinglePut *self = (PDBSinglePut*)notify->usrPvt;
+
280  pvd::Status sts;
+
281 
+
282  // busy state should be 1 (normal completion) or 2 (if cancel in progress)
+
283  if(epics::atomic::compareAndSwap(self->notifyBusy, 1, 0)==0) {
+
284  std::cerr<<"PDBSinglePut dbNotify state error?\n";
+
285  }
+
286 
+
287  switch(notify->status) {
+
288  case notifyOK:
+
289  break;
+
290  case notifyCanceled:
+
291  return; // skip notification
+
292  case notifyError:
+
293  sts = pvd::Status::error("Error in dbNotify");
+
294  break;
+
295  case notifyPutDisabled:
+
296  sts = pvd::Status::error("Put disabled");
+
297  break;
+
298  }
+
299 
+
300  PDBSinglePut::requester_type::shared_pointer req(self->requester.lock());
+
301  if(req)
+
302  req->putDone(sts, self->shared_from_this());
+
303 }
+
304 
+
305 PDBSinglePut::PDBSinglePut(const PDBSingleChannel::shared_pointer &channel,
+
306  const pva::ChannelPutRequester::shared_pointer &requester,
+
307  const pvd::PVStructure::shared_pointer &pvReq)
+
308  :channel(channel)
+
309  ,requester(requester)
+
310  ,changed(new pvd::BitSet(channel->fielddesc->getNumberFields()))
+
311  ,pvf(pvd::getPVDataCreate()->createPVStructure(channel->fielddesc))
+
312  ,pvif(channel->pv->builder->attach(pvf, FieldName()))
+
313  ,notifyBusy(0)
+
314  ,doProc(PVIF::ProcPassive)
+
315  ,doWait(false)
+
316 {
+
317  epics::atomic::increment(num_instances);
+
318  dbChannel *chan = channel->pv->chan;
+
319 
+
320  try {
+
321  getS<pvd::boolean>(pvReq, "record._options.block", doWait);
+
322  } catch(std::runtime_error& e) {
+
323  requester->message(std::string("block= not understood : ")+e.what(), pva::warningMessage);
+
324  }
+
325 
+
326  std::string proccmd;
+
327  if(getS<std::string>(pvReq, "record._options.process", proccmd)) {
+
328  if(proccmd=="true") {
+
329  doProc = PVIF::ProcForce;
+
330  } else if(proccmd=="false") {
+
331  doProc = PVIF::ProcInhibit;
+
332  doWait = false; // no point in waiting
+
333  } else if(proccmd=="passive") {
+
334  doProc = PVIF::ProcPassive;
+
335  } else {
+
336  requester->message("process= expects: true|false|passive", pva::warningMessage);
+
337  }
+
338  }
+
339 
+
340  memset((void*)&notify, 0, sizeof(notify));
+
341  notify.usrPvt = (void*)this;
+
342  notify.chan = chan;
+
343  notify.putCallback = &single_put_callback;
+
344  notify.doneCallback = &single_done_callback;
+
345 }
+
346 
+
347 PDBSinglePut::~PDBSinglePut()
+
348 {
+
349  cancel();
+
350  epics::atomic::decrement(num_instances);
+
351 }
+
352 
+
353 void PDBSinglePut::put(pvd::PVStructure::shared_pointer const & value,
+
354  pvd::BitSet::shared_pointer const & changed)
+
355 {
+
356  dbChannel *chan = channel->pv->chan;
+
357  dbFldDes *fld = dbChannelFldDes(chan);
+
358 
+
359  AsWritePvt asWritePvt (
+
360  asTrapWriteWithData(channel->aspvt.aspvt,
+
361  std::string(channel->cred.user.begin(), channel->cred.user.end()).c_str(),
+
362  std::string(channel->cred.host.begin(), channel->cred.host.end()).c_str(),
+
363  chan,
+
364  chan->final_type,
+
365  chan->final_no_elements,
+
366  NULL
+
367  )
+
368  );
+
369 
+
370  pvd::Status ret;
+
371  if(!channel->aspvt.canWrite()) {
+
372  ret = pvd::Status::error("Put not permitted");
+
373 
+
374  } else if(dbChannelFieldType(chan)>=DBF_INLINK && dbChannelFieldType(chan)<=DBF_FWDLINK) {
+
375  try{
+
376  std::string lval(value->getSubFieldT<pvd::PVScalar>("value")->getAs<std::string>());
+
377  long status = dbChannelPutField(chan, DBF_STRING, lval.c_str(), 1);
+
378  if(status)
+
379  ret = pvd::Status(pvd::Status::error("dbPutField() error"));
+
380  }catch(std::exception& e) {
+
381  std::ostringstream strm;
+
382  strm<<"Failed to put link field "<<dbChannelName(chan)<<"."<<fld->name<<" : "<<e.what()<<"\n";
+
383  ret = pvd::Status(pvd::Status::error(strm.str()));
+
384  }
+
385 
+
386  } else if(doWait) {
+
387  // TODO: dbNotify doesn't allow us for force processing
+
388 
+
389  // assume value may be a different struct each time
+
390  p2p::auto_ptr<PVIF> putpvif(channel->pv->builder->attach(value, FieldName()));
+
391  unsigned mask = putpvif->dbe(*changed);
+
392 
+
393  if(mask!=DBE_VALUE) {
+
394  requester_type::shared_pointer req(requester.lock());
+
395  if(req)
+
396  req->message("block=true only supports .value (empty put mask)", pva::warningMessage);
+
397  }
+
398 
+
399  if(epics::atomic::compareAndSwap(notifyBusy, 0, 1)!=0)
+
400  throw std::logic_error("Previous put() not complete");
+
401 
+
402  notify.requestType = (mask&DBE_VALUE) ? putProcessRequest : processRequest;
+
403 
+
404  wait_pvif = PTRMOVE(putpvif);
+
405  wait_changed = changed;
+
406 
+
407  dbProcessNotify(&notify);
+
408 
+
409  return; // skip notification
+
410  } else {
+
411  // assume value may be a different struct each time
+
412  p2p::auto_ptr<PVIF> putpvif(channel->pv->builder->attach(value, FieldName()));
+
413  try{
+
414  DBScanLocker L(chan);
+
415  ret = putpvif->get(*changed, doProc);
+
416 
+
417  }catch(std::runtime_error& e){
+
418  ret = pvd::Status::error(e.what());
+
419  }
+
420  }
+
421  requester_type::shared_pointer req(requester.lock());
+
422  if(req)
+
423  req->putDone(ret, shared_from_this());
+
424 }
+
425 
+
426 void PDBSinglePut::cancel()
+
427 {
+
428  if(epics::atomic::compareAndSwap(notifyBusy, 1, 2)==1) {
+
429  dbNotifyCancel(&notify);
+
430  wait_changed.reset();
+
431  wait_pvif.reset();
+
432  epics::atomic::set(notifyBusy, 0);
+
433  }
+
434 }
+
435 
+
436 void PDBSinglePut::get()
+
437 {
+
438  changed->clear();
+
439  {
+
440  DBScanLocker L(pvif->chan);
+
441  LocalFL FL(NULL, pvif->chan);
+
442  pvif->put(*changed, DBE_VALUE|DBE_ALARM|DBE_PROPERTY, FL.pfl);
+
443  }
+
444  //TODO: report unused fields as changed?
+
445  changed->clear();
+
446  changed->set(0);
+
447 
+
448  requester_type::shared_pointer req(requester.lock());
+
449  if(req)
+
450  req->getDone(pvd::Status(), shared_from_this(), pvf, changed);
+
451 }
+
452 
+
453 PDBSingleMonitor::PDBSingleMonitor(const PDBSinglePV::shared_pointer& pv,
+
454  const requester_t::shared_pointer& requester,
+
455  const pvd::PVStructure::shared_pointer& pvReq)
+
456  :BaseMonitor(pv->lock, requester, pvReq)
+
457  ,pv(pv)
+
458 {
+
459  epics::atomic::increment(num_instances);
+
460 }
+
461 
+
462 PDBSingleMonitor::~PDBSingleMonitor()
+
463 {
+
464  destroy();
+
465  epics::atomic::decrement(num_instances);
+
466 }
+
467 
+
468 void PDBSingleMonitor::destroy()
+
469 {
+
470  BaseMonitor::destroy();
+
471 }
+
472 
+
473 void PDBSingleMonitor::onStart()
+
474 {
+
475  pv->addMonitor(this);
+
476 }
+
477 
+
478 void PDBSingleMonitor::onStop()
+
479 {
+
480  guard_t G(pv->lock);
+
481 
+
482  pv->removeMonitor(this);
+
483 }
+
484 
+ +
486 {
+
487  guard_t G(pv->lock);
+
488  post(G);
+
489 }
+
virtual void requestUpdate() OVERRIDE FINAL
Definition: pdbsingle.cpp:485
+
bool post(guard_t &guard, const epics::pvData::BitSet &updated, no_overflow)
post update if queue not full, if full return false w/o overflow
Definition: pvahelper.h:136
+
Definition: pvif.h:81
+
Definition: pvif.h:365
+ + +
Definition: pdb.h:77
+ + +
Definition: pvif.h:223
+ + + +
Definition: pvif.h:250
+ + +
+ + + + diff --git a/pdbsingle_8h_source.html b/pdbsingle_8h_source.html new file mode 100644 index 0000000..a7ef78b --- /dev/null +++ b/pdbsingle_8h_source.html @@ -0,0 +1,269 @@ + + + + + + +pva2pva: pdbApp/pdbsingle.h Source File + + + + + + + + + +
+
+ + + + + + +
+
pva2pva +  1.4.1 +
+
+
+ + + + + + + + + +
+ +
+ + +
+
+
+
pdbsingle.h
+
+
+
1 #ifndef PDBSINGLE_H
+
2 #define PDBSINGLE_H
+
3 
+
4 #include <deque>
+
5 
+
6 #include <dbAccess.h>
+
7 #include <dbNotify.h>
+
8 #include <asLib.h>
+
9 
+
10 #include <dbEvent.h>
+
11 
+
12 #include <pv/pvAccess.h>
+
13 
+
14 #include "helper.h"
+
15 #include "pvahelper.h"
+
16 #include "pvif.h"
+
17 #include "pdb.h"
+
18 
+
19 struct PDBSingleMonitor;
+
20 
+
21 struct QSRV_API PDBSinglePV : public PDBPV
+
22 {
+
23  POINTER_DEFINITIONS(PDBSinglePV);
+
24  weak_pointer weakself;
+
25  inline shared_pointer shared_from_this() { return shared_pointer(weakself); }
+
26 
+
27  /* this dbChannel is shared by all operations,
+
28  * which is safe as it's modify-able field(s) (addr.pfield)
+
29  * are only access while the underlying record
+
30  * is locked.
+
31  */
+
32  DBCH chan;
+
33  // used for DBE_PROPERTY subscription when chan has filters
+
34  DBCH chan2;
+
35  PDBProvider::shared_pointer provider;
+
36 
+
37  // only for use in pdb_single_event()
+
38  // which is not concurrent for VALUE/PROPERTY.
+
39  epics::pvData::BitSet scratch;
+
40 
+
41  epicsMutex lock;
+
42 
+
43  p2p::auto_ptr<ScalarBuilder> builder;
+
44  p2p::auto_ptr<PVIF> pvif;
+
45 
+
46  epics::pvData::PVStructurePtr complete; // complete copy from subscription
+
47 
+
48  typedef std::set<PDBSingleMonitor*> interested_t;
+
49  bool interested_iterating;
+
50  interested_t interested, interested_add;
+
51 
+
52  typedef std::set<BaseMonitor::shared_pointer> interested_remove_t;
+
53  interested_remove_t interested_remove;
+
54 
+
55  DBEvent evt_VALUE, evt_PROPERTY;
+
56  bool hadevent_VALUE, hadevent_PROPERTY;
+
57 
+
58  static size_t num_instances;
+
59 
+
60  PDBSinglePV(DBCH& chan,
+
61  const PDBProvider::shared_pointer& prov);
+
62  virtual ~PDBSinglePV();
+
63 
+
64  void activate();
+
65 
+
66  virtual
+
67  epics::pvAccess::Channel::shared_pointer
+
68  connect(const std::tr1::shared_ptr<PDBProvider>& prov,
+
69  const epics::pvAccess::ChannelRequester::shared_pointer& req) OVERRIDE FINAL;
+
70 
+
71  void addMonitor(PDBSingleMonitor*);
+
72  void removeMonitor(PDBSingleMonitor*);
+
73  void finalizeMonitor();
+
74 };
+
75 
+
76 struct PDBSingleChannel : public BaseChannel,
+
77  public std::tr1::enable_shared_from_this<PDBSingleChannel>
+
78 {
+
79  POINTER_DEFINITIONS(PDBSingleChannel);
+
80 
+
81  PDBSinglePV::shared_pointer pv;
+
82  // storage referenced from aspvt
+
83  ASCred cred;
+
84  ASCLIENT aspvt;
+
85 
+
86  static size_t num_instances;
+
87 
+
88  PDBSingleChannel(const PDBSinglePV::shared_pointer& pv,
+
89  const epics::pvAccess::ChannelRequester::shared_pointer& req);
+
90  virtual ~PDBSingleChannel();
+
91 
+
92  virtual epics::pvAccess::ChannelPut::shared_pointer createChannelPut(
+
93  epics::pvAccess::ChannelPutRequester::shared_pointer const & requester,
+
94  epics::pvData::PVStructure::shared_pointer const & pvRequest) OVERRIDE FINAL;
+
95  virtual epics::pvData::Monitor::shared_pointer createMonitor(
+
96  epics::pvData::MonitorRequester::shared_pointer const & requester,
+
97  epics::pvData::PVStructure::shared_pointer const & pvRequest) OVERRIDE FINAL;
+
98 
+
99  virtual void printInfo(std::ostream& out) OVERRIDE FINAL;
+
100 };
+
101 
+
102 struct PDBSinglePut : public epics::pvAccess::ChannelPut,
+
103  public std::tr1::enable_shared_from_this<PDBSinglePut>
+
104 {
+
105  POINTER_DEFINITIONS(PDBSinglePut);
+
106 
+
107  typedef epics::pvAccess::ChannelPutRequester requester_t;
+
108  PDBSingleChannel::shared_pointer channel;
+
109  requester_t::weak_pointer requester;
+
110 
+
111  epics::pvData::BitSetPtr changed, wait_changed;
+
112  epics::pvData::PVStructurePtr pvf;
+
113  p2p::auto_ptr<PVIF> pvif, wait_pvif;
+
114  processNotify notify;
+
115  int notifyBusy; // atomic: 0 - idle, 1 - active, 2 - being cancelled
+
116 
+
117  // effectively const after ctor
+
118  PVIF::proc_t doProc;
+
119  bool doWait;
+
120 
+
121  static size_t num_instances;
+
122 
+
123  PDBSinglePut(const PDBSingleChannel::shared_pointer& channel,
+
124  const epics::pvAccess::ChannelPutRequester::shared_pointer& requester,
+
125  const epics::pvData::PVStructure::shared_pointer& pvReq);
+
126  virtual ~PDBSinglePut();
+
127 
+
128  virtual void destroy() OVERRIDE FINAL { pvif.reset(); channel.reset(); requester.reset(); }
+
129  virtual std::tr1::shared_ptr<epics::pvAccess::Channel> getChannel() OVERRIDE FINAL { return channel; }
+
130  virtual void cancel() OVERRIDE FINAL;
+
131  virtual void lastRequest() OVERRIDE FINAL {}
+
132  virtual void put(
+
133  epics::pvData::PVStructure::shared_pointer const & pvPutStructure,
+
134  epics::pvData::BitSet::shared_pointer const & putBitSet) OVERRIDE FINAL;
+
135  virtual void get() OVERRIDE FINAL;
+
136 };
+
137 
+ +
139 {
+
140  POINTER_DEFINITIONS(PDBSingleMonitor);
+
141 
+
142  const PDBSinglePV::shared_pointer pv;
+
143 
+
144  static size_t num_instances;
+
145 
+
146  PDBSingleMonitor(const PDBSinglePV::shared_pointer& pv,
+
147  const requester_t::shared_pointer& requester,
+
148  const epics::pvData::PVStructure::shared_pointer& pvReq);
+
149  virtual ~PDBSingleMonitor();
+
150 
+
151  virtual void onStart() OVERRIDE FINAL;
+
152  virtual void onStop() OVERRIDE FINAL;
+
153  virtual void requestUpdate() OVERRIDE FINAL;
+
154 
+
155  virtual void destroy() OVERRIDE FINAL;
+
156 };
+
157 
+
158 #endif // PDBSINGLE_H
+
virtual void requestUpdate() OVERRIDE FINAL
Definition: pdbsingle.cpp:485
+
Definition: pvif.h:107
+
Definition: pvif.h:81
+
Definition: pvif.h:100
+ + + +
Definition: pdb.h:16
+
Definition: pvif.h:223
+ + + +
+ + + + diff --git a/pva2pva_8h_source.html b/pva2pva_8h_source.html new file mode 100644 index 0000000..c25b0bd --- /dev/null +++ b/pva2pva_8h_source.html @@ -0,0 +1,115 @@ + + + + + + +pva2pva: p2pApp/pva2pva.h Source File + + + + + + + + + +
+
+ + + + + + +
+
pva2pva +  1.4.1 +
+
+
+ + + + + + + + + +
+ +
+ + +
+
+
+
pva2pva.h
+
+
+
1 #ifndef PVA2PVA_H
+
2 #define PVA2PVA_H
+
3 
+
4 #include <epicsGuard.h>
+
5 
+
6 #include <pv/pvAccess.h>
+
7 
+
8 typedef epicsGuard<epicsMutex> Guard;
+
9 typedef epicsGuardRelease<epicsMutex> UnGuard;
+
10 
+
11 void registerGWClientIocsh();
+
12 void gwServerShutdown();
+
13 void gwClientShutdown();
+
14 void registerReadOnly();
+
15 
+
16 #endif // PVA2PVA_H
+
+ + + + diff --git a/pvahelper_8h_source.html b/pvahelper_8h_source.html new file mode 100644 index 0000000..1a230d6 --- /dev/null +++ b/pvahelper_8h_source.html @@ -0,0 +1,474 @@ + + + + + + +pva2pva: common/pvahelper.h Source File + + + + + + + + + +
+
+ + + + + + +
+
pva2pva +  1.4.1 +
+
+
+ + + + + + + + + +
+ +
+ + +
+
+
+
pvahelper.h
+
+
+
1 #ifndef PVAHELPER_H
+
2 #define PVAHELPER_H
+
3 
+
4 #include <deque>
+
5 
+
6 #include <epicsGuard.h>
+
7 
+
8 #include <pv/pvAccess.h>
+
9 
+
10 template<typename T, typename A>
+
11 bool getS(const epics::pvData::PVStructurePtr& S, const char *name, A& val)
+
12 {
+
13  epics::pvData::PVScalarPtr F(S->getSubField<epics::pvData::PVScalar>(name));
+
14  if(F)
+
15  val = F->getAs<T>();
+
16  return !!F;
+
17 }
+
18 
+
19 struct BaseChannel : public epics::pvAccess::Channel
+
20 {
+
21  BaseChannel(const std::string& name,
+
22  const std::tr1::weak_ptr<epics::pvAccess::ChannelProvider>& prov,
+
23  const epics::pvAccess::ChannelRequester::shared_pointer& req,
+
24  const epics::pvData::StructureConstPtr& dtype
+
25  )
+
26  :pvname(name), provider(prov), requester(req), fielddesc(dtype)
+
27  {}
+
28  virtual ~BaseChannel() {}
+
29 
+
30  mutable epicsMutex lock;
+
31  typedef epicsGuard<epicsMutex> guard_t;
+
32 
+
33  const std::string pvname;
+
34  const epics::pvAccess::ChannelProvider::weak_pointer provider;
+
35  const requester_type::weak_pointer requester;
+
36  const epics::pvData::StructureConstPtr fielddesc;
+
37 
+
38  // assume Requester methods not called after destory()
+
39  virtual std::string getRequesterName() OVERRIDE
+
40  { return getChannelRequester()->getRequesterName(); }
+
41 
+
42  virtual void destroy() OVERRIDE FINAL {}
+
43 
+
44  virtual std::tr1::shared_ptr<epics::pvAccess::ChannelProvider> getProvider() OVERRIDE FINAL
+
45  { return epics::pvAccess::ChannelProvider::shared_pointer(provider); }
+
46  virtual std::string getRemoteAddress() OVERRIDE
+
47  { return getRequesterName(); }
+
48 
+
49  virtual std::string getChannelName() OVERRIDE FINAL { return pvname; }
+
50  virtual std::tr1::shared_ptr<epics::pvAccess::ChannelRequester> getChannelRequester() OVERRIDE FINAL
+
51  { return requester_type::shared_pointer(requester); }
+
52 
+
53  virtual void getField(epics::pvAccess::GetFieldRequester::shared_pointer const & requester,std::string const & subField) OVERRIDE
+
54  { requester->getDone(epics::pvData::Status(), fielddesc); }
+
55 
+
56  virtual void printInfo(std::ostream& out) OVERRIDE {
+
57  out<<"Channel '"<<pvname<<"' "<<getRemoteAddress()<<"\n";
+
58  }
+
59 };
+
60 
+
69 struct BaseMonitor : public epics::pvAccess::Monitor
+
70 {
+
71  POINTER_DEFINITIONS(BaseMonitor);
+
72  weak_pointer weakself;
+
73  inline shared_pointer shared_from_this() { return shared_pointer(weakself); }
+
74 
+
75  typedef epics::pvAccess::MonitorRequester requester_t;
+
76 
+
77  epicsMutex& lock; // not held during any callback
+
78  typedef epicsGuard<epicsMutex> guard_t;
+
79  typedef epicsGuardRelease<epicsMutex> unguard_t;
+
80 
+
81 private:
+
82  const requester_t::weak_pointer requester;
+
83 
+
84  epics::pvData::PVStructurePtr complete;
+
85  epics::pvData::BitSet changed, overflow;
+
86 
+
87  typedef std::deque<epics::pvAccess::MonitorElementPtr> buffer_t;
+
88  bool inoverflow;
+
89  bool running;
+
90  size_t nbuffers;
+
91  buffer_t inuse, empty;
+
92 
+
93 public:
+
94  BaseMonitor(epicsMutex& lock,
+
95  const requester_t::weak_pointer& requester,
+
96  const epics::pvData::PVStructure::shared_pointer& pvReq)
+
97  :lock(lock)
+
98  ,requester(requester)
+
99  ,inoverflow(false)
+
100  ,running(false)
+
101  ,nbuffers(2)
+
102  {}
+
103 
+
104  virtual ~BaseMonitor() {destroy();}
+
105 
+
106  inline const epics::pvData::PVStructurePtr& getValue() { return complete; }
+
107 
+
110  void connect(guard_t& guard, const epics::pvData::PVStructurePtr& value)
+
111  {
+
112  guard.assertIdenticalMutex(lock);
+
113  epics::pvData::StructureConstPtr dtype(value->getStructure());
+
114  epics::pvData::PVDataCreatePtr create(epics::pvData::getPVDataCreate());
+
115  BaseMonitor::shared_pointer self(shared_from_this());
+
116  requester_t::shared_pointer req(requester.lock());
+
117 
+
118  assert(!complete); // can't call twice
+
119 
+
120  complete = value;
+
121  empty.resize(nbuffers);
+
122  for(size_t i=0; i<empty.size(); i++) {
+
123  empty[i].reset(new epics::pvAccess::MonitorElement(create->createPVStructure(dtype)));
+
124  }
+
125 
+
126  if(req) {
+
127  unguard_t U(guard);
+
128  epics::pvData::Status sts;
+
129  req->monitorConnect(sts, self, dtype);
+
130  }
+
131  }
+
132 
+
133  struct no_overflow {};
+
134 
+
136  bool post(guard_t& guard, const epics::pvData::BitSet& updated, no_overflow)
+
137  {
+
138  guard.assertIdenticalMutex(lock);
+
139  requester_t::shared_pointer req;
+
140 
+
141  if(!complete || !running) return false;
+
142 
+
143  changed |= updated;
+
144 
+
145  if(empty.empty()) return false;
+
146 
+
147  if(p_postone())
+
148  req = requester.lock();
+
149  inoverflow = false;
+
150 
+
151  if(req) {
+
152  unguard_t U(guard);
+
153  req->monitorEvent(shared_from_this());
+
154  }
+
155  return true;
+
156  }
+
157 
+
159  bool post(guard_t& guard)
+
160  {
+
161  guard.assertIdenticalMutex(lock);
+
162  bool oflow;
+
163  requester_t::shared_pointer req;
+
164 
+
165  if(!complete || !running) return false;
+
166 
+
167  if(empty.empty()) {
+
168  oflow = inoverflow = true;
+
169 
+
170  } else {
+
171 
+
172  if(p_postone())
+
173  req = requester.lock();
+
174  oflow = inoverflow = false;
+
175  }
+
176 
+
177  if(req) {
+
178  unguard_t U(guard);
+
179  req->monitorEvent(shared_from_this());
+
180  }
+
181  return !oflow;
+
182  }
+
183 
+
185  bool post(guard_t& guard,
+
186  const epics::pvData::BitSet& updated,
+
187  const epics::pvData::BitSet& overflowed)
+
188  {
+
189  guard.assertIdenticalMutex(lock);
+
190  bool oflow;
+
191  requester_t::shared_pointer req;
+
192 
+
193  if(!complete || !running) return false;
+
194 
+
195  if(empty.empty()) {
+
196  oflow = inoverflow = true;
+
197  overflow |= overflowed;
+
198  overflow.or_and(updated, changed);
+
199  changed |= updated;
+
200 
+
201  } else {
+
202 
+
203  changed |= updated;
+
204  if(p_postone())
+
205  req = requester.lock();
+
206  oflow = inoverflow = false;
+
207  }
+
208 
+
209  if(req) {
+
210  unguard_t U(guard);
+
211  req->monitorEvent(shared_from_this());
+
212  }
+
213  return !oflow;
+
214  }
+
215 
+
217  bool post(guard_t& guard, const epics::pvData::BitSet& updated) {
+
218  bool oflow;
+
219  requester_t::shared_pointer req;
+
220 
+
221  if(!complete || !running) return false;
+
222 
+
223  if(empty.empty()) {
+
224  oflow = inoverflow = true;
+
225  overflow.or_and(updated, changed);
+
226  changed |= updated;
+
227 
+
228  } else {
+
229 
+
230  changed |= updated;
+
231  if(p_postone())
+
232  req = requester.lock();
+
233  oflow = inoverflow = false;
+
234  }
+
235 
+
236  if(req) {
+
237  unguard_t U(guard);
+
238  req->monitorEvent(shared_from_this());
+
239  }
+
240  return !oflow;
+
241  }
+
242 
+
243 private:
+
244  bool p_postone()
+
245  {
+
246  bool ret;
+
247  // assume lock is held
+
248  assert(!empty.empty());
+
249 
+
250  epics::pvAccess::MonitorElementPtr& elem = empty.front();
+
251 
+
252  elem->pvStructurePtr->copyUnchecked(*complete);
+
253  *elem->changedBitSet = changed;
+
254  *elem->overrunBitSet = overflow;
+
255 
+
256  overflow.clear();
+
257  changed.clear();
+
258 
+
259  ret = inuse.empty();
+
260  inuse.push_back(elem);
+
261  empty.pop_front();
+
262  return ret;
+
263  }
+
264 public:
+
265 
+
266  // for special handling when MonitorRequester start()s or stop()s
+
267  virtual void onStart() {}
+
268  virtual void onStop() {}
+
271  virtual void requestUpdate() {guard_t G(lock); post(G);}
+
272 
+
273  virtual void destroy()
+
274  {
+
275  stop();
+
276  }
+
277 
+
278 private:
+
279  virtual epics::pvData::Status start()
+
280  {
+
281  epics::pvData::Status ret;
+
282  bool notify = false;
+
283  BaseMonitor::shared_pointer self;
+
284  {
+
285  guard_t G(lock);
+
286  if(running) return ret;
+
287  running = true;
+
288  if(!complete) return ret; // haveType() not called (error?)
+
289  inoverflow = empty.empty();
+
290  if(!inoverflow) {
+
291 
+
292  // post complete event
+
293  overflow.clear();
+
294  changed.clear();
+
295  changed.set(0);
+
296  notify = true;
+
297  }
+
298  }
+
299  if(notify) onStart(); // may result in post()
+
300  return ret;
+
301  }
+
302 
+
303  virtual epics::pvData::Status stop()
+
304  {
+
305  BaseMonitor::shared_pointer self;
+
306  bool notify;
+
307  epics::pvData::Status ret;
+
308  {
+
309  guard_t G(lock);
+
310  notify = running;
+
311  running = false;
+
312  }
+
313  if(notify) onStop();
+
314  return ret;
+
315  }
+
316 
+
317  virtual epics::pvAccess::MonitorElementPtr poll()
+
318  {
+
319  epics::pvAccess::MonitorElementPtr ret;
+
320  guard_t G(lock);
+
321  if(running && complete && !inuse.empty()) {
+
322  ret = inuse.front();
+
323  inuse.pop_front();
+
324  }
+
325  return ret;
+
326  }
+
327 
+
328  virtual void release(epics::pvAccess::MonitorElementPtr const & elem)
+
329  {
+
330  BaseMonitor::shared_pointer self;
+
331  {
+
332  guard_t G(lock);
+
333  empty.push_back(elem);
+
334  if(inoverflow)
+
335  self = weakself.lock(); //TODO: concurrent release?
+
336  }
+
337  if(self)
+
338  self->requestUpdate(); // may result in post()
+
339  }
+
340 public:
+
341  virtual void getStats(Stats& s) const
+
342  {
+
343  guard_t G(lock);
+
344  s.nempty = empty.size();
+
345  s.nfilled = inuse.size();
+
346  s.noutstanding = nbuffers - s.nempty - s.nfilled;
+
347  }
+
348 };
+
349 
+
350 template<class CP>
+
351 struct BaseChannelProviderFactory : epics::pvAccess::ChannelProviderFactory
+
352 {
+
353  typedef CP provider_type;
+
354  std::string name;
+
355  epicsMutex lock;
+
356  std::tr1::weak_ptr<CP> last_shared;
+
357 
+
358  BaseChannelProviderFactory(const char *name) :name(name) {}
+
359  virtual ~BaseChannelProviderFactory() {}
+
360 
+
361  virtual std::string getFactoryName() { return name; }
+
362 
+
363  virtual epics::pvAccess::ChannelProvider::shared_pointer sharedInstance()
+
364  {
+
365  epicsGuard<epicsMutex> G(lock);
+
366  std::tr1::shared_ptr<CP> ret(last_shared.lock());
+
367  if(!ret) {
+
368  ret.reset(new CP());
+
369  last_shared = ret;
+
370  }
+
371  return ret;
+
372  }
+
373 
+
374  virtual epics::pvAccess::ChannelProvider::shared_pointer newInstance(const std::tr1::shared_ptr<epics::pvAccess::Configuration>&)
+
375  {
+
376  std::tr1::shared_ptr<CP> ret(new CP());
+
377  return ret;
+
378  }
+
379 };
+
380 
+
381 #endif // PVAHELPER_H
+
bool post(guard_t &guard, const epics::pvData::BitSet &updated)
post update with changed
Definition: pvahelper.h:217
+
bool post(guard_t &guard, const epics::pvData::BitSet &updated, no_overflow)
post update if queue not full, if full return false w/o overflow
Definition: pvahelper.h:136
+
bool post(guard_t &guard)
post update of pending changes. eg. call from requestUpdate()
Definition: pvahelper.h:159
+
void connect(guard_t &guard, const epics::pvData::PVStructurePtr &value)
Definition: pvahelper.h:110
+ +
virtual void requestUpdate()
Definition: pvahelper.h:271
+ + + +
bool post(guard_t &guard, const epics::pvData::BitSet &updated, const epics::pvData::BitSet &overflowed)
post update with changed and overflowed masks (eg. when updates were lost in some upstream queue) ...
Definition: pvahelper.h:185
+
+ + + + diff --git a/pvalink_8cpp_source.html b/pvalink_8cpp_source.html new file mode 100644 index 0000000..a34d124 --- /dev/null +++ b/pvalink_8cpp_source.html @@ -0,0 +1,456 @@ + + + + + + +pva2pva: pdbApp/pvalink.cpp Source File + + + + + + + + + +
+
+ + + + + + +
+
pva2pva +  1.4.1 +
+
+
+ + + + + + + + + +
+ +
+ + +
+
+
+
pvalink.cpp
+
+
+
1 
+
2 #include <set>
+
3 #include <map>
+
4 
+
5 #define EPICS_DBCA_PRIVATE_API
+
6 #include <epicsGuard.h>
+
7 #include <dbAccess.h>
+
8 #include <dbCommon.h>
+
9 #include <dbLink.h>
+
10 #include <dbScan.h>
+
11 #include <errlog.h>
+
12 #include <initHooks.h>
+
13 #include <alarm.h>
+
14 #include <epicsExit.h>
+
15 #include <epicsAtomic.h>
+
16 #include <link.h>
+
17 #include <dbJLink.h>
+
18 #include <epicsUnitTest.h>
+
19 #include <epicsString.h>
+
20 
+
21 #include <epicsStdio.h> /* redirects stdout/stderr */
+
22 
+
23 #include <pv/pvAccess.h>
+
24 #include <pv/clientFactory.h>
+
25 #include <pv/iocshelper.h>
+
26 #include <pv/reftrack.h>
+
27 #include <pva/client.h>
+
28 
+
29 #include "pv/qsrv.h"
+
30 #include "helper.h"
+
31 #include "pvif.h"
+
32 #include "pvalink.h"
+
33 
+
34 #include <epicsExport.h> /* defines epicsExportSharedSymbols */
+
35 
+
36 #if EPICS_VERSION_INT>=VERSION_INT(7,0,6,0)
+
37 # define HAVE_SHUTDOWN_HOOKS
+
38 #endif
+
39 
+
40 int pvaLinkDebug;
+
41 int pvaLinkIsolate;
+
42 
+
43 using namespace pvalink;
+
44 
+
45 namespace {
+
46 
+
47 // halt, and clear, scan workers before dbCloseLinks() (cf. iocShutdown())
+
48 static void shutdownStep1()
+
49 {
+
50  // no locking here as we assume that shutdown doesn't race startup
+
51  if(!pvaGlobal) return;
+
52 
+
53  pvaGlobal->queue.close();
+
54 }
+
55 
+
56 // Cleanup pvaGlobal, including PVA client and QSRV providers ahead of PDB cleanup
+
57 // specifically QSRV provider must be free'd prior to db_cleanup_events()
+
58 static void shutdownStep2()
+
59 {
+
60  if(!pvaGlobal) return;
+
61 
+
62  {
+
63  Guard G(pvaGlobal->lock);
+
64  if(pvaGlobal->channels.size()) {
+
65  fprintf(stderr, "pvaLink leaves %zu channels open\n",
+
66  pvaGlobal->channels.size());
+
67  }
+
68  }
+
69 
+
70  delete pvaGlobal;
+
71  pvaGlobal = NULL;
+
72 }
+
73 
+
74 #ifndef HAVE_SHUTDOWN_HOOKS
+
75 static void stopPVAPool(void*)
+
76 {
+
77  try {
+
78  shutdownStep1();
+
79  }catch(std::exception& e){
+
80  fprintf(stderr, "Error while stopping PVA link pool : %s\n", e.what());
+
81  }
+
82 }
+
83 
+
84 static void finalizePVA(void*)
+
85 {
+
86  try {
+
87  shutdownStep2();
+
88  }catch(std::exception& e){
+
89  fprintf(stderr, "Error initializing pva link handling : %s\n", e.what());
+
90  }
+
91 }
+
92 #endif
+
93 
+
94 /* The Initialization game...
+
95  *
+
96  * # Parse links during dbPutString() (calls our jlif*)
+
97  * # announce initHookAfterCaLinkInit
+
98  * # dbChannelInit() (needed for QSRV to work)
+
99  * # Re-parse links (calls to our jlif*)
+
100  * # Open links. Calls jlif::get_lset() and then lset::openLink()
+
101  * # announce initHookAfterInitDatabase
+
102  * # ... scan threads start ...
+
103  * # announce initHookAfterIocBuilt
+
104  */
+
105 void initPVALink(initHookState state)
+
106 {
+
107  try {
+
108  if(state==initHookAfterCaLinkInit) {
+
109  // before epicsExit(exitDatabase),
+
110  // so hook registered here will be run after iocShutdown()
+
111  // which closes links
+
112  if(pvaGlobal) {
+
113  cantProceed("# Missing call to testqsrvShutdownOk() and/or testqsrvCleanup()");
+
114  }
+
115  pvaGlobal = new pvaGlobal_t;
+
116 
+
117 #ifndef HAVE_SHUTDOWN_HOOKS
+
118  static bool atexitInstalled;
+
119  if(!atexitInstalled) {
+
120  epicsAtExit(finalizePVA, NULL);
+
121  atexitInstalled = true;
+
122  }
+
123 #endif
+
124 
+
125  } else if(state==initHookAfterInitDatabase) {
+
126  pvac::ClientProvider local("server:QSRV"),
+
127  remote("pva");
+
128  pvaGlobal->provider_local = local;
+
129  pvaGlobal->provider_remote = remote;
+
130 
+
131  } else if(state==initHookAfterIocBuilt) {
+
132  // after epicsExit(exitDatabase)
+
133  // so hook registered here will be run before iocShutdown()
+
134 
+
135 #ifndef HAVE_SHUTDOWN_HOOKS
+
136  epicsAtExit(stopPVAPool, NULL);
+
137 #endif
+
138 
+
139  Guard G(pvaGlobal->lock);
+
140  pvaGlobal->running = true;
+
141 
+
142  for(pvaGlobal_t::channels_t::iterator it(pvaGlobal->channels.begin()), end(pvaGlobal->channels.end());
+
143  it != end; ++it)
+
144  {
+
145  std::tr1::shared_ptr<pvaLinkChannel> chan(it->second.lock());
+
146  if(!chan) continue;
+
147 
+
148  chan->open();
+
149  }
+
150 #ifdef HAVE_SHUTDOWN_HOOKS
+
151  } else if(state==initHookAtShutdown) {
+
152  shutdownStep1();
+
153 
+
154  } else if(state==initHookAfterShutdown) {
+
155  shutdownStep2();
+
156 #endif
+
157  }
+
158  }catch(std::exception& e){
+
159  cantProceed("Error initializing pva link handling : %s\n", e.what());
+
160  }
+
161 }
+
162 
+
163 } // namespace
+
164 
+
165 // halt, and clear, scan workers before dbCloseLinks() (cf. iocShutdown())
+
166 void testqsrvShutdownOk(void)
+
167 {
+
168  try {
+
169  shutdownStep1();
+
170  }catch(std::exception& e){
+
171  testAbort("Error while stopping PVA link pool : %s\n", e.what());
+
172  }
+
173 }
+
174 
+
175 void testqsrvCleanup(void)
+
176 {
+
177  try {
+
178  shutdownStep2();
+
179  }catch(std::exception& e){
+
180  testAbort("Error initializing pva link handling : %s\n", e.what());
+
181  }
+
182 }
+
183 
+
184 void testqsrvWaitForLinkEvent(struct link *plink)
+
185 {
+
186  std::tr1::shared_ptr<pvaLinkChannel> lchan;
+
187  {
+
188  DBScanLocker lock(plink->precord);
+
189 
+
190  if(plink->type!=JSON_LINK || !plink->value.json.jlink || plink->value.json.jlink->pif!=&lsetPVA) {
+
191  testAbort("Not a PVA link");
+
192  }
+
193  pvaLink *pval = static_cast<pvaLink*>(plink->value.json.jlink);
+
194  lchan = pval->lchan;
+
195  }
+
196  if(lchan) {
+
197  lchan->run_done.wait();
+
198  }
+
199 }
+
200 
+
201 extern "C"
+
202 void dbpvar(const char *precordname, int level)
+
203 {
+
204  try {
+
205  if(!pvaGlobal) {
+
206  printf("PVA links not initialized\n");
+
207  return;
+
208  }
+
209 
+
210  if (!precordname || precordname[0] == '\0' || !strcmp(precordname, "*")) {
+
211  precordname = NULL;
+
212  printf("PVA links in all records\n\n");
+
213  } else {
+
214  printf("PVA links in record named '%s'\n\n", precordname);
+
215  }
+
216 
+
217  size_t nchans = 0, nlinks = 0, nconn = 0;
+
218 
+
219  pvaGlobal_t::channels_t channels;
+
220  {
+
221  Guard G(pvaGlobal->lock);
+
222  channels = pvaGlobal->channels; // copy snapshot
+
223  }
+
224 
+
225  for(pvaGlobal_t::channels_t::const_iterator it(channels.begin()), end(channels.end());
+
226  it != end; ++it)
+
227  {
+
228  std::tr1::shared_ptr<pvaLinkChannel> chan(it->second.lock());
+
229  if(!chan) continue;
+
230 
+
231  Guard G(chan->lock);
+
232 
+
233  if(precordname) {
+
234  // only show links fields of these records
+
235  bool match = false;
+
236  for(pvaLinkChannel::links_t::const_iterator it2(chan->links.begin()), end2(chan->links.end());
+
237  it2 != end2; ++it2)
+
238  {
+
239  const pvaLink *pval = *it2;
+
240  // plink==NULL shouldn't happen, but we are called for debugging, so be paranoid.
+
241  if(pval->plink && epicsStrGlobMatch(pval->plink->precord->name, precordname)) {
+
242  match = true;
+
243  nlinks++;
+
244  }
+
245  }
+
246  if(!match)
+
247  continue;
+
248  }
+
249 
+
250  nchans++;
+
251  if(chan->connected_latched)
+
252  nconn++;
+
253 
+
254  if(!precordname)
+
255  nlinks += chan->links.size();
+
256 
+
257  if(level<=0)
+
258  continue;
+
259 
+
260  if(level>=2 || (!chan->connected_latched && level==1)) {
+
261  if(chan->key.first.size()<=28) {
+
262  printf("%28s ", chan->key.first.c_str());
+
263  } else {
+
264  printf("%s\t", chan->key.first.c_str());
+
265  }
+
266 
+
267  printf("conn=%c %zu disconnects, %zu type changes",
+
268  chan->connected_latched?'T':'F',
+
269  chan->num_disconnect,
+
270  chan->num_type_change);
+
271  if(chan->op_put.valid()) {
+
272  printf(" Put");
+
273  }
+
274 
+
275  if(level>=3) {
+
276  printf(", provider '%s'", chan->providerName.c_str());
+
277  }
+
278  printf("\n");
+
279  // level 4 reserved for channel/provider details
+
280 
+
281  if(level>=5) {
+
282  for(pvaLinkChannel::links_t::const_iterator it2(chan->links.begin()), end2(chan->links.end());
+
283  it2 != end2; ++it2)
+
284  {
+
285  const pvaLink *pval = *it2;
+
286 
+
287  if(!pval->plink)
+
288  continue;
+
289  else if(precordname && !epicsStrGlobMatch(pval->plink->precord->name, precordname))
+
290  continue;
+
291 
+
292  const char *fldname = "???";
+
293  pdbRecordIterator rec(pval->plink->precord);
+
294  for(bool done = !!dbFirstField(&rec.ent, 0); !done; done = !!dbNextField(&rec.ent, 0))
+
295  {
+
296  if(rec.ent.pfield == (void*)pval->plink) {
+
297  fldname = rec.ent.pflddes->name;
+
298  break;
+
299  }
+
300  }
+
301 
+
302  printf("%*s%s.%s", 30, "", pval->plink ? pval->plink->precord->name : "<NULL>", fldname);
+
303 
+
304  switch(pval->pp) {
+
305  case pvaLinkConfig::NPP: printf(" NPP"); break;
+
306  case pvaLinkConfig::Default: printf(" Def"); break;
+
307  case pvaLinkConfig::PP: printf(" PP"); break;
+
308  case pvaLinkConfig::CP: printf(" CP"); break;
+
309  case pvaLinkConfig::CPP: printf(" CPP"); break;
+
310  }
+
311  switch(pval->ms) {
+
312  case pvaLinkConfig::NMS: printf(" NMS"); break;
+
313  case pvaLinkConfig::MS: printf(" MS"); break;
+
314  case pvaLinkConfig::MSI: printf(" MSI"); break;
+
315  }
+
316 
+
317  printf(" Q=%u pipe=%c defer=%c time=%c retry=%c morder=%d\n",
+
318  unsigned(pval->queueSize),
+
319  pval->pipeline ? 'T' : 'F',
+
320  pval->defer ? 'T' : 'F',
+
321  pval->time ? 'T' : 'F',
+
322  pval->retry ? 'T' : 'F',
+
323  pval->monorder);
+
324  }
+
325  printf("\n");
+
326  }
+
327  }
+
328  }
+
329 
+
330  printf(" %zu/%zu channels connected used by %zu links\n",
+
331  nconn, nchans, nlinks);
+
332 
+
333  } catch(std::exception& e) {
+
334  fprintf(stderr, "Error: %s\n", e.what());
+
335  }
+
336 }
+
337 
+
338 static
+
339 void installPVAAddLinkHook()
+
340 {
+
341  initHookRegister(&initPVALink);
+
342  epics::iocshRegister<const char*, int, &dbpvar>("dbpvar", "record name", "level");
+
343  epics::registerRefCounter("pvaLinkChannel", &pvaLinkChannel::num_instances);
+
344  epics::registerRefCounter("pvaLink", &pvaLink::num_instances);
+
345 }
+
346 
+
347 extern "C" {
+
348  epicsExportRegistrar(installPVAAddLinkHook);
+
349  epicsExportAddress(jlif, lsetPVA);
+
350  epicsExportAddress(int, pvaLinkDebug);
+
351  epicsExportAddress(int, pvaLinkNWorkers);
+
352 }
+ + + + + +
+ + + + diff --git a/pvalink_8h_source.html b/pvalink_8h_source.html new file mode 100644 index 0000000..324f40a --- /dev/null +++ b/pvalink_8h_source.html @@ -0,0 +1,360 @@ + + + + + + +pva2pva: pdbApp/pvalink.h Source File + + + + + + + + + +
+
+ + + + + + +
+
pva2pva +  1.4.1 +
+
+
+ + + + + + + + + +
+ +
+ + +
+
+
+
pvalink.h
+
+
+
1 #ifndef PVALINK_H
+
2 #define PVALINK_H
+
3 
+
4 #include <set>
+
5 #include <map>
+
6 
+
7 #define EPICS_DBCA_PRIVATE_API
+
8 #include <epicsGuard.h>
+
9 #include <dbAccess.h>
+
10 #include <dbCommon.h>
+
11 #include <dbLink.h>
+
12 #include <dbScan.h>
+
13 #include <errlog.h>
+
14 #include <initHooks.h>
+
15 #include <alarm.h>
+
16 #include <epicsExit.h>
+
17 #include <epicsAtomic.h>
+
18 #include <link.h>
+
19 #include <dbJLink.h>
+
20 #include <errlog.h>
+
21 #include <epicsThread.h>
+
22 #include <epicsMutex.h>
+
23 #include <epicsEvent.h>
+
24 #include <dbChannel.h>
+
25 #include <dbStaticLib.h>
+
26 #include <dbLock.h>
+
27 #include <dbEvent.h>
+
28 #include <epicsVersion.h>
+
29 
+
30 #include <pv/status.h>
+
31 #include <pv/bitSet.h>
+
32 #include <pv/pvData.h>
+
33 
+
34 #include <pva/client.h>
+
35 #include <pv/anyscalar.h>
+
36 #include <pv/thread.h>
+
37 #include <pv/lock.h>
+
38 #include <pv/iocshelper.h>
+
39 
+
40 #include <pv/sharedPtr.h>
+
41 
+
42 #include "helper.h"
+
43 #include "pvif.h"
+
44 #include "tpool.h"
+
45 
+
46 extern "C" {
+
47  QSRV_API extern int pvaLinkDebug;
+
48  QSRV_API extern int pvaLinkIsolate;
+
49  QSRV_API extern int pvaLinkNWorkers;
+
50 }
+
51 
+
52 #if 0
+
53 # define TRACE(X) std::cerr<<"PVAL "<<__func__<<" " X <<"\n"
+
54 #else
+
55 # define TRACE(X) do {} while(0)
+
56 #endif
+
57 
+
58 // pvaLink and pvaLinkChannel have ->debug
+
59 #define DEBUG(OBJ, X) do{ if((OBJ)->debug) std::cout X<<"\n"; }while(0)
+
60 
+
61 namespace pvalink {
+
62 
+
63 namespace pvd = epics::pvData;
+
64 namespace pva = epics::pvAccess;
+
65 
+
66 typedef epicsGuard<pvd::Mutex> Guard;
+
67 typedef epicsGuardRelease<pvd::Mutex> UnGuard;
+
68 
+
69 struct pvaLink;
+
70 struct pvaLinkChannel;
+
71 
+
72 extern lset pva_lset;
+
73 extern jlif lsetPVA;
+
74 
+
75 struct pvaLinkConfig : public jlink
+
76 {
+
77  // configuration, output of jlif parsing
+
79  std::string channelName;
+
81  std::string fieldName;
+
82 
+
83  size_t queueSize;
+
84 
+
85  enum pp_t {
+
86  NPP,
+
87  Default, // for put() only. For monitor, treated as NPP
+
88  PP, // for put() only, For monitor, treated as NPP
+
89  CP, // for monitor only, put treats as pp
+
90  CPP, // for monitor only, put treats as pp
+
91  } pp;
+
92  enum ms_t {
+
93  NMS,
+
94  MS,
+
95  MSI,
+
96  } ms;
+
97 
+
98  bool defer, pipeline, time, retry, local, always;
+
99  int monorder;
+
100 
+
101  // internals used by jlif parsing
+
102  std::string jkey;
+
103 
+
104  pvaLinkConfig();
+
105  virtual ~pvaLinkConfig();
+
106 };
+
107 
+
108 struct pvaGlobal_t {
+
109  pvac::ClientProvider provider_local,
+
110  provider_remote;
+
111 
+
112  const pvd::PVDataCreatePtr create;
+
113 
+
114  WorkQueue queue;
+
115 
+
116  pvd::Mutex lock;
+
117 
+
118  bool running; // set after dbEvent is initialized and safe to use
+
119 
+
120  // a tuple of channel name and printed pvRequest (or Monitor)
+
121  typedef std::pair<std::string, std::string> channels_key_t;
+
122  // pvaLinkChannel dtor prunes dead entires
+
123  typedef std::map<channels_key_t, std::tr1::weak_ptr<pvaLinkChannel> > channels_t;
+
124  // Cache of active Channels (really about caching Monitor)
+
125  channels_t channels;
+
126 
+
127  pvaGlobal_t();
+
128  ~pvaGlobal_t();
+
129 };
+
130 extern pvaGlobal_t *pvaGlobal;
+
131 
+
132 struct pvaLinkChannel : public pvac::ClientChannel::MonitorCallback,
+
133  public pvac::ClientChannel::PutCallback,
+
134  public epicsThreadRunable,
+
135  public std::tr1::enable_shared_from_this<pvaLinkChannel>
+
136 {
+
137  const pvaGlobal_t::channels_key_t key; // tuple of (channelName, pvRequest key)
+
138  const pvd::PVStructure::const_shared_pointer pvRequest; // used with monitor
+
139 
+
140  static size_t num_instances;
+
141 
+
142  pvd::Mutex lock;
+
143  epicsEvent run_done; // used by testing code
+
144 
+
145  pvac::ClientChannel chan;
+
146  pvac::Monitor op_mon;
+
147  pvac::Operation op_put;
+
148 
+
149  std::string providerName;
+
150  size_t num_disconnect, num_type_change;
+
151  bool connected;
+
152  bool connected_latched; // connection status at the run()
+
153  bool isatomic;
+
154  bool queued; // added to WorkQueue
+
155  bool debug; // set if any jlink::debug is set
+
156  std::tr1::shared_ptr<const void> previous_root;
+
157  typedef std::set<dbCommon*> after_put_t;
+
158  after_put_t after_put;
+
159 
+
160  struct LinkSort {
+
161  bool operator()(const pvaLink *L, const pvaLink *R) const;
+
162  };
+
163 
+
164  typedef std::set<pvaLink*, LinkSort> links_t;
+
165 
+
166  // list of currently attached links. maintained by pvaLink ctor/dtor
+
167  // TODO: sort by PHAS
+
168  links_t links;
+
169 
+
170  // set when 'links' is modified to trigger re-compute of record scan list
+
171  bool links_changed;
+
172 
+
173  pvaLinkChannel(const pvaGlobal_t::channels_key_t& key, const epics::pvData::PVStructure::const_shared_pointer &pvRequest);
+
174  virtual ~pvaLinkChannel();
+
175 
+
176  void open();
+
177  void put(bool force=false); // begin Put op.
+
178 
+
179  // pvac::ClientChanel::MonitorCallback
+
180  virtual void monitorEvent(const pvac::MonitorEvent& evt) OVERRIDE FINAL;
+
181 
+
182  // pvac::ClientChanel::PutCallback
+
183  virtual void putBuild(const epics::pvData::StructureConstPtr& build, pvac::ClientChannel::PutCallback::Args& args) OVERRIDE FINAL;
+
184  virtual void putDone(const pvac::PutEvent& evt) OVERRIDE FINAL;
+
185  struct AfterPut : public epicsThreadRunable {
+
186  std::tr1::weak_ptr<pvaLinkChannel> lc;
+
187  virtual ~AfterPut() {}
+
188  virtual void run() OVERRIDE FINAL;
+
189  };
+
190  std::tr1::shared_ptr<AfterPut> AP;
+
191 private:
+
192  virtual void run() OVERRIDE FINAL;
+
193  void run_dbProcess(size_t idx); // idx is index in scan_records
+
194 
+
195  // ==== Treat remaining as local to run()
+
196 
+
197  std::vector<dbCommon*> scan_records;
+
198  std::vector<bool> scan_check_passive;
+
199  std::vector<epics::pvData::BitSet> scan_changed;
+
200 
+
201  DBManyLock atomic_lock;
+
202 };
+
203 
+
204 struct pvaLink : public pvaLinkConfig
+
205 {
+
206  static size_t num_instances;
+
207 
+
208  bool alive; // attempt to catch some use after free
+
209  dbfType type;
+
210 
+
211  DBLINK * plink; // may be NULL
+
212 
+
213  std::tr1::shared_ptr<pvaLinkChannel> lchan;
+
214 
+
215  bool used_scratch, used_queue;
+
216  pvd::shared_vector<const void> put_scratch, put_queue;
+
217 
+
218  // cached fields from channel op_mon
+
219  // updated in onTypeChange()
+
220  epics::pvData::PVField::const_shared_pointer fld_value;
+
221  epics::pvData::PVScalar::const_shared_pointer fld_severity,
+
222  fld_seconds,
+
223  fld_nanoseconds;
+
224  epics::pvData::PVStructure::const_shared_pointer fld_display,
+
225  fld_control,
+
226  fld_valueAlarm;
+
227  epics::pvData::BitSet proc_changed;
+
228 
+
229  // cached snapshot of alarm and timestamp
+
230  // captured in pvaGetValue().
+
231  // we choose not to ensure consistency with display/control meta-data
+
232  epicsTimeStamp snap_time;
+
233  short snap_severity;
+
234 
+
235  pvaLink();
+
236  virtual ~pvaLink();
+
237 
+
238  // returns pvRequest to be used with monitor
+
239  pvd::PVStructurePtr makeRequest();
+
240 
+
241  bool valid() const;
+
242 
+
243  // fetch a sub-sub-field of the top monitored field.
+
244  pvd::PVField::const_shared_pointer getSubField(const char *name);
+
245 
+
246  void onDisconnect();
+
247  void onTypeChange();
+
248 };
+
249 
+
250 
+
251 } // namespace pvalink
+
252 
+
253 #endif // PVALINK_H
+ + + + + + + + + + +
+ + + + diff --git a/pvalink__channel_8cpp_source.html b/pvalink__channel_8cpp_source.html new file mode 100644 index 0000000..b8eb226 --- /dev/null +++ b/pvalink__channel_8cpp_source.html @@ -0,0 +1,535 @@ + + + + + + +pva2pva: pdbApp/pvalink_channel.cpp Source File + + + + + + + + + +
+
+ + + + + + +
+
pva2pva +  1.4.1 +
+
+
+ + + + + + + + + +
+ +
+ + +
+
+
+
pvalink_channel.cpp
+
+
+
1 
+
2 #include <alarm.h>
+
3 
+
4 #include <pv/reftrack.h>
+
5 
+
6 #include "pvalink.h"
+
7 
+
8 int pvaLinkNWorkers = 1;
+
9 
+
10 namespace pvalink {
+
11 
+
12 pvaGlobal_t *pvaGlobal;
+
13 
+
14 
+
15 pvaGlobal_t::pvaGlobal_t()
+
16  :create(pvd::getPVDataCreate())
+
17  ,queue("PVAL")
+
18  ,running(false)
+
19 {
+
20  // worker should be above PVA worker priority?
+
21  queue.start(std::max(1, pvaLinkNWorkers), epicsThreadPriorityMedium);
+
22 }
+
23 
+
24 pvaGlobal_t::~pvaGlobal_t()
+
25 {
+
26 }
+
27 
+
28 size_t pvaLinkChannel::num_instances;
+
29 size_t pvaLink::num_instances;
+
30 
+
31 
+
32 bool pvaLinkChannel::LinkSort::operator()(const pvaLink *L, const pvaLink *R) const {
+
33  if(L->monorder==R->monorder)
+
34  return L < R;
+
35  return L->monorder < R->monorder;
+
36 }
+
37 
+
38 // being called with pvaGlobal::lock held
+
39 pvaLinkChannel::pvaLinkChannel(const pvaGlobal_t::channels_key_t &key, const pvd::PVStructure::const_shared_pointer& pvRequest)
+
40  :key(key)
+
41  ,pvRequest(pvRequest)
+
42  ,num_disconnect(0u)
+
43  ,num_type_change(0u)
+
44  ,connected(false)
+
45  ,connected_latched(false)
+
46  ,isatomic(false)
+
47  ,queued(false)
+
48  ,debug(false)
+
49  ,links_changed(false)
+
50  ,AP(new AfterPut)
+
51 {}
+
52 
+
53 pvaLinkChannel::~pvaLinkChannel() {
+
54  {
+
55  Guard G(pvaGlobal->lock);
+
56  pvaGlobal->channels.erase(key);
+
57  }
+
58 
+
59  Guard G(lock);
+
60 
+
61  assert(links.empty());
+
62  REFTRACE_DECREMENT(num_instances);
+
63 }
+
64 
+
65 void pvaLinkChannel::open()
+
66 {
+
67  Guard G(lock);
+
68 
+
69  try {
+
70  chan = pvaGlobal->provider_local.connect(key.first);
+
71  DEBUG(this, <<key.first<<" OPEN Local");
+
72  providerName = pvaGlobal->provider_local.name();
+
73  } catch(std::exception& e){
+
74  // The PDBProvider doesn't have a way to communicate to us
+
75  // whether this is an invalid record or group name,
+
76  // or if this is some sort of internal error.
+
77  // So we are forced to assume it is an invalid name.
+
78  DEBUG(this, <<key.first<<" OPEN Not local "<<e.what());
+
79  }
+
80  if(!pvaLinkIsolate && !chan) {
+
81  chan = pvaGlobal->provider_remote.connect(key.first);
+
82  DEBUG(this, <<key.first<<" OPEN Remote ");
+
83  providerName = pvaGlobal->provider_remote.name();
+
84  }
+
85 
+
86  op_mon = chan.monitor(this, pvRequest);
+
87 
+
88  REFTRACE_INCREMENT(num_instances);
+
89 }
+
90 
+
91 static
+
92 pvd::StructureConstPtr putRequestType = pvd::getFieldCreate()->createFieldBuilder()
+
93  ->addNestedStructure("field")
+
94  ->endNested()
+
95  ->addNestedStructure("record")
+
96  ->addNestedStructure("_options")
+
97  ->add("block", pvd::pvBoolean)
+
98  ->add("process", pvd::pvString) // "true", "false", or "passive"
+
99  ->endNested()
+
100  ->endNested()
+
101  ->createStructure();
+
102 
+
103 // call with channel lock held
+
104 void pvaLinkChannel::put(bool force)
+
105 {
+
106  pvd::PVStructurePtr pvReq(pvd::getPVDataCreate()->createPVStructure(putRequestType));
+
107  pvReq->getSubFieldT<pvd::PVBoolean>("record._options.block")->put(!after_put.empty());
+
108 
+
109  unsigned reqProcess = 0;
+
110  bool doit = force;
+
111  for(links_t::iterator it(links.begin()), end(links.end()); it!=end; ++it)
+
112  {
+
113  pvaLink *link = *it;
+
114 
+
115  if(!link->used_scratch) continue;
+
116 
+
117  pvd::shared_vector<const void> temp;
+
118  temp.swap(link->put_scratch);
+
119  link->used_scratch = false;
+
120  temp.swap(link->put_queue);
+
121  link->used_queue = true;
+
122 
+
123  doit = true;
+
124 
+
125  switch(link->pp) {
+
126  case pvaLink::NPP:
+
127  reqProcess |= 1;
+
128  break;
+
129  case pvaLink::Default:
+
130  break;
+
131  case pvaLink::PP:
+
132  case pvaLink::CP:
+
133  case pvaLink::CPP:
+
134  reqProcess |= 2;
+
135  break;
+
136  }
+
137  }
+
138 
+
139  /* By default, use remote default (passive).
+
140  * Request processing, or not, if any link asks.
+
141  * Prefer PP over NPP if both are specified.
+
142  *
+
143  * TODO: per field granularity?
+
144  */
+
145  const char *proc = "passive";
+
146  if((reqProcess&2) || force) {
+
147  proc = "true";
+
148  } else if(reqProcess&1) {
+
149  proc = "false";
+
150  }
+
151  pvReq->getSubFieldT<pvd::PVString>("record._options.process")->put(proc);
+
152 
+
153  DEBUG(this, <<key.first<<"Start put "<<doit);
+
154  if(doit) {
+
155  // start net Put, cancels in-progress put
+
156  op_put = chan.put(this, pvReq);
+
157  }
+
158 }
+
159 
+
160 void pvaLinkChannel::putBuild(const epics::pvData::StructureConstPtr& build, pvac::ClientChannel::PutCallback::Args& args)
+
161 {
+
162  Guard G(lock);
+
163 
+
164  pvd::PVStructurePtr top(pvaGlobal->create->createPVStructure(build));
+
165 
+
166  for(links_t::iterator it(links.begin()), end(links.end()); it!=end; ++it)
+
167  {
+
168  pvaLink *link = *it;
+
169 
+
170  if(!link->used_queue) continue;
+
171  link->used_queue = false; // clear early so unexpected exception won't get us in a retry loop
+
172 
+
173  pvd::PVFieldPtr value(link->fieldName.empty() ? pvd::PVFieldPtr(top) : top->getSubField(link->fieldName));
+
174  if(value && value->getField()->getType()==pvd::structure) {
+
175  // maybe drill into NTScalar et al.
+
176  pvd::PVFieldPtr sub(static_cast<pvd::PVStructure*>(value.get())->getSubField("value"));
+
177  if(sub)
+
178  value.swap(sub);
+
179  }
+
180 
+
181  if(!value) continue; // TODO: how to signal error?
+
182 
+
183  pvd::PVStringArray::const_svector choices; // TODO populate from op_mon
+
184 
+
185  DEBUG(this, <<key.first<<" <- "<<value->getFullName());
+
186  copyDBF2PVD(link->put_queue, value, args.tosend, choices);
+
187 
+
188  link->put_queue.clear();
+
189  }
+
190  DEBUG(this, <<key.first<<" Put built");
+
191 
+
192  args.root = top;
+
193 }
+
194 
+
195 namespace {
+
196 // soo much easier with c++11 std::shared_ptr...
+
197 struct AFLinker {
+
198  std::tr1::shared_ptr<pvaLinkChannel> chan;
+
199  AFLinker(const std::tr1::shared_ptr<pvaLinkChannel>& chan) :chan(chan) {}
+
200  void operator()(pvaLinkChannel::AfterPut *) {
+
201  chan.reset();
+
202  }
+
203 };
+
204 } // namespace
+
205 
+
206 void pvaLinkChannel::putDone(const pvac::PutEvent& evt)
+
207 {
+
208  if(evt.event==pvac::PutEvent::Fail) {
+
209  errlogPrintf("%s PVA link put ERROR: %s\n", key.first.c_str(), evt.message.c_str());
+
210  }
+
211 
+
212  bool needscans;
+
213  {
+
214  Guard G(lock);
+
215 
+
216  DEBUG(this, <<key.first<<" Put result "<<evt.event);
+
217 
+
218  needscans = !after_put.empty();
+
219  op_put = pvac::Operation();
+
220 
+
221  if(evt.event==pvac::PutEvent::Success) {
+
222  // see if we need start a queue'd put
+
223  put();
+
224  }
+
225  }
+
226 
+
227  if(needscans) {
+
228  pvaGlobal->queue.add(AP);
+
229  }
+
230 }
+
231 
+
232 void pvaLinkChannel::AfterPut::run()
+
233 {
+
234  std::set<dbCommon*> toscan;
+
235  std::tr1::shared_ptr<pvaLinkChannel> link(lc.lock());
+
236  if(!link)
+
237  return;
+
238 
+
239  {
+
240  Guard G(link->lock);
+
241  toscan.swap(link->after_put);
+
242  }
+
243 
+
244  for(after_put_t::iterator it=toscan.begin(), end=toscan.end();
+
245  it!=end; ++it)
+
246  {
+
247  dbCommon *prec = *it;
+
248  dbScanLock(prec);
+
249  if(prec->pact) { // complete async. processing
+
250  (prec)->rset->process(prec);
+
251 
+
252  } else {
+
253  // maybe the result of "cancellation" or some record support logic error?
+
254  errlogPrintf("%s : not PACT when async PVA link completed. Logic error?\n", prec->name);
+
255  }
+
256  dbScanUnlock(prec);
+
257  }
+
258 
+
259 }
+
260 
+
261 void pvaLinkChannel::monitorEvent(const pvac::MonitorEvent& evt)
+
262 {
+
263  bool queue = false;
+
264 
+
265  {
+
266  DEBUG(this, <<key.first<<" EVENT "<<evt.event);
+
267  Guard G(lock);
+
268 
+
269  switch(evt.event) {
+
270  case pvac::MonitorEvent::Disconnect:
+
271  case pvac::MonitorEvent::Data:
+
272  connected = evt.event == pvac::MonitorEvent::Data;
+
273  queue = true;
+
274  break;
+
275  case pvac::MonitorEvent::Cancel:
+
276  break; // no-op
+
277  case pvac::MonitorEvent::Fail:
+
278  connected = false;
+
279  queue = true;
+
280  errlogPrintf("%s: PVA link monitor ERROR: %s\n", chan.name().c_str(), evt.message.c_str());
+
281  break;
+
282  }
+
283 
+
284  if(queued)
+
285  return; // already scheduled
+
286 
+
287  queued = queue;
+
288  }
+
289 
+
290  if(queue) {
+
291  pvaGlobal->queue.add(shared_from_this());
+
292  }
+
293 }
+
294 
+
295 // the work in calling dbProcess() which is common to
+
296 // both dbScanLock() and dbScanLockMany()
+
297 void pvaLinkChannel::run_dbProcess(size_t idx)
+
298 {
+
299  dbCommon *precord = scan_records[idx];
+
300 
+
301  if(scan_check_passive[idx] && precord->scan!=0) {
+
302  return;
+
303 
+
304  } else if(connected_latched && !op_mon.changed.logical_and(scan_changed[idx])) {
+
305  return;
+
306 
+
307  } else if (precord->pact) {
+
308  if (precord->tpro)
+
309  printf("%s: Active %s\n",
+
310  epicsThreadGetNameSelf(), precord->name);
+
311  precord->rpro = TRUE;
+
312 
+
313  }
+
314  dbProcess(precord);
+
315 }
+
316 
+
317 // Running from global WorkQueue thread
+
318 void pvaLinkChannel::run()
+
319 {
+
320  bool requeue = false;
+
321  {
+
322  Guard G(lock);
+
323 
+
324  queued = false;
+
325 
+
326  connected_latched = connected;
+
327 
+
328  // pop next update from monitor queue.
+
329  // still under lock to safeguard concurrent calls to lset functions
+
330  if(connected && !op_mon.poll()) {
+
331  DEBUG(this, <<key.first<<" RUN "<<"empty");
+
332  run_done.signal();
+
333  return; // monitor queue is empty, nothing more to do here
+
334  }
+
335 
+
336  DEBUG(this, <<key.first<<" RUN "<<(connected_latched?"connected":"disconnected"));
+
337 
+
338  assert(!connected || !!op_mon.root);
+
339 
+
340  if(!connected) {
+
341  num_disconnect++;
+
342 
+
343  // cancel pending put operations
+
344  op_put = pvac::Operation();
+
345 
+
346  for(links_t::iterator it(links.begin()), end(links.end()); it!=end; ++it)
+
347  {
+
348  pvaLink *link = *it;
+
349  link->onDisconnect();
+
350  }
+
351 
+
352  // Don't clear previous_root on disconnect.
+
353  // We will usually re-connect with the same type,
+
354  // and may get back the same PVStructure.
+
355 
+
356  } else if(previous_root.get() != (const void*)op_mon.root.get()) {
+
357  num_type_change++;
+
358 
+
359  for(links_t::iterator it(links.begin()), end(links.end()); it!=end; ++it)
+
360  {
+
361  pvaLink *link = *it;
+
362  link->onTypeChange();
+
363  }
+
364 
+
365  previous_root = std::tr1::static_pointer_cast<const void>(op_mon.root);
+
366  }
+
367 
+
368  // at this point we know we will re-queue, but not immediately
+
369  // so an expected error won't get us stuck in a tight loop.
+
370  requeue = queued = connected_latched;
+
371 
+
372  if(links_changed) {
+
373  // a link has been added or removed since the last update.
+
374  // rebuild our cached list of records to (maybe) process.
+
375 
+
376  scan_records.clear();
+
377  scan_check_passive.clear();
+
378  scan_changed.clear();
+
379 
+
380  for(links_t::iterator it(links.begin()), end(links.end()); it!=end; ++it)
+
381  {
+
382  pvaLink *link = *it;
+
383  assert(link && link->alive);
+
384 
+
385  if(!link->plink) continue;
+
386 
+
387  // only scan on monitor update for input links
+
388  if(link->type!=DBF_INLINK)
+
389  continue;
+
390 
+
391  // NPP and none/Default don't scan
+
392  // PP, CP, and CPP do scan
+
393  // PP and CPP only if SCAN=Passive
+
394  if(link->pp != pvaLink::PP && link->pp != pvaLink::CPP && link->pp != pvaLink::CP)
+
395  continue;
+
396 
+
397  scan_records.push_back(link->plink->precord);
+
398  scan_check_passive.push_back(link->pp != pvaLink::CP);
+
399  scan_changed.push_back(link->proc_changed);
+
400  }
+
401 
+
402  DBManyLock ML(scan_records);
+
403 
+
404  atomic_lock.swap(ML);
+
405 
+
406  links_changed = false;
+
407  }
+
408  }
+
409 
+
410  if(scan_records.empty()) {
+
411  // Nothing to do, so don't bother locking
+
412 
+
413  } else if(isatomic && scan_records.size() > 1u) {
+
414  DBManyLocker L(atomic_lock);
+
415 
+
416  for(size_t i=0, N=scan_records.size(); i<N; i++) {
+
417  run_dbProcess(i);
+
418  }
+
419 
+
420  } else {
+
421  for(size_t i=0, N=scan_records.size(); i<N; i++) {
+
422  DBScanLocker L(scan_records[i]);
+
423  run_dbProcess(i);
+
424  }
+
425  }
+
426 
+
427  if(requeue) {
+
428  // re-queue until monitor queue is empty
+
429  pvaGlobal->queue.add(shared_from_this());
+
430  } else {
+
431  run_done.signal();
+
432  }
+
433 }
+
434 
+
435 } // namespace pvalink
+ +
+ + + + diff --git a/pvalink__jlif_8cpp_source.html b/pvalink__jlif_8cpp_source.html new file mode 100644 index 0000000..77a3962 --- /dev/null +++ b/pvalink__jlif_8cpp_source.html @@ -0,0 +1,424 @@ + + + + + + +pva2pva: pdbApp/pvalink_jlif.cpp Source File + + + + + + + + + +
+
+ + + + + + +
+
pva2pva +  1.4.1 +
+
+
+ + + + + + + + + +
+ +
+ + +
+
+
+
pvalink_jlif.cpp
+
+
+
1 #include <sstream>
+
2 
+
3 #include <epicsStdio.h> // redirects stdout/stderr
+
4 
+
5 #include "pvalink.h"
+
6 
+
7 namespace pvalink {
+
8 pvaLinkConfig::pvaLinkConfig()
+
9  :queueSize(4)
+
10  ,pp(Default)
+
11  ,ms(NMS)
+
12  ,defer(false)
+
13  ,pipeline(false)
+
14  ,time(false)
+
15  ,retry(false)
+
16  ,local(false)
+
17  ,always(false)
+
18  ,monorder(0)
+
19 {}
+
20 pvaLinkConfig::~pvaLinkConfig() {}
+
21 }
+
22 
+
23 namespace {
+
24 
+
25 using namespace pvalink;
+
26 
+
27 /* link options.
+
28  *
+
29  * "pvname" # short-hand, sets PV name only
+
30  *
+
31  * {
+
32  * "pv":"name",
+
33  * "field":"blah.foo",
+
34  * "Q":5,
+
35  * "pipeline":false,
+
36  * "proc":true, // false, true, none, "", "NPP", "PP", "CP", "CPP"
+
37  * "sevr":true, // false, true, "NMS", "MS", "MSI", "MSS"
+
38  * "time":true, // false, true
+
39  * "monorder":#,// order of processing during CP scan
+
40  * "defer":true,// whether to immediately start Put, or only queue value to be sent
+
41  * "retry":true,// queue Put while disconnected, and retry on connect
+
42  * "always":true,// CP/CPP updates always process a like, even if its input field hasn't changed
+
43  * "local":false,// Require local channel
+
44  * }
+
45  */
+
46 
+
47 jlink* pva_alloc_jlink(short dbr)
+
48 {
+
49  try {
+
50  TRACE();
+
51  return new pvaLink;
+
52 
+
53  }catch(std::exception& e){
+
54  errlogPrintf("Error allocating pva link: %s\n", e.what());
+
55  return NULL;
+
56  }
+
57 }
+
58 
+
59 #define TRY pvaLinkConfig *pvt = static_cast<pvaLinkConfig*>(pjlink); (void)pvt; try
+
60 #define CATCH(RET) catch(std::exception& e){ \
+
61  errlogPrintf("Error in %s link: %s\n", __FUNCTION__, e.what()); \
+
62  return RET; }
+
63 
+
64 void pva_free_jlink(jlink *pjlink)
+
65 {
+
66  TRY {
+
67  TRACE();
+
68  delete pvt;
+
69  }catch(std::exception& e){
+
70  errlogPrintf("Error freeing pva link: %s\n", e.what());
+
71  }
+
72 }
+
73 
+
74 jlif_result pva_parse_null(jlink *pjlink)
+
75 {
+
76  TRY {
+
77  TRACE(<<pvt->jkey<<" ");
+
78  if(pvt->parseDepth!=1) {
+
79  // ignore
+
80  } else if(pvt->jkey == "proc") {
+
81  pvt->pp = pvaLinkConfig::Default;
+
82  } else if(pvt->jkey == "sevr") {
+
83  pvt->ms = pvaLinkConfig::NMS;
+
84  } else if(pvt->jkey == "local") {
+
85  pvt->local = false; // alias for local:false
+
86  } else if(pvt->debug) {
+
87  printf("pva link parsing unknown none depth=%u key=\"%s\"\n",
+
88  pvt->parseDepth, pvt->jkey.c_str());
+
89  }
+
90 
+
91  pvt->jkey.clear();
+
92  return jlif_continue;
+
93  }CATCH(jlif_stop)
+
94 }
+
95 
+
96 jlif_result pva_parse_bool(jlink *pjlink, int val)
+
97 {
+
98  TRY {
+
99  TRACE(<<pvt->jkey<<" "<<(val?"true":"false"));
+
100  if(pvt->parseDepth!=1) {
+
101  // ignore
+
102  } else if(pvt->jkey == "proc") {
+
103  pvt->pp = val ? pvaLinkConfig::PP : pvaLinkConfig::NPP;
+
104  } else if(pvt->jkey == "sevr") {
+
105  pvt->ms = val ? pvaLinkConfig::MS : pvaLinkConfig::NMS;
+
106  } else if(pvt->jkey == "defer") {
+
107  pvt->defer = !!val;
+
108  } else if(pvt->jkey == "pipeline") {
+
109  pvt->pipeline = !!val;
+
110  } else if(pvt->jkey == "time") {
+
111  pvt->time = !!val;
+
112  } else if(pvt->jkey == "retry") {
+
113  pvt->retry = !!val;
+
114  } else if(pvt->jkey == "local") {
+
115  pvt->local = !!val;
+
116  } else if(pvt->jkey == "always") {
+
117  pvt->always = !!val;
+
118  } else if(pvt->debug) {
+
119  printf("pva link parsing unknown integer depth=%u key=\"%s\" value=%s\n",
+
120  pvt->parseDepth, pvt->jkey.c_str(), val ? "true" : "false");
+
121  }
+
122 
+
123  pvt->jkey.clear();
+
124  return jlif_continue;
+
125  }CATCH(jlif_stop)
+
126 }
+
127 
+
128 jlif_result pva_parse_integer(jlink *pjlink, long long val)
+
129 {
+
130  TRY {
+
131  TRACE(<<pvt->jkey<<" "<<val);
+
132  if(pvt->parseDepth!=1) {
+
133  // ignore
+
134  } else if(pvt->jkey == "Q") {
+
135  pvt->queueSize = val < 1 ? 1 : size_t(val);
+
136  } else if(pvt->jkey == "monorder") {
+
137  pvt->monorder = std::max(-1024, std::min(int(val), 1024));
+
138  } else if(pvt->debug) {
+
139  printf("pva link parsing unknown integer depth=%u key=\"%s\" value=%lld\n",
+
140  pvt->parseDepth, pvt->jkey.c_str(), val);
+
141  }
+
142 
+
143  pvt->jkey.clear();
+
144  return jlif_continue;
+
145  }CATCH(jlif_stop)
+
146 }
+
147 
+
148 jlif_result pva_parse_string(jlink *pjlink, const char *val, size_t len)
+
149 {
+
150  TRY{
+
151  std::string sval(val, len);
+
152  TRACE(<<pvt->jkey<<" "<<sval);
+
153  if(pvt->parseDepth==0 || (pvt->parseDepth==1 && pvt->jkey=="pv")) {
+
154  pvt->channelName = sval;
+
155 
+
156  } else if(pvt->parseDepth > 1) {
+
157  // ignore
+
158 
+
159  } else if(pvt->jkey=="field") {
+
160  pvt->fieldName = sval;
+
161 
+
162  } else if(pvt->jkey=="proc") {
+
163  if(sval.empty()) {
+
164  pvt->pp = pvaLinkConfig::Default;
+
165  } else if(sval=="CP") {
+
166  pvt->pp = pvaLinkConfig::CP;
+
167  } else if(sval=="CPP") {
+
168  pvt->pp = pvaLinkConfig::CPP;
+
169  } else if(sval=="PP") {
+
170  pvt->pp = pvaLinkConfig::PP;
+
171  } else if(sval=="NPP") {
+
172  pvt->pp = pvaLinkConfig::NPP;
+
173  } else if(pvt->debug) {
+
174  printf("pva link parsing unknown proc depth=%u key=\"%s\" value=\"%s\"\n",
+
175  pvt->parseDepth, pvt->jkey.c_str(), sval.c_str());
+
176  }
+
177 
+
178  } else if(pvt->jkey=="sevr") {
+
179  if(sval=="NMS") {
+
180  pvt->ms = pvaLinkConfig::NMS;
+
181  } else if(sval=="MS") {
+
182  pvt->ms = pvaLinkConfig::MS;
+
183  } else if(sval=="MSI") {
+
184  pvt->ms = pvaLinkConfig::MSI;
+
185  } else if(sval=="MSS") {
+
186  // not sure how to handle mapping severity for MSS.
+
187  // leave room for this to happen compatibly later by
+
188  // handling as alias for MS until then.
+
189  pvt->ms = pvaLinkConfig::MS;
+
190  } else if(pvt->debug) {
+
191  printf("pva link parsing unknown sevr depth=%u key=\"%s\" value=\"%s\"\n",
+
192  pvt->parseDepth, pvt->jkey.c_str(), sval.c_str());
+
193  }
+
194 
+
195  } else if(pvt->debug) {
+
196  printf("pva link parsing unknown string depth=%u key=\"%s\" value=\"%s\"\n",
+
197  pvt->parseDepth, pvt->jkey.c_str(), sval.c_str());
+
198  }
+
199 
+
200  pvt->jkey.clear();
+
201  return jlif_continue;
+
202  }CATCH(jlif_stop)
+
203 }
+
204 
+
205 jlif_key_result pva_parse_start_map(jlink *pjlink)
+
206 {
+
207  TRY {
+
208  TRACE();
+
209  return jlif_key_continue;
+
210  }CATCH(jlif_key_stop)
+
211 }
+
212 
+
213 jlif_result pva_parse_key_map(jlink *pjlink, const char *key, size_t len)
+
214 {
+
215  TRY {
+
216  std::string sval(key, len);
+
217  TRACE(<<sval);
+
218  pvt->jkey = sval;
+
219 
+
220  return jlif_continue;
+
221  }CATCH(jlif_stop)
+
222 }
+
223 
+
224 jlif_result pva_parse_end_map(jlink *pjlink)
+
225 {
+
226  TRY {
+
227  TRACE();
+
228  return jlif_continue;
+
229  }CATCH(jlif_stop)
+
230 }
+
231 
+
232 struct lset* pva_get_lset(const jlink *pjlink)
+
233 {
+
234  TRACE();
+
235  return &pva_lset;
+
236 }
+
237 
+
238 void pva_report(const jlink *rpjlink, int lvl, int indent)
+
239 {
+
240  const pvaLink *pval = static_cast<const pvaLink*>(rpjlink);
+
241  try {
+
242  (void)pval;
+
243  printf("%*s'pva': %s", indent, "", pval->channelName.c_str());
+
244  if(!pval->fieldName.empty())
+
245  printf("|.%s", pval->fieldName.c_str());
+
246 
+
247  switch(pval->pp) {
+
248  case pvaLinkConfig::NPP: printf(" NPP"); break;
+
249  case pvaLinkConfig::Default: printf(" Def"); break;
+
250  case pvaLinkConfig::PP: printf(" PP"); break;
+
251  case pvaLinkConfig::CP: printf(" CP"); break;
+
252  case pvaLinkConfig::CPP: printf(" CPP"); break;
+
253  }
+
254  switch(pval->ms) {
+
255  case pvaLinkConfig::NMS: printf(" NMS"); break;
+
256  case pvaLinkConfig::MS: printf(" MS"); break;
+
257  case pvaLinkConfig::MSI: printf(" MSI"); break;
+
258  }
+
259  if(lvl>0) {
+
260  printf(" Q=%u pipe=%c defer=%c time=%c retry=%c morder=%d",
+
261  unsigned(pval->queueSize),
+
262  pval->pipeline ? 'T' : 'F',
+
263  pval->defer ? 'T' : 'F',
+
264  pval->time ? 'T' : 'F',
+
265  pval->retry ? 'T' : 'F',
+
266  pval->monorder);
+
267  }
+
268 
+
269  if(pval->lchan) {
+
270  // after open()
+
271  Guard G(pval->lchan->lock);
+
272 
+
273  printf(" conn=%c", pval->lchan->connected ? 'T' : 'F');
+
274  if(pval->lchan->op_put.valid()) {
+
275  printf(" Put");
+
276  }
+
277 
+
278  if(lvl>0) {
+
279  printf(" #disconn=%zu prov=%s", pval->lchan->num_disconnect, pval->lchan->providerName.c_str());
+
280  }
+
281  if(lvl>1) {
+
282  printf(" inprog=%c",
+
283  pval->lchan->queued?'T':'F');
+
284  }
+
285  if(lvl>5) {
+
286  std::ostringstream strm;
+
287  pval->lchan->chan.show(strm);
+
288  printf("\n%*s CH: %s", indent, "", strm.str().c_str());
+
289  }
+
290  } else {
+
291  printf(" No Channel");
+
292  }
+
293  printf("\n");
+
294  }CATCH()
+
295 }
+
296 
+
297 } //namespace
+
298 
+
299 namespace pvalink {
+
300 
+
301 jlif lsetPVA = {
+
302  "pva",
+
303  &pva_alloc_jlink,
+
304  &pva_free_jlink,
+
305  &pva_parse_null,
+
306  &pva_parse_bool,
+
307  &pva_parse_integer,
+
308  NULL,
+
309  &pva_parse_string,
+
310  &pva_parse_start_map,
+
311  &pva_parse_key_map,
+
312  &pva_parse_end_map,
+
313  NULL,
+
314  NULL,
+
315  NULL,
+
316  &pva_get_lset,
+
317  &pva_report,
+
318  NULL
+
319 };
+
320 
+
321 } //namespace pvalink
+ + + + +
+ + + + diff --git a/pvalink__link_8cpp_source.html b/pvalink__link_8cpp_source.html new file mode 100644 index 0000000..c4f5013 --- /dev/null +++ b/pvalink__link_8cpp_source.html @@ -0,0 +1,256 @@ + + + + + + +pva2pva: pdbApp/pvalink_link.cpp Source File + + + + + + + + + +
+
+ + + + + + +
+
pva2pva +  1.4.1 +
+
+
+ + + + + + + + + +
+ +
+ + +
+
+
+
pvalink_link.cpp
+
+
+
1 #include <pv/reftrack.h>
+
2 #include <alarm.h>
+
3 
+
4 #include "pvalink.h"
+
5 
+
6 namespace pvalink {
+
7 
+
8 pvaLink::pvaLink()
+
9  :alive(true)
+
10  ,type((dbfType)-1)
+
11  ,plink(0)
+
12  ,used_scratch(false)
+
13  ,used_queue(false)
+
14 {
+
15  REFTRACE_INCREMENT(num_instances);
+
16 
+
17  snap_severity = INVALID_ALARM;
+
18  snap_time.secPastEpoch = 0;
+
19  snap_time.nsec = 0;
+
20 
+
21  //TODO: valgrind tells me these aren't initialized by Base, but probably should be.
+
22  parseDepth = 0;
+
23  parent = 0;
+
24 }
+
25 
+
26 pvaLink::~pvaLink()
+
27 {
+
28  alive = false;
+
29 
+
30  if(lchan) { // may be NULL if parsing fails
+
31  Guard G(lchan->lock);
+
32 
+
33  lchan->links.erase(this);
+
34  lchan->links_changed = true;
+
35 
+
36  bool new_debug = false;
+
37  for(pvaLinkChannel::links_t::const_iterator it(lchan->links.begin()), end(lchan->links.end())
+
38  ; it!=end; ++it)
+
39  {
+
40  const pvaLink *pval = *it;
+
41  if(pval->debug) {
+
42  new_debug = true;
+
43  break;
+
44  }
+
45  }
+
46 
+
47  lchan->debug = new_debug;
+
48  }
+
49 
+
50  REFTRACE_DECREMENT(num_instances);
+
51 }
+
52 
+
53 static
+
54 pvd::StructureConstPtr monitorRequestType = pvd::getFieldCreate()->createFieldBuilder()
+
55  ->addNestedStructure("field")
+
56  ->endNested()
+
57  ->addNestedStructure("record")
+
58  ->addNestedStructure("_options")
+
59  ->add("pipeline", pvd::pvBoolean)
+
60  ->add("atomic", pvd::pvBoolean)
+
61  ->add("queueSize", pvd::pvUInt)
+
62  ->endNested()
+
63  ->endNested()
+
64  ->createStructure();
+
65 
+
66 pvd::PVStructurePtr pvaLink::makeRequest()
+
67 {
+
68  pvd::PVStructurePtr ret(pvd::getPVDataCreate()->createPVStructure(monitorRequestType));
+
69  ret->getSubFieldT<pvd::PVBoolean>("record._options.pipeline")->put(pipeline);
+
70  ret->getSubFieldT<pvd::PVBoolean>("record._options.atomic")->put(true);
+
71  ret->getSubFieldT<pvd::PVUInt>("record._options.queueSize")->put(queueSize);
+
72  return ret;
+
73 }
+
74 
+
75 // caller must lock lchan->lock
+
76 bool pvaLink::valid() const
+
77 {
+
78  return lchan->connected_latched && lchan->op_mon.root;
+
79 }
+
80 
+
81 // caller must lock lchan->lock
+
82 pvd::PVField::const_shared_pointer pvaLink::getSubField(const char *name)
+
83 {
+
84  pvd::PVField::const_shared_pointer ret;
+
85  if(valid()) {
+
86  if(fieldName.empty()) {
+
87  // we access the top level struct
+
88  ret = lchan->op_mon.root->getSubField(name);
+
89 
+
90  } else {
+
91  // we access a sub-struct
+
92  ret = lchan->op_mon.root->getSubField(fieldName);
+
93  if(!ret) {
+
94  // noop
+
95  } else if(ret->getField()->getType()!=pvd::structure) {
+
96  // addressed sub-field isn't a sub-structure
+
97  if(strcmp(name, "value")!=0) {
+
98  // unless we are trying to fetch the "value", we fail here
+
99  ret.reset();
+
100  }
+
101  } else {
+
102  ret = static_cast<const pvd::PVStructure*>(ret.get())->getSubField(name);
+
103  }
+
104  }
+
105  }
+
106  return ret;
+
107 }
+
108 
+
109 // call with channel lock held
+
110 void pvaLink::onDisconnect()
+
111 {
+
112  DEBUG(this,<<plink->precord->name<<" disconnect");
+
113  // TODO: option to remain queue'd while disconnected
+
114 
+
115  used_queue = used_scratch = false;
+
116 }
+
117 
+
118 void pvaLink::onTypeChange()
+
119 {
+
120  DEBUG(this,<<plink->precord->name<<" type change");
+
121 
+
122  assert(lchan->connected_latched && !!lchan->op_mon.root); // we should only be called when connected
+
123 
+
124  fld_value = getSubField("value");
+
125  fld_seconds = std::tr1::dynamic_pointer_cast<const pvd::PVScalar>(getSubField("timeStamp.secondsPastEpoch"));
+
126  fld_nanoseconds = std::tr1::dynamic_pointer_cast<const pvd::PVScalar>(getSubField("timeStamp.nanoseconds"));
+
127  fld_severity = std::tr1::dynamic_pointer_cast<const pvd::PVScalar>(getSubField("alarm.severity"));
+
128  fld_display = std::tr1::dynamic_pointer_cast<const pvd::PVStructure>(getSubField("display"));
+
129  fld_control = std::tr1::dynamic_pointer_cast<const pvd::PVStructure>(getSubField("control"));
+
130  fld_valueAlarm = std::tr1::dynamic_pointer_cast<const pvd::PVStructure>(getSubField("valueAlarm"));
+
131 
+
132  proc_changed.clear();
+
133 
+
134  // build mask of all "changed" bits associated with our .value
+
135  // CP/CPP input links will process this link only for updates where
+
136  // the changed mask and proc_changed share at least one set bit.
+
137  if(fld_value) {
+
138  // bit for this field
+
139  proc_changed.set(fld_value->getFieldOffset());
+
140 
+
141  // bits of all parent fields
+
142  for(const pvd::PVStructure* parent = fld_value->getParent(); parent; parent = parent->getParent()) {
+
143  proc_changed.set(parent->getFieldOffset());
+
144  }
+
145 
+
146  if(fld_value->getField()->getType()==pvd::structure)
+
147  {
+
148  // bits of all child fields
+
149  const pvd::PVStructure *val = static_cast<const pvd::PVStructure*>(fld_value.get());
+
150  for(size_t i=val->getFieldOffset(), N=val->getNextFieldOffset(); i<N; i++)
+
151  proc_changed.set(i);
+
152  }
+
153  }
+
154 }
+
155 
+
156 } // namespace pvalink
+ +
+ + + + diff --git a/pvalink__lset_8cpp_source.html b/pvalink__lset_8cpp_source.html new file mode 100644 index 0000000..08c8776 --- /dev/null +++ b/pvalink__lset_8cpp_source.html @@ -0,0 +1,626 @@ + + + + + + +pva2pva: pdbApp/pvalink_lset.cpp Source File + + + + + + + + + +
+
+ + + + + + +
+
pva2pva +  1.4.1 +
+
+
+ + + + + + + + + +
+ +
+ + +
+
+
+
pvalink_lset.cpp
+
+
+
1 
+
2 #include <epicsString.h>
+
3 #include <alarm.h>
+
4 #include <recGbl.h>
+
5 #include <epicsStdio.h> // redirect stdout/stderr
+
6 
+
7 #include <pv/current_function.h>
+
8 
+
9 #include "pvalink.h"
+
10 
+
11 
+
12 namespace {
+
13 
+
14 using namespace pvalink;
+
15 
+
16 #define TRY pvaLink *self = static_cast<pvaLink*>(plink->value.json.jlink); assert(self->alive); try
+
17 #define CATCH() catch(std::exception& e) { \
+
18  errlogPrintf("pvaLink %s fails %s: %s\n", CURRENT_FUNCTION, plink->precord->name, e.what()); \
+
19 }
+
20 
+
21 #define CHECK_VALID() if(!self->valid()) { DEBUG(self, <<CURRENT_FUNCTION<<" "<<self->channelName<<" !valid"); return -1;}
+
22 
+
23 dbfType getLinkType(DBLINK *plink)
+
24 {
+
25  dbCommon *prec = plink->precord;
+
26  pdbRecordIterator iter(prec);
+
27 
+
28  for(long status = dbFirstField(&iter.ent, 0); !status; status = dbNextField(&iter.ent, 0)) {
+
29  if(iter.ent.pfield==plink)
+
30  return iter.ent.pflddes->field_type;
+
31  }
+
32  throw std::logic_error("DBLINK* corrupt");
+
33 }
+
34 
+
35 void pvaOpenLink(DBLINK *plink)
+
36 {
+
37  try {
+
38  pvaLink* self((pvaLink*)plink->value.json.jlink);
+
39  self->type = getLinkType(plink);
+
40 
+
41  // workaround for Base not propagating info(base:lsetDebug to us
+
42  {
+
43  pdbRecordIterator rec(plink->precord);
+
44 
+
45  if(epicsStrCaseCmp(rec.info("base:lsetDebug", "NO"), "YES")==0) {
+
46  self->debug = 1;
+
47  }
+
48  }
+
49 
+
50  DEBUG(self, <<plink->precord->name<<" OPEN "<<self->channelName);
+
51 
+
52  // still single threaded at this point.
+
53  // also, no pvaLinkChannel::lock yet
+
54 
+
55  self->plink = plink;
+
56 
+
57  if(self->channelName.empty())
+
58  return; // nothing to do...
+
59 
+
60  pvd::PVStructure::const_shared_pointer pvRequest(self->makeRequest());
+
61  pvaGlobal_t::channels_key_t key;
+
62 
+
63  {
+
64  std::ostringstream strm;
+
65  strm<<*pvRequest; // print the request as a convient key for our channel cache
+
66 
+
67  key = std::make_pair(self->channelName, strm.str());
+
68  }
+
69 
+
70  std::tr1::shared_ptr<pvaLinkChannel> chan;
+
71  bool doOpen = false;
+
72  {
+
73  Guard G(pvaGlobal->lock);
+
74 
+
75  pvaGlobal_t::channels_t::iterator it(pvaGlobal->channels.find(key));
+
76 
+
77  if(it!=pvaGlobal->channels.end()) {
+
78  // re-use existing channel
+
79  chan = it->second.lock();
+
80  }
+
81 
+
82  if(!chan) {
+
83  // open new channel
+
84 
+
85  chan.reset(new pvaLinkChannel(key, pvRequest));
+
86  chan->AP->lc = chan;
+
87  pvaGlobal->channels.insert(std::make_pair(key, chan));
+
88  doOpen = true;
+
89  }
+
90 
+
91  doOpen &= pvaGlobal->running; // if not running, then open from initHook
+
92  }
+
93 
+
94  if(doOpen) {
+
95  chan->open(); // start subscription
+
96  }
+
97 
+
98  if(!self->local || chan->providerName=="QSRV"){
+
99  Guard G(chan->lock);
+
100 
+
101  chan->links.insert(self);
+
102  chan->links_changed = true;
+
103 
+
104  self->lchan.swap(chan); // we are now attached
+
105 
+
106  self->lchan->debug |= !!self->debug;
+
107  } else {
+
108  // TODO: only print duing iocInit()?
+
109  fprintf(stderr, "%s Error: local:true link to '%s' can't be fulfilled\n",
+
110  plink->precord->name, self->channelName.c_str());
+
111  plink->lset = NULL;
+
112  }
+
113 
+
114  return;
+
115  }CATCH()
+
116  // on error, prevent any further calls to our lset functions
+
117  plink->lset = NULL;
+
118 }
+
119 
+
120 void pvaRemoveLink(struct dbLocker *locker, DBLINK *plink)
+
121 {
+
122  try {
+
123  p2p::auto_ptr<pvaLink> self((pvaLink*)plink->value.json.jlink);
+
124  DEBUG(self, <<plink->precord->name<<" "<<CURRENT_FUNCTION<<" "<<self->channelName);
+
125  assert(self->alive);
+
126 
+
127  }CATCH()
+
128 }
+
129 
+
130 int pvaIsConnected(const DBLINK *plink)
+
131 {
+
132  TRY {
+
133  Guard G(self->lchan->lock);
+
134 
+
135  bool ret = self->valid();
+
136  DEBUG(self, <<plink->precord->name<<" "<<CURRENT_FUNCTION<<" "<<self->channelName<<" "<<ret);
+
137  return ret;
+
138 
+
139  }CATCH()
+
140  return 0;
+
141 }
+
142 
+
143 int pvaGetDBFtype(const DBLINK *plink)
+
144 {
+
145  TRY {
+
146  Guard G(self->lchan->lock);
+
147  CHECK_VALID();
+
148 
+
149  // if fieldName is empty, use top struct value
+
150  // if fieldName not empty
+
151  // if sub-field is struct, use sub-struct .value
+
152  // if sub-field not struct, treat as value
+
153 
+
154  pvd::PVField::const_shared_pointer value(self->getSubField("value"));
+
155 
+
156  pvd::ScalarType ftype = pvd::pvInt; // default for un-mapable types.
+
157  if(!value) {
+
158  // no-op
+
159  } else if(value->getField()->getType()==pvd::scalar)
+
160  ftype = static_cast<const pvd::Scalar*>(value->getField().get())->getScalarType();
+
161  else if(value->getField()->getType()==pvd::scalarArray)
+
162  ftype = static_cast<const pvd::ScalarArray*>(value->getField().get())->getElementType();
+
163 
+
164  int ret;
+
165  switch(ftype) {
+
166 #define CASE(BASETYPE, PVATYPE, DBFTYPE, PVACODE) case pvd::pv##PVACODE: ret = DBF_##DBFTYPE;
+
167 #define CASE_REAL_INT64
+
168 #include "pv/typemap.h"
+
169 #undef CASE_REAL_INT64
+
170 #undef CASE
+
171  case pvd::pvString: ret = DBF_STRING; // TODO: long string?
+
172  }
+
173 
+
174  DEBUG(self, <<plink->precord->name<<" "<<CURRENT_FUNCTION<<" "<<self->channelName<<" "<<dbGetFieldTypeString(ret));
+
175  return ret;
+
176 
+
177  }CATCH()
+
178  return -1;
+
179 }
+
180 
+
181 long pvaGetElements(const DBLINK *plink, long *nelements)
+
182 {
+
183  TRY {
+
184  Guard G(self->lchan->lock);
+
185  CHECK_VALID();
+
186 
+
187  long ret = 0;
+
188  if(self->fld_value && self->fld_value->getField()->getType()==pvd::scalarArray)
+
189  ret = static_cast<const pvd::PVScalarArray*>(self->fld_value.get())->getLength();
+
190 
+
191  DEBUG(self, <<plink->precord->name<<" "<<CURRENT_FUNCTION<<" "<<self->channelName<<" "<<ret);
+
192 
+
193  return ret;
+
194  }CATCH()
+
195  return -1;
+
196 }
+
197 
+
198 long pvaGetValue(DBLINK *plink, short dbrType, void *pbuffer,
+
199  long *pnRequest)
+
200 {
+
201  TRY {
+
202  Guard G(self->lchan->lock);
+
203 
+
204  if(!self->valid()) {
+
205  // disconnected
+
206  if(self->ms != pvaLink::NMS) {
+
207  recGblSetSevr(plink->precord, LINK_ALARM, self->snap_severity);
+
208  }
+
209  // TODO: better capture of disconnect time
+
210  epicsTimeGetCurrent(&self->snap_time);
+
211  if(self->time) {
+
212  plink->precord->time = self->snap_time;
+
213  }
+
214  DEBUG(self, <<CURRENT_FUNCTION<<" "<<self->channelName<<" !valid");
+
215  return -1;
+
216  }
+
217 
+
218  if(self->fld_value) {
+
219  long status = copyPVD2DBF(self->fld_value, pbuffer, dbrType, pnRequest);
+
220  if(status) {
+
221  DEBUG(self, <<plink->precord->name<<" "<<CURRENT_FUNCTION<<" "<<self->channelName<<" "<<status);
+
222  return status;
+
223  }
+
224  }
+
225 
+
226  if(self->fld_seconds) {
+
227  self->snap_time.secPastEpoch = self->fld_seconds->getAs<pvd::uint32>() - POSIX_TIME_AT_EPICS_EPOCH;
+
228  if(self->fld_nanoseconds) {
+
229  self->snap_time.nsec = self->fld_nanoseconds->getAs<pvd::uint32>();
+
230  } else {
+
231  self->snap_time.nsec = 0u;
+
232  }
+
233  } else {
+
234  self->snap_time.secPastEpoch = 0u;
+
235  self->snap_time.nsec = 0u;
+
236  }
+
237 
+
238  if(self->fld_severity) {
+
239  self->snap_severity = self->fld_severity->getAs<pvd::uint16>();
+
240  } else {
+
241  self->snap_severity = NO_ALARM;
+
242  }
+
243 
+
244  if((self->snap_severity!=NO_ALARM && self->ms == pvaLink::MS) ||
+
245  (self->snap_severity==INVALID_ALARM && self->ms == pvaLink::MSI))
+
246  {
+
247  recGblSetSevr(plink->precord, LINK_ALARM, self->snap_severity);
+
248  }
+
249 
+
250  if(self->time) {
+
251  plink->precord->time = self->snap_time;
+
252  }
+
253 
+
254  DEBUG(self, <<plink->precord->name<<" "<<CURRENT_FUNCTION<<" "<<self->channelName<<" OK");
+
255  return 0;
+
256  }CATCH()
+
257  return -1;
+
258 }
+
259 
+
260 long pvaGetControlLimits(const DBLINK *plink, double *lo, double *hi)
+
261 {
+
262  TRY {
+
263  Guard G(self->lchan->lock);
+
264  CHECK_VALID();
+
265 
+
266  if(self->fld_control) {
+
267  pvd::PVScalar::const_shared_pointer value;
+
268  if(lo) {
+
269  value = std::tr1::static_pointer_cast<const pvd::PVScalar>(self->fld_control->getSubField("limitLow"));
+
270  *lo = value ? value->getAs<double>() : 0.0;
+
271  }
+
272  if(hi) {
+
273  value = std::tr1::static_pointer_cast<const pvd::PVScalar>(self->fld_control->getSubField("limitHigh"));
+
274  *hi = value ? value->getAs<double>() : 0.0;
+
275  }
+
276  } else {
+
277  *lo = *hi = 0.0;
+
278  }
+
279  DEBUG(self, <<plink->precord->name<<" "<<CURRENT_FUNCTION<<" "<<self->channelName<<" "<<(lo ? *lo : 0)<<" "<<(hi ? *hi : 0));
+
280  return 0;
+
281  }CATCH()
+
282  return -1;
+
283 }
+
284 
+
285 long pvaGetGraphicLimits(const DBLINK *plink, double *lo, double *hi)
+
286 {
+
287  TRY {
+
288  Guard G(self->lchan->lock);
+
289  CHECK_VALID();
+
290 
+
291  if(self->fld_display) {
+
292  pvd::PVScalar::const_shared_pointer value;
+
293  if(lo) {
+
294  value = std::tr1::static_pointer_cast<const pvd::PVScalar>(self->fld_display->getSubField("limitLow"));
+
295  *lo = value ? value->getAs<double>() : 0.0;
+
296  }
+
297  if(hi) {
+
298  value = std::tr1::static_pointer_cast<const pvd::PVScalar>(self->fld_display->getSubField("limitHigh"));
+
299  *hi = value ? value->getAs<double>() : 0.0;
+
300  }
+
301  } else {
+
302  *lo = *hi = 0.0;
+
303  }
+
304  DEBUG(self, <<plink->precord->name<<" "<<CURRENT_FUNCTION<<" "<<self->channelName<<" "<<(lo ? *lo : 0)<<" "<<(hi ? *hi : 0));
+
305  return 0;
+
306  }CATCH()
+
307  return -1;
+
308 }
+
309 
+
310 long pvaGetAlarmLimits(const DBLINK *plink, double *lolo, double *lo,
+
311  double *hi, double *hihi)
+
312 {
+
313  TRY {
+
314  //Guard G(self->lchan->lock);
+
315  //CHECK_VALID();
+
316  *lolo = *lo = *hi = *hihi = 0.0;
+
317  DEBUG(self, <<plink->precord->name<<" "<<CURRENT_FUNCTION<<" "<<self->channelName<<" "<<(lolo ? *lolo : 0)<<" "<<(lo ? *lo : 0)<<" "<<(hi ? *hi : 0)<<" "<<(hihi ? *hihi : 0));
+
318  return 0;
+
319  }CATCH()
+
320  return -1;
+
321 }
+
322 
+
323 long pvaGetPrecision(const DBLINK *plink, short *precision)
+
324 {
+
325  TRY {
+
326  //Guard G(self->lchan->lock);
+
327  //CHECK_VALID();
+
328 
+
329  // No sane way to recover precision from display.format string.
+
330  *precision = 0;
+
331  DEBUG(self, <<plink->precord->name<<" "<<CURRENT_FUNCTION<<" "<<self->channelName<<" "<<precision);
+
332  return 0;
+
333  }CATCH()
+
334  return -1;
+
335 }
+
336 
+
337 long pvaGetUnits(const DBLINK *plink, char *units, int unitsSize)
+
338 {
+
339  TRY {
+
340  Guard G(self->lchan->lock);
+
341  CHECK_VALID();
+
342 
+
343  if(unitsSize==0) return 0;
+
344 
+
345  if(units && self->fld_display) {
+
346  pvd::PVString::const_shared_pointer value(std::tr1::static_pointer_cast<const pvd::PVString>(self->fld_display->getSubField("units")));
+
347  if(value) {
+
348  const std::string& egu = value->get();
+
349  strncpy(units, egu.c_str(), unitsSize);
+
350  }
+
351  } else if(units) {
+
352  units[0] = '\0';
+
353  }
+
354  units[unitsSize-1] = '\0';
+
355  DEBUG(self, <<plink->precord->name<<" "<<CURRENT_FUNCTION<<" "<<self->channelName<<" "<<units);
+
356  return 0;
+
357  }CATCH()
+
358  return -1;
+
359 }
+
360 
+
361 long pvaGetAlarm(const DBLINK *plink, epicsEnum16 *status,
+
362  epicsEnum16 *severity)
+
363 {
+
364  TRY {
+
365  Guard G(self->lchan->lock);
+
366  CHECK_VALID();
+
367 
+
368  if(severity) {
+
369  *severity = self->snap_severity;
+
370  }
+
371  if(status) {
+
372  *status = self->snap_severity ? LINK_ALARM : NO_ALARM;
+
373  }
+
374 
+
375  DEBUG(self, <<plink->precord->name<<" "<<CURRENT_FUNCTION<<" "<<self->channelName<<" "<<(severity ? *severity : 0)<<" "<<(status ? *status : 0));
+
376  return 0;
+
377  }CATCH()
+
378  return -1;
+
379 }
+
380 
+
381 long pvaGetTimeStamp(const DBLINK *plink, epicsTimeStamp *pstamp)
+
382 {
+
383  TRY {
+
384  Guard G(self->lchan->lock);
+
385  CHECK_VALID();
+
386 
+
387  if(pstamp) {
+
388  *pstamp = self->snap_time;
+
389  }
+
390 
+
391  DEBUG(self, <<plink->precord->name<<" "<<CURRENT_FUNCTION<<" "<<self->channelName<<" "<<(pstamp ? pstamp->secPastEpoch : 0)<<":"<<(pstamp ? pstamp->nsec: 0));
+
392  return 0;
+
393  }CATCH()
+
394  return -1;
+
395 }
+
396 
+
397 // note that we handle DBF_ENUM differently than in pvif.cpp
+
398 pvd::ScalarType DBR2PVD(short dbr)
+
399 {
+
400  switch(dbr) {
+
401 #define CASE(BASETYPE, PVATYPE, DBFTYPE, PVACODE) case DBR_##DBFTYPE: return pvd::pv##PVACODE;
+
402 #define CASE_SKIP_BOOL
+
403 #define CASE_REAL_INT64
+
404 #include "pv/typemap.h"
+
405 #undef CASE_SKIP_BOOL
+
406 #undef CASE_REAL_INT64
+
407 #undef CASE
+
408  case DBF_ENUM: return pvd::pvUShort;
+
409  case DBF_STRING: return pvd::pvString;
+
410  }
+
411  throw std::invalid_argument("Unsupported DBR code");
+
412 }
+
413 
+
414 long pvaPutValueX(DBLINK *plink, short dbrType,
+
415  const void *pbuffer, long nRequest, bool wait)
+
416 {
+
417  TRY {
+
418  (void)self;
+
419  Guard G(self->lchan->lock);
+
420 
+
421  if(nRequest < 0) return -1;
+
422 
+
423  if(!self->retry && !self->valid()) {
+
424  DEBUG(self, <<CURRENT_FUNCTION<<" "<<self->channelName<<" !valid");
+
425  return -1;
+
426  }
+
427 
+
428  pvd::ScalarType stype = DBR2PVD(dbrType);
+
429 
+
430  pvd::shared_vector<const void> buf;
+
431 
+
432  if(dbrType == DBF_STRING) {
+
433  const char *sbuffer = (const char*)pbuffer;
+
434  pvd::shared_vector<std::string> sval(nRequest);
+
435 
+
436  for(long n=0; n<nRequest; n++, sbuffer += MAX_STRING_SIZE) {
+
437  sval[n] = std::string(sbuffer, epicsStrnLen(sbuffer, MAX_STRING_SIZE));
+
438  }
+
439 
+
440  self->put_scratch = pvd::static_shared_vector_cast<const void>(pvd::freeze(sval));
+
441 
+
442  } else {
+
443  pvd::shared_vector<void> val(pvd::ScalarTypeFunc::allocArray(stype, size_t(nRequest)));
+
444 
+
445  assert(size_t(dbValueSize(dbrType)*nRequest) == val.size());
+
446 
+
447  memcpy(val.data(), pbuffer, val.size());
+
448 
+
449  self->put_scratch = pvd::freeze(val);
+
450  }
+
451 
+
452  self->used_scratch = true;
+
453 
+
454 #ifdef USE_MULTILOCK
+
455  if(wait)
+
456  self->lchan->after_put.insert(plink->precord);
+
457 #endif
+
458 
+
459  if(!self->defer) self->lchan->put();
+
460 
+
461  DEBUG(self, <<plink->precord->name<<" "<<CURRENT_FUNCTION<<" "<<self->channelName<<" "<<self->lchan->op_put.valid());
+
462  return 0;
+
463  }CATCH()
+
464  return -1;
+
465 }
+
466 
+
467 long pvaPutValue(DBLINK *plink, short dbrType,
+
468  const void *pbuffer, long nRequest)
+
469 {
+
470  return pvaPutValueX(plink, dbrType, pbuffer, nRequest, false);
+
471 }
+
472 
+
473 long pvaPutValueAsync(DBLINK *plink, short dbrType,
+
474  const void *pbuffer, long nRequest)
+
475 {
+
476  return pvaPutValueX(plink, dbrType, pbuffer, nRequest, true);
+
477 }
+
478 
+
479 void pvaScanForward(DBLINK *plink)
+
480 {
+
481  TRY {
+
482  Guard G(self->lchan->lock);
+
483 
+
484  if(!self->retry && !self->valid()) {
+
485  return;
+
486  }
+
487 
+
488  // FWD_LINK is never deferred, and always results in a Put
+
489  self->lchan->put(true);
+
490 
+
491  DEBUG(self, <<plink->precord->name<<" "<<CURRENT_FUNCTION<<" "<<self->channelName<<" "<<self->lchan->op_put.valid());
+
492  }CATCH()
+
493 }
+
494 
+
495 #undef TRY
+
496 #undef CATCH
+
497 
+
498 } //namespace
+
499 
+
500 namespace pvalink {
+
501 
+
502 lset pva_lset = {
+
503  0, 1, // non-const, volatile
+
504  &pvaOpenLink,
+
505  &pvaRemoveLink,
+
506  NULL, NULL, NULL,
+
507  &pvaIsConnected,
+
508  &pvaGetDBFtype,
+
509  &pvaGetElements,
+
510  &pvaGetValue,
+
511  &pvaGetControlLimits,
+
512  &pvaGetGraphicLimits,
+
513  &pvaGetAlarmLimits,
+
514  &pvaGetPrecision,
+
515  &pvaGetUnits,
+
516  &pvaGetAlarm,
+
517  &pvaGetTimeStamp,
+
518  &pvaPutValue,
+
519  &pvaPutValueAsync,
+
520  &pvaScanForward
+
521  //&pvaReportLink,
+
522 };
+
523 
+
524 } //namespace pvalink
+ + + +
+ + + + diff --git a/pvalink__null_8cpp_source.html b/pvalink__null_8cpp_source.html new file mode 100644 index 0000000..e63fe8a --- /dev/null +++ b/pvalink__null_8cpp_source.html @@ -0,0 +1,116 @@ + + + + + + +pva2pva: pdbApp/pvalink_null.cpp Source File + + + + + + + + + +
+
+ + + + + + +
+
pva2pva +  1.4.1 +
+
+
+ + + + + + + + + +
+ +
+ + +
+
+
+
pvalink_null.cpp
+
+
+
1 
+
2 #include <epicsExport.h>
+
3 
+
4 static void installPVAAddLinkHook() {}
+
5 
+
6 struct jlif {} lsetPVA;
+
7 
+
8 extern "C" {
+
9 int pvaLinkDebug;
+
10 int pvaLinkNWorkers;
+
11 
+
12  epicsExportRegistrar(installPVAAddLinkHook);
+
13  epicsExportAddress(jlif, lsetPVA);
+
14  epicsExportAddress(int, pvaLinkDebug);
+
15  epicsExportAddress(int, pvaLinkNWorkers);
+
16 }
+ +
+ + + + diff --git a/pvif_8cpp_source.html b/pvif_8cpp_source.html new file mode 100644 index 0000000..b9f822b --- /dev/null +++ b/pvif_8cpp_source.html @@ -0,0 +1,1440 @@ + + + + + + +pva2pva: pdbApp/pvif.cpp Source File + + + + + + + + + +
+
+ + + + + + +
+
pva2pva +  1.4.1 +
+
+
+ + + + + + + + + +
+ +
+ + +
+
+
+
pvif.cpp
+
+
+
1 
+
2 
+
3 #include <pv/pvIntrospect.h> /* for pvdVersion.h */
+
4 #include <pv/standardField.h>
+
5 
+
6 #include <dbAccess.h>
+
7 #include <dbChannel.h>
+
8 #include <dbStaticLib.h>
+
9 #include <dbLock.h>
+
10 #include <dbEvent.h>
+
11 #include <alarm.h>
+
12 #include <errSymTbl.h>
+
13 #include <epicsVersion.h>
+
14 #include <errlog.h>
+
15 #include <osiSock.h>
+
16 
+
17 #include <pv/status.h>
+
18 #include <pv/bitSet.h>
+
19 #include <pv/pvData.h>
+
20 #include <pv/anyscalar.h>
+
21 #include <pv/reftrack.h>
+
22 #include <pv/pvAccess.h>
+
23 #include <pv/security.h>
+
24 
+
25 #include "sb.h"
+
26 #include "pvif.h"
+
27 
+
28 #include <epicsExport.h>
+
29 
+
30 #ifdef EPICS_VERSION_INT
+
31 # if EPICS_VERSION_INT>=VERSION_INT(3,16,1,0)
+
32 # define USE_INT64
+
33  // effects all uses of pv/typemap.h
+
34 # define CASE_REAL_INT64
+
35 # endif
+
36 #endif
+
37 
+
38 namespace pvd = epics::pvData;
+
39 namespace pva = epics::pvAccess;
+
40 
+
41 DBCH::DBCH(dbChannel *ch) :chan(ch)
+
42 {
+
43  if(!chan)
+
44  throw std::invalid_argument("NULL channel");
+
45  prepare();
+
46 }
+
47 
+
48 DBCH::DBCH(const std::string& name)
+
49  :chan(dbChannelCreate(name.c_str()))
+
50 {
+
51  if(!chan)
+
52  throw std::invalid_argument(SB()<<"invalid channel: "<<name);
+
53  prepare();
+
54 }
+
55 
+
56 void DBCH::prepare()
+
57 {
+
58  if(!chan)
+
59  throw std::invalid_argument(SB()<<"NULL channel");
+
60  if(dbChannelOpen(chan)) {
+
61  dbChannelDelete(chan);
+
62  throw std::invalid_argument(SB()<<"Failed to open channel "<<dbChannelName(chan));
+
63  }
+
64 }
+
65 
+
66 DBCH::~DBCH()
+
67 {
+
68  if(chan) dbChannelDelete(chan);
+
69 }
+
70 
+
71 void DBCH::swap(DBCH& o)
+
72 {
+
73  std::swap(chan, o.chan);
+
74 }
+
75 
+
76 void ASCred::update(const pva::ChannelRequester::shared_pointer& req)
+
77 {
+
78  pva::PeerInfo::const_shared_pointer info(req->getPeerInfo());
+
79  std::string usertemp, hosttemp;
+
80 
+
81  if(info && info->identified) {
+
82  hosttemp = info->peer;
+
83  if(info->authority=="ca") {
+
84  usertemp = info->account;
+
85  size_t sep = usertemp.find_last_of('/');
+
86  if(sep != std::string::npos) {
+
87  // prevent CA auth from claiming to be eg. "krb/someone.special"
+
88  usertemp = usertemp.substr(sep+1);
+
89  }
+
90 
+
91  } else {
+
92  usertemp = info->authority + "/" + info->account;
+
93  }
+
94 
+
95  const char role[] = "role/";
+
96 
+
97  groups.resize(info->roles.size());
+
98  size_t idx = 0u;
+
99  for(pva::PeerInfo::roles_t::const_iterator it(info->roles.begin()), end(info->roles.end()); it!=end; ++it, idx++) {
+
100  groups[idx].resize((*it).size()+sizeof(role)); // sizeof(role) includes trailing nil
+
101  std::copy(role,
+
102  role+sizeof(role)-1,
+
103  groups[idx].begin());
+
104  std::copy(it->begin(),
+
105  it->end(),
+
106  groups[idx].begin()+sizeof(role)-1);
+
107  groups[idx][groups[idx].size()-1] = '\0';
+
108  }
+
109 
+
110  } else {
+
111  // legacy and anonymous
+
112  hosttemp = req->getRequesterName();
+
113  }
+
114 
+
115  // remote names have the form "IP:port"
+
116  size_t sep = hosttemp.find_first_of(':');
+
117  if(sep == std::string::npos) {
+
118  sep = hosttemp.size();
+
119  }
+
120  hosttemp.resize(sep);
+
121 
+
122  host.resize(hosttemp.size()+1);
+
123  std::copy(hosttemp.begin(),
+
124  hosttemp.end(),
+
125  host.begin());
+
126  host[hosttemp.size()] = '\0';
+
127 
+
128  user.resize(usertemp.size()+1);
+
129  std::copy(usertemp.begin(),
+
130  usertemp.end(),
+
131  user.begin());
+
132  user[usertemp.size()] = '\0';
+
133 }
+
134 
+
135 ASCLIENT::~ASCLIENT()
+
136 {
+
137  asRemoveClient(&aspvt);
+
138  for(size_t i=0, N=grppvt.size(); i<N; i++) {
+
139  asRemoveClient(&grppvt[i]);
+
140  }
+
141 }
+
142 
+
143 void ASCLIENT::add(dbChannel* chan, ASCred& cred)
+
144 {
+
145  asRemoveClient(&aspvt);
+
146  /* asAddClient() fails secure to no-permission */
+
147  (void)asAddClient(&aspvt, dbChannelRecord(chan)->asp, dbChannelFldDes(chan)->as_level, &cred.user[0], &cred.host[0]);
+
148 
+
149  grppvt.resize(cred.groups.size(), 0);
+
150 
+
151  for(size_t i=0, N=grppvt.size(); i<N; i++) {
+
152  asRemoveClient(&grppvt[i]);
+
153  (void)asAddClient(&grppvt[i], dbChannelRecord(chan)->asp, dbChannelFldDes(chan)->as_level, &cred.groups[i][0], &cred.host[0]);
+
154  }
+
155 }
+
156 
+
157 bool ASCLIENT::canWrite() {
+
158  if(!asActive || (aspvt && asCheckPut(aspvt)))
+
159  return true;
+
160  for(size_t i=0, N=grppvt.size(); i<N; i++) {
+
161  if(grppvt[i] && asCheckPut(grppvt[i]))
+
162  return true;
+
163  }
+
164  return false;
+
165 }
+
166 
+
167 PVIF::PVIF(dbChannel *ch)
+
168  :chan(ch)
+
169 {}
+
170 
+
171 namespace {
+
172 
+
173 struct pvTimeAlarm {
+
174  dbChannel *chan;
+
175 
+
176  pvd::uint32 nsecMask;
+
177 
+
178  pvd::BitSet maskALWAYS, maskALARM;
+
179 
+
180  pvd::PVLongPtr sec;
+
181  pvd::PVIntPtr status, severity, nsec, userTag;
+
182  pvd::PVStringPtr message;
+
183 
+
184  pvTimeAlarm() :chan(NULL), nsecMask(0) {}
+
185 };
+
186 
+
187 struct pvCommon : public pvTimeAlarm {
+
188 
+
189  pvd::BitSet maskVALUE, maskPROPERTY, maskVALUEPut;
+
190 
+
191  pvd::PVDoublePtr displayLow, displayHigh, controlLow, controlHigh;
+
192  pvd::PVStringPtr egu, desc;
+
193  pvd::PVIntPtr fmt, prec;
+
194 
+
195  pvd::PVScalarPtr warnLow, warnHigh, alarmLow, alarmHigh;
+
196 
+
197  pvd::PVStringArrayPtr enumopts;
+
198 };
+
199 
+
200 struct pvScalar : public pvCommon {
+
201  typedef pvd::PVScalar pvd_type;
+
202  pvd::PVScalarPtr value;
+
203 };
+
204 
+
205 struct pvArray : public pvCommon {
+
206  typedef pvd::PVScalarArray pvd_type;
+
207  pvd::PVScalarArrayPtr value;
+
208 };
+
209 
+
210 struct metaTIME {
+
211  DBRstatus
+
212  DBRamsg
+
213  DBRtime
+
214  DBRutag
+
215 
+
216  enum {mask = DBR_STATUS | DBR_AMSG | DBR_TIME | DBR_UTAG};
+
217 };
+
218 
+
219 struct metaDOUBLE {
+
220  DBRstatus
+
221  DBRamsg
+
222  DBRunits
+
223  DBRprecision
+
224  DBRtime
+
225  DBRutag
+
226  DBRgrDouble
+
227  DBRctrlDouble
+
228  DBRalDouble
+
229 
+
230  // similar junk
+
231  DBRenumStrs
+
232 
+
233  enum {mask = DBR_STATUS | DBR_AMSG | DBR_UNITS | DBR_PRECISION | DBR_TIME | DBR_UTAG | DBR_GR_DOUBLE | DBR_CTRL_DOUBLE | DBR_AL_DOUBLE};
+
234 };
+
235 
+
236 struct metaENUM {
+
237  DBRstatus
+
238  DBRamsg
+
239  DBRtime
+
240  DBRutag
+
241  DBRenumStrs
+
242 
+
243  // similar junk
+
244  DBRunits
+
245  DBRprecision
+
246  DBRgrDouble
+
247  DBRctrlDouble
+
248  DBRalDouble
+
249 
+
250  enum {mask = DBR_STATUS | DBR_AMSG | DBR_TIME | DBR_UTAG | DBR_ENUM_STRS};
+
251 };
+
252 
+
253 struct metaSTRING {
+
254  DBRstatus
+
255  DBRamsg
+
256  DBRtime
+
257  DBRutag
+
258 
+
259  // similar junk
+
260  DBRenumStrs
+
261  DBRunits
+
262  DBRprecision
+
263  DBRgrDouble
+
264  DBRctrlDouble
+
265  DBRalDouble
+
266 
+
267  enum {mask = DBR_STATUS | DBR_AMSG | DBR_TIME | DBR_UTAG};
+
268 };
+
269 
+
270 void attachTime(pvTimeAlarm& pvm, const pvd::PVStructurePtr& pv)
+
271 {
+
272 #define FMAP(MNAME, PVT, FNAME, DBE) pvm.MNAME = pv->getSubFieldT<pvd::PVT>(FNAME); \
+
273  pvm.mask ## DBE.set(pvm.MNAME->getFieldOffset())
+
274  FMAP(status, PVInt, "alarm.status", ALARM);
+
275  FMAP(severity, PVInt, "alarm.severity", ALARM);
+
276  FMAP(message, PVString, "alarm.message", ALARM);
+
277  FMAP(sec, PVLong, "timeStamp.secondsPastEpoch", ALWAYS);
+
278  FMAP(nsec, PVInt, "timeStamp.nanoseconds", ALWAYS);
+
279 #ifdef HAVE_UTAG
+
280  FMAP(userTag, PVInt, "timeStamp.userTag", ALWAYS);
+
281 #endif
+
282 #undef FMAP
+
283 }
+
284 
+
285 static
+
286 pvd::shared_vector<const std::string> buildFormats()
+
287 {
+
288  pvd::shared_vector<std::string> fmt;
+
289  fmt.push_back("Default");
+
290  fmt.push_back("String");
+
291  fmt.push_back("Binary");
+
292  fmt.push_back("Decimal");
+
293  fmt.push_back("Hex");
+
294  fmt.push_back("Exponential");
+
295  fmt.push_back("Engineering");
+
296  return pvd::freeze(fmt);
+
297 }
+
298 
+
299 static const
+
300 pvd::shared_vector<const std::string> displayForms(buildFormats());
+
301 
+
302 // lookup fields and populate pvCommon. Non-existant fields will be NULL.
+
303 void attachMeta(pvCommon& pvm, const pvd::PVStructurePtr& pv)
+
304 {
+
305  {
+
306  pvd::PVStructurePtr fmt(pv->getSubField<pvd::PVStructure>("display.form"));
+
307  if(fmt) {
+
308  fmt->getSubFieldT<pvd::PVStringArray>("choices")->replace(displayForms);
+
309  }
+
310  }
+
311  attachTime(pvm, pv);
+
312 #define FMAP(MNAME, PVT, FNAME, DBE) pvm.MNAME = pv->getSubField<pvd::PVT>(FNAME); \
+
313  if(pvm.MNAME) pvm.mask ## DBE.set(pvm.MNAME->getFieldOffset())
+
314  FMAP(displayHigh, PVDouble, "display.limitHigh", PROPERTY);
+
315  FMAP(displayLow, PVDouble, "display.limitLow", PROPERTY);
+
316  FMAP(controlHigh, PVDouble, "control.limitHigh", PROPERTY);
+
317  FMAP(controlLow, PVDouble, "control.limitLow", PROPERTY);
+
318  FMAP(egu, PVString, "display.units", PROPERTY);
+
319  FMAP(desc, PVString, "display.description", PROPERTY);
+
320  FMAP(prec, PVInt, "display.precision", PROPERTY);
+
321  FMAP(fmt, PVInt, "display.form.index", PROPERTY);
+
322  FMAP(warnHigh, PVScalar, "valueAlarm.highWarningLimit", PROPERTY);
+
323  FMAP(warnLow, PVScalar, "valueAlarm.lowWarningLimit", PROPERTY);
+
324  FMAP(alarmHigh, PVScalar, "valueAlarm.highAlarmLimit", PROPERTY);
+
325  FMAP(alarmLow, PVScalar, "valueAlarm.lowAlarmLimit", PROPERTY);
+
326  FMAP(enumopts, PVStringArray, "value.choices", PROPERTY);
+
327 #undef FMAP
+
328 }
+
329 
+
330 template<typename PVX>
+
331 void attachAll(PVX& pvm, const pvd::PVStructurePtr& pv)
+
332 {
+
333  pvm.value = pv->getSubField<typename PVX::pvd_type>("value.index");
+
334  if(!pvm.value)
+
335  pvm.value = pv->getSubFieldT<typename PVX::pvd_type>("value");
+
336  const pvd::PVField *fld = pvm.value.get();
+
337  pvm.maskVALUE.set(fld->getFieldOffset());
+
338  for(;fld; fld = fld->getParent()) {
+
339  // set field bit and all enclosing structure bits
+
340  pvm.maskVALUEPut.set(fld->getFieldOffset());
+
341  }
+
342  pvm.maskVALUEPut.set(0);
+
343  attachMeta(pvm, pv);
+
344 }
+
345 
+
346 template<typename Meta>
+
347 void mapStatus(const Meta& meta, pvd::PVInt* status, pvd::PVString* message)
+
348 {
+
349 #ifdef HAVE_UTAG
+
350  if(meta.amsg[0]!='\0') {
+
351  message->put(meta.amsg);
+
352  } else
+
353 #endif
+
354  if(meta.status<ALARM_NSTATUS)
+
355  message->put(epicsAlarmConditionStrings[meta.status]);
+
356  else
+
357  message->put("???");
+
358 
+
359  // Arbitrary mapping from DB status codes
+
360  unsigned out;
+
361  switch(meta.status) {
+
362  case NO_ALARM:
+
363  out = 0;
+
364  break;
+
365  case READ_ALARM:
+
366  case WRITE_ALARM:
+
367  case HIHI_ALARM:
+
368  case HIGH_ALARM:
+
369  case LOLO_ALARM:
+
370  case LOW_ALARM:
+
371  case STATE_ALARM:
+
372  case COS_ALARM:
+
373  case HW_LIMIT_ALARM:
+
374  out = 1; // DEVICE
+
375  break;
+
376  case COMM_ALARM:
+
377  case TIMEOUT_ALARM:
+
378  case UDF_ALARM:
+
379  out = 2; // DRIVER
+
380  break;
+
381  case CALC_ALARM:
+
382  case SCAN_ALARM:
+
383  case LINK_ALARM:
+
384  case SOFT_ALARM:
+
385  case BAD_SUB_ALARM:
+
386  out = 3; // RECORD
+
387  break;
+
388  case DISABLE_ALARM:
+
389  case SIMM_ALARM:
+
390  case READ_ACCESS_ALARM:
+
391  case WRITE_ACCESS_ALARM:
+
392  out = 4; // DB
+
393  break;
+
394  default:
+
395  out = 6; // UNDEFINED
+
396  }
+
397 
+
398  status->put(out);
+
399 }
+
400 
+
401 
+
402 template<typename META>
+
403 void putMetaImpl(const pvTimeAlarm& pv, const META& meta)
+
404 {
+
405  pvd::int32 nsec = meta.time.nsec;
+
406  if(pv.nsecMask) {
+
407  pv.userTag->put(nsec&pv.nsecMask);
+
408  nsec &= ~pv.nsecMask;
+
409 #ifdef HAVE_UTAG
+
410  } else {
+
411  pv.userTag->put(meta.utag);
+
412 #endif
+
413  }
+
414  pv.nsec->put(nsec); pv.sec->put(meta.time.secPastEpoch+POSIX_TIME_AT_EPICS_EPOCH);
+
415 }
+
416 
+
417 void putTime(const pvTimeAlarm& pv, unsigned dbe, db_field_log *pfl)
+
418 {
+
419  metaTIME meta;
+
420  long options = (int)metaTIME::mask, nReq = 0;
+
421 
+
422  long status = dbChannelGet(pv.chan, dbChannelFinalFieldType(pv.chan), &meta, &options, &nReq, pfl);
+
423  if(status)
+
424  throw std::runtime_error("dbGet for meta fails");
+
425 
+
426  putMetaImpl(pv, meta);
+
427  if(dbe&DBE_ALARM) {
+
428  mapStatus(meta, pv.status.get(), pv.message.get());
+
429  pv.severity->put(meta.severity);
+
430  }
+
431 }
+
432 
+
433 void putValue(dbChannel *chan, pvd::PVScalar* value, db_field_log *pfl)
+
434 {
+
435  dbrbuf buf;
+
436  long nReq = 1;
+
437 
+
438  long status = dbChannelGet(chan, dbChannelFinalFieldType(chan), &buf, NULL, &nReq, pfl);
+
439  if(status)
+
440  throw std::runtime_error("dbGet for meta fails");
+
441 
+
442  if(nReq==0) {
+
443  // this was an actual max length 1 array, which has zero elements now.
+
444  memset(&buf, 0, sizeof(buf));
+
445  }
+
446 
+
447  switch(dbChannelFinalFieldType(chan)) {
+
448 #define CASE(BASETYPE, PVATYPE, DBFTYPE, PVACODE) case DBR_##DBFTYPE: value->putFrom<PVATYPE>(buf.dbf_##DBFTYPE); break;
+
449 #define CASE_ENUM
+
450 #define CASE_SKIP_BOOL
+
451 #include "pv/typemap.h"
+
452 #undef CASE_ENUM
+
453 #undef CASE_SKIP_BOOL
+
454 #undef CASE
+
455  case DBR_STRING:
+
456  buf.dbf_STRING[sizeof(buf.dbf_STRING)-1] = '\0';
+
457  value->putFrom<std::string>(buf.dbf_STRING);
+
458  break;
+
459  default:
+
460  throw std::runtime_error("putValue unsupported DBR code");
+
461  }
+
462 }
+
463 
+
464 void getValue(dbChannel *chan, pvd::PVScalar* value)
+
465 {
+
466  dbrbuf buf;
+
467 
+
468  switch(dbChannelFinalFieldType(chan)) {
+
469 #define CASE(BASETYPE, PVATYPE, DBFTYPE, PVACODE) case DBR_##DBFTYPE: buf.dbf_##DBFTYPE = value->getAs<PVATYPE>(); break;
+
470 #define CASE_ENUM
+
471 #define CASE_SKIP_BOOL
+
472 #include "pv/typemap.h"
+
473 #undef CASE_ENUM
+
474 #undef CASE_SKIP_BOOL
+
475 #undef CASE
+
476  case DBR_STRING:
+
477  {
+
478  std::string val(value->getAs<std::string>());
+
479  strncpy(buf.dbf_STRING, val.c_str(), sizeof(buf.dbf_STRING));
+
480  buf.dbf_STRING[sizeof(buf.dbf_STRING)-1] = '\0';
+
481  }
+
482  break;
+
483  default:
+
484  throw std::runtime_error("getValue unsupported DBR code");
+
485  }
+
486 
+
487  long status = dbChannelPut(chan, dbChannelFinalFieldType(chan), &buf, 1);
+
488  if(status)
+
489  throw std::runtime_error("dbPut for meta fails");
+
490 }
+
491 
+
492 void getValue(dbChannel *chan, pvd::PVScalarArray* value)
+
493 {
+
494  short dbr = dbChannelFinalFieldType(chan);
+
495 
+
496  if(dbr!=DBR_STRING) {
+
497  pvd::shared_vector<const void> buf;
+
498 
+
499  value->getAs(buf);
+
500  long nReq = buf.size()/pvd::ScalarTypeFunc::elementSize(value->getScalarArray()->getElementType());
+
501 
+
502  long status = dbChannelPut(chan, dbr, buf.data(), nReq);
+
503  if(status)
+
504  throw std::runtime_error("dbChannelPut fails");
+
505 
+
506  } else {
+
507  pvd::shared_vector<const std::string> buf;
+
508 
+
509  value->getAs(buf);
+
510 
+
511  std::vector<char> temp(buf.size()*MAX_STRING_SIZE);
+
512 
+
513  for(size_t i=0, N=buf.size(); i<N; i++)
+
514  {
+
515  strncpy(&temp[i*MAX_STRING_SIZE], buf[i].c_str(), MAX_STRING_SIZE-1);
+
516  temp[i*MAX_STRING_SIZE + MAX_STRING_SIZE-1] = '\0';
+
517  }
+
518 
+
519  long status = dbChannelPut(chan, dbr, &temp[0], buf.size());
+
520  if(status)
+
521  throw std::runtime_error("dbChannelPut fails");
+
522  }
+
523 }
+
524 
+
525 void putValue(dbChannel *chan, pvd::PVScalarArray* value, db_field_log *pfl)
+
526 {
+
527  const short dbr = dbChannelFinalFieldType(chan);
+
528 
+
529  long nReq = dbChannelFinalElements(chan);
+
530  const pvd::ScalarType etype = value->getScalarArray()->getElementType();
+
531 
+
532  if(dbr!=DBR_STRING) {
+
533 
+
534  pvd::shared_vector<void> buf(pvd::ScalarTypeFunc::allocArray(etype, nReq)); // TODO: pool?
+
535 
+
536  long status = dbChannelGet(chan, dbr, buf.data(), NULL, &nReq, pfl);
+
537  if(status)
+
538  throw std::runtime_error("dbChannelGet for value fails");
+
539 
+
540  buf.slice(0, nReq*pvd::ScalarTypeFunc::elementSize(etype));
+
541 
+
542  value->putFrom(pvd::freeze(buf));
+
543 
+
544  } else {
+
545  std::vector<char> temp(nReq*MAX_STRING_SIZE);
+
546 
+
547  long status = dbChannelGet(chan, dbr, &temp[0], NULL, &nReq, pfl);
+
548  if(status)
+
549  throw std::runtime_error("dbChannelGet for value fails");
+
550 
+
551  pvd::shared_vector<std::string> buf(nReq);
+
552  for(long i=0; i<nReq; i++) {
+
553  temp[i*MAX_STRING_SIZE + MAX_STRING_SIZE-1] = '\0';
+
554  buf[i] = std::string(&temp[i*MAX_STRING_SIZE]);
+
555  }
+
556 
+
557  value->putFrom(pvd::freeze(buf));
+
558  }
+
559 }
+
560 template<typename META>
+
561 void putMeta(const pvCommon& pv, unsigned dbe, db_field_log *pfl)
+
562 {
+
563  META meta;
+
564  long options = (int)META::mask, nReq = 0;
+
565  dbCommon *prec = dbChannelRecord(pv.chan);
+
566 
+
567  long status = dbChannelGet(pv.chan, dbChannelFinalFieldType(pv.chan), &meta, &options, &nReq, pfl);
+
568  if(status)
+
569  throw std::runtime_error("dbGet for meta fails");
+
570 
+
571  putMetaImpl(pv, meta);
+
572 #define FMAP(MNAME, FNAME) pv.MNAME->put(meta.FNAME)
+
573  if(dbe&DBE_ALARM) {
+
574  mapStatus(meta, pv.status.get(), pv.message.get());
+
575  FMAP(severity, severity);
+
576  }
+
577  if(dbe&DBE_PROPERTY) {
+
578 #undef FMAP
+
579  if(pv.desc) pv.desc->put(prec->desc);
+
580 #define FMAP(MASK, MNAME, FNAME) if(META::mask&(MASK) && pv.MNAME) pv.MNAME->put(meta.FNAME)
+
581  FMAP(DBR_GR_DOUBLE, displayHigh, upper_disp_limit);
+
582  FMAP(DBR_GR_DOUBLE, displayLow, lower_disp_limit);
+
583  FMAP(DBR_CTRL_DOUBLE, controlHigh, upper_ctrl_limit);
+
584  FMAP(DBR_CTRL_DOUBLE, controlLow, lower_ctrl_limit);
+
585  FMAP(DBR_GR_DOUBLE, egu, units);
+
586 #undef FMAP
+
587  if(META::mask&DBR_PRECISION && pv.prec) {
+
588  pv.prec->put(pvd::int32(meta.precision.dp));
+
589  }
+
590 #define FMAP(MASK, MNAME, FNAME) if(META::mask&(MASK) && pv.MNAME) pv.MNAME->putFrom(meta.FNAME)
+
591  // not handling precision until I get a better idea of what 'format' is supposed to be...
+
592  //FMAP(prec, PVScalar, "display.form", PROPERTY);
+
593  FMAP(DBR_AL_DOUBLE, warnHigh, upper_warning_limit);
+
594  FMAP(DBR_AL_DOUBLE, warnLow, lower_warning_limit);
+
595  FMAP(DBR_AL_DOUBLE, alarmHigh, upper_alarm_limit);
+
596  FMAP(DBR_AL_DOUBLE, alarmLow, lower_alarm_limit);
+
597 #undef FMAP
+
598  if(pv.enumopts) {
+
599  pvd::shared_vector<std::string> strs(meta.no_str);
+
600  for(size_t i=0; i<strs.size(); i++)
+
601  {
+
602  meta.strs[i][sizeof(meta.strs[i])-1] = '\0';
+
603  strs[i] = meta.strs[i];
+
604  }
+
605  pv.enumopts->replace(pvd::freeze(strs));
+
606  }
+
607  }
+
608 }
+
609 
+
610 template<typename PVC, typename META>
+
611 void putAll(const PVC &pv, unsigned dbe, db_field_log *pfl)
+
612 {
+
613  if(dbe&(DBE_VALUE|DBE_ARCHIVE)) {
+
614  putValue(pv.chan, pv.value.get(), pfl);
+
615  }
+
616  if(!(dbe&DBE_PROPERTY)) {
+
617  putTime(pv, dbe, pfl);
+
618  } else {
+
619  putMeta<META>(pv, dbe, pfl);
+
620  }
+
621 }
+
622 
+
623 void findNSMask(pvTimeAlarm& pvmeta, pdbRecordIterator& info, const epics::pvData::PVStructurePtr& pvalue)
+
624 {
+
625  const char *UT = info.info("Q:time:tag");
+
626  if(UT && strncmp(UT, "nsec:lsb:", 9)==0) {
+
627  try{
+
628  pvmeta.nsecMask = epics::pvData::castUnsafe<pvd::uint32>(std::string(&UT[9]));
+
629  }catch(std::exception& e){
+
630  pvmeta.nsecMask = 0;
+
631  std::cerr<<info.name()<<" : Q:time:tag nsec:lsb: requires a number not '"<<UT[9]<<"'\n";
+
632  }
+
633  }
+
634  if(pvmeta.nsecMask>0 && pvmeta.nsecMask<=32) {
+
635  pvmeta.userTag = pvalue->getSubField<pvd::PVInt>("timeStamp.userTag");
+
636  if(!pvmeta.userTag) {
+
637  pvmeta.nsecMask = 0; // struct doesn't have userTag
+
638  } else {
+
639  pvd::uint64 mask = (1<<pvmeta.nsecMask)-1;
+
640  pvmeta.nsecMask = mask;
+
641  pvmeta.maskALWAYS.set(pvmeta.userTag->getFieldOffset());
+
642  }
+
643  } else
+
644  pvmeta.nsecMask = 0;
+
645 }
+
646 
+
647 void findFormat(pvTimeAlarm& pvmeta, pdbRecordIterator& info, const epics::pvData::PVStructurePtr& pvalue)
+
648 {
+
649  const char *FMT = info.info("Q:form");
+
650  if(FMT) {
+
651  pvd::PVScalarPtr fmt(pvalue->getSubField<pvd::PVScalar>("display.form.index"));
+
652  if(fmt) {
+
653  bool found = false;
+
654  for(size_t i=0; !found && i<displayForms.size(); i++) {
+
655  if((found=(displayForms[i]==FMT)))
+
656  fmt->putFrom<pvd::uint32>(i);
+
657  }
+
658  if(!found) {
+
659  try {
+
660  fmt->putFrom(std::string(FMT)); // attempt to parse as number
+
661  }catch(std::exception& e){
+
662  errlogPrintf("%s: info(Q:form, \"%s\") is not known format: %s\n", info.name(), FMT, e.what());
+
663  }
+
664  }
+
665  }
+
666  }
+
667 }
+
668 
+
669 pvd::Status checkDISP(dbChannel *chan)
+
670 {
+
671  dbCommon *prec = dbChannelRecord(chan);
+
672  pvd::Status ret;
+
673  if(prec->disp && dbChannelField(chan)!=&prec->disp)
+
674  ret = pvd::Status::error("Put Disabled");
+
675  return ret;
+
676 }
+
677 
+
678 template<typename PVX, typename META>
+
679 struct PVIFScalarNumeric : public PVIF
+
680 {
+
681  PVX pvmeta;
+
682  const epics::pvData::PVStructurePtr pvalue;
+
683 
+
684  PVIFScalarNumeric(dbChannel *ch, const epics::pvData::PVFieldPtr& p, pvd::PVField *enclosing)
+
685  :PVIF(ch)
+
686  ,pvalue(std::tr1::dynamic_pointer_cast<pvd::PVStructure>(p))
+
687  {
+
688  if(!pvalue)
+
689  throw std::runtime_error("Must attach to structure");
+
690 
+
691  pvmeta.chan = ch;
+
692  attachAll<PVX>(pvmeta, pvalue);
+
693  if(enclosing) {
+
694  size_t bit = enclosing->getFieldOffset();
+
695  // we are inside a structure array or similar with only one bit for all ours fields
+
696  pvmeta.maskALWAYS.clear();
+
697  pvmeta.maskALWAYS.set(bit);
+
698  pvmeta.maskVALUE.clear();
+
699  pvmeta.maskVALUE.set(bit);
+
700  pvmeta.maskALARM.clear();
+
701  pvmeta.maskALARM.set(bit);
+
702  pvmeta.maskPROPERTY.clear();
+
703  pvmeta.maskPROPERTY.set(bit);
+
704  pvmeta.maskVALUEPut.clear();
+
705  pvmeta.maskVALUEPut.set(0);
+
706  pvmeta.maskVALUEPut.set(bit);
+
707  }
+
708  pdbRecordIterator info(chan);
+
709  findNSMask(pvmeta, info, pvalue);
+
710  findFormat(pvmeta, info, pvalue);
+
711  }
+
712  virtual ~PVIFScalarNumeric() {}
+
713 
+
714  virtual void put(epics::pvData::BitSet& mask, unsigned dbe, db_field_log *pfl) OVERRIDE FINAL
+
715  {
+
716  try{
+
717  putAll<PVX, META>(pvmeta, dbe, pfl);
+
718  mask |= pvmeta.maskALWAYS;
+
719  if(dbe&(DBE_VALUE|DBE_ARCHIVE))
+
720  mask |= pvmeta.maskVALUE;
+
721  if(dbe&DBE_ALARM)
+
722  mask |= pvmeta.maskALARM;
+
723  if(dbe&DBE_PROPERTY)
+
724  mask |= pvmeta.maskPROPERTY;
+
725  }catch(...){
+
726  pvmeta.severity->put(3);
+
727  mask |= pvmeta.maskALARM;
+
728  throw;
+
729  }
+
730  }
+
731 
+
732  virtual pvd::Status get(const epics::pvData::BitSet& mask, proc_t proc, bool permit) OVERRIDE FINAL
+
733  {
+
734  pvd::Status ret = checkDISP(chan);
+
735  if(!ret)
+
736  return ret;
+
737 
+
738  bool newval = mask.logical_and(pvmeta.maskVALUEPut);
+
739  if(newval) {
+
740  if(permit)
+
741  getValue(pvmeta.chan, pvmeta.value.get());
+
742  else
+
743  ret = pvd::Status::error("Put not permitted");
+
744  }
+
745  if(newval || proc==PVIF::ProcForce) {
+
746  if(permit)
+
747  ret = PVIF::get(mask, proc);
+
748  else
+
749  ret = pvd::Status::error("Process not permitted");
+
750  }
+
751  return ret;
+
752  }
+
753 
+
754  virtual unsigned dbe(const epics::pvData::BitSet& mask) OVERRIDE FINAL
+
755  {
+
756  unsigned ret = 0;
+
757  if(mask.logical_and(pvmeta.maskVALUE))
+
758  ret |= DBE_VALUE;
+
759  if(mask.logical_and(pvmeta.maskALARM))
+
760  ret |= DBE_ALARM;
+
761  if(mask.logical_and(pvmeta.maskPROPERTY))
+
762  ret |= DBE_PROPERTY;
+
763  return ret;
+
764  }
+
765 };
+
766 
+
767 } // namespace
+
768 
+
769 static
+
770 pvd::ScalarType DBR2PVD(short dbr)
+
771 {
+
772  switch(dbr) {
+
773 #define CASE(BASETYPE, PVATYPE, DBFTYPE, PVACODE) case DBR_##DBFTYPE: return pvd::pv##PVACODE;
+
774 #define CASE_ENUM
+
775 #define CASE_SKIP_BOOL
+
776 #include "pv/typemap.h"
+
777 #undef CASE_ENUM
+
778 #undef CASE_SKIP_BOOL
+
779 #undef CASE
+
780  case DBF_STRING: return pvd::pvString;
+
781  }
+
782  throw std::invalid_argument("Unsupported DBR code");
+
783 }
+
784 
+
785 short PVD2DBR(pvd::ScalarType pvt)
+
786 {
+
787  switch(pvt) {
+
788 #define CASE(BASETYPE, PVATYPE, DBFTYPE, PVACODE) case pvd::pv##PVACODE: return DBR_##DBFTYPE;
+
789 #ifndef USE_INT64
+
790 # define CASE_SQUEEZE_INT64
+
791 #endif
+
792 #include "pv/typemap.h"
+
793 #ifndef USE_INT64
+
794 # undef CASE_SQUEEZE_INT64
+
795 #endif
+
796 #undef CASE
+
797  case pvd::pvString: return DBF_STRING;
+
798  }
+
799  return -1;
+
800 }
+
801 
+
802 static
+
803 pvd::StructureConstPtr buildTimeStamp()
+
804 {
+
805  return pvd::FieldBuilder::begin()
+
806  ->add("secondsPastEpoch", pvd::pvLong)
+
807  ->add("nanoseconds", pvd::pvInt)
+
808  ->add("userTag", pvd::pvInt)
+
809  ->createStructure();
+
810 }
+
811 
+
812 epics::pvData::FieldConstPtr
+
813 ScalarBuilder::dtype()
+
814 {
+
815  if(!channel)
+
816  throw std::runtime_error("+type:\"scalar\" requires +channel:");
+
817 
+
818  short dbr = dbChannelFinalFieldType(channel);
+
819  const long maxelem = dbChannelFinalElements(channel);
+
820  const pvd::ScalarType pvt = DBR2PVD(dbr);
+
821 
+
822  if(INVALID_DB_REQ(dbr))
+
823  throw std::invalid_argument("DBF code out of range");
+
824 
+
825  if(maxelem!=1 && dbr==DBR_ENUM)
+
826  dbr = DBF_SHORT;
+
827 
+
828  pvd::FieldBuilderPtr builder(pvd::getFieldCreate()->createFieldBuilder());
+
829  pvd::StandardFieldPtr standard(pvd::getStandardField());
+
830 
+
831  if(dbr==DBR_ENUM)
+
832  builder = builder->setId("epics:nt/NTEnum:1.0")
+
833  ->addNestedStructure("value")
+
834  ->setId("enum_t")
+
835  ->add("index", pvd::pvInt)
+
836  ->addArray("choices", pvd::pvString)
+
837  ->endNested();
+
838  else if(maxelem==1)
+
839  builder = builder->setId("epics:nt/NTScalar:1.0")
+
840  ->add("value", pvt);
+
841  else
+
842  builder = builder->setId("epics:nt/NTScalarArray:1.0")
+
843  ->addArray("value", pvt);
+
844 
+
845  builder = builder->add("alarm", standard->alarm())
+
846  ->add("timeStamp", buildTimeStamp());
+
847 
+
848  if(dbr!=DBR_ENUM) {
+
849  builder = builder->addNestedStructure("display")
+
850  ->add("limitLow", pvd::pvDouble)
+
851  ->add("limitHigh", pvd::pvDouble)
+
852  ->add("description", pvd::pvString)
+
853  ->add("units", pvd::pvString)
+
854  ->add("precision", pvd::pvInt)
+
855  ->addNestedStructure("form")
+
856  ->setId("enum_t")
+
857  ->add("index", pvd::pvInt)
+
858  ->addArray("choices", pvd::pvString)
+
859  ->endNested()
+
860  ->endNested()
+
861  ->add("control", standard->control());
+
862 
+
863  if(dbr!=DBR_STRING)
+
864  builder = builder->add("valueAlarm", standard->doubleAlarm());
+
865  }
+
866 
+
867  return builder->createStructure();
+
868 }
+
869 
+
870 PVIF*
+
871 ScalarBuilder::attach(const epics::pvData::PVStructurePtr& root, const FieldName& fldname)
+
872 {
+
873  if(!channel)
+
874  throw std::runtime_error("+type:\"scalar\" requires +channel:");
+
875  pvd::PVField *enclosing = 0;
+
876  pvd::PVFieldPtr fld(fldname.lookup(root, &enclosing));
+
877 
+
878  const short dbr = dbChannelFinalFieldType(channel);
+
879  const long maxelem = dbChannelFinalElements(channel);
+
880 
+
881  if(maxelem==1) {
+
882  switch(dbr) {
+
883  case DBR_CHAR:
+
884  case DBR_UCHAR:
+
885  case DBR_SHORT:
+
886  case DBR_USHORT:
+
887  case DBR_LONG:
+
888  case DBR_ULONG:
+
889 #ifdef USE_INT64
+
890  case DBR_INT64:
+
891  case DBR_UINT64:
+
892 #endif
+
893  return new PVIFScalarNumeric<pvScalar, metaDOUBLE>(channel, fld, enclosing);
+
894  case DBR_FLOAT:
+
895  case DBR_DOUBLE:
+
896  return new PVIFScalarNumeric<pvScalar, metaDOUBLE>(channel, fld, enclosing);
+
897  case DBR_ENUM:
+
898  return new PVIFScalarNumeric<pvScalar, metaENUM>(channel, fld, enclosing);
+
899  case DBR_STRING:
+
900  return new PVIFScalarNumeric<pvScalar, metaSTRING>(channel, fld, enclosing);
+
901  }
+
902  } else {
+
903  switch(dbr) {
+
904  case DBR_CHAR:
+
905  case DBR_UCHAR:
+
906  case DBR_SHORT:
+
907  case DBR_ENUM:
+
908  case DBR_USHORT:
+
909  case DBR_LONG:
+
910  case DBR_ULONG:
+
911  case DBR_STRING:
+
912  case DBR_FLOAT:
+
913 #ifdef USE_INT64
+
914  case DBR_INT64:
+
915  case DBR_UINT64:
+
916 #endif
+
917  case DBR_DOUBLE:
+
918  return new PVIFScalarNumeric<pvArray, metaDOUBLE>(channel, fld, enclosing);
+
919  }
+
920  }
+
921 
+
922  throw std::invalid_argument("Channel has invalid/unsupported DBR type");
+
923 }
+
924 
+
925 namespace {
+
926 template<class PVD>
+
927 struct PVIFPlain : public PVIF
+
928 {
+
929  const typename PVD::shared_pointer field;
+
930  size_t fieldOffset;
+
931  dbChannel * const channel;
+
932 
+
933  PVIFPlain(dbChannel *channel, const epics::pvData::PVFieldPtr& fld, epics::pvData::PVField* enclosing=0)
+
934  :PVIF(channel)
+
935  ,field(std::tr1::static_pointer_cast<PVD>(fld))
+
936  ,channel(channel)
+
937  {
+
938  if(!field)
+
939  throw std::logic_error("PVIFPlain attached type mis-match");
+
940  if(enclosing)
+
941  fieldOffset = enclosing->getFieldOffset();
+
942  else
+
943  fieldOffset = field->getFieldOffset();
+
944  }
+
945 
+
946  virtual ~PVIFPlain() {}
+
947 
+
948  virtual void put(epics::pvData::BitSet& mask, unsigned dbe, db_field_log *pfl) OVERRIDE FINAL
+
949  {
+
950  if(dbe&DBE_VALUE) {
+
951  putValue(channel, field.get(), pfl);
+
952  mask.set(fieldOffset);
+
953  }
+
954  }
+
955 
+
956  virtual pvd::Status get(const epics::pvData::BitSet& mask, proc_t proc, bool permit) OVERRIDE FINAL
+
957  {
+
958  pvd::Status ret = checkDISP(chan);
+
959  if(!ret)
+
960  return ret;
+
961 
+
962  bool newval = mask.get(fieldOffset);
+
963  if(newval) {
+
964  if(permit)
+
965  getValue(channel, field.get());
+
966  else
+
967  ret = pvd::Status::error("Put not permitted");
+
968  }
+
969  if(newval || proc==PVIF::ProcForce) {
+
970  if(permit)
+
971  ret = PVIF::get(mask, proc);
+
972  else
+
973  ret = pvd::Status::error("Process not permitted");
+
974  }
+
975  return ret;
+
976  }
+
977 
+
978  virtual unsigned dbe(const epics::pvData::BitSet& mask) OVERRIDE FINAL
+
979  {
+
980  // TODO: figure out how to handle various intermidiate compressed
+
981  // bitSet and enclosing.
+
982  // Until then check only also for wildcard bit (0).
+
983  if(mask.get(fieldOffset) || mask.get(0))
+
984  return DBE_VALUE;
+
985  return 0;
+
986  }
+
987 };
+
988 
+
989 struct PlainBuilder : public PVIFBuilder
+
990 {
+
991  explicit PlainBuilder(dbChannel* chan) :PVIFBuilder(chan) {}
+
992  virtual ~PlainBuilder() {}
+
993 
+
994  // fetch the structure description
+
995  virtual epics::pvData::FieldConstPtr dtype() OVERRIDE FINAL {
+
996  if(!channel)
+
997  throw std::runtime_error("+type:\"plain\" requires +channel:");
+
998 
+
999  const short dbr = dbChannelFinalFieldType(channel);
+
1000  const long maxelem = dbChannelFinalElements(channel);
+
1001  const pvd::ScalarType pvt = DBR2PVD(dbr);
+
1002 
+
1003  if(INVALID_DB_REQ(dbr))
+
1004  throw std::invalid_argument("DBF code out of range");
+
1005 
+
1006  if(maxelem==1)
+
1007  return pvd::getFieldCreate()->createScalar(pvt);
+
1008  else
+
1009  return pvd::getFieldCreate()->createScalarArray(pvt);
+
1010  }
+
1011 
+
1012  // Attach to a structure instance.
+
1013  // must be of the type returned by dtype().
+
1014  // need not be the root structure
+
1015  virtual PVIF* attach(const epics::pvData::PVStructurePtr& root,
+
1016  const FieldName& fldname) OVERRIDE FINAL
+
1017  {
+
1018  if(!channel)
+
1019  throw std::runtime_error("+type:\"plain\" requires +channel:");
+
1020  const long maxelem = dbChannelFinalElements(channel);
+
1021 
+
1022  pvd::PVField *enclosing = 0;
+
1023  pvd::PVFieldPtr fld(fldname.lookup(root, &enclosing));
+
1024 
+
1025  if(maxelem==1)
+
1026  return new PVIFPlain<pvd::PVScalar>(channel, fld, enclosing);
+
1027  else
+
1028  return new PVIFPlain<pvd::PVScalarArray>(channel, fld, enclosing);
+
1029  }
+
1030 };
+
1031 
+
1032 struct AnyScalarBuilder : public PVIFBuilder
+
1033 {
+
1034  explicit AnyScalarBuilder(dbChannel* chan) :PVIFBuilder(chan) {}
+
1035  virtual ~AnyScalarBuilder() {}
+
1036 
+
1037  // fetch the structure description
+
1038  virtual epics::pvData::FieldConstPtr dtype() OVERRIDE FINAL {
+
1039  (void)channel; //ignored
+
1040  return pvd::getFieldCreate()->createVariantUnion();
+
1041  }
+
1042 
+
1043  // Attach to a structure instance.
+
1044  // must be of the type returned by dtype().
+
1045  // need not be the root structure
+
1046  virtual PVIF* attach(const epics::pvData::PVStructurePtr& root,
+
1047  const FieldName& fldname) OVERRIDE FINAL
+
1048  {
+
1049  if(!channel)
+
1050  throw std::runtime_error("+type:\"any\" requires +channel:");
+
1051  pvd::PVDataCreatePtr create(pvd::getPVDataCreate());
+
1052  const short dbr = dbChannelFinalFieldType(channel);
+
1053  const long maxelem = dbChannelFinalElements(channel);
+
1054  const pvd::ScalarType pvt = DBR2PVD(dbr);
+
1055 
+
1056  pvd::PVField *enclosing = 0;
+
1057  pvd::PVFieldPtr fld(fldname.lookup(root, &enclosing));
+
1058 
+
1059  pvd::PVUnion *value = dynamic_cast<pvd::PVUnion*>(fld.get());
+
1060  if(!value)
+
1061  throw std::logic_error("Mis-matched attachment point");
+
1062 
+
1063  pvd::PVFieldPtr arr(value->get());
+
1064  if(!arr) {
+
1065  if(maxelem==1)
+
1066  arr = create->createPVScalar(pvt);
+
1067  else
+
1068  arr = create->createPVScalarArray(pvt);
+
1069  value->set(arr);
+
1070  }
+
1071 
+
1072  if(maxelem==1)
+
1073  return new PVIFPlain<pvd::PVScalar>(channel, arr, enclosing ? enclosing : arr.get());
+
1074  else
+
1075  return new PVIFPlain<pvd::PVScalarArray>(channel, arr, enclosing ? enclosing : arr.get());
+
1076  }
+
1077 
+
1078 };
+
1079 
+
1080 struct PVIFMeta : public PVIF
+
1081 {
+
1082  pvTimeAlarm meta;
+
1083 
+
1084  PVIFMeta(dbChannel *channel, const epics::pvData::PVFieldPtr& fld, epics::pvData::PVField* enclosing=0)
+
1085  :PVIF(channel)
+
1086  {
+
1087  pvd::PVStructurePtr field(std::tr1::dynamic_pointer_cast<pvd::PVStructure>(fld));
+
1088  if(!field)
+
1089  throw std::logic_error("PVIFMeta attached type mis-match");
+
1090  meta.chan = channel;
+
1091  pdbRecordIterator info(chan);
+
1092  attachTime(meta, field);
+
1093  findNSMask(meta, info, field);
+
1094  findFormat(meta, info, field);
+
1095  if(enclosing) {
+
1096  meta.maskALWAYS.clear();
+
1097  meta.maskALWAYS.set(enclosing->getFieldOffset());
+
1098  meta.maskALARM.clear();
+
1099  meta.maskALARM.set(enclosing->getFieldOffset());
+
1100  }
+
1101  }
+
1102 
+
1103  virtual ~PVIFMeta() {}
+
1104 
+
1105  virtual void put(epics::pvData::BitSet& mask, unsigned dbe, db_field_log *pfl) OVERRIDE FINAL
+
1106  {
+
1107  mask |= meta.maskALWAYS;
+
1108  if(dbe&DBE_ALARM)
+
1109  mask |= meta.maskALARM;
+
1110 
+
1111  putTime(meta, dbe, pfl);
+
1112  }
+
1113 
+
1114  virtual pvd::Status get(const epics::pvData::BitSet& mask, proc_t proc, bool permit) OVERRIDE FINAL
+
1115  {
+
1116  // can't put time/alarm
+
1117  if(mask.logical_and(meta.maskALARM))
+
1118  return pvd::Status::warn("Put to meta field ignored");
+
1119  return pvd::Status::Ok;
+
1120  }
+
1121 
+
1122  virtual unsigned dbe(const epics::pvData::BitSet& mask) OVERRIDE FINAL
+
1123  {
+
1124  if(mask.logical_and(meta.maskALARM))
+
1125  return DBE_ALARM;
+
1126  return 0;
+
1127  }
+
1128 };
+
1129 
+
1130 struct MetaBuilder : public PVIFBuilder
+
1131 {
+
1132  explicit MetaBuilder(dbChannel* chan) :PVIFBuilder(chan) {}
+
1133  virtual ~MetaBuilder() {}
+
1134 
+
1135  // fetch the structure description
+
1136  virtual epics::pvData::FieldConstPtr dtype() OVERRIDE FINAL {
+
1137  throw std::logic_error("Don't call me");
+
1138  }
+
1139 
+
1140  virtual epics::pvData::FieldBuilderPtr dtype(epics::pvData::FieldBuilderPtr& builder,
+
1141  const std::string& fld) OVERRIDE FINAL
+
1142  {
+
1143  pvd::StandardFieldPtr std(pvd::getStandardField());
+
1144  if(fld.empty()) {
+
1145  return builder->add("alarm", std->alarm())
+
1146  ->add("timeStamp", buildTimeStamp());
+
1147  } else {
+
1148  return builder->addNestedStructure(fld)
+
1149  ->add("alarm", std->alarm())
+
1150  ->add("timeStamp", buildTimeStamp())
+
1151  ->endNested();
+
1152  }
+
1153  }
+
1154 
+
1155  // Attach to a structure instance.
+
1156  // must be of the type returned by dtype().
+
1157  // need not be the root structure
+
1158  virtual PVIF* attach(const epics::pvData::PVStructurePtr& root,
+
1159  const FieldName& fldname) OVERRIDE FINAL
+
1160  {
+
1161  if(!channel)
+
1162  throw std::runtime_error("+type:\"meta\" requires +channel:");
+
1163 
+
1164  pvd::PVField *enclosing = 0;
+
1165  pvd::PVFieldPtr fld(fldname.lookup(root, &enclosing));
+
1166 
+
1167  return new PVIFMeta(channel, fld, enclosing);
+
1168  }
+
1169 
+
1170 };
+
1171 
+
1172 struct PVIFProc : public PVIF
+
1173 {
+
1174  PVIFProc(dbChannel *channel) :PVIF(channel) {}
+
1175 
+
1176  virtual void put(epics::pvData::BitSet& mask, unsigned dbe, db_field_log *pfl) OVERRIDE FINAL
+
1177  {
+
1178  // nothing to get
+
1179  }
+
1180 
+
1181  virtual pvd::Status get(const epics::pvData::BitSet& mask, proc_t proc, bool permit) OVERRIDE FINAL
+
1182  {
+
1183  // always process (if permitted)
+
1184  return PVIF::get(mask, PVIF::ProcForce, permit);
+
1185  }
+
1186 
+
1187  virtual unsigned dbe(const epics::pvData::BitSet& mask) OVERRIDE FINAL
+
1188  {
+
1189  return 0;
+
1190  }
+
1191 };
+
1192 
+
1193 struct ProcBuilder : public PVIFBuilder
+
1194 {
+
1195  explicit ProcBuilder(dbChannel* chan) :PVIFBuilder(chan) {}
+
1196  virtual ~ProcBuilder() {}
+
1197 
+
1198  // fetch the structure description
+
1199  virtual epics::pvData::FieldConstPtr dtype() OVERRIDE FINAL {
+
1200  throw std::logic_error("Don't call me");
+
1201  }
+
1202 
+
1203  virtual epics::pvData::FieldBuilderPtr dtype(epics::pvData::FieldBuilderPtr& builder,
+
1204  const std::string& fld) OVERRIDE FINAL
+
1205  {
+
1206  // invisible
+
1207  return builder;
+
1208  }
+
1209  virtual PVIF* attach(const epics::pvData::PVStructurePtr& root,
+
1210  const FieldName& fldname) OVERRIDE FINAL
+
1211  {
+
1212  if(!channel)
+
1213  throw std::runtime_error("+type:\"proc\" requires +channel:");
+
1214 
+
1215  return new PVIFProc(channel);
+
1216  }
+
1217 };
+
1218 
+
1219 struct PVIFNoOp : public PVIF
+
1220 {
+
1221  PVIFNoOp(dbChannel *channel) :PVIF(channel) {}
+
1222 
+
1223  virtual void put(epics::pvData::BitSet& mask, unsigned dbe, db_field_log *pfl) OVERRIDE FINAL
+
1224  {}
+
1225 
+
1226  virtual pvd::Status get(const epics::pvData::BitSet& mask, proc_t proc, bool permit) OVERRIDE FINAL
+
1227  {
+
1228  return pvd::Status();
+
1229  }
+
1230 
+
1231  virtual unsigned dbe(const epics::pvData::BitSet& mask) OVERRIDE FINAL
+
1232  {
+
1233  return 0;
+
1234  }
+
1235 };
+
1236 
+
1237 struct IDBuilder : public PVIFBuilder
+
1238 {
+
1239  explicit IDBuilder(dbChannel* chan) :PVIFBuilder(chan) {}
+
1240  virtual ~IDBuilder() {}
+
1241 
+
1242  // fetch the structure description
+
1243  virtual epics::pvData::FieldConstPtr dtype() OVERRIDE FINAL {
+
1244  throw std::logic_error("Don't call me");
+
1245  }
+
1246 
+
1247  virtual epics::pvData::FieldBuilderPtr dtype(epics::pvData::FieldBuilderPtr& builder,
+
1248  const std::string& fld) OVERRIDE FINAL
+
1249  {
+
1250  // caller has already done builder->setId(...)
+
1251  return builder;
+
1252  }
+
1253  virtual PVIF* attach(const epics::pvData::PVStructurePtr& root,
+
1254  const FieldName& fldname) OVERRIDE FINAL
+
1255  {
+
1256  return new PVIFNoOp(channel);
+
1257  }
+
1258 };
+
1259 
+
1260 }//namespace
+
1261 
+
1262 pvd::Status PVIF::get(const epics::pvData::BitSet& mask, proc_t proc, bool permit)
+
1263 {
+
1264  dbCommon *precord = dbChannelRecord(chan);
+
1265 
+
1266  bool tryproc = proc!=ProcPassive ? proc==ProcForce :
+
1267  dbChannelField(chan) == &precord->proc ||
+
1268  (dbChannelFldDes(chan)->process_passive &&
+
1269  precord->scan == 0);
+
1270 
+
1271  pvd::Status ret;
+
1272 
+
1273  if (tryproc) {
+
1274  if (!permit) {
+
1275  return pvd::Status::error("Process not permitted");
+
1276 
+
1277  } else if (precord->pact) {
+
1278  if (precord->tpro)
+
1279  printf("%s: Active %s\n",
+
1280  epicsThreadGetNameSelf(), precord->name);
+
1281  precord->rpro = TRUE;
+
1282  } else {
+
1283  /* indicate that dbPutField called dbProcess */
+
1284  precord->putf = TRUE;
+
1285  long err = dbProcess(precord);
+
1286  if(err) {
+
1287  char buf[32];
+
1288  errSymLookup(err, buf, sizeof(buf));
+
1289  std::ostringstream msg;
+
1290  msg<<"process error : "<<buf;
+
1291  ret = pvd::Status::error(msg.str());
+
1292  }
+
1293  }
+
1294  }
+
1295 
+
1296  return ret;
+
1297 }
+
1298 
+
1299 epics::pvData::FieldBuilderPtr
+
1300 PVIFBuilder::dtype(epics::pvData::FieldBuilderPtr& builder,
+
1301  const std::string &fld)
+
1302 {
+
1303  if(fld.empty())
+
1304  throw std::runtime_error(SB()<<"Can't attach +type "<<typeid(*this).name()<<" to root");
+
1305 
+
1306  epics::pvData::FieldConstPtr ftype(this->dtype());
+
1307  if(ftype)
+
1308  builder = builder->add(fld, ftype);
+
1309 
+
1310  return builder;
+
1311 }
+
1312 
+
1313 PVIFBuilder* PVIFBuilder::create(const std::string& type, dbChannel* chan)
+
1314 {
+
1315  if(type.empty() || type=="scalar")
+
1316  return new ScalarBuilder(chan);
+
1317  else if(type=="plain")
+
1318  return new PlainBuilder(chan);
+
1319  else if(type=="any")
+
1320  return new AnyScalarBuilder(chan);
+
1321  else if(type=="meta")
+
1322  return new MetaBuilder(chan);
+
1323  else if(type=="proc")
+
1324  return new ProcBuilder(chan);
+
1325  else if(type=="structure")
+
1326  return new IDBuilder(chan);
+
1327  else
+
1328  throw std::runtime_error(std::string("Unknown +type=")+type);
+
1329 }
+
Definition: pvif.h:81
+
Definition: pvif.h:100
+
Definition: sb.h:8
+
Definition: pvif.h:365
+
Definition: pvif.h:61
+ +
virtual unsigned dbe(const epics::pvData::BitSet &mask)=0
Calculate DBE mask from changed bitset.
+
virtual void put(epics::pvData::BitSet &mask, unsigned dbe, db_field_log *pfl)=0
+ +
virtual epics::pvData::Status get(const epics::pvData::BitSet &mask, proc_t proc=ProcInhibit, bool permit=true)=0
Definition: pvif.cpp:1262
+ + +
+ + + + diff --git a/pvif_8h_source.html b/pvif_8h_source.html new file mode 100644 index 0000000..6853d55 --- /dev/null +++ b/pvif_8h_source.html @@ -0,0 +1,536 @@ + + + + + + +pva2pva: pdbApp/pvif.h Source File + + + + + + + + + +
+
+ + + + + + +
+
pva2pva +  1.4.1 +
+
+
+ + + + + + + + + +
+ +
+ + +
+
+
+
pvif.h
+
+
+
1 #ifndef PVIF_H
+
2 #define PVIF_H
+
3 
+
4 #include <map>
+
5 
+
6 #include <asLib.h>
+
7 #include <dbAccess.h>
+
8 #include <dbChannel.h>
+
9 #include <dbStaticLib.h>
+
10 #include <dbLock.h>
+
11 #include <dbEvent.h>
+
12 #include <epicsVersion.h>
+
13 
+
14 #include <pv/status.h>
+
15 #include <pv/bitSet.h>
+
16 #include <pv/pvData.h>
+
17 #include <pv/anyscalar.h>
+
18 
+
19 #include <pv/qsrv.h>
+
20 
+
21 #ifndef VERSION_INT
+
22 # define VERSION_INT(V,R,M,P) ( ((V)<<24) | ((R)<<16) | ((M)<<8) | (P))
+
23 #endif
+
24 
+
25 #ifndef EPICS_VERSION_INT
+
26 # define EPICS_VERSION_INT VERSION_INT(EPICS_VERSION, EPICS_REVISION, EPICS_MODIFICATION, EPICS_PATCH_LEVEL)
+
27 #endif
+
28 
+
29 #if EPICS_VERSION_INT>=VERSION_INT(3,16,0,2)
+
30 # define USE_MULTILOCK
+
31 #endif
+
32 
+
33 #ifndef DBRutag
+
34 # define DBR_AMSG 0
+
35 # define DBR_UTAG 0
+
36 # define DBRamsg
+
37 # define DBRutag
+
38 #else
+
39 # define HAVE_UTAG
+
40 #endif
+
41 
+
42 namespace epics {
+
43 namespace pvAccess {
+
44 class ChannelRequester;
+
45 }
+
46 }
+
47 
+
48 short PVD2DBR(epics::pvData::ScalarType pvt);
+
49 
+
50 // copy from PVField (.value sub-field) to DBF buffer
+
51 QSRV_API
+
52 long copyPVD2DBF(const epics::pvData::PVField::const_shared_pointer& in,
+
53  void *outbuf, short outdbf, long *outnReq);
+
54 // copy from DBF buffer to PVField (.value sub-field)
+
55 QSRV_API
+
56 long copyDBF2PVD(const epics::pvData::shared_vector<const void>& buf,
+
57  const epics::pvData::PVField::shared_pointer& out,
+
58  epics::pvData::BitSet &changed,
+
59  const epics::pvData::PVStringArray::const_svector& choices);
+
60 
+
61 union dbrbuf {
+
62  epicsInt8 dbf_CHAR;
+
63  epicsUInt8 dbf_UCHAR;
+
64  epicsInt16 dbf_SHORT;
+
65  epicsUInt16 dbf_USHORT;
+
66  epicsEnum16 dbf_ENUM;
+
67  epicsInt32 dbf_LONG;
+
68  epicsUInt32 dbf_ULONG;
+
69  epicsFloat32 dbf_FLOAT;
+
70  epicsFloat64 dbf_DOUBLE;
+
71 
+
72 #ifdef EPICS_VERSION_INT
+
73 # if EPICS_VERSION_INT>=VERSION_INT(3,16,1,0)
+
74  epicsInt64 dbf_INT64;
+
75  epicsUInt64 dbf_UINT64;
+
76 # endif
+
77 #endif
+
78  char dbf_STRING[MAX_STRING_SIZE];
+
79 };
+
80 
+
81 struct QSRV_API DBCH {
+
82  dbChannel *chan;
+
83  DBCH() :chan(0) {}
+
84  explicit DBCH(dbChannel *ch); // calls dbChannelOpen()
+
85  explicit DBCH(const std::string& name);
+
86  ~DBCH();
+
87 
+
88  void swap(DBCH&);
+
89 
+
90  operator dbChannel*() { return chan; }
+
91  operator const dbChannel*() const { return chan; }
+
92  dbChannel *operator->() { return chan; }
+
93  const dbChannel *operator->() const { return chan; }
+
94 private:
+
95  DBCH(const DBCH&);
+
96  DBCH& operator=(const DBCH&);
+
97  void prepare();
+
98 };
+
99 
+
100 struct ASCred {
+
101  // string storage must be safely mutable. cf. asAddClient()
+
102  std::vector<char> user, host;
+
103  std::vector<std::vector<char> > groups;
+
104  void update(const std::tr1::shared_ptr<epics::pvAccess::ChannelRequester>& request);
+
105 };
+
106 
+
107 struct ASCLIENT {
+
108  ASCLIENTPVT aspvt;
+
109  std::vector<ASCLIENTPVT> grppvt;
+
110  ASCLIENT() :aspvt(0) {}
+
111  ~ASCLIENT();
+
112  // ASCred storage must remain valid
+
113  void add(dbChannel* chan, ASCred& cred);
+
114  bool canWrite();
+
115 };
+
116 
+ +
118  DBENTRY ent;
+
119  pdbRecordInfo(const char *name)
+
120  {
+
121  dbInitEntry(pdbbase, &ent);
+
122  if(dbFindRecordPart(&ent, &name))
+
123  throw std::runtime_error(ent.message);
+
124  }
+
125  ~pdbRecordInfo()
+
126  {
+
127  dbFinishEntry(&ent);
+
128  }
+
129  const char *info(const char *key, const char *def =0)
+
130  {
+
131  if(dbFindInfo(&ent, key))
+
132  return def;
+
133  return dbGetInfoString(&ent);
+
134  }
+
135 };
+
136 
+ +
138  DBENTRY ent;
+
139  bool m_done;
+ +
141  {
+
142  dbInitEntry(pdbbase, &ent);
+
143  m_done = dbFirstRecordType(&ent)!=0;
+
144  while(!m_done) {
+
145  if(dbFirstRecord(&ent)==0)
+
146  break;
+
147  // not instances of this type
+
148  m_done = dbNextRecordType(&ent)!=0;
+
149  }
+
150  }
+
151  pdbRecordIterator(const dbChannel *chan)
+
152  {
+
153 #if EPICS_VERSION_INT>=VERSION_INT(3,16,1,0)
+
154  dbInitEntryFromRecord(dbChannelRecord(chan), &ent);
+
155 #else
+
156  dbInitEntry(pdbbase, &ent);
+
157  if(dbFindRecord(&ent, dbChannelRecord(chan)->name)!=0)
+
158  throw std::logic_error("Record not found");
+
159 #endif
+
160  m_done = false;
+
161  }
+
162 #if EPICS_VERSION_INT>=VERSION_INT(3,16,1,0)
+
163  pdbRecordIterator(dbCommon *prec)
+
164  {
+
165  dbInitEntryFromRecord(prec, &ent);
+
166  m_done = false;
+
167  }
+
168 #endif
+ +
170  {
+
171  dbFinishEntry(&ent);
+
172  }
+
173  bool done() const { return m_done; }
+
174  bool next() {
+
175  if(!m_done && dbNextRecord(&ent)!=0)
+
176  {
+
177  // done with this recordType
+
178  while(true) {
+
179  m_done = dbNextRecordType(&ent)!=0;
+
180  if(m_done) break;
+
181  if(dbFirstRecord(&ent)==0)
+
182  break;
+
183  // not instances of this type
+
184  }
+
185  }
+
186  return m_done;
+
187  }
+
188  dbCommon* record() const {
+
189  return m_done ? NULL : (dbCommon*)ent.precnode->precord;
+
190  }
+
191  const char *name() const {
+
192  return m_done ? NULL : ent.precnode->recordname;
+
193  }
+
194  const char *info(const char *key, const char *def =0)
+
195  {
+
196  if(m_done || dbFindInfo(&ent, key))
+
197  return def;
+
198  return dbGetInfoString(&ent);
+
199  }
+
200 };
+
201 
+ +
203  DBENTRY ent;
+
204  bool m_done;
+ +
206  {
+
207  dbCopyEntryContents(&const_cast<pdbRecordIterator&>(I).ent, &ent);
+
208  m_done = dbFirstInfo(&ent)!=0;
+
209  }
+
210  ~pdbInfoIterator()
+
211  {
+
212  dbFinishEntry(&ent);
+
213  }
+
214  bool done() const { return m_done; }
+
215  bool next() {
+
216  m_done = dbNextInfo(&ent)!=0;
+
217  return m_done;
+
218  }
+
219  const char *name() { return dbGetInfoName(&ent); }
+
220  const char *value() { return dbGetInfoString(&ent); }
+
221 };
+
222 
+
223 struct DBEvent
+
224 {
+
225  dbEventSubscription subscript;
+
226  unsigned dbe_mask;
+
227  void *self;
+
228  unsigned index;
+
229  dbChannel *chan;
+
230  DBEvent() :subscript(NULL), self(NULL), index(0) {}
+
231  DBEvent(void* s) :subscript(NULL), self(s), index(0) {}
+
232  ~DBEvent() {destroy();}
+
233  void create(dbEventCtx ctx, dbChannel *ch, EVENTFUNC *fn, unsigned mask)
+
234  {
+
235  subscript = db_add_event(ctx, ch, fn, this, mask);
+
236  if(!subscript)
+
237  throw std::runtime_error("Failed to subscribe to dbEvent");
+
238  chan = ch;
+
239  dbe_mask = mask;
+
240  }
+
241  void destroy() {
+
242  if(subscript) db_cancel_event(subscript);
+
243  }
+
244  bool operator!() const { return !subscript; }
+
245 private:
+
246  DBEvent(const DBEvent&);
+
247  DBEvent& operator=(const DBEvent&);
+
248 };
+
249 
+
250 struct LocalFL
+
251 {
+
252  db_field_log *pfl;
+
253  bool ours;
+
254  LocalFL(db_field_log *pfl, dbChannel *pchan)
+
255  :pfl(pfl)
+
256  ,ours(false)
+
257  {
+
258  if(!pfl && (ellCount(&pchan->pre_chain)!=0 || ellCount(&pchan->post_chain)!=0)) {
+
259  pfl = db_create_read_log(pchan);
+
260  if(pfl) {
+
261  ours = true;
+
262  pfl = dbChannelRunPreChain(pchan, pfl);
+
263  if(pfl) pfl = dbChannelRunPostChain(pchan, pfl);
+
264  }
+
265  }
+
266  this->pfl = pfl;
+
267  }
+
268  ~LocalFL() {
+
269  if(ours) db_delete_field_log(pfl);
+
270  }
+
271 };
+
272 
+ +
274 {
+
275  dbCommon *prec;
+
276  DBScanLocker(dbChannel *chan) :prec(dbChannelRecord(chan))
+
277  { dbScanLock(prec); }
+
278  DBScanLocker(dbCommon *prec) :prec(prec)
+
279  { dbScanLock(prec); }
+
280  ~DBScanLocker()
+
281  { dbScanUnlock(prec); }
+
282 };
+
283 
+
284 #ifdef USE_MULTILOCK
+
285 
+
286 struct DBManyLock
+
287 {
+
288  dbLocker *plock;
+
289  DBManyLock() :plock(NULL) {}
+
290  DBManyLock(const std::vector<dbCommon*>& recs, unsigned flags=0)
+
291  :plock(dbLockerAlloc( (recs.size() > 0 ? (dbCommon**)&recs[0] : NULL), recs.size(), flags))
+
292  {
+
293  if(!plock) throw std::invalid_argument("Failed to create locker");
+
294  }
+
295  DBManyLock(dbCommon * const *precs, size_t nrecs, unsigned flags=0)
+
296  :plock(dbLockerAlloc((dbCommon**)precs, nrecs, flags))
+
297  {
+
298  if(!plock) throw std::invalid_argument("Failed to create locker");
+
299  }
+
300  ~DBManyLock() { if(plock) dbLockerFree(plock); }
+
301  void swap(DBManyLock& O) { std::swap(plock, O.plock); }
+
302  operator dbLocker*() { return plock; }
+
303 private:
+
304  DBManyLock(const DBManyLock&);
+
305  DBManyLock& operator=(const DBManyLock&);
+
306 };
+
307 
+
308 struct DBManyLocker
+
309 {
+
310  dbLocker *plock;
+
311  DBManyLocker(dbLocker *L) :plock(L)
+
312  {
+
313  dbScanLockMany(plock);
+
314  }
+
315  ~DBManyLocker()
+
316  {
+
317  dbScanUnlockMany(plock);
+
318  }
+
319 };
+
320 #endif
+
321 
+
322 struct QSRV_API FieldName
+
323 {
+
324  struct Component {
+
325  std::string name;
+
326  epicsUInt32 index;
+
327  Component() :index((epicsUInt32)-1) {}
+
328  Component(const std::string& name, epicsUInt32 index = (epicsUInt32)-1)
+
329  :name(name), index(index)
+
330  {}
+
331  bool isArray() const { return index!=(epicsUInt32)-1; }
+
332  };
+
333  typedef std::vector<Component> parts_t;
+
334  parts_t parts;
+
335 
+
336  FieldName() {}
+
337  explicit FieldName(const std::string&);
+
338 
+
339  void swap(FieldName& o) {
+
340  parts.swap(o.parts);
+
341  }
+
342 
+
343  bool empty() const { return parts.empty(); }
+
344  size_t size() const { return parts.size(); }
+
345  const Component& operator[](size_t i) const { return parts[i]; }
+
346  const Component& back() const { return parts.back(); }
+
347 
+
348  // Apply field name(s) to given structure
+
349  // if ppenclose!=NULL then the address of the enclosing field (eg. structureArray)
+
350  // whose fieldOffset shoulbe by used, or NULL if no enclosing
+
351  epics::pvData::PVFieldPtr
+
352  lookup(const epics::pvData::PVStructurePtr& S, epics::pvData::PVField** ppenclose) const;
+
353 
+
354  void show() const;
+
355 
+
356 #if !defined(__GNUC__) || (__GNUC__ * 100 + __GNUC_MINOR__ >= 403)
+
357 // Workaround needed for older GCC
+
358 private:
+
359 #endif
+
360  // Prevent default copy/assignment op's
+
361  FieldName(const FieldName&);
+
362  FieldName& operator=(const FieldName&);
+
363 };
+
364 
+
365 struct QSRV_API PVIF {
+
366  PVIF(dbChannel *ch);
+
367  virtual ~PVIF() {}
+
368 
+
369  dbChannel * const chan; // borrowed reference from PVIFBuilder
+
370 
+
371  enum proc_t {
+
372  ProcPassive,
+
373  ProcInhibit,
+
374  ProcForce,
+
375  };
+
376 
+
379  virtual void put(epics::pvData::BitSet& mask, unsigned dbe, db_field_log *pfl) =0;
+
382  virtual epics::pvData::Status get(const epics::pvData::BitSet& mask, proc_t proc=ProcInhibit, bool permit=true) =0;
+
384  virtual unsigned dbe(const epics::pvData::BitSet& mask) =0;
+
385 
+
386 private:
+
387  PVIF(const PVIF&);
+
388  PVIF& operator=(const PVIF&);
+
389 };
+
390 
+
403 struct QSRV_API PVIFBuilder
+
404 {
+
405  dbChannel* const channel;
+
406 
+
407  virtual ~PVIFBuilder() {}
+
408 
+
409  // fetch the structure description
+
410  virtual epics::pvData::FieldConstPtr dtype() =0;
+
411 
+
412  virtual epics::pvData::FieldBuilderPtr dtype(epics::pvData::FieldBuilderPtr& builder,
+
413  const std::string& fld);
+
414 
+
415  // Attach to a structure instance.
+
416  // must be of the type returned by dtype().
+
417  // must be the root structure
+
418  virtual PVIF* attach(const epics::pvData::PVStructurePtr& root, const FieldName& fld) =0;
+
419 
+
420  // entry point for Builder
+
421  static PVIFBuilder* create(const std::string& mapname, dbChannel* chan);
+
422 protected:
+
423  explicit PVIFBuilder(dbChannel* chan) : channel(chan) {}
+
424 private:
+
425  PVIFBuilder(const PVIFBuilder&);
+
426  PVIFBuilder& operator=(const PVIFBuilder&);
+
427 };
+
428 
+
429 struct QSRV_API ScalarBuilder : public PVIFBuilder
+
430 {
+
431  explicit ScalarBuilder(dbChannel* chan) :PVIFBuilder(chan) {}
+
432  virtual ~ScalarBuilder() {}
+
433 
+
434  virtual epics::pvData::FieldConstPtr dtype() OVERRIDE FINAL;
+
435  virtual PVIF* attach(const epics::pvData::PVStructurePtr& root, const FieldName& fld) OVERRIDE FINAL;
+
436 };
+
437 
+
438 
+
439 #endif // PVIF_H
+ +
Definition: pvif.h:107
+
Definition: pvif.h:81
+
Definition: pvif.h:100
+
Definition: pvif.h:365
+
Definition: pvif.h:61
+ + +
Definition: pvif.h:223
+ + +
Definition: pvif.h:250
+ + + +
+ + + + diff --git a/qsrv_8cpp_source.html b/qsrv_8cpp_source.html new file mode 100644 index 0000000..3c04b87 --- /dev/null +++ b/qsrv_8cpp_source.html @@ -0,0 +1,249 @@ + + + + + + +pva2pva: pdbApp/qsrv.cpp Source File + + + + + + + + + +
+
+ + + + + + +
+
pva2pva +  1.4.1 +
+
+
+ + + + + + + + + +
+ +
+ + +
+
+
+
qsrv.cpp
+
+
+
1 
+
2 #include <initHooks.h>
+
3 #include <epicsExit.h>
+
4 #include <epicsThread.h>
+
5 #include <epicsString.h>
+
6 #include <epicsStdio.h>
+
7 
+
8 #include <dbAccess.h>
+
9 #include <dbChannel.h>
+
10 #include <dbStaticLib.h>
+
11 #include <dbLock.h>
+
12 #include <dbEvent.h>
+
13 #include <epicsVersion.h>
+
14 #include <dbNotify.h>
+
15 
+
16 #include <pv/reftrack.h>
+
17 #include <pv/pvAccess.h>
+
18 #include <pv/serverContext.h>
+
19 #include <pv/iocshelper.h>
+
20 
+
21 #include "pv/qsrv.h"
+
22 #include "pvahelper.h"
+
23 #include "pvif.h"
+
24 #include "pdb.h"
+
25 #include "pdbsingle.h"
+
26 #ifdef USE_MULTILOCK
+
27 # include "pdbgroup.h"
+
28 #endif
+
29 
+
30 #include <epicsExport.h>
+
31 
+
32 namespace pva = epics::pvAccess;
+
33 
+
34 void QSRVRegistrar_counters()
+
35 {
+
36  epics::registerRefCounter("PDBSinglePV", &PDBSinglePV::num_instances);
+
37  epics::registerRefCounter("PDBSingleChannel", &PDBSingleChannel::num_instances);
+
38  epics::registerRefCounter("PDBSinglePut", &PDBSinglePut::num_instances);
+
39  epics::registerRefCounter("PDBSingleMonitor", &PDBSingleMonitor::num_instances);
+
40 #ifdef USE_MULTILOCK
+
41  epics::registerRefCounter("PDBGroupPV", &PDBGroupPV::num_instances);
+
42  epics::registerRefCounter("PDBGroupChannel", &PDBGroupChannel::num_instances);
+
43  epics::registerRefCounter("PDBGroupPut", &PDBGroupPut::num_instances);
+
44  epics::registerRefCounter("PDBGroupMonitor", &PDBGroupMonitor::num_instances);
+
45 #endif // USE_MULTILOCK
+
46  epics::registerRefCounter("PDBProvider", &PDBProvider::num_instances);
+
47 }
+
48 
+
49 long dbLoadGroup(const char* fname)
+
50 {
+
51  try {
+
52  if(!fname) {
+
53  printf("dbLoadGroup(\"file.json\")\n"
+
54  "\n"
+
55  "Load additional DB group definitions from file.\n");
+
56  return 1;
+
57  }
+
58 #ifndef USE_MULTILOCK
+
59  static bool warned;
+
60  if(!warned) {
+
61  warned = true;
+
62  fprintf(stderr, "ignoring %s\n", fname);
+
63  }
+
64 #endif
+
65 
+
66  if(fname[0]=='-') {
+
67  fname++;
+
68  if(fname[0]=='*' && fname[1]=='\0') {
+
69  PDBProvider::group_files.clear();
+
70  } else {
+
71  PDBProvider::group_files.remove(fname);
+
72  }
+
73  } else {
+
74  PDBProvider::group_files.remove(fname);
+
75  PDBProvider::group_files.push_back(fname);
+
76  }
+
77 
+
78  return 0;
+
79  }catch(std::exception& e){
+
80  fprintf(stderr, "Error: %s\n", e.what());
+
81  return 1;
+
82  }
+
83 }
+
84 
+
85 namespace {
+
86 
+
87 void dbLoadGroupWrap(const char* fname)
+
88 {
+
89  (void)dbLoadGroup(fname);
+
90 }
+
91 
+
92 void dbgl(int lvl, const char *pattern)
+
93 {
+
94  if(!pattern)
+
95  pattern = "";
+
96 
+
97  try {
+
98  PDBProvider::shared_pointer prov(
+
99  std::tr1::dynamic_pointer_cast<PDBProvider>(
+
100  pva::ChannelProviderRegistry::servers()->getProvider("QSRV")));
+
101  if(!prov)
+
102  throw std::runtime_error("No Provider (PVA server not running?)");
+
103 
+
104  PDBProvider::persist_pv_map_t pvs;
+
105  {
+
106  epicsGuard<epicsMutex> G(prov->transient_pv_map.mutex());
+
107  pvs = prov->persist_pv_map; // copy map
+
108  }
+
109 
+
110  for(PDBProvider::persist_pv_map_t::const_iterator it(pvs.begin()), end(pvs.end());
+
111  it != end; ++it)
+
112  {
+
113  if(pattern[0] && epicsStrGlobMatch(it->first.c_str(), pattern)==0)
+
114  continue;
+
115 
+
116  printf("%s\n", it->first.c_str());
+
117  if(lvl<=0)
+
118  continue;
+
119  it->second->show(lvl);
+
120  }
+
121 
+
122  }catch(std::exception& e){
+
123  fprintf(stderr, "Error: %s\n", e.what());
+
124  }
+
125 }
+
126 
+
127 void QSRVRegistrar()
+
128 {
+
129  QSRVRegistrar_counters();
+
130  pva::ChannelProviderRegistry::servers()->addSingleton<PDBProvider>("QSRV");
+
131  epics::iocshRegister<int, const char*, &dbgl>("dbgl", "level", "pattern");
+
132  epics::iocshRegister<const char*, &dbLoadGroupWrap>("dbLoadGroup", "jsonfile");
+
133 }
+
134 
+
135 } // namespace
+
136 
+
137 unsigned qsrvVersion(void)
+
138 {
+
139  return QSRV_VERSION_INT;
+
140 }
+
141 
+
142 unsigned qsrvABIVersion(void)
+
143 {
+
144  return QSRV_ABI_VERSION_INT;
+
145 }
+
146 
+
147 extern "C" {
+
148  epicsExportRegistrar(QSRVRegistrar);
+
149 }
+ +
+ + + + diff --git a/qsrv_page.html b/qsrv_page.html new file mode 100644 index 0000000..cd359dd --- /dev/null +++ b/qsrv_page.html @@ -0,0 +1,316 @@ + + + + + + +pva2pva: QSRV + + + + + + + + + +
+
+ + + + + + +
+
pva2pva +  1.4.1 +
+
+
+ + + + + + + + +
+ +
+ +
+
+
+
QSRV
+
+
+

+QSRV Configuration

+

By default QSRV exposes all Process Variables (fields of process database records). In addition to these "single" PVs are special "group" PVs.

+

+Single PVs

+

"single" PVs are the same set of names server by the Channel Access server (RSRV). This is all accessible record fields. So all data which is accessible via Channel Access is also accessible via PVAccess.

+

QSRV presents all "single" PVs as Structures conforming to the Normative Types NTScalar, NTScalarArray, or NTEnum depending on the native DBF field type.

+

+Group PV definitions

+

A group is defined using a JSON syntax. Groups are defined with respect to a Group Name, which is also the PV name. So unlike records, the "field" of a group have a different meaning. Group field names are not part of the PV name.

+

A group definition may be split among several records, or included in separate JSON file(s).

+

For example of a group including two records is:

+
record(ai, "rec:X") {
+
info(Q:group, {
+
"grp:name": {
+
"X": {+channel:"VAL"}
+
}
+
})
+
}
+
record(ai, "rec:Y") {
+
info(Q:group, {
+
"grp:name": {
+
"Y": {+channel:"VAL"}
+
}
+
})
+
}
+

Or equivalently with separate .db file and .json files.

+
# some .db
+
record(ai, "rec:X") {}
+
record(ai, "rec:Y") {}
+
{
+
"grp:name": {
+
"X": {+channel:"VAL"},
+
"Y": {+channel:"VAL"}
+
}
+
}
+

This group, named "grp:name", has two fields "X" and "Y".

+
$ pvget grp:name
+
grp:name
+
structure
+
epics:nt/NTScalar:1.0 X
+
double value 0
+
alarm_t alarm INVALID DRIVER UDF
+
time_t timeStamp <undefined> 0
+
...
+
epics:nt/NTScalar:1.0 Y
+
double value 0
+
alarm_t alarm INVALID DRIVER UDF
+
time_t timeStamp <undefined> 0
+
...
+

+Group PV reference

+
record(...) {
+
info(Q:group, {
+
"<group_name>":{
+
+id:"some/NT:1.0", # top level ID
+
+atomic:true, # whether monitors default to multi-locking atomicity
+
"<field.name>":{
+
+type:"scalar", # controls how map VAL mapped onto <field.name>
+
+channel:"VAL",
+
+id:"some/NT:1.0",
+
+trigger:"*", # "*" or comma seperated list of <field.name>s
+
+putorder:0, # set for fields where put is allowed, processing done in increasing order
+
},
+
"": {+type:"meta", +channel:"VAL"} # special case adds meta-data fields at top level
+
}
+
})
+
}
+

+Field mapping types

+
    +
  • "scalar" or ""
  • +
  • "plain"
  • +
  • "any"
  • +
  • "meta"
  • +
  • "proc"
  • +
  • "structure"
  • +
+

The "scalar" mapping places an NTScalar or NTScalarArray as a sub-structure.

+

The "plain" mapping ignores all meta-data and places only the "value" as a field. The "value" is equivalent to '.value' of the equivalent NTScalar/NTScalarArray as a field.

+

The "any" mapping places a variant union into which the "value" is placed.

+

The "meta" mapping ignores the "value" and places only the alarm and time meta-data as sub-fields. Placing an entry in a blank field name '"": {+type:"meta"}' allows these meta-data fields to be placed in the top-level structure.

+

The "proc" mapping uses neither "value" nor meta-data. Instead the target record is processed during a put.

+

The "structure" mapping allows an "+id" to be attached without a "+channel". So none of "+channel", "+trigger", nor "+putorder" are meaningful for a "structure" mapping.

+

+Field Update Triggers

+

The field triggers define how changes to the consitutent field are translated into a subscription update to the group.

+

The most use of these are "" which means that changes to the field are ignored, and do not result group update. And "*" which results in a group update containing the most recent values/meta-data of all fields.

+

It may be useful to specify a comma seperated list of field names so that changes may partially update the group.

+

+QSRV Timestamp Options

+

QSRV has the ability to perform certain transformations on the timestamp before transporting it. The mechanism for configuring this is the "Q:time:tag" info() tag.

+

+Nano-seconds least significant bits

+

Setting "Q:time:tag" to a value of "nsec:lsb:#", where # is a number between 0 and 32, will split the nanoseconds value stored in the associated record. The least significant # bits are stored in the 'timeStamp.userTag' field. While the remaining 32-# bits are stored in 'timeStamp.nanoseconds' (without shifting).

+

For example, in the following situation 20 bits are split off into userTag. If the nanoseconds part of the record timestamp is 0x12345678, then the PVD structure would include "timeStamp.nanoseconds=0x12300000" and "timeStamp.userTag=0x45678".

+
record(ai, "...") {
+
info(Q:time:tag, "nsec:lsb:20")
+
}
+

+QSRV Display Form Option

+

The value of the OPI display form hint ('display.form') can be set set with the "Q:form" info() tag. This hint, along with 'display.precision', is used by some OPI clients to control how values are rendered.

+

The text value of the tag must be one of the following choices.

+
    +
  • Default
  • +
  • String
  • +
  • Binary
  • +
  • Decimal
  • +
  • Hex
  • +
  • Exponential
  • +
  • Engineering
  • +
+
record(ai, "...") {
+
info(Q:form, "Default") # implied default
+
}
+

+Access Security

+

QSRV will enforce an optional access control policy file (.acf) loaded by the usual means (cf. asSetFilename() ). This policy is applied to both Single and Group PVs. With Group PVs, restrictions are not defined for the group, but rather for the individual member records. The same policy will be applied regardess of how a record is accessed (individually, or through a group).

+

Policy application differs from CA (RSRV) in several ways:

+

Client hostname is always the numeric IP address. HAG() entries must either contained numeric IP addresses, or that asCheckClientIP=1 flag must be set to translate hostnames into IPs on ACF file load (effects CA server as well). This prevents clients from trivially forging "hostname". In additional to client usernames. UAG definitions may contained items beginning with "role/" which are matched against the list of groups of which the client username is a member. Username to group lookup is done internally to QSRV, and depends on IOC host authentication configuration. Note that this is still based on the client provided username string.

+
UAG(special) {
+
someone, "role/op"
+
}
+

The "special" UAG will match CA or PVA clients with the username "someone". It will also match a PVA client if the client provided username is a member of the "op" group (supported on POSIX targets and Windows).

+

+PVAccess Links

+

When built against Base >= 3.16.1, support is enabled for PVAccess links, which are analogous to Channel Access (CA) links. However, the syntax for PVA links is quite different.

+
Note
The "dbjlr" and "dbpvar" IOC shell command provide information about PVA links in a running IOC.
+

A simple configuration using defaults is

+
record(longin, "tgt") {}
+
record(longin, "src") {
+
field(INP, {pva:"tgt"})
+
}
+

This is a shorthand for

+
record(longin, "tgt") {}
+
record(longin, "src") {
+
field(INP, {pva:{pv:"tgt"}})
+
}
+

Some additional keys (beyond "pv") may be used. Defaults are shown below:

+
record(longin, "tgt") {}
+
record(longin, "src") {
+
field(INP, {pva:{
+
pv:"tgt",
+
field:"", # may be a sub-field
+
local:false,# Require local PV
+
Q:4, # monitor queue depth
+
pipeline:false, # require that server uses monitor flow control protocol
+
proc:none, # Request record processing (side-effects).
+
sevr:false, # Maximize severity.
+
time:false, # set record time during getValue
+
monorder:0, # Order of record processing as a result of CP and CPP
+
retry:false,# allow Put while disconnected.
+
always:false,# CP/CPP input link process even when .value field hasn't changed
+
defer:false # Defer put
+
}})
+
}
+

+pv: Target PV name

+

The PV name to search for. This is the same name which could be used with 'pvget' or other client tools.

+

+field: Structure field name

+

The name of a sub-field of the remotely provided Structure. By default, an empty string "" uses the top-level Structure.

+

If the top level structure, or a sub-structure is selected, then it is expeccted to conform to NTScalar, NTScalarArray, or NTEnum to extract value and meta-data.

+

If the sub-field is an PVScalar or PVScalarArray, then a value will be taken from it, but not meta-data will be available.

+
Todo:
Ability to traverse through unions and into structure arrays (as with group mappings).
+

+local: Require local PV

+

When true, link will not connect unless the named PV is provided by the local (QSRV) data provider.

+

+Q: Monitor queue depth

+

Requests a certain monitor queue depth. The server may, or may not, take this into consideration when selecting a queue depth.

+

+pipeline: Monitor flow control

+

Expect that the server supports PVA monitor flow control. If not, then the subscription will stall (ick.)

+

+proc: Request record processing (side-effects)

+

The meaning of this option depends on the direction of the link.

+

For output links, this option allows a request for remote processing (side-effects).

+
    +
  • none (default) - Make no special request. Uses a server specific default.
  • +
  • false, "NPP" - Request to skip processing.
  • +
  • true, "PP" - Request to force processing.
  • +
  • "CP", "CPP" - For output links, an alias for "PP".
  • +
+

For input links, this option controls whether the record containing the PVA link will be processed when subscription events are received.

+
    +
  • none (default), false, "NPP" - Do not process on subscription updates.
  • +
  • true, "CP" - Always process on subscription updates.
  • +
  • "PP", "CPP" - Process on subscription updates if SCAN=Passive
  • +
+

+sevr: Alarm propagation

+

This option controls whether reading a value from an input PVA link has the addition effect of propagating any alarm via the Maximize Severity process.

+
    +
  • false - Do not maximize severity.
  • +
  • true - Maximize alarm severity
  • +
  • "MSI" - Maximize only if the remote severity is INVALID.
  • +
+

+time: Time propagation

+

Somewhat analogous to sevr: applied to timestamp. When true, the record TIME field is updated when the link value is read.

+
Warning
TSEL must be set to -2 for time:true to have an effect.
+

+monorder: Monitor processing order

+

When multiple record target the same target PV, and request processing on subscription updates. This option allows the order of processing to be specified.

+

Record are processed in increasing order. monorder=-1 is processed before monorder=0. Both are processed before monorder=1.

+

+defer: Defer put

+

By default (defer=false) an output link will immediately start a PVA Put operation. defer=true will store the new value in an internal cache, but not start a PVA Put.

+

This option, in combination with field: allows a single Put to contain updates to multiple sub-fields.

+

+retry: Put while disconnected

+

Allow a Put operation to be queued while the link is disconnected. The Put will be executed when the link becomes connected.

+

+always: CP/CPP always process

+

By default (always:false) a subscription update will only cause a CP input link to scan if the structure field (cf. field: option) is marked as changed. Set to true to override this, and always process the link.

+

+Link semantics/behavior

+

This section attempts to answer some questions about how links behave in certain situations.

+

Links are evaluated in three basic contexts.

+
    +
  • dbPutLink()/dbScanFwdLink()
  • +
  • dbGetLink() of non-CP link
  • +
  • dbGetLink() during a scan resulting from a CP link.
  • +
+

An input link can bring in a Value as well as meta-data, alarm, time, and display/control info. For input links, the PVA link engine attempts to always maintain consistency between Value, alarm, and time. However, consistency between these, and the display/control info is only ensured during a CP scan.

+
+ + + + diff --git a/qsrvpage_8h_source.html b/qsrvpage_8h_source.html new file mode 100644 index 0000000..99eb692 --- /dev/null +++ b/qsrvpage_8h_source.html @@ -0,0 +1,100 @@ + + + + + + +pva2pva: documentation/qsrvpage.h Source File + + + + + + + + + +
+
+ + + + + + +
+
pva2pva +  0 +
+
+
+ + + + + + + + + +
+ +
+ + +
+
+
+
qsrvpage.h
+
+
+
1 
+
+ + + + diff --git a/release_notes.html b/release_notes.html new file mode 100644 index 0000000..0ca1277 --- /dev/null +++ b/release_notes.html @@ -0,0 +1,210 @@ + + + + + + +pva2pva: Release Notes + + + + + + + + + +
+
+ + + + + + +
+
pva2pva +  1.4.1 +
+
+
+ + + + + + + + +
+ +
+ +
+
+
+
Release Notes
+
+
+

Release 1.4.1 (December 2023)

+
    +
  • Bug Fixes
      +
    • dbLoadGroup was fixed
    • +
    +
  • +
  • Additions
      +
    • Support for "meta" member at top of array of structs
    • +
    +
  • +
+

Release 1.4.0 (September 2022)

+
    +
  • Bug Fixes
      +
    • apply ACF when writing to atomic group
    • +
    +
  • +
  • Additions +
  • +
  • Changes
      +
    • Add Access Security hooks for single and group writes.
    • +
    • Enable "Async Soft Channel" for output links
    • +
    • When built against Base 7.0.6.1, set timeStamp.userTag from UTAG field.
    • +
    • Add DTYP="QSRV Set UTag" for longin, which sets UTAG=VAL.
    • +
    +
  • +
+

Release 1.3.1 (June 2021)

+
    +
  • Bug Fixes
      +
    • Correct handling for server side filters.
    • +
    +
  • +
  • Changes +
  • +
+

Release 1.3.0 (Feb 2021)

+
    +
  • Changes
      +
    • Add dbLoadGroup() iocsh function to read group JSON definitions from a file. Mappings in files must refer to full record names instead of fields. eg. 'recname.VAL' instead of 'VAL'.
    • +
    +
  • +
+

Release 1.2.4 (July 2020)

+
    +
  • Bug Fixes
      +
    • Fix stalled monitor when server side filter drops initial DBE_PROPERTY update.
    • +
    • Respect DISP
    • +
    +
  • +
  • Changes
      +
    • Refreshed softIocPVA to match options in Base.
    • +
    +
  • +
+

Release 1.2.3 (May 2020)

+ +

Release 1.2.2 (Nov 2019)

+
    +
  • Changes
      +
    • Enforce Access Security policy.
    • +
    • NTEnum .value field add missing "enum_t" type ID string.
    • +
    +
  • +
+

Release 1.2.1 (July 2019)

+
    +
  • Fixes
      +
    • Fix unittest: testpvalink. No functional change.
    • +
    +
  • +
+

Release 1.2.0 (Mar 2019)

+
    +
  • Incompatible changes +
  • +
  • Additions +
  • +
  • Fixes
      +
    • Correct handling of 64-bit integer fields.
    • +
    • Install a copy of softIocExit.db for standalone builds
    • +
    +
  • +
+

Release 1.1.0 (Nov 2018)

+
    +
  • Incompatible changes
      +
    • Requires pvDataCPP >= 7.1.0
    • +
    • Requires pvAccessCPP >= 6.1.0
    • +
    +
  • +
  • Removals
      +
    • Drop the broken ioccircle and ioccircle2 examples.
    • +
    +
  • +
  • Fixes
      +
    • Fix QSRV monitor locking causing crash
    • +
    • Fix Windows DLL import/export errors
    • +
    • Correctly handle empty "scalar" case of NELM=1, NORD=0.
    • +
    +
  • +
  • Additions
      +
    • QSRV implement channelList() (aka. 'pvlist') with list of record and group names.
    • +
    • PVAccess Links type (requires Base >= 3.16.1)
    • +
    +
  • +
+

Release 1.0.0 (Dec 2017)

+

Initial Release

+
+ + + + diff --git a/sb_8h_source.html b/sb_8h_source.html new file mode 100644 index 0000000..cccda42 --- /dev/null +++ b/sb_8h_source.html @@ -0,0 +1,116 @@ + + + + + + +pva2pva: common/sb.h Source File + + + + + + + + + +
+
+ + + + + + +
+
pva2pva +  1.4.1 +
+
+
+ + + + + + + + + +
+ +
+ + +
+
+
+
sb.h
+
+
+
1 #ifndef SB_H
+
2 #define SB_H
+
3 
+
4 #include <sstream>
+
5 
+
6 // in-line string builder (eg. for exception messages)
+
7 // throw std::runtime_error(SB()<<"Answer: !"<<42);
+
8 struct SB {
+
9  std::ostringstream strm;
+
10  SB() {}
+
11  operator std::string() const { return strm.str(); }
+
12  template<typename T>
+
13  SB& operator<<(T i) { strm<<i; return *this; }
+
14 };
+
15 
+
16 #endif // SB_H
+
Definition: sb.h:8
+
+ + + + diff --git a/search/all_61.html b/search/all_61.html new file mode 100644 index 0000000..b8328c6 --- /dev/null +++ b/search/all_61.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/search/all_61.js b/search/all_61.js new file mode 100644 index 0000000..2ddecf2 --- /dev/null +++ b/search/all_61.js @@ -0,0 +1,7 @@ +var searchData= +[ + ['afterput',['AfterPut',['../structpvalink_1_1pva_link_channel_1_1_after_put.html',1,'pvalink::pvaLinkChannel']]], + ['asclient',['ASCLIENT',['../struct_a_s_c_l_i_e_n_t.html',1,'']]], + ['ascred',['ASCred',['../struct_a_s_cred.html',1,'']]], + ['aswritepvt',['AsWritePvt',['../class_as_write_pvt.html',1,'']]] +]; diff --git a/search/all_62.html b/search/all_62.html new file mode 100644 index 0000000..281723e --- /dev/null +++ b/search/all_62.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/search/all_62.js b/search/all_62.js new file mode 100644 index 0000000..5390521 --- /dev/null +++ b/search/all_62.js @@ -0,0 +1,6 @@ +var searchData= +[ + ['basechannel',['BaseChannel',['../struct_base_channel.html',1,'']]], + ['basechannelproviderfactory',['BaseChannelProviderFactory',['../struct_base_channel_provider_factory.html',1,'']]], + ['basemonitor',['BaseMonitor',['../struct_base_monitor.html',1,'']]] +]; diff --git a/search/all_63.html b/search/all_63.html new file mode 100644 index 0000000..a8fe36d --- /dev/null +++ b/search/all_63.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/search/all_63.js b/search/all_63.js new file mode 100644 index 0000000..8b7d72a --- /dev/null +++ b/search/all_63.js @@ -0,0 +1,11 @@ +var searchData= +[ + ['cacheclean',['cacheClean',['../struct_channel_cache_1_1cache_clean.html',1,'ChannelCache']]], + ['channelcache',['ChannelCache',['../struct_channel_cache.html',1,'']]], + ['channelcacheentry',['ChannelCacheEntry',['../struct_channel_cache_entry.html',1,'']]], + ['channelname',['channelName',['../structpvalink_1_1pva_link_config.html#a87b194f54983a2d55f617cb6178368e2',1,'pvalink::pvaLinkConfig']]], + ['clear',['clear',['../classweak__value__map.html#ade67193285ef79b15cb6303b7326ca69',1,'weak_value_map::clear()'],['../classweak__set.html#ad2f334e307156c71951739779f82f05b',1,'weak_set::clear()']]], + ['component',['Component',['../struct_field_name_1_1_component.html',1,'FieldName']]], + ['connect',['connect',['../struct_base_monitor.html#ada8d7a8b60703ff92bea53153975da3c',1,'BaseMonitor']]], + ['crequester',['CRequester',['../struct_channel_cache_entry_1_1_c_requester.html',1,'ChannelCacheEntry']]] +]; diff --git a/search/all_64.html b/search/all_64.html new file mode 100644 index 0000000..b415c0e --- /dev/null +++ b/search/all_64.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/search/all_64.js b/search/all_64.js new file mode 100644 index 0000000..8dd8a44 --- /dev/null +++ b/search/all_64.js @@ -0,0 +1,8 @@ +var searchData= +[ + ['dbch',['DBCH',['../struct_d_b_c_h.html',1,'']]], + ['dbe',['dbe',['../struct_p_v_i_f.html#a88688f71c8732aa31befd7f17f5d5dff',1,'PVIF']]], + ['dbevent',['DBEvent',['../struct_d_b_event.html',1,'']]], + ['dbrbuf',['dbrbuf',['../uniondbrbuf.html',1,'']]], + ['dbscanlocker',['DBScanLocker',['../struct_d_b_scan_locker.html',1,'']]] +]; diff --git a/search/all_65.html b/search/all_65.html new file mode 100644 index 0000000..49e2cae --- /dev/null +++ b/search/all_65.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/search/all_65.js b/search/all_65.js new file mode 100644 index 0000000..573a1af --- /dev/null +++ b/search/all_65.js @@ -0,0 +1,6 @@ +var searchData= +[ + ['element_5fproxy',['element_proxy',['../classweak__value__map_1_1element__proxy.html',1,'weak_value_map']]], + ['empty',['empty',['../classweak__value__map.html#afa70a96eef949d4846c2f5e0a55c55d3',1,'weak_value_map::empty()'],['../classweak__set.html#a85208d398474d848e5e0c01e40237963',1,'weak_set::empty()']]], + ['erase',['erase',['../classweak__set.html#acc4699fb90930ee403f96f95aacbd113',1,'weak_set']]] +]; diff --git a/search/all_66.html b/search/all_66.html new file mode 100644 index 0000000..6aa068f --- /dev/null +++ b/search/all_66.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/search/all_66.js b/search/all_66.js new file mode 100644 index 0000000..05feef0 --- /dev/null +++ b/search/all_66.js @@ -0,0 +1,6 @@ +var searchData= +[ + ['field',['Field',['../struct_group_config_1_1_field.html',1,'GroupConfig']]], + ['fieldname',['FieldName',['../struct_field_name.html',1,'FieldName'],['../structpvalink_1_1pva_link_config.html#a747c31e4118c1ce1f10bb5301a66d281',1,'pvalink::pvaLinkConfig::fieldName()']]], + ['find',['find',['../classweak__value__map.html#a36d469f7d550860fbb60c6f73178d015',1,'weak_value_map']]] +]; diff --git a/search/all_67.html b/search/all_67.html new file mode 100644 index 0000000..a6568a3 --- /dev/null +++ b/search/all_67.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/search/all_67.js b/search/all_67.js new file mode 100644 index 0000000..ea97ecc --- /dev/null +++ b/search/all_67.js @@ -0,0 +1,8 @@ +var searchData= +[ + ['get',['get',['../struct_p_v_i_f.html#af77de9930438edc2dcf677ecc2449367',1,'PVIF']]], + ['group',['Group',['../struct_group_config_1_1_group.html',1,'GroupConfig']]], + ['groupconfig',['GroupConfig',['../struct_group_config.html',1,'']]], + ['gwchannel',['GWChannel',['../struct_g_w_channel.html',1,'']]], + ['gwserverchannelprovider',['GWServerChannelProvider',['../struct_g_w_server_channel_provider.html',1,'']]] +]; diff --git a/search/all_69.html b/search/all_69.html new file mode 100644 index 0000000..676651e --- /dev/null +++ b/search/all_69.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/search/all_69.js b/search/all_69.js new file mode 100644 index 0000000..db545f4 --- /dev/null +++ b/search/all_69.js @@ -0,0 +1,5 @@ +var searchData= +[ + ['info',['Info',['../struct_p_d_b_group_p_v_1_1_info.html',1,'PDBGroupPV']]], + ['insert',['insert',['../classweak__value__map.html#a461d05342f43e08f12725f41045407aa',1,'weak_value_map::insert()'],['../classweak__set.html#ab841af866b907702f804be850f3b40ba',1,'weak_set::insert()']]] +]; diff --git a/search/all_6a.html b/search/all_6a.html new file mode 100644 index 0000000..12ef2ec --- /dev/null +++ b/search/all_6a.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/search/all_6a.js b/search/all_6a.js new file mode 100644 index 0000000..6472dbb --- /dev/null +++ b/search/all_6a.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['jlif',['jlif',['../structjlif.html',1,'']]] +]; diff --git a/search/all_6c.html b/search/all_6c.html new file mode 100644 index 0000000..3623130 --- /dev/null +++ b/search/all_6c.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/search/all_6c.js b/search/all_6c.js new file mode 100644 index 0000000..f5624a9 --- /dev/null +++ b/search/all_6c.js @@ -0,0 +1,9 @@ +var searchData= +[ + ['lastelem',['lastelem',['../struct_monitor_cache_entry.html#ac32c2f4b0e388af0295f80e460f9c72e',1,'MonitorCacheEntry']]], + ['linksort',['LinkSort',['../structpvalink_1_1pva_link_channel_1_1_link_sort.html',1,'pvalink::pvaLinkChannel']]], + ['localfl',['LocalFL',['../struct_local_f_l.html',1,'']]], + ['lock_5fmap',['lock_map',['../classweak__value__map.html#ae2c29b1ad0568c24b4eb26a230cd8332',1,'weak_value_map']]], + ['lock_5fset',['lock_set',['../classweak__set.html#a733d68c57853458884c05a5deb1c2b3e',1,'weak_set']]], + ['lock_5fvector',['lock_vector',['../classweak__value__map.html#a0987b450867e9e43262504a81a9a2dd4',1,'weak_value_map::lock_vector()'],['../classweak__set.html#a4738c02e5bcd758679e669a4be6a7eb1',1,'weak_set::lock_vector()']]] +]; diff --git a/search/all_6d.html b/search/all_6d.html new file mode 100644 index 0000000..82ceec7 --- /dev/null +++ b/search/all_6d.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/search/all_6d.js b/search/all_6d.js new file mode 100644 index 0000000..8a59ad2 --- /dev/null +++ b/search/all_6d.js @@ -0,0 +1,6 @@ +var searchData= +[ + ['monitorcacheentry',['MonitorCacheEntry',['../struct_monitor_cache_entry.html',1,'']]], + ['monitoruser',['MonitorUser',['../struct_monitor_user.html',1,'']]], + ['mutex',['mutex',['../classweak__value__map.html#aad008499708cb7743e5ac7c1c15877e6',1,'weak_value_map::mutex()'],['../classweak__set.html#a0dd6280b6281db730f643ec9a3a9d51d',1,'weak_set::mutex()']]] +]; diff --git a/search/all_6e.html b/search/all_6e.html new file mode 100644 index 0000000..92a12bb --- /dev/null +++ b/search/all_6e.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/search/all_6e.js b/search/all_6e.js new file mode 100644 index 0000000..b61d050 --- /dev/null +++ b/search/all_6e.js @@ -0,0 +1,5 @@ +var searchData= +[ + ['next',['next',['../structweak__set_1_1_x_iterator.html#a5d0b1327596691e00b05a8c79a90faa0',1,'weak_set::XIterator']]], + ['no_5foverflow',['no_overflow',['../struct_base_monitor_1_1no__overflow.html',1,'BaseMonitor']]] +]; diff --git a/search/all_6f.html b/search/all_6f.html new file mode 100644 index 0000000..51c8b11 --- /dev/null +++ b/search/all_6f.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/search/all_6f.js b/search/all_6f.js new file mode 100644 index 0000000..5189619 --- /dev/null +++ b/search/all_6f.js @@ -0,0 +1,7 @@ +var searchData= +[ + ['operator_20value_5fpointer',['operator value_pointer',['../classweak__value__map_1_1element__proxy.html#a1b4cebcb96ce7a699077bb857b03f4bb',1,'weak_value_map::element_proxy']]], + ['operator_2a',['operator*',['../classweak__value__map_1_1element__proxy.html#ad027b985867564c2928f3137f8f58776',1,'weak_value_map::element_proxy']]], + ['operator_2d_3e',['operator->',['../classweak__value__map_1_1element__proxy.html#ae625d2a3b7892dc67cfbee0a47b63650',1,'weak_value_map::element_proxy']]], + ['operator_3d',['operator=',['../classweak__value__map_1_1element__proxy.html#ab534aca5e5498b566aec46b7c364abb4',1,'weak_value_map::element_proxy']]] +]; diff --git a/search/all_70.html b/search/all_70.html new file mode 100644 index 0000000..a279cb2 --- /dev/null +++ b/search/all_70.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/search/all_70.js b/search/all_70.js new file mode 100644 index 0000000..5de2495 --- /dev/null +++ b/search/all_70.js @@ -0,0 +1,25 @@ +var searchData= +[ + ['pva2pva_20home_20of_20qsrv_20and_20pvaccess_202_20pvaccess_20gateway',['pva2pva Home of QSRV and pvAccess 2 pvAccess gateway',['../index.html',1,'']]], + ['pdbgroupchannel',['PDBGroupChannel',['../struct_p_d_b_group_channel.html',1,'']]], + ['pdbgroupmonitor',['PDBGroupMonitor',['../struct_p_d_b_group_monitor.html',1,'']]], + ['pdbgroupput',['PDBGroupPut',['../struct_p_d_b_group_put.html',1,'']]], + ['pdbgrouppv',['PDBGroupPV',['../struct_p_d_b_group_p_v.html',1,'']]], + ['pdbinfoiterator',['pdbInfoIterator',['../structpdb_info_iterator.html',1,'']]], + ['pdbprovider',['PDBProvider',['../struct_p_d_b_provider.html',1,'']]], + ['pdbpv',['PDBPV',['../struct_p_d_b_p_v.html',1,'']]], + ['pdbrecordinfo',['pdbRecordInfo',['../structpdb_record_info.html',1,'']]], + ['pdbrecorditerator',['pdbRecordIterator',['../structpdb_record_iterator.html',1,'']]], + ['pdbsinglechannel',['PDBSingleChannel',['../struct_p_d_b_single_channel.html',1,'']]], + ['pdbsinglemonitor',['PDBSingleMonitor',['../struct_p_d_b_single_monitor.html',1,'']]], + ['pdbsingleput',['PDBSinglePut',['../struct_p_d_b_single_put.html',1,'']]], + ['pdbsinglepv',['PDBSinglePV',['../struct_p_d_b_single_p_v.html',1,'']]], + ['post',['post',['../struct_base_monitor.html#a6bae642fe4f1981a7fc0e92477f963c0',1,'BaseMonitor::post(guard_t &guard, const epics::pvData::BitSet &updated, no_overflow)'],['../struct_base_monitor.html#ae4c204a580cbb7f7febce7b632de6636',1,'BaseMonitor::post(guard_t &guard)'],['../struct_base_monitor.html#a0fdc1067e909a8be074e6f6d79d36ad7',1,'BaseMonitor::post(guard_t &guard, const epics::pvData::BitSet &updated, const epics::pvData::BitSet &overflowed)'],['../struct_base_monitor.html#af4c2dfbb286a9d52e9ae920ac9b8ebc6',1,'BaseMonitor::post(guard_t &guard, const epics::pvData::BitSet &updated)']]], + ['put',['put',['../struct_p_v_i_f.html#a85b75751dfef8bacfda925da28c6f357',1,'PVIF']]], + ['pvaglobal_5ft',['pvaGlobal_t',['../structpvalink_1_1pva_global__t.html',1,'pvalink']]], + ['pvalink',['pvaLink',['../structpvalink_1_1pva_link.html',1,'pvalink']]], + ['pvalinkchannel',['pvaLinkChannel',['../structpvalink_1_1pva_link_channel.html',1,'pvalink']]], + ['pvalinkconfig',['pvaLinkConfig',['../structpvalink_1_1pva_link_config.html',1,'pvalink']]], + ['pvif',['PVIF',['../struct_p_v_i_f.html',1,'']]], + ['pvifbuilder',['PVIFBuilder',['../struct_p_v_i_f_builder.html',1,'']]] +]; diff --git a/search/all_71.html b/search/all_71.html new file mode 100644 index 0000000..ee4ba24 --- /dev/null +++ b/search/all_71.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/search/all_71.js b/search/all_71.js new file mode 100644 index 0000000..0de28dc --- /dev/null +++ b/search/all_71.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['qsrv',['QSRV',['../qsrv_page.html',1,'']]] +]; diff --git a/search/all_72.html b/search/all_72.html new file mode 100644 index 0000000..315ac4f --- /dev/null +++ b/search/all_72.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/search/all_72.js b/search/all_72.js new file mode 100644 index 0000000..11c94a3 --- /dev/null +++ b/search/all_72.js @@ -0,0 +1,5 @@ +var searchData= +[ + ['release_20notes',['Release Notes',['../release_notes.html',1,'']]], + ['requestupdate',['requestUpdate',['../struct_p_d_b_group_monitor.html#a2234c632ad420916a7006923bb4a4c37',1,'PDBGroupMonitor::requestUpdate()'],['../struct_p_d_b_single_monitor.html#ae7a3df03fd5580c3c44425fcc44d2d66',1,'PDBSingleMonitor::requestUpdate()'],['../struct_base_monitor.html#a4e88164d25cff25ecb5b59c419002db1',1,'BaseMonitor::requestUpdate()']]] +]; diff --git a/search/all_73.html b/search/all_73.html new file mode 100644 index 0000000..09f8ce8 --- /dev/null +++ b/search/all_73.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/search/all_73.js b/search/all_73.js new file mode 100644 index 0000000..2ef98ae --- /dev/null +++ b/search/all_73.js @@ -0,0 +1,9 @@ +var searchData= +[ + ['sb',['SB',['../struct_s_b.html',1,'']]], + ['scalaraccessor',['ScalarAccessor',['../struct_scalar_accessor.html',1,'']]], + ['scalarbuilder',['ScalarBuilder',['../struct_scalar_builder.html',1,'']]], + ['serverconfig',['ServerConfig',['../struct_server_config.html',1,'']]], + ['size',['size',['../classweak__value__map.html#ac75448a45ea808754f865306603b0d67',1,'weak_value_map::size()'],['../classweak__set.html#a7200042241c652af5f3c315e0185d3fc',1,'weak_set::size()']]], + ['swap',['swap',['../classweak__value__map.html#a345b6fd964bbd24019462159e77e3769',1,'weak_value_map::swap()'],['../classweak__set.html#a4e686399a7ef165641aa5de49288a899',1,'weak_set::swap()']]] +]; diff --git a/search/all_74.html b/search/all_74.html new file mode 100644 index 0000000..c2cd095 --- /dev/null +++ b/search/all_74.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/search/all_74.js b/search/all_74.js new file mode 100644 index 0000000..5192dd0 --- /dev/null +++ b/search/all_74.js @@ -0,0 +1,14 @@ +var searchData= +[ + ['testchannelfieldrequester',['TestChannelFieldRequester',['../struct_test_channel_field_requester.html',1,'']]], + ['testchannelgetrequester',['TestChannelGetRequester',['../struct_test_channel_get_requester.html',1,'']]], + ['testchannelmonitorrequester',['TestChannelMonitorRequester',['../struct_test_channel_monitor_requester.html',1,'']]], + ['testchannelputrequester',['TestChannelPutRequester',['../struct_test_channel_put_requester.html',1,'']]], + ['testchannelrequester',['TestChannelRequester',['../struct_test_channel_requester.html',1,'']]], + ['testioc',['TestIOC',['../struct_test_i_o_c.html',1,'']]], + ['testprovider',['TestProvider',['../struct_test_provider.html',1,'']]], + ['testpv',['TestPV',['../struct_test_p_v.html',1,'']]], + ['testpvchannel',['TestPVChannel',['../struct_test_p_v_channel.html',1,'']]], + ['testpvmonitor',['TestPVMonitor',['../struct_test_p_v_monitor.html',1,'']]], + ['todo_20list',['Todo List',['../todo.html',1,'']]] +]; diff --git a/search/all_76.html b/search/all_76.html new file mode 100644 index 0000000..5643d68 --- /dev/null +++ b/search/all_76.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/search/all_76.js b/search/all_76.js new file mode 100644 index 0000000..b5ca06f --- /dev/null +++ b/search/all_76.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['value',['Value',['../structpvalink_1_1pva_link_1_1_value.html',1,'pvalink::pvaLink']]] +]; diff --git a/search/all_77.html b/search/all_77.html new file mode 100644 index 0000000..d01abb9 --- /dev/null +++ b/search/all_77.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/search/all_77.js b/search/all_77.js new file mode 100644 index 0000000..da7906f --- /dev/null +++ b/search/all_77.js @@ -0,0 +1,13 @@ +var searchData= +[ + ['weak_5fset',['weak_set',['../classweak__set.html',1,'weak_set< T >'],['../classweak__set.html#a36f38a6bd628016c6fd2e107ded76147',1,'weak_set::weak_set()']]], + ['weak_5fset_3c_20gwchannel_20_3e',['weak_set< GWChannel >',['../classweak__set.html',1,'']]], + ['weak_5fset_3c_20monitoruser_20_3e',['weak_set< MonitorUser >',['../classweak__set.html',1,'']]], + ['weak_5fset_3c_20testpvchannel_20_3e',['weak_set< TestPVChannel >',['../classweak__set.html',1,'']]], + ['weak_5fset_3c_20testpvmonitor_20_3e',['weak_set< TestPVMonitor >',['../classweak__set.html',1,'']]], + ['weak_5fvalue_5fmap',['weak_value_map',['../classweak__value__map.html',1,'weak_value_map< K, V, C >'],['../classweak__value__map.html#a8e175241057abbd795098554c51e2e55',1,'weak_value_map::weak_value_map()']]], + ['weak_5fvalue_5fmap_3c_20pvrequest_5ft_2c_20monitorcacheentry_20_3e',['weak_value_map< pvrequest_t, MonitorCacheEntry >',['../classweak__value__map.html',1,'']]], + ['weak_5fvalue_5fmap_3c_20std_3a_3astring_2c_20pdbpv_20_3e',['weak_value_map< std::string, PDBPV >',['../classweak__value__map.html',1,'']]], + ['weak_5fvalue_5fmap_3c_20std_3a_3astring_2c_20testpv_20_3e',['weak_value_map< std::string, TestPV >',['../classweak__value__map.html',1,'']]], + ['workqueue',['WorkQueue',['../struct_work_queue.html',1,'']]] +]; diff --git a/search/all_78.html b/search/all_78.html new file mode 100644 index 0000000..d1f9d7a --- /dev/null +++ b/search/all_78.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/search/all_78.js b/search/all_78.js new file mode 100644 index 0000000..0d74a97 --- /dev/null +++ b/search/all_78.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['xiterator',['XIterator',['../structweak__set_1_1_x_iterator.html',1,'weak_set']]] +]; diff --git a/search/classes_61.html b/search/classes_61.html new file mode 100644 index 0000000..80ea25b --- /dev/null +++ b/search/classes_61.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/search/classes_61.js b/search/classes_61.js new file mode 100644 index 0000000..2ddecf2 --- /dev/null +++ b/search/classes_61.js @@ -0,0 +1,7 @@ +var searchData= +[ + ['afterput',['AfterPut',['../structpvalink_1_1pva_link_channel_1_1_after_put.html',1,'pvalink::pvaLinkChannel']]], + ['asclient',['ASCLIENT',['../struct_a_s_c_l_i_e_n_t.html',1,'']]], + ['ascred',['ASCred',['../struct_a_s_cred.html',1,'']]], + ['aswritepvt',['AsWritePvt',['../class_as_write_pvt.html',1,'']]] +]; diff --git a/search/classes_62.html b/search/classes_62.html new file mode 100644 index 0000000..d850f52 --- /dev/null +++ b/search/classes_62.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/search/classes_62.js b/search/classes_62.js new file mode 100644 index 0000000..5390521 --- /dev/null +++ b/search/classes_62.js @@ -0,0 +1,6 @@ +var searchData= +[ + ['basechannel',['BaseChannel',['../struct_base_channel.html',1,'']]], + ['basechannelproviderfactory',['BaseChannelProviderFactory',['../struct_base_channel_provider_factory.html',1,'']]], + ['basemonitor',['BaseMonitor',['../struct_base_monitor.html',1,'']]] +]; diff --git a/search/classes_63.html b/search/classes_63.html new file mode 100644 index 0000000..0dccad2 --- /dev/null +++ b/search/classes_63.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/search/classes_63.js b/search/classes_63.js new file mode 100644 index 0000000..0001d01 --- /dev/null +++ b/search/classes_63.js @@ -0,0 +1,8 @@ +var searchData= +[ + ['cacheclean',['cacheClean',['../struct_channel_cache_1_1cache_clean.html',1,'ChannelCache']]], + ['channelcache',['ChannelCache',['../struct_channel_cache.html',1,'']]], + ['channelcacheentry',['ChannelCacheEntry',['../struct_channel_cache_entry.html',1,'']]], + ['component',['Component',['../struct_field_name_1_1_component.html',1,'FieldName']]], + ['crequester',['CRequester',['../struct_channel_cache_entry_1_1_c_requester.html',1,'ChannelCacheEntry']]] +]; diff --git a/search/classes_64.html b/search/classes_64.html new file mode 100644 index 0000000..31fc70b --- /dev/null +++ b/search/classes_64.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/search/classes_64.js b/search/classes_64.js new file mode 100644 index 0000000..353218a --- /dev/null +++ b/search/classes_64.js @@ -0,0 +1,7 @@ +var searchData= +[ + ['dbch',['DBCH',['../struct_d_b_c_h.html',1,'']]], + ['dbevent',['DBEvent',['../struct_d_b_event.html',1,'']]], + ['dbrbuf',['dbrbuf',['../uniondbrbuf.html',1,'']]], + ['dbscanlocker',['DBScanLocker',['../struct_d_b_scan_locker.html',1,'']]] +]; diff --git a/search/classes_65.html b/search/classes_65.html new file mode 100644 index 0000000..1f0d2ff --- /dev/null +++ b/search/classes_65.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/search/classes_65.js b/search/classes_65.js new file mode 100644 index 0000000..8bf5fbe --- /dev/null +++ b/search/classes_65.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['element_5fproxy',['element_proxy',['../classweak__value__map_1_1element__proxy.html',1,'weak_value_map']]] +]; diff --git a/search/classes_66.html b/search/classes_66.html new file mode 100644 index 0000000..61dded0 --- /dev/null +++ b/search/classes_66.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/search/classes_66.js b/search/classes_66.js new file mode 100644 index 0000000..7bba8f7 --- /dev/null +++ b/search/classes_66.js @@ -0,0 +1,5 @@ +var searchData= +[ + ['field',['Field',['../struct_group_config_1_1_field.html',1,'GroupConfig']]], + ['fieldname',['FieldName',['../struct_field_name.html',1,'']]] +]; diff --git a/search/classes_67.html b/search/classes_67.html new file mode 100644 index 0000000..ea38f24 --- /dev/null +++ b/search/classes_67.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/search/classes_67.js b/search/classes_67.js new file mode 100644 index 0000000..056b24a --- /dev/null +++ b/search/classes_67.js @@ -0,0 +1,7 @@ +var searchData= +[ + ['group',['Group',['../struct_group_config_1_1_group.html',1,'GroupConfig']]], + ['groupconfig',['GroupConfig',['../struct_group_config.html',1,'']]], + ['gwchannel',['GWChannel',['../struct_g_w_channel.html',1,'']]], + ['gwserverchannelprovider',['GWServerChannelProvider',['../struct_g_w_server_channel_provider.html',1,'']]] +]; diff --git a/search/classes_69.html b/search/classes_69.html new file mode 100644 index 0000000..7437847 --- /dev/null +++ b/search/classes_69.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/search/classes_69.js b/search/classes_69.js new file mode 100644 index 0000000..a20eaf4 --- /dev/null +++ b/search/classes_69.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['info',['Info',['../struct_p_d_b_group_p_v_1_1_info.html',1,'PDBGroupPV']]] +]; diff --git a/search/classes_6a.html b/search/classes_6a.html new file mode 100644 index 0000000..adba8b1 --- /dev/null +++ b/search/classes_6a.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/search/classes_6a.js b/search/classes_6a.js new file mode 100644 index 0000000..6472dbb --- /dev/null +++ b/search/classes_6a.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['jlif',['jlif',['../structjlif.html',1,'']]] +]; diff --git a/search/classes_6c.html b/search/classes_6c.html new file mode 100644 index 0000000..18594ee --- /dev/null +++ b/search/classes_6c.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/search/classes_6c.js b/search/classes_6c.js new file mode 100644 index 0000000..79f255c --- /dev/null +++ b/search/classes_6c.js @@ -0,0 +1,5 @@ +var searchData= +[ + ['linksort',['LinkSort',['../structpvalink_1_1pva_link_channel_1_1_link_sort.html',1,'pvalink::pvaLinkChannel']]], + ['localfl',['LocalFL',['../struct_local_f_l.html',1,'']]] +]; diff --git a/search/classes_6d.html b/search/classes_6d.html new file mode 100644 index 0000000..aa83590 --- /dev/null +++ b/search/classes_6d.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/search/classes_6d.js b/search/classes_6d.js new file mode 100644 index 0000000..c1de695 --- /dev/null +++ b/search/classes_6d.js @@ -0,0 +1,5 @@ +var searchData= +[ + ['monitorcacheentry',['MonitorCacheEntry',['../struct_monitor_cache_entry.html',1,'']]], + ['monitoruser',['MonitorUser',['../struct_monitor_user.html',1,'']]] +]; diff --git a/search/classes_6e.html b/search/classes_6e.html new file mode 100644 index 0000000..1f4391e --- /dev/null +++ b/search/classes_6e.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/search/classes_6e.js b/search/classes_6e.js new file mode 100644 index 0000000..9942426 --- /dev/null +++ b/search/classes_6e.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['no_5foverflow',['no_overflow',['../struct_base_monitor_1_1no__overflow.html',1,'BaseMonitor']]] +]; diff --git a/search/classes_70.html b/search/classes_70.html new file mode 100644 index 0000000..be46ae3 --- /dev/null +++ b/search/classes_70.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/search/classes_70.js b/search/classes_70.js new file mode 100644 index 0000000..e35e02a --- /dev/null +++ b/search/classes_70.js @@ -0,0 +1,22 @@ +var searchData= +[ + ['pdbgroupchannel',['PDBGroupChannel',['../struct_p_d_b_group_channel.html',1,'']]], + ['pdbgroupmonitor',['PDBGroupMonitor',['../struct_p_d_b_group_monitor.html',1,'']]], + ['pdbgroupput',['PDBGroupPut',['../struct_p_d_b_group_put.html',1,'']]], + ['pdbgrouppv',['PDBGroupPV',['../struct_p_d_b_group_p_v.html',1,'']]], + ['pdbinfoiterator',['pdbInfoIterator',['../structpdb_info_iterator.html',1,'']]], + ['pdbprovider',['PDBProvider',['../struct_p_d_b_provider.html',1,'']]], + ['pdbpv',['PDBPV',['../struct_p_d_b_p_v.html',1,'']]], + ['pdbrecordinfo',['pdbRecordInfo',['../structpdb_record_info.html',1,'']]], + ['pdbrecorditerator',['pdbRecordIterator',['../structpdb_record_iterator.html',1,'']]], + ['pdbsinglechannel',['PDBSingleChannel',['../struct_p_d_b_single_channel.html',1,'']]], + ['pdbsinglemonitor',['PDBSingleMonitor',['../struct_p_d_b_single_monitor.html',1,'']]], + ['pdbsingleput',['PDBSinglePut',['../struct_p_d_b_single_put.html',1,'']]], + ['pdbsinglepv',['PDBSinglePV',['../struct_p_d_b_single_p_v.html',1,'']]], + ['pvaglobal_5ft',['pvaGlobal_t',['../structpvalink_1_1pva_global__t.html',1,'pvalink']]], + ['pvalink',['pvaLink',['../structpvalink_1_1pva_link.html',1,'pvalink']]], + ['pvalinkchannel',['pvaLinkChannel',['../structpvalink_1_1pva_link_channel.html',1,'pvalink']]], + ['pvalinkconfig',['pvaLinkConfig',['../structpvalink_1_1pva_link_config.html',1,'pvalink']]], + ['pvif',['PVIF',['../struct_p_v_i_f.html',1,'']]], + ['pvifbuilder',['PVIFBuilder',['../struct_p_v_i_f_builder.html',1,'']]] +]; diff --git a/search/classes_73.html b/search/classes_73.html new file mode 100644 index 0000000..b57bc4d --- /dev/null +++ b/search/classes_73.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/search/classes_73.js b/search/classes_73.js new file mode 100644 index 0000000..3131927 --- /dev/null +++ b/search/classes_73.js @@ -0,0 +1,7 @@ +var searchData= +[ + ['sb',['SB',['../struct_s_b.html',1,'']]], + ['scalaraccessor',['ScalarAccessor',['../struct_scalar_accessor.html',1,'']]], + ['scalarbuilder',['ScalarBuilder',['../struct_scalar_builder.html',1,'']]], + ['serverconfig',['ServerConfig',['../struct_server_config.html',1,'']]] +]; diff --git a/search/classes_74.html b/search/classes_74.html new file mode 100644 index 0000000..ed66151 --- /dev/null +++ b/search/classes_74.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/search/classes_74.js b/search/classes_74.js new file mode 100644 index 0000000..b7147bc --- /dev/null +++ b/search/classes_74.js @@ -0,0 +1,13 @@ +var searchData= +[ + ['testchannelfieldrequester',['TestChannelFieldRequester',['../struct_test_channel_field_requester.html',1,'']]], + ['testchannelgetrequester',['TestChannelGetRequester',['../struct_test_channel_get_requester.html',1,'']]], + ['testchannelmonitorrequester',['TestChannelMonitorRequester',['../struct_test_channel_monitor_requester.html',1,'']]], + ['testchannelputrequester',['TestChannelPutRequester',['../struct_test_channel_put_requester.html',1,'']]], + ['testchannelrequester',['TestChannelRequester',['../struct_test_channel_requester.html',1,'']]], + ['testioc',['TestIOC',['../struct_test_i_o_c.html',1,'']]], + ['testprovider',['TestProvider',['../struct_test_provider.html',1,'']]], + ['testpv',['TestPV',['../struct_test_p_v.html',1,'']]], + ['testpvchannel',['TestPVChannel',['../struct_test_p_v_channel.html',1,'']]], + ['testpvmonitor',['TestPVMonitor',['../struct_test_p_v_monitor.html',1,'']]] +]; diff --git a/search/classes_76.html b/search/classes_76.html new file mode 100644 index 0000000..a62123a --- /dev/null +++ b/search/classes_76.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/search/classes_76.js b/search/classes_76.js new file mode 100644 index 0000000..b5ca06f --- /dev/null +++ b/search/classes_76.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['value',['Value',['../structpvalink_1_1pva_link_1_1_value.html',1,'pvalink::pvaLink']]] +]; diff --git a/search/classes_77.html b/search/classes_77.html new file mode 100644 index 0000000..6fac2af --- /dev/null +++ b/search/classes_77.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/search/classes_77.js b/search/classes_77.js new file mode 100644 index 0000000..37ad21a --- /dev/null +++ b/search/classes_77.js @@ -0,0 +1,13 @@ +var searchData= +[ + ['weak_5fset',['weak_set',['../classweak__set.html',1,'']]], + ['weak_5fset_3c_20gwchannel_20_3e',['weak_set< GWChannel >',['../classweak__set.html',1,'']]], + ['weak_5fset_3c_20monitoruser_20_3e',['weak_set< MonitorUser >',['../classweak__set.html',1,'']]], + ['weak_5fset_3c_20testpvchannel_20_3e',['weak_set< TestPVChannel >',['../classweak__set.html',1,'']]], + ['weak_5fset_3c_20testpvmonitor_20_3e',['weak_set< TestPVMonitor >',['../classweak__set.html',1,'']]], + ['weak_5fvalue_5fmap',['weak_value_map',['../classweak__value__map.html',1,'']]], + ['weak_5fvalue_5fmap_3c_20pvrequest_5ft_2c_20monitorcacheentry_20_3e',['weak_value_map< pvrequest_t, MonitorCacheEntry >',['../classweak__value__map.html',1,'']]], + ['weak_5fvalue_5fmap_3c_20std_3a_3astring_2c_20pdbpv_20_3e',['weak_value_map< std::string, PDBPV >',['../classweak__value__map.html',1,'']]], + ['weak_5fvalue_5fmap_3c_20std_3a_3astring_2c_20testpv_20_3e',['weak_value_map< std::string, TestPV >',['../classweak__value__map.html',1,'']]], + ['workqueue',['WorkQueue',['../struct_work_queue.html',1,'']]] +]; diff --git a/search/classes_78.html b/search/classes_78.html new file mode 100644 index 0000000..bef6654 --- /dev/null +++ b/search/classes_78.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/search/classes_78.js b/search/classes_78.js new file mode 100644 index 0000000..0d74a97 --- /dev/null +++ b/search/classes_78.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['xiterator',['XIterator',['../structweak__set_1_1_x_iterator.html',1,'weak_set']]] +]; diff --git a/search/close.png b/search/close.png new file mode 100644 index 0000000..9342d3d Binary files /dev/null and b/search/close.png differ diff --git a/search/functions_63.html b/search/functions_63.html new file mode 100644 index 0000000..98924d8 --- /dev/null +++ b/search/functions_63.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/search/functions_63.js b/search/functions_63.js new file mode 100644 index 0000000..2e86729 --- /dev/null +++ b/search/functions_63.js @@ -0,0 +1,5 @@ +var searchData= +[ + ['clear',['clear',['../classweak__value__map.html#ade67193285ef79b15cb6303b7326ca69',1,'weak_value_map::clear()'],['../classweak__set.html#ad2f334e307156c71951739779f82f05b',1,'weak_set::clear()']]], + ['connect',['connect',['../struct_base_monitor.html#ada8d7a8b60703ff92bea53153975da3c',1,'BaseMonitor']]] +]; diff --git a/search/functions_64.html b/search/functions_64.html new file mode 100644 index 0000000..bcfb550 --- /dev/null +++ b/search/functions_64.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/search/functions_64.js b/search/functions_64.js new file mode 100644 index 0000000..c18c1cd --- /dev/null +++ b/search/functions_64.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['dbe',['dbe',['../struct_p_v_i_f.html#a88688f71c8732aa31befd7f17f5d5dff',1,'PVIF']]] +]; diff --git a/search/functions_65.html b/search/functions_65.html new file mode 100644 index 0000000..f81fa7b --- /dev/null +++ b/search/functions_65.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/search/functions_65.js b/search/functions_65.js new file mode 100644 index 0000000..a786a31 --- /dev/null +++ b/search/functions_65.js @@ -0,0 +1,5 @@ +var searchData= +[ + ['empty',['empty',['../classweak__value__map.html#afa70a96eef949d4846c2f5e0a55c55d3',1,'weak_value_map::empty()'],['../classweak__set.html#a85208d398474d848e5e0c01e40237963',1,'weak_set::empty()']]], + ['erase',['erase',['../classweak__set.html#acc4699fb90930ee403f96f95aacbd113',1,'weak_set']]] +]; diff --git a/search/functions_66.html b/search/functions_66.html new file mode 100644 index 0000000..d0c32b6 --- /dev/null +++ b/search/functions_66.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/search/functions_66.js b/search/functions_66.js new file mode 100644 index 0000000..c1c90b2 --- /dev/null +++ b/search/functions_66.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['find',['find',['../classweak__value__map.html#a36d469f7d550860fbb60c6f73178d015',1,'weak_value_map']]] +]; diff --git a/search/functions_67.html b/search/functions_67.html new file mode 100644 index 0000000..39cc96d --- /dev/null +++ b/search/functions_67.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/search/functions_67.js b/search/functions_67.js new file mode 100644 index 0000000..19db9d8 --- /dev/null +++ b/search/functions_67.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['get',['get',['../struct_p_v_i_f.html#af77de9930438edc2dcf677ecc2449367',1,'PVIF']]] +]; diff --git a/search/functions_69.html b/search/functions_69.html new file mode 100644 index 0000000..954ac84 --- /dev/null +++ b/search/functions_69.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/search/functions_69.js b/search/functions_69.js new file mode 100644 index 0000000..707e563 --- /dev/null +++ b/search/functions_69.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['insert',['insert',['../classweak__value__map.html#a461d05342f43e08f12725f41045407aa',1,'weak_value_map::insert()'],['../classweak__set.html#ab841af866b907702f804be850f3b40ba',1,'weak_set::insert()']]] +]; diff --git a/search/functions_6c.html b/search/functions_6c.html new file mode 100644 index 0000000..903fb01 --- /dev/null +++ b/search/functions_6c.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/search/functions_6c.js b/search/functions_6c.js new file mode 100644 index 0000000..b8f4399 --- /dev/null +++ b/search/functions_6c.js @@ -0,0 +1,6 @@ +var searchData= +[ + ['lock_5fmap',['lock_map',['../classweak__value__map.html#ae2c29b1ad0568c24b4eb26a230cd8332',1,'weak_value_map']]], + ['lock_5fset',['lock_set',['../classweak__set.html#a733d68c57853458884c05a5deb1c2b3e',1,'weak_set']]], + ['lock_5fvector',['lock_vector',['../classweak__value__map.html#a0987b450867e9e43262504a81a9a2dd4',1,'weak_value_map::lock_vector()'],['../classweak__set.html#a4738c02e5bcd758679e669a4be6a7eb1',1,'weak_set::lock_vector()']]] +]; diff --git a/search/functions_6d.html b/search/functions_6d.html new file mode 100644 index 0000000..f721e11 --- /dev/null +++ b/search/functions_6d.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/search/functions_6d.js b/search/functions_6d.js new file mode 100644 index 0000000..df578f6 --- /dev/null +++ b/search/functions_6d.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['mutex',['mutex',['../classweak__value__map.html#aad008499708cb7743e5ac7c1c15877e6',1,'weak_value_map::mutex()'],['../classweak__set.html#a0dd6280b6281db730f643ec9a3a9d51d',1,'weak_set::mutex()']]] +]; diff --git a/search/functions_6e.html b/search/functions_6e.html new file mode 100644 index 0000000..2838a65 --- /dev/null +++ b/search/functions_6e.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/search/functions_6e.js b/search/functions_6e.js new file mode 100644 index 0000000..c541b64 --- /dev/null +++ b/search/functions_6e.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['next',['next',['../structweak__set_1_1_x_iterator.html#a5d0b1327596691e00b05a8c79a90faa0',1,'weak_set::XIterator']]] +]; diff --git a/search/functions_6f.html b/search/functions_6f.html new file mode 100644 index 0000000..f233220 --- /dev/null +++ b/search/functions_6f.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/search/functions_6f.js b/search/functions_6f.js new file mode 100644 index 0000000..5189619 --- /dev/null +++ b/search/functions_6f.js @@ -0,0 +1,7 @@ +var searchData= +[ + ['operator_20value_5fpointer',['operator value_pointer',['../classweak__value__map_1_1element__proxy.html#a1b4cebcb96ce7a699077bb857b03f4bb',1,'weak_value_map::element_proxy']]], + ['operator_2a',['operator*',['../classweak__value__map_1_1element__proxy.html#ad027b985867564c2928f3137f8f58776',1,'weak_value_map::element_proxy']]], + ['operator_2d_3e',['operator->',['../classweak__value__map_1_1element__proxy.html#ae625d2a3b7892dc67cfbee0a47b63650',1,'weak_value_map::element_proxy']]], + ['operator_3d',['operator=',['../classweak__value__map_1_1element__proxy.html#ab534aca5e5498b566aec46b7c364abb4',1,'weak_value_map::element_proxy']]] +]; diff --git a/search/functions_70.html b/search/functions_70.html new file mode 100644 index 0000000..c7cadcf --- /dev/null +++ b/search/functions_70.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/search/functions_70.js b/search/functions_70.js new file mode 100644 index 0000000..d717731 --- /dev/null +++ b/search/functions_70.js @@ -0,0 +1,5 @@ +var searchData= +[ + ['post',['post',['../struct_base_monitor.html#a6bae642fe4f1981a7fc0e92477f963c0',1,'BaseMonitor::post(guard_t &guard, const epics::pvData::BitSet &updated, no_overflow)'],['../struct_base_monitor.html#ae4c204a580cbb7f7febce7b632de6636',1,'BaseMonitor::post(guard_t &guard)'],['../struct_base_monitor.html#a0fdc1067e909a8be074e6f6d79d36ad7',1,'BaseMonitor::post(guard_t &guard, const epics::pvData::BitSet &updated, const epics::pvData::BitSet &overflowed)'],['../struct_base_monitor.html#af4c2dfbb286a9d52e9ae920ac9b8ebc6',1,'BaseMonitor::post(guard_t &guard, const epics::pvData::BitSet &updated)']]], + ['put',['put',['../struct_p_v_i_f.html#a85b75751dfef8bacfda925da28c6f357',1,'PVIF']]] +]; diff --git a/search/functions_72.html b/search/functions_72.html new file mode 100644 index 0000000..de10844 --- /dev/null +++ b/search/functions_72.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/search/functions_72.js b/search/functions_72.js new file mode 100644 index 0000000..50b9d38 --- /dev/null +++ b/search/functions_72.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['requestupdate',['requestUpdate',['../struct_p_d_b_group_monitor.html#a2234c632ad420916a7006923bb4a4c37',1,'PDBGroupMonitor::requestUpdate()'],['../struct_p_d_b_single_monitor.html#ae7a3df03fd5580c3c44425fcc44d2d66',1,'PDBSingleMonitor::requestUpdate()'],['../struct_base_monitor.html#a4e88164d25cff25ecb5b59c419002db1',1,'BaseMonitor::requestUpdate()']]] +]; diff --git a/search/functions_73.html b/search/functions_73.html new file mode 100644 index 0000000..a895245 --- /dev/null +++ b/search/functions_73.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/search/functions_73.js b/search/functions_73.js new file mode 100644 index 0000000..c6328be --- /dev/null +++ b/search/functions_73.js @@ -0,0 +1,5 @@ +var searchData= +[ + ['size',['size',['../classweak__value__map.html#ac75448a45ea808754f865306603b0d67',1,'weak_value_map::size()'],['../classweak__set.html#a7200042241c652af5f3c315e0185d3fc',1,'weak_set::size()']]], + ['swap',['swap',['../classweak__value__map.html#a345b6fd964bbd24019462159e77e3769',1,'weak_value_map::swap()'],['../classweak__set.html#a4e686399a7ef165641aa5de49288a899',1,'weak_set::swap()']]] +]; diff --git a/search/functions_77.html b/search/functions_77.html new file mode 100644 index 0000000..26195f0 --- /dev/null +++ b/search/functions_77.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/search/functions_77.js b/search/functions_77.js new file mode 100644 index 0000000..9bf5899 --- /dev/null +++ b/search/functions_77.js @@ -0,0 +1,5 @@ +var searchData= +[ + ['weak_5fset',['weak_set',['../classweak__set.html#a36f38a6bd628016c6fd2e107ded76147',1,'weak_set']]], + ['weak_5fvalue_5fmap',['weak_value_map',['../classweak__value__map.html#a8e175241057abbd795098554c51e2e55',1,'weak_value_map']]] +]; diff --git a/search/mag_sel.png b/search/mag_sel.png new file mode 100644 index 0000000..81f6040 Binary files /dev/null and b/search/mag_sel.png differ diff --git a/search/nomatches.html b/search/nomatches.html new file mode 100644 index 0000000..b1ded27 --- /dev/null +++ b/search/nomatches.html @@ -0,0 +1,12 @@ + + + + + + + +
+
No Matches
+
+ + diff --git a/search/pages_70.html b/search/pages_70.html new file mode 100644 index 0000000..f02d845 --- /dev/null +++ b/search/pages_70.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/search/pages_70.js b/search/pages_70.js new file mode 100644 index 0000000..af608c9 --- /dev/null +++ b/search/pages_70.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['pva2pva_20home_20of_20qsrv_20and_20pvaccess_202_20pvaccess_20gateway',['pva2pva Home of QSRV and pvAccess 2 pvAccess gateway',['../index.html',1,'']]] +]; diff --git a/search/pages_71.html b/search/pages_71.html new file mode 100644 index 0000000..6c7cda8 --- /dev/null +++ b/search/pages_71.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/search/pages_71.js b/search/pages_71.js new file mode 100644 index 0000000..0de28dc --- /dev/null +++ b/search/pages_71.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['qsrv',['QSRV',['../qsrv_page.html',1,'']]] +]; diff --git a/search/pages_72.html b/search/pages_72.html new file mode 100644 index 0000000..d96429b --- /dev/null +++ b/search/pages_72.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/search/pages_72.js b/search/pages_72.js new file mode 100644 index 0000000..3f24440 --- /dev/null +++ b/search/pages_72.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['release_20notes',['Release Notes',['../release_notes.html',1,'']]] +]; diff --git a/search/pages_74.html b/search/pages_74.html new file mode 100644 index 0000000..377f68e --- /dev/null +++ b/search/pages_74.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/search/pages_74.js b/search/pages_74.js new file mode 100644 index 0000000..441b2de --- /dev/null +++ b/search/pages_74.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['todo_20list',['Todo List',['../todo.html',1,'']]] +]; diff --git a/search/search.css b/search/search.css new file mode 100644 index 0000000..4d7612f --- /dev/null +++ b/search/search.css @@ -0,0 +1,271 @@ +/*---------------- Search Box */ + +#FSearchBox { + float: left; +} + +#MSearchBox { + white-space : nowrap; + position: absolute; + float: none; + display: inline; + margin-top: 8px; + right: 0px; + width: 170px; + z-index: 102; + background-color: white; +} + +#MSearchBox .left +{ + display:block; + position:absolute; + left:10px; + width:20px; + height:19px; + background:url('search_l.png') no-repeat; + background-position:right; +} + +#MSearchSelect { + display:block; + position:absolute; + width:20px; + height:19px; +} + +.left #MSearchSelect { + left:4px; +} + +.right #MSearchSelect { + right:5px; +} + +#MSearchField { + display:block; + position:absolute; + height:19px; + background:url('search_m.png') repeat-x; + border:none; + width:111px; + margin-left:20px; + padding-left:4px; + color: #909090; + outline: none; + font: 9pt Arial, Verdana, sans-serif; +} + +#FSearchBox #MSearchField { + margin-left:15px; +} + +#MSearchBox .right { + display:block; + position:absolute; + right:10px; + top:0px; + width:20px; + height:19px; + background:url('search_r.png') no-repeat; + background-position:left; +} + +#MSearchClose { + display: none; + position: absolute; + top: 4px; + background : none; + border: none; + margin: 0px 4px 0px 0px; + padding: 0px 0px; + outline: none; +} + +.left #MSearchClose { + left: 6px; +} + +.right #MSearchClose { + right: 2px; +} + +.MSearchBoxActive #MSearchField { + color: #000000; +} + +/*---------------- Search filter selection */ + +#MSearchSelectWindow { + display: none; + position: absolute; + left: 0; top: 0; + border: 1px solid #90A5CE; + background-color: #F9FAFC; + z-index: 1; + padding-top: 4px; + padding-bottom: 4px; + -moz-border-radius: 4px; + -webkit-border-top-left-radius: 4px; + -webkit-border-top-right-radius: 4px; + -webkit-border-bottom-left-radius: 4px; + -webkit-border-bottom-right-radius: 4px; + -webkit-box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.15); +} + +.SelectItem { + font: 8pt Arial, Verdana, sans-serif; + padding-left: 2px; + padding-right: 12px; + border: 0px; +} + +span.SelectionMark { + margin-right: 4px; + font-family: monospace; + outline-style: none; + text-decoration: none; +} + +a.SelectItem { + display: block; + outline-style: none; + color: #000000; + text-decoration: none; + padding-left: 6px; + padding-right: 12px; +} + +a.SelectItem:focus, +a.SelectItem:active { + color: #000000; + outline-style: none; + text-decoration: none; +} + +a.SelectItem:hover { + color: #FFFFFF; + background-color: #3D578C; + outline-style: none; + text-decoration: none; + cursor: pointer; + display: block; +} + +/*---------------- Search results window */ + +iframe#MSearchResults { + width: 60ex; + height: 15em; +} + +#MSearchResultsWindow { + display: none; + position: absolute; + left: 0; top: 0; + border: 1px solid #000; + background-color: #EEF1F7; +} + +/* ----------------------------------- */ + + +#SRIndex { + clear:both; + padding-bottom: 15px; +} + +.SREntry { + font-size: 10pt; + padding-left: 1ex; +} + +.SRPage .SREntry { + font-size: 8pt; + padding: 1px 5px; +} + +body.SRPage { + margin: 5px 2px; +} + +.SRChildren { + padding-left: 3ex; padding-bottom: .5em +} + +.SRPage .SRChildren { + display: none; +} + +.SRSymbol { + font-weight: bold; + color: #425E97; + font-family: Arial, Verdana, sans-serif; + text-decoration: none; + outline: none; +} + +a.SRScope { + display: block; + color: #425E97; + font-family: Arial, Verdana, sans-serif; + text-decoration: none; + outline: none; +} + +a.SRSymbol:focus, a.SRSymbol:active, +a.SRScope:focus, a.SRScope:active { + text-decoration: underline; +} + +span.SRScope { + padding-left: 4px; +} + +.SRPage .SRStatus { + padding: 2px 5px; + font-size: 8pt; + font-style: italic; +} + +.SRResult { + display: none; +} + +DIV.searchresults { + margin-left: 10px; + margin-right: 10px; +} + +/*---------------- External search page results */ + +.searchresult { + background-color: #F0F3F8; +} + +.pages b { + color: white; + padding: 5px 5px 3px 5px; + background-image: url("../tab_a.png"); + background-repeat: repeat-x; + text-shadow: 0 1px 1px #000000; +} + +.pages { + line-height: 17px; + margin-left: 4px; + text-decoration: none; +} + +.hl { + font-weight: bold; +} + +#searchresults { + margin-bottom: 20px; +} + +.searchpages { + margin-top: 10px; +} + diff --git a/search/search.js b/search/search.js new file mode 100644 index 0000000..580875b --- /dev/null +++ b/search/search.js @@ -0,0 +1,803 @@ +// Search script generated by doxygen +// Copyright (C) 2009 by Dimitri van Heesch. + +// The code in this file is loosly based on main.js, part of Natural Docs, +// which is Copyright (C) 2003-2008 Greg Valure +// Natural Docs is licensed under the GPL. + +var indexSectionsWithContent = +{ + 0: "0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000111111101101111111110011000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + 1: "0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000111111101101110100110011000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + 2: "0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001111101001111101100010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + 3: "0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001001000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + 4: "0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000111010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" +}; + +var indexSectionNames = +{ + 0: "all", + 1: "classes", + 2: "functions", + 3: "variables", + 4: "pages" +}; + +function convertToId(search) +{ + var result = ''; + for (i=0;i do a search + { + this.Search(); + } + } + + this.OnSearchSelectKey = function(evt) + { + var e = (evt) ? evt : window.event; // for IE + if (e.keyCode==40 && this.searchIndex0) // Up + { + this.searchIndex--; + this.OnSelectItem(this.searchIndex); + } + else if (e.keyCode==13 || e.keyCode==27) + { + this.OnSelectItem(this.searchIndex); + this.CloseSelectionWindow(); + this.DOMSearchField().focus(); + } + return false; + } + + // --------- Actions + + // Closes the results window. + this.CloseResultsWindow = function() + { + this.DOMPopupSearchResultsWindow().style.display = 'none'; + this.DOMSearchClose().style.display = 'none'; + this.Activate(false); + } + + this.CloseSelectionWindow = function() + { + this.DOMSearchSelectWindow().style.display = 'none'; + } + + // Performs a search. + this.Search = function() + { + this.keyTimeout = 0; + + // strip leading whitespace + var searchValue = this.DOMSearchField().value.replace(/^ +/, ""); + + var code = searchValue.toLowerCase().charCodeAt(0); + var hexCode; + if (code<16) + { + hexCode="0"+code.toString(16); + } + else + { + hexCode=code.toString(16); + } + + var resultsPage; + var resultsPageWithSearch; + var hasResultsPage; + + if (indexSectionsWithContent[this.searchIndex].charAt(code) == '1') + { + resultsPage = this.resultsPath + '/' + indexSectionNames[this.searchIndex] + '_' + hexCode + '.html'; + resultsPageWithSearch = resultsPage+'?'+escape(searchValue); + hasResultsPage = true; + } + else // nothing available for this search term + { + resultsPage = this.resultsPath + '/nomatches.html'; + resultsPageWithSearch = resultsPage; + hasResultsPage = false; + } + + window.frames.MSearchResults.location = resultsPageWithSearch; + var domPopupSearchResultsWindow = this.DOMPopupSearchResultsWindow(); + + if (domPopupSearchResultsWindow.style.display!='block') + { + var domSearchBox = this.DOMSearchBox(); + this.DOMSearchClose().style.display = 'inline'; + if (this.insideFrame) + { + var domPopupSearchResults = this.DOMPopupSearchResults(); + domPopupSearchResultsWindow.style.position = 'relative'; + domPopupSearchResultsWindow.style.display = 'block'; + var width = document.body.clientWidth - 8; // the -8 is for IE :-( + domPopupSearchResultsWindow.style.width = width + 'px'; + domPopupSearchResults.style.width = width + 'px'; + } + else + { + var domPopupSearchResults = this.DOMPopupSearchResults(); + var left = getXPos(domSearchBox) + 150; // domSearchBox.offsetWidth; + var top = getYPos(domSearchBox) + 20; // domSearchBox.offsetHeight + 1; + domPopupSearchResultsWindow.style.display = 'block'; + left -= domPopupSearchResults.offsetWidth; + domPopupSearchResultsWindow.style.top = top + 'px'; + domPopupSearchResultsWindow.style.left = left + 'px'; + } + } + + this.lastSearchValue = searchValue; + this.lastResultsPage = resultsPage; + } + + // -------- Activation Functions + + // Activates or deactivates the search panel, resetting things to + // their default values if necessary. + this.Activate = function(isActive) + { + if (isActive || // open it + this.DOMPopupSearchResultsWindow().style.display == 'block' + ) + { + this.DOMSearchBox().className = 'MSearchBoxActive'; + + var searchField = this.DOMSearchField(); + + if (searchField.value == this.searchLabel) // clear "Search" term upon entry + { + searchField.value = ''; + this.searchActive = true; + } + } + else if (!isActive) // directly remove the panel + { + this.DOMSearchBox().className = 'MSearchBoxInactive'; + this.DOMSearchField().value = this.searchLabel; + this.searchActive = false; + this.lastSearchValue = '' + this.lastResultsPage = ''; + } + } +} + +// ----------------------------------------------------------------------- + +// The class that handles everything on the search results page. +function SearchResults(name) +{ + // The number of matches from the last run of . + this.lastMatchCount = 0; + this.lastKey = 0; + this.repeatOn = false; + + // Toggles the visibility of the passed element ID. + this.FindChildElement = function(id) + { + var parentElement = document.getElementById(id); + var element = parentElement.firstChild; + + while (element && element!=parentElement) + { + if (element.nodeName == 'DIV' && element.className == 'SRChildren') + { + return element; + } + + if (element.nodeName == 'DIV' && element.hasChildNodes()) + { + element = element.firstChild; + } + else if (element.nextSibling) + { + element = element.nextSibling; + } + else + { + do + { + element = element.parentNode; + } + while (element && element!=parentElement && !element.nextSibling); + + if (element && element!=parentElement) + { + element = element.nextSibling; + } + } + } + } + + this.Toggle = function(id) + { + var element = this.FindChildElement(id); + if (element) + { + if (element.style.display == 'block') + { + element.style.display = 'none'; + } + else + { + element.style.display = 'block'; + } + } + } + + // Searches for the passed string. If there is no parameter, + // it takes it from the URL query. + // + // Always returns true, since other documents may try to call it + // and that may or may not be possible. + this.Search = function(search) + { + if (!search) // get search word from URL + { + search = window.location.search; + search = search.substring(1); // Remove the leading '?' + search = unescape(search); + } + + search = search.replace(/^ +/, ""); // strip leading spaces + search = search.replace(/ +$/, ""); // strip trailing spaces + search = search.toLowerCase(); + search = convertToId(search); + + var resultRows = document.getElementsByTagName("div"); + var matches = 0; + + var i = 0; + while (i < resultRows.length) + { + var row = resultRows.item(i); + if (row.className == "SRResult") + { + var rowMatchName = row.id.toLowerCase(); + rowMatchName = rowMatchName.replace(/^sr\d*_/, ''); // strip 'sr123_' + + if (search.length<=rowMatchName.length && + rowMatchName.substr(0, search.length)==search) + { + row.style.display = 'block'; + matches++; + } + else + { + row.style.display = 'none'; + } + } + i++; + } + document.getElementById("Searching").style.display='none'; + if (matches == 0) // no results + { + document.getElementById("NoMatches").style.display='block'; + } + else // at least one result + { + document.getElementById("NoMatches").style.display='none'; + } + this.lastMatchCount = matches; + return true; + } + + // return the first item with index index or higher that is visible + this.NavNext = function(index) + { + var focusItem; + while (1) + { + var focusName = 'Item'+index; + focusItem = document.getElementById(focusName); + if (focusItem && focusItem.parentNode.parentNode.style.display=='block') + { + break; + } + else if (!focusItem) // last element + { + break; + } + focusItem=null; + index++; + } + return focusItem; + } + + this.NavPrev = function(index) + { + var focusItem; + while (1) + { + var focusName = 'Item'+index; + focusItem = document.getElementById(focusName); + if (focusItem && focusItem.parentNode.parentNode.style.display=='block') + { + break; + } + else if (!focusItem) // last element + { + break; + } + focusItem=null; + index--; + } + return focusItem; + } + + this.ProcessKeys = function(e) + { + if (e.type == "keydown") + { + this.repeatOn = false; + this.lastKey = e.keyCode; + } + else if (e.type == "keypress") + { + if (!this.repeatOn) + { + if (this.lastKey) this.repeatOn = true; + return false; // ignore first keypress after keydown + } + } + else if (e.type == "keyup") + { + this.lastKey = 0; + this.repeatOn = false; + } + return this.lastKey!=0; + } + + this.Nav = function(evt,itemIndex) + { + var e = (evt) ? evt : window.event; // for IE + if (e.keyCode==13) return true; + if (!this.ProcessKeys(e)) return false; + + if (this.lastKey==38) // Up + { + var newIndex = itemIndex-1; + var focusItem = this.NavPrev(newIndex); + if (focusItem) + { + var child = this.FindChildElement(focusItem.parentNode.parentNode.id); + if (child && child.style.display == 'block') // children visible + { + var n=0; + var tmpElem; + while (1) // search for last child + { + tmpElem = document.getElementById('Item'+newIndex+'_c'+n); + if (tmpElem) + { + focusItem = tmpElem; + } + else // found it! + { + break; + } + n++; + } + } + } + if (focusItem) + { + focusItem.focus(); + } + else // return focus to search field + { + parent.document.getElementById("MSearchField").focus(); + } + } + else if (this.lastKey==40) // Down + { + var newIndex = itemIndex+1; + var focusItem; + var item = document.getElementById('Item'+itemIndex); + var elem = this.FindChildElement(item.parentNode.parentNode.id); + if (elem && elem.style.display == 'block') // children visible + { + focusItem = document.getElementById('Item'+itemIndex+'_c0'); + } + if (!focusItem) focusItem = this.NavNext(newIndex); + if (focusItem) focusItem.focus(); + } + else if (this.lastKey==39) // Right + { + var item = document.getElementById('Item'+itemIndex); + var elem = this.FindChildElement(item.parentNode.parentNode.id); + if (elem) elem.style.display = 'block'; + } + else if (this.lastKey==37) // Left + { + var item = document.getElementById('Item'+itemIndex); + var elem = this.FindChildElement(item.parentNode.parentNode.id); + if (elem) elem.style.display = 'none'; + } + else if (this.lastKey==27) // Escape + { + parent.searchBox.CloseResultsWindow(); + parent.document.getElementById("MSearchField").focus(); + } + else if (this.lastKey==13) // Enter + { + return true; + } + return false; + } + + this.NavChild = function(evt,itemIndex,childIndex) + { + var e = (evt) ? evt : window.event; // for IE + if (e.keyCode==13) return true; + if (!this.ProcessKeys(e)) return false; + + if (this.lastKey==38) // Up + { + if (childIndex>0) + { + var newIndex = childIndex-1; + document.getElementById('Item'+itemIndex+'_c'+newIndex).focus(); + } + else // already at first child, jump to parent + { + document.getElementById('Item'+itemIndex).focus(); + } + } + else if (this.lastKey==40) // Down + { + var newIndex = childIndex+1; + var elem = document.getElementById('Item'+itemIndex+'_c'+newIndex); + if (!elem) // last child, jump to parent next parent + { + elem = this.NavNext(itemIndex+1); + } + if (elem) + { + elem.focus(); + } + } + else if (this.lastKey==27) // Escape + { + parent.searchBox.CloseResultsWindow(); + parent.document.getElementById("MSearchField").focus(); + } + else if (this.lastKey==13) // Enter + { + return true; + } + return false; + } +} + +function setKeyActions(elem,action) +{ + elem.setAttribute('onkeydown',action); + elem.setAttribute('onkeypress',action); + elem.setAttribute('onkeyup',action); +} + +function setClassAttr(elem,attr) +{ + elem.setAttribute('class',attr); + elem.setAttribute('className',attr); +} + +function createResults() +{ + var results = document.getElementById("SRResults"); + for (var e=0; e + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/search/variables_63.js b/search/variables_63.js new file mode 100644 index 0000000..033dcd7 --- /dev/null +++ b/search/variables_63.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['channelname',['channelName',['../structpvalink_1_1pva_link_config.html#a87b194f54983a2d55f617cb6178368e2',1,'pvalink::pvaLinkConfig']]] +]; diff --git a/search/variables_66.html b/search/variables_66.html new file mode 100644 index 0000000..802fdbc --- /dev/null +++ b/search/variables_66.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/search/variables_66.js b/search/variables_66.js new file mode 100644 index 0000000..15bf295 --- /dev/null +++ b/search/variables_66.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['fieldname',['fieldName',['../structpvalink_1_1pva_link_config.html#a747c31e4118c1ce1f10bb5301a66d281',1,'pvalink::pvaLinkConfig']]] +]; diff --git a/search/variables_6c.html b/search/variables_6c.html new file mode 100644 index 0000000..c136114 --- /dev/null +++ b/search/variables_6c.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/search/variables_6c.js b/search/variables_6c.js new file mode 100644 index 0000000..81602ec --- /dev/null +++ b/search/variables_6c.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['lastelem',['lastelem',['../struct_monitor_cache_entry.html#ac32c2f4b0e388af0295f80e460f9c72e',1,'MonitorCacheEntry']]] +]; diff --git a/server_8cpp_source.html b/server_8cpp_source.html new file mode 100644 index 0000000..9305610 --- /dev/null +++ b/server_8cpp_source.html @@ -0,0 +1,424 @@ + + + + + + +pva2pva: p2pApp/server.cpp Source File + + + + + + + + + +
+
+ + + + + + +
+
pva2pva +  1.4.1 +
+
+
+ + + + + + + + + +
+ +
+ + +
+
+
+
server.cpp
+
+
+
1 #include <stdio.h>
+
2 
+
3 #include <epicsAtomic.h>
+
4 #include <epicsString.h>
+
5 #include <epicsTimer.h>
+
6 
+
7 #include <pv/logger.h>
+
8 #include <pv/pvIntrospect.h> /* for pvdVersion.h */
+
9 #include <pv/epicsException.h>
+
10 #include <pv/serverContext.h>
+
11 #include <pv/logger.h>
+
12 
+
13 #define epicsExportSharedSymbols
+
14 #include "helper.h"
+
15 #include "pva2pva.h"
+
16 #include "server.h"
+
17 
+
18 #if defined(PVDATA_VERSION_INT)
+
19 #if PVDATA_VERSION_INT > VERSION_INT(7,0,0,0)
+
20 # define USE_MSTATS
+
21 #endif
+
22 #endif
+
23 
+
24 namespace pva = epics::pvAccess;
+
25 namespace pvd = epics::pvData;
+
26 
+
27 std::tr1::shared_ptr<pva::ChannelProvider>
+
28 GWServerChannelProvider::getChannelProvider()
+
29 {
+
30  return shared_from_this();
+
31 }
+
32 
+
33 // Called from UDP search thread with no locks held
+
34 // Called from TCP threads (for search w/ TCP)
+
35 pva::ChannelFind::shared_pointer
+
36 GWServerChannelProvider::channelFind(std::string const & channelName,
+
37  pva::ChannelFindRequester::shared_pointer const & channelFindRequester)
+
38 {
+
39  pva::ChannelFind::shared_pointer ret;
+
40  bool found = false;
+
41 
+
42  if(!channelName.empty())
+
43  {
+
44  LOG(pva::logLevelDebug, "Searching for '%s'", channelName.c_str());
+
45  ChannelCacheEntry::shared_pointer ent(cache.lookup(channelName));
+
46  if(ent) {
+
47  found = true;
+
48  ret = shared_from_this();
+
49  }
+
50  }
+
51 
+
52  // unlock for callback
+
53 
+
54  channelFindRequester->channelFindResult(pvd::Status::Ok, ret, found);
+
55 
+
56  return ret;
+
57 }
+
58 
+
59 // The return value of this function is ignored
+
60 // The newly created channel is given to the ChannelRequester
+
61 pva::Channel::shared_pointer
+
62 GWServerChannelProvider::createChannel(std::string const & channelName,
+
63  pva::ChannelRequester::shared_pointer const & channelRequester,
+
64  short priority, std::string const & addressx)
+
65 {
+
66  GWChannel::shared_pointer ret;
+
67  std::string address = channelRequester->getRequesterName();
+
68 
+
69  if(!channelName.empty())
+
70  {
+
71  Guard G(cache.cacheLock);
+
72 
+
73  ChannelCacheEntry::shared_pointer ent(cache.lookup(channelName)); // recursively locks cacheLock
+
74 
+
75  if(ent)
+
76  {
+
77  ret.reset(new GWChannel(ent, shared_from_this(), channelRequester, address));
+
78  ent->interested.insert(ret);
+
79  ret->weakref = ret;
+
80  }
+
81  }
+
82 
+
83  if(!ret) {
+
84  pvd::Status S(pvd::Status::STATUSTYPE_ERROR, "Not found");
+
85  channelRequester->channelCreated(S, ret);
+
86  } else {
+
87  channelRequester->channelCreated(pvd::Status::Ok, ret);
+
88  channelRequester->channelStateChange(ret, pva::Channel::CONNECTED);
+
89  }
+
90 
+
91  return ret; // ignored by caller
+
92 }
+
93 
+
94 void GWServerChannelProvider::destroy() {}
+
95 
+
96 GWServerChannelProvider::GWServerChannelProvider(const pva::ChannelProvider::shared_pointer& prov)
+
97  :cache(prov)
+
98 {}
+
99 
+
100 GWServerChannelProvider::~GWServerChannelProvider() {}
+
101 
+
102 void ServerConfig::drop(const char *client, const char *channel)
+
103 {
+
104  if(!client)
+
105  client= "";
+
106  if(!channel)
+
107  channel = "";
+
108  // TODO: channel glob match
+
109 
+
110  FOREACH(clients_t::const_iterator, it, end, clients)
+
111  {
+
112  if(client[0]!='\0' && client[0]!='*' && it->first!=client)
+
113  continue;
+
114 
+
115  const GWServerChannelProvider::shared_pointer& prov(it->second);
+
116 
+
117  ChannelCacheEntry::shared_pointer entry;
+
118 
+
119  // find the channel, if it's there
+
120  {
+
121  Guard G(prov->cache.cacheLock);
+
122 
+
123  ChannelCache::entries_t::iterator it = prov->cache.entries.find(channel);
+
124  if(it==prov->cache.entries.end())
+
125  continue;
+
126 
+
127  std::cout<<"Drop from "<<it->first<<" : "<<it->second->channelName<<"\n";
+
128 
+
129  entry = it->second;
+
130  prov->cache.entries.erase(it); // drop out of cache (TODO: not required)
+
131  }
+
132 
+
133  // trigger client side disconnect (recursively calls call CRequester::channelStateChange())
+
134  // TODO: shouldn't need this
+
135  entry->channel->destroy();
+
136 
+
137  }
+
138 }
+
139 
+
140 void ServerConfig::status_server(int lvl, const char *server)
+
141 {
+
142  if(!server)
+
143  server = "";
+
144 
+
145  FOREACH(servers_t::const_iterator, it, end, servers)
+
146  {
+
147  if(server[0]!='\0' && server[0]!='*' && it->first!=server)
+
148  continue;
+
149 
+
150  const pva::ServerContext::shared_pointer& serv(it->second);
+
151  std::cout<<"==> Server: "<<it->first<<"\n";
+
152  serv->printInfo(std::cout);
+
153  std::cout<<"<== Server: "<<it->first<<"\n\n";
+
154  // TODO: print client list somehow
+
155  }
+
156 }
+
157 
+
158 void ServerConfig::status_client(int lvl, const char *client, const char *channel)
+
159 {
+
160  if(!client)
+
161  client= "";
+
162  if(!channel)
+
163  channel = "";
+
164 
+
165  bool iswild = strchr(channel, '?') || strchr(channel, '*');
+
166 
+
167  FOREACH(clients_t::const_iterator, it, end, clients)
+
168  {
+
169  if(client[0]!='\0' && client[0]!='*' && it->first!=client)
+
170  continue;
+
171 
+
172  const GWServerChannelProvider::shared_pointer& prov(it->second);
+
173 
+
174  std::cout<<"==> Client: "<<it->first<<"\n";
+
175 
+
176  ChannelCache::entries_t entries;
+
177 
+
178  size_t ncache, ncleaned, ndust;
+
179  {
+
180  Guard G(prov->cache.cacheLock);
+
181 
+
182  ncache = prov->cache.entries.size();
+
183  ncleaned = prov->cache.cleanerRuns;
+
184  ndust = prov->cache.cleanerDust;
+
185 
+
186  if(lvl>0) {
+
187  if(!iswild) { // no string or some glob pattern
+
188  entries = prov->cache.entries; // copy of std::map
+
189  } else { // just one channel
+
190  ChannelCache::entries_t::iterator it(prov->cache.entries.find(channel));
+
191  if(it!=prov->cache.entries.end())
+
192  entries[it->first] = it->second;
+
193  }
+
194  }
+
195  }
+
196 
+
197  std::cout<<"Cache has "<<ncache<<" channels. Cleaned "
+
198  <<ncleaned<<" times closing "<<ndust<<" channels\n";
+
199 
+
200  if(lvl<=0)
+
201  continue;
+
202 
+
203  FOREACH(ChannelCache::entries_t::const_iterator, it2, end2, entries)
+
204  {
+
205  const std::string& channame = it2->first;
+
206  if(iswild && !epicsStrGlobMatch(channame.c_str(), channel))
+
207  continue;
+
208 
+
209  ChannelCacheEntry& E = *it2->second;
+
210  ChannelCacheEntry::mon_entries_t::lock_vector_type mons;
+
211  size_t nsrv, nmon;
+
212  bool dropflag;
+
213  const char *chstate;
+
214  {
+
215  Guard G(E.mutex());
+
216  chstate = pva::Channel::ConnectionStateNames[E.channel->getConnectionState()];
+
217  nsrv = E.interested.size();
+
218  nmon = E.mon_entries.size();
+
219  dropflag = E.dropPoke;
+
220 
+
221  if(lvl>1)
+
222  mons = E.mon_entries.lock_vector();
+
223  }
+
224 
+
225  std::cout<<chstate
+
226  <<" Client Channel '"<<channame
+
227  <<"' used by "<<nsrv<<" Server channel(s) with "
+
228  <<nmon<<" unique subscription(s) "
+
229  <<(dropflag?'!':'_')<<"\n";
+
230 
+
231  if(lvl<=1)
+
232  continue;
+
233 
+
234  FOREACH(ChannelCacheEntry::mon_entries_t::lock_vector_type::const_iterator, it2, end2, mons) {
+
235  MonitorCacheEntry& ME = *it2->second;
+
236 
+
237  MonitorCacheEntry::interested_t::vector_type usrs;
+
238  size_t nsrvmon;
+
239 #ifdef USE_MSTATS
+
240  pvd::Monitor::Stats mstats;
+
241 #endif
+
242  bool hastype, hasdata, isdone;
+
243  {
+
244  Guard G(ME.mutex());
+
245 
+
246  nsrvmon = ME.interested.size();
+
247  hastype = !!ME.typedesc;
+
248  hasdata = !!ME.lastelem;
+
249  isdone = ME.done;
+
250 
+
251 #ifdef USE_MSTATS
+
252  if(ME.mon)
+
253  ME.mon->getStats(mstats);
+
254 #endif
+
255 
+
256  if(lvl>2)
+
257  usrs = ME.interested.lock_vector();
+
258  }
+
259 
+
260  // TODO: how to describe pvRequest in a compact way...
+
261  std::cout<<" Client Monitor used by "<<nsrvmon<<" Server monitors, "
+
262  <<"Has "<<(hastype?"":"not ")
+
263  <<"opened, Has "<<(hasdata?"":"not ")
+
264  <<"recv'd some data, Has "<<(isdone?"":"not ")<<"finalized\n"
+
265  " "<< epicsAtomicGetSizeT(&ME.nwakeups)<<" wakeups "
+
266  <<epicsAtomicGetSizeT(&ME.nevents)<<" events\n";
+
267 #ifdef USE_MSTATS
+
268  if(mstats.nempty || mstats.nfilled || mstats.noutstanding)
+
269  std::cout<<" US monitor queue "<<mstats.nfilled
+
270  <<" filled, "<<mstats.noutstanding
+
271  <<" outstanding, "<<mstats.nempty<<" empty\n";
+
272 #endif
+
273  if(lvl<=2)
+
274  continue;
+
275 
+
276  FOREACH(MonitorCacheEntry::interested_t::vector_type::const_iterator, it3, end3, usrs) {
+
277  MonitorUser& MU = **it3;
+
278 
+
279  size_t nempty, nfilled, nused, total;
+
280  std::string remote;
+
281  bool isrunning;
+
282  {
+
283  Guard G(MU.mutex());
+
284 
+
285  nempty = MU.empty.size();
+
286  nfilled = MU.filled.size();
+
287  nused = MU.inuse.size();
+
288  isrunning = MU.running;
+
289 
+
290  GWChannel::shared_pointer srvchan(MU.srvchan.lock());
+
291  if(srvchan)
+
292  remote = srvchan->address;
+
293  else
+
294  remote = "<unknown>";
+
295  }
+
296  total = nempty + nfilled + nused;
+
297 
+
298  std::cout<<" Server monitor from "
+
299  <<remote
+
300  <<(isrunning?"":" Paused")
+
301  <<" buffer "<<nfilled<<"/"<<total
+
302  <<" out "<<nused<<"/"<<total
+
303  <<" "<<epicsAtomicGetSizeT(&MU.nwakeups)<<" wakeups "
+
304  <<epicsAtomicGetSizeT(&MU.nevents)<<" events "
+
305  <<epicsAtomicGetSizeT(&MU.ndropped)<<" drops\n";
+
306  }
+
307  }
+
308 
+
309 
+
310 
+
311  }
+
312 
+
313 
+
314  std::cout<<"<== Client: "<<it->first<<"\n\n";
+
315  }
+
316 }
+
epics::pvData::MonitorElement::shared_pointer lastelem
Definition: chancache.h:46
+
Definition: chancache.h:103
+ +
size_t size() const
Definition: weakmap.h:147
+
lock_vector_type lock_vector() const
Definition: weakmap.h:259
+
vector_type lock_vector() const
Definition: weakset.h:268
+
size_t size() const
Definition: weakset.h:168
+
Definition: chancache.h:22
+ +
+ + + + diff --git a/server_8h_source.html b/server_8h_source.html new file mode 100644 index 0000000..8d89531 --- /dev/null +++ b/server_8h_source.html @@ -0,0 +1,158 @@ + + + + + + +pva2pva: p2pApp/server.h Source File + + + + + + + + + +
+
+ + + + + + +
+
pva2pva +  1.4.1 +
+
+
+ + + + + + + + + +
+ +
+ + +
+
+
+
server.h
+
+
+
1 #ifndef SERVER_H
+
2 #define SERVER_H
+
3 
+
4 #include <pv/serverContext.h>
+
5 
+
6 #include "chancache.h"
+
7 #include "channel.h"
+
8 
+ +
10  public epics::pvAccess::ChannelProvider,
+
11  public epics::pvAccess::ChannelFind,
+
12  public std::tr1::enable_shared_from_this<GWServerChannelProvider>
+
13 {
+
14  POINTER_DEFINITIONS(GWServerChannelProvider);
+
15  ChannelCache cache;
+
16 
+
17  virtual std::tr1::shared_ptr<ChannelProvider> getChannelProvider();
+
18 
+
19  virtual void cancel() {}
+
20 
+
21  virtual std::string getProviderName() {
+
22  return "GWServer";
+
23  }
+
24 
+
25  virtual epics::pvAccess::ChannelFind::shared_pointer channelFind(std::string const & channelName,
+
26  epics::pvAccess::ChannelFindRequester::shared_pointer const & channelFindRequester);
+
27 
+
28  using epics::pvAccess::ChannelProvider::createChannel;
+
29  virtual epics::pvAccess::Channel::shared_pointer createChannel(std::string const & channelName,
+
30  epics::pvAccess::ChannelRequester::shared_pointer const & channelRequester,
+
31  short priority, std::string const & addressx);
+
32  virtual void destroy();
+
33 
+
34  explicit GWServerChannelProvider(const epics::pvAccess::ChannelProvider::shared_pointer& prov);
+
35  virtual ~GWServerChannelProvider();
+
36 };
+
37 
+
38 struct ServerConfig {
+
39  int debug;
+
40  bool interactive;
+
41  epics::pvData::PVStructure::shared_pointer conf;
+
42 
+
43  typedef std::map<std::string, GWServerChannelProvider::shared_pointer> clients_t;
+
44  clients_t clients;
+
45 
+
46  typedef std::map<std::string, epics::pvAccess::ServerContext::shared_pointer> servers_t;
+
47  servers_t servers;
+
48 
+
49  ServerConfig() :debug(1), interactive(true) {}
+
50 
+
51  void drop(const char *client, const char *channel);
+
52  void status_server(int lvl, const char *server);
+
53  void status_client(int lvl, const char *client, const char *channel);
+
54 };
+
55 
+
56 #endif // SERVER_H
+ + + +
+ + + + diff --git a/soft_main_8cpp_source.html b/soft_main_8cpp_source.html new file mode 100644 index 0000000..347f0d4 --- /dev/null +++ b/soft_main_8cpp_source.html @@ -0,0 +1,381 @@ + + + + + + +pva2pva: pdbApp/softMain.cpp Source File + + + + + + + + + +
+
+ + + + + + +
+
pva2pva +  1.4.1 +
+
+
+ + + + + + + + + +
+ +
+ + +
+
+
+
softMain.cpp
+
+
+
1 /*************************************************************************\
+
2 * Copyright (c) 2008 UChicago Argonne LLC, as Operator of Argonne
+
3 * National Laboratory.
+
4 * Copyright (c) 2003 The Regents of the University of California, as
+
5 * Operator of Los Alamos National Laboratory.
+
6 * EPICS BASE is distributed subject to the Software License Agreement
+
7 * found in the file LICENSE that is included with this distribution.
+
8 \*************************************************************************/
+
9 
+
10 /* Author: Andrew Johnson Date: 2003-04-08 */
+
11 
+
12 #include <iostream>
+
13 #include <string>
+
14 #include <list>
+
15 #include <stdexcept>
+
16 
+
17 #include <epicsVersion.h>
+
18 #include <epicsGetopt.h>
+
19 #include "registryFunction.h"
+
20 #include "epicsThread.h"
+
21 #include "epicsExit.h"
+
22 #include "epicsStdio.h"
+
23 #include "epicsString.h"
+
24 #include "dbStaticLib.h"
+
25 #include "subRecord.h"
+
26 #include "dbAccess.h"
+
27 #include "asDbLib.h"
+
28 #include "iocInit.h"
+
29 #include "iocsh.h"
+
30 #include "osiFileName.h"
+
31 
+
32 #include <pv/qsrv.h>
+
33 
+
34 extern "C" int softIocPVA_registerRecordDeviceDriver(struct dbBase *pdbbase);
+
35 
+
36 #ifndef EPICS_BASE
+
37 // so IDEs knows EPICS_BASE is a string constant
+
38 # define EPICS_BASE "/"
+
39 # error -DEPICS_BASE required
+
40 #endif
+
41 
+
42 #if EPICS_VERSION_INT>=VERSION_INT(7,0,2,0)
+
43 # define USE_EXECDIR
+
44 #endif
+
45 
+
46 #define DBD_BASE "dbd" OSI_PATH_SEPARATOR "softIocPVA.dbd"
+
47 #define EXIT_BASE "db" OSI_PATH_SEPARATOR "softIocExit.db"
+
48 #define DBD_FILE_REL ".." OSI_PATH_SEPARATOR ".." OSI_PATH_SEPARATOR DBD_BASE
+
49 #define EXIT_FILE_REL ".." OSI_PATH_SEPARATOR ".." OSI_PATH_SEPARATOR EXIT_BASE
+
50 #define DBD_FILE EPICS_BASE OSI_PATH_SEPARATOR DBD_BASE
+
51 #define EXIT_FILE EPICS_BASE OSI_PATH_SEPARATOR EXIT_BASE
+
52 
+
53 namespace {
+
54 
+
55 bool verbose = false;
+
56 
+
57 static void exitSubroutine(subRecord *precord) {
+
58  epicsExitLater((precord->a == 0.0) ? EXIT_SUCCESS : EXIT_FAILURE);
+
59 }
+
60 
+
61 void usage(const char *arg0, const std::string& base_dbd) {
+
62  std::cout<<"Usage: "<<arg0<<
+
63  " [-D softIocPVA.dbd] [-h] [-S] [-s] [-v] [-a ascf]\n"
+
64  "[-m macro=value,macro2=value2] [-d file.db]\n"
+
65  "[-x prefix] [st.cmd]\n"
+
66  "\n"
+
67  " -D <dbd> If used, must come first. Specify the path to the softIocPVA.dbdfile."
+
68  " The compile-time install location is saved in the binary as a default.\n"
+
69  "\n"
+
70  " -h Print this mesage and exit.\n"
+
71  "\n"
+
72  " -S Prevents an interactive shell being started.\n"
+
73  "\n"
+
74  " -s Previously caused a shell to be started. Now accepted and ignored.\n"
+
75  "\n"
+
76  " -v Verbose, display steps taken during startup.\n"
+
77  "\n"
+
78  " -a <acf> Access Security configuration file. Macro substitution is\n"
+
79  " performed.\n"
+
80  "\n"
+
81  " -G <json> DB Group definition file in JSON format.\n"
+
82  "\n"
+
83  " -m <MAC>=<value>,... Set/replace macro definitions used by subsequent -d and\n"
+
84  " -a.\n"
+
85  "\n"
+
86  " -d <db> Load records from file (dbLoadRecords). Macro substitution is\n"
+
87  " performed.\n"
+
88  "\n"
+
89  " -x <prefix> Load softIocExit.db. Provides a record \"<prefix>:exit\".\n"
+
90  " Put 0 to exit with success, or non-zero to exit with an error.\n"
+
91  "\n"
+
92  "Any number of -m and -d arguments can be interspersed; the macros are applied\n"
+
93  "to the following .db files. Each later -m option causes earlier macros to be\n"
+
94  "discarded.\n"
+
95  "\n"
+
96  "A st.cmd file is optional. If any databases were loaded the st.cmd file will\n"
+
97  "be run *after* iocInit. To perform iocsh commands before iocInit, all database\n"
+
98  "loading must be performed by the script itself, or by the user from the\n"
+
99  "interactive IOC shell.\n"
+
100  "\n"
+
101  "Compiled-in path to softIocPVA.dbd is:\n"
+
102  "\t"<<base_dbd.c_str()<<"\n";
+
103 }
+
104 
+
105 void errIf(int ret, const std::string& msg)
+
106 {
+
107  if(ret)
+
108  throw std::runtime_error(msg);
+
109 }
+
110 
+
111 bool lazy_dbd_loaded;
+
112 
+
113 void lazy_dbd(const std::string& dbd_file) {
+
114  if(lazy_dbd_loaded) return;
+
115  lazy_dbd_loaded = true;
+
116 
+
117  if (verbose)
+
118  std::cout<<"dbLoadDatabase(\""<<dbd_file<<"\")\n";
+
119  errIf(dbLoadDatabase(dbd_file.c_str(), NULL, NULL),
+
120  std::string("Failed to load DBD file: ")+dbd_file);
+
121 
+
122  if (verbose)
+
123  std::cout<<"softIocPVA_registerRecordDeviceDriver(pdbbase)\n";
+
124  softIocPVA_registerRecordDeviceDriver(pdbbase);
+
125  registryFunctionAdd("exit", (REGISTRYFUNCTION) exitSubroutine);
+
126 }
+
127 
+
128 } // namespace
+
129 
+
130 int main(int argc, char *argv[])
+
131 {
+
132  try {
+
133  std::string dbd_file(DBD_FILE),
+
134  exit_file(EXIT_FILE),
+
135  macros, // scratch space for macros (may be given more than once)
+
136  xmacro;
+
137  bool interactive = true;
+
138  bool loadedDb = false;
+
139  bool ranScript = false;
+
140 
+
141 #ifdef USE_EXECDIR
+
142  // attempt to compute relative paths
+
143  {
+
144  std::string prefix;
+
145  char *cprefix = epicsGetExecDir();
+
146  if(cprefix) {
+
147  try {
+
148  prefix = cprefix;
+
149  free(cprefix);
+
150  } catch(...) {
+
151  free(cprefix);
+
152  throw;
+
153  }
+
154  }
+
155 
+
156  dbd_file = prefix + DBD_FILE_REL;
+
157  exit_file = prefix + EXIT_FILE_REL;
+
158  }
+
159 #endif
+
160 
+
161  int opt;
+
162 
+
163  while ((opt = getopt(argc, argv, "ha:D:d:m:Ssx:G:v")) != -1) {
+
164  switch (opt) {
+
165  case 'h': /* Print usage */
+
166  usage(argv[0], dbd_file);
+
167  epicsExit(0);
+
168  return 0;
+
169  default:
+
170  usage(argv[0], dbd_file);
+
171  std::cerr<<"Unknown argument: -"<<char(opt)<<"\n";
+
172  epicsExit(2);
+
173  return 2;
+
174  case 'a':
+
175  lazy_dbd(dbd_file);
+
176  if (!macros.empty()) {
+
177  if (verbose)
+
178  std::cout<<"asSetSubstitutions(\""<<macros<<"\")\n";
+
179  if(asSetSubstitutions(macros.c_str()))
+
180  throw std::bad_alloc();
+
181  }
+
182  if (verbose)
+
183  std::cout<<"asSetFilename(\""<<optarg<<"\")\n";
+
184  if(asSetFilename(optarg))
+
185  throw std::bad_alloc();
+
186  break;
+
187  case 'D':
+
188  if(lazy_dbd_loaded) {
+
189  throw std::runtime_error("-D specified too late. softIocPVA.dbd already loaded.\n");
+
190  }
+
191  dbd_file = optarg;
+
192  break;
+
193  case 'd':
+
194  lazy_dbd(dbd_file);
+
195  if (verbose) {
+
196  std::cout<<"dbLoadRecords(\""<<optarg<<"\"";
+
197  if(!macros.empty())
+
198  std::cout<<", \""<<macros<<"\"";
+
199  std::cout<<")\n";
+
200  }
+
201  errIf(dbLoadRecords(optarg, macros.c_str()),
+
202  std::string("Failed to load: ")+optarg);
+
203  loadedDb = true;
+
204  break;
+
205  case 'm':
+
206  macros = optarg;
+
207  break;
+
208  case 'S':
+
209  interactive = false;
+
210  break;
+
211  case 's':
+
212  break; // historical
+
213  case 'v':
+
214  verbose = true;
+
215  break;
+
216  case 'x':
+
217  lazy_dbd(dbd_file);
+
218  xmacro = "IOC=";
+
219  xmacro += optarg;
+
220  errIf(dbLoadRecords(exit_file.c_str(), xmacro.c_str()),
+
221  std::string("Failed to load: ")+exit_file);
+
222  loadedDb = true;
+
223  break;
+
224  case 'G':
+
225  dbLoadGroup(optarg);
+
226  break;
+
227  }
+
228  }
+
229 
+
230  lazy_dbd(dbd_file);
+
231 
+
232  if(optind<argc) {
+
233  // run script
+
234  // ignore any extra positional args (historical)
+
235 
+
236  if (verbose)
+
237  std::cout<<"# Begin "<<argv[optind]<<"\n";
+
238  errIf(iocsh(argv[optind]),
+
239  std::string("Error in ")+argv[optind]);
+
240  if (verbose)
+
241  std::cout<<"# End "<<argv[optind]<<"\n";
+
242 
+
243  epicsThreadSleep(0.2);
+
244  ranScript = true; /* Assume the script has done any necessary initialization */
+
245  }
+
246 
+
247  if (loadedDb) {
+
248  if (verbose)
+
249  std::cout<<"iocInit()\n";
+
250  iocInit();
+
251  epicsThreadSleep(0.2);
+
252  }
+
253 
+
254  if(interactive) {
+
255  std::cout.flush();
+
256  std::cerr.flush();
+
257  if(iocsh(NULL)) {
+
258  epicsExit(1);
+
259  return 1;
+
260  }
+
261 
+
262  } else {
+
263  if (loadedDb || ranScript) {
+
264  epicsThreadExitMain();
+
265 
+
266  } else {
+
267  usage(argv[0], dbd_file);
+
268  std::cerr<<"Nothing to do!\n";
+
269  epicsExit(1);
+
270  return 1;
+
271  }
+
272  }
+
273 
+
274  epicsExit(0);
+
275  return 0;
+
276 
+
277  }catch(std::exception& e){
+
278  std::cerr<<"Error: "<<e.what()<<"\n";
+
279  epicsExit(2);
+
280  return 2;
+
281  }
+
282 }
+
+ + + + diff --git a/struct_a_s_c_l_i_e_n_t-members.html b/struct_a_s_c_l_i_e_n_t-members.html new file mode 100644 index 0000000..fc5b291 --- /dev/null +++ b/struct_a_s_c_l_i_e_n_t-members.html @@ -0,0 +1,107 @@ + + + + + + +pva2pva: Member List + + + + + + + + + +
+
+ + + + + + +
+
pva2pva +  1.4.1 +
+
+
+ + + + + + + + + +
+ +
+ +
+
+
+
ASCLIENT Member List
+
+
+ +

This is the complete list of members for ASCLIENT, including all inherited members.

+ + + + + + + +
add(dbChannel *chan, ASCred &cred) (defined in ASCLIENT)ASCLIENT
ASCLIENT() (defined in ASCLIENT)ASCLIENTinline
aspvt (defined in ASCLIENT)ASCLIENT
canWrite() (defined in ASCLIENT)ASCLIENT
grppvt (defined in ASCLIENT)ASCLIENT
~ASCLIENT() (defined in ASCLIENT)ASCLIENT
+ + + + diff --git a/struct_a_s_c_l_i_e_n_t.html b/struct_a_s_c_l_i_e_n_t.html new file mode 100644 index 0000000..05ea88d --- /dev/null +++ b/struct_a_s_c_l_i_e_n_t.html @@ -0,0 +1,128 @@ + + + + + + +pva2pva: ASCLIENT Struct Reference + + + + + + + + + +
+
+ + + + + + +
+
pva2pva +  1.4.1 +
+
+
+ + + + + + + + + +
+ +
+ +
+
+ +
+
ASCLIENT Struct Reference
+
+
+ + + + + + +

+Public Member Functions

+void add (dbChannel *chan, ASCred &cred)
 
+bool canWrite ()
 
+ + + + + +

+Public Attributes

+ASCLIENTPVT aspvt
 
+std::vector< ASCLIENTPVT > grppvt
 
+

Detailed Description

+
+

Definition at line 107 of file pvif.h.

+

The documentation for this struct was generated from the following files: +
+ + + + diff --git a/struct_a_s_cred-members.html b/struct_a_s_cred-members.html new file mode 100644 index 0000000..5ebd1b8 --- /dev/null +++ b/struct_a_s_cred-members.html @@ -0,0 +1,105 @@ + + + + + + +pva2pva: Member List + + + + + + + + + +
+
+ + + + + + +
+
pva2pva +  1.4.1 +
+
+
+ + + + + + + + + +
+ +
+ +
+
+
+
ASCred Member List
+
+
+ +

This is the complete list of members for ASCred, including all inherited members.

+ + + + + +
groups (defined in ASCred)ASCred
host (defined in ASCred)ASCred
update(const std::tr1::shared_ptr< epics::pvAccess::ChannelRequester > &request) (defined in ASCred)ASCred
user (defined in ASCred)ASCred
+ + + + diff --git a/struct_a_s_cred.html b/struct_a_s_cred.html new file mode 100644 index 0000000..2744a5e --- /dev/null +++ b/struct_a_s_cred.html @@ -0,0 +1,128 @@ + + + + + + +pva2pva: ASCred Struct Reference + + + + + + + + + +
+
+ + + + + + +
+
pva2pva +  1.4.1 +
+
+
+ + + + + + + + + +
+ +
+ +
+
+ +
+
ASCred Struct Reference
+
+
+ + + + +

+Public Member Functions

+void update (const std::tr1::shared_ptr< epics::pvAccess::ChannelRequester > &request)
 
+ + + + + + + +

+Public Attributes

+std::vector< char > user
 
+std::vector< char > host
 
+std::vector< std::vector< char > > groups
 
+

Detailed Description

+
+

Definition at line 100 of file pvif.h.

+

The documentation for this struct was generated from the following files: +
+ + + + diff --git a/struct_base_channel-members.html b/struct_base_channel-members.html new file mode 100644 index 0000000..ef41a37 --- /dev/null +++ b/struct_base_channel-members.html @@ -0,0 +1,117 @@ + + + + + + +pva2pva: Member List + + + + + + + + + +
+
+ + + + + + +
+
pva2pva +  1.4.1 +
+
+
+ + + + + + + + + +
+ +
+ +
+
+
+
BaseChannel Member List
+
+
+ +

This is the complete list of members for BaseChannel, including all inherited members.

+ + + + + + + + + + + + + + + + + +
BaseChannel(const std::string &name, const std::tr1::weak_ptr< epics::pvAccess::ChannelProvider > &prov, const epics::pvAccess::ChannelRequester::shared_pointer &req, const epics::pvData::StructureConstPtr &dtype) (defined in BaseChannel)BaseChannelinline
destroy() OVERRIDE FINAL (defined in BaseChannel)BaseChannelinlinevirtual
fielddesc (defined in BaseChannel)BaseChannel
getChannelName() OVERRIDE FINAL (defined in BaseChannel)BaseChannelinlinevirtual
getChannelRequester() OVERRIDE FINAL (defined in BaseChannel)BaseChannelinlinevirtual
getField(epics::pvAccess::GetFieldRequester::shared_pointer const &requester, std::string const &subField) OVERRIDE (defined in BaseChannel)BaseChannelinlinevirtual
getProvider() OVERRIDE FINAL (defined in BaseChannel)BaseChannelinlinevirtual
getRemoteAddress() OVERRIDE (defined in BaseChannel)BaseChannelinlinevirtual
getRequesterName() OVERRIDE (defined in BaseChannel)BaseChannelinlinevirtual
guard_t typedef (defined in BaseChannel)BaseChannel
lock (defined in BaseChannel)BaseChannelmutable
printInfo(std::ostream &out) OVERRIDE (defined in BaseChannel)BaseChannelinlinevirtual
provider (defined in BaseChannel)BaseChannel
pvname (defined in BaseChannel)BaseChannel
requester (defined in BaseChannel)BaseChannel
~BaseChannel() (defined in BaseChannel)BaseChannelinlinevirtual
+ + + + diff --git a/struct_base_channel.html b/struct_base_channel.html new file mode 100644 index 0000000..f0d927b --- /dev/null +++ b/struct_base_channel.html @@ -0,0 +1,180 @@ + + + + + + +pva2pva: BaseChannel Struct Reference + + + + + + + + + +
+
+ + + + + + +
+
pva2pva +  1.4.1 +
+
+
+ + + + + + + + + +
+ +
+ +
+
+ +
+
BaseChannel Struct Reference
+
+
+
+Inheritance diagram for BaseChannel:
+
+
Inheritance graph
+ + +
[legend]
+
+Collaboration diagram for BaseChannel:
+
+
Collaboration graph
+
[legend]
+ + + + +

+Public Types

+typedef epicsGuard< epicsMutex > guard_t
 
+ + + + + + + + + + + + + + + + + + + +

+Public Member Functions

BaseChannel (const std::string &name, const std::tr1::weak_ptr< epics::pvAccess::ChannelProvider > &prov, const epics::pvAccess::ChannelRequester::shared_pointer &req, const epics::pvData::StructureConstPtr &dtype)
 
+virtual std::string getRequesterName () OVERRIDE
 
+virtual void destroy () OVERRIDE FINAL
 
+virtual std::tr1::shared_ptr
+< epics::pvAccess::ChannelProvider > 
getProvider () OVERRIDE FINAL
 
+virtual std::string getRemoteAddress () OVERRIDE
 
+virtual std::string getChannelName () OVERRIDE FINAL
 
+virtual std::tr1::shared_ptr
+< epics::pvAccess::ChannelRequester > 
getChannelRequester () OVERRIDE FINAL
 
+virtual void getField (epics::pvAccess::GetFieldRequester::shared_pointer const &requester, std::string const &subField) OVERRIDE
 
+virtual void printInfo (std::ostream &out) OVERRIDE
 
+ + + + + + + + + + + +

+Public Attributes

+epicsMutex lock
 
+const std::string pvname
 
+const
+epics::pvAccess::ChannelProvider::weak_pointer 
provider
 
+const requester_type::weak_pointer requester
 
+const
+epics::pvData::StructureConstPtr 
fielddesc
 
+

Detailed Description

+
+

Definition at line 19 of file pvahelper.h.

+

The documentation for this struct was generated from the following file: +
+ + + + diff --git a/struct_base_channel__coll__graph.map b/struct_base_channel__coll__graph.map new file mode 100644 index 0000000..0a54029 --- /dev/null +++ b/struct_base_channel__coll__graph.map @@ -0,0 +1,2 @@ + + diff --git a/struct_base_channel__coll__graph.md5 b/struct_base_channel__coll__graph.md5 new file mode 100644 index 0000000..21866c0 --- /dev/null +++ b/struct_base_channel__coll__graph.md5 @@ -0,0 +1 @@ +ebcad8780f5b5a97bcf99f46503f36f3 \ No newline at end of file diff --git a/struct_base_channel__coll__graph.png b/struct_base_channel__coll__graph.png new file mode 100644 index 0000000..f962926 Binary files /dev/null and b/struct_base_channel__coll__graph.png differ diff --git a/struct_base_channel__inherit__graph.map b/struct_base_channel__inherit__graph.map new file mode 100644 index 0000000..d634fb7 --- /dev/null +++ b/struct_base_channel__inherit__graph.map @@ -0,0 +1,5 @@ + + + + + diff --git a/struct_base_channel__inherit__graph.md5 b/struct_base_channel__inherit__graph.md5 new file mode 100644 index 0000000..66a07e8 --- /dev/null +++ b/struct_base_channel__inherit__graph.md5 @@ -0,0 +1 @@ +c6748908d104a7637f9fccb67293c091 \ No newline at end of file diff --git a/struct_base_channel__inherit__graph.png b/struct_base_channel__inherit__graph.png new file mode 100644 index 0000000..766fc4a Binary files /dev/null and b/struct_base_channel__inherit__graph.png differ diff --git a/struct_base_channel_provider_factory-members.html b/struct_base_channel_provider_factory-members.html new file mode 100644 index 0000000..7d78980 --- /dev/null +++ b/struct_base_channel_provider_factory-members.html @@ -0,0 +1,110 @@ + + + + + + +pva2pva: Member List + + + + + + + + + +
+
+ + + + + + +
+
pva2pva +  1.4.1 +
+
+
+ + + + + + + + + +
+ +
+ +
+
+
+
BaseChannelProviderFactory< CP > Member List
+
+
+ +

This is the complete list of members for BaseChannelProviderFactory< CP >, including all inherited members.

+ + + + + + + + + + +
BaseChannelProviderFactory(const char *name) (defined in BaseChannelProviderFactory< CP >)BaseChannelProviderFactory< CP >inline
getFactoryName() (defined in BaseChannelProviderFactory< CP >)BaseChannelProviderFactory< CP >inlinevirtual
last_shared (defined in BaseChannelProviderFactory< CP >)BaseChannelProviderFactory< CP >
lock (defined in BaseChannelProviderFactory< CP >)BaseChannelProviderFactory< CP >
name (defined in BaseChannelProviderFactory< CP >)BaseChannelProviderFactory< CP >
newInstance(const std::tr1::shared_ptr< epics::pvAccess::Configuration > &) (defined in BaseChannelProviderFactory< CP >)BaseChannelProviderFactory< CP >inlinevirtual
provider_type typedef (defined in BaseChannelProviderFactory< CP >)BaseChannelProviderFactory< CP >
sharedInstance() (defined in BaseChannelProviderFactory< CP >)BaseChannelProviderFactory< CP >inlinevirtual
~BaseChannelProviderFactory() (defined in BaseChannelProviderFactory< CP >)BaseChannelProviderFactory< CP >inlinevirtual
+ + + + diff --git a/struct_base_channel_provider_factory.html b/struct_base_channel_provider_factory.html new file mode 100644 index 0000000..9b301d3 --- /dev/null +++ b/struct_base_channel_provider_factory.html @@ -0,0 +1,158 @@ + + + + + + +pva2pva: BaseChannelProviderFactory< CP > Struct Template Reference + + + + + + + + + +
+
+ + + + + + +
+
pva2pva +  1.4.1 +
+
+
+ + + + + + + + + +
+ +
+ +
+
+ +
+
BaseChannelProviderFactory< CP > Struct Template Reference
+
+
+
+Inheritance diagram for BaseChannelProviderFactory< CP >:
+
+
Inheritance graph
+
[legend]
+
+Collaboration diagram for BaseChannelProviderFactory< CP >:
+
+
Collaboration graph
+
[legend]
+ + + + +

+Public Types

+typedef CP provider_type
 
+ + + + + + + + + +

+Public Member Functions

BaseChannelProviderFactory (const char *name)
 
+virtual std::string getFactoryName ()
 
+virtual
+epics::pvAccess::ChannelProvider::shared_pointer 
sharedInstance ()
 
+virtual
+epics::pvAccess::ChannelProvider::shared_pointer 
newInstance (const std::tr1::shared_ptr< epics::pvAccess::Configuration > &)
 
+ + + + + + + +

+Public Attributes

+std::string name
 
+epicsMutex lock
 
+std::tr1::weak_ptr< CP > last_shared
 
+

Detailed Description

+

template<class CP>
+struct BaseChannelProviderFactory< CP >

+ + +

Definition at line 351 of file pvahelper.h.

+

The documentation for this struct was generated from the following file: +
+ + + + diff --git a/struct_base_channel_provider_factory__coll__graph.map b/struct_base_channel_provider_factory__coll__graph.map new file mode 100644 index 0000000..eb95b42 --- /dev/null +++ b/struct_base_channel_provider_factory__coll__graph.map @@ -0,0 +1,2 @@ + + diff --git a/struct_base_channel_provider_factory__coll__graph.md5 b/struct_base_channel_provider_factory__coll__graph.md5 new file mode 100644 index 0000000..5179ac1 --- /dev/null +++ b/struct_base_channel_provider_factory__coll__graph.md5 @@ -0,0 +1 @@ +6df3c9c141dc31d4b391983b367c2049 \ No newline at end of file diff --git a/struct_base_channel_provider_factory__coll__graph.png b/struct_base_channel_provider_factory__coll__graph.png new file mode 100644 index 0000000..c1b5f1e Binary files /dev/null and b/struct_base_channel_provider_factory__coll__graph.png differ diff --git a/struct_base_channel_provider_factory__inherit__graph.map b/struct_base_channel_provider_factory__inherit__graph.map new file mode 100644 index 0000000..eb95b42 --- /dev/null +++ b/struct_base_channel_provider_factory__inherit__graph.map @@ -0,0 +1,2 @@ + + diff --git a/struct_base_channel_provider_factory__inherit__graph.md5 b/struct_base_channel_provider_factory__inherit__graph.md5 new file mode 100644 index 0000000..5179ac1 --- /dev/null +++ b/struct_base_channel_provider_factory__inherit__graph.md5 @@ -0,0 +1 @@ +6df3c9c141dc31d4b391983b367c2049 \ No newline at end of file diff --git a/struct_base_channel_provider_factory__inherit__graph.png b/struct_base_channel_provider_factory__inherit__graph.png new file mode 100644 index 0000000..c1b5f1e Binary files /dev/null and b/struct_base_channel_provider_factory__inherit__graph.png differ diff --git a/struct_base_monitor-members.html b/struct_base_monitor-members.html new file mode 100644 index 0000000..5ecfc97 --- /dev/null +++ b/struct_base_monitor-members.html @@ -0,0 +1,121 @@ + + + + + + +pva2pva: Member List + + + + + + + + + +
+
+ + + + + + +
+
pva2pva +  1.4.1 +
+
+
+ + + + + + + + + +
+ +
+ +
+
+
+
BaseMonitor Member List
+
+
+ +

This is the complete list of members for BaseMonitor, including all inherited members.

+ + + + + + + + + + + + + + + + + + + + + +
BaseMonitor(epicsMutex &lock, const requester_t::weak_pointer &requester, const epics::pvData::PVStructure::shared_pointer &pvReq) (defined in BaseMonitor)BaseMonitorinline
connect(guard_t &guard, const epics::pvData::PVStructurePtr &value)BaseMonitorinline
destroy() (defined in BaseMonitor)BaseMonitorinlinevirtual
getStats(Stats &s) const (defined in BaseMonitor)BaseMonitorinlinevirtual
getValue() (defined in BaseMonitor)BaseMonitorinline
guard_t typedef (defined in BaseMonitor)BaseMonitor
lock (defined in BaseMonitor)BaseMonitor
onStart() (defined in BaseMonitor)BaseMonitorinlinevirtual
onStop() (defined in BaseMonitor)BaseMonitorinlinevirtual
POINTER_DEFINITIONS(BaseMonitor) (defined in BaseMonitor)BaseMonitor
post(guard_t &guard, const epics::pvData::BitSet &updated, no_overflow)BaseMonitorinline
post(guard_t &guard)BaseMonitorinline
post(guard_t &guard, const epics::pvData::BitSet &updated, const epics::pvData::BitSet &overflowed)BaseMonitorinline
post(guard_t &guard, const epics::pvData::BitSet &updated)BaseMonitorinline
requester_t typedef (defined in BaseMonitor)BaseMonitor
requestUpdate()BaseMonitorinlinevirtual
shared_from_this() (defined in BaseMonitor)BaseMonitorinline
unguard_t typedef (defined in BaseMonitor)BaseMonitor
weakself (defined in BaseMonitor)BaseMonitor
~BaseMonitor() (defined in BaseMonitor)BaseMonitorinlinevirtual
+ + + + diff --git a/struct_base_monitor.html b/struct_base_monitor.html new file mode 100644 index 0000000..1df90cf --- /dev/null +++ b/struct_base_monitor.html @@ -0,0 +1,293 @@ + + + + + + +pva2pva: BaseMonitor Struct Reference + + + + + + + + + +
+
+ + + + + + +
+
pva2pva +  1.4.1 +
+
+
+ + + + + + + + + +
+ +
+ +
+
+ +
+
BaseMonitor Struct Reference
+
+
+ +

#include <pvahelper.h>

+
+Inheritance diagram for BaseMonitor:
+
+
Inheritance graph
+ + +
[legend]
+
+Collaboration diagram for BaseMonitor:
+
+
Collaboration graph
+
[legend]
+ + + + +

+Classes

struct  no_overflow
 
+ + + + + + + +

+Public Types

+typedef
+epics::pvAccess::MonitorRequester 
requester_t
 
+typedef epicsGuard< epicsMutex > guard_t
 
+typedef epicsGuardRelease
+< epicsMutex > 
unguard_t
 
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Public Member Functions

POINTER_DEFINITIONS (BaseMonitor)
 
+shared_pointer shared_from_this ()
 
BaseMonitor (epicsMutex &lock, const requester_t::weak_pointer &requester, const epics::pvData::PVStructure::shared_pointer &pvReq)
 
+const
+epics::pvData::PVStructurePtr & 
getValue ()
 
void connect (guard_t &guard, const epics::pvData::PVStructurePtr &value)
 
+bool post (guard_t &guard, const epics::pvData::BitSet &updated, no_overflow)
 post update if queue not full, if full return false w/o overflow
 
+bool post (guard_t &guard)
 post update of pending changes. eg. call from requestUpdate()
 
+bool post (guard_t &guard, const epics::pvData::BitSet &updated, const epics::pvData::BitSet &overflowed)
 post update with changed and overflowed masks (eg. when updates were lost in some upstream queue)
 
+bool post (guard_t &guard, const epics::pvData::BitSet &updated)
 post update with changed
 
+virtual void onStart ()
 
+virtual void onStop ()
 
virtual void requestUpdate ()
 
+virtual void destroy ()
 
+virtual void getStats (Stats &s) const
 
+ + + + + +

+Public Attributes

+weak_pointer weakself
 
+epicsMutex & lock
 
+

Detailed Description

+

Helper which implements a Monitor queue. connect()s to a complete copy of a PVStructure. When this struct has changed, post(BitSet) should be called.

+

Derived class may use onStart(), onStop(), and requestUpdate() to react to subscriber events.

+ +

Definition at line 69 of file pvahelper.h.

+

Member Function Documentation

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
void BaseMonitor::connect (guard_t & guard,
const epics::pvData::PVStructurePtr & value 
)
+
+inline
+
+

Must call before first post(). Sets .complete and calls monitorConnect()

+
Note
that value will never by accessed except by post() and requestUpdate()
+ +

Definition at line 110 of file pvahelper.h.

+
111  {
+
112  guard.assertIdenticalMutex(lock);
+
113  epics::pvData::StructureConstPtr dtype(value->getStructure());
+
114  epics::pvData::PVDataCreatePtr create(epics::pvData::getPVDataCreate());
+
115  BaseMonitor::shared_pointer self(shared_from_this());
+
116  requester_t::shared_pointer req(requester.lock());
+
117 
+
118  assert(!complete); // can't call twice
+
119 
+
120  complete = value;
+
121  empty.resize(nbuffers);
+
122  for(size_t i=0; i<empty.size(); i++) {
+
123  empty[i].reset(new epics::pvAccess::MonitorElement(create->createPVStructure(dtype)));
+
124  }
+
125 
+
126  if(req) {
+
127  unguard_t U(guard);
+
128  epics::pvData::Status sts;
+
129  req->monitorConnect(sts, self, dtype);
+
130  }
+
131  }
+
+
+
+ +
+
+ + + + + +
+ + + + + + + +
virtual void BaseMonitor::requestUpdate ()
+
+inlinevirtual
+
+

called when within release() when the opportunity exists to end the overflow condition May do nothing, or lock and call post()

+ +

Reimplemented in PDBGroupMonitor, and PDBSingleMonitor.

+ +

Definition at line 271 of file pvahelper.h.

+
271 {guard_t G(lock); post(G);}
+
bool post(guard_t &guard, const epics::pvData::BitSet &updated, no_overflow)
post update if queue not full, if full return false w/o overflow
Definition: pvahelper.h:136
+
+
+
+
The documentation for this struct was generated from the following file: +
+ + + + diff --git a/struct_base_monitor_1_1no__overflow.html b/struct_base_monitor_1_1no__overflow.html new file mode 100644 index 0000000..fc5748c --- /dev/null +++ b/struct_base_monitor_1_1no__overflow.html @@ -0,0 +1,108 @@ + + + + + + +pva2pva: BaseMonitor::no_overflow Struct Reference + + + + + + + + + +
+
+ + + + + + +
+
pva2pva +  1.4.1 +
+
+
+ + + + + + + + + +
+ +
+ + +
+
+
+
BaseMonitor::no_overflow Struct Reference
+
+
+

Detailed Description

+
+

Definition at line 133 of file pvahelper.h.

+

The documentation for this struct was generated from the following file: +
+ + + + diff --git a/struct_base_monitor__coll__graph.map b/struct_base_monitor__coll__graph.map new file mode 100644 index 0000000..6f78e05 --- /dev/null +++ b/struct_base_monitor__coll__graph.map @@ -0,0 +1,2 @@ + + diff --git a/struct_base_monitor__coll__graph.md5 b/struct_base_monitor__coll__graph.md5 new file mode 100644 index 0000000..757450a --- /dev/null +++ b/struct_base_monitor__coll__graph.md5 @@ -0,0 +1 @@ +9bec16926cf082cebd95eaf02e9651b7 \ No newline at end of file diff --git a/struct_base_monitor__coll__graph.png b/struct_base_monitor__coll__graph.png new file mode 100644 index 0000000..fca0b62 Binary files /dev/null and b/struct_base_monitor__coll__graph.png differ diff --git a/struct_base_monitor__inherit__graph.map b/struct_base_monitor__inherit__graph.map new file mode 100644 index 0000000..21e4f7c --- /dev/null +++ b/struct_base_monitor__inherit__graph.map @@ -0,0 +1,4 @@ + + + + diff --git a/struct_base_monitor__inherit__graph.md5 b/struct_base_monitor__inherit__graph.md5 new file mode 100644 index 0000000..89fb8c7 --- /dev/null +++ b/struct_base_monitor__inherit__graph.md5 @@ -0,0 +1 @@ +a4965d29b916fab80b5fae9a6e523c63 \ No newline at end of file diff --git a/struct_base_monitor__inherit__graph.png b/struct_base_monitor__inherit__graph.png new file mode 100644 index 0000000..5493dd0 Binary files /dev/null and b/struct_base_monitor__inherit__graph.png differ diff --git a/struct_channel_cache-members.html b/struct_channel_cache-members.html new file mode 100644 index 0000000..54974b8 --- /dev/null +++ b/struct_channel_cache-members.html @@ -0,0 +1,113 @@ + + + + + + +pva2pva: Member List + + + + + + + + + +
+
+ + + + + + +
+
pva2pva +  1.4.1 +
+
+
+ + + + + + + + + +
+ +
+ +
+
+
+
ChannelCache Member List
+
+
+ +

This is the complete list of members for ChannelCache, including all inherited members.

+ + + + + + + + + + + + + +
cacheLock (defined in ChannelCache)ChannelCache
ChannelCache(const epics::pvAccess::ChannelProvider::shared_pointer &prov) (defined in ChannelCache)ChannelCache
cleaner (defined in ChannelCache)ChannelCache
cleanerDust (defined in ChannelCache)ChannelCache
cleanerRuns (defined in ChannelCache)ChannelCache
cleanTimer (defined in ChannelCache)ChannelCache
entries (defined in ChannelCache)ChannelCache
entries_t typedef (defined in ChannelCache)ChannelCache
lookup(const std::string &name) (defined in ChannelCache)ChannelCache
provider (defined in ChannelCache)ChannelCache
timerQueue (defined in ChannelCache)ChannelCache
~ChannelCache() (defined in ChannelCache)ChannelCache
+ + + + diff --git a/struct_channel_cache.html b/struct_channel_cache.html new file mode 100644 index 0000000..071bf76 --- /dev/null +++ b/struct_channel_cache.html @@ -0,0 +1,170 @@ + + + + + + +pva2pva: ChannelCache Struct Reference + + + + + + + + + +
+
+ + + + + + +
+
pva2pva +  1.4.1 +
+
+
+ + + + + + + + + +
+ +
+ +
+
+ +
+
ChannelCache Struct Reference
+
+
+ +

#include <chancache.h>

+
+Collaboration diagram for ChannelCache:
+
+
Collaboration graph
+ + +
[legend]
+ + + + +

+Classes

struct  cacheClean
 
+ + + +

+Public Types

+typedef std::map< std::string,
+ChannelCacheEntry::shared_pointer > 
entries_t
 
+ + + + + +

+Public Member Functions

ChannelCache (const epics::pvAccess::ChannelProvider::shared_pointer &prov)
 
+ChannelCacheEntry::shared_pointer lookup (const std::string &name)
 
+ + + + + + + + + + + + + + + + + +

+Public Attributes

+epicsMutex cacheLock
 
+entries_t entries
 
+epics::pvAccess::ChannelProvider::shared_pointer provider
 
+epicsTimerQueueActive * timerQueue
 
+epicsTimer * cleanTimer
 
+cacheCleancleaner
 
+size_t cleanerRuns
 
+size_t cleanerDust
 
+

Detailed Description

+

Holds the set of channels the GW is searching for, or has found.

+ +

Definition at line 151 of file chancache.h.

+

The documentation for this struct was generated from the following files: +
+ + + + diff --git a/struct_channel_cache_1_1cache_clean-members.html b/struct_channel_cache_1_1cache_clean-members.html new file mode 100644 index 0000000..3debdbb --- /dev/null +++ b/struct_channel_cache_1_1cache_clean-members.html @@ -0,0 +1,108 @@ + + + + + + +pva2pva: Member List + + + + + + + + + +
+
+ + + + + + +
+
pva2pva +  1.4.1 +
+
+
+ + + + + + + + + +
+ +
+ + +
+
+
+
ChannelCache::cacheClean Member List
+
+
+ +

This is the complete list of members for ChannelCache::cacheClean, including all inherited members.

+ + + + +
cache (defined in ChannelCache::cacheClean)ChannelCache::cacheClean
cacheClean(ChannelCache *c) (defined in ChannelCache::cacheClean)ChannelCache::cacheCleaninline
expire(const epicsTime &currentTime) (defined in ChannelCache::cacheClean)ChannelCache::cacheCleaninline
+ + + + diff --git a/struct_channel_cache_1_1cache_clean.html b/struct_channel_cache_1_1cache_clean.html new file mode 100644 index 0000000..31bbd23 --- /dev/null +++ b/struct_channel_cache_1_1cache_clean.html @@ -0,0 +1,140 @@ + + + + + + +pva2pva: ChannelCache::cacheClean Struct Reference + + + + + + + + + +
+
+ + + + + + +
+
pva2pva +  1.4.1 +
+
+
+ + + + + + + + + +
+ +
+ + +
+
+ +
+
ChannelCache::cacheClean Struct Reference
+
+
+
+Inheritance diagram for ChannelCache::cacheClean:
+
+
Inheritance graph
+
[legend]
+
+Collaboration diagram for ChannelCache::cacheClean:
+
+
Collaboration graph
+ + +
[legend]
+ + + + + + +

+Public Member Functions

cacheClean (ChannelCache *c)
 
+epicsTimerNotify::expireStatus expire (const epicsTime &currentTime)
 
+ + + +

+Public Attributes

+ChannelCachecache
 
+

Detailed Description

+
+

Definition at line 102 of file chancache.cpp.

+

The documentation for this struct was generated from the following file: +
+ + + + diff --git a/struct_channel_cache_1_1cache_clean__coll__graph.map b/struct_channel_cache_1_1cache_clean__coll__graph.map new file mode 100644 index 0000000..59dc1b0 --- /dev/null +++ b/struct_channel_cache_1_1cache_clean__coll__graph.map @@ -0,0 +1,3 @@ + + + diff --git a/struct_channel_cache_1_1cache_clean__coll__graph.md5 b/struct_channel_cache_1_1cache_clean__coll__graph.md5 new file mode 100644 index 0000000..c12dd80 --- /dev/null +++ b/struct_channel_cache_1_1cache_clean__coll__graph.md5 @@ -0,0 +1 @@ +beaf1b066deb6032961387c292579351 \ No newline at end of file diff --git a/struct_channel_cache_1_1cache_clean__coll__graph.png b/struct_channel_cache_1_1cache_clean__coll__graph.png new file mode 100644 index 0000000..d9b2bc0 Binary files /dev/null and b/struct_channel_cache_1_1cache_clean__coll__graph.png differ diff --git a/struct_channel_cache_1_1cache_clean__inherit__graph.map b/struct_channel_cache_1_1cache_clean__inherit__graph.map new file mode 100644 index 0000000..5fe1835 --- /dev/null +++ b/struct_channel_cache_1_1cache_clean__inherit__graph.map @@ -0,0 +1,2 @@ + + diff --git a/struct_channel_cache_1_1cache_clean__inherit__graph.md5 b/struct_channel_cache_1_1cache_clean__inherit__graph.md5 new file mode 100644 index 0000000..bb5aaaa --- /dev/null +++ b/struct_channel_cache_1_1cache_clean__inherit__graph.md5 @@ -0,0 +1 @@ +a4d6464eb72604b2d3a5908f8f2e5694 \ No newline at end of file diff --git a/struct_channel_cache_1_1cache_clean__inherit__graph.png b/struct_channel_cache_1_1cache_clean__inherit__graph.png new file mode 100644 index 0000000..c39794a Binary files /dev/null and b/struct_channel_cache_1_1cache_clean__inherit__graph.png differ diff --git a/struct_channel_cache__coll__graph.map b/struct_channel_cache__coll__graph.map new file mode 100644 index 0000000..fecacde --- /dev/null +++ b/struct_channel_cache__coll__graph.map @@ -0,0 +1,3 @@ + + + diff --git a/struct_channel_cache__coll__graph.md5 b/struct_channel_cache__coll__graph.md5 new file mode 100644 index 0000000..0150234 --- /dev/null +++ b/struct_channel_cache__coll__graph.md5 @@ -0,0 +1 @@ +dd0609ddf8e924817b5a1f06ec72d95a \ No newline at end of file diff --git a/struct_channel_cache__coll__graph.png b/struct_channel_cache__coll__graph.png new file mode 100644 index 0000000..228ca56 Binary files /dev/null and b/struct_channel_cache__coll__graph.png differ diff --git a/struct_channel_cache_entry-members.html b/struct_channel_cache_entry-members.html new file mode 100644 index 0000000..cfe6e6c --- /dev/null +++ b/struct_channel_cache_entry-members.html @@ -0,0 +1,116 @@ + + + + + + +pva2pva: Member List + + + + + + + + + +
+
+ + + + + + +
+
pva2pva +  1.4.1 +
+
+
+ + + + + + + + + +
+ +
+ +
+
+
+
ChannelCacheEntry Member List
+
+
+ +

This is the complete list of members for ChannelCacheEntry, including all inherited members.

+ + + + + + + + + + + + + + + + +
cache (defined in ChannelCacheEntry)ChannelCacheEntry
channel (defined in ChannelCacheEntry)ChannelCacheEntry
ChannelCacheEntry(ChannelCache *, const std::string &n) (defined in ChannelCacheEntry)ChannelCacheEntry
channelName (defined in ChannelCacheEntry)ChannelCacheEntry
dropPoke (defined in ChannelCacheEntry)ChannelCacheEntry
interested (defined in ChannelCacheEntry)ChannelCacheEntry
interested_t typedef (defined in ChannelCacheEntry)ChannelCacheEntry
mon_entries (defined in ChannelCacheEntry)ChannelCacheEntry
mon_entries_t typedef (defined in ChannelCacheEntry)ChannelCacheEntry
mutex() const (defined in ChannelCacheEntry)ChannelCacheEntryinline
num_instances (defined in ChannelCacheEntry)ChannelCacheEntrystatic
POINTER_DEFINITIONS(ChannelCacheEntry) (defined in ChannelCacheEntry)ChannelCacheEntry
pvrequest_t typedef (defined in ChannelCacheEntry)ChannelCacheEntry
requester (defined in ChannelCacheEntry)ChannelCacheEntry
~ChannelCacheEntry() (defined in ChannelCacheEntry)ChannelCacheEntryvirtual
+ + + + diff --git a/struct_channel_cache_entry.html b/struct_channel_cache_entry.html new file mode 100644 index 0000000..121b38d --- /dev/null +++ b/struct_channel_cache_entry.html @@ -0,0 +1,182 @@ + + + + + + +pva2pva: ChannelCacheEntry Struct Reference + + + + + + + + + +
+
+ + + + + + +
+
pva2pva +  1.4.1 +
+
+
+ + + + + + + + + +
+ +
+ +
+ +
+
+Collaboration diagram for ChannelCacheEntry:
+
+
Collaboration graph
+ + +
[legend]
+ + + + +

+Classes

struct  CRequester
 
+ + + + + + + +

+Public Types

+typedef weak_set< GWChannelinterested_t
 
+typedef
+MonitorCacheEntry::pvrequest_t 
pvrequest_t
 
+typedef weak_value_map
+< pvrequest_t,
+MonitorCacheEntry
mon_entries_t
 
+ + + + + + + +

+Public Member Functions

POINTER_DEFINITIONS (ChannelCacheEntry)
 
+epicsMutex & mutex () const
 
ChannelCacheEntry (ChannelCache *, const std::string &n)
 
+ + + + + + + + + + + + + + + +

+Public Attributes

+const std::string channelName
 
+ChannelCache *const cache
 
+epics::pvAccess::Channel::shared_pointer channel
 
+epics::pvAccess::ChannelRequester::shared_pointer requester
 
+bool dropPoke
 
+interested_t interested
 
+mon_entries_t mon_entries
 
+ + + +

+Static Public Attributes

+static size_t num_instances
 
+

Detailed Description

+
+

Definition at line 103 of file chancache.h.

+

The documentation for this struct was generated from the following files: +
+ + + + diff --git a/struct_channel_cache_entry_1_1_c_requester-members.html b/struct_channel_cache_entry_1_1_c_requester-members.html new file mode 100644 index 0000000..5b979a3 --- /dev/null +++ b/struct_channel_cache_entry_1_1_c_requester-members.html @@ -0,0 +1,112 @@ + + + + + + +pva2pva: Member List + + + + + + + + + +
+
+ + + + + + +
+
pva2pva +  1.4.1 +
+
+
+ + + + + + + + + +
+ +
+ + +
+
+
+
ChannelCacheEntry::CRequester Member List
+
+
+ +

This is the complete list of members for ChannelCacheEntry::CRequester, including all inherited members.

+ + + + + + + + +
chan (defined in ChannelCacheEntry::CRequester)ChannelCacheEntry::CRequester
channelCreated(const epics::pvData::Status &status, epics::pvAccess::Channel::shared_pointer const &channel) (defined in ChannelCacheEntry::CRequester)ChannelCacheEntry::CRequestervirtual
channelStateChange(epics::pvAccess::Channel::shared_pointer const &channel, epics::pvAccess::Channel::ConnectionState connectionState) (defined in ChannelCacheEntry::CRequester)ChannelCacheEntry::CRequestervirtual
CRequester(const ChannelCacheEntry::shared_pointer &p) (defined in ChannelCacheEntry::CRequester)ChannelCacheEntry::CRequester
getRequesterName() (defined in ChannelCacheEntry::CRequester)ChannelCacheEntry::CRequestervirtual
num_instances (defined in ChannelCacheEntry::CRequester)ChannelCacheEntry::CRequesterstatic
~CRequester() (defined in ChannelCacheEntry::CRequester)ChannelCacheEntry::CRequestervirtual
+ + + + diff --git a/struct_channel_cache_entry_1_1_c_requester.html b/struct_channel_cache_entry_1_1_c_requester.html new file mode 100644 index 0000000..7228f8b --- /dev/null +++ b/struct_channel_cache_entry_1_1_c_requester.html @@ -0,0 +1,156 @@ + + + + + + +pva2pva: ChannelCacheEntry::CRequester Struct Reference + + + + + + + + + +
+
+ + + + + + +
+
pva2pva +  1.4.1 +
+
+
+ + + + + + + + + +
+ +
+ + +
+
+ +
+
ChannelCacheEntry::CRequester Struct Reference
+
+
+
+Inheritance diagram for ChannelCacheEntry::CRequester:
+
+
Inheritance graph
+ + +
[legend]
+
+Collaboration diagram for ChannelCacheEntry::CRequester:
+
+
Collaboration graph
+ + +
[legend]
+ + + + + + + + + + +

+Public Member Functions

CRequester (const ChannelCacheEntry::shared_pointer &p)
 
+virtual std::string getRequesterName ()
 
+virtual void channelCreated (const epics::pvData::Status &status, epics::pvAccess::Channel::shared_pointer const &channel)
 
+virtual void channelStateChange (epics::pvAccess::Channel::shared_pointer const &channel, epics::pvAccess::Channel::ConnectionState connectionState)
 
+ + + +

+Public Attributes

+ChannelCacheEntry::weak_pointer chan
 
+ + + +

+Static Public Attributes

+static size_t num_instances
 
+

Detailed Description

+
+

Definition at line 132 of file chancache.h.

+

The documentation for this struct was generated from the following files: +
+ + + + diff --git a/struct_channel_cache_entry_1_1_c_requester__coll__graph.map b/struct_channel_cache_entry_1_1_c_requester__coll__graph.map new file mode 100644 index 0000000..4449dc1 --- /dev/null +++ b/struct_channel_cache_entry_1_1_c_requester__coll__graph.map @@ -0,0 +1,2 @@ + + diff --git a/struct_channel_cache_entry_1_1_c_requester__coll__graph.md5 b/struct_channel_cache_entry_1_1_c_requester__coll__graph.md5 new file mode 100644 index 0000000..d785009 --- /dev/null +++ b/struct_channel_cache_entry_1_1_c_requester__coll__graph.md5 @@ -0,0 +1 @@ +28296036f805238230f051c4baad01f5 \ No newline at end of file diff --git a/struct_channel_cache_entry_1_1_c_requester__coll__graph.png b/struct_channel_cache_entry_1_1_c_requester__coll__graph.png new file mode 100644 index 0000000..3fe5f33 Binary files /dev/null and b/struct_channel_cache_entry_1_1_c_requester__coll__graph.png differ diff --git a/struct_channel_cache_entry_1_1_c_requester__inherit__graph.map b/struct_channel_cache_entry_1_1_c_requester__inherit__graph.map new file mode 100644 index 0000000..4449dc1 --- /dev/null +++ b/struct_channel_cache_entry_1_1_c_requester__inherit__graph.map @@ -0,0 +1,2 @@ + + diff --git a/struct_channel_cache_entry_1_1_c_requester__inherit__graph.md5 b/struct_channel_cache_entry_1_1_c_requester__inherit__graph.md5 new file mode 100644 index 0000000..d785009 --- /dev/null +++ b/struct_channel_cache_entry_1_1_c_requester__inherit__graph.md5 @@ -0,0 +1 @@ +28296036f805238230f051c4baad01f5 \ No newline at end of file diff --git a/struct_channel_cache_entry_1_1_c_requester__inherit__graph.png b/struct_channel_cache_entry_1_1_c_requester__inherit__graph.png new file mode 100644 index 0000000..3fe5f33 Binary files /dev/null and b/struct_channel_cache_entry_1_1_c_requester__inherit__graph.png differ diff --git a/struct_channel_cache_entry__coll__graph.map b/struct_channel_cache_entry__coll__graph.map new file mode 100644 index 0000000..1d1d4fd --- /dev/null +++ b/struct_channel_cache_entry__coll__graph.map @@ -0,0 +1,6 @@ + + + + + + diff --git a/struct_channel_cache_entry__coll__graph.md5 b/struct_channel_cache_entry__coll__graph.md5 new file mode 100644 index 0000000..f471200 --- /dev/null +++ b/struct_channel_cache_entry__coll__graph.md5 @@ -0,0 +1 @@ +71ebd1a2c65ce8d94912bbd7f0ac52f8 \ No newline at end of file diff --git a/struct_channel_cache_entry__coll__graph.png b/struct_channel_cache_entry__coll__graph.png new file mode 100644 index 0000000..fd33e26 Binary files /dev/null and b/struct_channel_cache_entry__coll__graph.png differ diff --git a/struct_d_b_c_h-members.html b/struct_d_b_c_h-members.html new file mode 100644 index 0000000..b707f94 --- /dev/null +++ b/struct_d_b_c_h-members.html @@ -0,0 +1,111 @@ + + + + + + +pva2pva: Member List + + + + + + + + + +
+
+ + + + + + +
+
pva2pva +  1.4.1 +
+
+
+ + + + + + + + + +
+ +
+ +
+
+
+
DBCH Member List
+
+
+ +

This is the complete list of members for DBCH, including all inherited members.

+ + + + + + + + + + + +
chan (defined in DBCH)DBCH
DBCH() (defined in DBCH)DBCHinline
DBCH(dbChannel *ch) (defined in DBCH)DBCHexplicit
DBCH(const std::string &name) (defined in DBCH)DBCHexplicit
operator const dbChannel *() const (defined in DBCH)DBCHinline
operator dbChannel *() (defined in DBCH)DBCHinline
operator->() (defined in DBCH)DBCHinline
operator->() const (defined in DBCH)DBCHinline
swap(DBCH &) (defined in DBCH)DBCH
~DBCH() (defined in DBCH)DBCH
+ + + + diff --git a/struct_d_b_c_h.html b/struct_d_b_c_h.html new file mode 100644 index 0000000..5f6b43f --- /dev/null +++ b/struct_d_b_c_h.html @@ -0,0 +1,140 @@ + + + + + + +pva2pva: DBCH Struct Reference + + + + + + + + + +
+
+ + + + + + +
+
pva2pva +  1.4.1 +
+
+
+ + + + + + + + + +
+ +
+ +
+ +
+ + + + + + + + + + + + + + + + +

+Public Member Functions

DBCH (dbChannel *ch)
 
DBCH (const std::string &name)
 
+void swap (DBCH &)
 
operator dbChannel * ()
 
operator const dbChannel * () const
 
+dbChannel * operator-> ()
 
+const dbChannel * operator-> () const
 
+ + + +

+Public Attributes

+dbChannel * chan
 
+

Detailed Description

+
+

Definition at line 81 of file pvif.h.

+

The documentation for this struct was generated from the following files: +
+ + + + diff --git a/struct_d_b_event-members.html b/struct_d_b_event-members.html new file mode 100644 index 0000000..51e73b4 --- /dev/null +++ b/struct_d_b_event-members.html @@ -0,0 +1,112 @@ + + + + + + +pva2pva: Member List + + + + + + + + + +
+
+ + + + + + +
+
pva2pva +  1.4.1 +
+
+
+ + + + + + + + + +
+ +
+ +
+
+
+
DBEvent Member List
+
+
+ +

This is the complete list of members for DBEvent, including all inherited members.

+ + + + + + + + + + + + +
chan (defined in DBEvent)DBEvent
create(dbEventCtx ctx, dbChannel *ch, EVENTFUNC *fn, unsigned mask) (defined in DBEvent)DBEventinline
dbe_mask (defined in DBEvent)DBEvent
DBEvent() (defined in DBEvent)DBEventinline
DBEvent(void *s) (defined in DBEvent)DBEventinline
destroy() (defined in DBEvent)DBEventinline
index (defined in DBEvent)DBEvent
operator!() const (defined in DBEvent)DBEventinline
self (defined in DBEvent)DBEvent
subscript (defined in DBEvent)DBEvent
~DBEvent() (defined in DBEvent)DBEventinline
+ + + + diff --git a/struct_d_b_event.html b/struct_d_b_event.html new file mode 100644 index 0000000..6d5bad0 --- /dev/null +++ b/struct_d_b_event.html @@ -0,0 +1,142 @@ + + + + + + +pva2pva: DBEvent Struct Reference + + + + + + + + + +
+
+ + + + + + +
+
pva2pva +  1.4.1 +
+
+
+ + + + + + + + + +
+ +
+ +
+
+ +
+
DBEvent Struct Reference
+
+
+ + + + + + + + + + +

+Public Member Functions

DBEvent (void *s)
 
+void create (dbEventCtx ctx, dbChannel *ch, EVENTFUNC *fn, unsigned mask)
 
+void destroy ()
 
+bool operator! () const
 
+ + + + + + + + + + + +

+Public Attributes

+dbEventSubscription subscript
 
+unsigned dbe_mask
 
+void * self
 
+unsigned index
 
+dbChannel * chan
 
+

Detailed Description

+
+

Definition at line 223 of file pvif.h.

+

The documentation for this struct was generated from the following file: +
+ + + + diff --git a/struct_d_b_scan_locker-members.html b/struct_d_b_scan_locker-members.html new file mode 100644 index 0000000..7a6c0d0 --- /dev/null +++ b/struct_d_b_scan_locker-members.html @@ -0,0 +1,105 @@ + + + + + + +pva2pva: Member List + + + + + + + + + +
+
+ + + + + + +
+
pva2pva +  1.4.1 +
+
+
+ + + + + + + + + +
+ +
+ +
+
+
+
DBScanLocker Member List
+
+
+ +

This is the complete list of members for DBScanLocker, including all inherited members.

+ + + + + +
DBScanLocker(dbChannel *chan) (defined in DBScanLocker)DBScanLockerinline
DBScanLocker(dbCommon *prec) (defined in DBScanLocker)DBScanLockerinline
prec (defined in DBScanLocker)DBScanLocker
~DBScanLocker() (defined in DBScanLocker)DBScanLockerinline
+ + + + diff --git a/struct_d_b_scan_locker.html b/struct_d_b_scan_locker.html new file mode 100644 index 0000000..9fa6851 --- /dev/null +++ b/struct_d_b_scan_locker.html @@ -0,0 +1,124 @@ + + + + + + +pva2pva: DBScanLocker Struct Reference + + + + + + + + + +
+
+ + + + + + +
+
pva2pva +  1.4.1 +
+
+
+ + + + + + + + + +
+ +
+ +
+
+ +
+
DBScanLocker Struct Reference
+
+
+ + + + + + +

+Public Member Functions

DBScanLocker (dbChannel *chan)
 
DBScanLocker (dbCommon *prec)
 
+ + + +

+Public Attributes

+dbCommon * prec
 
+

Detailed Description

+
+

Definition at line 273 of file pvif.h.

+

The documentation for this struct was generated from the following file: +
+ + + + diff --git a/struct_field_name-members.html b/struct_field_name-members.html new file mode 100644 index 0000000..ec4d34f --- /dev/null +++ b/struct_field_name-members.html @@ -0,0 +1,112 @@ + + + + + + +pva2pva: Member List + + + + + + + + + +
+
+ + + + + + +
+
pva2pva +  1.4.1 +
+
+
+ + + + + + + + + +
+ +
+ +
+
+
+
FieldName Member List
+
+
+ +

This is the complete list of members for FieldName, including all inherited members.

+ + + + + + + + + + + + +
back() const (defined in FieldName)FieldNameinline
empty() const (defined in FieldName)FieldNameinline
FieldName() (defined in FieldName)FieldNameinline
FieldName(const std::string &) (defined in FieldName)FieldNameexplicit
lookup(const epics::pvData::PVStructurePtr &S, epics::pvData::PVField **ppenclose) const (defined in FieldName)FieldName
operator[](size_t i) const (defined in FieldName)FieldNameinline
parts (defined in FieldName)FieldName
parts_t typedef (defined in FieldName)FieldName
show() const (defined in FieldName)FieldName
size() const (defined in FieldName)FieldNameinline
swap(FieldName &o) (defined in FieldName)FieldNameinline
+ + + + diff --git a/struct_field_name.html b/struct_field_name.html new file mode 100644 index 0000000..d36c798 --- /dev/null +++ b/struct_field_name.html @@ -0,0 +1,156 @@ + + + + + + +pva2pva: FieldName Struct Reference + + + + + + + + + +
+
+ + + + + + +
+
pva2pva +  1.4.1 +
+
+
+ + + + + + + + + +
+ +
+ +
+
+ +
+
FieldName Struct Reference
+
+
+ + + + +

+Classes

struct  Component
 
+ + + +

+Public Types

+typedef std::vector< Componentparts_t
 
+ + + + + + + + + + + + + + + + + +

+Public Member Functions

FieldName (const std::string &)
 
+void swap (FieldName &o)
 
+bool empty () const
 
+size_t size () const
 
+const Componentoperator[] (size_t i) const
 
+const Componentback () const
 
+epics::pvData::PVFieldPtr lookup (const epics::pvData::PVStructurePtr &S, epics::pvData::PVField **ppenclose) const
 
+void show () const
 
+ + + +

+Public Attributes

+parts_t parts
 
+

Detailed Description

+
+

Definition at line 322 of file pvif.h.

+

The documentation for this struct was generated from the following files: +
+ + + + diff --git a/struct_field_name_1_1_component-members.html b/struct_field_name_1_1_component-members.html new file mode 100644 index 0000000..e0285ea --- /dev/null +++ b/struct_field_name_1_1_component-members.html @@ -0,0 +1,111 @@ + + + + + + +pva2pva: Member List + + + + + + + + + +
+
+ + + + + + +
+
pva2pva +  1.4.1 +
+
+
+ + + + + + + + + +
+ +
+ + +
+
+
+
FieldName::Component Member List
+
+
+ +

This is the complete list of members for FieldName::Component, including all inherited members.

+ + + + + + + +
__pad0__ (defined in FieldName::Component)FieldName::Component
Component() (defined in FieldName::Component)FieldName::Componentinline
index (defined in FieldName::Component)FieldName::Component
index(index) (defined in FieldName::Component)FieldName::Componentinline
isArray() const (defined in FieldName::Component)FieldName::Componentinline
name (defined in FieldName::Component)FieldName::Component
+ + + + diff --git a/struct_field_name_1_1_component.html b/struct_field_name_1_1_component.html new file mode 100644 index 0000000..9ba2d90 --- /dev/null +++ b/struct_field_name_1_1_component.html @@ -0,0 +1,134 @@ + + + + + + +pva2pva: FieldName::Component Struct Reference + + + + + + + + + +
+
+ + + + + + +
+
pva2pva +  1.4.1 +
+
+
+ + + + + + + + + +
+ +
+ + +
+
+ +
+
FieldName::Component Struct Reference
+
+
+ + + + + + +

+Public Member Functions

index (index)
 
+bool isArray () const
 
+ + + + + + + +

+Public Attributes

+std::string name
 
+epicsUInt32 index
 
__pad0__:name(name)
 
+

Detailed Description

+
+

Definition at line 324 of file pvif.h.

+

The documentation for this struct was generated from the following file: +
+ + + + diff --git a/struct_g_w_channel-members.html b/struct_g_w_channel-members.html new file mode 100644 index 0000000..94285f0 --- /dev/null +++ b/struct_g_w_channel-members.html @@ -0,0 +1,127 @@ + + + + + + +pva2pva: Member List + + + + + + + + + +
+
+ + + + + + +
+
pva2pva +  1.4.1 +
+
+
+ + + + + + + + + +
+ +
+ +
+
+
+
GWChannel Member List
+
+
+ +

This is the complete list of members for GWChannel, including all inherited members.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
address (defined in GWChannel)GWChannel
createChannelArray(epics::pvAccess::ChannelArrayRequester::shared_pointer const &channelArrayRequester, epics::pvData::PVStructure::shared_pointer const &pvRequest) (defined in GWChannel)GWChannelvirtual
createChannelGet(epics::pvAccess::ChannelGetRequester::shared_pointer const &channelGetRequester, epics::pvData::PVStructure::shared_pointer const &pvRequest) (defined in GWChannel)GWChannelvirtual
createChannelProcess(epics::pvAccess::ChannelProcessRequester::shared_pointer const &channelProcessRequester, epics::pvData::PVStructure::shared_pointer const &pvRequest) (defined in GWChannel)GWChannelvirtual
createChannelPut(epics::pvAccess::ChannelPutRequester::shared_pointer const &channelPutRequester, epics::pvData::PVStructure::shared_pointer const &pvRequest) (defined in GWChannel)GWChannelvirtual
createChannelPutGet(epics::pvAccess::ChannelPutGetRequester::shared_pointer const &channelPutGetRequester, epics::pvData::PVStructure::shared_pointer const &pvRequest) (defined in GWChannel)GWChannelvirtual
createChannelRPC(epics::pvAccess::ChannelRPCRequester::shared_pointer const &channelRPCRequester, epics::pvData::PVStructure::shared_pointer const &pvRequest) (defined in GWChannel)GWChannelvirtual
createMonitor(epics::pvData::MonitorRequester::shared_pointer const &monitorRequester, epics::pvData::PVStructure::shared_pointer const &pvRequest) (defined in GWChannel)GWChannelvirtual
destroy() (defined in GWChannel)GWChannelvirtual
entry (defined in GWChannel)GWChannel
getAccessRights(epics::pvData::PVField::shared_pointer const &pvField) (defined in GWChannel)GWChannelvirtual
getChannelName() (defined in GWChannel)GWChannelvirtual
getChannelRequester() (defined in GWChannel)GWChannelvirtual
getConnectionState() (defined in GWChannel)GWChannelvirtual
getField(epics::pvAccess::GetFieldRequester::shared_pointer const &requester, std::string const &subField) (defined in GWChannel)GWChannelvirtual
getProvider() (defined in GWChannel)GWChannelvirtual
getRemoteAddress() (defined in GWChannel)GWChannelvirtual
getRequesterName() (defined in GWChannel)GWChannelvirtual
GWChannel(const ChannelCacheEntry::shared_pointer &e, const epics::pvAccess::ChannelProvider::weak_pointer &srvprov, const requester_type::weak_pointer &, const std::string &addr) (defined in GWChannel)GWChannel
num_instances (defined in GWChannel)GWChannelstatic
POINTER_DEFINITIONS(GWChannel) (defined in GWChannel)GWChannel
printInfo(std::ostream &out) (defined in GWChannel)GWChannelvirtual
requester (defined in GWChannel)GWChannel
server_provder (defined in GWChannel)GWChannel
weakref (defined in GWChannel)GWChannel
~GWChannel() (defined in GWChannel)GWChannelvirtual
+ + + + diff --git a/struct_g_w_channel.html b/struct_g_w_channel.html new file mode 100644 index 0000000..22fcd17 --- /dev/null +++ b/struct_g_w_channel.html @@ -0,0 +1,217 @@ + + + + + + +pva2pva: GWChannel Struct Reference + + + + + + + + + +
+
+ + + + + + +
+
pva2pva +  1.4.1 +
+
+
+ + + + + + + + + +
+ +
+ +
+ +
+
+Inheritance diagram for GWChannel:
+
+
Inheritance graph
+
[legend]
+
+Collaboration diagram for GWChannel:
+
+
Collaboration graph
+
[legend]
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Public Member Functions

POINTER_DEFINITIONS (GWChannel)
 
GWChannel (const ChannelCacheEntry::shared_pointer &e, const epics::pvAccess::ChannelProvider::weak_pointer &srvprov, const requester_type::weak_pointer &, const std::string &addr)
 
+virtual std::string getRequesterName ()
 
+virtual void destroy ()
 
+virtual std::tr1::shared_ptr
+< epics::pvAccess::ChannelProvider > 
getProvider ()
 
+virtual std::string getRemoteAddress ()
 
+virtual ConnectionState getConnectionState ()
 
+virtual std::string getChannelName ()
 
+virtual std::tr1::shared_ptr
+< epics::pvAccess::ChannelRequester > 
getChannelRequester ()
 
+virtual void getField (epics::pvAccess::GetFieldRequester::shared_pointer const &requester, std::string const &subField)
 
+virtual
+epics::pvAccess::AccessRights 
getAccessRights (epics::pvData::PVField::shared_pointer const &pvField)
 
+virtual
+epics::pvAccess::ChannelProcess::shared_pointer 
createChannelProcess (epics::pvAccess::ChannelProcessRequester::shared_pointer const &channelProcessRequester, epics::pvData::PVStructure::shared_pointer const &pvRequest)
 
+virtual
+epics::pvAccess::ChannelGet::shared_pointer 
createChannelGet (epics::pvAccess::ChannelGetRequester::shared_pointer const &channelGetRequester, epics::pvData::PVStructure::shared_pointer const &pvRequest)
 
+virtual
+epics::pvAccess::ChannelPut::shared_pointer 
createChannelPut (epics::pvAccess::ChannelPutRequester::shared_pointer const &channelPutRequester, epics::pvData::PVStructure::shared_pointer const &pvRequest)
 
+virtual
+epics::pvAccess::ChannelPutGet::shared_pointer 
createChannelPutGet (epics::pvAccess::ChannelPutGetRequester::shared_pointer const &channelPutGetRequester, epics::pvData::PVStructure::shared_pointer const &pvRequest)
 
+virtual
+epics::pvAccess::ChannelRPC::shared_pointer 
createChannelRPC (epics::pvAccess::ChannelRPCRequester::shared_pointer const &channelRPCRequester, epics::pvData::PVStructure::shared_pointer const &pvRequest)
 
+virtual
+epics::pvData::Monitor::shared_pointer 
createMonitor (epics::pvData::MonitorRequester::shared_pointer const &monitorRequester, epics::pvData::PVStructure::shared_pointer const &pvRequest)
 
+virtual
+epics::pvAccess::ChannelArray::shared_pointer 
createChannelArray (epics::pvAccess::ChannelArrayRequester::shared_pointer const &channelArrayRequester, epics::pvData::PVStructure::shared_pointer const &pvRequest)
 
+virtual void printInfo (std::ostream &out)
 
+ + + + + + + + + + + +

+Public Attributes

+weak_pointer weakref
 
+const
+ChannelCacheEntry::shared_pointer 
entry
 
+const requester_type::weak_pointer requester
 
+const std::string address
 
+const
+epics::pvAccess::ChannelProvider::weak_pointer 
server_provder
 
+ + + +

+Static Public Attributes

+static size_t num_instances
 
+

Detailed Description

+
+

Definition at line 8 of file channel.h.

+

The documentation for this struct was generated from the following files: +
+ + + + diff --git a/struct_g_w_channel__coll__graph.map b/struct_g_w_channel__coll__graph.map new file mode 100644 index 0000000..530c431 --- /dev/null +++ b/struct_g_w_channel__coll__graph.map @@ -0,0 +1,2 @@ + + diff --git a/struct_g_w_channel__coll__graph.md5 b/struct_g_w_channel__coll__graph.md5 new file mode 100644 index 0000000..be8ca34 --- /dev/null +++ b/struct_g_w_channel__coll__graph.md5 @@ -0,0 +1 @@ +e934d05e08425536a8955787022740f7 \ No newline at end of file diff --git a/struct_g_w_channel__coll__graph.png b/struct_g_w_channel__coll__graph.png new file mode 100644 index 0000000..5a92cdf Binary files /dev/null and b/struct_g_w_channel__coll__graph.png differ diff --git a/struct_g_w_channel__inherit__graph.map b/struct_g_w_channel__inherit__graph.map new file mode 100644 index 0000000..530c431 --- /dev/null +++ b/struct_g_w_channel__inherit__graph.map @@ -0,0 +1,2 @@ + + diff --git a/struct_g_w_channel__inherit__graph.md5 b/struct_g_w_channel__inherit__graph.md5 new file mode 100644 index 0000000..be8ca34 --- /dev/null +++ b/struct_g_w_channel__inherit__graph.md5 @@ -0,0 +1 @@ +e934d05e08425536a8955787022740f7 \ No newline at end of file diff --git a/struct_g_w_channel__inherit__graph.png b/struct_g_w_channel__inherit__graph.png new file mode 100644 index 0000000..5a92cdf Binary files /dev/null and b/struct_g_w_channel__inherit__graph.png differ diff --git a/struct_g_w_server_channel_provider-members.html b/struct_g_w_server_channel_provider-members.html new file mode 100644 index 0000000..2d9c420 --- /dev/null +++ b/struct_g_w_server_channel_provider-members.html @@ -0,0 +1,111 @@ + + + + + + +pva2pva: Member List + + + + + + + + + +
+
+ + + + + + +
+
pva2pva +  1.4.1 +
+
+
+ + + + + + + + + +
+ +
+ +
+
+
+
GWServerChannelProvider Member List
+
+
+ +

This is the complete list of members for GWServerChannelProvider, including all inherited members.

+ + + + + + + + + + + +
cache (defined in GWServerChannelProvider)GWServerChannelProvider
cancel() (defined in GWServerChannelProvider)GWServerChannelProviderinlinevirtual
channelFind(std::string const &channelName, epics::pvAccess::ChannelFindRequester::shared_pointer const &channelFindRequester) (defined in GWServerChannelProvider)GWServerChannelProvidervirtual
createChannel(std::string const &channelName, epics::pvAccess::ChannelRequester::shared_pointer const &channelRequester, short priority, std::string const &addressx) (defined in GWServerChannelProvider)GWServerChannelProvidervirtual
destroy() (defined in GWServerChannelProvider)GWServerChannelProvidervirtual
getChannelProvider() (defined in GWServerChannelProvider)GWServerChannelProvidervirtual
getProviderName() (defined in GWServerChannelProvider)GWServerChannelProviderinlinevirtual
GWServerChannelProvider(const epics::pvAccess::ChannelProvider::shared_pointer &prov) (defined in GWServerChannelProvider)GWServerChannelProviderexplicit
POINTER_DEFINITIONS(GWServerChannelProvider) (defined in GWServerChannelProvider)GWServerChannelProvider
~GWServerChannelProvider() (defined in GWServerChannelProvider)GWServerChannelProvidervirtual
+ + + + diff --git a/struct_g_w_server_channel_provider.html b/struct_g_w_server_channel_provider.html new file mode 100644 index 0000000..cf65469 --- /dev/null +++ b/struct_g_w_server_channel_provider.html @@ -0,0 +1,160 @@ + + + + + + +pva2pva: GWServerChannelProvider Struct Reference + + + + + + + + + +
+
+ + + + + + +
+
pva2pva +  1.4.1 +
+
+
+ + + + + + + + + +
+ +
+ +
+
+ +
+
GWServerChannelProvider Struct Reference
+
+
+
+Inheritance diagram for GWServerChannelProvider:
+
+
Inheritance graph
+ + +
[legend]
+
+Collaboration diagram for GWServerChannelProvider:
+
+
Collaboration graph
+ + +
[legend]
+ + + + + + + + + + + + + + + + + + +

+Public Member Functions

POINTER_DEFINITIONS (GWServerChannelProvider)
 
+virtual std::tr1::shared_ptr
+< ChannelProvider > 
getChannelProvider ()
 
+virtual void cancel ()
 
+virtual std::string getProviderName ()
 
+virtual
+epics::pvAccess::ChannelFind::shared_pointer 
channelFind (std::string const &channelName, epics::pvAccess::ChannelFindRequester::shared_pointer const &channelFindRequester)
 
+virtual
+epics::pvAccess::Channel::shared_pointer 
createChannel (std::string const &channelName, epics::pvAccess::ChannelRequester::shared_pointer const &channelRequester, short priority, std::string const &addressx)
 
+virtual void destroy ()
 
GWServerChannelProvider (const epics::pvAccess::ChannelProvider::shared_pointer &prov)
 
+ + + +

+Public Attributes

+ChannelCache cache
 
+

Detailed Description

+
+

Definition at line 9 of file server.h.

+

The documentation for this struct was generated from the following files: +
+ + + + diff --git a/struct_g_w_server_channel_provider__coll__graph.map b/struct_g_w_server_channel_provider__coll__graph.map new file mode 100644 index 0000000..ff26c15 --- /dev/null +++ b/struct_g_w_server_channel_provider__coll__graph.map @@ -0,0 +1,4 @@ + + + + diff --git a/struct_g_w_server_channel_provider__coll__graph.md5 b/struct_g_w_server_channel_provider__coll__graph.md5 new file mode 100644 index 0000000..0028527 --- /dev/null +++ b/struct_g_w_server_channel_provider__coll__graph.md5 @@ -0,0 +1 @@ +72e7285ff5abe413dfae04bd61b17271 \ No newline at end of file diff --git a/struct_g_w_server_channel_provider__coll__graph.png b/struct_g_w_server_channel_provider__coll__graph.png new file mode 100644 index 0000000..019aa20 Binary files /dev/null and b/struct_g_w_server_channel_provider__coll__graph.png differ diff --git a/struct_g_w_server_channel_provider__inherit__graph.map b/struct_g_w_server_channel_provider__inherit__graph.map new file mode 100644 index 0000000..c1d79ce --- /dev/null +++ b/struct_g_w_server_channel_provider__inherit__graph.map @@ -0,0 +1,2 @@ + + diff --git a/struct_g_w_server_channel_provider__inherit__graph.md5 b/struct_g_w_server_channel_provider__inherit__graph.md5 new file mode 100644 index 0000000..6c38274 --- /dev/null +++ b/struct_g_w_server_channel_provider__inherit__graph.md5 @@ -0,0 +1 @@ +695b45b64deffe77a65a97cc5b3e94c4 \ No newline at end of file diff --git a/struct_g_w_server_channel_provider__inherit__graph.png b/struct_g_w_server_channel_provider__inherit__graph.png new file mode 100644 index 0000000..07ee728 Binary files /dev/null and b/struct_g_w_server_channel_provider__inherit__graph.png differ diff --git a/struct_group_config-members.html b/struct_group_config-members.html new file mode 100644 index 0000000..5cf038b --- /dev/null +++ b/struct_group_config-members.html @@ -0,0 +1,106 @@ + + + + + + +pva2pva: Member List + + + + + + + + + +
+
+ + + + + + +
+
pva2pva +  1.4.1 +
+
+
+ + + + + + + + + +
+ +
+ +
+
+
+
GroupConfig Member List
+
+
+ +

This is the complete list of members for GroupConfig, including all inherited members.

+ + + + + + +
groups (defined in GroupConfig)GroupConfig
groups_t typedef (defined in GroupConfig)GroupConfig
parse(const char *txt, const char *recname, GroupConfig &result) (defined in GroupConfig)GroupConfigstatic
swap(GroupConfig &o) (defined in GroupConfig)GroupConfiginline
warning (defined in GroupConfig)GroupConfig
+ + + + diff --git a/struct_group_config.html b/struct_group_config.html new file mode 100644 index 0000000..a87b69f --- /dev/null +++ b/struct_group_config.html @@ -0,0 +1,148 @@ + + + + + + +pva2pva: GroupConfig Struct Reference + + + + + + + + + +
+
+ + + + + + +
+
pva2pva +  1.4.1 +
+
+
+ + + + + + + + + +
+ +
+ +
+ +
+ + + + + + +

+Classes

struct  Field
 
struct  Group
 
+ + + +

+Public Types

+typedef std::map< std::string,
+Group
groups_t
 
+ + + +

+Public Member Functions

+void swap (GroupConfig &o)
 
+ + + +

+Static Public Member Functions

+static void parse (const char *txt, const char *recname, GroupConfig &result)
 
+ + + + + +

+Public Attributes

+groups_t groups
 
+std::string warning
 
+

Detailed Description

+
+

Definition at line 20 of file pdbgroup.h.

+

The documentation for this struct was generated from the following files: +
+ + + + diff --git a/struct_group_config_1_1_field-members.html b/struct_group_config_1_1_field-members.html new file mode 100644 index 0000000..9f4fa75 --- /dev/null +++ b/struct_group_config_1_1_field-members.html @@ -0,0 +1,112 @@ + + + + + + +pva2pva: Member List + + + + + + + + + +
+
+ + + + + + +
+
pva2pva +  1.4.1 +
+
+
+ + + + + + + + + +
+ +
+ + +
+
+
+
GroupConfig::Field Member List
+
+
+ +

This is the complete list of members for GroupConfig::Field, including all inherited members.

+ + + + + + + + +
channel (defined in GroupConfig::Field)GroupConfig::Field
Field() (defined in GroupConfig::Field)GroupConfig::Fieldinline
id (defined in GroupConfig::Field)GroupConfig::Field
putorder (defined in GroupConfig::Field)GroupConfig::Field
swap(Field &o) (defined in GroupConfig::Field)GroupConfig::Fieldinline
trigger (defined in GroupConfig::Field)GroupConfig::Field
type (defined in GroupConfig::Field)GroupConfig::Field
+ + + + diff --git a/struct_group_config_1_1_field.html b/struct_group_config_1_1_field.html new file mode 100644 index 0000000..7588325 --- /dev/null +++ b/struct_group_config_1_1_field.html @@ -0,0 +1,137 @@ + + + + + + +pva2pva: GroupConfig::Field Struct Reference + + + + + + + + + +
+
+ + + + + + +
+
pva2pva +  1.4.1 +
+
+
+ + + + + + + + + +
+ +
+ + +
+
+ +
+
GroupConfig::Field Struct Reference
+
+
+ + + + +

+Public Member Functions

+void swap (Field &o)
 
+ + + + + + + + + + + +

+Public Attributes

+std::string type
 
+std::string channel
 
+std::string trigger
 
+std::string id
 
+int putorder
 
+

Detailed Description

+
+

Definition at line 22 of file pdbgroup.h.

+

The documentation for this struct was generated from the following file: +
+ + + + diff --git a/struct_group_config_1_1_group-members.html b/struct_group_config_1_1_group-members.html new file mode 100644 index 0000000..d480212 --- /dev/null +++ b/struct_group_config_1_1_group-members.html @@ -0,0 +1,112 @@ + + + + + + +pva2pva: Member List + + + + + + + + + +
+
+ + + + + + +
+
pva2pva +  1.4.1 +
+
+
+ + + + + + + + + +
+ +
+ + +
+
+
+
GroupConfig::Group Member List
+
+
+ +

This is the complete list of members for GroupConfig::Group, including all inherited members.

+ + + + + + + + +
atomic (defined in GroupConfig::Group)GroupConfig::Group
atomic_set (defined in GroupConfig::Group)GroupConfig::Group
fields (defined in GroupConfig::Group)GroupConfig::Group
fields_t typedef (defined in GroupConfig::Group)GroupConfig::Group
Group() (defined in GroupConfig::Group)GroupConfig::Groupinline
id (defined in GroupConfig::Group)GroupConfig::Group
swap(Group &o) (defined in GroupConfig::Group)GroupConfig::Groupinline
+ + + + diff --git a/struct_group_config_1_1_group.html b/struct_group_config_1_1_group.html new file mode 100644 index 0000000..688a874 --- /dev/null +++ b/struct_group_config_1_1_group.html @@ -0,0 +1,142 @@ + + + + + + +pva2pva: GroupConfig::Group Struct Reference + + + + + + + + + +
+
+ + + + + + +
+
pva2pva +  1.4.1 +
+
+
+ + + + + + + + + +
+ +
+ + +
+
+ +
+
GroupConfig::Group Struct Reference
+
+
+ + + + +

+Public Types

+typedef std::map< std::string,
+Field
fields_t
 
+ + + +

+Public Member Functions

+void swap (Group &o)
 
+ + + + + + + + + +

+Public Attributes

+fields_t fields
 
+bool atomic
 
+bool atomic_set
 
+std::string id
 
+

Detailed Description

+
+

Definition at line 37 of file pdbgroup.h.

+

The documentation for this struct was generated from the following file: +
+ + + + diff --git a/struct_local_f_l-members.html b/struct_local_f_l-members.html new file mode 100644 index 0000000..202c49c --- /dev/null +++ b/struct_local_f_l-members.html @@ -0,0 +1,105 @@ + + + + + + +pva2pva: Member List + + + + + + + + + +
+
+ + + + + + +
+
pva2pva +  1.4.1 +
+
+
+ + + + + + + + + +
+ +
+ +
+
+
+
LocalFL Member List
+
+
+ +

This is the complete list of members for LocalFL, including all inherited members.

+ + + + + +
LocalFL(db_field_log *pfl, dbChannel *pchan) (defined in LocalFL)LocalFLinline
ours (defined in LocalFL)LocalFL
pfl (defined in LocalFL)LocalFL
~LocalFL() (defined in LocalFL)LocalFLinline
+ + + + diff --git a/struct_local_f_l.html b/struct_local_f_l.html new file mode 100644 index 0000000..ee0938e --- /dev/null +++ b/struct_local_f_l.html @@ -0,0 +1,124 @@ + + + + + + +pva2pva: LocalFL Struct Reference + + + + + + + + + +
+
+ + + + + + +
+
pva2pva +  1.4.1 +
+
+
+ + + + + + + + + +
+ +
+ +
+
+ +
+
LocalFL Struct Reference
+
+
+ + + + +

+Public Member Functions

LocalFL (db_field_log *pfl, dbChannel *pchan)
 
+ + + + + +

+Public Attributes

+db_field_log * pfl
 
+bool ours
 
+

Detailed Description

+
+

Definition at line 250 of file pvif.h.

+

The documentation for this struct was generated from the following file: +
+ + + + diff --git a/struct_monitor_cache_entry-members.html b/struct_monitor_cache_entry-members.html new file mode 100644 index 0000000..1f55461 --- /dev/null +++ b/struct_monitor_cache_entry-members.html @@ -0,0 +1,124 @@ + + + + + + +pva2pva: Member List + + + + + + + + + +
+
+ + + + + + +
+
pva2pva +  1.4.1 +
+
+
+ + + + + + + + + +
+ +
+ +
+
+
+
MonitorCacheEntry Member List
+
+
+ +

This is the complete list of members for MonitorCacheEntry, including all inherited members.

+ + + + + + + + + + + + + + + + + + + + + + + + +
bufferSize (defined in MonitorCacheEntry)MonitorCacheEntry
chan (defined in MonitorCacheEntry)MonitorCacheEntry
done (defined in MonitorCacheEntry)MonitorCacheEntry
getRequesterName() (defined in MonitorCacheEntry)MonitorCacheEntryvirtual
havedata (defined in MonitorCacheEntry)MonitorCacheEntry
interested (defined in MonitorCacheEntry)MonitorCacheEntry
interested_t typedef (defined in MonitorCacheEntry)MonitorCacheEntry
lastelemMonitorCacheEntry
mon (defined in MonitorCacheEntry)MonitorCacheEntry
MonitorCacheEntry(ChannelCacheEntry *ent, const epics::pvData::PVStructure::shared_pointer &pvr) (defined in MonitorCacheEntry)MonitorCacheEntry
monitorConnect(epics::pvData::Status const &status, epics::pvData::MonitorPtr const &monitor, epics::pvData::StructureConstPtr const &structure) (defined in MonitorCacheEntry)MonitorCacheEntryvirtual
monitorEvent(epics::pvData::MonitorPtr const &monitor) (defined in MonitorCacheEntry)MonitorCacheEntryvirtual
mutex() const (defined in MonitorCacheEntry)MonitorCacheEntryinline
nevents (defined in MonitorCacheEntry)MonitorCacheEntry
num_instances (defined in MonitorCacheEntry)MonitorCacheEntrystatic
nwakeups (defined in MonitorCacheEntry)MonitorCacheEntry
POINTER_DEFINITIONS(MonitorCacheEntry) (defined in MonitorCacheEntry)MonitorCacheEntry
pvrequest_t typedef (defined in MonitorCacheEntry)MonitorCacheEntry
startresult (defined in MonitorCacheEntry)MonitorCacheEntry
typedesc (defined in MonitorCacheEntry)MonitorCacheEntry
unlisten(epics::pvData::MonitorPtr const &monitor) (defined in MonitorCacheEntry)MonitorCacheEntryvirtual
weakref (defined in MonitorCacheEntry)MonitorCacheEntry
~MonitorCacheEntry() (defined in MonitorCacheEntry)MonitorCacheEntryvirtual
+ + + + diff --git a/struct_monitor_cache_entry.html b/struct_monitor_cache_entry.html new file mode 100644 index 0000000..e0357ea --- /dev/null +++ b/struct_monitor_cache_entry.html @@ -0,0 +1,217 @@ + + + + + + +pva2pva: MonitorCacheEntry Struct Reference + + + + + + + + + +
+
+ + + + + + +
+
pva2pva +  1.4.1 +
+
+
+ + + + + + + + + +
+ +
+ +
+ +
+
+Inheritance diagram for MonitorCacheEntry:
+
+
Inheritance graph
+
[legend]
+
+Collaboration diagram for MonitorCacheEntry:
+
+
Collaboration graph
+ + +
[legend]
+ + + + + + +

+Public Types

+typedef std::vector< epicsUInt8 > pvrequest_t
 
+typedef weak_set< MonitorUserinterested_t
 
+ + + + + + + + + + + + + + + +

+Public Member Functions

POINTER_DEFINITIONS (MonitorCacheEntry)
 
+epicsMutex & mutex () const
 
MonitorCacheEntry (ChannelCacheEntry *ent, const epics::pvData::PVStructure::shared_pointer &pvr)
 
+virtual void monitorConnect (epics::pvData::Status const &status, epics::pvData::MonitorPtr const &monitor, epics::pvData::StructureConstPtr const &structure)
 
+virtual void monitorEvent (epics::pvData::MonitorPtr const &monitor)
 
+virtual void unlisten (epics::pvData::MonitorPtr const &monitor)
 
+virtual std::string getRequesterName ()
 
+ + + + + + + + + + + + + + + + + + + + + + + + + +

+Public Attributes

+weak_pointer weakref
 
+ChannelCacheEntry *const chan
 
+const size_t bufferSize
 
+bool havedata
 
+bool done
 
+size_t nwakeups
 
+size_t nevents
 
+epics::pvData::StructureConstPtr typedesc
 
epics::pvData::MonitorElement::shared_pointer lastelem
 
+epics::pvData::MonitorPtr mon
 
+epics::pvData::Status startresult
 
+interested_t interested
 
+ + + +

+Static Public Attributes

+static size_t num_instances
 
+

Detailed Description

+
+

Definition at line 22 of file chancache.h.

+

Member Data Documentation

+ +
+
+ + + + +
epics::pvData::MonitorElement::shared_pointer MonitorCacheEntry::lastelem
+
+

value of upstream monitor (accumulation of all deltas) changed/overflow bit masks of last delta

+ +

Definition at line 46 of file chancache.h.

+ +
+
+
The documentation for this struct was generated from the following files: +
+ + + + diff --git a/struct_monitor_cache_entry__coll__graph.map b/struct_monitor_cache_entry__coll__graph.map new file mode 100644 index 0000000..b7ff1a9 --- /dev/null +++ b/struct_monitor_cache_entry__coll__graph.map @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/struct_monitor_cache_entry__coll__graph.md5 b/struct_monitor_cache_entry__coll__graph.md5 new file mode 100644 index 0000000..9627e47 --- /dev/null +++ b/struct_monitor_cache_entry__coll__graph.md5 @@ -0,0 +1 @@ +a12bf28b5c29fe2d8ddc0d8d32846c50 \ No newline at end of file diff --git a/struct_monitor_cache_entry__coll__graph.png b/struct_monitor_cache_entry__coll__graph.png new file mode 100644 index 0000000..0447207 Binary files /dev/null and b/struct_monitor_cache_entry__coll__graph.png differ diff --git a/struct_monitor_cache_entry__inherit__graph.map b/struct_monitor_cache_entry__inherit__graph.map new file mode 100644 index 0000000..4256c4b --- /dev/null +++ b/struct_monitor_cache_entry__inherit__graph.map @@ -0,0 +1,2 @@ + + diff --git a/struct_monitor_cache_entry__inherit__graph.md5 b/struct_monitor_cache_entry__inherit__graph.md5 new file mode 100644 index 0000000..df060d5 --- /dev/null +++ b/struct_monitor_cache_entry__inherit__graph.md5 @@ -0,0 +1 @@ +d05ff58af12878bd053f0c3463304ae0 \ No newline at end of file diff --git a/struct_monitor_cache_entry__inherit__graph.png b/struct_monitor_cache_entry__inherit__graph.png new file mode 100644 index 0000000..bc39503 Binary files /dev/null and b/struct_monitor_cache_entry__inherit__graph.png differ diff --git a/struct_monitor_user-members.html b/struct_monitor_user-members.html new file mode 100644 index 0000000..bf2cf7b --- /dev/null +++ b/struct_monitor_user-members.html @@ -0,0 +1,126 @@ + + + + + + +pva2pva: Member List + + + + + + + + + +
+
+ + + + + + +
+
pva2pva +  1.4.1 +
+
+
+ + + + + + + + + +
+ +
+ +
+
+
+
MonitorUser Member List
+
+
+ +

This is the complete list of members for MonitorUser, including all inherited members.

+ + + + + + + + + + + + + + + + + + + + + + + + + + +
destroy() (defined in MonitorUser)MonitorUservirtual
empty (defined in MonitorUser)MonitorUser
entry (defined in MonitorUser)MonitorUser
filled (defined in MonitorUser)MonitorUser
getRequesterName() (defined in MonitorUser)MonitorUservirtual
initial (defined in MonitorUser)MonitorUser
inoverflow (defined in MonitorUser)MonitorUser
inuse (defined in MonitorUser)MonitorUser
MonitorUser(const MonitorCacheEntry::shared_pointer &) (defined in MonitorUser)MonitorUser
mutex() const (defined in MonitorUser)MonitorUserinline
ndropped (defined in MonitorUser)MonitorUser
nevents (defined in MonitorUser)MonitorUser
num_instances (defined in MonitorUser)MonitorUserstatic
nwakeups (defined in MonitorUser)MonitorUser
overflowElement (defined in MonitorUser)MonitorUser
POINTER_DEFINITIONS(MonitorUser) (defined in MonitorUser)MonitorUser
poll() (defined in MonitorUser)MonitorUservirtual
release(epics::pvData::MonitorElementPtr const &monitorElement) (defined in MonitorUser)MonitorUservirtual
req (defined in MonitorUser)MonitorUser
running (defined in MonitorUser)MonitorUser
srvchan (defined in MonitorUser)MonitorUser
start() (defined in MonitorUser)MonitorUservirtual
stop() (defined in MonitorUser)MonitorUservirtual
weakref (defined in MonitorUser)MonitorUser
~MonitorUser() (defined in MonitorUser)MonitorUservirtual
+ + + + diff --git a/struct_monitor_user.html b/struct_monitor_user.html new file mode 100644 index 0000000..f786095 --- /dev/null +++ b/struct_monitor_user.html @@ -0,0 +1,206 @@ + + + + + + +pva2pva: MonitorUser Struct Reference + + + + + + + + + +
+
+ + + + + + +
+
pva2pva +  1.4.1 +
+
+
+ + + + + + + + + +
+ +
+ +
+ +
+
+Inheritance diagram for MonitorUser:
+
+
Inheritance graph
+
[legend]
+
+Collaboration diagram for MonitorUser:
+
+
Collaboration graph
+
[legend]
+ + + + + + + + + + + + + + + + + + + + +

+Public Member Functions

POINTER_DEFINITIONS (MonitorUser)
 
+epicsMutex & mutex () const
 
MonitorUser (const MonitorCacheEntry::shared_pointer &)
 
+virtual void destroy ()
 
+virtual epics::pvData::Status start ()
 
+virtual epics::pvData::Status stop ()
 
+virtual
+epics::pvData::MonitorElementPtr 
poll ()
 
+virtual void release (epics::pvData::MonitorElementPtr const &monitorElement)
 
+virtual std::string getRequesterName ()
 
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Public Attributes

+weak_pointer weakref
 
+MonitorCacheEntry::shared_pointer entry
 
+epics::pvData::MonitorRequester::weak_pointer req
 
+std::tr1::weak_ptr< GWChannelsrvchan
 
+bool initial
 
+bool running
 
+bool inoverflow
 
+size_t nwakeups
 
+size_t nevents
 
+size_t ndropped
 
+std::deque
+< epics::pvData::MonitorElementPtr > 
filled
 
+std::deque
+< epics::pvData::MonitorElementPtr > 
empty
 
+std::set
+< epics::pvData::MonitorElementPtr > 
inuse
 
+epics::pvData::MonitorElementPtr overflowElement
 
+ + + +

+Static Public Attributes

+static size_t num_instances
 
+

Detailed Description

+
+

Definition at line 65 of file chancache.h.

+

The documentation for this struct was generated from the following files: +
+ + + + diff --git a/struct_monitor_user__coll__graph.map b/struct_monitor_user__coll__graph.map new file mode 100644 index 0000000..800c3cb --- /dev/null +++ b/struct_monitor_user__coll__graph.map @@ -0,0 +1,2 @@ + + diff --git a/struct_monitor_user__coll__graph.md5 b/struct_monitor_user__coll__graph.md5 new file mode 100644 index 0000000..a527139 --- /dev/null +++ b/struct_monitor_user__coll__graph.md5 @@ -0,0 +1 @@ +f7d6bd32f99b56d00465312439452992 \ No newline at end of file diff --git a/struct_monitor_user__coll__graph.png b/struct_monitor_user__coll__graph.png new file mode 100644 index 0000000..62fac34 Binary files /dev/null and b/struct_monitor_user__coll__graph.png differ diff --git a/struct_monitor_user__inherit__graph.map b/struct_monitor_user__inherit__graph.map new file mode 100644 index 0000000..800c3cb --- /dev/null +++ b/struct_monitor_user__inherit__graph.map @@ -0,0 +1,2 @@ + + diff --git a/struct_monitor_user__inherit__graph.md5 b/struct_monitor_user__inherit__graph.md5 new file mode 100644 index 0000000..a527139 --- /dev/null +++ b/struct_monitor_user__inherit__graph.md5 @@ -0,0 +1 @@ +f7d6bd32f99b56d00465312439452992 \ No newline at end of file diff --git a/struct_monitor_user__inherit__graph.png b/struct_monitor_user__inherit__graph.png new file mode 100644 index 0000000..62fac34 Binary files /dev/null and b/struct_monitor_user__inherit__graph.png differ diff --git a/struct_p_d_b_group_channel-members.html b/struct_p_d_b_group_channel-members.html new file mode 100644 index 0000000..ed8eb9f --- /dev/null +++ b/struct_p_d_b_group_channel-members.html @@ -0,0 +1,126 @@ + + + + + + +pva2pva: Member List + + + + + + + + + +
+
+ + + + + + +
+
pva2pva +  1.4.1 +
+
+
+ + + + + + + + + +
+ +
+ +
+
+
+
PDBGroupChannel Member List
+
+
+ +

This is the complete list of members for PDBGroupChannel, including all inherited members.

+ + + + + + + + + + + + + + + + + + + + + + + + + + +
aspvt (defined in PDBGroupChannel)PDBGroupChannel
BaseChannel(const std::string &name, const std::tr1::weak_ptr< epics::pvAccess::ChannelProvider > &prov, const epics::pvAccess::ChannelRequester::shared_pointer &req, const epics::pvData::StructureConstPtr &dtype) (defined in BaseChannel)BaseChannelinline
createChannelPut(epics::pvAccess::ChannelPutRequester::shared_pointer const &requester, epics::pvData::PVStructure::shared_pointer const &pvRequest) OVERRIDE FINAL (defined in PDBGroupChannel)PDBGroupChannelvirtual
createMonitor(epics::pvData::MonitorRequester::shared_pointer const &requester, epics::pvData::PVStructure::shared_pointer const &pvRequest) OVERRIDE FINAL (defined in PDBGroupChannel)PDBGroupChannelvirtual
cred (defined in PDBGroupChannel)PDBGroupChannel
destroy() OVERRIDE FINAL (defined in BaseChannel)BaseChannelinlinevirtual
fielddesc (defined in BaseChannel)BaseChannel
getChannelName() OVERRIDE FINAL (defined in BaseChannel)BaseChannelinlinevirtual
getChannelRequester() OVERRIDE FINAL (defined in BaseChannel)BaseChannelinlinevirtual
getField(epics::pvAccess::GetFieldRequester::shared_pointer const &requester, std::string const &subField) OVERRIDE (defined in BaseChannel)BaseChannelinlinevirtual
getProvider() OVERRIDE FINAL (defined in BaseChannel)BaseChannelinlinevirtual
getRemoteAddress() OVERRIDE (defined in BaseChannel)BaseChannelinlinevirtual
getRequesterName() OVERRIDE (defined in BaseChannel)BaseChannelinlinevirtual
guard_t typedef (defined in BaseChannel)BaseChannel
lock (defined in BaseChannel)BaseChannelmutable
num_instances (defined in PDBGroupChannel)PDBGroupChannelstatic
PDBGroupChannel(const PDBGroupPV::shared_pointer &pv, const std::tr1::shared_ptr< epics::pvAccess::ChannelProvider > &prov, const epics::pvAccess::ChannelRequester::shared_pointer &req) (defined in PDBGroupChannel)PDBGroupChannel
POINTER_DEFINITIONS(PDBGroupChannel) (defined in PDBGroupChannel)PDBGroupChannel
printInfo(std::ostream &out) OVERRIDE FINAL (defined in PDBGroupChannel)PDBGroupChannelvirtual
provider (defined in BaseChannel)BaseChannel
pv (defined in PDBGroupChannel)PDBGroupChannel
pvname (defined in BaseChannel)BaseChannel
requester (defined in BaseChannel)BaseChannel
~BaseChannel() (defined in BaseChannel)BaseChannelinlinevirtual
~PDBGroupChannel() (defined in PDBGroupChannel)PDBGroupChannelvirtual
+ + + + diff --git a/struct_p_d_b_group_channel.html b/struct_p_d_b_group_channel.html new file mode 100644 index 0000000..a6ae1ce --- /dev/null +++ b/struct_p_d_b_group_channel.html @@ -0,0 +1,215 @@ + + + + + + +pva2pva: PDBGroupChannel Struct Reference + + + + + + + + + +
+
+ + + + + + +
+
pva2pva +  1.4.1 +
+
+
+ + + + + + + + + +
+ +
+ +
+ +
+
+Inheritance diagram for PDBGroupChannel:
+
+
Inheritance graph
+ + +
[legend]
+
+Collaboration diagram for PDBGroupChannel:
+
+
Collaboration graph
+ + +
[legend]
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Public Member Functions

POINTER_DEFINITIONS (PDBGroupChannel)
 
PDBGroupChannel (const PDBGroupPV::shared_pointer &pv, const std::tr1::shared_ptr< epics::pvAccess::ChannelProvider > &prov, const epics::pvAccess::ChannelRequester::shared_pointer &req)
 
+virtual
+epics::pvAccess::ChannelPut::shared_pointer 
createChannelPut (epics::pvAccess::ChannelPutRequester::shared_pointer const &requester, epics::pvData::PVStructure::shared_pointer const &pvRequest) OVERRIDE FINAL
 
+virtual
+epics::pvData::Monitor::shared_pointer 
createMonitor (epics::pvData::MonitorRequester::shared_pointer const &requester, epics::pvData::PVStructure::shared_pointer const &pvRequest) OVERRIDE FINAL
 
+virtual void printInfo (std::ostream &out) OVERRIDE FINAL
 
- Public Member Functions inherited from BaseChannel
BaseChannel (const std::string &name, const std::tr1::weak_ptr< epics::pvAccess::ChannelProvider > &prov, const epics::pvAccess::ChannelRequester::shared_pointer &req, const epics::pvData::StructureConstPtr &dtype)
 
+virtual std::string getRequesterName () OVERRIDE
 
+virtual void destroy () OVERRIDE FINAL
 
+virtual std::tr1::shared_ptr
+< epics::pvAccess::ChannelProvider > 
getProvider () OVERRIDE FINAL
 
+virtual std::string getRemoteAddress () OVERRIDE
 
+virtual std::string getChannelName () OVERRIDE FINAL
 
+virtual std::tr1::shared_ptr
+< epics::pvAccess::ChannelRequester > 
getChannelRequester () OVERRIDE FINAL
 
+virtual void getField (epics::pvAccess::GetFieldRequester::shared_pointer const &requester, std::string const &subField) OVERRIDE
 
+ + + + + + + + + + + + + + + + + + +

+Public Attributes

+PDBGroupPV::shared_pointer pv
 
+std::vector< ASCLIENTaspvt
 
+ASCred cred
 
- Public Attributes inherited from BaseChannel
+epicsMutex lock
 
+const std::string pvname
 
+const
+epics::pvAccess::ChannelProvider::weak_pointer 
provider
 
+const requester_type::weak_pointer requester
 
+const
+epics::pvData::StructureConstPtr 
fielddesc
 
+ + + +

+Static Public Attributes

+static size_t num_instances
 
+ + + + +

+Additional Inherited Members

- Public Types inherited from BaseChannel
+typedef epicsGuard< epicsMutex > guard_t
 
+

Detailed Description

+
+

Definition at line 136 of file pdbgroup.h.

+

The documentation for this struct was generated from the following files: +
+ + + + diff --git a/struct_p_d_b_group_channel__coll__graph.map b/struct_p_d_b_group_channel__coll__graph.map new file mode 100644 index 0000000..e4e447e --- /dev/null +++ b/struct_p_d_b_group_channel__coll__graph.map @@ -0,0 +1,4 @@ + + + + diff --git a/struct_p_d_b_group_channel__coll__graph.md5 b/struct_p_d_b_group_channel__coll__graph.md5 new file mode 100644 index 0000000..f2beb03 --- /dev/null +++ b/struct_p_d_b_group_channel__coll__graph.md5 @@ -0,0 +1 @@ +dfb888b6e25befe674889d4d84d852f4 \ No newline at end of file diff --git a/struct_p_d_b_group_channel__coll__graph.png b/struct_p_d_b_group_channel__coll__graph.png new file mode 100644 index 0000000..50f092e Binary files /dev/null and b/struct_p_d_b_group_channel__coll__graph.png differ diff --git a/struct_p_d_b_group_channel__inherit__graph.map b/struct_p_d_b_group_channel__inherit__graph.map new file mode 100644 index 0000000..98e277f --- /dev/null +++ b/struct_p_d_b_group_channel__inherit__graph.map @@ -0,0 +1,3 @@ + + + diff --git a/struct_p_d_b_group_channel__inherit__graph.md5 b/struct_p_d_b_group_channel__inherit__graph.md5 new file mode 100644 index 0000000..945f46e --- /dev/null +++ b/struct_p_d_b_group_channel__inherit__graph.md5 @@ -0,0 +1 @@ +6d6f25b044503b8c23e2719f8452efb4 \ No newline at end of file diff --git a/struct_p_d_b_group_channel__inherit__graph.png b/struct_p_d_b_group_channel__inherit__graph.png new file mode 100644 index 0000000..c3b2ef2 Binary files /dev/null and b/struct_p_d_b_group_channel__inherit__graph.png differ diff --git a/struct_p_d_b_group_monitor-members.html b/struct_p_d_b_group_monitor-members.html new file mode 100644 index 0000000..91858b1 --- /dev/null +++ b/struct_p_d_b_group_monitor-members.html @@ -0,0 +1,127 @@ + + + + + + +pva2pva: Member List + + + + + + + + + +
+
+ + + + + + +
+
pva2pva +  1.4.1 +
+
+
+ + + + + + + + + +
+ +
+ +
+
+
+
PDBGroupMonitor Member List
+
+
+ +

This is the complete list of members for PDBGroupMonitor, including all inherited members.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
atomic (defined in PDBGroupMonitor)PDBGroupMonitor
BaseMonitor(epicsMutex &lock, const requester_t::weak_pointer &requester, const epics::pvData::PVStructure::shared_pointer &pvReq) (defined in BaseMonitor)BaseMonitorinline
connect(guard_t &guard, const epics::pvData::PVStructurePtr &value)BaseMonitorinline
destroy() OVERRIDE FINAL (defined in PDBGroupMonitor)PDBGroupMonitorvirtual
getStats(Stats &s) const (defined in BaseMonitor)BaseMonitorinlinevirtual
getValue() (defined in BaseMonitor)BaseMonitorinline
guard_t typedef (defined in BaseMonitor)BaseMonitor
lock (defined in BaseMonitor)BaseMonitor
num_instances (defined in PDBGroupMonitor)PDBGroupMonitorstatic
onStart() OVERRIDE FINAL (defined in PDBGroupMonitor)PDBGroupMonitorvirtual
onStop() OVERRIDE FINAL (defined in PDBGroupMonitor)PDBGroupMonitorvirtual
PDBGroupMonitor(const PDBGroupPV::shared_pointer &pv, const requester_type::weak_pointer &requester, const epics::pvData::PVStructure::shared_pointer &pvReq) (defined in PDBGroupMonitor)PDBGroupMonitor
POINTER_DEFINITIONS(PDBGroupMonitor) (defined in PDBGroupMonitor)PDBGroupMonitor
POINTER_DEFINITIONS(BaseMonitor) (defined in BaseMonitor)BaseMonitor
post(guard_t &guard, const epics::pvData::BitSet &updated, no_overflow)BaseMonitorinline
post(guard_t &guard)BaseMonitorinline
post(guard_t &guard, const epics::pvData::BitSet &updated, const epics::pvData::BitSet &overflowed)BaseMonitorinline
post(guard_t &guard, const epics::pvData::BitSet &updated)BaseMonitorinline
pv (defined in PDBGroupMonitor)PDBGroupMonitor
requester_t typedef (defined in BaseMonitor)BaseMonitor
requestUpdate() OVERRIDE FINALPDBGroupMonitorvirtual
shared_from_this() (defined in BaseMonitor)BaseMonitorinline
unguard_t typedef (defined in BaseMonitor)BaseMonitor
weakself (defined in BaseMonitor)BaseMonitor
~BaseMonitor() (defined in BaseMonitor)BaseMonitorinlinevirtual
~PDBGroupMonitor() (defined in PDBGroupMonitor)PDBGroupMonitorvirtual
+ + + + diff --git a/struct_p_d_b_group_monitor.html b/struct_p_d_b_group_monitor.html new file mode 100644 index 0000000..e0b3869 --- /dev/null +++ b/struct_p_d_b_group_monitor.html @@ -0,0 +1,251 @@ + + + + + + +pva2pva: PDBGroupMonitor Struct Reference + + + + + + + + + +
+
+ + + + + + +
+
pva2pva +  1.4.1 +
+
+
+ + + + + + + + + +
+ +
+ +
+ +
+
+Inheritance diagram for PDBGroupMonitor:
+
+
Inheritance graph
+ + +
[legend]
+
+Collaboration diagram for PDBGroupMonitor:
+
+
Collaboration graph
+ + +
[legend]
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Public Member Functions

POINTER_DEFINITIONS (PDBGroupMonitor)
 
PDBGroupMonitor (const PDBGroupPV::shared_pointer &pv, const requester_type::weak_pointer &requester, const epics::pvData::PVStructure::shared_pointer &pvReq)
 
+virtual void onStart () OVERRIDE FINAL
 
+virtual void onStop () OVERRIDE FINAL
 
virtual void requestUpdate () OVERRIDE FINAL
 
+virtual void destroy () OVERRIDE FINAL
 
- Public Member Functions inherited from BaseMonitor
POINTER_DEFINITIONS (BaseMonitor)
 
+shared_pointer shared_from_this ()
 
BaseMonitor (epicsMutex &lock, const requester_t::weak_pointer &requester, const epics::pvData::PVStructure::shared_pointer &pvReq)
 
+const
+epics::pvData::PVStructurePtr & 
getValue ()
 
void connect (guard_t &guard, const epics::pvData::PVStructurePtr &value)
 
+bool post (guard_t &guard, const epics::pvData::BitSet &updated, no_overflow)
 post update if queue not full, if full return false w/o overflow
 
+bool post (guard_t &guard)
 post update of pending changes. eg. call from requestUpdate()
 
+bool post (guard_t &guard, const epics::pvData::BitSet &updated, const epics::pvData::BitSet &overflowed)
 post update with changed and overflowed masks (eg. when updates were lost in some upstream queue)
 
+bool post (guard_t &guard, const epics::pvData::BitSet &updated)
 post update with changed
 
+virtual void getStats (Stats &s) const
 
+ + + + + + + + + + +

+Public Attributes

+PDBGroupPV::shared_pointer pv
 
+bool atomic
 
- Public Attributes inherited from BaseMonitor
+weak_pointer weakself
 
+epicsMutex & lock
 
+ + + +

+Static Public Attributes

+static size_t num_instances
 
+ + + + + + + + +

+Additional Inherited Members

- Public Types inherited from BaseMonitor
+typedef
+epics::pvAccess::MonitorRequester 
requester_t
 
+typedef epicsGuard< epicsMutex > guard_t
 
+typedef epicsGuardRelease
+< epicsMutex > 
unguard_t
 
+

Detailed Description

+
+

Definition at line 196 of file pdbgroup.h.

+

Member Function Documentation

+ +
+
+ + + + + +
+ + + + + + + +
void PDBGroupMonitor::requestUpdate ()
+
+virtual
+
+

called when within release() when the opportunity exists to end the overflow condition May do nothing, or lock and call post()

+ +

Reimplemented from BaseMonitor.

+ +

Definition at line 470 of file pdbgroup.cpp.

+
471 {
+
472  Guard G(pv->lock);
+
473  post(G);
+
474 }
+
bool post(guard_t &guard, const epics::pvData::BitSet &updated, no_overflow)
post update if queue not full, if full return false w/o overflow
Definition: pvahelper.h:136
+
+
+
+
The documentation for this struct was generated from the following files: +
+ + + + diff --git a/struct_p_d_b_group_monitor__coll__graph.map b/struct_p_d_b_group_monitor__coll__graph.map new file mode 100644 index 0000000..08acf52 --- /dev/null +++ b/struct_p_d_b_group_monitor__coll__graph.map @@ -0,0 +1,3 @@ + + + diff --git a/struct_p_d_b_group_monitor__coll__graph.md5 b/struct_p_d_b_group_monitor__coll__graph.md5 new file mode 100644 index 0000000..c77b5c1 --- /dev/null +++ b/struct_p_d_b_group_monitor__coll__graph.md5 @@ -0,0 +1 @@ +e3dadae42c249257c0997dd1050e9e15 \ No newline at end of file diff --git a/struct_p_d_b_group_monitor__coll__graph.png b/struct_p_d_b_group_monitor__coll__graph.png new file mode 100644 index 0000000..18feb00 Binary files /dev/null and b/struct_p_d_b_group_monitor__coll__graph.png differ diff --git a/struct_p_d_b_group_monitor__inherit__graph.map b/struct_p_d_b_group_monitor__inherit__graph.map new file mode 100644 index 0000000..08acf52 --- /dev/null +++ b/struct_p_d_b_group_monitor__inherit__graph.map @@ -0,0 +1,3 @@ + + + diff --git a/struct_p_d_b_group_monitor__inherit__graph.md5 b/struct_p_d_b_group_monitor__inherit__graph.md5 new file mode 100644 index 0000000..c77b5c1 --- /dev/null +++ b/struct_p_d_b_group_monitor__inherit__graph.md5 @@ -0,0 +1 @@ +e3dadae42c249257c0997dd1050e9e15 \ No newline at end of file diff --git a/struct_p_d_b_group_monitor__inherit__graph.png b/struct_p_d_b_group_monitor__inherit__graph.png new file mode 100644 index 0000000..18feb00 Binary files /dev/null and b/struct_p_d_b_group_monitor__inherit__graph.png differ diff --git a/struct_p_d_b_group_p_v-members.html b/struct_p_d_b_group_p_v-members.html new file mode 100644 index 0000000..42c0fef --- /dev/null +++ b/struct_p_d_b_group_p_v-members.html @@ -0,0 +1,132 @@ + + + + + + +pva2pva: Member List + + + + + + + + + +
+
+ + + + + + +
+
pva2pva +  1.4.1 +
+
+
+ + + + + + + + + +
+ +
+ +
+
+
+
PDBGroupPV Member List
+
+
+ +

This is the complete list of members for PDBGroupPV, including all inherited members.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
addMonitor(PDBGroupMonitor *) (defined in PDBGroupPV)PDBGroupPV
complete (defined in PDBGroupPV)PDBGroupPV
connect(const std::tr1::shared_ptr< PDBProvider > &prov, const epics::pvAccess::ChannelRequester::shared_pointer &req) OVERRIDE FINAL (defined in PDBGroupPV)PDBGroupPVvirtual
fielddesc (defined in PDBPV)PDBPV
finalizeMonitor() (defined in PDBGroupPV)PDBGroupPV
initial_waits (defined in PDBGroupPV)PDBGroupPV
interested (defined in PDBGroupPV)PDBGroupPV
interested_add (defined in PDBGroupPV)PDBGroupPV
interested_iterating (defined in PDBGroupPV)PDBGroupPV
interested_remove (defined in PDBGroupPV)PDBGroupPV
interested_remove_t typedef (defined in PDBGroupPV)PDBGroupPV
interested_t typedef (defined in PDBGroupPV)PDBGroupPV
lock (defined in PDBGroupPV)PDBGroupPV
locker (defined in PDBGroupPV)PDBGroupPV
members (defined in PDBGroupPV)PDBGroupPV
members_t typedef (defined in PDBGroupPV)PDBGroupPV
monatomic (defined in PDBGroupPV)PDBGroupPV
name (defined in PDBGroupPV)PDBGroupPV
num_instances (defined in PDBGroupPV)PDBGroupPVstatic
PDBGroupPV() (defined in PDBGroupPV)PDBGroupPV
PDBPV() (defined in PDBPV)PDBPVinline
pgatomic (defined in PDBGroupPV)PDBGroupPV
POINTER_DEFINITIONS(PDBGroupPV) (defined in PDBGroupPV)PDBGroupPV
POINTER_DEFINITIONS(PDBPV) (defined in PDBPV)PDBPV
removeMonitor(PDBGroupMonitor *) (defined in PDBGroupPV)PDBGroupPV
scratch (defined in PDBGroupPV)PDBGroupPV
shared_from_this() (defined in PDBGroupPV)PDBGroupPVinline
show(int lvl) OVERRIDE (defined in PDBGroupPV)PDBGroupPVvirtual
weakself (defined in PDBGroupPV)PDBGroupPV
~PDBGroupPV() (defined in PDBGroupPV)PDBGroupPVvirtual
~PDBPV() (defined in PDBPV)PDBPVinlinevirtual
+ + + + diff --git a/struct_p_d_b_group_p_v.html b/struct_p_d_b_group_p_v.html new file mode 100644 index 0000000..ab9936f --- /dev/null +++ b/struct_p_d_b_group_p_v.html @@ -0,0 +1,232 @@ + + + + + + +pva2pva: PDBGroupPV Struct Reference + + + + + + + + + +
+
+ + + + + + +
+
pva2pva +  1.4.1 +
+
+
+ + + + + + + + + +
+ +
+ +
+ +
+
+Inheritance diagram for PDBGroupPV:
+
+
Inheritance graph
+ + +
[legend]
+
+Collaboration diagram for PDBGroupPV:
+
+
Collaboration graph
+ + +
[legend]
+ + + + +

+Classes

struct  Info
 
+ + + + + + + +

+Public Types

+typedef
+epics::pvData::shared_vector
+< Info
members_t
 
+typedef std::set
+< PDBGroupMonitor * > 
interested_t
 
+typedef std::set
+< BaseMonitor::shared_pointer > 
interested_remove_t
 
+ + + + + + + + + + + + + + + + + + +

+Public Member Functions

POINTER_DEFINITIONS (PDBGroupPV)
 
+shared_pointer shared_from_this ()
 
+virtual
+epics::pvAccess::Channel::shared_pointer 
connect (const std::tr1::shared_ptr< PDBProvider > &prov, const epics::pvAccess::ChannelRequester::shared_pointer &req) OVERRIDE FINAL
 
+void addMonitor (PDBGroupMonitor *)
 
+void removeMonitor (PDBGroupMonitor *)
 
+void finalizeMonitor ()
 
+virtual void show (int lvl) OVERRIDE
 
- Public Member Functions inherited from PDBPV
POINTER_DEFINITIONS (PDBPV)
 
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Public Attributes

+weak_pointer weakself
 
+epics::pvData::BitSet scratch
 
+epicsMutex lock
 
+bool pgatomic
 
+bool monatomic
 
+std::string name
 
+members_t members
 
+DBManyLock locker
 
+epics::pvData::PVStructurePtr complete
 
+bool interested_iterating
 
+interested_t interested
 
+interested_t interested_add
 
+interested_remove_t interested_remove
 
+size_t initial_waits
 
- Public Attributes inherited from PDBPV
+epics::pvData::StructureConstPtr fielddesc
 
+ + + +

+Static Public Attributes

+static size_t num_instances
 
+

Detailed Description

+
+

Definition at line 71 of file pdbgroup.h.

+

The documentation for this struct was generated from the following files: +
+ + + + diff --git a/struct_p_d_b_group_p_v_1_1_info-members.html b/struct_p_d_b_group_p_v_1_1_info-members.html new file mode 100644 index 0000000..93fbd40 --- /dev/null +++ b/struct_p_d_b_group_p_v_1_1_info-members.html @@ -0,0 +1,119 @@ + + + + + + +pva2pva: Member List + + + + + + + + + +
+
+ + + + + + +
+
pva2pva +  1.4.1 +
+
+
+ + + + + + + + + +
+ +
+ + +
+
+
+
PDBGroupPV::Info Member List
+
+
+ +

This is the complete list of members for PDBGroupPV::Info, including all inherited members.

+ + + + + + + + + + + + + + + +
allowProc (defined in PDBGroupPV::Info)PDBGroupPV::Info
attachment (defined in PDBGroupPV::Info)PDBGroupPV::Info
builder (defined in PDBGroupPV::Info)PDBGroupPV::Info
chan (defined in PDBGroupPV::Info)PDBGroupPV::Info
chan2 (defined in PDBGroupPV::Info)PDBGroupPV::Info
evt_PROPERTY (defined in PDBGroupPV::Info)PDBGroupPV::Info
evt_VALUE (defined in PDBGroupPV::Info)PDBGroupPV::Info
had_initial_PROPERTY (defined in PDBGroupPV::Info)PDBGroupPV::Info
had_initial_VALUE (defined in PDBGroupPV::Info)PDBGroupPV::Info
Info() (defined in PDBGroupPV::Info)PDBGroupPV::Infoinline
locker (defined in PDBGroupPV::Info)PDBGroupPV::Info
pvif (defined in PDBGroupPV::Info)PDBGroupPV::Info
triggers (defined in PDBGroupPV::Info)PDBGroupPV::Info
triggers_t typedef (defined in PDBGroupPV::Info)PDBGroupPV::Info
+ + + + diff --git a/struct_p_d_b_group_p_v_1_1_info.html b/struct_p_d_b_group_p_v_1_1_info.html new file mode 100644 index 0000000..946df5e --- /dev/null +++ b/struct_p_d_b_group_p_v_1_1_info.html @@ -0,0 +1,165 @@ + + + + + + +pva2pva: PDBGroupPV::Info Struct Reference + + + + + + + + + +
+
+ + + + + + +
+
pva2pva +  1.4.1 +
+
+
+ + + + + + + + + +
+ +
+ + +
+
+ +
+
PDBGroupPV::Info Struct Reference
+
+
+
+Collaboration diagram for PDBGroupPV::Info:
+
+
Collaboration graph
+ + +
[legend]
+ + + + +

+Public Types

+typedef std::vector< size_t > triggers_t
 
+ + + + + + + + + + + + + + + + + + + + + + + + + +

+Public Attributes

+DBCH chan
 
+DBCH chan2
 
+std::tr1::shared_ptr< PVIFBuilderbuilder
 
+FieldName attachment
 
+triggers_t triggers
 
+DBManyLock locker
 
+p2p::auto_ptr< PVIFpvif
 
+DBEvent evt_VALUE
 
+DBEvent evt_PROPERTY
 
+bool had_initial_VALUE
 
+bool had_initial_PROPERTY
 
+bool allowProc
 
+

Detailed Description

+
+

Definition at line 88 of file pdbgroup.h.

+

The documentation for this struct was generated from the following file: +
+ + + + diff --git a/struct_p_d_b_group_p_v_1_1_info__coll__graph.map b/struct_p_d_b_group_p_v_1_1_info__coll__graph.map new file mode 100644 index 0000000..ea43ec5 --- /dev/null +++ b/struct_p_d_b_group_p_v_1_1_info__coll__graph.map @@ -0,0 +1,5 @@ + + + + + diff --git a/struct_p_d_b_group_p_v_1_1_info__coll__graph.md5 b/struct_p_d_b_group_p_v_1_1_info__coll__graph.md5 new file mode 100644 index 0000000..14f086f --- /dev/null +++ b/struct_p_d_b_group_p_v_1_1_info__coll__graph.md5 @@ -0,0 +1 @@ +bf86f02ee8adfeb408fa18611625bfaf \ No newline at end of file diff --git a/struct_p_d_b_group_p_v_1_1_info__coll__graph.png b/struct_p_d_b_group_p_v_1_1_info__coll__graph.png new file mode 100644 index 0000000..9d9d36e Binary files /dev/null and b/struct_p_d_b_group_p_v_1_1_info__coll__graph.png differ diff --git a/struct_p_d_b_group_p_v__coll__graph.map b/struct_p_d_b_group_p_v__coll__graph.map new file mode 100644 index 0000000..420da88 --- /dev/null +++ b/struct_p_d_b_group_p_v__coll__graph.map @@ -0,0 +1,3 @@ + + + diff --git a/struct_p_d_b_group_p_v__coll__graph.md5 b/struct_p_d_b_group_p_v__coll__graph.md5 new file mode 100644 index 0000000..880d9f4 --- /dev/null +++ b/struct_p_d_b_group_p_v__coll__graph.md5 @@ -0,0 +1 @@ +e4464774e1b37c7c9cb8002aaf10879d \ No newline at end of file diff --git a/struct_p_d_b_group_p_v__coll__graph.png b/struct_p_d_b_group_p_v__coll__graph.png new file mode 100644 index 0000000..07c0d4e Binary files /dev/null and b/struct_p_d_b_group_p_v__coll__graph.png differ diff --git a/struct_p_d_b_group_p_v__inherit__graph.map b/struct_p_d_b_group_p_v__inherit__graph.map new file mode 100644 index 0000000..420da88 --- /dev/null +++ b/struct_p_d_b_group_p_v__inherit__graph.map @@ -0,0 +1,3 @@ + + + diff --git a/struct_p_d_b_group_p_v__inherit__graph.md5 b/struct_p_d_b_group_p_v__inherit__graph.md5 new file mode 100644 index 0000000..880d9f4 --- /dev/null +++ b/struct_p_d_b_group_p_v__inherit__graph.md5 @@ -0,0 +1 @@ +e4464774e1b37c7c9cb8002aaf10879d \ No newline at end of file diff --git a/struct_p_d_b_group_p_v__inherit__graph.png b/struct_p_d_b_group_p_v__inherit__graph.png new file mode 100644 index 0000000..07c0d4e Binary files /dev/null and b/struct_p_d_b_group_p_v__inherit__graph.png differ diff --git a/struct_p_d_b_group_put-members.html b/struct_p_d_b_group_put-members.html new file mode 100644 index 0000000..01c85a1 --- /dev/null +++ b/struct_p_d_b_group_put-members.html @@ -0,0 +1,120 @@ + + + + + + +pva2pva: Member List + + + + + + + + + +
+
+ + + + + + +
+
pva2pva +  1.4.1 +
+
+
+ + + + + + + + + +
+ +
+ +
+
+
+
PDBGroupPut Member List
+
+
+ +

This is the complete list of members for PDBGroupPut, including all inherited members.

+ + + + + + + + + + + + + + + + + + + + +
atomic (defined in PDBGroupPut)PDBGroupPut
cancel() OVERRIDE FINAL (defined in PDBGroupPut)PDBGroupPutinlinevirtual
changed (defined in PDBGroupPut)PDBGroupPut
channel (defined in PDBGroupPut)PDBGroupPut
destroy() OVERRIDE FINAL (defined in PDBGroupPut)PDBGroupPutinlinevirtual
doProc (defined in PDBGroupPut)PDBGroupPut
doWait (defined in PDBGroupPut)PDBGroupPut
get() OVERRIDE FINAL (defined in PDBGroupPut)PDBGroupPutvirtual
getChannel() OVERRIDE FINAL (defined in PDBGroupPut)PDBGroupPutinlinevirtual
lastRequest() OVERRIDE FINAL (defined in PDBGroupPut)PDBGroupPutinlinevirtual
num_instances (defined in PDBGroupPut)PDBGroupPutstatic
PDBGroupPut(const PDBGroupChannel::shared_pointer &channel, const epics::pvAccess::ChannelPutRequester::shared_pointer &requester, const epics::pvData::PVStructure::shared_pointer &pvReq) (defined in PDBGroupPut)PDBGroupPut
POINTER_DEFINITIONS(PDBGroupPut) (defined in PDBGroupPut)PDBGroupPut
put(epics::pvData::PVStructure::shared_pointer const &pvPutStructure, epics::pvData::BitSet::shared_pointer const &putBitSet) OVERRIDE FINAL (defined in PDBGroupPut)PDBGroupPutvirtual
pvf (defined in PDBGroupPut)PDBGroupPut
pvif (defined in PDBGroupPut)PDBGroupPut
requester (defined in PDBGroupPut)PDBGroupPut
requester_t typedef (defined in PDBGroupPut)PDBGroupPut
~PDBGroupPut() (defined in PDBGroupPut)PDBGroupPutvirtual
+ + + + diff --git a/struct_p_d_b_group_put.html b/struct_p_d_b_group_put.html new file mode 100644 index 0000000..c120ed3 --- /dev/null +++ b/struct_p_d_b_group_put.html @@ -0,0 +1,191 @@ + + + + + + +pva2pva: PDBGroupPut Struct Reference + + + + + + + + + +
+
+ + + + + + +
+
pva2pva +  1.4.1 +
+
+
+ + + + + + + + + +
+ +
+ +
+ +
+
+Inheritance diagram for PDBGroupPut:
+
+
Inheritance graph
+
[legend]
+
+Collaboration diagram for PDBGroupPut:
+
+
Collaboration graph
+
[legend]
+ + + + +

+Public Types

+typedef
+epics::pvAccess::ChannelPutRequester 
requester_t
 
+ + + + + + + + + + + + + + + + + +

+Public Member Functions

POINTER_DEFINITIONS (PDBGroupPut)
 
PDBGroupPut (const PDBGroupChannel::shared_pointer &channel, const epics::pvAccess::ChannelPutRequester::shared_pointer &requester, const epics::pvData::PVStructure::shared_pointer &pvReq)
 
+virtual void destroy () OVERRIDE FINAL
 
+virtual std::tr1::shared_ptr
+< epics::pvAccess::Channel > 
getChannel () OVERRIDE FINAL
 
+virtual void cancel () OVERRIDE FINAL
 
+virtual void lastRequest () OVERRIDE FINAL
 
+virtual void put (epics::pvData::PVStructure::shared_pointer const &pvPutStructure, epics::pvData::BitSet::shared_pointer const &putBitSet) OVERRIDE FINAL
 
+virtual void get () OVERRIDE FINAL
 
+ + + + + + + + + + + + + + + + + +

+Public Attributes

+PDBGroupChannel::shared_pointer channel
 
+requester_type::weak_pointer requester
 
+bool atomic
 
+bool doWait
 
+PVIF::proc_t doProc
 
+epics::pvData::BitSetPtr changed
 
+epics::pvData::PVStructurePtr pvf
 
+std::vector
+< std::tr1::shared_ptr< PVIF > > 
pvif
 
+ + + +

+Static Public Attributes

+static size_t num_instances
 
+

Detailed Description

+
+

Definition at line 163 of file pdbgroup.h.

+

The documentation for this struct was generated from the following files: +
+ + + + diff --git a/struct_p_d_b_group_put__coll__graph.map b/struct_p_d_b_group_put__coll__graph.map new file mode 100644 index 0000000..adbcafd --- /dev/null +++ b/struct_p_d_b_group_put__coll__graph.map @@ -0,0 +1,2 @@ + + diff --git a/struct_p_d_b_group_put__coll__graph.md5 b/struct_p_d_b_group_put__coll__graph.md5 new file mode 100644 index 0000000..a49eadb --- /dev/null +++ b/struct_p_d_b_group_put__coll__graph.md5 @@ -0,0 +1 @@ +9b974a0837f395f03e9f6c67833c2728 \ No newline at end of file diff --git a/struct_p_d_b_group_put__coll__graph.png b/struct_p_d_b_group_put__coll__graph.png new file mode 100644 index 0000000..154b5cf Binary files /dev/null and b/struct_p_d_b_group_put__coll__graph.png differ diff --git a/struct_p_d_b_group_put__inherit__graph.map b/struct_p_d_b_group_put__inherit__graph.map new file mode 100644 index 0000000..adbcafd --- /dev/null +++ b/struct_p_d_b_group_put__inherit__graph.map @@ -0,0 +1,2 @@ + + diff --git a/struct_p_d_b_group_put__inherit__graph.md5 b/struct_p_d_b_group_put__inherit__graph.md5 new file mode 100644 index 0000000..a49eadb --- /dev/null +++ b/struct_p_d_b_group_put__inherit__graph.md5 @@ -0,0 +1 @@ +9b974a0837f395f03e9f6c67833c2728 \ No newline at end of file diff --git a/struct_p_d_b_group_put__inherit__graph.png b/struct_p_d_b_group_put__inherit__graph.png new file mode 100644 index 0000000..154b5cf Binary files /dev/null and b/struct_p_d_b_group_put__inherit__graph.png differ diff --git a/struct_p_d_b_p_v-members.html b/struct_p_d_b_p_v-members.html new file mode 100644 index 0000000..942dd78 --- /dev/null +++ b/struct_p_d_b_p_v-members.html @@ -0,0 +1,107 @@ + + + + + + +pva2pva: Member List + + + + + + + + + +
+
+ + + + + + +
+
pva2pva +  1.4.1 +
+
+
+ + + + + + + + + +
+ +
+ +
+
+
+
PDBPV Member List
+
+
+ +

This is the complete list of members for PDBPV, including all inherited members.

+ + + + + + + +
connect(const std::tr1::shared_ptr< PDBProvider > &prov, const epics::pvAccess::ChannelRequester::shared_pointer &req)=0 (defined in PDBPV)PDBPVpure virtual
fielddesc (defined in PDBPV)PDBPV
PDBPV() (defined in PDBPV)PDBPVinline
POINTER_DEFINITIONS(PDBPV) (defined in PDBPV)PDBPV
show(int lvl) (defined in PDBPV)PDBPVinlinevirtual
~PDBPV() (defined in PDBPV)PDBPVinlinevirtual
+ + + + diff --git a/struct_p_d_b_p_v.html b/struct_p_d_b_p_v.html new file mode 100644 index 0000000..6764f1b --- /dev/null +++ b/struct_p_d_b_p_v.html @@ -0,0 +1,135 @@ + + + + + + +pva2pva: PDBPV Struct Reference + + + + + + + + + +
+
+ + + + + + +
+
pva2pva +  1.4.1 +
+
+
+ + + + + + + + + +
+ +
+ +
+
+ +
+
PDBPV Struct Referenceabstract
+
+
+
+Inheritance diagram for PDBPV:
+
+
Inheritance graph
+ + +
[legend]
+ + + + + + + + +

+Public Member Functions

POINTER_DEFINITIONS (PDBPV)
 
+virtual
+epics::pvAccess::Channel::shared_pointer 
connect (const std::tr1::shared_ptr< PDBProvider > &prov, const epics::pvAccess::ChannelRequester::shared_pointer &req)=0
 
+virtual void show (int lvl)
 
+ + + +

+Public Attributes

+epics::pvData::StructureConstPtr fielddesc
 
+

Detailed Description

+
+

Definition at line 16 of file pdb.h.

+

The documentation for this struct was generated from the following file: +
+ + + + diff --git a/struct_p_d_b_p_v__inherit__graph.map b/struct_p_d_b_p_v__inherit__graph.map new file mode 100644 index 0000000..9750083 --- /dev/null +++ b/struct_p_d_b_p_v__inherit__graph.map @@ -0,0 +1,4 @@ + + + + diff --git a/struct_p_d_b_p_v__inherit__graph.md5 b/struct_p_d_b_p_v__inherit__graph.md5 new file mode 100644 index 0000000..aea35e5 --- /dev/null +++ b/struct_p_d_b_p_v__inherit__graph.md5 @@ -0,0 +1 @@ +5db70f9878068b7f76dba4a7f7ef0999 \ No newline at end of file diff --git a/struct_p_d_b_p_v__inherit__graph.png b/struct_p_d_b_p_v__inherit__graph.png new file mode 100644 index 0000000..05c0f77 Binary files /dev/null and b/struct_p_d_b_p_v__inherit__graph.png differ diff --git a/struct_p_d_b_provider-members.html b/struct_p_d_b_provider-members.html new file mode 100644 index 0000000..b0a8034 --- /dev/null +++ b/struct_p_d_b_provider-members.html @@ -0,0 +1,120 @@ + + + + + + +pva2pva: Member List + + + + + + + + + +
+
+ + + + + + +
+
pva2pva +  1.4.1 +
+
+
+ + + + + + + + + +
+ +
+ +
+
+
+
PDBProvider Member List
+
+
+ +

This is the complete list of members for PDBProvider, including all inherited members.

+ + + + + + + + + + + + + + + + + + + + +
cancel() OVERRIDE FINAL (defined in PDBProvider)PDBProviderinlinevirtual
channelFind(std::string const &channelName, epics::pvAccess::ChannelFindRequester::shared_pointer const &channelFindRequester) OVERRIDE FINAL (defined in PDBProvider)PDBProvidervirtual
channelList(epics::pvAccess::ChannelListRequester::shared_pointer const &channelListRequester) OVERRIDE FINAL (defined in PDBProvider)PDBProvidervirtual
createChannel(std::string const &channelName, epics::pvAccess::ChannelRequester::shared_pointer const &channelRequester, short priority=PRIORITY_DEFAULT) OVERRIDE FINAL (defined in PDBProvider)PDBProvidervirtual
createChannel(std::string const &channelName, epics::pvAccess::ChannelRequester::shared_pointer const &channelRequester, short priority, std::string const &address) OVERRIDE FINAL (defined in PDBProvider)PDBProvidervirtual
destroy() OVERRIDE FINAL (defined in PDBProvider)PDBProvidervirtual
event_context (defined in PDBProvider)PDBProvider
getChannelProvider() OVERRIDE FINAL (defined in PDBProvider)PDBProviderinlinevirtual
getProviderName() OVERRIDE FINAL (defined in PDBProvider)PDBProvidervirtual
group_files (defined in PDBProvider)PDBProviderstatic
group_files_t typedef (defined in PDBProvider)PDBProvider
num_instances (defined in PDBProvider)PDBProviderstatic
PDBProvider(const epics::pvAccess::Configuration::const_shared_pointer &=epics::pvAccess::Configuration::const_shared_pointer()) (defined in PDBProvider)PDBProviderexplicit
persist_pv_map (defined in PDBProvider)PDBProvider
persist_pv_map_t typedef (defined in PDBProvider)PDBProvider
POINTER_DEFINITIONS(PDBProvider) (defined in PDBProvider)PDBProvider
transient_pv_map (defined in PDBProvider)PDBProvider
transient_pv_map_t typedef (defined in PDBProvider)PDBProvider
~PDBProvider() (defined in PDBProvider)PDBProvidervirtual
+ + + + diff --git a/struct_p_d_b_provider.html b/struct_p_d_b_provider.html new file mode 100644 index 0000000..5abee9a --- /dev/null +++ b/struct_p_d_b_provider.html @@ -0,0 +1,199 @@ + + + + + + +pva2pva: PDBProvider Struct Reference + + + + + + + + + +
+
+ + + + + + +
+
pva2pva +  1.4.1 +
+
+
+ + + + + + + + + +
+ +
+ +
+ +
+
+Inheritance diagram for PDBProvider:
+
+
Inheritance graph
+ + +
[legend]
+
+Collaboration diagram for PDBProvider:
+
+
Collaboration graph
+ + +
[legend]
+ + + + + + + + +

+Public Types

+typedef std::map< std::string,
+PDBPV::shared_pointer > 
persist_pv_map_t
 
+typedef weak_value_map
+< std::string, PDBPV
transient_pv_map_t
 
+typedef std::list< std::string > group_files_t
 
+ + + + + + + + + + + + + + + + + + + + + +

+Public Member Functions

POINTER_DEFINITIONS (PDBProvider)
 
PDBProvider (const epics::pvAccess::Configuration::const_shared_pointer &=epics::pvAccess::Configuration::const_shared_pointer())
 
+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
+< ChannelProvider > 
getChannelProvider () OVERRIDE FINAL
 
+virtual void cancel () OVERRIDE FINAL
 
+ + + + + + + +

+Public Attributes

+persist_pv_map_t persist_pv_map
 
+transient_pv_map_t transient_pv_map
 
+dbEventCtx event_context
 
+ + + + + +

+Static Public Attributes

+static group_files_t group_files
 
+static size_t num_instances
 
+

Detailed Description

+
+

Definition at line 34 of file pdb.h.

+

The documentation for this struct was generated from the following files: +
+ + + + diff --git a/struct_p_d_b_provider__coll__graph.map b/struct_p_d_b_provider__coll__graph.map new file mode 100644 index 0000000..29143fd --- /dev/null +++ b/struct_p_d_b_provider__coll__graph.map @@ -0,0 +1,3 @@ + + + diff --git a/struct_p_d_b_provider__coll__graph.md5 b/struct_p_d_b_provider__coll__graph.md5 new file mode 100644 index 0000000..6a04c4c --- /dev/null +++ b/struct_p_d_b_provider__coll__graph.md5 @@ -0,0 +1 @@ +c2ac46d0b7a470d00aac2cdbe45431aa \ No newline at end of file diff --git a/struct_p_d_b_provider__coll__graph.png b/struct_p_d_b_provider__coll__graph.png new file mode 100644 index 0000000..c1128cd Binary files /dev/null and b/struct_p_d_b_provider__coll__graph.png differ diff --git a/struct_p_d_b_provider__inherit__graph.map b/struct_p_d_b_provider__inherit__graph.map new file mode 100644 index 0000000..cfe7147 --- /dev/null +++ b/struct_p_d_b_provider__inherit__graph.map @@ -0,0 +1,2 @@ + + diff --git a/struct_p_d_b_provider__inherit__graph.md5 b/struct_p_d_b_provider__inherit__graph.md5 new file mode 100644 index 0000000..c60a081 --- /dev/null +++ b/struct_p_d_b_provider__inherit__graph.md5 @@ -0,0 +1 @@ +d472b3f6fea1a14b4fe7f375a6ded550 \ No newline at end of file diff --git a/struct_p_d_b_provider__inherit__graph.png b/struct_p_d_b_provider__inherit__graph.png new file mode 100644 index 0000000..44f0529 Binary files /dev/null and b/struct_p_d_b_provider__inherit__graph.png differ diff --git a/struct_p_d_b_single_channel-members.html b/struct_p_d_b_single_channel-members.html new file mode 100644 index 0000000..f32258a --- /dev/null +++ b/struct_p_d_b_single_channel-members.html @@ -0,0 +1,126 @@ + + + + + + +pva2pva: Member List + + + + + + + + + +
+
+ + + + + + +
+
pva2pva +  1.4.1 +
+
+
+ + + + + + + + + +
+ +
+ +
+
+
+
PDBSingleChannel Member List
+
+
+ +

This is the complete list of members for PDBSingleChannel, including all inherited members.

+ + + + + + + + + + + + + + + + + + + + + + + + + + +
aspvt (defined in PDBSingleChannel)PDBSingleChannel
BaseChannel(const std::string &name, const std::tr1::weak_ptr< epics::pvAccess::ChannelProvider > &prov, const epics::pvAccess::ChannelRequester::shared_pointer &req, const epics::pvData::StructureConstPtr &dtype) (defined in BaseChannel)BaseChannelinline
createChannelPut(epics::pvAccess::ChannelPutRequester::shared_pointer const &requester, epics::pvData::PVStructure::shared_pointer const &pvRequest) OVERRIDE FINAL (defined in PDBSingleChannel)PDBSingleChannelvirtual
createMonitor(epics::pvData::MonitorRequester::shared_pointer const &requester, epics::pvData::PVStructure::shared_pointer const &pvRequest) OVERRIDE FINAL (defined in PDBSingleChannel)PDBSingleChannelvirtual
cred (defined in PDBSingleChannel)PDBSingleChannel
destroy() OVERRIDE FINAL (defined in BaseChannel)BaseChannelinlinevirtual
fielddesc (defined in BaseChannel)BaseChannel
getChannelName() OVERRIDE FINAL (defined in BaseChannel)BaseChannelinlinevirtual
getChannelRequester() OVERRIDE FINAL (defined in BaseChannel)BaseChannelinlinevirtual
getField(epics::pvAccess::GetFieldRequester::shared_pointer const &requester, std::string const &subField) OVERRIDE (defined in BaseChannel)BaseChannelinlinevirtual
getProvider() OVERRIDE FINAL (defined in BaseChannel)BaseChannelinlinevirtual
getRemoteAddress() OVERRIDE (defined in BaseChannel)BaseChannelinlinevirtual
getRequesterName() OVERRIDE (defined in BaseChannel)BaseChannelinlinevirtual
guard_t typedef (defined in BaseChannel)BaseChannel
lock (defined in BaseChannel)BaseChannelmutable
num_instances (defined in PDBSingleChannel)PDBSingleChannelstatic
PDBSingleChannel(const PDBSinglePV::shared_pointer &pv, const epics::pvAccess::ChannelRequester::shared_pointer &req) (defined in PDBSingleChannel)PDBSingleChannel
POINTER_DEFINITIONS(PDBSingleChannel) (defined in PDBSingleChannel)PDBSingleChannel
printInfo(std::ostream &out) OVERRIDE FINAL (defined in PDBSingleChannel)PDBSingleChannelvirtual
provider (defined in BaseChannel)BaseChannel
pv (defined in PDBSingleChannel)PDBSingleChannel
pvname (defined in BaseChannel)BaseChannel
requester (defined in BaseChannel)BaseChannel
~BaseChannel() (defined in BaseChannel)BaseChannelinlinevirtual
~PDBSingleChannel() (defined in PDBSingleChannel)PDBSingleChannelvirtual
+ + + + diff --git a/struct_p_d_b_single_channel.html b/struct_p_d_b_single_channel.html new file mode 100644 index 0000000..a32b3b8 --- /dev/null +++ b/struct_p_d_b_single_channel.html @@ -0,0 +1,215 @@ + + + + + + +pva2pva: PDBSingleChannel Struct Reference + + + + + + + + + +
+
+ + + + + + +
+
pva2pva +  1.4.1 +
+
+
+ + + + + + + + + +
+ +
+ +
+ +
+
+Inheritance diagram for PDBSingleChannel:
+
+
Inheritance graph
+ + +
[legend]
+
+Collaboration diagram for PDBSingleChannel:
+
+
Collaboration graph
+ + +
[legend]
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Public Member Functions

POINTER_DEFINITIONS (PDBSingleChannel)
 
PDBSingleChannel (const PDBSinglePV::shared_pointer &pv, const epics::pvAccess::ChannelRequester::shared_pointer &req)
 
+virtual
+epics::pvAccess::ChannelPut::shared_pointer 
createChannelPut (epics::pvAccess::ChannelPutRequester::shared_pointer const &requester, epics::pvData::PVStructure::shared_pointer const &pvRequest) OVERRIDE FINAL
 
+virtual
+epics::pvData::Monitor::shared_pointer 
createMonitor (epics::pvData::MonitorRequester::shared_pointer const &requester, epics::pvData::PVStructure::shared_pointer const &pvRequest) OVERRIDE FINAL
 
+virtual void printInfo (std::ostream &out) OVERRIDE FINAL
 
- Public Member Functions inherited from BaseChannel
BaseChannel (const std::string &name, const std::tr1::weak_ptr< epics::pvAccess::ChannelProvider > &prov, const epics::pvAccess::ChannelRequester::shared_pointer &req, const epics::pvData::StructureConstPtr &dtype)
 
+virtual std::string getRequesterName () OVERRIDE
 
+virtual void destroy () OVERRIDE FINAL
 
+virtual std::tr1::shared_ptr
+< epics::pvAccess::ChannelProvider > 
getProvider () OVERRIDE FINAL
 
+virtual std::string getRemoteAddress () OVERRIDE
 
+virtual std::string getChannelName () OVERRIDE FINAL
 
+virtual std::tr1::shared_ptr
+< epics::pvAccess::ChannelRequester > 
getChannelRequester () OVERRIDE FINAL
 
+virtual void getField (epics::pvAccess::GetFieldRequester::shared_pointer const &requester, std::string const &subField) OVERRIDE
 
+ + + + + + + + + + + + + + + + + + +

+Public Attributes

+PDBSinglePV::shared_pointer pv
 
+ASCred cred
 
+ASCLIENT aspvt
 
- Public Attributes inherited from BaseChannel
+epicsMutex lock
 
+const std::string pvname
 
+const
+epics::pvAccess::ChannelProvider::weak_pointer 
provider
 
+const requester_type::weak_pointer requester
 
+const
+epics::pvData::StructureConstPtr 
fielddesc
 
+ + + +

+Static Public Attributes

+static size_t num_instances
 
+ + + + +

+Additional Inherited Members

- Public Types inherited from BaseChannel
+typedef epicsGuard< epicsMutex > guard_t
 
+

Detailed Description

+
+

Definition at line 76 of file pdbsingle.h.

+

The documentation for this struct was generated from the following files: +
+ + + + diff --git a/struct_p_d_b_single_channel__coll__graph.map b/struct_p_d_b_single_channel__coll__graph.map new file mode 100644 index 0000000..6b46e6b --- /dev/null +++ b/struct_p_d_b_single_channel__coll__graph.map @@ -0,0 +1,5 @@ + + + + + diff --git a/struct_p_d_b_single_channel__coll__graph.md5 b/struct_p_d_b_single_channel__coll__graph.md5 new file mode 100644 index 0000000..229c4c5 --- /dev/null +++ b/struct_p_d_b_single_channel__coll__graph.md5 @@ -0,0 +1 @@ +31f17e39ba412b2363a21adde09ed252 \ No newline at end of file diff --git a/struct_p_d_b_single_channel__coll__graph.png b/struct_p_d_b_single_channel__coll__graph.png new file mode 100644 index 0000000..5b82065 Binary files /dev/null and b/struct_p_d_b_single_channel__coll__graph.png differ diff --git a/struct_p_d_b_single_channel__inherit__graph.map b/struct_p_d_b_single_channel__inherit__graph.map new file mode 100644 index 0000000..13048fb --- /dev/null +++ b/struct_p_d_b_single_channel__inherit__graph.map @@ -0,0 +1,3 @@ + + + diff --git a/struct_p_d_b_single_channel__inherit__graph.md5 b/struct_p_d_b_single_channel__inherit__graph.md5 new file mode 100644 index 0000000..4c196ef --- /dev/null +++ b/struct_p_d_b_single_channel__inherit__graph.md5 @@ -0,0 +1 @@ +24cc87335015963525227cb21212d99b \ No newline at end of file diff --git a/struct_p_d_b_single_channel__inherit__graph.png b/struct_p_d_b_single_channel__inherit__graph.png new file mode 100644 index 0000000..d87e19d Binary files /dev/null and b/struct_p_d_b_single_channel__inherit__graph.png differ diff --git a/struct_p_d_b_single_monitor-members.html b/struct_p_d_b_single_monitor-members.html new file mode 100644 index 0000000..38a18b0 --- /dev/null +++ b/struct_p_d_b_single_monitor-members.html @@ -0,0 +1,126 @@ + + + + + + +pva2pva: Member List + + + + + + + + + +
+
+ + + + + + +
+
pva2pva +  1.4.1 +
+
+
+ + + + + + + + + +
+ +
+ +
+
+
+
PDBSingleMonitor Member List
+
+
+ +

This is the complete list of members for PDBSingleMonitor, including all inherited members.

+ + + + + + + + + + + + + + + + + + + + + + + + + + +
BaseMonitor(epicsMutex &lock, const requester_t::weak_pointer &requester, const epics::pvData::PVStructure::shared_pointer &pvReq) (defined in BaseMonitor)BaseMonitorinline
connect(guard_t &guard, const epics::pvData::PVStructurePtr &value)BaseMonitorinline
destroy() OVERRIDE FINAL (defined in PDBSingleMonitor)PDBSingleMonitorvirtual
getStats(Stats &s) const (defined in BaseMonitor)BaseMonitorinlinevirtual
getValue() (defined in BaseMonitor)BaseMonitorinline
guard_t typedef (defined in BaseMonitor)BaseMonitor
lock (defined in BaseMonitor)BaseMonitor
num_instances (defined in PDBSingleMonitor)PDBSingleMonitorstatic
onStart() OVERRIDE FINAL (defined in PDBSingleMonitor)PDBSingleMonitorvirtual
onStop() OVERRIDE FINAL (defined in PDBSingleMonitor)PDBSingleMonitorvirtual
PDBSingleMonitor(const PDBSinglePV::shared_pointer &pv, const requester_t::shared_pointer &requester, const epics::pvData::PVStructure::shared_pointer &pvReq) (defined in PDBSingleMonitor)PDBSingleMonitor
POINTER_DEFINITIONS(PDBSingleMonitor) (defined in PDBSingleMonitor)PDBSingleMonitor
POINTER_DEFINITIONS(BaseMonitor) (defined in BaseMonitor)BaseMonitor
post(guard_t &guard, const epics::pvData::BitSet &updated, no_overflow)BaseMonitorinline
post(guard_t &guard)BaseMonitorinline
post(guard_t &guard, const epics::pvData::BitSet &updated, const epics::pvData::BitSet &overflowed)BaseMonitorinline
post(guard_t &guard, const epics::pvData::BitSet &updated)BaseMonitorinline
pv (defined in PDBSingleMonitor)PDBSingleMonitor
requester_t typedef (defined in BaseMonitor)BaseMonitor
requestUpdate() OVERRIDE FINALPDBSingleMonitorvirtual
shared_from_this() (defined in BaseMonitor)BaseMonitorinline
unguard_t typedef (defined in BaseMonitor)BaseMonitor
weakself (defined in BaseMonitor)BaseMonitor
~BaseMonitor() (defined in BaseMonitor)BaseMonitorinlinevirtual
~PDBSingleMonitor() (defined in PDBSingleMonitor)PDBSingleMonitorvirtual
+ + + + diff --git a/struct_p_d_b_single_monitor.html b/struct_p_d_b_single_monitor.html new file mode 100644 index 0000000..0520b3f --- /dev/null +++ b/struct_p_d_b_single_monitor.html @@ -0,0 +1,248 @@ + + + + + + +pva2pva: PDBSingleMonitor Struct Reference + + + + + + + + + +
+
+ + + + + + +
+
pva2pva +  1.4.1 +
+
+
+ + + + + + + + + +
+ +
+ +
+ +
+
+Inheritance diagram for PDBSingleMonitor:
+
+
Inheritance graph
+ + +
[legend]
+
+Collaboration diagram for PDBSingleMonitor:
+
+
Collaboration graph
+ + +
[legend]
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Public Member Functions

POINTER_DEFINITIONS (PDBSingleMonitor)
 
PDBSingleMonitor (const PDBSinglePV::shared_pointer &pv, const requester_t::shared_pointer &requester, const epics::pvData::PVStructure::shared_pointer &pvReq)
 
+virtual void onStart () OVERRIDE FINAL
 
+virtual void onStop () OVERRIDE FINAL
 
virtual void requestUpdate () OVERRIDE FINAL
 
+virtual void destroy () OVERRIDE FINAL
 
- Public Member Functions inherited from BaseMonitor
POINTER_DEFINITIONS (BaseMonitor)
 
+shared_pointer shared_from_this ()
 
BaseMonitor (epicsMutex &lock, const requester_t::weak_pointer &requester, const epics::pvData::PVStructure::shared_pointer &pvReq)
 
+const
+epics::pvData::PVStructurePtr & 
getValue ()
 
void connect (guard_t &guard, const epics::pvData::PVStructurePtr &value)
 
+bool post (guard_t &guard, const epics::pvData::BitSet &updated, no_overflow)
 post update if queue not full, if full return false w/o overflow
 
+bool post (guard_t &guard)
 post update of pending changes. eg. call from requestUpdate()
 
+bool post (guard_t &guard, const epics::pvData::BitSet &updated, const epics::pvData::BitSet &overflowed)
 post update with changed and overflowed masks (eg. when updates were lost in some upstream queue)
 
+bool post (guard_t &guard, const epics::pvData::BitSet &updated)
 post update with changed
 
+virtual void getStats (Stats &s) const
 
+ + + + + + + + +

+Public Attributes

+const PDBSinglePV::shared_pointer pv
 
- Public Attributes inherited from BaseMonitor
+weak_pointer weakself
 
+epicsMutex & lock
 
+ + + +

+Static Public Attributes

+static size_t num_instances
 
+ + + + + + + + +

+Additional Inherited Members

- Public Types inherited from BaseMonitor
+typedef
+epics::pvAccess::MonitorRequester 
requester_t
 
+typedef epicsGuard< epicsMutex > guard_t
 
+typedef epicsGuardRelease
+< epicsMutex > 
unguard_t
 
+

Detailed Description

+
+

Definition at line 138 of file pdbsingle.h.

+

Member Function Documentation

+ +
+
+ + + + + +
+ + + + + + + +
void PDBSingleMonitor::requestUpdate ()
+
+virtual
+
+

called when within release() when the opportunity exists to end the overflow condition May do nothing, or lock and call post()

+ +

Reimplemented from BaseMonitor.

+ +

Definition at line 485 of file pdbsingle.cpp.

+
486 {
+
487  guard_t G(pv->lock);
+
488  post(G);
+
489 }
+
bool post(guard_t &guard, const epics::pvData::BitSet &updated, no_overflow)
post update if queue not full, if full return false w/o overflow
Definition: pvahelper.h:136
+
+
+
+
The documentation for this struct was generated from the following files: +
+ + + + diff --git a/struct_p_d_b_single_monitor__coll__graph.map b/struct_p_d_b_single_monitor__coll__graph.map new file mode 100644 index 0000000..dd663cc --- /dev/null +++ b/struct_p_d_b_single_monitor__coll__graph.map @@ -0,0 +1,3 @@ + + + diff --git a/struct_p_d_b_single_monitor__coll__graph.md5 b/struct_p_d_b_single_monitor__coll__graph.md5 new file mode 100644 index 0000000..8fc8933 --- /dev/null +++ b/struct_p_d_b_single_monitor__coll__graph.md5 @@ -0,0 +1 @@ +608c19aec9d7f9916c0838a011ba2168 \ No newline at end of file diff --git a/struct_p_d_b_single_monitor__coll__graph.png b/struct_p_d_b_single_monitor__coll__graph.png new file mode 100644 index 0000000..6a73b46 Binary files /dev/null and b/struct_p_d_b_single_monitor__coll__graph.png differ diff --git a/struct_p_d_b_single_monitor__inherit__graph.map b/struct_p_d_b_single_monitor__inherit__graph.map new file mode 100644 index 0000000..dd663cc --- /dev/null +++ b/struct_p_d_b_single_monitor__inherit__graph.map @@ -0,0 +1,3 @@ + + + diff --git a/struct_p_d_b_single_monitor__inherit__graph.md5 b/struct_p_d_b_single_monitor__inherit__graph.md5 new file mode 100644 index 0000000..8fc8933 --- /dev/null +++ b/struct_p_d_b_single_monitor__inherit__graph.md5 @@ -0,0 +1 @@ +608c19aec9d7f9916c0838a011ba2168 \ No newline at end of file diff --git a/struct_p_d_b_single_monitor__inherit__graph.png b/struct_p_d_b_single_monitor__inherit__graph.png new file mode 100644 index 0000000..6a73b46 Binary files /dev/null and b/struct_p_d_b_single_monitor__inherit__graph.png differ diff --git a/struct_p_d_b_single_p_v-members.html b/struct_p_d_b_single_p_v-members.html new file mode 100644 index 0000000..b499daf --- /dev/null +++ b/struct_p_d_b_single_p_v-members.html @@ -0,0 +1,135 @@ + + + + + + +pva2pva: Member List + + + + + + + + + +
+
+ + + + + + +
+
pva2pva +  1.4.1 +
+
+
+ + + + + + + + + +
+ +
+ +
+
+
+
PDBSinglePV Member List
+
+
+ +

This is the complete list of members for PDBSinglePV, including all inherited members.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
activate() (defined in PDBSinglePV)PDBSinglePV
addMonitor(PDBSingleMonitor *) (defined in PDBSinglePV)PDBSinglePV
builder (defined in PDBSinglePV)PDBSinglePV
chan (defined in PDBSinglePV)PDBSinglePV
chan2 (defined in PDBSinglePV)PDBSinglePV
complete (defined in PDBSinglePV)PDBSinglePV
connect(const std::tr1::shared_ptr< PDBProvider > &prov, const epics::pvAccess::ChannelRequester::shared_pointer &req) OVERRIDE FINAL (defined in PDBSinglePV)PDBSinglePVvirtual
evt_PROPERTY (defined in PDBSinglePV)PDBSinglePV
evt_VALUE (defined in PDBSinglePV)PDBSinglePV
fielddesc (defined in PDBPV)PDBPV
finalizeMonitor() (defined in PDBSinglePV)PDBSinglePV
hadevent_PROPERTY (defined in PDBSinglePV)PDBSinglePV
hadevent_VALUE (defined in PDBSinglePV)PDBSinglePV
interested (defined in PDBSinglePV)PDBSinglePV
interested_add (defined in PDBSinglePV)PDBSinglePV
interested_iterating (defined in PDBSinglePV)PDBSinglePV
interested_remove (defined in PDBSinglePV)PDBSinglePV
interested_remove_t typedef (defined in PDBSinglePV)PDBSinglePV
interested_t typedef (defined in PDBSinglePV)PDBSinglePV
lock (defined in PDBSinglePV)PDBSinglePV
num_instances (defined in PDBSinglePV)PDBSinglePVstatic
PDBPV() (defined in PDBPV)PDBPVinline
PDBSinglePV(DBCH &chan, const PDBProvider::shared_pointer &prov) (defined in PDBSinglePV)PDBSinglePV
POINTER_DEFINITIONS(PDBSinglePV) (defined in PDBSinglePV)PDBSinglePV
POINTER_DEFINITIONS(PDBPV) (defined in PDBPV)PDBPV
provider (defined in PDBSinglePV)PDBSinglePV
pvif (defined in PDBSinglePV)PDBSinglePV
removeMonitor(PDBSingleMonitor *) (defined in PDBSinglePV)PDBSinglePV
scratch (defined in PDBSinglePV)PDBSinglePV
shared_from_this() (defined in PDBSinglePV)PDBSinglePVinline
show(int lvl) (defined in PDBPV)PDBPVinlinevirtual
weakself (defined in PDBSinglePV)PDBSinglePV
~PDBPV() (defined in PDBPV)PDBPVinlinevirtual
~PDBSinglePV() (defined in PDBSinglePV)PDBSinglePVvirtual
+ + + + diff --git a/struct_p_d_b_single_p_v.html b/struct_p_d_b_single_p_v.html new file mode 100644 index 0000000..5b2e47e --- /dev/null +++ b/struct_p_d_b_single_p_v.html @@ -0,0 +1,236 @@ + + + + + + +pva2pva: PDBSinglePV Struct Reference + + + + + + + + + +
+
+ + + + + + +
+
pva2pva +  1.4.1 +
+
+
+ + + + + + + + + +
+ +
+ +
+ +
+
+Inheritance diagram for PDBSinglePV:
+
+
Inheritance graph
+ + +
[legend]
+
+Collaboration diagram for PDBSinglePV:
+
+
Collaboration graph
+ + +
[legend]
+ + + + + + +

+Public Types

+typedef std::set
+< PDBSingleMonitor * > 
interested_t
 
+typedef std::set
+< BaseMonitor::shared_pointer > 
interested_remove_t
 
+ + + + + + + + + + + + + + + + + + + + + + +

+Public Member Functions

POINTER_DEFINITIONS (PDBSinglePV)
 
+shared_pointer shared_from_this ()
 
PDBSinglePV (DBCH &chan, const PDBProvider::shared_pointer &prov)
 
+void activate ()
 
+virtual
+epics::pvAccess::Channel::shared_pointer 
connect (const std::tr1::shared_ptr< PDBProvider > &prov, const epics::pvAccess::ChannelRequester::shared_pointer &req) OVERRIDE FINAL
 
+void addMonitor (PDBSingleMonitor *)
 
+void removeMonitor (PDBSingleMonitor *)
 
+void finalizeMonitor ()
 
- Public Member Functions inherited from PDBPV
POINTER_DEFINITIONS (PDBPV)
 
+virtual void show (int lvl)
 
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Public Attributes

+weak_pointer weakself
 
+DBCH chan
 
+DBCH chan2
 
+PDBProvider::shared_pointer provider
 
+epics::pvData::BitSet scratch
 
+epicsMutex lock
 
+p2p::auto_ptr< ScalarBuilderbuilder
 
+p2p::auto_ptr< PVIFpvif
 
+epics::pvData::PVStructurePtr complete
 
+bool interested_iterating
 
+interested_t interested
 
+interested_t interested_add
 
+interested_remove_t interested_remove
 
+DBEvent evt_VALUE
 
+DBEvent evt_PROPERTY
 
+bool hadevent_VALUE
 
+bool hadevent_PROPERTY
 
- Public Attributes inherited from PDBPV
+epics::pvData::StructureConstPtr fielddesc
 
+ + + +

+Static Public Attributes

+static size_t num_instances
 
+

Detailed Description

+
+

Definition at line 21 of file pdbsingle.h.

+

The documentation for this struct was generated from the following files: +
+ + + + diff --git a/struct_p_d_b_single_p_v__coll__graph.map b/struct_p_d_b_single_p_v__coll__graph.map new file mode 100644 index 0000000..13432ae --- /dev/null +++ b/struct_p_d_b_single_p_v__coll__graph.map @@ -0,0 +1,5 @@ + + + + + diff --git a/struct_p_d_b_single_p_v__coll__graph.md5 b/struct_p_d_b_single_p_v__coll__graph.md5 new file mode 100644 index 0000000..a4da2b6 --- /dev/null +++ b/struct_p_d_b_single_p_v__coll__graph.md5 @@ -0,0 +1 @@ +cff779a5aa98266fe97b0248a0807ad2 \ No newline at end of file diff --git a/struct_p_d_b_single_p_v__coll__graph.png b/struct_p_d_b_single_p_v__coll__graph.png new file mode 100644 index 0000000..60c5893 Binary files /dev/null and b/struct_p_d_b_single_p_v__coll__graph.png differ diff --git a/struct_p_d_b_single_p_v__inherit__graph.map b/struct_p_d_b_single_p_v__inherit__graph.map new file mode 100644 index 0000000..699c327 --- /dev/null +++ b/struct_p_d_b_single_p_v__inherit__graph.map @@ -0,0 +1,3 @@ + + + diff --git a/struct_p_d_b_single_p_v__inherit__graph.md5 b/struct_p_d_b_single_p_v__inherit__graph.md5 new file mode 100644 index 0000000..25cbfd3 --- /dev/null +++ b/struct_p_d_b_single_p_v__inherit__graph.md5 @@ -0,0 +1 @@ +88de74815aa0a17d1144d323b11b93e3 \ No newline at end of file diff --git a/struct_p_d_b_single_p_v__inherit__graph.png b/struct_p_d_b_single_p_v__inherit__graph.png new file mode 100644 index 0000000..bdd2004 Binary files /dev/null and b/struct_p_d_b_single_p_v__inherit__graph.png differ diff --git a/struct_p_d_b_single_put-members.html b/struct_p_d_b_single_put-members.html new file mode 100644 index 0000000..07bcfb2 --- /dev/null +++ b/struct_p_d_b_single_put-members.html @@ -0,0 +1,123 @@ + + + + + + +pva2pva: Member List + + + + + + + + + +
+
+ + + + + + +
+
pva2pva +  1.4.1 +
+
+
+ + + + + + + + + +
+ +
+ +
+
+
+
PDBSinglePut Member List
+
+
+ +

This is the complete list of members for PDBSinglePut, including all inherited members.

+ + + + + + + + + + + + + + + + + + + + + + + +
cancel() OVERRIDE FINAL (defined in PDBSinglePut)PDBSinglePutvirtual
changed (defined in PDBSinglePut)PDBSinglePut
channel (defined in PDBSinglePut)PDBSinglePut
destroy() OVERRIDE FINAL (defined in PDBSinglePut)PDBSinglePutinlinevirtual
doProc (defined in PDBSinglePut)PDBSinglePut
doWait (defined in PDBSinglePut)PDBSinglePut
get() OVERRIDE FINAL (defined in PDBSinglePut)PDBSinglePutvirtual
getChannel() OVERRIDE FINAL (defined in PDBSinglePut)PDBSinglePutinlinevirtual
lastRequest() OVERRIDE FINAL (defined in PDBSinglePut)PDBSinglePutinlinevirtual
notify (defined in PDBSinglePut)PDBSinglePut
notifyBusy (defined in PDBSinglePut)PDBSinglePut
num_instances (defined in PDBSinglePut)PDBSinglePutstatic
PDBSinglePut(const PDBSingleChannel::shared_pointer &channel, const epics::pvAccess::ChannelPutRequester::shared_pointer &requester, const epics::pvData::PVStructure::shared_pointer &pvReq) (defined in PDBSinglePut)PDBSinglePut
POINTER_DEFINITIONS(PDBSinglePut) (defined in PDBSinglePut)PDBSinglePut
put(epics::pvData::PVStructure::shared_pointer const &pvPutStructure, epics::pvData::BitSet::shared_pointer const &putBitSet) OVERRIDE FINAL (defined in PDBSinglePut)PDBSinglePutvirtual
pvf (defined in PDBSinglePut)PDBSinglePut
pvif (defined in PDBSinglePut)PDBSinglePut
requester (defined in PDBSinglePut)PDBSinglePut
requester_t typedef (defined in PDBSinglePut)PDBSinglePut
wait_changed (defined in PDBSinglePut)PDBSinglePut
wait_pvif (defined in PDBSinglePut)PDBSinglePut
~PDBSinglePut() (defined in PDBSinglePut)PDBSinglePutvirtual
+ + + + diff --git a/struct_p_d_b_single_put.html b/struct_p_d_b_single_put.html new file mode 100644 index 0000000..95b9ad0 --- /dev/null +++ b/struct_p_d_b_single_put.html @@ -0,0 +1,199 @@ + + + + + + +pva2pva: PDBSinglePut Struct Reference + + + + + + + + + +
+
+ + + + + + +
+
pva2pva +  1.4.1 +
+
+
+ + + + + + + + + +
+ +
+ +
+ +
+
+Inheritance diagram for PDBSinglePut:
+
+
Inheritance graph
+
[legend]
+
+Collaboration diagram for PDBSinglePut:
+
+
Collaboration graph
+
[legend]
+ + + + +

+Public Types

+typedef
+epics::pvAccess::ChannelPutRequester 
requester_t
 
+ + + + + + + + + + + + + + + + + +

+Public Member Functions

POINTER_DEFINITIONS (PDBSinglePut)
 
PDBSinglePut (const PDBSingleChannel::shared_pointer &channel, const epics::pvAccess::ChannelPutRequester::shared_pointer &requester, const epics::pvData::PVStructure::shared_pointer &pvReq)
 
+virtual void destroy () OVERRIDE FINAL
 
+virtual std::tr1::shared_ptr
+< epics::pvAccess::Channel > 
getChannel () OVERRIDE FINAL
 
+virtual void cancel () OVERRIDE FINAL
 
+virtual void lastRequest () OVERRIDE FINAL
 
+virtual void put (epics::pvData::PVStructure::shared_pointer const &pvPutStructure, epics::pvData::BitSet::shared_pointer const &putBitSet) OVERRIDE FINAL
 
+virtual void get () OVERRIDE FINAL
 
+ + + + + + + + + + + + + + + + + + + + + + + +

+Public Attributes

+PDBSingleChannel::shared_pointer channel
 
+requester_t::weak_pointer requester
 
+epics::pvData::BitSetPtr changed
 
+epics::pvData::BitSetPtr wait_changed
 
+epics::pvData::PVStructurePtr pvf
 
+p2p::auto_ptr< PVIFpvif
 
+p2p::auto_ptr< PVIFwait_pvif
 
+processNotify notify
 
+int notifyBusy
 
+PVIF::proc_t doProc
 
+bool doWait
 
+ + + +

+Static Public Attributes

+static size_t num_instances
 
+

Detailed Description

+
+

Definition at line 102 of file pdbsingle.h.

+

The documentation for this struct was generated from the following files: +
+ + + + diff --git a/struct_p_d_b_single_put__coll__graph.map b/struct_p_d_b_single_put__coll__graph.map new file mode 100644 index 0000000..57d3aa1 --- /dev/null +++ b/struct_p_d_b_single_put__coll__graph.map @@ -0,0 +1,2 @@ + + diff --git a/struct_p_d_b_single_put__coll__graph.md5 b/struct_p_d_b_single_put__coll__graph.md5 new file mode 100644 index 0000000..71303d0 --- /dev/null +++ b/struct_p_d_b_single_put__coll__graph.md5 @@ -0,0 +1 @@ +05da203783c28c046d28230f5770f6d0 \ No newline at end of file diff --git a/struct_p_d_b_single_put__coll__graph.png b/struct_p_d_b_single_put__coll__graph.png new file mode 100644 index 0000000..983624d Binary files /dev/null and b/struct_p_d_b_single_put__coll__graph.png differ diff --git a/struct_p_d_b_single_put__inherit__graph.map b/struct_p_d_b_single_put__inherit__graph.map new file mode 100644 index 0000000..57d3aa1 --- /dev/null +++ b/struct_p_d_b_single_put__inherit__graph.map @@ -0,0 +1,2 @@ + + diff --git a/struct_p_d_b_single_put__inherit__graph.md5 b/struct_p_d_b_single_put__inherit__graph.md5 new file mode 100644 index 0000000..71303d0 --- /dev/null +++ b/struct_p_d_b_single_put__inherit__graph.md5 @@ -0,0 +1 @@ +05da203783c28c046d28230f5770f6d0 \ No newline at end of file diff --git a/struct_p_d_b_single_put__inherit__graph.png b/struct_p_d_b_single_put__inherit__graph.png new file mode 100644 index 0000000..983624d Binary files /dev/null and b/struct_p_d_b_single_put__inherit__graph.png differ diff --git a/struct_p_v_i_f-members.html b/struct_p_v_i_f-members.html new file mode 100644 index 0000000..dbf8e9a --- /dev/null +++ b/struct_p_v_i_f-members.html @@ -0,0 +1,111 @@ + + + + + + +pva2pva: Member List + + + + + + + + + +
+
+ + + + + + +
+
pva2pva +  1.4.1 +
+
+
+ + + + + + + + + +
+ +
+ +
+
+
+
PVIF Member List
+
+
+ +

This is the complete list of members for PVIF, including all inherited members.

+ + + + + + + + + + + +
chan (defined in PVIF)PVIF
dbe(const epics::pvData::BitSet &mask)=0PVIFpure virtual
get(const epics::pvData::BitSet &mask, proc_t proc=ProcInhibit, bool permit=true)=0PVIFpure virtual
proc_t enum name (defined in PVIF)PVIF
ProcForce enum value (defined in PVIF)PVIF
ProcInhibit enum value (defined in PVIF)PVIF
ProcPassive enum value (defined in PVIF)PVIF
put(epics::pvData::BitSet &mask, unsigned dbe, db_field_log *pfl)=0PVIFpure virtual
PVIF(dbChannel *ch) (defined in PVIF)PVIF
~PVIF() (defined in PVIF)PVIFinlinevirtual
+ + + + diff --git a/struct_p_v_i_f.html b/struct_p_v_i_f.html new file mode 100644 index 0000000..7bc2b16 --- /dev/null +++ b/struct_p_v_i_f.html @@ -0,0 +1,259 @@ + + + + + + +pva2pva: PVIF Struct Reference + + + + + + + + + +
+
+ + + + + + +
+
pva2pva +  1.4.1 +
+
+
+ + + + + + + + + +
+ +
+ +
+
+ +
+
PVIF Struct Referenceabstract
+
+
+ + + + +

+Public Types

enum  proc_t { ProcPassive, +ProcInhibit, +ProcForce + }
 
+ + + + + + + + + + +

+Public Member Functions

PVIF (dbChannel *ch)
 
virtual void put (epics::pvData::BitSet &mask, unsigned dbe, db_field_log *pfl)=0
 
virtual epics::pvData::Status get (const epics::pvData::BitSet &mask, proc_t proc=ProcInhibit, bool permit=true)=0
 
+virtual unsigned dbe (const epics::pvData::BitSet &mask)=0
 Calculate DBE mask from changed bitset.
 
+ + + +

+Public Attributes

+dbChannel *const chan
 
+

Detailed Description

+
+

Definition at line 365 of file pvif.h.

+

Member Function Documentation

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + +
pvd::Status PVIF::get (const epics::pvData::BitSet & mask,
proc_t proc = ProcInhibit,
bool permit = true 
)
+
+pure virtual
+
+

May copy from pvalue to PDB record (call dbChannelPut()) caller must lock record

+ +

Definition at line 1262 of file pvif.cpp.

+
1263 {
+
1264  dbCommon *precord = dbChannelRecord(chan);
+
1265 
+
1266  bool tryproc = proc!=ProcPassive ? proc==ProcForce :
+
1267  dbChannelField(chan) == &precord->proc ||
+
1268  (dbChannelFldDes(chan)->process_passive &&
+
1269  precord->scan == 0);
+
1270 
+
1271  pvd::Status ret;
+
1272 
+
1273  if (tryproc) {
+
1274  if (!permit) {
+
1275  return pvd::Status::error("Process not permitted");
+
1276 
+
1277  } else if (precord->pact) {
+
1278  if (precord->tpro)
+
1279  printf("%s: Active %s\n",
+
1280  epicsThreadGetNameSelf(), precord->name);
+
1281  precord->rpro = TRUE;
+
1282  } else {
+
1283  /* indicate that dbPutField called dbProcess */
+
1284  precord->putf = TRUE;
+
1285  long err = dbProcess(precord);
+
1286  if(err) {
+
1287  char buf[32];
+
1288  errSymLookup(err, buf, sizeof(buf));
+
1289  std::ostringstream msg;
+
1290  msg<<"process error : "<<buf;
+
1291  ret = pvd::Status::error(msg.str());
+
1292  }
+
1293  }
+
1294  }
+
1295 
+
1296  return ret;
+
1297 }
+
+
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + +
virtual void PVIF::put (epics::pvData::BitSet & mask,
unsigned dbe,
db_field_log * pfl 
)
+
+pure virtual
+
+

Copy from PDB record to pvalue (call dbChannelGet()) caller must lock record

+ +
+
+
The documentation for this struct was generated from the following files: +
+ + + + diff --git a/struct_p_v_i_f_builder-members.html b/struct_p_v_i_f_builder-members.html new file mode 100644 index 0000000..0761e55 --- /dev/null +++ b/struct_p_v_i_f_builder-members.html @@ -0,0 +1,108 @@ + + + + + + +pva2pva: Member List + + + + + + + + + +
+
+ + + + + + +
+
pva2pva +  1.4.1 +
+
+
+ + + + + + + + + +
+ +
+ +
+
+
+
PVIFBuilder Member List
+
+
+ +

This is the complete list of members for PVIFBuilder, including all inherited members.

+ + + + + + + + +
attach(const epics::pvData::PVStructurePtr &root, const FieldName &fld)=0 (defined in PVIFBuilder)PVIFBuilderpure virtual
channel (defined in PVIFBuilder)PVIFBuilder
create(const std::string &mapname, dbChannel *chan) (defined in PVIFBuilder)PVIFBuilderstatic
dtype()=0 (defined in PVIFBuilder)PVIFBuilderpure virtual
dtype(epics::pvData::FieldBuilderPtr &builder, const std::string &fld) (defined in PVIFBuilder)PVIFBuildervirtual
PVIFBuilder(dbChannel *chan) (defined in PVIFBuilder)PVIFBuilderinlineexplicitprotected
~PVIFBuilder() (defined in PVIFBuilder)PVIFBuilderinlinevirtual
+ + + + diff --git a/struct_p_v_i_f_builder.html b/struct_p_v_i_f_builder.html new file mode 100644 index 0000000..f818473 --- /dev/null +++ b/struct_p_v_i_f_builder.html @@ -0,0 +1,157 @@ + + + + + + +pva2pva: PVIFBuilder Struct Reference + + + + + + + + + +
+
+ + + + + + +
+
pva2pva +  1.4.1 +
+
+
+ + + + + + + + + +
+ +
+ +
+ +
+ +

#include <pvif.h>

+
+Inheritance diagram for PVIFBuilder:
+
+
Inheritance graph
+ + +
[legend]
+ + + + + + + + +

+Public Member Functions

+virtual
+epics::pvData::FieldConstPtr 
dtype ()=0
 
+virtual
+epics::pvData::FieldBuilderPtr 
dtype (epics::pvData::FieldBuilderPtr &builder, const std::string &fld)
 
+virtual PVIFattach (const epics::pvData::PVStructurePtr &root, const FieldName &fld)=0
 
+ + + +

+Static Public Member Functions

+static PVIFBuildercreate (const std::string &mapname, dbChannel *chan)
 
+ + + +

+Public Attributes

+dbChannel *const channel
 
+ + + +

+Protected Member Functions

PVIFBuilder (dbChannel *chan)
 
+

Detailed Description

+

Factory for PVIF instances.

+

Caller first passes a mapping type (eg. "scalar") to PVIFBuilder::create() to obtain a PVIFBuilder which may then by used to create PVIF instances for specific dbChannel.

+

Caller than uses PVIFBuilder::dtype() to obtain (sub)Field descriptions. eg. more than one of these may be composed into an overall Structure description.

+

Caller than creates a PVStructure and uses PVIFBuilder::attach() to build mappings for each dbChannel in the composed locations.

+ +

Definition at line 403 of file pvif.h.

+

The documentation for this struct was generated from the following files: +
+ + + + diff --git a/struct_p_v_i_f_builder__inherit__graph.map b/struct_p_v_i_f_builder__inherit__graph.map new file mode 100644 index 0000000..1b9953b --- /dev/null +++ b/struct_p_v_i_f_builder__inherit__graph.map @@ -0,0 +1,3 @@ + + + diff --git a/struct_p_v_i_f_builder__inherit__graph.md5 b/struct_p_v_i_f_builder__inherit__graph.md5 new file mode 100644 index 0000000..4c4cacc --- /dev/null +++ b/struct_p_v_i_f_builder__inherit__graph.md5 @@ -0,0 +1 @@ +eb0bd51a49052b6f6ea2f55e318c1ee7 \ No newline at end of file diff --git a/struct_p_v_i_f_builder__inherit__graph.png b/struct_p_v_i_f_builder__inherit__graph.png new file mode 100644 index 0000000..d3a91c4 Binary files /dev/null and b/struct_p_v_i_f_builder__inherit__graph.png differ diff --git a/struct_s_b-members.html b/struct_s_b-members.html new file mode 100644 index 0000000..cc9933c --- /dev/null +++ b/struct_s_b-members.html @@ -0,0 +1,105 @@ + + + + + + +pva2pva: Member List + + + + + + + + + +
+
+ + + + + + +
+
pva2pva +  1.4.1 +
+
+
+ + + + + + + + + +
+ +
+ +
+
+
+
SB Member List
+
+
+ +

This is the complete list of members for SB, including all inherited members.

+ + + + + +
operator std::string() const (defined in SB)SBinline
operator<<(T i) (defined in SB)SBinline
SB() (defined in SB)SBinline
strm (defined in SB)SB
+ + + + diff --git a/struct_s_b.html b/struct_s_b.html new file mode 100644 index 0000000..ac41d0e --- /dev/null +++ b/struct_s_b.html @@ -0,0 +1,125 @@ + + + + + + +pva2pva: SB Struct Reference + + + + + + + + + +
+
+ + + + + + +
+
pva2pva +  1.4.1 +
+
+
+ + + + + + + + + +
+ +
+ +
+ +
+ + + + + + + +

+Public Member Functions

operator std::string () const
 
+template<typename T >
SBoperator<< (T i)
 
+ + + +

+Public Attributes

+std::ostringstream strm
 
+

Detailed Description

+
+

Definition at line 8 of file sb.h.

+

The documentation for this struct was generated from the following file: +
+ + + + diff --git a/struct_scalar_accessor-members.html b/struct_scalar_accessor-members.html new file mode 100644 index 0000000..51d7a23 --- /dev/null +++ b/struct_scalar_accessor-members.html @@ -0,0 +1,107 @@ + + + + + + +pva2pva: Member List + + + + + + + + + +
+
+ + + + + + +
+
pva2pva +  1.4.1 +
+
+
+ + + + + + + + + +
+ +
+ +
+
+
+
ScalarAccessor< T > Member List
+
+
+ +

This is the complete list of members for ScalarAccessor< T >, including all inherited members.

+ + + + + + + +
field (defined in ScalarAccessor< T >)ScalarAccessor< T >
operator value_type() (defined in ScalarAccessor< T >)ScalarAccessor< T >inline
operator+=(T v) (defined in ScalarAccessor< T >)ScalarAccessor< T >inline
operator=(T v) (defined in ScalarAccessor< T >)ScalarAccessor< T >inline
ScalarAccessor(const epics::pvData::PVStructurePtr &s, const char *name) (defined in ScalarAccessor< T >)ScalarAccessor< T >inline
value_type typedef (defined in ScalarAccessor< T >)ScalarAccessor< T >
+ + + + diff --git a/struct_scalar_accessor.html b/struct_scalar_accessor.html new file mode 100644 index 0000000..af18cf0 --- /dev/null +++ b/struct_scalar_accessor.html @@ -0,0 +1,140 @@ + + + + + + +pva2pva: ScalarAccessor< T > Struct Template Reference + + + + + + + + + +
+
+ + + + + + +
+
pva2pva +  1.4.1 +
+
+
+ + + + + + + + + +
+ +
+ +
+
+ +
+
ScalarAccessor< T > Struct Template Reference
+
+
+ + + + +

+Public Types

+typedef T value_type
 
+ + + + + + + + + +

+Public Member Functions

ScalarAccessor (const epics::pvData::PVStructurePtr &s, const char *name)
 
operator value_type ()
 
+ScalarAccessoroperator= (T v)
 
+ScalarAccessoroperator+= (T v)
 
+ + + +

+Public Attributes

+epics::pvData::PVScalar::shared_pointer field
 
+

Detailed Description

+

template<typename T>
+struct ScalarAccessor< T >

+ + +

Definition at line 38 of file utilities.h.

+

The documentation for this struct was generated from the following file: +
+ + + + diff --git a/struct_scalar_builder-members.html b/struct_scalar_builder-members.html new file mode 100644 index 0000000..c80540c --- /dev/null +++ b/struct_scalar_builder-members.html @@ -0,0 +1,110 @@ + + + + + + +pva2pva: Member List + + + + + + + + + +
+
+ + + + + + +
+
pva2pva +  1.4.1 +
+
+
+ + + + + + + + + +
+ +
+ +
+
+
+
ScalarBuilder Member List
+
+
+ +

This is the complete list of members for ScalarBuilder, including all inherited members.

+ + + + + + + + + + +
attach(const epics::pvData::PVStructurePtr &root, const FieldName &fld) OVERRIDE FINAL (defined in ScalarBuilder)ScalarBuildervirtual
channel (defined in PVIFBuilder)PVIFBuilder
create(const std::string &mapname, dbChannel *chan) (defined in PVIFBuilder)PVIFBuilderstatic
dtype() OVERRIDE FINAL (defined in ScalarBuilder)ScalarBuildervirtual
dtype(epics::pvData::FieldBuilderPtr &builder, const std::string &fld) (defined in PVIFBuilder)PVIFBuildervirtual
PVIFBuilder(dbChannel *chan) (defined in PVIFBuilder)PVIFBuilderinlineexplicitprotected
ScalarBuilder(dbChannel *chan) (defined in ScalarBuilder)ScalarBuilderinlineexplicit
~PVIFBuilder() (defined in PVIFBuilder)PVIFBuilderinlinevirtual
~ScalarBuilder() (defined in ScalarBuilder)ScalarBuilderinlinevirtual
+ + + + diff --git a/struct_scalar_builder.html b/struct_scalar_builder.html new file mode 100644 index 0000000..c4a4fb3 --- /dev/null +++ b/struct_scalar_builder.html @@ -0,0 +1,156 @@ + + + + + + +pva2pva: ScalarBuilder Struct Reference + + + + + + + + + +
+
+ + + + + + +
+
pva2pva +  1.4.1 +
+
+
+ + + + + + + + + +
+ +
+ +
+
+ +
+
ScalarBuilder Struct Reference
+
+
+
+Inheritance diagram for ScalarBuilder:
+
+
Inheritance graph
+ + +
[legend]
+
+Collaboration diagram for ScalarBuilder:
+
+
Collaboration graph
+ + +
[legend]
+ + + + + + + + + + + +

+Public Member Functions

ScalarBuilder (dbChannel *chan)
 
+virtual
+epics::pvData::FieldConstPtr 
dtype () OVERRIDE FINAL
 
+virtual PVIFattach (const epics::pvData::PVStructurePtr &root, const FieldName &fld) OVERRIDE FINAL
 
- Public Member Functions inherited from PVIFBuilder
+virtual
+epics::pvData::FieldBuilderPtr 
dtype (epics::pvData::FieldBuilderPtr &builder, const std::string &fld)
 
+ + + + + + + + + + +

+Additional Inherited Members

- Static Public Member Functions inherited from PVIFBuilder
+static PVIFBuildercreate (const std::string &mapname, dbChannel *chan)
 
- Public Attributes inherited from PVIFBuilder
+dbChannel *const channel
 
- Protected Member Functions inherited from PVIFBuilder
PVIFBuilder (dbChannel *chan)
 
+

Detailed Description

+
+

Definition at line 429 of file pvif.h.

+

The documentation for this struct was generated from the following files: +
+ + + + diff --git a/struct_scalar_builder__coll__graph.map b/struct_scalar_builder__coll__graph.map new file mode 100644 index 0000000..b3f4cd2 --- /dev/null +++ b/struct_scalar_builder__coll__graph.map @@ -0,0 +1,3 @@ + + + diff --git a/struct_scalar_builder__coll__graph.md5 b/struct_scalar_builder__coll__graph.md5 new file mode 100644 index 0000000..f33dba6 --- /dev/null +++ b/struct_scalar_builder__coll__graph.md5 @@ -0,0 +1 @@ +5bc6dc15778ea4680c1b63fa7c2c7177 \ No newline at end of file diff --git a/struct_scalar_builder__coll__graph.png b/struct_scalar_builder__coll__graph.png new file mode 100644 index 0000000..45c8237 Binary files /dev/null and b/struct_scalar_builder__coll__graph.png differ diff --git a/struct_scalar_builder__inherit__graph.map b/struct_scalar_builder__inherit__graph.map new file mode 100644 index 0000000..b3f4cd2 --- /dev/null +++ b/struct_scalar_builder__inherit__graph.map @@ -0,0 +1,3 @@ + + + diff --git a/struct_scalar_builder__inherit__graph.md5 b/struct_scalar_builder__inherit__graph.md5 new file mode 100644 index 0000000..f33dba6 --- /dev/null +++ b/struct_scalar_builder__inherit__graph.md5 @@ -0,0 +1 @@ +5bc6dc15778ea4680c1b63fa7c2c7177 \ No newline at end of file diff --git a/struct_scalar_builder__inherit__graph.png b/struct_scalar_builder__inherit__graph.png new file mode 100644 index 0000000..45c8237 Binary files /dev/null and b/struct_scalar_builder__inherit__graph.png differ diff --git a/struct_server_config-members.html b/struct_server_config-members.html new file mode 100644 index 0000000..1fdcef1 --- /dev/null +++ b/struct_server_config-members.html @@ -0,0 +1,112 @@ + + + + + + +pva2pva: Member List + + + + + + + + + +
+
+ + + + + + +
+
pva2pva +  1.4.1 +
+
+
+ + + + + + + + + +
+ +
+ +
+
+
+
ServerConfig Member List
+
+
+ +

This is the complete list of members for ServerConfig, including all inherited members.

+ + + + + + + + + + + + +
clients (defined in ServerConfig)ServerConfig
clients_t typedef (defined in ServerConfig)ServerConfig
conf (defined in ServerConfig)ServerConfig
debug (defined in ServerConfig)ServerConfig
drop(const char *client, const char *channel) (defined in ServerConfig)ServerConfig
interactive (defined in ServerConfig)ServerConfig
ServerConfig() (defined in ServerConfig)ServerConfiginline
servers (defined in ServerConfig)ServerConfig
servers_t typedef (defined in ServerConfig)ServerConfig
status_client(int lvl, const char *client, const char *channel) (defined in ServerConfig)ServerConfig
status_server(int lvl, const char *server) (defined in ServerConfig)ServerConfig
+ + + + diff --git a/struct_server_config.html b/struct_server_config.html new file mode 100644 index 0000000..2e7938e --- /dev/null +++ b/struct_server_config.html @@ -0,0 +1,152 @@ + + + + + + +pva2pva: ServerConfig Struct Reference + + + + + + + + + +
+
+ + + + + + +
+
pva2pva +  1.4.1 +
+
+
+ + + + + + + + + +
+ +
+ +
+
+ +
+
ServerConfig Struct Reference
+
+
+ + + + + + +

+Public Types

+typedef std::map< std::string,
+GWServerChannelProvider::shared_pointer > 
clients_t
 
+typedef std::map< std::string,
+epics::pvAccess::ServerContext::shared_pointer > 
servers_t
 
+ + + + + + + +

+Public Member Functions

+void drop (const char *client, const char *channel)
 
+void status_server (int lvl, const char *server)
 
+void status_client (int lvl, const char *client, const char *channel)
 
+ + + + + + + + + + + +

+Public Attributes

+int debug
 
+bool interactive
 
+epics::pvData::PVStructure::shared_pointer conf
 
+clients_t clients
 
+servers_t servers
 
+

Detailed Description

+
+

Definition at line 38 of file server.h.

+

The documentation for this struct was generated from the following files: +
+ + + + diff --git a/struct_test_channel_field_requester-members.html b/struct_test_channel_field_requester-members.html new file mode 100644 index 0000000..f98ea15 --- /dev/null +++ b/struct_test_channel_field_requester-members.html @@ -0,0 +1,108 @@ + + + + + + +pva2pva: Member List + + + + + + + + + +
+
+ + + + + + +
+
pva2pva +  1.4.1 +
+
+
+ + + + + + + + + +
+ +
+ +
+
+
+
TestChannelFieldRequester Member List
+
+
+ +

This is the complete list of members for TestChannelFieldRequester, including all inherited members.

+ + + + + + + + +
done (defined in TestChannelFieldRequester)TestChannelFieldRequester
fielddesc (defined in TestChannelFieldRequester)TestChannelFieldRequester
getDone(const epics::pvData::Status &status, epics::pvData::FieldConstPtr const &field) (defined in TestChannelFieldRequester)TestChannelFieldRequesterinlinevirtual
POINTER_DEFINITIONS(TestChannelFieldRequester) (defined in TestChannelFieldRequester)TestChannelFieldRequester
status (defined in TestChannelFieldRequester)TestChannelFieldRequester
TestChannelFieldRequester() (defined in TestChannelFieldRequester)TestChannelFieldRequesterinline
~TestChannelFieldRequester() (defined in TestChannelFieldRequester)TestChannelFieldRequesterinlinevirtual
+ + + + diff --git a/struct_test_channel_field_requester.html b/struct_test_channel_field_requester.html new file mode 100644 index 0000000..53eeaec --- /dev/null +++ b/struct_test_channel_field_requester.html @@ -0,0 +1,140 @@ + + + + + + +pva2pva: TestChannelFieldRequester Struct Reference + + + + + + + + + +
+
+ + + + + + +
+
pva2pva +  1.4.1 +
+
+
+ + + + + + + + + +
+ +
+ +
+
+ +
+
TestChannelFieldRequester Struct Reference
+
+
+
+Inheritance diagram for TestChannelFieldRequester:
+
+
Inheritance graph
+
[legend]
+
+Collaboration diagram for TestChannelFieldRequester:
+
+
Collaboration graph
+
[legend]
+ + + + + + +

+Public Member Functions

POINTER_DEFINITIONS (TestChannelFieldRequester)
 
+virtual void getDone (const epics::pvData::Status &status, epics::pvData::FieldConstPtr const &field)
 
+ + + + + + + +

+Public Attributes

+bool done
 
+epics::pvData::Status status
 
+epics::pvData::FieldConstPtr fielddesc
 
+

Detailed Description

+
+

Definition at line 75 of file utilities.h.

+

The documentation for this struct was generated from the following file: +
+ + + + diff --git a/struct_test_channel_field_requester__coll__graph.map b/struct_test_channel_field_requester__coll__graph.map new file mode 100644 index 0000000..28bb8fe --- /dev/null +++ b/struct_test_channel_field_requester__coll__graph.map @@ -0,0 +1,2 @@ + + diff --git a/struct_test_channel_field_requester__coll__graph.md5 b/struct_test_channel_field_requester__coll__graph.md5 new file mode 100644 index 0000000..c8ea5bd --- /dev/null +++ b/struct_test_channel_field_requester__coll__graph.md5 @@ -0,0 +1 @@ +6e6db236b6a355b9a100c9ec6abf8357 \ No newline at end of file diff --git a/struct_test_channel_field_requester__coll__graph.png b/struct_test_channel_field_requester__coll__graph.png new file mode 100644 index 0000000..1c258a1 Binary files /dev/null and b/struct_test_channel_field_requester__coll__graph.png differ diff --git a/struct_test_channel_field_requester__inherit__graph.map b/struct_test_channel_field_requester__inherit__graph.map new file mode 100644 index 0000000..28bb8fe --- /dev/null +++ b/struct_test_channel_field_requester__inherit__graph.map @@ -0,0 +1,2 @@ + + diff --git a/struct_test_channel_field_requester__inherit__graph.md5 b/struct_test_channel_field_requester__inherit__graph.md5 new file mode 100644 index 0000000..c8ea5bd --- /dev/null +++ b/struct_test_channel_field_requester__inherit__graph.md5 @@ -0,0 +1 @@ +6e6db236b6a355b9a100c9ec6abf8357 \ No newline at end of file diff --git a/struct_test_channel_field_requester__inherit__graph.png b/struct_test_channel_field_requester__inherit__graph.png new file mode 100644 index 0000000..1c258a1 Binary files /dev/null and b/struct_test_channel_field_requester__inherit__graph.png differ diff --git a/struct_test_channel_get_requester-members.html b/struct_test_channel_get_requester-members.html new file mode 100644 index 0000000..d374d52 --- /dev/null +++ b/struct_test_channel_get_requester-members.html @@ -0,0 +1,114 @@ + + + + + + +pva2pva: Member List + + + + + + + + + +
+
+ + + + + + +
+
pva2pva +  1.4.1 +
+
+
+ + + + + + + + + +
+ +
+ +
+
+
+
TestChannelGetRequester Member List
+
+
+ +

This is the complete list of members for TestChannelGetRequester, including all inherited members.

+ + + + + + + + + + + + + + +
changed (defined in TestChannelGetRequester)TestChannelGetRequester
channelGet (defined in TestChannelGetRequester)TestChannelGetRequester
channelGetConnect(const epics::pvData::Status &status, epics::pvAccess::ChannelGet::shared_pointer const &channelGet, epics::pvData::Structure::const_shared_pointer const &structure) (defined in TestChannelGetRequester)TestChannelGetRequestervirtual
connected (defined in TestChannelGetRequester)TestChannelGetRequester
done (defined in TestChannelGetRequester)TestChannelGetRequester
fielddesc (defined in TestChannelGetRequester)TestChannelGetRequester
getDone(const epics::pvData::Status &status, epics::pvAccess::ChannelGet::shared_pointer const &channelGet, epics::pvData::PVStructure::shared_pointer const &pvStructure, epics::pvData::BitSet::shared_pointer const &bitSet) (defined in TestChannelGetRequester)TestChannelGetRequestervirtual
POINTER_DEFINITIONS(TestChannelGetRequester) (defined in TestChannelGetRequester)TestChannelGetRequester
statusConnect (defined in TestChannelGetRequester)TestChannelGetRequester
statusDone (defined in TestChannelGetRequester)TestChannelGetRequester
TestChannelGetRequester() (defined in TestChannelGetRequester)TestChannelGetRequester
value (defined in TestChannelGetRequester)TestChannelGetRequester
~TestChannelGetRequester() (defined in TestChannelGetRequester)TestChannelGetRequestervirtual
+ + + + diff --git a/struct_test_channel_get_requester.html b/struct_test_channel_get_requester.html new file mode 100644 index 0000000..ad629fe --- /dev/null +++ b/struct_test_channel_get_requester.html @@ -0,0 +1,159 @@ + + + + + + +pva2pva: TestChannelGetRequester Struct Reference + + + + + + + + + +
+
+ + + + + + +
+
pva2pva +  1.4.1 +
+
+
+ + + + + + + + + +
+ +
+ +
+
+ +
+
TestChannelGetRequester Struct Reference
+
+
+
+Inheritance diagram for TestChannelGetRequester:
+
+
Inheritance graph
+
[legend]
+
+Collaboration diagram for TestChannelGetRequester:
+
+
Collaboration graph
+
[legend]
+ + + + + + + + +

+Public Member Functions

POINTER_DEFINITIONS (TestChannelGetRequester)
 
+virtual void channelGetConnect (const epics::pvData::Status &status, epics::pvAccess::ChannelGet::shared_pointer const &channelGet, epics::pvData::Structure::const_shared_pointer const &structure)
 
+virtual void getDone (const epics::pvData::Status &status, epics::pvAccess::ChannelGet::shared_pointer const &channelGet, epics::pvData::PVStructure::shared_pointer const &pvStructure, epics::pvData::BitSet::shared_pointer const &bitSet)
 
+ + + + + + + + + + + + + + + + + +

+Public Attributes

+bool connected
 
+bool done
 
+epics::pvData::Status statusConnect
 
+epics::pvData::Status statusDone
 
+epics::pvAccess::ChannelGet::shared_pointer channelGet
 
+epics::pvData::Structure::const_shared_pointer fielddesc
 
+epics::pvData::PVStructure::shared_pointer value
 
+epics::pvData::BitSet::shared_pointer changed
 
+

Detailed Description

+
+

Definition at line 97 of file utilities.h.

+

The documentation for this struct was generated from the following files: +
+ + + + diff --git a/struct_test_channel_get_requester__coll__graph.map b/struct_test_channel_get_requester__coll__graph.map new file mode 100644 index 0000000..b790be9 --- /dev/null +++ b/struct_test_channel_get_requester__coll__graph.map @@ -0,0 +1,2 @@ + + diff --git a/struct_test_channel_get_requester__coll__graph.md5 b/struct_test_channel_get_requester__coll__graph.md5 new file mode 100644 index 0000000..007be94 --- /dev/null +++ b/struct_test_channel_get_requester__coll__graph.md5 @@ -0,0 +1 @@ +516ab33126719ac946571ff8639bb9c1 \ No newline at end of file diff --git a/struct_test_channel_get_requester__coll__graph.png b/struct_test_channel_get_requester__coll__graph.png new file mode 100644 index 0000000..1ab12d9 Binary files /dev/null and b/struct_test_channel_get_requester__coll__graph.png differ diff --git a/struct_test_channel_get_requester__inherit__graph.map b/struct_test_channel_get_requester__inherit__graph.map new file mode 100644 index 0000000..b790be9 --- /dev/null +++ b/struct_test_channel_get_requester__inherit__graph.map @@ -0,0 +1,2 @@ + + diff --git a/struct_test_channel_get_requester__inherit__graph.md5 b/struct_test_channel_get_requester__inherit__graph.md5 new file mode 100644 index 0000000..007be94 --- /dev/null +++ b/struct_test_channel_get_requester__inherit__graph.md5 @@ -0,0 +1 @@ +516ab33126719ac946571ff8639bb9c1 \ No newline at end of file diff --git a/struct_test_channel_get_requester__inherit__graph.png b/struct_test_channel_get_requester__inherit__graph.png new file mode 100644 index 0000000..1ab12d9 Binary files /dev/null and b/struct_test_channel_get_requester__inherit__graph.png differ diff --git a/struct_test_channel_monitor_requester-members.html b/struct_test_channel_monitor_requester-members.html new file mode 100644 index 0000000..b62c69d --- /dev/null +++ b/struct_test_channel_monitor_requester-members.html @@ -0,0 +1,117 @@ + + + + + + +pva2pva: Member List + + + + + + + + + +
+
+ + + + + + +
+
pva2pva +  1.4.1 +
+
+
+ + + + + + + + + +
+ +
+ +
+
+
+
TestChannelMonitorRequester Member List
+
+
+ +

This is the complete list of members for TestChannelMonitorRequester, including all inherited members.

+ + + + + + + + + + + + + + + + + +
connected (defined in TestChannelMonitorRequester)TestChannelMonitorRequester
connectStatus (defined in TestChannelMonitorRequester)TestChannelMonitorRequester
dtype (defined in TestChannelMonitorRequester)TestChannelMonitorRequester
eventCnt (defined in TestChannelMonitorRequester)TestChannelMonitorRequester
lock (defined in TestChannelMonitorRequester)TestChannelMonitorRequester
mon (defined in TestChannelMonitorRequester)TestChannelMonitorRequester
monitorConnect(epics::pvData::Status const &status, epics::pvData::MonitorPtr const &monitor, epics::pvData::StructureConstPtr const &structure) (defined in TestChannelMonitorRequester)TestChannelMonitorRequestervirtual
monitorEvent(epics::pvData::MonitorPtr const &monitor) (defined in TestChannelMonitorRequester)TestChannelMonitorRequestervirtual
POINTER_DEFINITIONS(TestChannelMonitorRequester) (defined in TestChannelMonitorRequester)TestChannelMonitorRequester
TestChannelMonitorRequester() (defined in TestChannelMonitorRequester)TestChannelMonitorRequester
unlisten(epics::pvData::MonitorPtr const &monitor) (defined in TestChannelMonitorRequester)TestChannelMonitorRequestervirtual
unlistend (defined in TestChannelMonitorRequester)TestChannelMonitorRequester
wait (defined in TestChannelMonitorRequester)TestChannelMonitorRequester
waitForConnect() (defined in TestChannelMonitorRequester)TestChannelMonitorRequester
waitForEvent() (defined in TestChannelMonitorRequester)TestChannelMonitorRequester
~TestChannelMonitorRequester() (defined in TestChannelMonitorRequester)TestChannelMonitorRequestervirtual
+ + + + diff --git a/struct_test_channel_monitor_requester.html b/struct_test_channel_monitor_requester.html new file mode 100644 index 0000000..c34035d --- /dev/null +++ b/struct_test_channel_monitor_requester.html @@ -0,0 +1,168 @@ + + + + + + +pva2pva: TestChannelMonitorRequester Struct Reference + + + + + + + + + +
+
+ + + + + + +
+
pva2pva +  1.4.1 +
+
+
+ + + + + + + + + +
+ +
+ +
+
+ +
+
TestChannelMonitorRequester Struct Reference
+
+
+
+Inheritance diagram for TestChannelMonitorRequester:
+
+
Inheritance graph
+
[legend]
+
+Collaboration diagram for TestChannelMonitorRequester:
+
+
Collaboration graph
+
[legend]
+ + + + + + + + + + + + + + +

+Public Member Functions

POINTER_DEFINITIONS (TestChannelMonitorRequester)
 
+virtual void monitorConnect (epics::pvData::Status const &status, epics::pvData::MonitorPtr const &monitor, epics::pvData::StructureConstPtr const &structure)
 
+virtual void monitorEvent (epics::pvData::MonitorPtr const &monitor)
 
+virtual void unlisten (epics::pvData::MonitorPtr const &monitor)
 
+bool waitForConnect ()
 
+bool waitForEvent ()
 
+ + + + + + + + + + + + + + + + + +

+Public Attributes

+epicsMutex lock
 
+epicsEvent wait
 
+bool connected
 
+bool unlistend
 
+size_t eventCnt
 
+epics::pvData::Status connectStatus
 
+epics::pvData::MonitorPtr mon
 
+epics::pvData::StructureConstPtr dtype
 
+

Detailed Description

+
+

Definition at line 155 of file utilities.h.

+

The documentation for this struct was generated from the following files: +
+ + + + diff --git a/struct_test_channel_monitor_requester__coll__graph.map b/struct_test_channel_monitor_requester__coll__graph.map new file mode 100644 index 0000000..b73fc4a --- /dev/null +++ b/struct_test_channel_monitor_requester__coll__graph.map @@ -0,0 +1,2 @@ + + diff --git a/struct_test_channel_monitor_requester__coll__graph.md5 b/struct_test_channel_monitor_requester__coll__graph.md5 new file mode 100644 index 0000000..e1e7b20 --- /dev/null +++ b/struct_test_channel_monitor_requester__coll__graph.md5 @@ -0,0 +1 @@ +c37fad6c8c0f404a2834bdb047e86f27 \ No newline at end of file diff --git a/struct_test_channel_monitor_requester__coll__graph.png b/struct_test_channel_monitor_requester__coll__graph.png new file mode 100644 index 0000000..636a9a6 Binary files /dev/null and b/struct_test_channel_monitor_requester__coll__graph.png differ diff --git a/struct_test_channel_monitor_requester__inherit__graph.map b/struct_test_channel_monitor_requester__inherit__graph.map new file mode 100644 index 0000000..b73fc4a --- /dev/null +++ b/struct_test_channel_monitor_requester__inherit__graph.map @@ -0,0 +1,2 @@ + + diff --git a/struct_test_channel_monitor_requester__inherit__graph.md5 b/struct_test_channel_monitor_requester__inherit__graph.md5 new file mode 100644 index 0000000..e1e7b20 --- /dev/null +++ b/struct_test_channel_monitor_requester__inherit__graph.md5 @@ -0,0 +1 @@ +c37fad6c8c0f404a2834bdb047e86f27 \ No newline at end of file diff --git a/struct_test_channel_monitor_requester__inherit__graph.png b/struct_test_channel_monitor_requester__inherit__graph.png new file mode 100644 index 0000000..636a9a6 Binary files /dev/null and b/struct_test_channel_monitor_requester__inherit__graph.png differ diff --git a/struct_test_channel_put_requester-members.html b/struct_test_channel_put_requester-members.html new file mode 100644 index 0000000..5cb6e93 --- /dev/null +++ b/struct_test_channel_put_requester-members.html @@ -0,0 +1,117 @@ + + + + + + +pva2pva: Member List + + + + + + + + + +
+
+ + + + + + +
+
pva2pva +  1.4.1 +
+
+
+ + + + + + + + + +
+ +
+ +
+
+
+
TestChannelPutRequester Member List
+
+
+ +

This is the complete list of members for TestChannelPutRequester, including all inherited members.

+ + + + + + + + + + + + + + + + + +
changed (defined in TestChannelPutRequester)TestChannelPutRequester
channelPutConnect(const epics::pvData::Status &status, epics::pvAccess::ChannelPut::shared_pointer const &channelPut, epics::pvData::Structure::const_shared_pointer const &structure) (defined in TestChannelPutRequester)TestChannelPutRequestervirtual
connected (defined in TestChannelPutRequester)TestChannelPutRequester
doneGet (defined in TestChannelPutRequester)TestChannelPutRequester
donePut (defined in TestChannelPutRequester)TestChannelPutRequester
fielddesc (defined in TestChannelPutRequester)TestChannelPutRequester
getDone(const epics::pvData::Status &status, epics::pvAccess::ChannelPut::shared_pointer const &channelPut, epics::pvData::PVStructure::shared_pointer const &pvStructure, epics::pvData::BitSet::shared_pointer const &bitSet) (defined in TestChannelPutRequester)TestChannelPutRequestervirtual
POINTER_DEFINITIONS(TestChannelPutRequester) (defined in TestChannelPutRequester)TestChannelPutRequester
put (defined in TestChannelPutRequester)TestChannelPutRequester
putDone(const epics::pvData::Status &status, epics::pvAccess::ChannelPut::shared_pointer const &channelPut) (defined in TestChannelPutRequester)TestChannelPutRequestervirtual
statusConnect (defined in TestChannelPutRequester)TestChannelPutRequester
statusGet (defined in TestChannelPutRequester)TestChannelPutRequester
statusPut (defined in TestChannelPutRequester)TestChannelPutRequester
TestChannelPutRequester() (defined in TestChannelPutRequester)TestChannelPutRequester
value (defined in TestChannelPutRequester)TestChannelPutRequester
~TestChannelPutRequester() (defined in TestChannelPutRequester)TestChannelPutRequestervirtual
+ + + + diff --git a/struct_test_channel_put_requester.html b/struct_test_channel_put_requester.html new file mode 100644 index 0000000..10a1400 --- /dev/null +++ b/struct_test_channel_put_requester.html @@ -0,0 +1,168 @@ + + + + + + +pva2pva: TestChannelPutRequester Struct Reference + + + + + + + + + +
+
+ + + + + + +
+
pva2pva +  1.4.1 +
+
+
+ + + + + + + + + +
+ +
+ +
+
+ +
+
TestChannelPutRequester Struct Reference
+
+
+
+Inheritance diagram for TestChannelPutRequester:
+
+
Inheritance graph
+
[legend]
+
+Collaboration diagram for TestChannelPutRequester:
+
+
Collaboration graph
+
[legend]
+ + + + + + + + + + +

+Public Member Functions

POINTER_DEFINITIONS (TestChannelPutRequester)
 
+virtual void channelPutConnect (const epics::pvData::Status &status, epics::pvAccess::ChannelPut::shared_pointer const &channelPut, epics::pvData::Structure::const_shared_pointer const &structure)
 
+virtual void putDone (const epics::pvData::Status &status, epics::pvAccess::ChannelPut::shared_pointer const &channelPut)
 
+virtual void getDone (const epics::pvData::Status &status, epics::pvAccess::ChannelPut::shared_pointer const &channelPut, epics::pvData::PVStructure::shared_pointer const &pvStructure, epics::pvData::BitSet::shared_pointer const &bitSet)
 
+ + + + + + + + + + + + + + + + + + + + + +

+Public Attributes

+bool connected
 
+bool doneGet
 
+bool donePut
 
+epics::pvData::Status statusConnect
 
+epics::pvData::Status statusPut
 
+epics::pvData::Status statusGet
 
+epics::pvAccess::ChannelPut::shared_pointer put
 
+epics::pvData::Structure::const_shared_pointer fielddesc
 
+epics::pvData::PVStructure::shared_pointer value
 
+epics::pvData::BitSet::shared_pointer changed
 
+

Detailed Description

+
+

Definition at line 124 of file utilities.h.

+

The documentation for this struct was generated from the following files: +
+ + + + diff --git a/struct_test_channel_put_requester__coll__graph.map b/struct_test_channel_put_requester__coll__graph.map new file mode 100644 index 0000000..5a9f787 --- /dev/null +++ b/struct_test_channel_put_requester__coll__graph.map @@ -0,0 +1,2 @@ + + diff --git a/struct_test_channel_put_requester__coll__graph.md5 b/struct_test_channel_put_requester__coll__graph.md5 new file mode 100644 index 0000000..7011943 --- /dev/null +++ b/struct_test_channel_put_requester__coll__graph.md5 @@ -0,0 +1 @@ +a4ab2eb7acb7c2c7e3ce9df957b896a6 \ No newline at end of file diff --git a/struct_test_channel_put_requester__coll__graph.png b/struct_test_channel_put_requester__coll__graph.png new file mode 100644 index 0000000..fe70caf Binary files /dev/null and b/struct_test_channel_put_requester__coll__graph.png differ diff --git a/struct_test_channel_put_requester__inherit__graph.map b/struct_test_channel_put_requester__inherit__graph.map new file mode 100644 index 0000000..5a9f787 --- /dev/null +++ b/struct_test_channel_put_requester__inherit__graph.map @@ -0,0 +1,2 @@ + + diff --git a/struct_test_channel_put_requester__inherit__graph.md5 b/struct_test_channel_put_requester__inherit__graph.md5 new file mode 100644 index 0000000..7011943 --- /dev/null +++ b/struct_test_channel_put_requester__inherit__graph.md5 @@ -0,0 +1 @@ +a4ab2eb7acb7c2c7e3ce9df957b896a6 \ No newline at end of file diff --git a/struct_test_channel_put_requester__inherit__graph.png b/struct_test_channel_put_requester__inherit__graph.png new file mode 100644 index 0000000..fe70caf Binary files /dev/null and b/struct_test_channel_put_requester__inherit__graph.png differ diff --git a/struct_test_channel_requester-members.html b/struct_test_channel_requester-members.html new file mode 100644 index 0000000..f90b639 --- /dev/null +++ b/struct_test_channel_requester-members.html @@ -0,0 +1,112 @@ + + + + + + +pva2pva: Member List + + + + + + + + + +
+
+ + + + + + +
+
pva2pva +  1.4.1 +
+
+
+ + + + + + + + + +
+ +
+ +
+
+
+
TestChannelRequester Member List
+
+
+ +

This is the complete list of members for TestChannelRequester, including all inherited members.

+ + + + + + + + + + + + +
chan (defined in TestChannelRequester)TestChannelRequester
channelCreated(const epics::pvData::Status &status, epics::pvAccess::Channel::shared_pointer const &channel) (defined in TestChannelRequester)TestChannelRequestervirtual
channelStateChange(epics::pvAccess::Channel::shared_pointer const &channel, epics::pvAccess::Channel::ConnectionState connectionState) (defined in TestChannelRequester)TestChannelRequestervirtual
laststate (defined in TestChannelRequester)TestChannelRequester
lock (defined in TestChannelRequester)TestChannelRequester
POINTER_DEFINITIONS(TestChannelRequester) (defined in TestChannelRequester)TestChannelRequester
status (defined in TestChannelRequester)TestChannelRequester
TestChannelRequester() (defined in TestChannelRequester)TestChannelRequester
wait (defined in TestChannelRequester)TestChannelRequester
waitForConnect() (defined in TestChannelRequester)TestChannelRequester
~TestChannelRequester() (defined in TestChannelRequester)TestChannelRequestervirtual
+ + + + diff --git a/struct_test_channel_requester.html b/struct_test_channel_requester.html new file mode 100644 index 0000000..133beae --- /dev/null +++ b/struct_test_channel_requester.html @@ -0,0 +1,153 @@ + + + + + + +pva2pva: TestChannelRequester Struct Reference + + + + + + + + + +
+
+ + + + + + +
+
pva2pva +  1.4.1 +
+
+
+ + + + + + + + + +
+ +
+ +
+
+ +
+
TestChannelRequester Struct Reference
+
+
+
+Inheritance diagram for TestChannelRequester:
+
+
Inheritance graph
+
[legend]
+
+Collaboration diagram for TestChannelRequester:
+
+
Collaboration graph
+
[legend]
+ + + + + + + + + + +

+Public Member Functions

POINTER_DEFINITIONS (TestChannelRequester)
 
+virtual void channelCreated (const epics::pvData::Status &status, epics::pvAccess::Channel::shared_pointer const &channel)
 
+virtual void channelStateChange (epics::pvAccess::Channel::shared_pointer const &channel, epics::pvAccess::Channel::ConnectionState connectionState)
 
+bool waitForConnect ()
 
+ + + + + + + + + + + +

+Public Attributes

+epicsMutex lock
 
+epicsEvent wait
 
+epics::pvAccess::Channel::shared_pointer chan
 
+epics::pvData::Status status
 
+epics::pvAccess::Channel::ConnectionState laststate
 
+

Detailed Description

+
+

Definition at line 57 of file utilities.h.

+

The documentation for this struct was generated from the following files: +
+ + + + diff --git a/struct_test_channel_requester__coll__graph.map b/struct_test_channel_requester__coll__graph.map new file mode 100644 index 0000000..e0cc3f9 --- /dev/null +++ b/struct_test_channel_requester__coll__graph.map @@ -0,0 +1,2 @@ + + diff --git a/struct_test_channel_requester__coll__graph.md5 b/struct_test_channel_requester__coll__graph.md5 new file mode 100644 index 0000000..dd56f67 --- /dev/null +++ b/struct_test_channel_requester__coll__graph.md5 @@ -0,0 +1 @@ +a4f0c8ebc92b47720771fccc0a637d58 \ No newline at end of file diff --git a/struct_test_channel_requester__coll__graph.png b/struct_test_channel_requester__coll__graph.png new file mode 100644 index 0000000..a166967 Binary files /dev/null and b/struct_test_channel_requester__coll__graph.png differ diff --git a/struct_test_channel_requester__inherit__graph.map b/struct_test_channel_requester__inherit__graph.map new file mode 100644 index 0000000..e0cc3f9 --- /dev/null +++ b/struct_test_channel_requester__inherit__graph.map @@ -0,0 +1,2 @@ + + diff --git a/struct_test_channel_requester__inherit__graph.md5 b/struct_test_channel_requester__inherit__graph.md5 new file mode 100644 index 0000000..dd56f67 --- /dev/null +++ b/struct_test_channel_requester__inherit__graph.md5 @@ -0,0 +1 @@ +a4f0c8ebc92b47720771fccc0a637d58 \ No newline at end of file diff --git a/struct_test_channel_requester__inherit__graph.png b/struct_test_channel_requester__inherit__graph.png new file mode 100644 index 0000000..a166967 Binary files /dev/null and b/struct_test_channel_requester__inherit__graph.png differ diff --git a/struct_test_i_o_c-members.html b/struct_test_i_o_c-members.html new file mode 100644 index 0000000..a0eab2c --- /dev/null +++ b/struct_test_i_o_c-members.html @@ -0,0 +1,106 @@ + + + + + + +pva2pva: Member List + + + + + + + + + +
+
+ + + + + + +
+
pva2pva +  1.4.1 +
+
+
+ + + + + + + + + +
+ +
+ +
+
+
+
TestIOC Member List
+
+
+ +

This is the complete list of members for TestIOC, including all inherited members.

+ + + + + + +
hasInit (defined in TestIOC)TestIOC
init() (defined in TestIOC)TestIOCinline
shutdown() (defined in TestIOC)TestIOCinline
TestIOC() (defined in TestIOC)TestIOCinline
~TestIOC() (defined in TestIOC)TestIOCinline
+ + + + diff --git a/struct_test_i_o_c.html b/struct_test_i_o_c.html new file mode 100644 index 0000000..437fe25 --- /dev/null +++ b/struct_test_i_o_c.html @@ -0,0 +1,124 @@ + + + + + + +pva2pva: TestIOC Struct Reference + + + + + + + + + +
+
+ + + + + + +
+
pva2pva +  1.4.1 +
+
+
+ + + + + + + + + +
+ +
+ +
+
+ +
+
TestIOC Struct Reference
+
+
+ + + + + + +

+Public Member Functions

+void init ()
 
+void shutdown ()
 
+ + + +

+Public Attributes

+bool hasInit
 
+

Detailed Description

+
+

Definition at line 297 of file utilities.h.

+

The documentation for this struct was generated from the following file: +
+ + + + diff --git a/struct_test_p_v-members.html b/struct_test_p_v-members.html new file mode 100644 index 0000000..4da123e --- /dev/null +++ b/struct_test_p_v-members.html @@ -0,0 +1,117 @@ + + + + + + +pva2pva: Member List + + + + + + + + + +
+
+ + + + + + +
+
pva2pva +  1.4.1 +
+
+
+ + + + + + + + + +
+ +
+ +
+
+
+
TestPV Member List
+
+
+ +

This is the complete list of members for TestPV, including all inherited members.

+ + + + + + + + + + + + + + + + + +
channels (defined in TestPV)TestPV
channels_t typedef (defined in TestPV)TestPV
disconnect() (defined in TestPV)TestPV
dtype (defined in TestPV)TestPV
factory (defined in TestPV)TestPV
lock (defined in TestPV)TestPVmutable
name (defined in TestPV)TestPV
POINTER_DEFINITIONS(TestPV) (defined in TestPV)TestPV
post(bool notify=true) (defined in TestPV)TestPV
post(const epics::pvData::BitSet &changed, bool notify=true) (defined in TestPV)TestPV
provider (defined in TestPV)TestPV
TestProvider (defined in TestPV)TestPVfriend
TestPV(const std::string &name, const std::tr1::shared_ptr< TestProvider > &provider, const epics::pvData::StructureConstPtr &dtype) (defined in TestPV)TestPV
value (defined in TestPV)TestPV
weakself (defined in TestPV)TestPV
~TestPV() (defined in TestPV)TestPV
+ + + + diff --git a/struct_test_p_v.html b/struct_test_p_v.html new file mode 100644 index 0000000..5588a33 --- /dev/null +++ b/struct_test_p_v.html @@ -0,0 +1,178 @@ + + + + + + +pva2pva: TestPV Struct Reference + + + + + + + + + +
+
+ + + + + + +
+
pva2pva +  1.4.1 +
+
+
+ + + + + + + + + +
+ +
+ +
+ +
+
+Collaboration diagram for TestPV:
+
+
Collaboration graph
+ + +
[legend]
+ + + + +

+Public Types

+typedef weak_set< TestPVChannelchannels_t
 
+ + + + + + + + + + + +

+Public Member Functions

POINTER_DEFINITIONS (TestPV)
 
TestPV (const std::string &name, const std::tr1::shared_ptr< TestProvider > &provider, const epics::pvData::StructureConstPtr &dtype)
 
+void post (bool notify=true)
 
+void post (const epics::pvData::BitSet &changed, bool notify=true)
 
+void disconnect ()
 
+ + + + + + + + + + + + + + + + + +

+Public Attributes

+std::tr1::weak_ptr< TestPVweakself
 
+const std::string name
 
+std::tr1::weak_ptr
+< TestProvider > const 
provider
 
+epics::pvData::PVDataCreatePtr factory
 
+const
+epics::pvData::StructureConstPtr 
dtype
 
+epics::pvData::PVStructurePtr value
 
+epicsMutex lock
 
+channels_t channels
 
+ + + +

+Friends

+struct TestProvider
 
+

Detailed Description

+
+

Definition at line 237 of file utilities.h.

+

The documentation for this struct was generated from the following files: +
+ + + + diff --git a/struct_test_p_v__coll__graph.map b/struct_test_p_v__coll__graph.map new file mode 100644 index 0000000..29c65ca --- /dev/null +++ b/struct_test_p_v__coll__graph.map @@ -0,0 +1,3 @@ + + + diff --git a/struct_test_p_v__coll__graph.md5 b/struct_test_p_v__coll__graph.md5 new file mode 100644 index 0000000..6e69d2b --- /dev/null +++ b/struct_test_p_v__coll__graph.md5 @@ -0,0 +1 @@ +dd8e0f92f6f9803a32bb71e95049f3b6 \ No newline at end of file diff --git a/struct_test_p_v__coll__graph.png b/struct_test_p_v__coll__graph.png new file mode 100644 index 0000000..06bf665 Binary files /dev/null and b/struct_test_p_v__coll__graph.png differ diff --git a/struct_test_p_v_channel-members.html b/struct_test_p_v_channel-members.html new file mode 100644 index 0000000..330db53 --- /dev/null +++ b/struct_test_p_v_channel-members.html @@ -0,0 +1,127 @@ + + + + + + +pva2pva: Member List + + + + + + + + + +
+
+ + + + + + +
+
pva2pva +  1.4.1 +
+
+
+ + + + + + + + + +
+ +
+ +
+
+
+
TestPVChannel Member List
+
+
+ +

This is the complete list of members for TestPVChannel, including all inherited members.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
BaseChannel(const std::string &name, const std::tr1::weak_ptr< epics::pvAccess::ChannelProvider > &prov, const epics::pvAccess::ChannelRequester::shared_pointer &req, const epics::pvData::StructureConstPtr &dtype) (defined in BaseChannel)BaseChannelinline
createMonitor(epics::pvData::MonitorRequester::shared_pointer const &monitorRequester, epics::pvData::PVStructure::shared_pointer const &pvRequest) (defined in TestPVChannel)TestPVChannelvirtual
destroy() OVERRIDE FINAL (defined in BaseChannel)BaseChannelinlinevirtual
fielddesc (defined in BaseChannel)BaseChannel
getChannelName() OVERRIDE FINAL (defined in BaseChannel)BaseChannelinlinevirtual
getChannelRequester() OVERRIDE FINAL (defined in BaseChannel)BaseChannelinlinevirtual
getConnectionState() (defined in TestPVChannel)TestPVChannelvirtual
getField(epics::pvAccess::GetFieldRequester::shared_pointer const &requester, std::string const &subField) (defined in TestPVChannel)TestPVChannelvirtual
getProvider() OVERRIDE FINAL (defined in BaseChannel)BaseChannelinlinevirtual
getRemoteAddress() (defined in TestPVChannel)TestPVChannelinlinevirtual
getRequesterName() OVERRIDE (defined in BaseChannel)BaseChannelinlinevirtual
guard_t typedef (defined in BaseChannel)BaseChannel
lock (defined in BaseChannel)BaseChannelmutable
monitors (defined in TestPVChannel)TestPVChannel
monitors_t typedef (defined in TestPVChannel)TestPVChannel
POINTER_DEFINITIONS(TestPVChannel) (defined in TestPVChannel)TestPVChannel
printInfo(std::ostream &out) OVERRIDE (defined in BaseChannel)BaseChannelinlinevirtual
provider (defined in BaseChannel)BaseChannel
pv (defined in TestPVChannel)TestPVChannel
pvname (defined in BaseChannel)BaseChannel
requester (defined in BaseChannel)BaseChannel
state (defined in TestPVChannel)TestPVChannel
TestPVChannel(const std::tr1::shared_ptr< TestPV > &pv, const std::tr1::shared_ptr< epics::pvAccess::ChannelRequester > &req) (defined in TestPVChannel)TestPVChannel
weakself (defined in TestPVChannel)TestPVChannel
~BaseChannel() (defined in BaseChannel)BaseChannelinlinevirtual
~TestPVChannel() (defined in TestPVChannel)TestPVChannelvirtual
+ + + + diff --git a/struct_test_p_v_channel.html b/struct_test_p_v_channel.html new file mode 100644 index 0000000..f2a9604 --- /dev/null +++ b/struct_test_p_v_channel.html @@ -0,0 +1,215 @@ + + + + + + +pva2pva: TestPVChannel Struct Reference + + + + + + + + + +
+
+ + + + + + +
+
pva2pva +  1.4.1 +
+
+
+ + + + + + + + + +
+ +
+ +
+
+ +
+
TestPVChannel Struct Reference
+
+
+
+Inheritance diagram for TestPVChannel:
+
+
Inheritance graph
+ + +
[legend]
+
+Collaboration diagram for TestPVChannel:
+
+
Collaboration graph
+ + +
[legend]
+ + + + + + + +

+Public Types

+typedef weak_set< TestPVMonitormonitors_t
 
- Public Types inherited from BaseChannel
+typedef epicsGuard< epicsMutex > guard_t
 
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Public Member Functions

POINTER_DEFINITIONS (TestPVChannel)
 
TestPVChannel (const std::tr1::shared_ptr< TestPV > &pv, const std::tr1::shared_ptr< epics::pvAccess::ChannelRequester > &req)
 
+virtual std::string getRemoteAddress ()
 
+virtual ConnectionState getConnectionState ()
 
+virtual void getField (epics::pvAccess::GetFieldRequester::shared_pointer const &requester, std::string const &subField)
 
+virtual
+epics::pvData::Monitor::shared_pointer 
createMonitor (epics::pvData::MonitorRequester::shared_pointer const &monitorRequester, epics::pvData::PVStructure::shared_pointer const &pvRequest)
 
- Public Member Functions inherited from BaseChannel
BaseChannel (const std::string &name, const std::tr1::weak_ptr< epics::pvAccess::ChannelProvider > &prov, const epics::pvAccess::ChannelRequester::shared_pointer &req, const epics::pvData::StructureConstPtr &dtype)
 
+virtual std::string getRequesterName () OVERRIDE
 
+virtual void destroy () OVERRIDE FINAL
 
+virtual std::tr1::shared_ptr
+< epics::pvAccess::ChannelProvider > 
getProvider () OVERRIDE FINAL
 
+virtual std::string getChannelName () OVERRIDE FINAL
 
+virtual std::tr1::shared_ptr
+< epics::pvAccess::ChannelRequester > 
getChannelRequester () OVERRIDE FINAL
 
+virtual void printInfo (std::ostream &out) OVERRIDE
 
+ + + + + + + + + + + + + + + + + + + + +

+Public Attributes

+std::tr1::weak_ptr< TestPVChannelweakself
 
+const std::tr1::shared_ptr
+< TestPV
pv
 
+ConnectionState state
 
+monitors_t monitors
 
- Public Attributes inherited from BaseChannel
+epicsMutex lock
 
+const std::string pvname
 
+const
+epics::pvAccess::ChannelProvider::weak_pointer 
provider
 
+const requester_type::weak_pointer requester
 
+const
+epics::pvData::StructureConstPtr 
fielddesc
 
+

Detailed Description

+
+

Definition at line 182 of file utilities.h.

+

The documentation for this struct was generated from the following files: +
+ + + + diff --git a/struct_test_p_v_channel__coll__graph.map b/struct_test_p_v_channel__coll__graph.map new file mode 100644 index 0000000..3024682 --- /dev/null +++ b/struct_test_p_v_channel__coll__graph.map @@ -0,0 +1,4 @@ + + + + diff --git a/struct_test_p_v_channel__coll__graph.md5 b/struct_test_p_v_channel__coll__graph.md5 new file mode 100644 index 0000000..31001e8 --- /dev/null +++ b/struct_test_p_v_channel__coll__graph.md5 @@ -0,0 +1 @@ +023832ddea6da119b61bb5c01d131b33 \ No newline at end of file diff --git a/struct_test_p_v_channel__coll__graph.png b/struct_test_p_v_channel__coll__graph.png new file mode 100644 index 0000000..8f01d5a Binary files /dev/null and b/struct_test_p_v_channel__coll__graph.png differ diff --git a/struct_test_p_v_channel__inherit__graph.map b/struct_test_p_v_channel__inherit__graph.map new file mode 100644 index 0000000..d4896fc --- /dev/null +++ b/struct_test_p_v_channel__inherit__graph.map @@ -0,0 +1,3 @@ + + + diff --git a/struct_test_p_v_channel__inherit__graph.md5 b/struct_test_p_v_channel__inherit__graph.md5 new file mode 100644 index 0000000..c56c596 --- /dev/null +++ b/struct_test_p_v_channel__inherit__graph.md5 @@ -0,0 +1 @@ +9fd41e3145f8acc656677f3ec72fa43a \ No newline at end of file diff --git a/struct_test_p_v_channel__inherit__graph.png b/struct_test_p_v_channel__inherit__graph.png new file mode 100644 index 0000000..9d49cbd Binary files /dev/null and b/struct_test_p_v_channel__inherit__graph.png differ diff --git a/struct_test_p_v_monitor-members.html b/struct_test_p_v_monitor-members.html new file mode 100644 index 0000000..bb4cb7d --- /dev/null +++ b/struct_test_p_v_monitor-members.html @@ -0,0 +1,119 @@ + + + + + + +pva2pva: Member List + + + + + + + + + +
+
+ + + + + + +
+
pva2pva +  1.4.1 +
+
+
+ + + + + + + + + +
+ +
+ +
+
+
+
TestPVMonitor Member List
+
+
+ +

This is the complete list of members for TestPVMonitor, including all inherited members.

+ + + + + + + + + + + + + + + + + + + +
buffer (defined in TestPVMonitor)TestPVMonitor
channel (defined in TestPVMonitor)TestPVMonitor
destroy() (defined in TestPVMonitor)TestPVMonitorvirtual
finalize (defined in TestPVMonitor)TestPVMonitor
free (defined in TestPVMonitor)TestPVMonitor
inoverflow (defined in TestPVMonitor)TestPVMonitor
needWakeup (defined in TestPVMonitor)TestPVMonitor
overflow (defined in TestPVMonitor)TestPVMonitor
POINTER_DEFINITIONS(TestPVMonitor) (defined in TestPVMonitor)TestPVMonitor
poll() (defined in TestPVMonitor)TestPVMonitorvirtual
release(epics::pvData::MonitorElementPtr const &monitorElement) (defined in TestPVMonitor)TestPVMonitorvirtual
requester (defined in TestPVMonitor)TestPVMonitor
running (defined in TestPVMonitor)TestPVMonitor
start() (defined in TestPVMonitor)TestPVMonitorvirtual
stop() (defined in TestPVMonitor)TestPVMonitorvirtual
TestPVMonitor(const TestPVChannel::shared_pointer &ch, const epics::pvData::MonitorRequester::shared_pointer &req, size_t bsize) (defined in TestPVMonitor)TestPVMonitor
weakself (defined in TestPVMonitor)TestPVMonitor
~TestPVMonitor() (defined in TestPVMonitor)TestPVMonitorvirtual
+ + + + diff --git a/struct_test_p_v_monitor.html b/struct_test_p_v_monitor.html new file mode 100644 index 0000000..9db0e60 --- /dev/null +++ b/struct_test_p_v_monitor.html @@ -0,0 +1,181 @@ + + + + + + +pva2pva: TestPVMonitor Struct Reference + + + + + + + + + +
+
+ + + + + + +
+
pva2pva +  1.4.1 +
+
+
+ + + + + + + + + +
+ +
+ +
+
+ +
+
TestPVMonitor Struct Reference
+
+
+
+Inheritance diagram for TestPVMonitor:
+
+
Inheritance graph
+
[legend]
+
+Collaboration diagram for TestPVMonitor:
+
+
Collaboration graph
+
[legend]
+ + + + + + + + + + + + + + + + +

+Public Member Functions

POINTER_DEFINITIONS (TestPVMonitor)
 
TestPVMonitor (const TestPVChannel::shared_pointer &ch, const epics::pvData::MonitorRequester::shared_pointer &req, size_t bsize)
 
+virtual void destroy ()
 
+virtual epics::pvData::Status start ()
 
+virtual epics::pvData::Status stop ()
 
+virtual
+epics::pvData::MonitorElementPtr 
poll ()
 
+virtual void release (epics::pvData::MonitorElementPtr const &monitorElement)
 
+ + + + + + + + + + + + + + + + + + + + + +

+Public Attributes

+std::tr1::weak_ptr< TestPVMonitorweakself
 
+const TestPVChannel::shared_pointer channel
 
+const
+epics::pvData::MonitorRequester::weak_pointer 
requester
 
+bool running
 
+bool finalize
 
+bool inoverflow
 
+bool needWakeup
 
+std::deque
+< epics::pvData::MonitorElementPtr > 
buffer
 
+std::deque
+< epics::pvData::MonitorElementPtr > 
free
 
+epics::pvData::MonitorElementPtr overflow
 
+

Detailed Description

+
+

Definition at line 208 of file utilities.h.

+

The documentation for this struct was generated from the following files: +
+ + + + diff --git a/struct_test_p_v_monitor__coll__graph.map b/struct_test_p_v_monitor__coll__graph.map new file mode 100644 index 0000000..10b1779 --- /dev/null +++ b/struct_test_p_v_monitor__coll__graph.map @@ -0,0 +1,2 @@ + + diff --git a/struct_test_p_v_monitor__coll__graph.md5 b/struct_test_p_v_monitor__coll__graph.md5 new file mode 100644 index 0000000..0e75833 --- /dev/null +++ b/struct_test_p_v_monitor__coll__graph.md5 @@ -0,0 +1 @@ +3bbcf8b1e7f71583f3accc6e509eb2ee \ No newline at end of file diff --git a/struct_test_p_v_monitor__coll__graph.png b/struct_test_p_v_monitor__coll__graph.png new file mode 100644 index 0000000..30de0d6 Binary files /dev/null and b/struct_test_p_v_monitor__coll__graph.png differ diff --git a/struct_test_p_v_monitor__inherit__graph.map b/struct_test_p_v_monitor__inherit__graph.map new file mode 100644 index 0000000..10b1779 --- /dev/null +++ b/struct_test_p_v_monitor__inherit__graph.map @@ -0,0 +1,2 @@ + + diff --git a/struct_test_p_v_monitor__inherit__graph.md5 b/struct_test_p_v_monitor__inherit__graph.md5 new file mode 100644 index 0000000..0e75833 --- /dev/null +++ b/struct_test_p_v_monitor__inherit__graph.md5 @@ -0,0 +1 @@ +3bbcf8b1e7f71583f3accc6e509eb2ee \ No newline at end of file diff --git a/struct_test_p_v_monitor__inherit__graph.png b/struct_test_p_v_monitor__inherit__graph.png new file mode 100644 index 0000000..30de0d6 Binary files /dev/null and b/struct_test_p_v_monitor__inherit__graph.png differ diff --git a/struct_test_provider-members.html b/struct_test_provider-members.html new file mode 100644 index 0000000..73e2e5f --- /dev/null +++ b/struct_test_provider-members.html @@ -0,0 +1,116 @@ + + + + + + +pva2pva: Member List + + + + + + + + + +
+
+ + + + + + +
+
pva2pva +  1.4.1 +
+
+
+ + + + + + + + + +
+ +
+ +
+
+
+
TestProvider Member List
+
+
+ +

This is the complete list of members for TestProvider, including all inherited members.

+ + + + + + + + + + + + + + + + +
addPV(const std::string &name, const epics::pvData::StructureConstPtr &tdef) (defined in TestProvider)TestProvider
channelFind(std::string const &channelName, epics::pvAccess::ChannelFindRequester::shared_pointer const &channelFindRequester) (defined in TestProvider)TestProvidervirtual
channelList(epics::pvAccess::ChannelListRequester::shared_pointer const &channelListRequester) (defined in TestProvider)TestProvidervirtual
createChannel(std::string const &channelName, epics::pvAccess::ChannelRequester::shared_pointer const &channelRequester, short priority=PRIORITY_DEFAULT) (defined in TestProvider)TestProvidervirtual
createChannel(std::string const &channelName, epics::pvAccess::ChannelRequester::shared_pointer const &channelRequester, short priority, std::string const &address) (defined in TestProvider)TestProvidervirtual
destroy() (defined in TestProvider)TestProvidervirtual
dispatch() (defined in TestProvider)TestProvider
getProviderName() (defined in TestProvider)TestProviderinlinevirtual
lock (defined in TestProvider)TestProvidermutable
POINTER_DEFINITIONS(TestProvider) (defined in TestProvider)TestProvider
pvs (defined in TestProvider)TestProvider
pvs_t typedef (defined in TestProvider)TestProvider
testCounts() (defined in TestProvider)TestProviderstatic
TestProvider() (defined in TestProvider)TestProvider
~TestProvider() (defined in TestProvider)TestProvidervirtual
+ + + + diff --git a/struct_test_provider.html b/struct_test_provider.html new file mode 100644 index 0000000..b7a4a76 --- /dev/null +++ b/struct_test_provider.html @@ -0,0 +1,180 @@ + + + + + + +pva2pva: TestProvider Struct Reference + + + + + + + + + +
+
+ + + + + + +
+
pva2pva +  1.4.1 +
+
+
+ + + + + + + + + +
+ +
+ +
+ +
+
+Inheritance diagram for TestProvider:
+
+
Inheritance graph
+
[legend]
+
+Collaboration diagram for TestProvider:
+
+
Collaboration graph
+ + +
[legend]
+ + + + +

+Public Types

+typedef weak_value_map
+< std::string, TestPV
pvs_t
 
+ + + + + + + + + + + + + + + + + + + +

+Public Member Functions

POINTER_DEFINITIONS (TestProvider)
 
+virtual std::string getProviderName ()
 
+virtual void destroy ()
 
+virtual
+epics::pvAccess::ChannelFind::shared_pointer 
channelFind (std::string const &channelName, epics::pvAccess::ChannelFindRequester::shared_pointer const &channelFindRequester)
 
+virtual
+epics::pvAccess::ChannelFind::shared_pointer 
channelList (epics::pvAccess::ChannelListRequester::shared_pointer const &channelListRequester)
 
+virtual
+epics::pvAccess::Channel::shared_pointer 
createChannel (std::string const &channelName, epics::pvAccess::ChannelRequester::shared_pointer const &channelRequester, short priority=PRIORITY_DEFAULT)
 
+virtual
+epics::pvAccess::Channel::shared_pointer 
createChannel (std::string const &channelName, epics::pvAccess::ChannelRequester::shared_pointer const &channelRequester, short priority, std::string const &address)
 
+TestPV::shared_pointer addPV (const std::string &name, const epics::pvData::StructureConstPtr &tdef)
 
+void dispatch ()
 
+ + + +

+Static Public Member Functions

+static void testCounts ()
 
+ + + + + +

+Public Attributes

+epicsMutex lock
 
+pvs_t pvs
 
+

Detailed Description

+
+

Definition at line 267 of file utilities.h.

+

The documentation for this struct was generated from the following files: +
+ + + + diff --git a/struct_test_provider__coll__graph.map b/struct_test_provider__coll__graph.map new file mode 100644 index 0000000..506f9c9 --- /dev/null +++ b/struct_test_provider__coll__graph.map @@ -0,0 +1,3 @@ + + + diff --git a/struct_test_provider__coll__graph.md5 b/struct_test_provider__coll__graph.md5 new file mode 100644 index 0000000..4913165 --- /dev/null +++ b/struct_test_provider__coll__graph.md5 @@ -0,0 +1 @@ +56f9733b227604e4e9f312e6b2222634 \ No newline at end of file diff --git a/struct_test_provider__coll__graph.png b/struct_test_provider__coll__graph.png new file mode 100644 index 0000000..5bdf1ac Binary files /dev/null and b/struct_test_provider__coll__graph.png differ diff --git a/struct_test_provider__inherit__graph.map b/struct_test_provider__inherit__graph.map new file mode 100644 index 0000000..e2900e6 --- /dev/null +++ b/struct_test_provider__inherit__graph.map @@ -0,0 +1,2 @@ + + diff --git a/struct_test_provider__inherit__graph.md5 b/struct_test_provider__inherit__graph.md5 new file mode 100644 index 0000000..c9fc31a --- /dev/null +++ b/struct_test_provider__inherit__graph.md5 @@ -0,0 +1 @@ +f077aff3d034cbb605b0b165883eb426 \ No newline at end of file diff --git a/struct_test_provider__inherit__graph.png b/struct_test_provider__inherit__graph.png new file mode 100644 index 0000000..3b2b610 Binary files /dev/null and b/struct_test_provider__inherit__graph.png differ diff --git a/struct_work_queue-members.html b/struct_work_queue-members.html new file mode 100644 index 0000000..6a1e3b5 --- /dev/null +++ b/struct_work_queue-members.html @@ -0,0 +1,107 @@ + + + + + + +pva2pva: Member List + + + + + + + + + +
+
+ + + + + + +
+
pva2pva +  1.4.1 +
+
+
+ + + + + + + + + +
+ +
+ +
+
+
+
WorkQueue Member List
+
+
+ +

This is the complete list of members for WorkQueue, including all inherited members.

+ + + + + + + +
add(const value_type &work) (defined in WorkQueue)WorkQueue
close() (defined in WorkQueue)WorkQueue
start(unsigned nworkers=1, unsigned prio=epicsThreadPriorityLow) (defined in WorkQueue)WorkQueue
value_type typedef (defined in WorkQueue)WorkQueue
WorkQueue(const std::string &name) (defined in WorkQueue)WorkQueue
~WorkQueue() (defined in WorkQueue)WorkQueuevirtual
+ + + + diff --git a/struct_work_queue.html b/struct_work_queue.html new file mode 100644 index 0000000..df0d93a --- /dev/null +++ b/struct_work_queue.html @@ -0,0 +1,146 @@ + + + + + + +pva2pva: WorkQueue Struct Reference + + + + + + + + + +
+
+ + + + + + +
+
pva2pva +  1.4.1 +
+
+
+ + + + + + + + + +
+ +
+ +
+
+ +
+
WorkQueue Struct Reference
+
+
+
+Inheritance diagram for WorkQueue:
+
+
Inheritance graph
+ + +
[legend]
+
+Collaboration diagram for WorkQueue:
+
+
Collaboration graph
+ + +
[legend]
+ + + + +

+Public Types

+typedef std::tr1::weak_ptr
+< epicsThreadRunable > 
value_type
 
+ + + + + + + + + +

+Public Member Functions

WorkQueue (const std::string &name)
 
+void start (unsigned nworkers=1, unsigned prio=epicsThreadPriorityLow)
 
+void close ()
 
+void add (const value_type &work)
 
+

Detailed Description

+
+

Definition at line 16 of file tpool.h.

+

The documentation for this struct was generated from the following files: +
+ + + + diff --git a/struct_work_queue__coll__graph.map b/struct_work_queue__coll__graph.map new file mode 100644 index 0000000..bee9fc7 --- /dev/null +++ b/struct_work_queue__coll__graph.map @@ -0,0 +1,2 @@ + + diff --git a/struct_work_queue__coll__graph.md5 b/struct_work_queue__coll__graph.md5 new file mode 100644 index 0000000..fdf1cb4 --- /dev/null +++ b/struct_work_queue__coll__graph.md5 @@ -0,0 +1 @@ +c93efeff2239dc9c7b464404e397f796 \ No newline at end of file diff --git a/struct_work_queue__coll__graph.png b/struct_work_queue__coll__graph.png new file mode 100644 index 0000000..ed5a333 Binary files /dev/null and b/struct_work_queue__coll__graph.png differ diff --git a/struct_work_queue__inherit__graph.map b/struct_work_queue__inherit__graph.map new file mode 100644 index 0000000..bee9fc7 --- /dev/null +++ b/struct_work_queue__inherit__graph.map @@ -0,0 +1,2 @@ + + diff --git a/struct_work_queue__inherit__graph.md5 b/struct_work_queue__inherit__graph.md5 new file mode 100644 index 0000000..fdf1cb4 --- /dev/null +++ b/struct_work_queue__inherit__graph.md5 @@ -0,0 +1 @@ +c93efeff2239dc9c7b464404e397f796 \ No newline at end of file diff --git a/struct_work_queue__inherit__graph.png b/struct_work_queue__inherit__graph.png new file mode 100644 index 0000000..ed5a333 Binary files /dev/null and b/struct_work_queue__inherit__graph.png differ diff --git a/structjlif.html b/structjlif.html new file mode 100644 index 0000000..91062a5 --- /dev/null +++ b/structjlif.html @@ -0,0 +1,104 @@ + + + + + + +pva2pva: jlif Struct Reference + + + + + + + + + +
+
+ + + + + + +
+
pva2pva +  1.4.1 +
+
+
+ + + + + + + + + +
+ +
+ +
+
+
+
jlif Struct Reference
+
+
+

Detailed Description

+
+

Definition at line 6 of file pvalink_null.cpp.

+

The documentation for this struct was generated from the following file: +
+ + + + diff --git a/structpdb_info_iterator-members.html b/structpdb_info_iterator-members.html new file mode 100644 index 0000000..5e8ffb8 --- /dev/null +++ b/structpdb_info_iterator-members.html @@ -0,0 +1,109 @@ + + + + + + +pva2pva: Member List + + + + + + + + + +
+
+ + + + + + +
+
pva2pva +  1.4.1 +
+
+
+ + + + + + + + + +
+ +
+ +
+
+
+
pdbInfoIterator Member List
+
+
+ +

This is the complete list of members for pdbInfoIterator, including all inherited members.

+ + + + + + + + + +
done() const (defined in pdbInfoIterator)pdbInfoIteratorinline
ent (defined in pdbInfoIterator)pdbInfoIterator
m_done (defined in pdbInfoIterator)pdbInfoIterator
name() (defined in pdbInfoIterator)pdbInfoIteratorinline
next() (defined in pdbInfoIterator)pdbInfoIteratorinline
pdbInfoIterator(const pdbRecordIterator &I) (defined in pdbInfoIterator)pdbInfoIteratorinline
value() (defined in pdbInfoIterator)pdbInfoIteratorinline
~pdbInfoIterator() (defined in pdbInfoIterator)pdbInfoIteratorinline
+ + + + diff --git a/structpdb_info_iterator.html b/structpdb_info_iterator.html new file mode 100644 index 0000000..01aad00 --- /dev/null +++ b/structpdb_info_iterator.html @@ -0,0 +1,136 @@ + + + + + + +pva2pva: pdbInfoIterator Struct Reference + + + + + + + + + +
+
+ + + + + + +
+
pva2pva +  1.4.1 +
+
+
+ + + + + + + + + +
+ +
+ +
+
+ +
+
pdbInfoIterator Struct Reference
+
+
+ + + + + + + + + + + + +

+Public Member Functions

pdbInfoIterator (const pdbRecordIterator &I)
 
+bool done () const
 
+bool next ()
 
+const char * name ()
 
+const char * value ()
 
+ + + + + +

+Public Attributes

+DBENTRY ent
 
+bool m_done
 
+

Detailed Description

+
+

Definition at line 202 of file pvif.h.

+

The documentation for this struct was generated from the following file: +
+ + + + diff --git a/structpdb_record_info-members.html b/structpdb_record_info-members.html new file mode 100644 index 0000000..b7a6114 --- /dev/null +++ b/structpdb_record_info-members.html @@ -0,0 +1,105 @@ + + + + + + +pva2pva: Member List + + + + + + + + + +
+
+ + + + + + +
+
pva2pva +  1.4.1 +
+
+
+ + + + + + + + + +
+ +
+ +
+
+
+
pdbRecordInfo Member List
+
+
+ +

This is the complete list of members for pdbRecordInfo, including all inherited members.

+ + + + + +
ent (defined in pdbRecordInfo)pdbRecordInfo
info(const char *key, const char *def=0) (defined in pdbRecordInfo)pdbRecordInfoinline
pdbRecordInfo(const char *name) (defined in pdbRecordInfo)pdbRecordInfoinline
~pdbRecordInfo() (defined in pdbRecordInfo)pdbRecordInfoinline
+ + + + diff --git a/structpdb_record_info.html b/structpdb_record_info.html new file mode 100644 index 0000000..4116f0f --- /dev/null +++ b/structpdb_record_info.html @@ -0,0 +1,124 @@ + + + + + + +pva2pva: pdbRecordInfo Struct Reference + + + + + + + + + +
+
+ + + + + + +
+
pva2pva +  1.4.1 +
+
+
+ + + + + + + + + +
+ +
+ +
+
+ +
+
pdbRecordInfo Struct Reference
+
+
+ + + + + + +

+Public Member Functions

pdbRecordInfo (const char *name)
 
+const char * info (const char *key, const char *def=0)
 
+ + + +

+Public Attributes

+DBENTRY ent
 
+

Detailed Description

+
+

Definition at line 117 of file pvif.h.

+

The documentation for this struct was generated from the following file: +
+ + + + diff --git a/structpdb_record_iterator-members.html b/structpdb_record_iterator-members.html new file mode 100644 index 0000000..0c72a68 --- /dev/null +++ b/structpdb_record_iterator-members.html @@ -0,0 +1,111 @@ + + + + + + +pva2pva: Member List + + + + + + + + + +
+
+ + + + + + +
+
pva2pva +  1.4.1 +
+
+
+ + + + + + + + + +
+ +
+ +
+
+
+
pdbRecordIterator Member List
+
+
+ +

This is the complete list of members for pdbRecordIterator, including all inherited members.

+ + + + + + + + + + + +
done() const (defined in pdbRecordIterator)pdbRecordIteratorinline
ent (defined in pdbRecordIterator)pdbRecordIterator
info(const char *key, const char *def=0) (defined in pdbRecordIterator)pdbRecordIteratorinline
m_done (defined in pdbRecordIterator)pdbRecordIterator
name() const (defined in pdbRecordIterator)pdbRecordIteratorinline
next() (defined in pdbRecordIterator)pdbRecordIteratorinline
pdbRecordIterator() (defined in pdbRecordIterator)pdbRecordIteratorinline
pdbRecordIterator(const dbChannel *chan) (defined in pdbRecordIterator)pdbRecordIteratorinline
record() const (defined in pdbRecordIterator)pdbRecordIteratorinline
~pdbRecordIterator() (defined in pdbRecordIterator)pdbRecordIteratorinline
+ + + + diff --git a/structpdb_record_iterator.html b/structpdb_record_iterator.html new file mode 100644 index 0000000..503aae8 --- /dev/null +++ b/structpdb_record_iterator.html @@ -0,0 +1,139 @@ + + + + + + +pva2pva: pdbRecordIterator Struct Reference + + + + + + + + + +
+
+ + + + + + +
+
pva2pva +  1.4.1 +
+
+
+ + + + + + + + + +
+ +
+ +
+
+ +
+
pdbRecordIterator Struct Reference
+
+
+ + + + + + + + + + + + + + +

+Public Member Functions

pdbRecordIterator (const dbChannel *chan)
 
+bool done () const
 
+bool next ()
 
+dbCommon * record () const
 
+const char * name () const
 
+const char * info (const char *key, const char *def=0)
 
+ + + + + +

+Public Attributes

+DBENTRY ent
 
+bool m_done
 
+

Detailed Description

+
+

Definition at line 137 of file pvif.h.

+

The documentation for this struct was generated from the following file: +
+ + + + diff --git a/structpvalink_1_1pva_global__t-members.html b/structpvalink_1_1pva_global__t-members.html new file mode 100644 index 0000000..117e3a0 --- /dev/null +++ b/structpvalink_1_1pva_global__t-members.html @@ -0,0 +1,116 @@ + + + + + + +pva2pva: Member List + + + + + + + + + +
+
+ + + + + + +
+
pva2pva +  1.4.1 +
+
+
+ + + + + + + + + +
+ +
+ + +
+
+
+
pvalink::pvaGlobal_t Member List
+
+
+ +

This is the complete list of members for pvalink::pvaGlobal_t, including all inherited members.

+ + + + + + + + + + + + +
channels (defined in pvalink::pvaGlobal_t)pvalink::pvaGlobal_t
channels_key_t typedef (defined in pvalink::pvaGlobal_t)pvalink::pvaGlobal_t
channels_t typedef (defined in pvalink::pvaGlobal_t)pvalink::pvaGlobal_t
create (defined in pvalink::pvaGlobal_t)pvalink::pvaGlobal_t
lock (defined in pvalink::pvaGlobal_t)pvalink::pvaGlobal_t
provider_local (defined in pvalink::pvaGlobal_t)pvalink::pvaGlobal_t
provider_remote (defined in pvalink::pvaGlobal_t)pvalink::pvaGlobal_t
pvaGlobal_t() (defined in pvalink::pvaGlobal_t)pvalink::pvaGlobal_t
queue (defined in pvalink::pvaGlobal_t)pvalink::pvaGlobal_t
running (defined in pvalink::pvaGlobal_t)pvalink::pvaGlobal_t
~pvaGlobal_t() (defined in pvalink::pvaGlobal_t)pvalink::pvaGlobal_t
+ + + + diff --git a/structpvalink_1_1pva_global__t.html b/structpvalink_1_1pva_global__t.html new file mode 100644 index 0000000..df8db6a --- /dev/null +++ b/structpvalink_1_1pva_global__t.html @@ -0,0 +1,158 @@ + + + + + + +pva2pva: pvalink::pvaGlobal_t Struct Reference + + + + + + + + + +
+
+ + + + + + +
+
pva2pva +  1.4.1 +
+
+
+ + + + + + + + + +
+ +
+ + +
+
+ +
+
pvalink::pvaGlobal_t Struct Reference
+
+
+
+Collaboration diagram for pvalink::pvaGlobal_t:
+
+
Collaboration graph
+ + +
[legend]
+ + + + + + +

+Public Types

+typedef std::pair< std::string,
+std::string > 
channels_key_t
 
+typedef std::map
+< channels_key_t,
+std::tr1::weak_ptr
+< pvaLinkChannel > > 
channels_t
 
+ + + + + + + + + + + + + + + +

+Public Attributes

+pvac::ClientProvider provider_local
 
+pvac::ClientProvider provider_remote
 
+const pvd::PVDataCreatePtr create
 
+WorkQueue queue
 
+pvd::Mutex lock
 
+bool running
 
+channels_t channels
 
+

Detailed Description

+
+

Definition at line 108 of file pvalink.h.

+

The documentation for this struct was generated from the following files: +
+ + + + diff --git a/structpvalink_1_1pva_global__t_1_1_scan-members.html b/structpvalink_1_1pva_global__t_1_1_scan-members.html new file mode 100644 index 0000000..05dfe5e --- /dev/null +++ b/structpvalink_1_1pva_global__t_1_1_scan-members.html @@ -0,0 +1,108 @@ + + + + + + +pva2pva: Member List + + + + + + + + + +
+
+ + + + + + +
+
pva2pva +  0 +
+
+
+ + + + + + + + + +
+ +
+ + +
+
+
+
pvalink::pvaGlobal_t::Scan Member List
+
+
+ +

This is the complete list of members for pvalink::pvaGlobal_t::Scan, including all inherited members.

+ + + + +
chan (defined in pvalink::pvaGlobal_t::Scan)pvalink::pvaGlobal_t::Scan
Scan() (defined in pvalink::pvaGlobal_t::Scan)pvalink::pvaGlobal_t::Scaninline
usecached (defined in pvalink::pvaGlobal_t::Scan)pvalink::pvaGlobal_t::Scan
+ + + + diff --git a/structpvalink_1_1pva_global__t_1_1_scan.html b/structpvalink_1_1pva_global__t_1_1_scan.html new file mode 100644 index 0000000..01a0b92 --- /dev/null +++ b/structpvalink_1_1pva_global__t_1_1_scan.html @@ -0,0 +1,122 @@ + + + + + + +pva2pva: pvalink::pvaGlobal_t::Scan Struct Reference + + + + + + + + + +
+
+ + + + + + +
+
pva2pva +  0 +
+
+
+ + + + + + + + + +
+ +
+ + +
+
+ +
+
pvalink::pvaGlobal_t::Scan Struct Reference
+
+
+ + + + + + +

+Public Attributes

+std::tr1::weak_ptr
+< pvaLinkChannel
chan
 
+bool usecached
 
+

Detailed Description

+
+

Definition at line 52 of file pvalink.h.

+

The documentation for this struct was generated from the following file: +
+ + + + diff --git a/structpvalink_1_1pva_global__t__coll__graph.map b/structpvalink_1_1pva_global__t__coll__graph.map new file mode 100644 index 0000000..495620c --- /dev/null +++ b/structpvalink_1_1pva_global__t__coll__graph.map @@ -0,0 +1,3 @@ + + + diff --git a/structpvalink_1_1pva_global__t__coll__graph.md5 b/structpvalink_1_1pva_global__t__coll__graph.md5 new file mode 100644 index 0000000..fab8e3e --- /dev/null +++ b/structpvalink_1_1pva_global__t__coll__graph.md5 @@ -0,0 +1 @@ +20081f2739515c354ded7567ffbdb073 \ No newline at end of file diff --git a/structpvalink_1_1pva_global__t__coll__graph.png b/structpvalink_1_1pva_global__t__coll__graph.png new file mode 100644 index 0000000..a9c932d Binary files /dev/null and b/structpvalink_1_1pva_global__t__coll__graph.png differ diff --git a/structpvalink_1_1pva_link-members.html b/structpvalink_1_1pva_link-members.html new file mode 100644 index 0000000..ddb6995 --- /dev/null +++ b/structpvalink_1_1pva_link-members.html @@ -0,0 +1,156 @@ + + + + + + +pva2pva: Member List + + + + + + + + + +
+
+ + + + + + +
+
pva2pva +  1.4.1 +
+
+
+ + + + + + + + + +
+ +
+ + +
+
+
+
pvalink::pvaLink Member List
+
+
+ +

This is the complete list of members for pvalink::pvaLink, including all inherited members.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
alive (defined in pvalink::pvaLink)pvalink::pvaLink
always (defined in pvalink::pvaLinkConfig)pvalink::pvaLinkConfig
channelNamepvalink::pvaLinkConfig
CP enum value (defined in pvalink::pvaLinkConfig)pvalink::pvaLinkConfig
CPP enum value (defined in pvalink::pvaLinkConfig)pvalink::pvaLinkConfig
Default enum value (defined in pvalink::pvaLinkConfig)pvalink::pvaLinkConfig
defer (defined in pvalink::pvaLinkConfig)pvalink::pvaLinkConfig
fieldNamepvalink::pvaLinkConfig
fld_control (defined in pvalink::pvaLink)pvalink::pvaLink
fld_display (defined in pvalink::pvaLink)pvalink::pvaLink
fld_nanoseconds (defined in pvalink::pvaLink)pvalink::pvaLink
fld_seconds (defined in pvalink::pvaLink)pvalink::pvaLink
fld_severity (defined in pvalink::pvaLink)pvalink::pvaLink
fld_value (defined in pvalink::pvaLink)pvalink::pvaLink
fld_valueAlarm (defined in pvalink::pvaLink)pvalink::pvaLink
getSubField(const char *name) (defined in pvalink::pvaLink)pvalink::pvaLink
jkey (defined in pvalink::pvaLinkConfig)pvalink::pvaLinkConfig
lchan (defined in pvalink::pvaLink)pvalink::pvaLink
local (defined in pvalink::pvaLinkConfig)pvalink::pvaLinkConfig
makeRequest() (defined in pvalink::pvaLink)pvalink::pvaLink
monorder (defined in pvalink::pvaLinkConfig)pvalink::pvaLinkConfig
ms (defined in pvalink::pvaLinkConfig)pvalink::pvaLinkConfig
MS enum value (defined in pvalink::pvaLinkConfig)pvalink::pvaLinkConfig
ms_t enum name (defined in pvalink::pvaLinkConfig)pvalink::pvaLinkConfig
MSI enum value (defined in pvalink::pvaLinkConfig)pvalink::pvaLinkConfig
NMS enum value (defined in pvalink::pvaLinkConfig)pvalink::pvaLinkConfig
NPP enum value (defined in pvalink::pvaLinkConfig)pvalink::pvaLinkConfig
num_instances (defined in pvalink::pvaLink)pvalink::pvaLinkstatic
onDisconnect() (defined in pvalink::pvaLink)pvalink::pvaLink
onTypeChange() (defined in pvalink::pvaLink)pvalink::pvaLink
pipeline (defined in pvalink::pvaLinkConfig)pvalink::pvaLinkConfig
plink (defined in pvalink::pvaLink)pvalink::pvaLink
pp (defined in pvalink::pvaLinkConfig)pvalink::pvaLinkConfig
PP enum value (defined in pvalink::pvaLinkConfig)pvalink::pvaLinkConfig
pp_t enum name (defined in pvalink::pvaLinkConfig)pvalink::pvaLinkConfig
proc_changed (defined in pvalink::pvaLink)pvalink::pvaLink
put_queue (defined in pvalink::pvaLink)pvalink::pvaLink
put_scratch (defined in pvalink::pvaLink)pvalink::pvaLink
pvaLink() (defined in pvalink::pvaLink)pvalink::pvaLink
pvaLinkConfig() (defined in pvalink::pvaLinkConfig)pvalink::pvaLinkConfig
queueSize (defined in pvalink::pvaLinkConfig)pvalink::pvaLinkConfig
retry (defined in pvalink::pvaLinkConfig)pvalink::pvaLinkConfig
snap_severity (defined in pvalink::pvaLink)pvalink::pvaLink
snap_time (defined in pvalink::pvaLink)pvalink::pvaLink
time (defined in pvalink::pvaLinkConfig)pvalink::pvaLinkConfig
type (defined in pvalink::pvaLink)pvalink::pvaLink
used_queue (defined in pvalink::pvaLink)pvalink::pvaLink
used_scratch (defined in pvalink::pvaLink)pvalink::pvaLink
valid() const (defined in pvalink::pvaLink)pvalink::pvaLink
~pvaLink() (defined in pvalink::pvaLink)pvalink::pvaLinkvirtual
~pvaLinkConfig() (defined in pvalink::pvaLinkConfig)pvalink::pvaLinkConfigvirtual
+ + + + diff --git a/structpvalink_1_1pva_link.html b/structpvalink_1_1pva_link.html new file mode 100644 index 0000000..9025e18 --- /dev/null +++ b/structpvalink_1_1pva_link.html @@ -0,0 +1,273 @@ + + + + + + +pva2pva: pvalink::pvaLink Struct Reference + + + + + + + + + +
+
+ + + + + + +
+
pva2pva +  1.4.1 +
+
+
+ + + + + + + + + +
+ +
+ + +
+ +
+
+Inheritance diagram for pvalink::pvaLink:
+
+
Inheritance graph
+ + +
[legend]
+
+Collaboration diagram for pvalink::pvaLink:
+
+
Collaboration graph
+ + +
[legend]
+ + + + + + + + + + + + +

+Public Member Functions

+pvd::PVStructurePtr makeRequest ()
 
+bool valid () const
 
+pvd::PVField::const_shared_pointer getSubField (const char *name)
 
+void onDisconnect ()
 
+void onTypeChange ()
 
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Public Attributes

+bool alive
 
+dbfType type
 
+DBLINK * plink
 
+std::tr1::shared_ptr
+< pvaLinkChannel
lchan
 
+bool used_scratch
 
+bool used_queue
 
+pvd::shared_vector< const void > put_scratch
 
+pvd::shared_vector< const void > put_queue
 
+epics::pvData::PVField::const_shared_pointer fld_value
 
+epics::pvData::PVScalar::const_shared_pointer fld_severity
 
+epics::pvData::PVScalar::const_shared_pointer fld_seconds
 
+epics::pvData::PVScalar::const_shared_pointer fld_nanoseconds
 
+epics::pvData::PVStructure::const_shared_pointer fld_display
 
+epics::pvData::PVStructure::const_shared_pointer fld_control
 
+epics::pvData::PVStructure::const_shared_pointer fld_valueAlarm
 
+epics::pvData::BitSet proc_changed
 
+epicsTimeStamp snap_time
 
+short snap_severity
 
+ + + +

+Static Public Attributes

+static size_t num_instances
 
+ + + + + + +

+Additional Inherited Members

+

Detailed Description

+
+

Definition at line 204 of file pvalink.h.

+

The documentation for this struct was generated from the following files: +
+ + + + diff --git a/structpvalink_1_1pva_link_1_1_value-members.html b/structpvalink_1_1pva_link_1_1_value-members.html new file mode 100644 index 0000000..54b27c9 --- /dev/null +++ b/structpvalink_1_1pva_link_1_1_value-members.html @@ -0,0 +1,114 @@ + + + + + + +pva2pva: Member List + + + + + + + + + +
+
+ + + + + + +
+
pva2pva +  0 +
+
+
+ + + + + + + + + +
+ +
+ + +
+
+
+
pvalink::pvaLink::Value Member List
+
+ + + + + diff --git a/structpvalink_1_1pva_link_1_1_value.html b/structpvalink_1_1pva_link_1_1_value.html new file mode 100644 index 0000000..1aaca4f --- /dev/null +++ b/structpvalink_1_1pva_link_1_1_value.html @@ -0,0 +1,150 @@ + + + + + + +pva2pva: pvalink::pvaLink::Value Struct Reference + + + + + + + + + +
+
+ + + + + + +
+
pva2pva +  0 +
+
+
+ + + + + + + + + +
+ +
+ + +
+
+ +
+
pvalink::pvaLink::Value Struct Reference
+
+
+
+Collaboration diagram for pvalink::pvaLink::Value:
+
+
Collaboration graph
+ + +
[legend]
+ + + + +

+Public Member Functions

+void clear ()
 
+ + + + + + + + + + + + + + + +

+Public Attributes

+bool valid
 
+bool scalar
 
+pvd::ScalarType etype
 
+pvd::shared_vector< const void > valueA
 
+dbrbuf valueS
 
+epicsUInt16 sevr
 
+epicsTimeStamp time
 
+

Detailed Description

+
+

Definition at line 191 of file pvalink.h.

+

The documentation for this struct was generated from the following file: +
+ + + + diff --git a/structpvalink_1_1pva_link_1_1_value__coll__graph.map b/structpvalink_1_1pva_link_1_1_value__coll__graph.map new file mode 100644 index 0000000..8bf86fa --- /dev/null +++ b/structpvalink_1_1pva_link_1_1_value__coll__graph.map @@ -0,0 +1,3 @@ + + + diff --git a/structpvalink_1_1pva_link_1_1_value__coll__graph.md5 b/structpvalink_1_1pva_link_1_1_value__coll__graph.md5 new file mode 100644 index 0000000..507f185 --- /dev/null +++ b/structpvalink_1_1pva_link_1_1_value__coll__graph.md5 @@ -0,0 +1 @@ +f2ac7df2b6e892ed54894d5808686f98 \ No newline at end of file diff --git a/structpvalink_1_1pva_link_1_1_value__coll__graph.png b/structpvalink_1_1pva_link_1_1_value__coll__graph.png new file mode 100644 index 0000000..c304dca Binary files /dev/null and b/structpvalink_1_1pva_link_1_1_value__coll__graph.png differ diff --git a/structpvalink_1_1pva_link__coll__graph.map b/structpvalink_1_1pva_link__coll__graph.map new file mode 100644 index 0000000..0d24d34 --- /dev/null +++ b/structpvalink_1_1pva_link__coll__graph.map @@ -0,0 +1,3 @@ + + + diff --git a/structpvalink_1_1pva_link__coll__graph.md5 b/structpvalink_1_1pva_link__coll__graph.md5 new file mode 100644 index 0000000..46f766c --- /dev/null +++ b/structpvalink_1_1pva_link__coll__graph.md5 @@ -0,0 +1 @@ +8127be780995731714c6ecf25a9ffb41 \ No newline at end of file diff --git a/structpvalink_1_1pva_link__coll__graph.png b/structpvalink_1_1pva_link__coll__graph.png new file mode 100644 index 0000000..1034a12 Binary files /dev/null and b/structpvalink_1_1pva_link__coll__graph.png differ diff --git a/structpvalink_1_1pva_link__inherit__graph.map b/structpvalink_1_1pva_link__inherit__graph.map new file mode 100644 index 0000000..0d24d34 --- /dev/null +++ b/structpvalink_1_1pva_link__inherit__graph.map @@ -0,0 +1,3 @@ + + + diff --git a/structpvalink_1_1pva_link__inherit__graph.md5 b/structpvalink_1_1pva_link__inherit__graph.md5 new file mode 100644 index 0000000..46f766c --- /dev/null +++ b/structpvalink_1_1pva_link__inherit__graph.md5 @@ -0,0 +1 @@ +8127be780995731714c6ecf25a9ffb41 \ No newline at end of file diff --git a/structpvalink_1_1pva_link__inherit__graph.png b/structpvalink_1_1pva_link__inherit__graph.png new file mode 100644 index 0000000..1034a12 Binary files /dev/null and b/structpvalink_1_1pva_link__inherit__graph.png differ diff --git a/structpvalink_1_1pva_link_channel-members.html b/structpvalink_1_1pva_link_channel-members.html new file mode 100644 index 0000000..a70c5fb --- /dev/null +++ b/structpvalink_1_1pva_link_channel-members.html @@ -0,0 +1,135 @@ + + + + + + +pva2pva: Member List + + + + + + + + + +
+
+ + + + + + +
+
pva2pva +  1.4.1 +
+
+
+ + + + + + + + + +
+ +
+ + +
+
+
+
pvalink::pvaLinkChannel Member List
+
+
+ +

This is the complete list of members for pvalink::pvaLinkChannel, including all inherited members.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
after_put (defined in pvalink::pvaLinkChannel)pvalink::pvaLinkChannel
after_put_t typedef (defined in pvalink::pvaLinkChannel)pvalink::pvaLinkChannel
AP (defined in pvalink::pvaLinkChannel)pvalink::pvaLinkChannel
chan (defined in pvalink::pvaLinkChannel)pvalink::pvaLinkChannel
connected (defined in pvalink::pvaLinkChannel)pvalink::pvaLinkChannel
connected_latched (defined in pvalink::pvaLinkChannel)pvalink::pvaLinkChannel
debug (defined in pvalink::pvaLinkChannel)pvalink::pvaLinkChannel
isatomic (defined in pvalink::pvaLinkChannel)pvalink::pvaLinkChannel
key (defined in pvalink::pvaLinkChannel)pvalink::pvaLinkChannel
links (defined in pvalink::pvaLinkChannel)pvalink::pvaLinkChannel
links_changed (defined in pvalink::pvaLinkChannel)pvalink::pvaLinkChannel
links_t typedef (defined in pvalink::pvaLinkChannel)pvalink::pvaLinkChannel
lock (defined in pvalink::pvaLinkChannel)pvalink::pvaLinkChannel
monitorEvent(const pvac::MonitorEvent &evt) OVERRIDE FINAL (defined in pvalink::pvaLinkChannel)pvalink::pvaLinkChannelvirtual
num_disconnect (defined in pvalink::pvaLinkChannel)pvalink::pvaLinkChannel
num_instances (defined in pvalink::pvaLinkChannel)pvalink::pvaLinkChannelstatic
num_type_change (defined in pvalink::pvaLinkChannel)pvalink::pvaLinkChannel
op_mon (defined in pvalink::pvaLinkChannel)pvalink::pvaLinkChannel
op_put (defined in pvalink::pvaLinkChannel)pvalink::pvaLinkChannel
open() (defined in pvalink::pvaLinkChannel)pvalink::pvaLinkChannel
previous_root (defined in pvalink::pvaLinkChannel)pvalink::pvaLinkChannel
providerName (defined in pvalink::pvaLinkChannel)pvalink::pvaLinkChannel
put(bool force=false) (defined in pvalink::pvaLinkChannel)pvalink::pvaLinkChannel
putBuild(const epics::pvData::StructureConstPtr &build, pvac::ClientChannel::PutCallback::Args &args) OVERRIDE FINAL (defined in pvalink::pvaLinkChannel)pvalink::pvaLinkChannelvirtual
putDone(const pvac::PutEvent &evt) OVERRIDE FINAL (defined in pvalink::pvaLinkChannel)pvalink::pvaLinkChannelvirtual
pvaLinkChannel(const pvaGlobal_t::channels_key_t &key, const epics::pvData::PVStructure::const_shared_pointer &pvRequest) (defined in pvalink::pvaLinkChannel)pvalink::pvaLinkChannel
pvRequest (defined in pvalink::pvaLinkChannel)pvalink::pvaLinkChannel
queued (defined in pvalink::pvaLinkChannel)pvalink::pvaLinkChannel
run_done (defined in pvalink::pvaLinkChannel)pvalink::pvaLinkChannel
~pvaLinkChannel() (defined in pvalink::pvaLinkChannel)pvalink::pvaLinkChannelvirtual
+ + + + diff --git a/structpvalink_1_1pva_link_channel.html b/structpvalink_1_1pva_link_channel.html new file mode 100644 index 0000000..ab17e46 --- /dev/null +++ b/structpvalink_1_1pva_link_channel.html @@ -0,0 +1,239 @@ + + + + + + +pva2pva: pvalink::pvaLinkChannel Struct Reference + + + + + + + + + +
+
+ + + + + + +
+
pva2pva +  1.4.1 +
+
+
+ + + + + + + + + +
+ +
+ + +
+
+ +
+
pvalink::pvaLinkChannel Struct Reference
+
+
+
+Inheritance diagram for pvalink::pvaLinkChannel:
+
+
Inheritance graph
+ + +
[legend]
+
+Collaboration diagram for pvalink::pvaLinkChannel:
+
+
Collaboration graph
+ + +
[legend]
+ + + + + + +

+Classes

struct  AfterPut
 
struct  LinkSort
 
+ + + + + +

+Public Types

+typedef std::set< dbCommon * > after_put_t
 
+typedef std::set< pvaLink
+*, LinkSort
links_t
 
+ + + + + + + + + + + + + +

+Public Member Functions

pvaLinkChannel (const pvaGlobal_t::channels_key_t &key, const epics::pvData::PVStructure::const_shared_pointer &pvRequest)
 
+void open ()
 
+void put (bool force=false)
 
+virtual void monitorEvent (const pvac::MonitorEvent &evt) OVERRIDE FINAL
 
+virtual void putBuild (const epics::pvData::StructureConstPtr &build, pvac::ClientChannel::PutCallback::Args &args) OVERRIDE FINAL
 
+virtual void putDone (const pvac::PutEvent &evt) OVERRIDE FINAL
 
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Public Attributes

+const pvaGlobal_t::channels_key_t key
 
+const
+pvd::PVStructure::const_shared_pointer 
pvRequest
 
+pvd::Mutex lock
 
+epicsEvent run_done
 
+pvac::ClientChannel chan
 
+pvac::Monitor op_mon
 
+pvac::Operation op_put
 
+std::string providerName
 
+size_t num_disconnect
 
+size_t num_type_change
 
+bool connected
 
+bool connected_latched
 
+bool isatomic
 
+bool queued
 
+bool debug
 
+std::tr1::shared_ptr< const void > previous_root
 
+after_put_t after_put
 
+links_t links
 
+bool links_changed
 
+std::tr1::shared_ptr< AfterPutAP
 
+ + + +

+Static Public Attributes

+static size_t num_instances
 
+

Detailed Description

+
+

Definition at line 132 of file pvalink.h.

+

The documentation for this struct was generated from the following files: +
+ + + + diff --git a/structpvalink_1_1pva_link_channel_1_1_after_put-members.html b/structpvalink_1_1pva_link_channel_1_1_after_put-members.html new file mode 100644 index 0000000..5d4bba8 --- /dev/null +++ b/structpvalink_1_1pva_link_channel_1_1_after_put-members.html @@ -0,0 +1,108 @@ + + + + + + +pva2pva: Member List + + + + + + + + + +
+
+ + + + + + +
+
pva2pva +  1.4.1 +
+
+
+ + + + + + + + + +
+ +
+ + +
+
+
+
pvalink::pvaLinkChannel::AfterPut Member List
+
+
+ +

This is the complete list of members for pvalink::pvaLinkChannel::AfterPut, including all inherited members.

+ + + + +
lc (defined in pvalink::pvaLinkChannel::AfterPut)pvalink::pvaLinkChannel::AfterPut
run() OVERRIDE FINAL (defined in pvalink::pvaLinkChannel::AfterPut)pvalink::pvaLinkChannel::AfterPutvirtual
~AfterPut() (defined in pvalink::pvaLinkChannel::AfterPut)pvalink::pvaLinkChannel::AfterPutinlinevirtual
+ + + + diff --git a/structpvalink_1_1pva_link_channel_1_1_after_put.html b/structpvalink_1_1pva_link_channel_1_1_after_put.html new file mode 100644 index 0000000..e1765b1 --- /dev/null +++ b/structpvalink_1_1pva_link_channel_1_1_after_put.html @@ -0,0 +1,141 @@ + + + + + + +pva2pva: pvalink::pvaLinkChannel::AfterPut Struct Reference + + + + + + + + + +
+
+ + + + + + +
+
pva2pva +  1.4.1 +
+
+
+ + + + + + + + + +
+ +
+ + +
+
+ +
+
pvalink::pvaLinkChannel::AfterPut Struct Reference
+
+
+
+Inheritance diagram for pvalink::pvaLinkChannel::AfterPut:
+
+
Inheritance graph
+ + +
[legend]
+
+Collaboration diagram for pvalink::pvaLinkChannel::AfterPut:
+
+
Collaboration graph
+ + +
[legend]
+ + + + +

+Public Member Functions

+virtual void run () OVERRIDE FINAL
 
+ + + +

+Public Attributes

+std::tr1::weak_ptr
+< pvaLinkChannel
lc
 
+

Detailed Description

+
+

Definition at line 185 of file pvalink.h.

+

The documentation for this struct was generated from the following files: +
+ + + + diff --git a/structpvalink_1_1pva_link_channel_1_1_after_put__coll__graph.map b/structpvalink_1_1pva_link_channel_1_1_after_put__coll__graph.map new file mode 100644 index 0000000..a4480b8 --- /dev/null +++ b/structpvalink_1_1pva_link_channel_1_1_after_put__coll__graph.map @@ -0,0 +1,2 @@ + + diff --git a/structpvalink_1_1pva_link_channel_1_1_after_put__coll__graph.md5 b/structpvalink_1_1pva_link_channel_1_1_after_put__coll__graph.md5 new file mode 100644 index 0000000..d22526c --- /dev/null +++ b/structpvalink_1_1pva_link_channel_1_1_after_put__coll__graph.md5 @@ -0,0 +1 @@ +320e78fefe30c4627c559218d10aca7c \ No newline at end of file diff --git a/structpvalink_1_1pva_link_channel_1_1_after_put__coll__graph.png b/structpvalink_1_1pva_link_channel_1_1_after_put__coll__graph.png new file mode 100644 index 0000000..d767974 Binary files /dev/null and b/structpvalink_1_1pva_link_channel_1_1_after_put__coll__graph.png differ diff --git a/structpvalink_1_1pva_link_channel_1_1_after_put__inherit__graph.map b/structpvalink_1_1pva_link_channel_1_1_after_put__inherit__graph.map new file mode 100644 index 0000000..a4480b8 --- /dev/null +++ b/structpvalink_1_1pva_link_channel_1_1_after_put__inherit__graph.map @@ -0,0 +1,2 @@ + + diff --git a/structpvalink_1_1pva_link_channel_1_1_after_put__inherit__graph.md5 b/structpvalink_1_1pva_link_channel_1_1_after_put__inherit__graph.md5 new file mode 100644 index 0000000..d22526c --- /dev/null +++ b/structpvalink_1_1pva_link_channel_1_1_after_put__inherit__graph.md5 @@ -0,0 +1 @@ +320e78fefe30c4627c559218d10aca7c \ No newline at end of file diff --git a/structpvalink_1_1pva_link_channel_1_1_after_put__inherit__graph.png b/structpvalink_1_1pva_link_channel_1_1_after_put__inherit__graph.png new file mode 100644 index 0000000..d767974 Binary files /dev/null and b/structpvalink_1_1pva_link_channel_1_1_after_put__inherit__graph.png differ diff --git a/structpvalink_1_1pva_link_channel_1_1_link_sort-members.html b/structpvalink_1_1pva_link_channel_1_1_link_sort-members.html new file mode 100644 index 0000000..9fb1fb9 --- /dev/null +++ b/structpvalink_1_1pva_link_channel_1_1_link_sort-members.html @@ -0,0 +1,106 @@ + + + + + + +pva2pva: Member List + + + + + + + + + +
+
+ + + + + + +
+
pva2pva +  1.4.1 +
+
+
+ + + + + + + + + +
+ +
+ + +
+
+
+
pvalink::pvaLinkChannel::LinkSort Member List
+
+
+ +

This is the complete list of members for pvalink::pvaLinkChannel::LinkSort, including all inherited members.

+ + +
operator()(const pvaLink *L, const pvaLink *R) const (defined in pvalink::pvaLinkChannel::LinkSort)pvalink::pvaLinkChannel::LinkSort
+ + + + diff --git a/structpvalink_1_1pva_link_channel_1_1_link_sort.html b/structpvalink_1_1pva_link_channel_1_1_link_sort.html new file mode 100644 index 0000000..9e8430b --- /dev/null +++ b/structpvalink_1_1pva_link_channel_1_1_link_sort.html @@ -0,0 +1,119 @@ + + + + + + +pva2pva: pvalink::pvaLinkChannel::LinkSort Struct Reference + + + + + + + + + +
+
+ + + + + + +
+
pva2pva +  1.4.1 +
+
+
+ + + + + + + + + +
+ +
+ + +
+
+ +
+
pvalink::pvaLinkChannel::LinkSort Struct Reference
+
+
+ + + + +

+Public Member Functions

+bool operator() (const pvaLink *L, const pvaLink *R) const
 
+

Detailed Description

+
+

Definition at line 160 of file pvalink.h.

+

The documentation for this struct was generated from the following files: +
+ + + + diff --git a/structpvalink_1_1pva_link_channel__coll__graph.map b/structpvalink_1_1pva_link_channel__coll__graph.map new file mode 100644 index 0000000..6d93e77 --- /dev/null +++ b/structpvalink_1_1pva_link_channel__coll__graph.map @@ -0,0 +1,2 @@ + + diff --git a/structpvalink_1_1pva_link_channel__coll__graph.md5 b/structpvalink_1_1pva_link_channel__coll__graph.md5 new file mode 100644 index 0000000..6bb6b4b --- /dev/null +++ b/structpvalink_1_1pva_link_channel__coll__graph.md5 @@ -0,0 +1 @@ +2bb7ade2926d671545bc1a71eab3737f \ No newline at end of file diff --git a/structpvalink_1_1pva_link_channel__coll__graph.png b/structpvalink_1_1pva_link_channel__coll__graph.png new file mode 100644 index 0000000..23b765b Binary files /dev/null and b/structpvalink_1_1pva_link_channel__coll__graph.png differ diff --git a/structpvalink_1_1pva_link_channel__inherit__graph.map b/structpvalink_1_1pva_link_channel__inherit__graph.map new file mode 100644 index 0000000..6d93e77 --- /dev/null +++ b/structpvalink_1_1pva_link_channel__inherit__graph.map @@ -0,0 +1,2 @@ + + diff --git a/structpvalink_1_1pva_link_channel__inherit__graph.md5 b/structpvalink_1_1pva_link_channel__inherit__graph.md5 new file mode 100644 index 0000000..6bb6b4b --- /dev/null +++ b/structpvalink_1_1pva_link_channel__inherit__graph.md5 @@ -0,0 +1 @@ +2bb7ade2926d671545bc1a71eab3737f \ No newline at end of file diff --git a/structpvalink_1_1pva_link_channel__inherit__graph.png b/structpvalink_1_1pva_link_channel__inherit__graph.png new file mode 100644 index 0000000..23b765b Binary files /dev/null and b/structpvalink_1_1pva_link_channel__inherit__graph.png differ diff --git a/structpvalink_1_1pva_link_config-members.html b/structpvalink_1_1pva_link_config-members.html new file mode 100644 index 0000000..e9b47ee --- /dev/null +++ b/structpvalink_1_1pva_link_config-members.html @@ -0,0 +1,130 @@ + + + + + + +pva2pva: Member List + + + + + + + + + +
+
+ + + + + + +
+
pva2pva +  1.4.1 +
+
+
+ + + + + + + + + +
+ +
+ + +
+
+
+
pvalink::pvaLinkConfig Member List
+
+
+ +

This is the complete list of members for pvalink::pvaLinkConfig, including all inherited members.

+ + + + + + + + + + + + + + + + + + + + + + + + + + +
always (defined in pvalink::pvaLinkConfig)pvalink::pvaLinkConfig
channelNamepvalink::pvaLinkConfig
CP enum value (defined in pvalink::pvaLinkConfig)pvalink::pvaLinkConfig
CPP enum value (defined in pvalink::pvaLinkConfig)pvalink::pvaLinkConfig
Default enum value (defined in pvalink::pvaLinkConfig)pvalink::pvaLinkConfig
defer (defined in pvalink::pvaLinkConfig)pvalink::pvaLinkConfig
fieldNamepvalink::pvaLinkConfig
jkey (defined in pvalink::pvaLinkConfig)pvalink::pvaLinkConfig
local (defined in pvalink::pvaLinkConfig)pvalink::pvaLinkConfig
monorder (defined in pvalink::pvaLinkConfig)pvalink::pvaLinkConfig
MS enum value (defined in pvalink::pvaLinkConfig)pvalink::pvaLinkConfig
ms (defined in pvalink::pvaLinkConfig)pvalink::pvaLinkConfig
ms_t enum name (defined in pvalink::pvaLinkConfig)pvalink::pvaLinkConfig
MSI enum value (defined in pvalink::pvaLinkConfig)pvalink::pvaLinkConfig
NMS enum value (defined in pvalink::pvaLinkConfig)pvalink::pvaLinkConfig
NPP enum value (defined in pvalink::pvaLinkConfig)pvalink::pvaLinkConfig
pipeline (defined in pvalink::pvaLinkConfig)pvalink::pvaLinkConfig
pp (defined in pvalink::pvaLinkConfig)pvalink::pvaLinkConfig
PP enum value (defined in pvalink::pvaLinkConfig)pvalink::pvaLinkConfig
pp_t enum name (defined in pvalink::pvaLinkConfig)pvalink::pvaLinkConfig
pvaLinkConfig() (defined in pvalink::pvaLinkConfig)pvalink::pvaLinkConfig
queueSize (defined in pvalink::pvaLinkConfig)pvalink::pvaLinkConfig
retry (defined in pvalink::pvaLinkConfig)pvalink::pvaLinkConfig
time (defined in pvalink::pvaLinkConfig)pvalink::pvaLinkConfig
~pvaLinkConfig() (defined in pvalink::pvaLinkConfig)pvalink::pvaLinkConfigvirtual
+ + + + diff --git a/structpvalink_1_1pva_link_config.html b/structpvalink_1_1pva_link_config.html new file mode 100644 index 0000000..4bfc062 --- /dev/null +++ b/structpvalink_1_1pva_link_config.html @@ -0,0 +1,190 @@ + + + + + + +pva2pva: pvalink::pvaLinkConfig Struct Reference + + + + + + + + + +
+
+ + + + + + +
+
pva2pva +  1.4.1 +
+
+
+ + + + + + + + + +
+ +
+ + +
+
+ +
+
pvalink::pvaLinkConfig Struct Reference
+
+
+
+Inheritance diagram for pvalink::pvaLinkConfig:
+
+
Inheritance graph
+ + +
[legend]
+
+Collaboration diagram for pvalink::pvaLinkConfig:
+
+
Collaboration graph
+ + +
[legend]
+ + + + + + +

+Public Types

enum  pp_t {
+  NPP, +Default, +PP, +CP, +
+  CPP +
+ }
 
enum  ms_t { NMS, +MS, +MSI + }
 
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Public Attributes

+std::string channelName
 Channel (aka PV) name string.
 
+std::string fieldName
 sub-field within addressed PVStructure
 
+size_t queueSize
 
+enum pvalink::pvaLinkConfig::pp_t pp
 
+enum pvalink::pvaLinkConfig::ms_t ms
 
+bool defer
 
+bool pipeline
 
+bool time
 
+bool retry
 
+bool local
 
+bool always
 
+int monorder
 
+std::string jkey
 
+

Detailed Description

+
+

Definition at line 75 of file pvalink.h.

+

The documentation for this struct was generated from the following files: +
+ + + + diff --git a/structpvalink_1_1pva_link_config__coll__graph.map b/structpvalink_1_1pva_link_config__coll__graph.map new file mode 100644 index 0000000..91537e6 --- /dev/null +++ b/structpvalink_1_1pva_link_config__coll__graph.map @@ -0,0 +1,2 @@ + + diff --git a/structpvalink_1_1pva_link_config__coll__graph.md5 b/structpvalink_1_1pva_link_config__coll__graph.md5 new file mode 100644 index 0000000..3f1fe7d --- /dev/null +++ b/structpvalink_1_1pva_link_config__coll__graph.md5 @@ -0,0 +1 @@ +951ccaaf89a00315512a56268d283296 \ No newline at end of file diff --git a/structpvalink_1_1pva_link_config__coll__graph.png b/structpvalink_1_1pva_link_config__coll__graph.png new file mode 100644 index 0000000..0ac7261 Binary files /dev/null and b/structpvalink_1_1pva_link_config__coll__graph.png differ diff --git a/structpvalink_1_1pva_link_config__inherit__graph.map b/structpvalink_1_1pva_link_config__inherit__graph.map new file mode 100644 index 0000000..365d3ad --- /dev/null +++ b/structpvalink_1_1pva_link_config__inherit__graph.map @@ -0,0 +1,3 @@ + + + diff --git a/structpvalink_1_1pva_link_config__inherit__graph.md5 b/structpvalink_1_1pva_link_config__inherit__graph.md5 new file mode 100644 index 0000000..87f7415 --- /dev/null +++ b/structpvalink_1_1pva_link_config__inherit__graph.md5 @@ -0,0 +1 @@ +5607291d593384d1a88364135901944a \ No newline at end of file diff --git a/structpvalink_1_1pva_link_config__inherit__graph.png b/structpvalink_1_1pva_link_config__inherit__graph.png new file mode 100644 index 0000000..201a5a4 Binary files /dev/null and b/structpvalink_1_1pva_link_config__inherit__graph.png differ diff --git a/structweak__set_1_1_x_iterator-members.html b/structweak__set_1_1_x_iterator-members.html new file mode 100644 index 0000000..f805577 --- /dev/null +++ b/structweak__set_1_1_x_iterator-members.html @@ -0,0 +1,111 @@ + + + + + + +pva2pva: Member List + + + + + + + + + +
+
+ + + + + + +
+
pva2pva +  1.4.1 +
+
+
+ + + + + + + + + +
+ +
+ + +
+
+
+
weak_set< T >::XIterator Member List
+
+
+ +

This is the complete list of members for weak_set< T >::XIterator, including all inherited members.

+ + + + + + + +
end (defined in weak_set< T >::XIterator)weak_set< T >::XIterator
guard (defined in weak_set< T >::XIterator)weak_set< T >::XIterator
it (defined in weak_set< T >::XIterator)weak_set< T >::XIterator
next()weak_set< T >::XIteratorinline
set (defined in weak_set< T >::XIterator)weak_set< T >::XIterator
XIterator(weak_set &S) (defined in weak_set< T >::XIterator)weak_set< T >::XIteratorinline
+ + + + diff --git a/structweak__set_1_1_x_iterator.html b/structweak__set_1_1_x_iterator.html new file mode 100644 index 0000000..cbd4de4 --- /dev/null +++ b/structweak__set_1_1_x_iterator.html @@ -0,0 +1,154 @@ + + + + + + +pva2pva: weak_set< T >::XIterator Struct Reference + + + + + + + + + +
+
+ + + + + + +
+
pva2pva +  1.4.1 +
+
+
+ + + + + + + + + +
+ +
+ + +
+
+ +
+
weak_set< T >::XIterator Struct Reference
+
+
+ +

an iterator-ish object which also locks the set during iteration + More...

+ +

#include <weakset.h>

+
+Collaboration diagram for weak_set< T >::XIterator:
+
+
Collaboration graph
+ + +
[legend]
+ + + + + + + +

+Public Member Functions

XIterator (weak_set &S)
 
+value_pointer next ()
 yield the next live entry
 
+ + + + + + + + + +

+Public Attributes

+weak_setset
 
+epicsGuard< epicsMutex > guard
 
+store_t::iterator it
 
+store_t::iterator end
 
+

Detailed Description

+

template<typename T>
+struct weak_set< T >::XIterator

+ +

an iterator-ish object which also locks the set during iteration

+ +

Definition at line 204 of file weakset.h.

+

The documentation for this struct was generated from the following file: +
+ + + + diff --git a/structweak__set_1_1_x_iterator__coll__graph.map b/structweak__set_1_1_x_iterator__coll__graph.map new file mode 100644 index 0000000..cc30700 --- /dev/null +++ b/structweak__set_1_1_x_iterator__coll__graph.map @@ -0,0 +1,3 @@ + + + diff --git a/structweak__set_1_1_x_iterator__coll__graph.md5 b/structweak__set_1_1_x_iterator__coll__graph.md5 new file mode 100644 index 0000000..0455dfd --- /dev/null +++ b/structweak__set_1_1_x_iterator__coll__graph.md5 @@ -0,0 +1 @@ +fba55dd87ae6671818448fc0df51ca5e \ No newline at end of file diff --git a/structweak__set_1_1_x_iterator__coll__graph.png b/structweak__set_1_1_x_iterator__coll__graph.png new file mode 100644 index 0000000..bc4d27c Binary files /dev/null and b/structweak__set_1_1_x_iterator__coll__graph.png differ diff --git a/sync_off.png b/sync_off.png new file mode 100644 index 0000000..3b443fc Binary files /dev/null and b/sync_off.png differ diff --git a/sync_on.png b/sync_on.png new file mode 100644 index 0000000..e08320f Binary files /dev/null and b/sync_on.png differ diff --git a/tab_a.png b/tab_a.png new file mode 100644 index 0000000..3b725c4 Binary files /dev/null and b/tab_a.png differ diff --git a/tab_b.png b/tab_b.png new file mode 100644 index 0000000..e2b4a86 Binary files /dev/null and b/tab_b.png differ diff --git a/tab_h.png b/tab_h.png new file mode 100644 index 0000000..fd5cb70 Binary files /dev/null and b/tab_h.png differ diff --git a/tab_s.png b/tab_s.png new file mode 100644 index 0000000..ab478c9 Binary files /dev/null and b/tab_s.png differ diff --git a/tabs.css b/tabs.css new file mode 100644 index 0000000..9cf578f --- /dev/null +++ b/tabs.css @@ -0,0 +1,60 @@ +.tabs, .tabs2, .tabs3 { + background-image: url('tab_b.png'); + width: 100%; + z-index: 101; + font-size: 13px; + font-family: 'Lucida Grande',Geneva,Helvetica,Arial,sans-serif; +} + +.tabs2 { + font-size: 10px; +} +.tabs3 { + font-size: 9px; +} + +.tablist { + margin: 0; + padding: 0; + display: table; +} + +.tablist li { + float: left; + display: table-cell; + background-image: url('tab_b.png'); + line-height: 36px; + list-style: none; +} + +.tablist a { + display: block; + padding: 0 20px; + font-weight: bold; + background-image:url('tab_s.png'); + background-repeat:no-repeat; + background-position:right; + color: #283A5D; + text-shadow: 0px 1px 1px rgba(255, 255, 255, 0.9); + text-decoration: none; + outline: none; +} + +.tabs3 .tablist a { + padding: 0 10px; +} + +.tablist a:hover { + background-image: url('tab_h.png'); + background-repeat:repeat-x; + color: #fff; + text-shadow: 0px 1px 1px rgba(0, 0, 0, 1.0); + text-decoration: none; +} + +.tablist li.current a { + background-image: url('tab_a.png'); + background-repeat:repeat-x; + color: #fff; + text-shadow: 0px 1px 1px rgba(0, 0, 0, 1.0); +} diff --git a/testmon_8cpp_source.html b/testmon_8cpp_source.html new file mode 100644 index 0000000..6536e8a --- /dev/null +++ b/testmon_8cpp_source.html @@ -0,0 +1,474 @@ + + + + + + +pva2pva: p2pApp/testmon.cpp Source File + + + + + + + + + +
+
+ + + + + + +
+
pva2pva +  1.4.1 +
+
+
+ + + + + + + + + +
+ +
+ + +
+
+
+
testmon.cpp
+
+
+
1 
+
2 #include <epicsAtomic.h>
+
3 #include <epicsGuard.h>
+
4 #include <epicsUnitTest.h>
+
5 #include <testMain.h>
+
6 
+
7 #include <pv/epicsException.h>
+
8 #include <pv/monitor.h>
+
9 #include <pv/thread.h>
+
10 #include <pv/serverContext.h>
+
11 
+
12 #include "server.h"
+
13 
+
14 #include "utilities.h"
+
15 
+
16 namespace pvd = epics::pvData;
+
17 namespace pva = epics::pvAccess;
+
18 
+
19 typedef epicsGuard<epicsMutex> Guard;
+
20 
+
21 namespace {
+
22 
+
23 pvd::PVStructurePtr makeRequest(size_t bsize)
+
24 {
+
25  pvd::StructureConstPtr dtype(pvd::getFieldCreate()->createFieldBuilder()
+
26  ->addNestedStructure("record")
+
27  ->addNestedStructure("_options")
+
28  ->add("queueSize", pvd::pvString) // yes, really. PVA wants a string
+
29  ->endNested()
+
30  ->endNested()
+
31  ->createStructure());
+
32 
+
33  pvd::PVStructurePtr ret(pvd::getPVDataCreate()->createPVStructure(dtype));
+
34  ret->getSubFieldT<pvd::PVScalar>("record._options.queueSize")->putFrom<pvd::int32>(bsize);
+
35 
+
36  return ret;
+
37 }
+
38 
+
39 struct TestMonitor {
+
40  TestProvider::shared_pointer upstream;
+
41  TestPV::shared_pointer test1;
+
42  ScalarAccessor<pvd::int32> test1_x, test1_y;
+
43 
+
44  GWServerChannelProvider::shared_pointer gateway;
+
45 
+
46  TestChannelRequester::shared_pointer client_req;
+
47  pva::Channel::shared_pointer client;
+
48 
+
49  // prepare providers and connect the client channel, don't setup monitor
+
50  TestMonitor()
+
51  :upstream(new TestProvider())
+
52  ,test1(upstream->addPV("test1", pvd::getFieldCreate()->createFieldBuilder()
+
53  ->add("x", pvd::pvInt)
+
54  ->add("y", pvd::pvInt)
+
55  ->createStructure()))
+
56  ,test1_x(test1->value, "x")
+
57  ,test1_y(test1->value, "y")
+
58  ,gateway(new GWServerChannelProvider(upstream))
+
59  ,client_req(new TestChannelRequester)
+
60  ,client(gateway->createChannel("test1", client_req))
+
61  {
+
62  testDiag("pre-test setup");
+
63  if(!client)
+
64  testAbort("channel \"test1\" not connected");
+
65  test1_x = 1;
+
66  test1_y = 2;
+
67  }
+
68 
+
69  ~TestMonitor()
+
70  {
+
71  client->destroy();
+
72  gateway->destroy(); // noop atm.
+
73  }
+
74 
+
75  void test_event()
+
76  {
+
77  testDiag("Push the initial event through from upstream to downstream");
+
78 
+
79  TestChannelMonitorRequester::shared_pointer mreq(new TestChannelMonitorRequester);
+
80  pvd::Monitor::shared_pointer mon(client->createMonitor(mreq, makeRequest(2)));
+
81  if(!mon) testAbort("Failed to create monitor");
+
82 
+
83  testEqual(mreq->eventCnt, 0u);
+
84  testOk1(mon->start().isSuccess());
+
85  upstream->dispatch(); // trigger monitorEvent() from upstream to gateway
+
86 
+
87  testEqual(mreq->eventCnt, 1u);
+
88  pva::MonitorElementPtr elem(mon->poll());
+
89  testOk1(!!elem.get());
+
90  if(!!elem.get()) testEqual(toString(*elem->changedBitSet), "{0}");
+
91  else testFail("oops");
+
92  testOk1(elem && elem->pvStructurePtr->getSubFieldT<pvd::PVInt>("x")->get()==1);
+
93 
+
94  if(elem) mon->release(elem);
+
95 
+
96  testOk1(!mon->poll());
+
97 
+
98  mon->destroy();
+
99  }
+
100 
+
101  void test_share()
+
102  {
+
103  // here both downstream monitors are on the same Channel,
+
104  // which would be inefficient, and slightly unrealistic, w/ real PVA,
+
105  // but w/ TestProvider makes no difference
+
106  testDiag("Test two downstream monitors sharing the same upstream");
+
107 
+
108  TestChannelMonitorRequester::shared_pointer mreq(new TestChannelMonitorRequester);
+
109  pvd::Monitor::shared_pointer mon(client->createMonitor(mreq, makeRequest(2)));
+
110  if(!mon) testAbort("Failed to create monitor");
+
111 
+
112 
+
113  TestChannelMonitorRequester::shared_pointer mreq2(new TestChannelMonitorRequester);
+
114  pvd::Monitor::shared_pointer mon2(client->createMonitor(mreq2, makeRequest(2)));
+
115  if(!mon2) testAbort("Failed to create monitor2");
+
116 
+
117  testOk1(mreq->eventCnt==0);
+
118  testOk1(mreq2->eventCnt==0);
+
119  testOk1(mon->start().isSuccess());
+
120  testOk1(mon2->start().isSuccess());
+
121  upstream->dispatch(); // trigger monitorEvent() from upstream to gateway
+
122 
+
123  testOk1(mreq->eventCnt==1);
+
124  testOk1(mreq2->eventCnt==1);
+
125 
+
126  pva::MonitorElementPtr elem(mon->poll());
+
127  pva::MonitorElementPtr elem2(mon2->poll());
+
128  testOk1(!!elem.get());
+
129  testOk1(!!elem2.get());
+
130  testOk1(elem!=elem2);
+
131  testOk1(elem && elem->pvStructurePtr->getSubFieldT<pvd::PVInt>("x")->get()==1);
+
132  testOk1(elem && elem->pvStructurePtr->getSubFieldT<pvd::PVInt>("y")->get()==2);
+
133  testOk1(elem2 && elem2->pvStructurePtr->getSubFieldT<pvd::PVInt>("x")->get()==1);
+
134  testOk1(elem2 && elem2->pvStructurePtr->getSubFieldT<pvd::PVInt>("y")->get()==2);
+
135 
+
136  if(elem) mon->release(elem);
+
137  if(elem2) mon2->release(elem2);
+
138 
+
139  testOk1(!mon->poll());
+
140  testOk1(!mon2->poll());
+
141 
+
142  testDiag("explicitly push an update");
+
143  test1_x = 42;
+
144  test1_y = 43;
+
145  pvd::BitSet changed;
+
146  changed.set(1); // only indicate that 'x' changed
+
147  test1->post(changed);
+
148 
+
149  elem = mon->poll();
+
150  elem2 = mon2->poll();
+
151  testOk1(!!elem.get());
+
152  testOk1(!!elem2.get());
+
153  testOk1(elem!=elem2);
+
154  if(elem) testDiag("elem changed '%s' overflow '%s'", toString(*elem->changedBitSet).c_str(), toString(*elem->overrunBitSet).c_str());
+
155  testOk1(elem && elem->pvStructurePtr->getSubFieldT<pvd::PVInt>("x")->get()==42);
+
156  testOk1(elem && elem->pvStructurePtr->getSubFieldT<pvd::PVInt>("y")->get()==2);
+
157  if(elem2) testDiag("elem2 changed '%s' overflow '%s'", toString(*elem2->changedBitSet).c_str(), toString(*elem2->overrunBitSet).c_str());
+
158  testOk1(elem2 && elem2->pvStructurePtr->getSubFieldT<pvd::PVInt>("x")->get()==42);
+
159  testOk1(elem2 && elem2->pvStructurePtr->getSubFieldT<pvd::PVInt>("y")->get()==2);
+
160 
+
161  if(elem) mon->release(elem);
+
162  if(elem2) mon2->release(elem2);
+
163 
+
164  testOk1(!mon->poll());
+
165  testOk1(!mon2->poll());
+
166 
+
167  mon->destroy();
+
168  mon2->destroy();
+
169  }
+
170 
+
171  void test_ds_no_start()
+
172  {
+
173  testDiag("Test downstream monitor never start()s");
+
174 
+
175  TestChannelMonitorRequester::shared_pointer mreq(new TestChannelMonitorRequester);
+
176  pvd::Monitor::shared_pointer mon(client->createMonitor(mreq, makeRequest(2)));
+
177  if(!mon) testAbort("Failed to create monitor");
+
178 
+
179  upstream->dispatch(); // trigger monitorEvent() from upstream to gateway
+
180 
+
181  testOk1(mreq->eventCnt==0);
+
182  testOk1(!mon->poll());
+
183 
+
184  pvd::BitSet changed;
+
185  changed.set(1);
+
186  test1_x=50;
+
187  test1->post(changed, false);
+
188  test1_x=51;
+
189  test1->post(changed, false);
+
190  test1_x=52;
+
191  test1->post(changed, false);
+
192  test1_x=53;
+
193  test1->post(changed);
+
194 
+
195  testOk1(!mon->poll());
+
196 
+
197  mon->destroy();
+
198  }
+
199 
+
200  void test_overflow_upstream()
+
201  {
+
202  testDiag("Check behavour when upstream monitor overflows (mostly transparent)");
+
203 
+
204  TestChannelMonitorRequester::shared_pointer mreq(new TestChannelMonitorRequester);
+
205  pvd::Monitor::shared_pointer mon(client->createMonitor(mreq, makeRequest(2)));
+
206  if(!mon) testAbort("Failed to create monitor");
+
207 
+
208  testOk1(mreq->eventCnt==0);
+
209  testOk1(mon->start().isSuccess());
+
210  upstream->dispatch(); // trigger monitorEvent() from upstream to gateway
+
211  testOk1(mreq->eventCnt==1);
+
212 
+
213  testDiag("poll initial update");
+
214  pva::MonitorElementPtr elem(mon->poll());
+
215  testOk1(!!elem.get());
+
216  if(elem) mon->release(elem);
+
217 
+
218  testOk1(!mon->poll());
+
219 
+
220  // queue 4 events input buffer of size 2
+
221  // don't notify downstream until after overflow has occurred
+
222  pvd::BitSet changed;
+
223  changed.set(1);
+
224  test1_x=50;
+
225  testDiag("post 50");
+
226  test1->post(changed, false);
+
227  test1_x=51;
+
228  testDiag("post 51");
+
229  test1->post(changed, false);
+
230  test1_x=52;
+
231  testDiag("post 52");
+
232  test1->post(changed, false);
+
233  test1_x=53;
+
234  testDiag("post 53");
+
235  test1->post(changed);
+
236 
+
237  elem = mon->poll();
+
238  testOk1(!!elem.get());
+
239 
+
240  testDiag("XX %d", elem ? elem->pvStructurePtr->getSubFieldT<pvd::PVInt>("x")->get() : -42);
+
241  testOk1(elem && elem->pvStructurePtr->getSubFieldT<pvd::PVInt>("x")->get()==50);
+
242  testOk1(elem && elem->changedBitSet->nextSetBit(0)==1);
+
243  testOk1(elem && elem->changedBitSet->nextSetBit(2)==-1);
+
244  testOk1(elem && elem->overrunBitSet->nextSetBit(0)==-1);
+
245 
+
246  if(elem) mon->release(elem);
+
247 
+
248  elem = mon->poll();
+
249  testOk1(!!elem.get());
+
250 
+
251  testOk1(elem && elem->pvStructurePtr->getSubFieldT<pvd::PVInt>("x")->get()==51);
+
252  testOk1(elem && elem->changedBitSet->nextSetBit(0)==1);
+
253  testOk1(elem && elem->changedBitSet->nextSetBit(2)==-1);
+
254  testOk1(elem && elem->overrunBitSet->nextSetBit(0)==-1);
+
255 
+
256  if(elem) mon->release(elem);
+
257 
+
258  elem = mon->poll();
+
259  testOk1(!!elem.get());
+
260 
+
261  testOk1(elem && elem->pvStructurePtr->getSubFieldT<pvd::PVInt>("x")->get()==53);
+
262  testOk1(elem && elem->changedBitSet->nextSetBit(0)==1);
+
263  testOk1(elem && elem->changedBitSet->nextSetBit(2)==-1);
+
264  testOk1(elem && elem->overrunBitSet->nextSetBit(0)==1);
+
265  testOk1(elem && elem->overrunBitSet->nextSetBit(2)==-1);
+
266 
+
267  if(elem) mon->release(elem);
+
268 
+
269  testOk1(!mon->poll());
+
270 
+
271  mon->destroy();
+
272  }
+
273 
+
274  void test_overflow_downstream()
+
275  {
+
276  testDiag("Check behavour when downstream monitor overflows");
+
277 
+
278  TestChannelMonitorRequester::shared_pointer mreq(new TestChannelMonitorRequester);
+
279  pvd::Monitor::shared_pointer mon(client->createMonitor(mreq, makeRequest(2)));
+
280  if(!mon) testAbort("Failed to create monitor");
+
281 
+
282  testOk1(mreq->eventCnt==0);
+
283  testOk1(mon->start().isSuccess());
+
284  upstream->dispatch(); // trigger monitorEvent() from upstream to gateway
+
285  testOk1(mreq->eventCnt==1);
+
286 
+
287  testDiag("poll initial update");
+
288  pva::MonitorElementPtr elem(mon->poll());
+
289  testOk1(!!elem.get());
+
290  if(elem) mon->release(elem);
+
291 
+
292  // queue 4 events into buffer of size 2 (plus the overflow element)
+
293  // notify downstream after each update
+
294  // so the upstream queue never overflows
+
295  pvd::BitSet changed;
+
296  changed.set(1);
+
297  test1_x=50;
+
298  test1->post(changed);
+
299  test1_x=51;
+
300  test1->post(changed);
+
301  test1_x=52;
+
302  test1->post(changed);
+
303  test1_x=53;
+
304  test1->post(changed);
+
305 
+
306  elem = mon->poll();
+
307  testOk1(!!elem.get());
+
308 
+
309  testOk1(elem && elem->pvStructurePtr->getSubFieldT<pvd::PVInt>("x")->get()==50);
+
310  testOk1(elem && elem->changedBitSet->nextSetBit(0)==1);
+
311  testOk1(elem && elem->changedBitSet->nextSetBit(2)==-1);
+
312  testOk1(elem && elem->overrunBitSet->nextSetBit(0)==-1);
+
313 
+
314  if(elem) mon->release(elem);
+
315 
+
316  elem = mon->poll();
+
317  testOk1(!!elem.get());
+
318 
+
319  testOk1(elem && elem->pvStructurePtr->getSubFieldT<pvd::PVInt>("x")->get()==51);
+
320  testOk1(elem && elem->changedBitSet->nextSetBit(0)==1);
+
321  testOk1(elem && elem->changedBitSet->nextSetBit(2)==-1);
+
322  testOk1(elem && elem->overrunBitSet->nextSetBit(0)==-1);
+
323 
+
324  if(elem) mon->release(elem);
+
325 
+
326  elem = mon->poll();
+
327  testOk1(!!elem.get());
+
328 
+
329  testOk1(elem && elem->pvStructurePtr->getSubFieldT<pvd::PVInt>("x")->get()==53);
+
330  testOk1(elem && elem->changedBitSet->nextSetBit(0)==1);
+
331  testOk1(elem && elem->changedBitSet->nextSetBit(2)==-1);
+
332  testOk1(elem && elem->overrunBitSet->nextSetBit(0)==1);
+
333  testOk1(elem && elem->overrunBitSet->nextSetBit(2)==-1);
+
334 
+
335  if(elem) mon->release(elem);
+
336 
+
337  testOk1(!mon->poll());
+
338 
+
339  mon->destroy();
+
340  }
+
341 };
+
342 
+
343 } // namespace
+
344 
+
345 MAIN(testmon)
+
346 {
+
347  testPlan(79);
+
348  TEST_METHOD(TestMonitor, test_event);
+
349  TEST_METHOD(TestMonitor, test_share);
+
350  TEST_METHOD(TestMonitor, test_ds_no_start);
+
351  TEST_METHOD(TestMonitor, test_overflow_upstream);
+
352  TEST_METHOD(TestMonitor, test_overflow_downstream);
+
353  TestProvider::testCounts();
+
354  int ok = 1;
+
355  size_t temp;
+
356 #define TESTC(name) temp=epicsAtomicGetSizeT(&name::num_instances); ok &= temp==0; testDiag("num. live " #name " %u", (unsigned)temp)
+
357  TESTC(GWChannel);
+ +
359  TESTC(ChannelCacheEntry);
+
360  TESTC(MonitorCacheEntry);
+
361  TESTC(MonitorUser);
+
362 #undef TESTC
+
363  testOk(ok, "All instances free'd");
+
364  return testDone();
+
365 }
+ +
Definition: chancache.h:132
+ +
Definition: chancache.h:103
+ + +
Definition: chancache.h:22
+ + + +
+ + + + diff --git a/todo.html b/todo.html new file mode 100644 index 0000000..9e60f3e --- /dev/null +++ b/todo.html @@ -0,0 +1,94 @@ + + + + + + +pva2pva: Todo List + + + + + + + + + +
+
+ + + + + + +
+
pva2pva +  1.4.1 +
+
+
+ + + + + + + + +
+ +
+ +
+
+
+
Todo List
+
+
+
+
Page QSRV
+
Ability to traverse through unions and into structure arrays (as with group mappings).
+
+
+ + + + diff --git a/tpool_8cpp_source.html b/tpool_8cpp_source.html new file mode 100644 index 0000000..20c00c0 --- /dev/null +++ b/tpool_8cpp_source.html @@ -0,0 +1,234 @@ + + + + + + +pva2pva: pdbApp/tpool.cpp Source File + + + + + + + + + +
+
+ + + + + + +
+
pva2pva +  1.4.1 +
+
+
+ + + + + + + + + +
+ +
+ + +
+
+
+
tpool.cpp
+
+
+
1 
+
2 #include <typeinfo>
+
3 #include <stdexcept>
+
4 
+
5 #include <epicsEvent.h>
+
6 #include <epicsGuard.h>
+
7 #include <epicsThread.h>
+
8 #include <errlog.h>
+
9 
+
10 #include <pv/sharedPtr.h>
+
11 
+
12 #include "helper.h"
+
13 #include "tpool.h"
+
14 
+
15 typedef epicsGuard<epicsMutex> Guard;
+
16 typedef epicsGuardRelease<epicsMutex> UnGuard;
+
17 
+
18 WorkQueue::WorkQueue(const std::string& name)
+
19  :name(name)
+
20  ,state(Idle)
+
21 {}
+
22 
+
23 WorkQueue::~WorkQueue() { close(); }
+
24 
+
25 void WorkQueue::start(unsigned nworkers, unsigned prio)
+
26 {
+
27  Guard G(mutex);
+
28 
+
29  if(state!=Idle)
+
30  throw std::logic_error("Already started");
+
31 
+
32  try {
+
33  state = Active;
+
34 
+
35  for(unsigned i=0; i<nworkers; i++) {
+
36  p2p::auto_ptr<epicsThread> worker(new epicsThread(*this, name.c_str(),
+
37  epicsThreadGetStackSize(epicsThreadStackSmall),
+
38  prio));
+
39 
+
40  worker->start();
+
41 
+
42  workers.push_back(worker.get());
+
43  worker.release();
+
44  }
+
45  }catch(...){
+
46  UnGuard U(G); // unlock as close() blocks to join any workers which were started
+
47  close();
+
48  throw;
+
49  }
+
50 }
+
51 
+
52 void WorkQueue::close()
+
53 {
+
54  workers_t temp;
+
55 
+
56  {
+
57  Guard G(mutex);
+
58  if(state!=Active)
+
59  return;
+
60 
+
61  temp.swap(workers);
+
62  state = Stopping;
+
63  }
+
64 
+
65  wakeup.signal();
+
66 
+
67  for(workers_t::iterator it(temp.begin()), end(temp.end()); it!=end; ++it)
+
68  {
+
69  (*it)->exitWait();
+
70  delete *it;
+
71  }
+
72 
+
73  {
+
74  Guard G(mutex);
+
75  state = Idle;
+
76  }
+
77 }
+
78 
+
79 void WorkQueue::add(const value_type& work)
+
80 {
+
81  bool empty;
+
82 
+
83  {
+
84  Guard G(mutex);
+
85  if(state!=Active)
+
86  return;
+
87 
+
88  empty = queue.empty();
+
89 
+
90  queue.push_back(work);
+
91  }
+
92 
+
93  if(empty) {
+
94  wakeup.signal();
+
95  }
+
96 }
+
97 
+
98 void WorkQueue::run()
+
99 {
+
100  Guard G(mutex);
+
101 
+
102  std::tr1::shared_ptr<epicsThreadRunable> work;
+
103 
+
104  while(state==Active) {
+
105 
+
106  if(!queue.empty()) {
+
107  work = queue.front().lock();
+
108  queue.pop_front();
+
109  }
+
110 
+
111  bool last = queue.empty();
+
112 
+
113  {
+
114  UnGuard U(G);
+
115 
+
116  if(work) {
+
117  try {
+
118  work->run();
+
119  work.reset();
+
120  }catch(std::exception& e){
+
121  errlogPrintf("%s Unhandled exception from %s: %s\n",
+
122  name.c_str(), typeid(work.get()).name(), e.what());
+
123  work.reset();
+
124  }
+
125  }
+
126 
+
127  if(last) {
+
128  wakeup.wait();
+
129  }
+
130  }
+
131  }
+
132 
+
133  // pass along the close() signal to next worker
+
134  wakeup.signal();
+
135 }
+
+ + + + diff --git a/tpool_8h_source.html b/tpool_8h_source.html new file mode 100644 index 0000000..861337a --- /dev/null +++ b/tpool_8h_source.html @@ -0,0 +1,152 @@ + + + + + + +pva2pva: pdbApp/tpool.h Source File + + + + + + + + + +
+
+ + + + + + +
+
pva2pva +  1.4.1 +
+
+
+ + + + + + + + + +
+ +
+ + +
+
+
+
tpool.h
+
+
+
1 #ifndef TPOOL_H
+
2 #define TPOOL_H
+
3 
+
4 #include <stdexcept>
+
5 #include <deque>
+
6 #include <vector>
+
7 #include <string>
+
8 
+
9 #include <errlog.h>
+
10 #include <epicsThread.h>
+
11 #include <epicsMutex.h>
+
12 #include <epicsEvent.h>
+
13 
+
14 #include <pv/sharedPtr.h>
+
15 
+
16 struct WorkQueue : private epicsThreadRunable
+
17 {
+
18  typedef std::tr1::weak_ptr<epicsThreadRunable> value_type;
+
19 
+
20 private:
+
21  const std::string name;
+
22 
+
23  epicsMutex mutex;
+
24 
+
25  enum state_t {
+
26  Idle,
+
27  Active,
+
28  Stopping,
+
29  } state;
+
30 
+
31  typedef std::deque<value_type> queue_t;
+
32  queue_t queue;
+
33 
+
34  epicsEvent wakeup;
+
35 
+
36  typedef std::vector<epicsThread*> workers_t;
+
37  workers_t workers;
+
38 
+
39 public:
+
40  WorkQueue(const std::string& name);
+
41  virtual ~WorkQueue();
+
42 
+
43  void start(unsigned nworkers=1, unsigned prio = epicsThreadPriorityLow);
+
44  void close();
+
45 
+
46  void add(const value_type& work);
+
47 
+
48 private:
+
49  virtual void run();
+
50 };
+
51 
+
52 #endif // TPOOL_H
+ +
+ + + + diff --git a/uniondbrbuf-members.html b/uniondbrbuf-members.html new file mode 100644 index 0000000..d0ad3d6 --- /dev/null +++ b/uniondbrbuf-members.html @@ -0,0 +1,111 @@ + + + + + + +pva2pva: Member List + + + + + + + + + +
+
+ + + + + + +
+
pva2pva +  1.4.1 +
+
+
+ + + + + + + + + +
+ +
+ +
+
+
+
dbrbuf Member List
+
+
+ +

This is the complete list of members for dbrbuf, including all inherited members.

+ + + + + + + + + + + +
dbf_CHAR (defined in dbrbuf)dbrbuf
dbf_DOUBLE (defined in dbrbuf)dbrbuf
dbf_ENUM (defined in dbrbuf)dbrbuf
dbf_FLOAT (defined in dbrbuf)dbrbuf
dbf_LONG (defined in dbrbuf)dbrbuf
dbf_SHORT (defined in dbrbuf)dbrbuf
dbf_STRING (defined in dbrbuf)dbrbuf
dbf_UCHAR (defined in dbrbuf)dbrbuf
dbf_ULONG (defined in dbrbuf)dbrbuf
dbf_USHORT (defined in dbrbuf)dbrbuf
+ + + + diff --git a/uniondbrbuf.html b/uniondbrbuf.html new file mode 100644 index 0000000..0fc56e4 --- /dev/null +++ b/uniondbrbuf.html @@ -0,0 +1,141 @@ + + + + + + +pva2pva: dbrbuf Union Reference + + + + + + + + + +
+
+ + + + + + +
+
pva2pva +  1.4.1 +
+
+
+ + + + + + + + + +
+ +
+ +
+
+ +
+
dbrbuf Union Reference
+
+
+ + + + + + + + + + + + + + + + + + + + + + +

+Public Attributes

+epicsInt8 dbf_CHAR
 
+epicsUInt8 dbf_UCHAR
 
+epicsInt16 dbf_SHORT
 
+epicsUInt16 dbf_USHORT
 
+epicsEnum16 dbf_ENUM
 
+epicsInt32 dbf_LONG
 
+epicsUInt32 dbf_ULONG
 
+epicsFloat32 dbf_FLOAT
 
+epicsFloat64 dbf_DOUBLE
 
+char dbf_STRING [MAX_STRING_SIZE]
 
+

Detailed Description

+
+

Definition at line 61 of file pvif.h.

+

The documentation for this union was generated from the following file: +
+ + + + diff --git a/utilities_8cpp_source.html b/utilities_8cpp_source.html new file mode 100644 index 0000000..a2fb5c7 --- /dev/null +++ b/utilities_8cpp_source.html @@ -0,0 +1,744 @@ + + + + + + +pva2pva: common/utilities.cpp Source File + + + + + + + + + +
+
+ + + + + + +
+
pva2pva +  1.4.1 +
+
+
+ + + + + + + + + +
+ +
+ + +
+
+
+
utilities.cpp
+
+
+
1 
+
2 #include <epicsAtomic.h>
+
3 #include <errlog.h>
+
4 #include <epicsEvent.h>
+
5 #include <epicsUnitTest.h>
+
6 #include <dbUnitTest.h>
+
7 
+
8 #include <pv/pvUnitTest.h>
+
9 #include <pv/pvAccess.h>
+
10 
+
11 #define epicsExportSharedSymbols
+
12 #include <utilities.h>
+
13 #include <helper.h>
+
14 
+
15 typedef epicsGuard<epicsMutex> Guard;
+
16 typedef epicsGuardRelease<epicsMutex> UnGuard;
+
17 
+
18 namespace pvd = epics::pvData;
+
19 namespace pva = epics::pvAccess;
+
20 
+
21 static size_t countTestChannelRequester;
+
22 
+
23 TestChannelRequester::TestChannelRequester()
+
24  :laststate(pva::Channel::NEVER_CONNECTED)
+
25 {
+
26  epicsAtomicIncrSizeT(&countTestChannelRequester);
+
27 }
+
28 
+
29 
+
30 TestChannelRequester::~TestChannelRequester()
+
31 {
+
32  epicsAtomicDecrSizeT(&countTestChannelRequester);
+
33 }
+
34 
+
35 void TestChannelRequester::channelCreated(const pvd::Status& status, pva::Channel::shared_pointer const & channel)
+
36 {
+
37  testDiag("channelCreated %s", channel ? channel->getChannelName().c_str() : "<fails>");
+
38  Guard G(lock);
+
39  laststate = pva::Channel::CONNECTED;
+
40  this->status = status;
+
41  chan = channel;
+
42  wait.trigger();
+
43 }
+
44 
+
45 void TestChannelRequester::channelStateChange(pva::Channel::shared_pointer const & channel,
+
46  pva::Channel::ConnectionState connectionState)
+
47 {
+
48  testDiag("channelStateChange %s %d", channel->getChannelName().c_str(), (int)connectionState);
+
49  Guard G(lock);
+
50  laststate = connectionState;
+
51  wait.trigger();
+
52 }
+
53 
+
54 bool TestChannelRequester::waitForConnect()
+
55 {
+
56  Guard G(lock);
+
57  assert(chan);
+
58  while(true) {
+
59  pva::Channel::ConnectionState cur = chan->getConnectionState();
+
60  switch(cur) {
+
61  case pva::Channel::NEVER_CONNECTED:
+
62  break;
+
63  case pva::Channel::CONNECTED:
+
64  return true;
+
65  case pva::Channel::DISCONNECTED:
+
66  case pva::Channel::DESTROYED:
+
67  return false;
+
68  }
+
69  UnGuard U(G);
+
70  wait.wait();
+
71  }
+
72 
+
73 }
+
74 
+
75 static size_t countTestChannelGetRequester;
+
76 
+
77 TestChannelGetRequester::TestChannelGetRequester()
+
78  :connected(false)
+
79  ,done(false)
+
80 {
+
81  epicsAtomicIncrSizeT(&countTestChannelGetRequester);
+
82 }
+
83 
+
84 TestChannelGetRequester::~TestChannelGetRequester()
+
85 {
+
86  epicsAtomicDecrSizeT(&countTestChannelGetRequester);
+
87 }
+
88 
+
89 void TestChannelGetRequester::channelGetConnect(const epics::pvData::Status &status,
+
90  const epics::pvAccess::ChannelGet::shared_pointer &get,
+
91  const epics::pvData::Structure::const_shared_pointer &structure)
+
92 {
+
93  if(connected)
+
94  testFail("channelGetConnect() called twice");
+
95  statusConnect = status;
+
96  channelGet = get;
+
97  fielddesc = structure;
+
98  connected = true;
+
99 }
+
100 
+
101 void TestChannelGetRequester::getDone(const epics::pvData::Status &status,
+
102  const epics::pvAccess::ChannelGet::shared_pointer &get,
+
103  const epics::pvData::PVStructure::shared_pointer &pvStructure,
+
104  const epics::pvData::BitSet::shared_pointer &bitSet)
+
105 {
+
106  statusDone = status;
+
107  channelGet = get;
+
108  value = pvStructure;
+
109  changed = bitSet;
+
110  done = true;
+
111 }
+
112 
+
113 TestChannelPutRequester::TestChannelPutRequester()
+
114  :connected(false)
+
115  ,doneGet(false)
+
116  ,donePut(false)
+
117 {}
+
118 TestChannelPutRequester::~TestChannelPutRequester() {}
+
119 
+
120 void TestChannelPutRequester::channelPutConnect(
+
121  const epics::pvData::Status& status,
+
122  epics::pvAccess::ChannelPut::shared_pointer const & channelPut,
+
123  epics::pvData::Structure::const_shared_pointer const & structure)
+
124 {
+
125  statusConnect = status;
+
126  put = channelPut;
+
127  fielddesc = structure;
+
128  connected = true;
+
129 }
+
130 
+
131 void TestChannelPutRequester::putDone(
+
132  const epics::pvData::Status& status,
+
133  epics::pvAccess::ChannelPut::shared_pointer const & channelPut)
+
134 {
+
135  statusPut = status;
+
136  put = channelPut;
+
137  donePut = true;
+
138 }
+
139 
+
140 void TestChannelPutRequester::getDone(
+
141  const epics::pvData::Status& status,
+
142  epics::pvAccess::ChannelPut::shared_pointer const & channelPut,
+
143  epics::pvData::PVStructure::shared_pointer const & pvStructure,
+
144  epics::pvData::BitSet::shared_pointer const & bitSet)
+
145 {
+
146  statusGet = status;
+
147  put = channelPut;
+
148  value = pvStructure;
+
149  changed = bitSet;
+
150  doneGet = true;
+
151 }
+
152 
+
153 
+
154 static size_t countTestChannelMonitorRequester;
+
155 
+
156 TestChannelMonitorRequester::TestChannelMonitorRequester()
+
157  :connected(false)
+
158  ,unlistend(false)
+
159  ,eventCnt(0)
+
160 {
+
161  epicsAtomicIncrSizeT(&countTestChannelMonitorRequester);
+
162 }
+
163 
+
164 TestChannelMonitorRequester::~TestChannelMonitorRequester()
+
165 {
+
166  epicsAtomicDecrSizeT(&countTestChannelMonitorRequester);
+
167 }
+
168 
+
169 void TestChannelMonitorRequester::monitorConnect(pvd::Status const & status,
+
170  pvd::MonitorPtr const & monitor,
+
171  pvd::StructureConstPtr const & structure)
+
172 {
+
173  testDiag("monitorConnect %p %d", monitor.get(), (int)status.isSuccess());
+
174  Guard G(lock);
+
175  connectStatus = status;
+
176  dtype = structure;
+
177  connected = true;
+
178  wait.trigger();
+
179 }
+
180 
+
181 void TestChannelMonitorRequester::monitorEvent(pvd::MonitorPtr const & monitor)
+
182 {
+
183  testDiag("monitorEvent %p", monitor.get());
+
184  mon = monitor;
+
185  eventCnt++;
+
186  wait.trigger();
+
187 }
+
188 
+
189 void TestChannelMonitorRequester::unlisten(pvd::MonitorPtr const & monitor)
+
190 {
+
191  testDiag("unlisten %p", monitor.get());
+
192  Guard G(lock);
+
193  unlistend = true;
+
194  wait.trigger();
+
195 }
+
196 
+
197 bool TestChannelMonitorRequester::waitForConnect()
+
198 {
+
199  Guard G(lock);
+
200  while(!connected) {
+
201  UnGuard U(G);
+
202  wait.wait();
+
203  }
+
204  return true;
+
205 }
+
206 
+
207 bool TestChannelMonitorRequester::waitForEvent()
+
208 {
+
209  Guard G(lock);
+
210  size_t icnt = eventCnt;
+
211  while(!unlistend && eventCnt==icnt) {
+
212  UnGuard U(G);
+
213  wait.wait();
+
214  }
+
215  return !unlistend;
+
216 }
+
217 
+
218 static size_t countTestPVChannel;
+
219 
+
220 TestPVChannel::TestPVChannel(const std::tr1::shared_ptr<TestPV> &pv,
+
221  const std::tr1::shared_ptr<pva::ChannelRequester> &req)
+
222  :BaseChannel(pv->name, pv->provider, req, pv->dtype)
+
223  ,pv(pv)
+
224  ,state(CONNECTED)
+
225 {
+
226  epicsAtomicIncrSizeT(&countTestPVChannel);
+
227 }
+
228 
+
229 TestPVChannel::~TestPVChannel()
+
230 {
+
231  epicsAtomicDecrSizeT(&countTestPVChannel);
+
232 }
+
233 
+
234 TestPVChannel::ConnectionState TestPVChannel::getConnectionState()
+
235 {
+
236  Guard G(pv->lock);
+
237  return state;
+
238 }
+
239 
+
240 void TestPVChannel::getField(pva::GetFieldRequester::shared_pointer const & requester,std::string const & subField)
+
241 {
+
242  Guard G(pv->lock);
+
243 
+
244  //TODO subField?
+
245  requester->getDone(pvd::Status(), pv->dtype);
+
246 }
+
247 
+
248 pvd::Monitor::shared_pointer
+
249 TestPVChannel::createMonitor(
+
250  pvd::MonitorRequester::shared_pointer const & requester,
+
251  pvd::PVStructure::shared_pointer const & pvRequest)
+
252 {
+
253  shared_pointer self(weakself);
+
254  TestPVMonitor::shared_pointer ret(new TestPVMonitor(self, requester, 2));
+
255  {
+
256  Guard G(pv->lock);
+
257  monitors.insert(ret);
+
258  static_cast<TestPVMonitor*>(ret.get())->weakself = ret; // save wrapped weak ref
+
259  }
+
260  testDiag("TestPVChannel::createMonitor %s %p", pv->name.c_str(), ret.get());
+
261  requester->monitorConnect(pvd::Status(), ret, pv->dtype);
+
262  return ret;
+
263 }
+
264 
+
265 static size_t countTestPVMonitor;
+
266 
+
267 TestPVMonitor::TestPVMonitor(const TestPVChannel::shared_pointer& ch,
+
268  const pvd::MonitorRequester::shared_pointer& req,
+
269  size_t bsize)
+
270  :channel(ch)
+
271  ,requester(req)
+
272  ,running(false)
+
273  ,finalize(false)
+
274  ,inoverflow(false)
+
275  ,needWakeup(false)
+
276 {
+
277  pvd::PVDataCreatePtr fact(pvd::PVDataCreate::getPVDataCreate());
+
278  for(size_t i=0; i<bsize; i++) {
+
279  pva::MonitorElementPtr elem(new pvd::MonitorElement(fact->createPVStructure(channel->pv->dtype)));
+
280  free.push_back(elem);
+
281  }
+
282  overflow.reset(new pvd::MonitorElement(fact->createPVStructure(channel->pv->dtype)));
+
283  overflow->changedBitSet->set(0); // initially all changed
+
284  epicsAtomicIncrSizeT(&countTestPVMonitor);
+
285 }
+
286 
+
287 TestPVMonitor::~TestPVMonitor()
+
288 {
+
289  epicsAtomicDecrSizeT(&countTestPVMonitor);
+
290 }
+
291 
+
292 void TestPVMonitor::destroy()
+
293 {
+
294  Guard G(channel->pv->lock);
+
295 
+
296  shared_pointer self(weakself);
+
297  channel->monitors.erase(self); // ensure we don't get more notifications
+
298 }
+
299 
+
300 pvd::Status TestPVMonitor::start()
+
301 {
+
302  testDiag("TestPVMonitor::start %p", this);
+
303 
+
304  Guard G(channel->pv->lock);
+
305  if(finalize && buffer.empty())
+
306  return pvd::Status();
+
307 
+
308  if(running)
+
309  return pvd::Status();
+
310  running = true;
+
311 
+
312  // overflow element does double duty to hold this monitor's copy
+
313  overflow->pvStructurePtr->copyUnchecked(*channel->pv->value);
+
314 
+
315  if(this->buffer.empty()) {
+
316  needWakeup = true;
+
317  testDiag(" need wakeup");
+
318  }
+
319 
+
320  if(!this->free.empty()) {
+
321  pva::MonitorElementPtr monitorElement(this->free.front());
+
322 
+
323  if(overflow->changedBitSet->isEmpty()) {
+
324  overflow->changedBitSet->set(0); // initial update has all changed
+
325  overflow->overrunBitSet->clear();
+
326  }
+
327 
+
328  monitorElement->pvStructurePtr->copyUnchecked(*overflow->pvStructurePtr);
+
329  *monitorElement->changedBitSet = *overflow->changedBitSet;
+
330  *monitorElement->overrunBitSet = *overflow->overrunBitSet;
+
331  overflow->changedBitSet->clear();
+
332  overflow->overrunBitSet->clear();
+
333 
+
334  buffer.push_back(monitorElement);
+
335  this->free.pop_front();
+
336  testDiag(" push current");
+
337 
+
338  } else {
+
339  inoverflow = true;
+
340  overflow->changedBitSet->clear();
+
341  overflow->changedBitSet->set(0);
+
342  testDiag(" push overflow");
+
343  }
+
344 
+
345  return pvd::Status();
+
346 }
+
347 
+
348 pvd::Status TestPVMonitor::stop()
+
349 {
+
350  testDiag("TestPVMonitor::stop %p", this);
+
351  Guard G(channel->pv->lock);
+
352  running = false;
+
353  return pvd::Status();
+
354 }
+
355 
+
356 pva::MonitorElementPtr TestPVMonitor::poll()
+
357 {
+
358  pva::MonitorElementPtr ret;
+
359  Guard G(channel->pv->lock);
+
360  if(!buffer.empty()) {
+
361  ret = buffer.front();
+
362  buffer.pop_front();
+
363  }
+
364  testDiag("TestPVMonitor::poll %p %p", this, ret.get());
+
365  return ret;
+
366 }
+
367 
+
368 void TestPVMonitor::release(pva::MonitorElementPtr const & monitorElement)
+
369 {
+
370  Guard G(channel->pv->lock);
+
371  testDiag("TestPVMonitor::release %p %p", this, monitorElement.get());
+
372 
+
373  if(inoverflow) {
+
374  // buffer.empty() may be true if all elements poll()d by user
+
375  assert(this->free.empty());
+
376 
+
377  monitorElement->pvStructurePtr->copyUnchecked(*overflow->pvStructurePtr);
+
378  *monitorElement->changedBitSet = *overflow->changedBitSet;
+
379  *monitorElement->overrunBitSet = *overflow->overrunBitSet;
+
380 
+
381  overflow->changedBitSet->clear();
+
382  overflow->overrunBitSet->clear();
+
383 
+
384  buffer.push_back(monitorElement);
+
385  testDiag("TestPVMonitor::release overflow resume %p %p", this, monitorElement.get());
+
386  inoverflow = false;
+
387  } else {
+
388  this->free.push_back(monitorElement);
+
389  }
+
390 }
+
391 
+
392 static size_t countTestPV;
+
393 
+
394 TestPV::TestPV(const std::string& name,
+
395  const std::tr1::shared_ptr<TestProvider>& provider,
+
396  const pvd::StructureConstPtr& dtype)
+
397  :name(name)
+
398  ,provider(provider)
+
399  ,factory(pvd::PVDataCreate::getPVDataCreate())
+
400  ,dtype(dtype)
+
401  ,value(factory->createPVStructure(dtype))
+
402 {
+
403  epicsAtomicIncrSizeT(&countTestPV);
+
404 }
+
405 
+
406 TestPV::~TestPV()
+
407 {
+
408  epicsAtomicDecrSizeT(&countTestPV);
+
409 }
+
410 
+
411 void TestPV::post(bool notify)
+
412 {
+
413  pvd::BitSet changed;
+
414  changed.set(0); // all
+
415  post(changed, notify);
+
416 }
+
417 
+
418 void TestPV::post(const pvd::BitSet& changed, bool notify)
+
419 {
+
420  testDiag("post %s %d changed '%s'", name.c_str(), (int)notify, toString(changed).c_str());
+
421  Guard G(lock);
+
422 
+
423  channels_t::vector_type toupdate(channels.lock_vector());
+
424 
+
425  FOREACH(channels_t::vector_type::const_iterator, it, end, toupdate) // channel
+
426  {
+
427  TestPVChannel *chan = it->get();
+
428 
+
429  TestPVChannel::monitors_t::vector_type tomon(chan->monitors.lock_vector());
+
430  FOREACH(TestPVChannel::monitors_t::vector_type::const_iterator, it2, end2, tomon) // monitor/subscription
+
431  {
+
432  TestPVMonitor *mon = it2->get();
+
433 
+
434  if(!mon->running)
+
435  continue;
+
436 
+
437  mon->overflow->pvStructurePtr->copyUnchecked(*value, changed);
+
438 
+
439  if(mon->free.empty()) {
+
440  mon->inoverflow = true;
+
441  mon->overflow->overrunBitSet->or_and(*mon->overflow->changedBitSet, changed); // oflow |= prev_changed & new_changed
+
442  *mon->overflow->changedBitSet |= changed;
+
443  testDiag("overflow changed '%s' overrun '%s'",
+
444  toString(*mon->overflow->changedBitSet).c_str(),
+
445  toString(*mon->overflow->overrunBitSet).c_str());
+
446 
+
447  } else {
+
448  assert(!mon->inoverflow);
+
449 
+
450  if(mon->buffer.empty())
+
451  mon->needWakeup = true;
+
452 
+
453  pvd::MonitorElementPtr& elem(mon->free.front());
+
454  // Note: can't use 'changed' to optimize this copy since we don't know
+
455  // the state of the free element
+
456  elem->pvStructurePtr->copyUnchecked(*mon->overflow->pvStructurePtr);
+
457  *elem->changedBitSet = changed;
+
458  elem->overrunBitSet->clear(); // redundant/paranoia
+
459 
+
460  mon->buffer.push_back(elem);
+
461  mon->free.pop_front();
+
462  testDiag("push %p changed '%s' overflow '%s'", elem.get(),
+
463  toString(*elem->changedBitSet).c_str(),
+
464  toString(*elem->overrunBitSet).c_str());
+
465  }
+
466 
+
467  if(mon->needWakeup && notify) {
+
468  testDiag(" wakeup");
+
469  mon->needWakeup = false;
+
470  pva::MonitorRequester::shared_pointer req(mon->requester.lock());
+
471  UnGuard U(G);
+
472  if(req)
+
473  req->monitorEvent(*it2);
+
474  }
+
475  }
+
476  }
+
477 }
+
478 
+
479 void TestPV::disconnect()
+
480 {
+
481  Guard G(lock);
+
482  channels_t::vector_type toupdate(channels.lock_vector());
+
483 
+
484  FOREACH(channels_t::vector_type::const_iterator, it, end, toupdate) // channel
+
485  {
+
486  TestPVChannel *chan = it->get();
+
487 
+
488  chan->state = TestPVChannel::DISCONNECTED;
+
489  {
+
490  pva::ChannelRequester::shared_pointer req(chan->requester.lock());
+
491  UnGuard U(G);
+
492  if(req)
+
493  req->channelStateChange(*it, TestPVChannel::DISCONNECTED);
+
494  }
+
495  }
+
496 }
+
497 
+
498 static size_t countTestProvider;
+
499 
+
500 TestProvider::TestProvider()
+
501 {
+
502  epicsAtomicIncrSizeT(&countTestProvider);
+
503 }
+
504 
+
505 TestProvider::~TestProvider()
+
506 {
+
507  epicsAtomicDecrSizeT(&countTestProvider);
+
508 }
+
509 
+
510 void TestProvider::destroy()
+
511 {
+
512  // TODO: disconnect all?
+
513 }
+
514 
+
515 pva::ChannelFind::shared_pointer
+
516 TestProvider::channelList(pva::ChannelListRequester::shared_pointer const & requester)
+
517 {
+
518  pva::ChannelFind::shared_pointer ret;
+
519  pvd::PVStringArray::const_svector names;
+
520  requester->channelListResult(pvd::Status(pvd::Status::STATUSTYPE_FATAL, "Not implemented"),
+
521  ret,
+
522  names,
+
523  true);
+
524  return ret;
+
525 }
+
526 
+
527 pva::ChannelFind::shared_pointer
+
528 TestProvider::channelFind(std::string const & channelName,
+
529  pva::ChannelFindRequester::shared_pointer const & requester)
+
530 {
+
531  pva::ChannelFind::shared_pointer ret;
+
532  requester->channelFindResult(pvd::Status(pvd::Status::STATUSTYPE_FATAL, "Not implemented"),
+
533  ret, false);
+
534  return ret;
+
535 }
+
536 
+
537 pva::Channel::shared_pointer
+
538 TestProvider::createChannel(std::string const & channelName,pva::ChannelRequester::shared_pointer const & requester,
+
539  short priority)
+
540 {
+
541  return createChannel(channelName, requester, priority, "<unused>");
+
542 }
+
543 
+
544 pva::Channel::shared_pointer
+
545 TestProvider::createChannel(std::string const & channelName,
+
546  pva::ChannelRequester::shared_pointer const & requester,
+
547  short priority, std::string const & address)
+
548 {
+
549  pva::Channel::shared_pointer ret;
+
550 
+
551  {
+
552  Guard G(lock);
+
553 
+
554  TestPV::shared_pointer pv(pvs.find(channelName));
+
555  if(pv) {
+
556  TestPVChannel::shared_pointer chan(new TestPVChannel(pv, requester));
+
557  pv->channels.insert(chan);
+
558  chan->weakself = chan;
+
559  ret = chan;
+
560  }
+
561  }
+
562 
+
563  if(ret) {
+
564  requester->channelCreated(pvd::Status(), ret);
+
565  } else {
+
566  requester->channelCreated(pvd::Status(pvd::Status::STATUSTYPE_ERROR, "PV not found"), ret);
+
567  }
+
568  testDiag("createChannel %s %p", channelName.c_str(), ret.get());
+
569  return ret;
+
570 }
+
571 
+
572 TestPV::shared_pointer
+
573 TestProvider::addPV(const std::string& name, const pvd::StructureConstPtr& tdef)
+
574 {
+
575  Guard G(lock);
+
576  TestPV::shared_pointer ret(new TestPV(name, shared_from_this(), tdef));
+
577  pvs.insert(name, ret);
+
578  return ret;
+
579 }
+
580 
+
581 void TestProvider::dispatch()
+
582 {
+
583  Guard G(lock);
+
584  testDiag("TestProvider::dispatch");
+
585 
+
586  pvs_t::lock_vector_type allpvs(pvs.lock_vector());
+
587  FOREACH(pvs_t::lock_vector_type::const_iterator, pvit, pvend, allpvs)
+
588  {
+
589  TestPV *pv = pvit->second.get();
+
590  TestPV::channels_t::vector_type channels(pv->channels.lock_vector());
+
591 
+
592  FOREACH(TestPV::channels_t::vector_type::const_iterator, chit, chend, channels)
+
593  {
+
594  TestPVChannel *chan = chit->get();
+
595  TestPVChannel::monitors_t::vector_type monitors(chan->monitors.lock_vector());
+
596 
+
597  if(!chan->isConnected())
+
598  continue;
+
599 
+
600  FOREACH(TestPVChannel::monitors_t::vector_type::const_iterator, monit, monend, monitors)
+
601  {
+
602  TestPVMonitor *mon = monit->get();
+
603 
+
604  if(mon->finalize || !mon->running)
+
605  continue;
+
606 
+
607  if(mon->needWakeup) {
+
608  testDiag(" wakeup monitor %p", mon);
+
609  mon->needWakeup = false;
+
610  pva::MonitorRequester::shared_pointer req(mon->requester.lock());
+
611  UnGuard U(G);
+
612  if(req)
+
613  req->monitorEvent(*monit);
+
614  }
+
615  }
+
616  }
+
617  }
+
618 }
+
619 
+
620 void TestProvider::testCounts()
+
621 {
+
622  int ok = 1;
+
623  size_t temp;
+
624 #define TESTC(name) temp=epicsAtomicGetSizeT(&count##name); ok &= temp==0; testDiag("num. live " #name " %u", (unsigned)temp)
+ +
626  TESTC(TestChannelRequester);
+
627  TESTC(TestProvider);
+
628  TESTC(TestPV);
+
629  TESTC(TestPVChannel);
+
630  TESTC(TestPVMonitor);
+
631 #undef TESTC
+
632  testOk(ok, "All instances free'd");
+
633 }
+ + +
lock_vector_type lock_vector() const
Definition: weakmap.h:259
+ + +
value_pointer find(const K &k) const
Definition: weakmap.h:215
+
vector_type lock_vector() const
Definition: weakset.h:268
+ +
value_pointer insert(const K &k, value_pointer &v)
Definition: weakmap.h:230
+
void insert(value_pointer &)
Definition: weakset.h:227
+ + +
+ + + + diff --git a/utilities_8h_source.html b/utilities_8h_source.html new file mode 100644 index 0000000..649c622 --- /dev/null +++ b/utilities_8h_source.html @@ -0,0 +1,435 @@ + + + + + + +pva2pva: common/utilities.h Source File + + + + + + + + + +
+
+ + + + + + +
+
pva2pva +  1.4.1 +
+
+
+ + + + + + + + + +
+ +
+ + +
+
+
+
utilities.h
+
+
+
1 #ifndef UTILITIES_H
+
2 #define UTILITIES_H
+
3 
+
4 #include <deque>
+
5 #include <sstream>
+
6 
+
7 #include <errlog.h>
+
8 #include <epicsEvent.h>
+
9 #include <epicsUnitTest.h>
+
10 #include <dbUnitTest.h>
+
11 
+
12 #include <pv/pvUnitTest.h>
+
13 #include <pv/pvAccess.h>
+
14 
+
15 #include "pvahelper.h"
+
16 #include "weakmap.h"
+
17 #include "weakset.h"
+
18 
+
19 struct TestPV;
+
20 struct TestPVChannel;
+
21 struct TestPVMonitor;
+
22 struct TestProvider;
+
23 
+
24 // minimally useful boilerplate which must appear *everywhere*
+
25 #define DUMBREQUESTER(NAME) \
+
26  virtual std::string getRequesterName() OVERRIDE { return #NAME; }
+
27 
+
28 template<typename T>
+
29 inline std::string toString(const T& tbs)
+
30 {
+
31  std::ostringstream oss;
+
32  oss << tbs;
+
33  return oss.str();
+
34 }
+
35 
+
36 // Boilerplate reduction for accessing a scalar field
+
37 template<typename T>
+ +
39  epics::pvData::PVScalar::shared_pointer field;
+
40  typedef T value_type;
+
41  ScalarAccessor(const epics::pvData::PVStructurePtr& s, const char *name)
+
42  :field(s->getSubFieldT<epics::pvData::PVScalar>(name))
+
43  {}
+
44  operator value_type() {
+
45  return field->getAs<T>();
+
46  }
+
47  ScalarAccessor& operator=(T v) {
+
48  field->putFrom<T>(v);
+
49  return *this;
+
50  }
+
51  ScalarAccessor& operator+=(T v) {
+
52  field->putFrom<T>(field->getAs<T>()+v);
+
53  return *this;
+
54  }
+
55 };
+
56 
+
57 struct TestChannelRequester : public epics::pvAccess::ChannelRequester
+
58 {
+
59  POINTER_DEFINITIONS(TestChannelRequester);
+
60  DUMBREQUESTER(TestChannelRequester)
+
61 
+
62  epicsMutex lock;
+
63  epicsEvent wait;
+
64  epics::pvAccess::Channel::shared_pointer chan;
+
65  epics::pvData::Status status;
+
66  epics::pvAccess::Channel::ConnectionState laststate;
+ +
68  virtual ~TestChannelRequester();
+
69  virtual void channelCreated(const epics::pvData::Status& status, epics::pvAccess::Channel::shared_pointer const & channel);
+
70  virtual void channelStateChange(epics::pvAccess::Channel::shared_pointer const & channel, epics::pvAccess::Channel::ConnectionState connectionState);
+
71 
+
72  bool waitForConnect();
+
73 };
+
74 
+
75 struct TestChannelFieldRequester : public epics::pvAccess::GetFieldRequester
+
76 {
+
77  POINTER_DEFINITIONS(TestChannelFieldRequester);
+
78  DUMBREQUESTER(TestChannelFieldRequester)
+
79 
+
80  bool done;
+
81  epics::pvData::Status status;
+
82  epics::pvData::FieldConstPtr fielddesc;
+
83 
+
84  TestChannelFieldRequester() :done(false) {}
+
85  virtual ~TestChannelFieldRequester() {}
+
86 
+
87  virtual void getDone(
+
88  const epics::pvData::Status& status,
+
89  epics::pvData::FieldConstPtr const & field)
+
90  {
+
91  this->status = status;
+
92  fielddesc = field;
+
93  done = true;
+
94  }
+
95 };
+
96 
+
97 struct TestChannelGetRequester : public epics::pvAccess::ChannelGetRequester
+
98 {
+
99  POINTER_DEFINITIONS(TestChannelGetRequester);
+
100  DUMBREQUESTER(TestChannelGetRequester)
+
101 
+
102  bool connected, done;
+
103  epics::pvData::Status statusConnect, statusDone;
+
104  epics::pvAccess::ChannelGet::shared_pointer channelGet;
+
105  epics::pvData::Structure::const_shared_pointer fielddesc;
+
106  epics::pvData::PVStructure::shared_pointer value;
+
107  epics::pvData::BitSet::shared_pointer changed;
+
108 
+ +
110  virtual ~TestChannelGetRequester();
+
111 
+
112  virtual void channelGetConnect(
+
113  const epics::pvData::Status& status,
+
114  epics::pvAccess::ChannelGet::shared_pointer const & channelGet,
+
115  epics::pvData::Structure::const_shared_pointer const & structure);
+
116 
+
117  virtual void getDone(
+
118  const epics::pvData::Status& status,
+
119  epics::pvAccess::ChannelGet::shared_pointer const & channelGet,
+
120  epics::pvData::PVStructure::shared_pointer const & pvStructure,
+
121  epics::pvData::BitSet::shared_pointer const & bitSet);
+
122 };
+
123 
+
124 struct TestChannelPutRequester : public epics::pvAccess::ChannelPutRequester
+
125 {
+
126  POINTER_DEFINITIONS(TestChannelPutRequester);
+
127  DUMBREQUESTER(TestChannelPutRequester)
+
128 
+
129  bool connected, doneGet, donePut;
+
130  epics::pvData::Status statusConnect, statusPut, statusGet;
+
131  epics::pvAccess::ChannelPut::shared_pointer put;
+
132  epics::pvData::Structure::const_shared_pointer fielddesc;
+
133  epics::pvData::PVStructure::shared_pointer value;
+
134  epics::pvData::BitSet::shared_pointer changed;
+
135 
+ +
137  virtual ~TestChannelPutRequester();
+
138 
+
139  virtual void channelPutConnect(
+
140  const epics::pvData::Status& status,
+
141  epics::pvAccess::ChannelPut::shared_pointer const & channelPut,
+
142  epics::pvData::Structure::const_shared_pointer const & structure);
+
143 
+
144  virtual void putDone(
+
145  const epics::pvData::Status& status,
+
146  epics::pvAccess::ChannelPut::shared_pointer const & channelPut);
+
147 
+
148  virtual void getDone(
+
149  const epics::pvData::Status& status,
+
150  epics::pvAccess::ChannelPut::shared_pointer const & channelPut,
+
151  epics::pvData::PVStructure::shared_pointer const & pvStructure,
+
152  epics::pvData::BitSet::shared_pointer const & bitSet);
+
153 };
+
154 
+
155 struct TestChannelMonitorRequester : public epics::pvData::MonitorRequester
+
156 {
+
157  POINTER_DEFINITIONS(TestChannelMonitorRequester);
+
158  DUMBREQUESTER(TestChannelMonitorRequester)
+
159 
+
160  epicsMutex lock;
+
161  epicsEvent wait;
+
162  bool connected;
+
163  bool unlistend;
+
164  size_t eventCnt;
+
165  epics::pvData::Status connectStatus;
+
166  epics::pvData::MonitorPtr mon;
+
167  epics::pvData::StructureConstPtr dtype;
+
168 
+ +
170  virtual ~TestChannelMonitorRequester();
+
171 
+
172  virtual void monitorConnect(epics::pvData::Status const & status,
+
173  epics::pvData::MonitorPtr const & monitor,
+
174  epics::pvData::StructureConstPtr const & structure);
+
175  virtual void monitorEvent(epics::pvData::MonitorPtr const & monitor);
+
176  virtual void unlisten(epics::pvData::MonitorPtr const & monitor);
+
177 
+
178  bool waitForConnect();
+
179  bool waitForEvent();
+
180 };
+
181 
+
182 struct TestPVChannel : public BaseChannel
+
183 {
+
184  POINTER_DEFINITIONS(TestPVChannel);
+
185  DUMBREQUESTER(TestPVChannel)
+
186  std::tr1::weak_ptr<TestPVChannel> weakself;
+
187 
+
188  const std::tr1::shared_ptr<TestPV> pv;
+
189  ConnectionState state;
+
190 
+ +
192  monitors_t monitors;
+
193 
+
194  TestPVChannel(const std::tr1::shared_ptr<TestPV>& pv,
+
195  const std::tr1::shared_ptr<epics::pvAccess::ChannelRequester>& req);
+
196  virtual ~TestPVChannel();
+
197 
+
198  virtual std::string getRemoteAddress() { return "localhost:1234"; }
+
199  virtual ConnectionState getConnectionState();
+
200 
+
201  virtual void getField(epics::pvAccess::GetFieldRequester::shared_pointer const & requester,std::string const & subField);
+
202 
+
203  virtual epics::pvData::Monitor::shared_pointer createMonitor(
+
204  epics::pvData::MonitorRequester::shared_pointer const & monitorRequester,
+
205  epics::pvData::PVStructure::shared_pointer const & pvRequest);
+
206 };
+
207 
+
208 struct TestPVMonitor : public epics::pvData::Monitor
+
209 {
+
210  POINTER_DEFINITIONS(TestPVMonitor);
+
211  std::tr1::weak_ptr<TestPVMonitor> weakself;
+
212 
+
213  const TestPVChannel::shared_pointer channel;
+
214  const epics::pvData::MonitorRequester::weak_pointer requester;
+
215 
+
216  bool running;
+
217  bool finalize;
+
218  bool inoverflow;
+
219  bool needWakeup;
+
220 
+
221  TestPVMonitor(const TestPVChannel::shared_pointer& ch,
+
222  const epics::pvData::MonitorRequester::shared_pointer& req,
+
223  size_t bsize);
+
224  virtual ~TestPVMonitor();
+
225 
+
226  virtual void destroy();
+
227 
+
228  virtual epics::pvData::Status start();
+
229  virtual epics::pvData::Status stop();
+
230  virtual epics::pvData::MonitorElementPtr poll();
+
231  virtual void release(epics::pvData::MonitorElementPtr const & monitorElement);
+
232 
+
233  std::deque<epics::pvData::MonitorElementPtr> buffer, free;
+
234  epics::pvData::MonitorElementPtr overflow;
+
235 };
+
236 
+
237 struct TestPV
+
238 {
+
239  POINTER_DEFINITIONS(TestPV);
+
240  std::tr1::weak_ptr<TestPV> weakself;
+
241 
+
242  const std::string name;
+
243  std::tr1::weak_ptr<TestProvider> const provider;
+
244 
+
245  epics::pvData::PVDataCreatePtr factory;
+
246 
+
247  const epics::pvData::StructureConstPtr dtype;
+
248  epics::pvData::PVStructurePtr value;
+
249 
+
250  TestPV(const std::string& name,
+
251  const std::tr1::shared_ptr<TestProvider>& provider,
+
252  const epics::pvData::StructureConstPtr& dtype);
+
253  ~TestPV();
+
254 
+
255  void post(bool notify = true);
+
256  void post(const epics::pvData::BitSet& changed, bool notify = true);
+
257 
+
258  void disconnect();
+
259 
+
260  mutable epicsMutex lock;
+
261 
+ +
263  channels_t channels;
+
264  friend struct TestProvider;
+
265 };
+
266 
+
267 struct TestProvider : public epics::pvAccess::ChannelProvider, std::tr1::enable_shared_from_this<TestProvider>
+
268 {
+
269  POINTER_DEFINITIONS(TestProvider);
+
270 
+
271  virtual std::string getProviderName() { return "TestProvider"; }
+
272 
+
273  virtual void destroy();
+
274 
+
275  virtual epics::pvAccess::ChannelFind::shared_pointer channelFind(std::string const & channelName,
+
276  epics::pvAccess::ChannelFindRequester::shared_pointer const & channelFindRequester);
+
277  virtual epics::pvAccess::ChannelFind::shared_pointer channelList(epics::pvAccess::ChannelListRequester::shared_pointer const & channelListRequester);
+
278  virtual epics::pvAccess::Channel::shared_pointer createChannel(std::string const & channelName,epics::pvAccess::ChannelRequester::shared_pointer const & channelRequester,
+
279  short priority = PRIORITY_DEFAULT);
+
280  virtual epics::pvAccess::Channel::shared_pointer createChannel(std::string const & channelName, epics::pvAccess::ChannelRequester::shared_pointer const & channelRequester,
+
281  short priority, std::string const & address);
+
282 
+
283  TestProvider();
+
284  virtual ~TestProvider();
+
285 
+
286  TestPV::shared_pointer addPV(const std::string& name, const epics::pvData::StructureConstPtr& tdef);
+
287 
+
288  void dispatch();
+
289 
+
290  mutable epicsMutex lock;
+ +
292  pvs_t pvs;
+
293 
+
294  static void testCounts();
+
295 };
+
296 
+
297 struct TestIOC {
+
298  bool hasInit;
+
299  TestIOC() : hasInit(false) {
+
300  testdbPrepare();
+
301  }
+
302  ~TestIOC() {
+
303  this->shutdown();
+
304  testdbCleanup();
+
305  }
+
306  void init() {
+
307  if(!hasInit) {
+
308  eltc(0);
+
309  testIocInitOk();
+
310  eltc(1);
+
311  hasInit = true;
+
312  }
+
313  }
+
314  void shutdown() {
+
315  if(hasInit) {
+
316  testIocShutdownOk();
+
317  hasInit = false;
+
318  }
+
319  }
+
320 };
+
321 
+
322 #endif // UTILITIES_H
+ + + + + + + + + + + + + + +
+ + + + diff --git a/utilitiesx_8cpp_source.html b/utilitiesx_8cpp_source.html new file mode 100644 index 0000000..283b12a --- /dev/null +++ b/utilitiesx_8cpp_source.html @@ -0,0 +1,101 @@ + + + + + + +pva2pva: p2pApp/utilitiesx.cpp Source File + + + + + + + + + +
+
+ + + + + + +
+
pva2pva +  1.4.1 +
+
+
+ + + + + + + + + +
+ +
+ + +
+
+
+
utilitiesx.cpp
+
+
+
1 // hack to avoid a convienence library
+
2 #include "utilities.cpp"
+
+ + + + diff --git a/weakmap_8h_source.html b/weakmap_8h_source.html new file mode 100644 index 0000000..5767b3f --- /dev/null +++ b/weakmap_8h_source.html @@ -0,0 +1,317 @@ + + + + + + +pva2pva: p2pApp/weakmap.h Source File + + + + + + + + + +
+
+ + + + + + +
+
pva2pva +  1.4.1 +
+
+
+ + + + + + + + + +
+ +
+ + +
+
+
+
weakmap.h
+
+
+
1 #ifndef WEAKMAP_H
+
2 #define WEAKMAP_H
+
3 
+
4 #include <map>
+
5 #include <set>
+
6 #include <vector>
+
7 #include <stdexcept>
+
8 
+
9 #include <pv/sharedPtr.h>
+
10 #include <epicsMutex.h>
+
11 #include <epicsGuard.h>
+
12 
+
58 template<typename K, typename V, typename C = std::less<K> >
+ +
60 {
+
61 public:
+
62  typedef K key_type;
+
63  typedef V value_type;
+
64  typedef std::tr1::shared_ptr<V> value_pointer;
+
65  typedef std::tr1::weak_ptr<V> value_weak_pointer;
+
66  typedef std::set<value_pointer> set_type;
+
67 
+
68  typedef epicsMutex mutex_type;
+
69  typedef epicsGuard<epicsMutex> guard_type;
+
70  typedef epicsGuardRelease<epicsMutex> release_type;
+
71 private:
+
72  typedef std::map<K, value_weak_pointer, C> store_t;
+
73 
+
74  struct data {
+
75  mutex_type mutex;
+
76  store_t store;
+
77  };
+
78  std::tr1::shared_ptr<data> _data;
+
79 
+
80  struct dtor {
+
81  std::tr1::weak_ptr<data> container;
+
82  K key;
+
83  value_pointer realself;
+
84  dtor(const std::tr1::weak_ptr<data>& d,
+
85  const K& k,
+
86  const value_pointer& w)
+
87  :container(d), key(k), realself(w)
+
88  {}
+
89  void operator()(value_type *)
+
90  {
+
91  value_pointer R;
+
92  R.swap(realself);
+
93  std::tr1::shared_ptr<data> cont(container.lock());
+
94  if(cont) {
+
95  guard_type G(cont->mutex);
+
96  cont->store.erase(key);
+
97  }
+
98 
+
99  /* A subtle gotcha may exist since this struct
+
100  * may not be destructed until the *weak*
+
101  * count of the enclosing shared_ptr goes
+
102  * to zero. Which won't happen
+
103  * as long as we hold a weak ref to the
+
104  * container holding a weak ref to us.
+
105  * It is *essential* that we break this
+
106  * "weak ref. loop" explicitly
+
107  */
+
108  container.reset();
+
109  }
+
110  };
+
111 public:
+
113  weak_value_map() :_data(new data) {}
+
114 
+
115 private:
+
117  weak_value_map(const weak_value_map& O);
+
119  weak_value_map& operator=(const weak_value_map& O);
+
120 public:
+
121 
+
124  void swap(weak_value_map& O) {
+
125  _data.swap(O._data);
+
126  }
+
127 
+
130  void clear() {
+
131  guard_type G(_data->mutex);
+
132  return _data->store.clear();
+
133  }
+
134 
+
138  bool empty() const {
+
139  guard_type G(_data->mutex);
+
140  return _data->store.empty();
+
141  }
+
142 
+
147  size_t size() const {
+
148  guard_type G(_data->mutex);
+
149  return _data->store.size();
+
150  }
+
151 
+ +
156  weak_value_map& M;
+
157  const key_type& k;
+
158  friend class weak_value_map;
+
159  element_proxy(weak_value_map& m, const key_type& k)
+
160  :M(m), k(k) {}
+
161  public:
+
162  ~element_proxy() {}
+
166  value_pointer& operator=(value_pointer& v)
+
167  {
+
168  if(!v.unique())
+
169  throw std::invalid_argument("Only unique() references may be inserted");
+
170  value_pointer chainptr(v.get(), dtor(M._data, k, v));
+
171  M._data->store[k] = chainptr;
+
172  v.swap(chainptr);
+
173  return v;
+
174  }
+
176  inline V& operator*() const {
+
177  return *value_pointer(*this);
+
178  }
+
180  inline V* operator->() const {
+
181  return value_pointer(*this).get();
+
182  }
+
184  operator value_pointer() const
+
185  {
+
186  value_pointer ret = M.find(k);
+
187  if(!ret)
+
188  throw std::runtime_error("Bad key");
+
189  return ret;
+
190  }
+
191  bool operator==(const value_pointer& v) const
+
192  {
+
193  return M.find(k)==v;
+
194  }
+
195  bool operator!=(const value_pointer& v) const
+
196  {
+
197  return !(*this==v);
+
198  }
+
199  };
+
200 
+
201  inline element_proxy operator[](const K& k)
+
202  {
+
203  return element_proxy(*this, k);
+
204  }
+
205 
+
206  value_pointer operator[](const K& k) const
+
207  {
+
208  value_pointer ret = find(k);
+
209  if(!ret)
+
210  throw std::runtime_error("Bad key");
+
211  }
+
212 
+
215  value_pointer find(const K& k) const
+
216  {
+
217  value_pointer ret;
+
218  guard_type G(_data->mutex);
+
219  typename store_t::const_iterator it(_data->store.find(k));
+
220  if(it!=_data->store.end()) {
+
221  // may be nullptr if we race destruction
+
222  // as ref. count falls to zero before we can remove it
+
223  ret = it->second.lock();
+
224  }
+
225  return ret;
+
226  }
+
227 
+
230  value_pointer insert(const K& k, value_pointer& v)
+
231  {
+
232  value_pointer ret;
+
233  guard_type G(_data->mutex);
+
234  typename store_t::const_iterator it = _data->store.find(k);
+
235  if(it!=_data->store.end())
+
236  ret = it->second.lock();
+
237  (*this)[k] = v;
+
238  return ret;
+
239  }
+
240 
+
241  typedef std::map<K, value_pointer, C> lock_map_type;
+
243  lock_map_type lock_map() const
+
244  {
+
245  lock_map_type ret;
+
246  guard_type G(_data->mutex);
+
247  for(typename store_t::const_iterator it = _data->store.begin(),
+
248  end = _data->store.end(); it!=end; ++it)
+
249  {
+
250  value_pointer P(it->second.lock);
+
251  if(P) ret[it->first] = P;
+
252  }
+
253  return ret;
+
254  }
+
255 
+
256  typedef std::vector<std::pair<K, value_pointer> > lock_vector_type;
+
259  lock_vector_type lock_vector() const
+
260  {
+
261  lock_vector_type ret;
+
262  guard_type G(_data->mutex);
+
263  ret.reserve(_data->store.size());
+
264  for(typename store_t::const_iterator it = _data->store.begin(),
+
265  end = _data->store.end(); it!=end; ++it)
+
266  {
+
267  value_pointer P(it->second.lock());
+
268  if(P) ret.push_back(std::make_pair(it->first, P));
+
269  }
+
270  return ret;
+
271  }
+
272 
+
276  inline epicsMutex& mutex() const {
+
277  return _data->mutex;
+
278  }
+
279 };
+
280 
+
281 #endif // WEAKMAP_H
+
void clear()
Definition: weakmap.h:130
+ +
V * operator->() const
Support: map[k]-&gt;mem.
Definition: weakmap.h:180
+
size_t size() const
Definition: weakmap.h:147
+
lock_vector_type lock_vector() const
Definition: weakmap.h:259
+
void swap(weak_value_map &O)
Definition: weakmap.h:124
+
weak_value_map()
Construct a new empty set.
Definition: weakmap.h:113
+
epicsMutex & mutex() const
Definition: weakmap.h:276
+
value_pointer find(const K &k) const
Definition: weakmap.h:215
+
lock_map_type lock_map() const
Return an equivalent map with strong value references.
Definition: weakmap.h:243
+
V & operator*() const
Support: *map[k].
Definition: weakmap.h:176
+
value_pointer & operator=(value_pointer &v)
Definition: weakmap.h:166
+
value_pointer insert(const K &k, value_pointer &v)
Definition: weakmap.h:230
+
An associative map where a weak_ptr to the value is stored.
Definition: weakmap.h:59
+
bool empty() const
Definition: weakmap.h:138
+
+ + + + diff --git a/weakset_8h_source.html b/weakset_8h_source.html new file mode 100644 index 0000000..2006ab3 --- /dev/null +++ b/weakset_8h_source.html @@ -0,0 +1,324 @@ + + + + + + +pva2pva: p2pApp/weakset.h Source File + + + + + + + + + +
+
+ + + + + + +
+
pva2pva +  1.4.1 +
+
+
+ + + + + + + + + +
+ +
+ + +
+
+
+
weakset.h
+
+
+
1 #ifndef WEAKSET_H
+
2 #define WEAKSET_H
+
3 
+
4 #include <set>
+
5 #include <vector>
+
6 #include <stdexcept>
+
7 
+
8 #include <pv/sharedPtr.h>
+
9 #include <epicsMutex.h>
+
10 #include <epicsGuard.h>
+
11 
+
56 template<typename T>
+
57 class weak_set
+
58 {
+
59 public:
+
60  typedef T value_type;
+
61  typedef std::tr1::shared_ptr<T> value_pointer;
+
62  typedef std::tr1::weak_ptr<T> value_weak_pointer;
+
63  typedef std::set<value_pointer> set_type;
+
64  typedef std::vector<value_pointer> vector_type;
+
65 
+
66  typedef epicsMutex mutex_type;
+
67  typedef epicsGuard<epicsMutex> guard_type;
+
68  typedef epicsGuardRelease<epicsMutex> release_type;
+
69 private:
+
70  struct weak_less {
+
71  bool operator()(const value_weak_pointer& lhs,
+
72  const value_weak_pointer& rhs) const
+
73  {
+
74  value_pointer LHS(lhs.lock()), RHS(rhs.lock());
+
75  return LHS && RHS && LHS.get() < RHS.get();
+
76  }
+
77  bool operator()(const value_pointer& lhs,
+
78  const value_weak_pointer& rhs) const
+
79  {
+
80  value_pointer RHS(rhs.lock());
+
81  return RHS && lhs.get() < RHS.get();
+
82  }
+
83  bool operator()(const value_weak_pointer& lhs,
+
84  const value_pointer& rhs) const
+
85  {
+
86  value_pointer LHS(lhs.lock());
+
87  return LHS && LHS.get() < rhs.get();
+
88  }
+
89  };
+
90 
+
91  typedef std::set<value_weak_pointer, weak_less> store_t;
+
92 
+
93  struct data {
+
94  mutex_type mutex;
+
95  store_t store;
+
96  };
+
97  std::tr1::shared_ptr<data> _data;
+
98 
+
102  struct dtor {
+
103  std::tr1::weak_ptr<data> container;
+
104  value_pointer realself;
+
105  dtor(const std::tr1::weak_ptr<data>& d,
+
106  const value_pointer& w)
+
107  :container(d), realself(w)
+
108  {}
+
109  void operator()(value_type *)
+
110  {
+
111  value_pointer R;
+
112  R.swap(realself);
+
113  assert(R.unique());
+
114  std::tr1::shared_ptr<data> C(container.lock());
+
115  if(C) {
+
116  guard_type G(C->mutex);
+
117  C->store.erase(R);
+
118  }
+
119 
+
120  /* A subtle gotcha may exist since this struct
+
121  * may not be destructed until the *weak*
+
122  * count of the enclosing shared_ptr goes
+
123  * to zero. Which won't happen
+
124  * as long as we hold a weak ref to the
+
125  * container holding a weak ref to us.
+
126  * It is *essential* that we break this
+
127  * "weak ref. loop" explicitly
+
128  */
+
129  container.reset();
+
130  }
+
131  };
+
132 public:
+
134  weak_set() :_data(new data) {}
+
135 
+
136 private:
+
138  weak_set(const weak_set& O);
+
140  weak_set& operator=(const weak_set& O);
+
141 public:
+
142 
+
145  void swap(weak_set& O) {
+
146  _data.swap(O._data);
+
147  }
+
148 
+
151  void clear() {
+
152  guard_type G(_data->mutex);
+
153  return _data->store.clear();
+
154  }
+
155 
+
159  bool empty() const {
+
160  guard_type G(_data->mutex);
+
161  return _data->store.empty();
+
162  }
+
163 
+
168  size_t size() const {
+
169  guard_type G(_data->mutex);
+
170  return _data->store.size();
+
171  }
+
172 
+
176  void insert(value_pointer&);
+
177 
+
180  size_t erase(value_pointer& v) {
+
181  guard_type G(_data->mutex);
+
182  return _data->store.erase(v);
+
183  }
+
184 
+
187  set_type lock_set() const;
+
188 
+
192  vector_type lock_vector() const;
+
193 
+
194  void lock_vector(vector_type&) const;
+
195 
+
199  inline epicsMutex& mutex() const {
+
200  return _data->mutex;
+
201  }
+
202 
+
204  struct XIterator {
+
205  weak_set& set;
+
206  epicsGuard<epicsMutex> guard;
+
207  typename store_t::iterator it, end;
+
208  XIterator(weak_set& S) :set(S), guard(S.mutex()), it(S._data->store.begin()), end(S._data->store.end()) {}
+
210  value_pointer next() {
+
211  value_pointer ret;
+
212  while(it!=end) {
+
213  ret = (it++)->lock();
+
214  if(ret) break;
+
215  }
+
216  return ret;
+
217  }
+
218  private:
+
219  XIterator(const XIterator&);
+
220  XIterator& operator=(const XIterator&);
+
221  };
+
222 
+
223  typedef XIterator iterator;
+
224 };
+
225 
+
226 template<typename T>
+
227 void weak_set<T>::insert(value_pointer &v)
+
228 {
+
229  if(!v.unique())
+
230  throw std::invalid_argument("Only unique() references may be inserted");
+
231 
+
232  guard_type G(_data->mutex);
+
233  typename store_t::const_iterator it = _data->store.find(v);
+
234  if(it==_data->store.end()) { // new object
+
235 
+
236  // wrapped strong ref. which removes from our map
+
237  value_pointer chainptr(v.get(), dtor(_data, v));
+
238 
+
239  _data->store.insert(chainptr);
+
240 
+
241  v.swap(chainptr); // we only keep the chained pointer
+
242  } else {
+
243  // already stored, no-op
+
244 
+
245  // paranoia, if already inserted then this should be a wrapped ref.
+
246  // but not sure how to check this so update arg. with known wrapped ref.
+
247  v = value_pointer(*it); // could throw bad_weak_ptr, but really never should
+
248  }
+
249 }
+
250 
+
251 template<typename T>
+
252 typename weak_set<T>::set_type
+ +
254 {
+
255  set_type ret;
+
256  guard_type G(_data->mutex);
+
257  for(typename store_t::const_iterator it=_data->store.begin(),
+
258  end=_data->store.end(); it!=end; ++it)
+
259  {
+
260  value_pointer P(it->lock());
+
261  if(P) ret.insert(P);
+
262  }
+
263  return ret;
+
264 }
+
265 
+
266 template<typename T>
+
267 typename weak_set<T>::vector_type
+ +
269 {
+
270  vector_type ret;
+
271  lock_vector(ret);
+
272  return ret;
+
273 }
+
274 
+
275 template<typename T>
+
276 void weak_set<T>::lock_vector(vector_type& ret) const
+
277 {
+
278  guard_type G(_data->mutex);
+
279  ret.reserve(_data->store.size());
+
280  for(typename store_t::const_iterator it=_data->store.begin(),
+
281  end=_data->store.end(); it!=end; ++it)
+
282  {
+
283  value_pointer P(it->lock());
+
284  if(P) ret.push_back(P);
+
285  }
+
286 }
+
287 
+
288 #endif // WEAKSET_H
+
set_type lock_set() const
Definition: weakset.h:253
+
size_t erase(value_pointer &v)
Definition: weakset.h:180
+
bool empty() const
Definition: weakset.h:159
+
epicsMutex & mutex() const
Definition: weakset.h:199
+
value_pointer next()
yield the next live entry
Definition: weakset.h:210
+
weak_set()
Construct a new empty set.
Definition: weakset.h:134
+
void swap(weak_set &O)
Definition: weakset.h:145
+
a std::set-ish container where entries are removed when ref. counts fall to zero
Definition: weakset.h:57
+
vector_type lock_vector() const
Definition: weakset.h:268
+
void clear()
Definition: weakset.h:151
+
size_t size() const
Definition: weakset.h:168
+
an iterator-ish object which also locks the set during iteration
Definition: weakset.h:204
+
void insert(value_pointer &)
Definition: weakset.h:227
+
+ + + +