This is Unofficial EPICS BASE Doxygen Site
monitor.h
Go to the documentation of this file.
1 /* monitor.h */
2 /*
3  * Copyright information and license terms for this software can be
4  * found in the file LICENSE that is included with the distribution
5  */
9 #ifndef MONITOR_H
10 #define MONITOR_H
11 
12 #include <list>
13 #include <ostream>
14 
15 #ifdef epicsExportSharedSymbols
16 # define monitorEpicsExportSharedSymbols
17 # undef epicsExportSharedSymbols
18 #endif
19 
20 #include <epicsMutex.h>
21 #include <pv/status.h>
22 #include <pv/pvData.h>
23 #include <pv/sharedPtr.h>
24 #include <pv/bitSet.h>
25 #include <pv/createRequest.h>
26 
27 #ifdef monitorEpicsExportSharedSymbols
28 # define epicsExportSharedSymbols
29 # undef monitorEpicsExportSharedSymbols
30 #endif
31 
32 #include <pv/requester.h>
33 #include <pv/destroyable.h>
34 
35 #include <shareLib.h>
36 
37 namespace epics { namespace pvAccess {
38 
39 class MonitorRequester;
41 typedef std::tr1::shared_ptr<MonitorElement> MonitorElementPtr;
42 typedef std::vector<MonitorElementPtr> MonitorElementPtrArray;
43 
44 class Monitor;
45 typedef std::tr1::shared_ptr<Monitor> MonitorPtr;
46 
47 
55 public:
57  MonitorElement(epics::pvData::PVStructurePtr const & pvStructurePtr);
59  const epics::pvData::BitSet::shared_pointer changedBitSet;
60  const epics::pvData::BitSet::shared_pointer overrunBitSet;
61 
62  class Ref;
63 };
64 
69 class epicsShareClass Monitor : public virtual Destroyable{
70  public:
73 
74  virtual ~Monitor(){}
79  virtual epics::pvData::Status start() = 0;
84  virtual epics::pvData::Status stop() = 0;
92  virtual MonitorElementPtr poll() = 0;
98  virtual void release(MonitorElementPtr const & monitorElement) = 0;
99 
100  struct Stats {
101  size_t nfilled;
102  size_t noutstanding;
103  size_t nempty;
104  };
105 
106  virtual void getStats(Stats& s) const {
107  s.nfilled = s.noutstanding = s.nempty = 0;
108  }
109 
114  virtual void reportRemoteQueueStatus(epics::pvData::int32 freeElements) {}
115 };
116 
147 {
148  Monitor* mon;
149  MonitorElementPtr elem;
150 public:
151  Ref() :mon(0), elem() {}
152  Ref(Monitor& M) :mon(&M), elem(mon->poll()) {}
153  Ref(const Monitor::shared_pointer& M) :mon(M.get()), elem(mon->poll()) {}
154  ~Ref() { reset(); }
155 #if __cplusplus>=201103L
156  Ref(Ref&& o) :mon(o.mon), elem(o.elem) {
157  o.mon = 0;
158  o.elem.reset();
159  }
160 #endif
161  void swap(Ref& o) {
162  std::swap(mon , o.mon);
163  std::swap(elem, o.elem);
164  }
167  MonitorElementPtr letGo() {
168  MonitorElementPtr ret;
169  elem.swap(ret);
170  return ret;
171  }
172  void attach(Monitor& M) {
173  reset();
174  mon = &M;
175  }
176  void attach(const Monitor::shared_pointer& M) {
177  reset();
178  mon = M.get();
179  }
180  bool next() {
181  if(elem) mon->release(elem);
182  elem = mon->poll();
183  return !!elem;
184  }
185  void reset() {
186  if(elem && mon) mon->release(elem);
187  elem.reset();
188  }
189  Ref& operator++() {// prefix increment. aka "++(*this)"
190  next();
191  return *this;
192  }
193 #if __cplusplus>=201103L
194  inline explicit operator bool() const { return elem.get(); }
195 #else
196 private:
197  typedef const Monitor* const * hidden_bool_type;
198 public:
199  operator hidden_bool_type() const { return elem.get() ? &mon : 0; }
200 #endif
201  inline MonitorElement* operator->() { return elem.get(); }
202  inline MonitorElement& operator*() { return *elem; }
203  inline MonitorElement* get() { return elem.get(); }
204 
205  inline bool operator==(const Ref& o) const { return elem==o.elem; }
206  inline bool operator!=(const Ref& o) const { return !(*this==o); }
207 
209 };
210 
211 #if __cplusplus>=201103L
212 // used by c++11 for-range
213 inline MonitorElement::Ref begin(Monitor& mon) { return MonitorElement::Ref(mon); }
214 inline MonitorElement::Ref end(Monitor& mon) { return MonitorElement::Ref(); }
215 #endif // __cplusplus<201103L
216 
259  public std::tr1::enable_shared_from_this<MonitorFIFO>
260 {
261 public:
268  virtual ~Source();
272  virtual void freeHighMark(MonitorFIFO *mon, size_t numEmpty) {}
273  };
275  size_t maxCount,
276  defCount,
277  actualCount;
280  Config();
281  };
282 
289  MonitorFIFO(const std::tr1::shared_ptr<MonitorRequester> &requester,
290  const pvData::PVStructure::const_shared_pointer &pvRequest,
291  const Source::shared_pointer& source = Source::shared_pointer(),
292  Config *conf=0);
293  virtual ~MonitorFIFO();
294 
297  inline const std::tr1::shared_ptr<MonitorRequester> getRequester() const { return requester.lock(); }
298 
299  void show(std::ostream& strm) const;
300 
301  virtual void destroy() OVERRIDE FINAL;
302 
303  // configuration
304 
308  void setFreeHighMark(double level);
309 
310  // up-stream interface (putting data into FIFO)
312  void open(const epics::pvData::StructureConstPtr& type);
314  void close();
316  void finish();
321  bool tryPost(const pvData::PVStructure& value,
322  const epics::pvData::BitSet& changed,
323  const epics::pvData::BitSet& overrun = epics::pvData::BitSet(),
324  bool force =false);
326  void post(const pvData::PVStructure& value,
327  const epics::pvData::BitSet& changed,
328  const epics::pvData::BitSet& overrun = epics::pvData::BitSet());
333  void notify();
334 
335  // down-stream interface (taking data from FIFO)
336  virtual epics::pvData::Status start() OVERRIDE FINAL;
337  virtual epics::pvData::Status stop() OVERRIDE FINAL;
338  virtual MonitorElementPtr poll() OVERRIDE FINAL;
339  virtual void release(MonitorElementPtr const & monitorElement) OVERRIDE FINAL; // may call Source::freeHighMark()
340  virtual void getStats(Stats& s) const OVERRIDE FINAL;
341  virtual void reportRemoteQueueStatus(epics::pvData::int32 freeElements) OVERRIDE FINAL;
342 
344  size_t freeCount() const;
345 private:
346  size_t _freeCount() const;
347 
348  friend void providerRegInit(void*);
349  static size_t num_instances;
350 
351  // const after ctor
352  Config conf;
353 
354  // locking here is complicated...
355  // our entry points which make callbacks are:
356  // notify() -> MonitorRequester::monitorConnect()
357  // -> MonitorRequester::monitorEvent()
358  // -> MonitorRequester::unlisten()
359  // -> ChannelBaseRequester::channelDisconnect()
360  // start() -> MonitorRequester::monitorEvent()
361  // release() -> Source::freeHighMark()
362  // -> notify() -> ...
363  // reportRemoteQueueStatus() -> Source::freeHighMark()
364  // -> notify() -> ...
365  mutable epicsMutex mutex;
366 
367  // ownership is archored at the downstream (consumer) end.
368  // strong refs are:
369  // downstream -> MonitorFIFO -> Source
370  // weak refs are:
371  // MonitorRequester <- MonitorFIFO <- upstream
372 
373  // so we expect that downstream will hold a strong ref to us,
374  // and we keep a weak ref to downstream's MonitorRequester
375  const std::tr1::weak_ptr<MonitorRequester> requester;
376 
377  const epics::pvData::PVStructure::const_shared_pointer pvRequest;
378 
379  // then we expect to keep a strong ref to upstream (Source)
380  // and expect that upstream will have only a weak ref to us.
381  const Source::shared_pointer upstream;
382 
383  enum state_t {
384  Closed, // not open()'d
385  Opened, // successful open()
386  Error, // unsuccessful open()
387  } state;
388  bool pipeline; // const after ctor
389  bool running; // start() vs. stop()
390  bool finished; // finish() called
391  epics::pvData::BitSet scratch, oscratch; // using during post to avoid re-alloc
392 
393  bool needConnected;
394  bool needEvent;
395  bool needUnlisten;
396  bool needClosed;
397 
398  epics::pvData::Status error; // Set when entering Error state
399 
400  size_t freeHighLevel;
401  epicsInt32 flowCount;
402 
404 
405  typedef std::list<MonitorElementPtr> buffer_t;
406  // we allocate one extra buffer element to hold data when post()
407  // while all elements poll()'d. So there will always be one
408  // element on either the empty or inuse lists
409  buffer_t inuse, empty, returned;
410  /* our elements are in one of 4 states
411  * Empty - on empty list
412  * In Use - on inuse list
413  * Polled - Returnedd from poll(). Not tracked
414  * Returned - only if pipeline==true, release()'d but not ack'd
415  */
416 
418 };
419 
420 static inline
421 std::ostream& operator<<(std::ostream& strm, const MonitorFIFO& fifo) {
422  fifo.show(strm);
423  return strm;
424 }
425 
426 }}
427 
428 namespace epics { namespace pvData {
429 
435 }}
436 
437 #endif /* MONITOR_H */
epics::pvData::BitSetPtr empty
Definition: pvAccess.cpp:135
Definition: link.h:174
virtual void reportRemoteQueueStatus(epics::pvData::int32 freeElements)
Definition: monitor.h:114
pvd::StructureConstPtr type
Ref(const Monitor::shared_pointer &M)
Definition: monitor.h:153
TODO only here because of the Lockable.
Definition: ntaggregate.cpp:16
std::tr1::shared_ptr< const Structure > StructureConstPtr
Definition: pvIntrospect.h:162
void providerRegInit(void *)
A vector of bits.
Definition: bitSet.h:56
An element for a monitorQueue.
Definition: monitor.h:54
Mark external symbols and entry points for shared libraries.
epics::pvData::PVRequestMapper::mode_t mapperMode
default Mask.
Definition: monitor.h:279
epicsTime begin
Definition: caConnTest.cpp:22
#define OVERRIDE
Definition: pvAccess.h:55
const epics::pvData::PVStructurePtr pvStructurePtr
Definition: monitor.h:58
size_t nfilled
of elements ready to be poll()d
Definition: monitor.h:101
MonitorElement * operator->()
Definition: monitor.h:201
std::vector< MonitorElementPtr > MonitorElementPtrArray
Definition: monitor.h:42
#define POINTER_DEFINITIONS(clazz)
Definition: sharedPtr.h:198
virtual void release(MonitorElementPtr const &monitorElement)=0
epicsMutex mutex
Definition: pvAccess.cpp:71
APIs for the epicsMutex mutual exclusion semaphore.
size_t maxCount
upper limit on requested FIFO size
Definition: monitor.h:275
const ChannelProcessRequester::weak_pointer requester
Definition: pvAccess.cpp:68
#define epicsShareClass
Definition: shareLib.h:206
const epics::pvData::BitSet::shared_pointer overrunBitSet
Definition: monitor.h:60
Data interface for a structure,.
Definition: pvData.h:712
std::tr1::shared_ptr< PVStructure > PVStructurePtr
Definition: pvData.h:87
MonitorRequester requester_type
Definition: monitor.h:72
const epics::pvData::BitSet::shared_pointer changedBitSet
Definition: monitor.h:59
Callback implemented by monitor clients.
Definition: pvAccess.h:249
size_t nempty
of elements available for new remote data
Definition: monitor.h:103
Definition: caget.c:48
void swap(shared_ptr< T > &a, shared_ptr< T > &b) BOOST_NOEXCEPT
Definition: shared_ptr.hpp:783
size_t noutstanding
of elements poll()d but not released()d
Definition: monitor.h:102
std::tr1::shared_ptr< MonitorElement > MonitorElementPtr
Definition: monitor.h:40
const std::tr1::shared_ptr< MonitorRequester > getRequester() const
Definition: monitor.h:297
Instance declaring destroy method.
Definition: destroyable.h:24
bool operator!=(const Ref &o) const
Definition: monitor.h:206
MonitorElement & operator*()
Definition: monitor.h:202
void attach(const Monitor::shared_pointer &M)
Definition: monitor.h:176
bool operator==(const Ref &o) const
Definition: monitor.h:205
virtual void getStats(Stats &s) const
Definition: monitor.h:106
void show(std::ostream &strm) const
Definition: monitor.cpp:104
#define EPICS_NOT_COPYABLE(CLASS)
Disable implicit copyable.
virtual MonitorElementPtr poll()=0
bool dropEmptyUpdates
default true. Drop updates which don&#39;t include an field values.
Definition: monitor.h:278
int32_t int32
Definition: pvType.h:83
std::tr1::shared_ptr< Monitor > MonitorPtr
Definition: monitor.h:44
int epicsInt32
Definition: epicsTypes.h:42
#define FINAL
Definition: pvAccess.h:48
virtual void freeHighMark(MonitorFIFO *mon, size_t numEmpty)
Definition: monitor.h:272