This is Unofficial EPICS BASE Doxygen Site
pvalink.h
Go to the documentation of this file.
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 
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 
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,
111 
113 
115 
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 
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 
143  epicsEvent run_done; // used by testing code
144 
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 
158  struct LinkSort {
159  bool operator()(const pvaLink *L, const pvaLink *R) const;
160  };
161 
162  typedef std::set<pvaLink*, LinkSort> links_t;
163 
164  // list of currently attached links. maintained by pvaLink ctor/dtor
165  // TODO: sort by PHAS
166  links_t links;
167 
168  // set when 'links' is modified to trigger re-compute of record scan list
170 
171  pvaLinkChannel(const pvaGlobal_t::channels_key_t& key, const epics::pvData::PVStructure::const_shared_pointer &pvRequest);
172  virtual ~pvaLinkChannel();
173 
174  void open();
175  void put(bool force=false); // begin Put op.
176 
177  // pvac::ClientChanel::MonitorCallback
178  virtual void monitorEvent(const pvac::MonitorEvent& evt) OVERRIDE FINAL;
179 
180  // pvac::ClientChanel::PutCallback
182  virtual void putDone(const pvac::PutEvent& evt) OVERRIDE FINAL;
183 private:
184  virtual void run() OVERRIDE FINAL;
185  void run_dbProcess(size_t idx); // idx is index in scan_records
186 
187  // ==== Treat remaining as local to run()
188 
189  std::vector<dbCommon*> scan_records;
190  std::vector<bool> scan_check_passive;
191  std::vector<epics::pvData::BitSet> scan_changed;
192 
193  DBManyLock atomic_lock;
194 };
195 
196 struct pvaLink : public pvaLinkConfig
197 {
198  static size_t num_instances;
199 
200  bool alive; // attempt to catch some use after free
201 
202  DBLINK * plink; // may be NULL
203 
204  std::tr1::shared_ptr<pvaLinkChannel> lchan;
205 
206  bool used_scratch, used_queue;
208 
209  // cached fields from channel op_mon
210  // updated in onTypeChange()
211  epics::pvData::PVField::const_shared_pointer fld_value;
212  epics::pvData::PVScalar::const_shared_pointer fld_severity,
213  fld_seconds,
214  fld_nanoseconds;
215  epics::pvData::PVStructure::const_shared_pointer fld_display,
216  fld_control,
219 
220  // cached snapshot of alarm and timestamp
221  // captured in pvaGetValue().
222  // we choose not to ensure consistency with display/control meta-data
225 
226  pvaLink();
227  virtual ~pvaLink();
228 
229  // returns pvRequest to be used with monitor
230  pvd::PVStructurePtr makeRequest();
231 
232  bool valid() const;
233 
234  // fetch a sub-sub-field of the top monitored field.
235  pvd::PVField::const_shared_pointer getSubField(const char *name);
236 
237  void onDisconnect();
238  void onTypeChange();
239 };
240 
241 
242 } // namespace pvalink
243 
244 #endif // PVALINK_H
std::tr1::shared_ptr< detail::SharedPut > put
callbacks for put()
Definition: client.h:358
Definition: memory.hpp:41
TODO only here because of the Lockable.
Definition: ntaggregate.cpp:16
std::tr1::shared_ptr< const Structure > StructureConstPtr
Definition: pvIntrospect.h:162
A vector of bits.
Definition: bitSet.h:56
Handle for monitor subscription.
Definition: client.h:117
#define OVERRIDE
Definition: pvAccess.h:55
Handle for in-progress get/put/rpc operation.
Definition: client.h:50
std::tr1::shared_ptr< PVDataCreate > PVDataCreatePtr
Definition: pvData.h:124
Holds all PVA related.
Definition: pvif.h:34
Information on put completion.
Definition: client.h:88
pvData
Definition: monitor.h:428
APIs for the epicsMutex mutual exclusion semaphore.
#define QSRV_API
Definition: qsrv.h:36
Extended replacement for the Posix exit and atexit routines.
Central client context.
Definition: client.h:517
APIs for the epicsEvent binary semaphore.
std::tr1::shared_ptr< PVStructure > PVStructurePtr
Definition: pvData.h:87
Information on monitor subscription/queue change.
Definition: client.h:184
EPICS time stamp, for use from C code.
Definition: epicsTime.h:33
epicsMutex Mutex
Definition: lock.h:28
Monitor event notification.
Definition: client.h:403
C++ and C descriptions for a thread.
#define FINAL
Definition: pvAccess.h:48