this resolves issue with monitor overrun counter; master field listeners will be called only once, before calling listeners for the first subfield

This commit is contained in:
Sinisa Veseli
2022-03-14 09:17:33 -05:00
parent 05d54c61e1
commit 0d85561481
2 changed files with 23 additions and 1 deletions

View File

@ -332,6 +332,7 @@ PVRecordField::PVRecordField(
PVRecordPtr const & pvRecord) PVRecordPtr const & pvRecord)
: pvField(pvField), : pvField(pvField),
isStructure(pvField->getField()->getType()==structure ? true : false), isStructure(pvField->getField()->getType()==structure ? true : false),
master(),
parent(parent), parent(parent),
pvRecord(pvRecord) pvRecord(pvRecord)
{ {
@ -420,12 +421,16 @@ void PVRecordField::postParent(PVRecordFieldPtr const & subField)
PVRecordStructurePtr parent(this->parent.lock()); PVRecordStructurePtr parent(this->parent.lock());
if(parent) { if(parent) {
parent->postParent(subField); parent->postParent(subField);
parent->callListener();
} }
} }
void PVRecordField::postSubField() void PVRecordField::postSubField()
{ {
// Master field pointer will be set in only one subfield
PVRecordStructurePtr master(this->master.lock());
if(master) {
master->callListener();
}
callListener(); callListener();
if(isStructure) { if(isStructure) {
PVRecordStructurePtr pvrs = PVRecordStructurePtr pvrs =
@ -468,6 +473,11 @@ void PVRecordStructure::init()
PVRecordStructurePtr self = PVRecordStructurePtr self =
static_pointer_cast<PVRecordStructure>(shared_from_this()); static_pointer_cast<PVRecordStructure>(shared_from_this());
PVRecordPtr pvRecord = getPVRecord(); PVRecordPtr pvRecord = getPVRecord();
static bool masterFieldCallbackSet = false;
bool isMasterField = (!getFullFieldName().size());
if (isMasterField) {
masterFieldCallbackSet = false;
}
for(size_t i=0; i<numFields; i++) { for(size_t i=0; i<numFields; i++) {
PVFieldPtr pvField = pvFields[i]; PVFieldPtr pvField = pvFields[i];
if(pvField->getField()->getType()==structure) { if(pvField->getField()->getType()==structure) {
@ -481,6 +491,17 @@ void PVRecordStructure::init()
new PVRecordField(pvField,self,pvRecord)); new PVRecordField(pvField,self,pvRecord));
pvRecordFields->push_back(pvRecordField); pvRecordFields->push_back(pvRecordField);
pvRecordField->init(); pvRecordField->init();
// Master field listeners will be called before
// calling listeners for the first subfield
if (!masterFieldCallbackSet) {
masterFieldCallbackSet = true;
// Find master field
PVRecordStructurePtr p = pvRecordField->parent.lock();
while (p) {
pvRecordField->master = p;
p = p->parent.lock();
}
}
} }
} }
} }

View File

@ -376,6 +376,7 @@ private:
std::list<PVListenerWPtr> pvListenerList; std::list<PVListenerWPtr> pvListenerList;
epics::pvData::PVField::weak_pointer pvField; epics::pvData::PVField::weak_pointer pvField;
bool isStructure; bool isStructure;
PVRecordStructureWPtr master;
PVRecordStructureWPtr parent; PVRecordStructureWPtr parent;
PVRecordWPtr pvRecord; PVRecordWPtr pvRecord;
std::string fullName; std::string fullName;