This is Unofficial EPICS BASE Doxygen Site
epics::pvAccess::MonitorFIFO Class Reference

#include "monitor.h"

+ Inheritance diagram for epics::pvAccess::MonitorFIFO:
+ Collaboration diagram for epics::pvAccess::MonitorFIFO:

Classes

struct  Config
 
struct  Source
 

Public Member Functions

 POINTER_DEFINITIONS (MonitorFIFO)
 
 MonitorFIFO (const std::tr1::shared_ptr< MonitorRequester > &requester, const pvData::PVStructure::const_shared_pointer &pvRequest, const Source::shared_pointer &source=Source::shared_pointer(), Config *conf=0)
 
virtual ~MonitorFIFO ()
 
const std::tr1::shared_ptr< MonitorRequestergetRequester () const
 
void show (std::ostream &strm) const
 
virtual void destroy () OVERRIDE FINAL
 
void setFreeHighMark (double level)
 
void open (const epics::pvData::StructureConstPtr &type)
 Mark subscription as "open" with the associated structure type. More...
 
void close ()
 Abnormal closure (eg. due to upstream dis-connection) More...
 
void finish ()
 Successful closure (eg. RDB query done) More...
 
bool tryPost (const pvData::PVStructure &value, const epics::pvData::BitSet &changed, const epics::pvData::BitSet &overrun=epics::pvData::BitSet(), bool force=false)
 
void post (const pvData::PVStructure &value, const epics::pvData::BitSet &changed, const epics::pvData::BitSet &overrun=epics::pvData::BitSet())
 Consume a free slot if available, otherwise squash with most recent. More...
 
void notify ()
 
virtual epics::pvData::Status start () OVERRIDE FINAL
 
virtual epics::pvData::Status stop () OVERRIDE FINAL
 
virtual MonitorElementPtr poll () OVERRIDE FINAL
 
virtual void release (MonitorElementPtr const &monitorElement) OVERRIDE FINAL
 
virtual void getStats (Stats &s) const OVERRIDE FINAL
 
virtual void reportRemoteQueueStatus (epics::pvData::int32 freeElements) OVERRIDE FINAL
 
size_t freeCount () const
 Number of unused FIFO slots at this moment, which may changed in the next. More...
 
- Public Member Functions inherited from epics::pvAccess::Monitor
 POINTER_DEFINITIONS (Monitor)
 
virtual ~Monitor ()
 
- Public Member Functions inherited from epics::pvAccess::Destroyable
 POINTER_DEFINITIONS (Destroyable)
 

Friends

void providerRegInit (void *)
 

Additional Inherited Members

- Public Types inherited from epics::pvAccess::Monitor
typedef MonitorRequester requester_type
 
- Protected Member Functions inherited from epics::pvAccess::Destroyable
virtual ~Destroyable ()
 

Detailed Description

Utility implementation of Monitor.

The Monitor interface defines the downstream (consumer facing) side of a FIFO. This class is a concrete implementation of this FIFO, including the upstream (producer facing) side.

In addition to MonitorRequester, which provides callbacks to the downstream side, The MonitorFIFO::Source class provides callbacks to the upstream side.

The simplest usage is to create (as shown below), then put update into the FIFO using post() and tryPost(). These methods behave the same when the queue is not full, but differ when it is. Additionally, tryPost() has an argument 'force'. Together there are three actions

post(value, changed) - combines the new update with the last (most recent) in the FIFO.

tryPost(value, changed, ..., false) - Makes no change to the FIFO and returns false.

tryPost(value, changed, ..., true) - Over-fills the FIFO with the new element, then returns false.

Note
Calls to post() or tryPost() must be followed with a call to notify(). Callers of notify() must not hold any locks, or a deadlock is possible.

The intent of tryPost() with force=true is to aid code which is transferring values from some upstream buffer and this FIFO. Such code can be complicated if an item is removed from the upstream buffer, but can't be put into this downstream FIFO. Rather than being forced to effectivly maintain a third FIFO, code can use force=true.

In either case, tryPost()==false indicates the the FIFO is full.

eg. simple usage in a sub-class for Channel named MyChannel.

pva::Monitor::shared_pointer
MyChannel::createMonitor(const pva::MonitorRequester::shared_pointer &requester,
const pvd::PVStructure::shared_pointer &pvRequest)
{
std::tr1::shared_ptr<pva::MonitorFIFO> ret(new pva::MonitorFIFO(requester, pvRequest));
ret->open(spamtype);
ret->notify();
// ret->post(...); // maybe initial update
}

Definition at line 258 of file monitor.h.

Constructor & Destructor Documentation

epics::pvAccess::MonitorFIFO::MonitorFIFO ( const std::tr1::shared_ptr< MonitorRequester > &  requester,
const pvData::PVStructure::const_shared_pointer &  pvRequest,
const Source::shared_pointer &  source = Source::shared_pointer(),
Config conf = 0 
)
Parameters
requesterDownstream/consumer callbacks
pvRequestDownstream provided options
sourceUpstream/producer callbacks
confUpstream provided options. Updated with actual values used. May be NULL to use defaults.

Definition at line 37 of file monitor.cpp.

40  :conf(inconf ? *inconf : Config())
42  ,pvRequest(pvRequest)
43  ,upstream(source)
44  ,state(Closed)
45  ,pipeline(false)
46  ,running(false)
47  ,finished(false)
48  ,needConnected(false)
49  ,needEvent(false)
50  ,needUnlisten(false)
51  ,needClosed(false)
52  ,freeHighLevel(0u)
53  ,flowCount(0)
54 {
55  REFTRACE_INCREMENT(num_instances);
56 
57  if(conf.maxCount==0)
58  conf.maxCount = 1;
59 
60  if(conf.defCount==0)
61  conf.defCount = 1;
62 
63  pvd::PVScalar::const_shared_pointer O(pvRequest->getSubField<pvd::PVScalar>("record._options.queueSize"));
64  if(O && conf.actualCount==0) {
65  try {
66  conf.actualCount = O->getAs<pvd::uint32>();
67  } catch(std::exception& e) {
68  std::ostringstream strm;
69  strm<<"invalid queueSize : "<<e.what();
70  requester->message(strm.str());
71  }
72  }
73 
74  if(conf.actualCount==0)
75  conf.actualCount = conf.defCount;
76 
77  if(conf.actualCount > conf.maxCount)
78  conf.actualCount = conf.maxCount;
79 
80  O = pvRequest->getSubField<pvd::PVScalar>("record._options.pipeline");
81  if(O) {
82  try {
83  pipeline = O->getAs<pvd::boolean>();
84  } catch(std::exception& e) {
85  std::ostringstream strm;
86  strm<<"invalid pipeline : "<<e.what();
87  requester->message(strm.str());
88  }
89  }
90 
91  setFreeHighMark(0.00);
92 
93  if(inconf)
94  *inconf = conf;
95 }
PVScalar is the base class for each scalar field.
Definition: pvData.h:272
void setFreeHighMark(double level)
Definition: monitor.cpp:127
size_t actualCount
filled in with actual FIFO size
Definition: monitor.h:275
size_t maxCount
upper limit on requested FIFO size
Definition: monitor.h:275
const ChannelProcessRequester::weak_pointer requester
Definition: pvAccess.cpp:68
size_t defCount
FIFO size when client makes no request.
Definition: monitor.h:275
detail::pick_type< int8_t, signed char, detail::pick_type< uint8_t, char, unsigned char >::type >::type boolean
Definition: pvType.h:71
uint32_t uint32
Definition: pvType.h:99
epics::pvAccess::MonitorFIFO::~MonitorFIFO ( )
virtual

Definition at line 97 of file monitor.cpp.

97  {
98  REFTRACE_DECREMENT(num_instances);
99 }

Member Function Documentation

void epics::pvAccess::MonitorFIFO::close ( )

Abnormal closure (eg. due to upstream dis-connection)

Definition at line 190 of file monitor.cpp.

191 {
192  Guard G(mutex);
193  needClosed = state==Opened;
194  state = Closed;
195 }
void epics::pvAccess::MonitorFIFO::destroy ( )
virtual

Destroy this instance.

Implements epics::pvAccess::Destroyable.

Definition at line 101 of file monitor.cpp.

102 {}
void epics::pvAccess::MonitorFIFO::finish ( )

Successful closure (eg. RDB query done)

Definition at line 197 of file monitor.cpp.

198 {
199  Guard G(mutex);
200  if(state==Closed)
201  throw std::logic_error("Can not finish() a closed Monitor");
202  else if(finished)
203  return; // no-op
204 
205  finished = true;
206  if(inuse.empty() && running && state==Opened)
207  needUnlisten = true;
208 }
size_t epics::pvAccess::MonitorFIFO::freeCount ( ) const

Number of unused FIFO slots at this moment, which may changed in the next.

Definition at line 501 of file monitor.cpp.

502 {
503  Guard G(mutex);
504  return _freeCount();
505 }
const std::tr1::shared_ptr<MonitorRequester> epics::pvAccess::MonitorFIFO::getRequester ( ) const
inline

Access to MonitorRequester passed to ctor, or NULL if it has already been destroyed.

Since
>6.1.0

Definition at line 297 of file monitor.h.

297 { return requester.lock(); }
const ChannelProcessRequester::weak_pointer requester
Definition: pvAccess.cpp:68
void epics::pvAccess::MonitorFIFO::getStats ( Stats s) const
virtual

Reimplemented from epics::pvAccess::Monitor.

Definition at line 461 of file monitor.cpp.

462 {
463  Guard G(mutex);
464  s.nempty = empty.size() + returned.size();
465  s.nfilled = inuse.size();
466  s.noutstanding = conf.actualCount - s.nempty - s.nfilled;
467 }
epics::pvData::BitSetPtr empty
Definition: pvAccess.cpp:135
size_t actualCount
filled in with actual FIFO size
Definition: monitor.h:275
void epics::pvAccess::MonitorFIFO::notify ( )

Call after calling any other upstream interface methods (open()/close()/finish()/post()/...) when no upstream mutexes are locked. Do not call from Source::freeHighMark(). This is done automatically. Call any MonitorRequester methods.

Definition at line 318 of file monitor.cpp.

319 {
320  Monitor::shared_pointer self;
321  MonitorRequester::shared_pointer req;
323  bool conn = false,
324  evt = false,
325  unl = false,
326  clo = false;
327  pvd::Status err;
328 
329  {
330  Guard G(mutex);
331 
332  std::swap(conn, needConnected);
333  std::swap(evt, needEvent);
334  std::swap(unl, needUnlisten);
335  std::swap(clo, needClosed);
336  std::swap(err, error);
337 
338  if(conn | evt | unl | clo) {
339  req = requester.lock();
340  self = shared_from_this();
341  }
342  if(conn && err.isSuccess())
343  type = mapper.requested();
344  }
345 
346  if(!req)
347  return;
348  if(conn && err.isSuccess())
349  req->monitorConnect(pvd::Status(), self, type);
350  else if(conn)
351  req->monitorConnect(err, self, type);
352  if(evt)
353  req->monitorEvent(self);
354  if(unl)
355  req->unlisten(self);
356  if(clo)
357  req->channelDisconnect(false);
358 }
pvd::StructureConstPtr type
std::tr1::shared_ptr< const Structure > StructureConstPtr
Definition: pvIntrospect.h:162
const ChannelProcessRequester::weak_pointer requester
Definition: pvAccess.cpp:68
bool isSuccess() const
Definition: status.h:103
void swap(shared_ptr< T > &a, shared_ptr< T > &b) BOOST_NOEXCEPT
Definition: shared_ptr.hpp:783
const StructureConstPtr & requested() const
void epics::pvAccess::MonitorFIFO::open ( const epics::pvData::StructureConstPtr type)

Mark subscription as "open" with the associated structure type.

Definition at line 137 of file monitor.cpp.

138 {
139  std::string message;
140  {
141  Guard G(mutex);
142 
143  if(state!=Closed)
144  throw std::logic_error("Monitor already open. Must close() before re-openning");
145  else if(needClosed)
146  throw std::logic_error("Monitor needs notify() between close() and open().");
147  else if(finished)
148  throw std::logic_error("Monitor finished. re-open() not possible");
149 
150  // keep the code simpler.
151  // never try to re-use elements, even on re-open w/o type change.
152  empty.clear();
153  inuse.clear();
154  returned.clear();
155 
156  // fill up empty.
158 
159  try {
160  mapper.compute(*create->createPVStructure(type), *pvRequest, conf.mapperMode);
161  message = mapper.warnings();
162 
163  while(empty.size() < conf.actualCount+1) {
164  MonitorElementPtr elem(new MonitorElement(mapper.buildRequested()));
165  empty.push_back(elem);
166  }
167 
168  state = Opened;
169  error = pvd::Status(); // ok
170 
171  assert(inuse.empty());
172  assert(empty.size()>=2);
173  assert(returned.empty());
174  assert(conf.actualCount>=1);
175 
176  }catch(std::runtime_error& e){
177  // error from compute()
178  error = pvd::Status::error(e.what());
179  state = Error;
180  }
181  needConnected = true;
182  }
183  if(message.empty()) return;
184  requester_type::shared_pointer req(requester.lock());
185  if(req) {
186  req->message(message, warningMessage);
187  }
188 }
epics::pvData::BitSetPtr empty
Definition: pvAccess.cpp:135
#define assert(exp)
Declare that a condition should be true.
Definition: epicsAssert.h:70
const std::string & warnings() const
After compute(), check if !warnings().empty()
static Status error(const std::string &m)
Definition: status.h:50
void compute(const PVStructure &base, const PVStructure &pvRequest, mode_t mode=Mask)
PVStructurePtr buildRequested() const
pvd::StructureConstPtr type
epics::pvData::PVRequestMapper::mode_t mapperMode
default Mask.
Definition: monitor.h:279
size_t actualCount
filled in with actual FIFO size
Definition: monitor.h:275
std::tr1::shared_ptr< PVDataCreate > PVDataCreatePtr
Definition: pvData.h:124
const ChannelProcessRequester::weak_pointer requester
Definition: pvAccess.cpp:68
std::tr1::shared_ptr< MonitorElement > MonitorElementPtr
Definition: monitor.h:40
FORCE_INLINE const PVDataCreatePtr & getPVDataCreate()
Definition: pvData.h:1648
epics::pvAccess::MonitorFIFO::POINTER_DEFINITIONS ( MonitorFIFO  )
MonitorElementPtr epics::pvAccess::MonitorFIFO::poll ( )
virtual

If monitor has occurred return data.

Returns
monitorElement for modified data. Must call get to determine if data is available.

May recursively call MonitorRequester::unlisten()

Implements epics::pvAccess::Monitor.

Definition at line 397 of file monitor.cpp.

398 {
399  MonitorElementPtr ret;
400  Monitor::shared_pointer self;
401  MonitorRequester::shared_pointer req;
402 
403  {
404  Guard G(mutex);
405 
406  if(!inuse.empty() && inuse.size() + empty.size() > 1) {
407  ret = inuse.front();
408  inuse.pop_front();
409  if(inuse.empty() && finished) {
410  self = shared_from_this();
411  req = requester.lock();
412  }
413  }
414 
415  assert(!inuse.empty() || !empty.empty());
416  }
417 
418  if(req) {
419  req->unlisten(self);
420  }
421 
422  return ret;
423 }
epics::pvData::BitSetPtr empty
Definition: pvAccess.cpp:135
#define assert(exp)
Declare that a condition should be true.
Definition: epicsAssert.h:70
const ChannelProcessRequester::weak_pointer requester
Definition: pvAccess.cpp:68
std::tr1::shared_ptr< MonitorElement > MonitorElementPtr
Definition: monitor.h:40
void epics::pvAccess::MonitorFIFO::post ( const pvData::PVStructure value,
const epics::pvData::BitSet changed,
const epics::pvData::BitSet overrun = epics::pvData::BitSet() 
)

Consume a free slot if available, otherwise squash with most recent.

Definition at line 259 of file monitor.cpp.

262 {
263  Guard G(mutex);
264 
265  if(state!=Opened || finished) return;
266  assert(!empty.empty() || !inuse.empty());
267 
268  const bool use_empty = !empty.empty();
269 
270  MonitorElementPtr elem;
271 
272  if(use_empty) {
273  // space in window, or entering overflow, fill an empty element
274 
275  assert(!empty.empty());
276 
277  elem = empty.front();
278 
279  } else {
280  // window full and already in overflow
281  // squash with last element
282  assert(!inuse.empty());
283  elem = inuse.back();
284  }
285 
286  if(conf.dropEmptyUpdates && !changed.logical_and(mapper.requestedMask()))
287  return; // drop empty update
288 
289  scratch.clear();
290  mapper.copyBaseToRequested(value, changed, *elem->pvStructurePtr, scratch);
291 
292  if(use_empty) {
293  *elem->changedBitSet = scratch;
294  elem->overrunBitSet->clear();
295  mapper.maskBaseToRequested(overrun, *elem->overrunBitSet);
296 
297  if(inuse.empty() && running)
298  needEvent = true;
299 
300  inuse.push_back(elem);
301  empty.pop_front();
302  if(pipeline)
303  flowCount--;
304 
305  } else {
306  // in overflow
307  // squash
308  elem->overrunBitSet->or_and(*elem->changedBitSet, scratch);
309  *elem->changedBitSet |= scratch;
310  oscratch.clear();
311  mapper.maskBaseToRequested(overrun, oscratch);
312  elem->overrunBitSet->or_and(oscratch, scratch);
313 
314  // leave as inuse.back()
315  }
316 }
epics::pvData::BitSetPtr empty
Definition: pvAccess.cpp:135
void copyBaseToRequested(const PVStructure &base, const BitSet &baseMask, PVStructure &request, BitSet &requestMask) const
Definition: link.h:174
#define assert(exp)
Declare that a condition should be true.
Definition: epicsAssert.h:70
BitSet & clear(uint32 bitIndex)
Definition: bitSet.cpp:112
const BitSet & requestedMask() const
void maskBaseToRequested(const BitSet &baseMask, BitSet &requestMask) const
bool logical_and(const BitSet &other) const
Returns true if any bit is set in both *this and other.
Definition: bitSet.cpp:214
std::tr1::shared_ptr< MonitorElement > MonitorElementPtr
Definition: monitor.h:40
bool dropEmptyUpdates
default true. Drop updates which don&#39;t include an field values.
Definition: monitor.h:278
void epics::pvAccess::MonitorFIFO::release ( MonitorElementPtr const &  monitorElement)
virtual

Release a MonitorElement that was returned by poll. A poll() must be called after the release() to check the presence of any modified data.

Parameters
monitorElement

Implements epics::pvAccess::Monitor.

Definition at line 425 of file monitor.cpp.

426 {
427  size_t nempty;
428  {
429  Guard G(mutex);
430 
431  assert(!inuse.empty() || !empty.empty());
432 
433  const pvd::StructureConstPtr& type((!inuse.empty() ? inuse.front() : empty.back())->pvStructurePtr->getStructure());
434 
435  if(elem->pvStructurePtr->getStructure() != type // return of old type
436  || empty.size()+returned.size()>=conf.actualCount+1) // return of force'd
437  return; // ignore it
438 
439  if(pipeline) {
440  // work done during reportRemoteQueueStatus()
441  returned.push_back(elem);
442  return;
443  }
444 
445  bool below = _freeCount() <= freeHighLevel;
446 
447  empty.push_front(elem);
448 
449  bool above = _freeCount() > freeHighLevel;
450 
451  if(!below || !above || !upstream)
452  return;
453 
454  nempty = _freeCount();
455  }
456 
457  upstream->freeHighMark(this, nempty);
458  notify();
459 }
epics::pvData::BitSetPtr empty
Definition: pvAccess.cpp:135
#define assert(exp)
Declare that a condition should be true.
Definition: epicsAssert.h:70
pvd::StructureConstPtr type
std::tr1::shared_ptr< const Structure > StructureConstPtr
Definition: pvIntrospect.h:162
size_t actualCount
filled in with actual FIFO size
Definition: monitor.h:275
void epics::pvAccess::MonitorFIFO::reportRemoteQueueStatus ( epics::pvData::int32  freeElements)
virtual

Report remote queue status.

Parameters
freeElementsnumber of free elements.

Reimplemented from epics::pvAccess::Monitor.

Definition at line 469 of file monitor.cpp.

470 {
471  if(nfree<=0 || !pipeline)
472  return; // paranoia
473 
474  size_t nempty;
475  {
476  Guard G(mutex);
477 
478  bool below = _freeCount() <= freeHighLevel;
479 
480  size_t nack = std::min(size_t(nfree), returned.size());
481  flowCount += nfree;
482 
483  buffer_t::iterator end(returned.begin());
484  std::advance(end, nack);
485 
486  // remove[0, nack) from returned and append to empty
487  empty.splice(empty.end(), returned, returned.begin(), end);
488 
489  bool above = _freeCount() > freeHighLevel;
490 
491  if(!below || !above || empty.size()<=1 || !upstream)
492  return;
493 
494  nempty = _freeCount();
495  }
496 
497  upstream->freeHighMark(this, nempty);
498  notify();
499 }
epics::pvData::BitSetPtr empty
Definition: pvAccess.cpp:135
#define min(x, y)
Definition: flexdef.h:78
void epics::pvAccess::MonitorFIFO::setFreeHighMark ( double  level)

Level, as a percentage of empty buffer slots, at which to call Source::freeHighMark(). Trigger condition is when number of free buffer slots goes above this level. In range [0.0, 1.0)

Definition at line 127 of file monitor.cpp.

128 {
129  level = std::max(0.0, std::min(level, 1.0));
130  pvd::uint32 lvl = std::max(size_t(0), std::min(size_t(conf.actualCount * level), conf.actualCount-1));
131 
132  Guard G(mutex);
133 
134  freeHighLevel = lvl;
135 }
#define max(x, y)
Definition: flexdef.h:81
#define min(x, y)
Definition: flexdef.h:78
size_t actualCount
filled in with actual FIFO size
Definition: monitor.h:275
uint32_t uint32
Definition: pvType.h:99
void epics::pvAccess::MonitorFIFO::show ( std::ostream &  strm) const

Definition at line 104 of file monitor.cpp.

105 {
106  // const (after ctor) bits
107  strm<<"MonitorFIFO"
108  " pipeline="<<pipeline
109  <<" size="<<conf.actualCount
110  <<" freeHighLevel="<<freeHighLevel
111  <<"\n";
112 
113  Guard G(mutex);
114 
115  switch(state) {
116  case Closed: strm<<" Closed"; break;
117  case Opened: strm<<" Opened"; break;
118  case Error: strm<<" Error:"<<error; break;
119  }
120 
121  strm<<" running="<<running<<" finished="<<finished<<"\n";
122  strm<<" #empty="<<empty.size()<<" #returned="<<returned.size()<<" #inuse="<<inuse.size()<<" flowCount="<<flowCount<<"\n";
123  strm<<" events "<<(needConnected?'C':'_')<<(needEvent?'E':'_')<<(needUnlisten?'U':'_')<<(needClosed?'X':'_')
124  <<"\n";
125 }
epics::pvData::BitSetPtr empty
Definition: pvAccess.cpp:135
size_t actualCount
filled in with actual FIFO size
Definition: monitor.h:275
pvd::Status epics::pvAccess::MonitorFIFO::start ( )
virtual

Start monitoring.

Returns
completion status.

Implements epics::pvAccess::Monitor.

Definition at line 360 of file monitor.cpp.

361 {
362  Monitor::shared_pointer self;
363  MonitorRequester::shared_pointer req;
364 
365  {
366  Guard G(mutex);
367 
368  if(state==Closed)
369  throw std::logic_error("Monitor can't start() before open()");
370 
371  if(running || state!=Opened)
372  return pvd::Status();
373 
374  if(!inuse.empty()) {
375  self = shared_from_this();
376  req = requester.lock();
377  }
378 
379  running = true;
380  }
381 
382  if(req)
383  req->monitorEvent(self);
384 
385  return pvd::Status();
386 }
const ChannelProcessRequester::weak_pointer requester
Definition: pvAccess.cpp:68
pvd::Status epics::pvAccess::MonitorFIFO::stop ( )
virtual

Stop Monitoring.

Returns
completion status.

Implements epics::pvAccess::Monitor.

Definition at line 388 of file monitor.cpp.

389 {
390  Guard G(mutex);
391 
392  running = false;
393 
394  return pvd::Status();
395 }
bool epics::pvAccess::MonitorFIFO::tryPost ( const pvData::PVStructure value,
const epics::pvData::BitSet changed,
const epics::pvData::BitSet overrun = epics::pvData::BitSet(),
bool  force = false 
)

Consume a free slot if available. otherwise ... if !force take no action and return false. if force then attempt to allocate and fill a new slot, then return false. The extra slot will be free'd after it is consumed.

Definition at line 210 of file monitor.cpp.

214 {
215  Guard G(mutex);
216 
217  if(state!=Opened || finished) return false; // when Error, act as always "full"
218  assert(!empty.empty() || !inuse.empty());
219 
220  const bool havefree = _freeCount()>0u;
221 
222  MonitorElementPtr elem;
223  if(conf.dropEmptyUpdates && !changed.logical_and(mapper.requestedMask())) {
224  // drop empty update
225  } else if(havefree) {
226  // take an empty element
227  elem = empty.front();
228  empty.pop_front();
229  } else if(force) {
230  // allocate an extra element
231  elem.reset(new MonitorElement(mapper.buildRequested()));
232  }
233 
234  if(elem) {
235  try {
236  elem->changedBitSet->clear();
237  mapper.copyBaseToRequested(value, changed,
238  *elem->pvStructurePtr, *elem->changedBitSet);
239  elem->overrunBitSet->clear();
240  mapper.maskBaseToRequested(overrun, *elem->overrunBitSet);
241 
242  if(inuse.empty() && running)
243  needEvent = true;
244  inuse.push_back(elem);
245  }catch(...){
246  if(havefree) {
247  empty.push_front(elem);
248  }
249  throw;
250  }
251  if(pipeline)
252  flowCount--;
253  }
254 
255  return _freeCount()>0u;
256 }
epics::pvData::BitSetPtr empty
Definition: pvAccess.cpp:135
void copyBaseToRequested(const PVStructure &base, const BitSet &baseMask, PVStructure &request, BitSet &requestMask) const
Definition: link.h:174
#define assert(exp)
Declare that a condition should be true.
Definition: epicsAssert.h:70
const BitSet & requestedMask() const
void maskBaseToRequested(const BitSet &baseMask, BitSet &requestMask) const
PVStructurePtr buildRequested() const
bool logical_and(const BitSet &other) const
Returns true if any bit is set in both *this and other.
Definition: bitSet.cpp:214
std::tr1::shared_ptr< MonitorElement > MonitorElementPtr
Definition: monitor.h:40
bool dropEmptyUpdates
default true. Drop updates which don&#39;t include an field values.
Definition: monitor.h:278

Friends And Related Function Documentation

void providerRegInit ( void *  )
friend

Definition at line 208 of file ChannelAccessFactory.cpp.

209 {
212 
213  providerRegGbl = new providerRegGbl_t;
214  providerRegGbl->clients->add("pva", createClientProvider);
215 
218  registerRefCounter("Transport (ABC)", &Transport::num_instances);
221  registerRefCounter("ChannelProvider (ABC)", &ChannelProvider::num_instances);
222  registerRefCounter("Channel (ABC)", &Channel::num_instances);
223  registerRefCounter("ChannelRequester (ABC)", &ChannelRequester::num_instances);
224  registerRefCounter("ChannelBaseRequester (ABC)", &ChannelBaseRequester::num_instances);
225  registerRefCounter("ChannelRequest (ABC)", &ChannelRequest::num_instances);
226  registerRefCounter("ResponseHandler (ABC)", &ResponseHandler::num_instances);
227  registerRefCounter("MonitorFIFO", &MonitorFIFO::num_instances);
232  registerRefCounter("pvas::SharedPV", &pvas::SharedPV::num_instances);
233 }
LIBCOM_API void epicsStdCall epicsSignalInstallSigPipeIgnore(void)
Definition: osdSignal.cpp:17
static size_t num_instances
static size_t num_instances
Definition: pvAccess.h:895
ChannelProvider::shared_pointer createClientProvider(const Configuration::shared_pointer &conf)
LIBCOM_API void epicsStdCall epicsSignalInstallSigAlarmIgnore(void)
Definition: osdSignal.cpp:18
void registerRefCounter(const char *name, const size_t *counter)
Definition: reftrack.cpp:59
void registerRefTrackServer()
Definition: server.cpp:281
static size_t num_instances
Definition: remote.h:168

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