simplify monitors; cleanup code; fix race condidition for monitor cleanup
This commit is contained in:
@@ -21,8 +21,9 @@
|
||||
#include <deque>
|
||||
|
||||
#include <pv/pvData.h>
|
||||
|
||||
#include <pv/pvCopy.h>
|
||||
#include <pv/convert.h>
|
||||
#include <pv/pvTimeStamp.h>
|
||||
|
||||
#ifdef pvdatabaseEpicsExportSharedSymbols
|
||||
# define epicsExportSharedSymbols
|
||||
@@ -61,6 +62,7 @@ typedef std::tr1::shared_ptr<PVDatabase> PVDatabasePtr;
|
||||
* @author mrk
|
||||
*/
|
||||
class epicsShareClass PVRecord :
|
||||
public epics::pvData::PVCopyTraverseMasterCallback,
|
||||
public std::tr1::enable_shared_from_this<PVRecord>
|
||||
{
|
||||
public:
|
||||
@@ -84,7 +86,7 @@ public:
|
||||
* If it encounters errors it should raise alarms and/or
|
||||
* call the <b>message</b> method provided by the base class.
|
||||
*/
|
||||
virtual void process() {}
|
||||
virtual void process();
|
||||
/**
|
||||
* Destroy the PVRecord. Release any resources used and
|
||||
* get rid of listeners and requesters.
|
||||
@@ -168,15 +170,26 @@ public:
|
||||
* Add a PVListener.
|
||||
* This must be called before calling pvRecordField.addListener.
|
||||
* @param pvListener The listener.
|
||||
* @param pvCopy The pvStructure that has the client fields.
|
||||
* @return <b>true</b> if the listener was added.
|
||||
*/
|
||||
bool addListener(PVListenerPtr const & pvListener);
|
||||
bool addListener(
|
||||
PVListenerPtr const & pvListener,
|
||||
epics::pvData::PVCopyPtr const & pvCopy);
|
||||
/*
|
||||
* PVCopyTraverseMasterCallback method
|
||||
* @param pvField The next client field.
|
||||
*/
|
||||
void nextMasterPVField(epics::pvData::PVFieldPtr const & pvField);
|
||||
/**
|
||||
* Remove a listener.
|
||||
* @param pvListener The listener.
|
||||
* @param pvCopy The pvStructure that has the client fields.
|
||||
* @return <b>true</b> if the listener was removed.
|
||||
*/
|
||||
bool removeListener(PVListenerPtr const & pvListener);
|
||||
bool removeListener(
|
||||
PVListenerPtr const & pvListener,
|
||||
epics::pvData::PVCopyPtr const & pvCopy);
|
||||
/**
|
||||
* Begins a group of puts.
|
||||
*/
|
||||
@@ -221,6 +234,7 @@ private:
|
||||
PVRecordFieldPtr findPVRecordField(
|
||||
PVRecordStructurePtr const & pvrs,
|
||||
epics::pvData::PVFieldPtr const & pvField);
|
||||
|
||||
std::string recordName;
|
||||
epics::pvData::PVStructurePtr pvStructure;
|
||||
epics::pvData::ConvertPtr convert;
|
||||
@@ -231,6 +245,13 @@ private:
|
||||
std::size_t depthGroupPut;
|
||||
int traceLevel;
|
||||
bool isDestroyed;
|
||||
|
||||
epics::pvData::PVTimeStamp pvTimeStamp;
|
||||
epics::pvData::TimeStamp timeStamp;
|
||||
|
||||
// following only valid while addListener or removeListener is active.
|
||||
bool isAddListener;
|
||||
PVListenerPtr pvListener;
|
||||
};
|
||||
|
||||
epicsShareExtern std::ostream& operator<<(std::ostream& o, const PVRecord& record);
|
||||
@@ -289,21 +310,6 @@ public:
|
||||
* @return The shared pointer,
|
||||
*/
|
||||
PVRecordPtr getPVRecord();
|
||||
/**
|
||||
* Add A PVListener to this field.
|
||||
* Whenever this field or any subfield if this field is modified the listener will be notified.
|
||||
* PVListener is described below.
|
||||
* Before a listener can call addListener it must first call PVRecord.registerListener.
|
||||
* @param pvListener The listener.
|
||||
* @return <b<true</b> if listener is added.
|
||||
*/
|
||||
bool addListener(PVListenerPtr const & pvListener);
|
||||
/**
|
||||
* Remove a listener.
|
||||
* @param pvListener The listener.
|
||||
* @return <b<true</b> if listener is removed.
|
||||
*/
|
||||
virtual void removeListener(PVListenerPtr const & pvListener);
|
||||
/**
|
||||
* This is called by the code that implements the data interface.
|
||||
* It is called whenever the put method is called.
|
||||
@@ -318,6 +324,8 @@ protected:
|
||||
virtual void postParent(PVRecordFieldPtr const & subField);
|
||||
virtual void postSubField();
|
||||
private:
|
||||
bool addListener(PVListenerPtr const & pvListener);
|
||||
virtual void removeListener(PVListenerPtr const & pvListener);
|
||||
void callListener();
|
||||
|
||||
std::list<PVListenerPtr> pvListenerList;
|
||||
@@ -368,11 +376,6 @@ public:
|
||||
* @return The shared pointer.
|
||||
*/
|
||||
epics::pvData::PVStructurePtr getPVStructure();
|
||||
/**
|
||||
* Called by PVRecord::removeListener.
|
||||
* @param pvListener The listener.
|
||||
*/
|
||||
virtual void removeListener(PVListenerPtr const & pvListener);
|
||||
/**
|
||||
* Called by implementation code of PVRecord.
|
||||
*/
|
||||
@@ -383,6 +386,8 @@ protected:
|
||||
*/
|
||||
virtual void init();
|
||||
private:
|
||||
virtual void removeListener(PVListenerPtr const & pvListener);
|
||||
|
||||
epics::pvData::PVStructurePtr pvStructure;
|
||||
PVRecordFieldPtrArrayPtr pvRecordFields;
|
||||
friend class PVRecord;
|
||||
|
||||
@@ -42,7 +42,8 @@ PVRecord::PVRecord(
|
||||
convert(getConvert()),
|
||||
depthGroupPut(0),
|
||||
traceLevel(0),
|
||||
isDestroyed(false)
|
||||
isDestroyed(false),
|
||||
isAddListener(false)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -59,6 +60,8 @@ void PVRecord::initPVRecord()
|
||||
pvRecordStructure = PVRecordStructurePtr(
|
||||
new PVRecordStructure(pvStructure,parent,getPtrSelf()));
|
||||
pvRecordStructure->init();
|
||||
PVFieldPtr pvField = pvStructure->getSubField("timeStamp");
|
||||
if(pvField) pvTimeStamp.attach(pvField);
|
||||
}
|
||||
|
||||
void PVRecord::destroy()
|
||||
@@ -73,6 +76,7 @@ void PVRecord::destroy()
|
||||
return;
|
||||
}
|
||||
isDestroyed = true;
|
||||
pvTimeStamp.detach();
|
||||
|
||||
std::list<PVRecordClientPtr>::iterator clientIter;
|
||||
while(true) {
|
||||
@@ -103,6 +107,17 @@ void PVRecord::destroy()
|
||||
}
|
||||
}
|
||||
|
||||
void PVRecord::process()
|
||||
{
|
||||
if(traceLevel>2) {
|
||||
cout << "PVRecord::process() " << recordName << endl;
|
||||
}
|
||||
if(pvTimeStamp.isAttached()) {
|
||||
timeStamp.getCurrent();
|
||||
pvTimeStamp.set(timeStamp);
|
||||
}
|
||||
}
|
||||
|
||||
string PVRecord::getRecordName() const {return recordName;}
|
||||
|
||||
PVRecordStructurePtr PVRecord::getPVRecordStructure() const {return pvRecordStructure;}
|
||||
@@ -263,7 +278,9 @@ void PVRecord::detachClients()
|
||||
}
|
||||
}
|
||||
|
||||
bool PVRecord::addListener(PVListenerPtr const & pvListener)
|
||||
bool PVRecord::addListener(
|
||||
PVListenerPtr const & pvListener,
|
||||
PVCopyPtr const & pvCopy)
|
||||
{
|
||||
if(traceLevel>1) {
|
||||
cout << "PVRecord::addListener() " << recordName << endl;
|
||||
@@ -283,6 +300,10 @@ bool PVRecord::addListener(PVListenerPtr const & pvListener)
|
||||
}
|
||||
}
|
||||
pvListenerList.push_back(pvListener);
|
||||
this->pvListener = pvListener;
|
||||
isAddListener = true;
|
||||
pvCopy->traverseMaster(getPtrSelf());
|
||||
this->pvListener = PVListenerPtr();;
|
||||
unlock();
|
||||
return true;
|
||||
} catch(...) {
|
||||
@@ -291,7 +312,19 @@ bool PVRecord::addListener(PVListenerPtr const & pvListener)
|
||||
}
|
||||
}
|
||||
|
||||
bool PVRecord::removeListener(PVListenerPtr const & pvListener)
|
||||
void PVRecord::nextMasterPVField(PVFieldPtr const & pvField)
|
||||
{
|
||||
PVRecordFieldPtr pvRecordField = findPVRecordField(pvField);
|
||||
if(isAddListener) {
|
||||
pvRecordField->addListener(pvListener);
|
||||
} else {
|
||||
pvRecordField->removeListener(pvListener);
|
||||
}
|
||||
}
|
||||
|
||||
bool PVRecord::removeListener(
|
||||
PVListenerPtr const & pvListener,
|
||||
PVCopyPtr const & pvCopy)
|
||||
{
|
||||
if(traceLevel>1) {
|
||||
cout << "PVRecord::removeListener() " << recordName << endl;
|
||||
@@ -307,7 +340,10 @@ bool PVRecord::removeListener(PVListenerPtr const & pvListener)
|
||||
{
|
||||
if((*iter).get()==pvListener.get()) {
|
||||
pvListenerList.erase(iter);
|
||||
pvRecordStructure->removeListener(pvListener);
|
||||
this->pvListener = pvListener;
|
||||
isAddListener = false;
|
||||
pvCopy->traverseMaster(getPtrSelf());
|
||||
this->pvListener = PVListenerPtr();;
|
||||
unlock();
|
||||
return true;
|
||||
}
|
||||
@@ -411,6 +447,9 @@ PVRecordPtr PVRecordField::getPVRecord() {return pvRecord;}
|
||||
|
||||
bool PVRecordField::addListener(PVListenerPtr const & pvListener)
|
||||
{
|
||||
if(pvRecord->getTraceLevel()>1) {
|
||||
cout << "PVRecordField::addListener() " << getFullName() << endl;
|
||||
}
|
||||
std::list<PVListenerPtr>::iterator iter;
|
||||
for (iter = pvListenerList.begin(); iter!=pvListenerList.end(); iter++ ) {
|
||||
if((*iter).get()==pvListener.get()) {
|
||||
@@ -423,6 +462,9 @@ bool PVRecordField::addListener(PVListenerPtr const & pvListener)
|
||||
|
||||
void PVRecordField::removeListener(PVListenerPtr const & pvListener)
|
||||
{
|
||||
if(pvRecord->getTraceLevel()>1) {
|
||||
cout << "PVRecordField::removeListener() " << getFullName() << endl;
|
||||
}
|
||||
std::list<PVListenerPtr>::iterator iter;
|
||||
for (iter = pvListenerList.begin(); iter!=pvListenerList.end(); iter++ ) {
|
||||
if((*iter).get()==pvListener.get()) {
|
||||
|
||||
Reference in New Issue
Block a user