24 #define epicsExportSharedSymbols 37 namespace epics {
namespace pvDatabase {
44 static Status failedToCreateMonitorStatus(
69 : elements(monitorElementArray),
70 size(monitorElementArray.size()),
96 int ind = nextGetFree;
98 if(nextGetFree>=size) nextGetFree = 0;
104 if(element!=elements[nextSetUsed++]) {
105 throw std::logic_error(
"not correct queueElement");
108 if(nextSetUsed>=size) nextSetUsed = 0;
114 int ind = nextGetUsed;
116 if(nextGetUsed>=size) nextGetUsed = 0;
117 return elements[ind];
121 if(element!=elements[nextReleaseUsed++]) {
122 throw std::logic_error(
123 "not queueElement returned by last call to getUsed");
125 if(nextReleaseUsed>=size) nextReleaseUsed = 0;
138 public std::tr1::enable_shared_from_this<MonitorLocal>
140 enum MonitorState {idle,active,deleted};
151 virtual void dataPut(
154 virtual void beginGroupPut(
PVRecordPtr const & pvRecord);
155 virtual void endGroupPut(
PVRecordPtr const & pvRecord);
156 virtual void unlisten(
PVRecordPtr const & pvRecord);
158 void releaseActiveElement();
161 MonitorRequester::shared_pointer
const & channelMonitorRequester,
165 MonitorLocalPtr getPtrSelf()
167 return shared_from_this();
169 MonitorRequester::weak_pointer monitorRequester;
173 MonitorElementQueuePtr queue;
181 MonitorLocal::MonitorLocal(
182 MonitorRequester::shared_pointer
const & channelMonitorRequester,
184 : monitorRequester(channelMonitorRequester),
200 if(pvRecord->getTraceLevel()>0)
202 cout <<
"MonitorLocal::start state " << state << endl;
206 if(state==active)
return alreadyStartedStatus;
207 if(state==deleted)
return deletedStatus;
209 pvRecord->addListener(getPtrSelf(),pvCopy);
215 activeElement = queue->getFree();
216 activeElement->changedBitSet->clear();
217 activeElement->overrunBitSet->clear();
218 activeElement->changedBitSet->set(0);
225 if(pvRecord->getTraceLevel()>0){
226 cout <<
"MonitorLocal::stop state " << state << endl;
230 if(state==idle)
return notStartedStatus;
231 if(state==deleted)
return deletedStatus;
234 pvRecord->removeListener(getPtrSelf(),pvCopy);
240 if(pvRecord->getTraceLevel()>1)
242 cout <<
"MonitorLocal::poll state " << state << endl;
246 if(state!=active)
return NULLMonitorElement;
247 return queue->getUsed();
253 if(pvRecord->getTraceLevel()>1)
255 cout <<
"MonitorLocal::release state " << state << endl;
259 if(state!=active)
return;
260 queue->releaseUsed(monitorElement);
266 if(pvRecord->getTraceLevel()>1)
268 cout <<
"MonitorLocal::releaseActiveElement state " << state << endl;
272 if(state!=active)
return;
273 bool result = pvCopy->updateCopyFromBitSet(activeElement->pvStructurePtr,activeElement->changedBitSet);
276 if(!newActive)
return;
277 BitSetUtil::compress(activeElement->changedBitSet,activeElement->pvStructurePtr);
278 BitSetUtil::compress(activeElement->overrunBitSet,activeElement->pvStructurePtr);
279 queue->setUsed(activeElement);
280 activeElement = newActive;
281 activeElement->changedBitSet->clear();
282 activeElement->overrunBitSet->clear();
284 MonitorRequesterPtr
requester = monitorRequester.lock();
285 if(!requester)
return;
286 requester->monitorEvent(getPtrSelf());
292 if(pvRecord->getTraceLevel()>1)
294 cout <<
"MonitorLocal::dataPut(pvRecordField)" << endl;
296 if(state!=active)
return;
299 size_t offset = pvCopy->getCopyOffset(pvRecordField->getPVField());
300 BitSetPtr const &changedBitSet = activeElement->changedBitSet;
301 BitSetPtr const &overrunBitSet = activeElement->overrunBitSet;
302 bool isSet = changedBitSet->get(offset);
303 changedBitSet->set(offset);
304 if(isSet) overrunBitSet->set(offset);
317 if(pvRecord->getTraceLevel()>1)
319 cout <<
"MonitorLocal::dataPut(requested,pvRecordField)" << endl;
321 if(state!=active)
return;
324 BitSetPtr const &changedBitSet = activeElement->changedBitSet;
325 BitSetPtr const &overrunBitSet = activeElement->overrunBitSet;
326 size_t offsetCopyRequested = pvCopy->getCopyOffset(
327 requested->getPVField());
328 size_t offset = offsetCopyRequested
329 + (pvRecordField->getPVField()->getFieldOffset()
330 - requested->getPVField()->getFieldOffset());
331 bool isSet = changedBitSet->get(offset);
332 changedBitSet->set(offset);
333 if(isSet) overrunBitSet->set(offset);
344 if(pvRecord->getTraceLevel()>1)
346 cout <<
"MonitorLocal::beginGroupPut()" << endl;
348 if(state!=active)
return;
358 if(pvRecord->getTraceLevel()>1)
360 cout <<
"MonitorLocal::endGroupPut dataChanged " << dataChanged << endl;
362 if(state!=active)
return;
375 if(pvRecord->getTraceLevel()>1)
377 cout <<
"MonitorLocal::unlisten\n";
383 MonitorRequesterPtr
requester = monitorRequester.lock();
385 if(pvRecord->getTraceLevel()>1)
387 cout <<
"MonitorLocal::unlisten calling requester->unlisten\n";
389 requester->unlisten(getPtrSelf());
397 size_t queueSize = 2;
399 MonitorRequesterPtr
requester = monitorRequester.lock();
400 if(!requester)
return false;
406 std::stringstream ss;
407 ss << pvString->
get();
411 requester->message(
"queueSize " +pvString->get() +
" illegal",
errorMessage);
416 pvField = pvRequest->getSubField(
"field");
418 pvCopy = PVCopy::create(
419 pvRecord->getPVRecordStructure()->getPVStructure(),
426 if(pvField->getField()->getType()!=
structure) {
430 pvCopy = PVCopy::create(
431 pvRecord->getPVRecordStructure()->getPVStructure(),
438 if(queueSize<2) queueSize = 2;
439 std::vector<MonitorElementPtr> monitorElementArray;
440 monitorElementArray.reserve(queueSize);
441 for(
size_t i=0;
i<queueSize;
i++) {
445 monitorElementArray.push_back(monitorElement);
448 requester->monitorConnect(
451 pvCopy->getStructure());
457 MonitorRequester::shared_pointer
const & monitorRequester,
461 monitorRequester,pvRecord));
462 bool result = monitor->init(pvRequest);
466 monitorRequester->monitorConnect(
467 failedToCreateMonitorStatus,monitor,structure);
470 if(pvRecord->getTraceLevel()>0)
472 cout <<
"MonitorFactory::createMonitor" 473 <<
" recordName " << pvRecord->getRecordName() << endl;
virtual void beginGroupPut(PVRecordPtr const &pvRecord)
Begin a set of puts.
virtual void release(MonitorElementPtr const &monitorElement)
std::tr1::shared_ptr< PVCopy > PVCopyPtr
Listener for PVRecord::message.
shared_ptr< T > static_pointer_cast(shared_ptr< U > const &r) BOOST_NOEXCEPT
virtual MonitorElementPtr poll()
TODO only here because of the Lockable.
std::tr1::shared_ptr< const Structure > StructureConstPtr
A lock for multithreading.
An element for a monitorQueue.
storage_t::arg_type get() const
virtual ~MonitorElementQueue()
virtual void endGroupPut(PVRecordPtr const &pvRecord)
End a set of puts.
PVString is special case, since it implements SerializableArray.
std::vector< MonitorElementPtr > MonitorElementPtrArray
void releaseUsed(MonitorElementPtr const &element)
#define POINTER_DEFINITIONS(clazz)
epicsShareFunc epics::pvData::MonitorPtr createMonitorLocal(PVRecordPtr const &pvRecord, epics::pvData::MonitorRequester::shared_pointer const &monitorRequester, epics::pvData::PVStructurePtr const &pvRequest)
virtual void dataPut(PVRecordFieldPtr const &pvRecordField)
pvField has been modified.
const ChannelProcessRequester::weak_pointer requester
std::tr1::shared_ptr< MonitorLocal > MonitorLocalPtr
void setUsed(MonitorElementPtr const &element)
MonitorElementQueue(std::vector< MonitorElementPtr > monitorElementArray)
Data interface for a structure,.
std::tr1::shared_ptr< MonitorRequester > MonitorRequesterPtr
std::tr1::shared_ptr< PVRecord > PVRecordPtr
virtual void unlisten(PVRecordPtr const &pvRecord)
Connection to record is being terminated.
std::tr1::shared_ptr< PVStructure > PVStructurePtr
std::tr1::shared_ptr< PVString > PVStringPtr
std::tr1::shared_ptr< PVRecordStructure > PVRecordStructurePtr
std::tr1::shared_ptr< PVField > PVFieldPtr
MonitorElementPtr getUsed()
std::tr1::shared_ptr< PVRecordField > PVRecordFieldPtr
std::tr1::shared_ptr< MonitorElementQueue > MonitorElementQueuePtr
MonitorLocal(MonitorRequester::shared_pointer const &channelMonitorRequester, PVRecordPtr const &pvRecord)
virtual void detach(PVRecordPtr const &pvRecord)
Detach from the record because it is being removed.
std::tr1::shared_ptr< MonitorElement > MonitorElementPtr
std::tr1::shared_ptr< BitSet > BitSetPtr
bool init(PVStructurePtr const &pvRequest)
std::tr1::shared_ptr< Monitor > MonitorPtr
MonitorElementPtr getFree()
void releaseActiveElement()