From 0d855614813efe1492ad32d9c303ea3c00a3c18c Mon Sep 17 00:00:00 2001 From: Sinisa Veseli Date: Mon, 14 Mar 2022 09:17:33 -0500 Subject: [PATCH] this resolves issue with monitor overrun counter; master field listeners will be called only once, before calling listeners for the first subfield --- src/database/pvRecord.cpp | 23 ++++++++++++++++++++++- src/pv/pvDatabase.h | 1 + 2 files changed, 23 insertions(+), 1 deletion(-) diff --git a/src/database/pvRecord.cpp b/src/database/pvRecord.cpp index d343b6c..5357fc8 100644 --- a/src/database/pvRecord.cpp +++ b/src/database/pvRecord.cpp @@ -332,6 +332,7 @@ PVRecordField::PVRecordField( PVRecordPtr const & pvRecord) : pvField(pvField), isStructure(pvField->getField()->getType()==structure ? true : false), + master(), parent(parent), pvRecord(pvRecord) { @@ -420,12 +421,16 @@ void PVRecordField::postParent(PVRecordFieldPtr const & subField) PVRecordStructurePtr parent(this->parent.lock()); if(parent) { parent->postParent(subField); - parent->callListener(); } } void PVRecordField::postSubField() { + // Master field pointer will be set in only one subfield + PVRecordStructurePtr master(this->master.lock()); + if(master) { + master->callListener(); + } callListener(); if(isStructure) { PVRecordStructurePtr pvrs = @@ -468,6 +473,11 @@ void PVRecordStructure::init() PVRecordStructurePtr self = static_pointer_cast(shared_from_this()); PVRecordPtr pvRecord = getPVRecord(); + static bool masterFieldCallbackSet = false; + bool isMasterField = (!getFullFieldName().size()); + if (isMasterField) { + masterFieldCallbackSet = false; + } for(size_t i=0; igetField()->getType()==structure) { @@ -481,6 +491,17 @@ void PVRecordStructure::init() new PVRecordField(pvField,self,pvRecord)); pvRecordFields->push_back(pvRecordField); 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(); + } + } } } } diff --git a/src/pv/pvDatabase.h b/src/pv/pvDatabase.h index a072466..3142373 100644 --- a/src/pv/pvDatabase.h +++ b/src/pv/pvDatabase.h @@ -376,6 +376,7 @@ private: std::list pvListenerList; epics::pvData::PVField::weak_pointer pvField; bool isStructure; + PVRecordStructureWPtr master; PVRecordStructureWPtr parent; PVRecordWPtr pvRecord; std::string fullName;