latest changes; memory leaks fixed
This commit is contained in:
@ -40,5 +40,5 @@ PVDATA=/home/mrk/hg/pvDataCPP
|
|||||||
PVACCESS=/home/mrk/hg/pvAccessCPP
|
PVACCESS=/home/mrk/hg/pvAccessCPP
|
||||||
|
|
||||||
# set your EPICS_BASE, PVDATA and PVACCESS paths in here
|
# set your EPICS_BASE, PVDATA and PVACCESS paths in here
|
||||||
-include $(TOP)/configure/RELEASE.local
|
|
||||||
-include $(TOP)/../RELEASE.local
|
-include $(TOP)/../RELEASE.local
|
||||||
|
-include $(TOP)/configure/RELEASE.local
|
||||||
|
@ -77,6 +77,8 @@ int main(int argc,char *argv[])
|
|||||||
PVRecordPtr pvRecord;
|
PVRecordPtr pvRecord;
|
||||||
pvRecord = ArrayPerformance::create(recordName,size,delay);
|
pvRecord = ArrayPerformance::create(recordName,size,delay);
|
||||||
result = master->addRecord(pvRecord);
|
result = master->addRecord(pvRecord);
|
||||||
|
PVRecordPtr arrayPreformance = pvRecord;
|
||||||
|
arrayPreformance->setTraceLevel(1);
|
||||||
pvRecord = TraceRecord::create("traceRecordPGRPC");
|
pvRecord = TraceRecord::create("traceRecordPGRPC");
|
||||||
result = master->addRecord(pvRecord);
|
result = master->addRecord(pvRecord);
|
||||||
if(!result) cout<< "record " << recordName << " not added" << endl;
|
if(!result) cout<< "record " << recordName << " not added" << endl;
|
||||||
@ -97,11 +99,14 @@ int main(int argc,char *argv[])
|
|||||||
if(str.compare("exit")==0) break;
|
if(str.compare("exit")==0) break;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
arrayPreformance.reset();
|
||||||
for(size_t i=0; i<nMonitor; ++i) longArrayMonitor[i]->stop();
|
for(size_t i=0; i<nMonitor; ++i) longArrayMonitor[i]->stop();
|
||||||
|
for(size_t i=0; i<nMonitor; ++i) longArrayMonitor[i]->destroy();
|
||||||
pvaServer->shutdown();
|
pvaServer->shutdown();
|
||||||
epicsThreadSleep(1.0);
|
epicsThreadSleep(1.0);
|
||||||
pvaServer->destroy();
|
pvaServer->destroy();
|
||||||
ClientFactory::stop();
|
ClientFactory::stop();
|
||||||
|
epicsThreadSleep(1.0);
|
||||||
channelProvider->destroy();
|
channelProvider->destroy();
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -62,9 +62,10 @@ int main(int argc,char *argv[])
|
|||||||
if(str.compare("exit")==0) break;
|
if(str.compare("exit")==0) break;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
ClientFactory::stop();
|
||||||
|
epicsThreadSleep(.1);
|
||||||
longArrayMonitor->destroy();
|
longArrayMonitor->destroy();
|
||||||
longArrayMonitor.reset();
|
longArrayMonitor.reset();
|
||||||
ClientFactory::stop();
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -37,6 +37,7 @@ public:
|
|||||||
: longArrayMonitor(longArrayMonitor)
|
: longArrayMonitor(longArrayMonitor)
|
||||||
{}
|
{}
|
||||||
virtual ~LAMChannelRequester(){}
|
virtual ~LAMChannelRequester(){}
|
||||||
|
virtual void destroy(){longArrayMonitor.reset();}
|
||||||
virtual String getRequesterName() { return requesterName;}
|
virtual String getRequesterName() { return requesterName;}
|
||||||
virtual void message(String const & message, MessageType messageType)
|
virtual void message(String const & message, MessageType messageType)
|
||||||
{ messagePvt(message,messageType);}
|
{ messagePvt(message,messageType);}
|
||||||
@ -184,7 +185,6 @@ void LAMMonitorRequester::run()
|
|||||||
double diff = TimeStamp::diff(timeStamp,timeStampLast);
|
double diff = TimeStamp::diff(timeStamp,timeStampLast);
|
||||||
double elementsPerSecond = data.size();
|
double elementsPerSecond = data.size();
|
||||||
elementsPerSecond = 1e-6*elementsPerSecond/diff;
|
elementsPerSecond = 1e-6*elementsPerSecond/diff;
|
||||||
cout.flush();
|
|
||||||
cout << "first " << first << " last " << last << " sum " << sum;
|
cout << "first " << first << " last " << last << " sum " << sum;
|
||||||
cout << " elements/sec " << elementsPerSecond << "million";
|
cout << " elements/sec " << elementsPerSecond << "million";
|
||||||
BitSetPtr changed = monitorElement->changedBitSet;
|
BitSetPtr changed = monitorElement->changedBitSet;
|
||||||
@ -196,7 +196,6 @@ void LAMMonitorRequester::run()
|
|||||||
overrun->toString(&buffer);
|
overrun->toString(&buffer);
|
||||||
cout << " overrun " << buffer;
|
cout << " overrun " << buffer;
|
||||||
cout << endl;
|
cout << endl;
|
||||||
cout.flush();
|
|
||||||
timeStampLast = timeStamp;
|
timeStampLast = timeStamp;
|
||||||
} else {
|
} else {
|
||||||
cout << "size = 0" << endl;
|
cout << "size = 0" << endl;
|
||||||
@ -282,6 +281,7 @@ void LongArrayMonitor::destroy()
|
|||||||
monitor.reset();
|
monitor.reset();
|
||||||
channel->destroy();
|
channel->destroy();
|
||||||
channel.reset();
|
channel.reset();
|
||||||
|
channelRequester->destroy();
|
||||||
channelRequester.reset();
|
channelRequester.reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -28,6 +28,7 @@ using std::endl;
|
|||||||
static MonitorAlgorithmCreatePtr nullMonitorAlgorithmCreate;
|
static MonitorAlgorithmCreatePtr nullMonitorAlgorithmCreate;
|
||||||
static MonitorPtr nullMonitor;
|
static MonitorPtr nullMonitor;
|
||||||
static MonitorElementPtr NULLMonitorElement;
|
static MonitorElementPtr NULLMonitorElement;
|
||||||
|
static Status wasDestroyedStatus(Status::Status::STATUSTYPE_ERROR,"was destroyed");
|
||||||
|
|
||||||
static ConvertPtr convert = getConvert();
|
static ConvertPtr convert = getConvert();
|
||||||
|
|
||||||
@ -81,14 +82,12 @@ public:
|
|||||||
virtual MonitorElementPtr poll();
|
virtual MonitorElementPtr poll();
|
||||||
virtual void release(MonitorElementPtr const &monitorElement);
|
virtual void release(MonitorElementPtr const &monitorElement);
|
||||||
private:
|
private:
|
||||||
MonitorLocalPtr monitorLocal;
|
std::tr1::weak_ptr<MonitorLocal> monitorLocal;
|
||||||
PVStructurePtr pvCopyStructure;
|
PVStructurePtr pvCopyStructure;
|
||||||
MonitorElementPtr monitorElement;
|
MonitorElementPtr monitorElement;
|
||||||
bool gotMonitor;
|
bool gotMonitor;
|
||||||
bool wasReleased;
|
|
||||||
BitSetPtr changedBitSet;
|
BitSetPtr changedBitSet;
|
||||||
BitSetPtr overrunBitSet;
|
BitSetPtr overrunBitSet;
|
||||||
Mutex mutex;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class RealQueue :
|
class RealQueue :
|
||||||
@ -106,11 +105,10 @@ public:
|
|||||||
virtual MonitorElementPtr poll();
|
virtual MonitorElementPtr poll();
|
||||||
virtual void release(MonitorElementPtr const &monitorElement);
|
virtual void release(MonitorElementPtr const &monitorElement);
|
||||||
private:
|
private:
|
||||||
MonitorLocalPtr monitorLocal;
|
std::tr1::weak_ptr<MonitorLocal> monitorLocal;
|
||||||
Queue<MonitorElement> queue;
|
Queue<MonitorElement> queue;
|
||||||
bool queueIsFull;
|
bool queueIsFull;
|
||||||
MonitorElementPtr monitorElement;
|
MonitorElementPtr monitorElement;
|
||||||
Mutex mutex;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@ -190,11 +188,15 @@ void MonitorLocal::destroy()
|
|||||||
|
|
||||||
Status MonitorLocal::start()
|
Status MonitorLocal::start()
|
||||||
{
|
{
|
||||||
|
{
|
||||||
|
Lock xx(mutex);
|
||||||
if(pvRecord->getTraceLevel()>0)
|
if(pvRecord->getTraceLevel()>0)
|
||||||
{
|
{
|
||||||
cout << "MonitorLocal::start() " << endl;
|
cout << "MonitorLocal::start() " << endl;
|
||||||
}
|
}
|
||||||
|
if(isDestroyed) return wasDestroyedStatus;
|
||||||
firstMonitor = true;
|
firstMonitor = true;
|
||||||
|
}
|
||||||
return queue->start();
|
return queue->start();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -211,11 +213,44 @@ Status MonitorLocal::stop()
|
|||||||
|
|
||||||
MonitorElementPtr MonitorLocal::poll()
|
MonitorElementPtr MonitorLocal::poll()
|
||||||
{
|
{
|
||||||
|
pvRecord->lock();
|
||||||
|
try {
|
||||||
|
Lock xx(mutex);
|
||||||
if(pvRecord->getTraceLevel()>1)
|
if(pvRecord->getTraceLevel()>1)
|
||||||
{
|
{
|
||||||
cout << "MonitorLocal::poll() " << endl;
|
cout << "MonitorLocal::poll() " << endl;
|
||||||
}
|
}
|
||||||
return queue->poll();
|
if(isDestroyed) {
|
||||||
|
pvRecord->unlock();
|
||||||
|
return NULLMonitorElement;
|
||||||
|
}
|
||||||
|
MonitorElementPtr element = queue->poll();
|
||||||
|
pvRecord->unlock();
|
||||||
|
return element;
|
||||||
|
} catch(...) {
|
||||||
|
pvRecord->unlock();
|
||||||
|
throw;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void MonitorLocal::release(MonitorElementPtr const & monitorElement)
|
||||||
|
{
|
||||||
|
pvRecord->lock();
|
||||||
|
try {
|
||||||
|
Lock xx(mutex);
|
||||||
|
if(pvRecord->getTraceLevel()>1)
|
||||||
|
{
|
||||||
|
cout << "MonitorLocal::release() " << endl;
|
||||||
|
}
|
||||||
|
if(isDestroyed) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
queue->release(monitorElement);
|
||||||
|
pvRecord->unlock();
|
||||||
|
} catch(...) {
|
||||||
|
pvRecord->unlock();
|
||||||
|
throw;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void MonitorLocal::dataChanged()
|
void MonitorLocal::dataChanged()
|
||||||
@ -224,6 +259,8 @@ void MonitorLocal::dataChanged()
|
|||||||
{
|
{
|
||||||
cout << "MonitorLocal::dataChanged() " "firstMonitor " << firstMonitor << endl;
|
cout << "MonitorLocal::dataChanged() " "firstMonitor " << firstMonitor << endl;
|
||||||
}
|
}
|
||||||
|
Lock xx(mutex);
|
||||||
|
if(isDestroyed) return;
|
||||||
if(firstMonitor) {
|
if(firstMonitor) {
|
||||||
queue->dataChanged();
|
queue->dataChanged();
|
||||||
firstMonitor = false;
|
firstMonitor = false;
|
||||||
@ -244,15 +281,6 @@ void MonitorLocal::unlisten()
|
|||||||
monitorRequester->unlisten(getPtrSelf());
|
monitorRequester->unlisten(getPtrSelf());
|
||||||
}
|
}
|
||||||
|
|
||||||
void MonitorLocal::release(MonitorElementPtr const & monitorElement)
|
|
||||||
{
|
|
||||||
if(pvRecord->getTraceLevel()>1)
|
|
||||||
{
|
|
||||||
cout << "MonitorLocal::release() " << endl;
|
|
||||||
}
|
|
||||||
queue->release(monitorElement);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool MonitorLocal::init(PVStructurePtr const & pvRequest)
|
bool MonitorLocal::init(PVStructurePtr const & pvRequest)
|
||||||
{
|
{
|
||||||
PVFieldPtr pvField;
|
PVFieldPtr pvField;
|
||||||
@ -273,10 +301,7 @@ bool MonitorLocal::init(PVStructurePtr const & pvRequest)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(queueSize==1) {
|
|
||||||
monitorRequester->message("queueSize can not be 1",errorMessage);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
pvField = pvRequest->getSubField("field");
|
pvField = pvRequest->getSubField("field");
|
||||||
if(pvField.get()==NULL) {
|
if(pvField.get()==NULL) {
|
||||||
pvCopy = PVCopy::create(pvRecord,pvRequest,"");
|
pvCopy = PVCopy::create(pvRecord,pvRequest,"");
|
||||||
@ -297,7 +322,7 @@ bool MonitorLocal::init(PVStructurePtr const & pvRequest)
|
|||||||
}
|
}
|
||||||
pvCopyMonitor = pvCopy->createPVCopyMonitor(getPtrSelf());
|
pvCopyMonitor = pvCopy->createPVCopyMonitor(getPtrSelf());
|
||||||
// MARTY MUST IMPLEMENT periodic
|
// MARTY MUST IMPLEMENT periodic
|
||||||
if(queueSize==0) {
|
if(queueSize<2) {
|
||||||
queue = NOQueuePtr(new NOQueue(getPtrSelf()));
|
queue = NOQueuePtr(new NOQueue(getPtrSelf()));
|
||||||
} else {
|
} else {
|
||||||
std::vector<MonitorElementPtr> monitorElementArray;
|
std::vector<MonitorElementPtr> monitorElementArray;
|
||||||
@ -387,7 +412,6 @@ NOQueue::NOQueue(
|
|||||||
pvCopyStructure(monitorLocal->getPVCopy()->createPVStructure()),
|
pvCopyStructure(monitorLocal->getPVCopy()->createPVStructure()),
|
||||||
monitorElement(new MonitorElement(pvCopyStructure)),
|
monitorElement(new MonitorElement(pvCopyStructure)),
|
||||||
gotMonitor(false),
|
gotMonitor(false),
|
||||||
wasReleased(false),
|
|
||||||
changedBitSet(new BitSet(pvCopyStructure->getNumberFields())),
|
changedBitSet(new BitSet(pvCopyStructure->getNumberFields())),
|
||||||
overrunBitSet(new BitSet(pvCopyStructure->getNumberFields()))
|
overrunBitSet(new BitSet(pvCopyStructure->getNumberFields()))
|
||||||
{
|
{
|
||||||
@ -395,12 +419,12 @@ NOQueue::NOQueue(
|
|||||||
|
|
||||||
Status NOQueue::start()
|
Status NOQueue::start()
|
||||||
{
|
{
|
||||||
Lock xx(mutex);
|
|
||||||
gotMonitor = true;
|
gotMonitor = true;
|
||||||
wasReleased = true;
|
|
||||||
changedBitSet->clear();
|
changedBitSet->clear();
|
||||||
overrunBitSet->clear();
|
overrunBitSet->clear();
|
||||||
monitorLocal->getPVCopyMonitor()->startMonitoring(
|
MonitorLocalPtr ml = monitorLocal.lock();
|
||||||
|
if(ml==NULL) return wasDestroyedStatus;
|
||||||
|
ml->getPVCopyMonitor()->startMonitoring(
|
||||||
changedBitSet,
|
changedBitSet,
|
||||||
overrunBitSet);
|
overrunBitSet);
|
||||||
return Status::Ok;
|
return Status::Ok;
|
||||||
@ -412,17 +436,17 @@ void NOQueue::stop()
|
|||||||
|
|
||||||
bool NOQueue::dataChanged()
|
bool NOQueue::dataChanged()
|
||||||
{
|
{
|
||||||
Lock xx(mutex);
|
|
||||||
monitorLocal->getPVCopy()->updateCopyFromBitSet(
|
|
||||||
pvCopyStructure, changedBitSet);
|
|
||||||
gotMonitor = true;
|
gotMonitor = true;
|
||||||
return wasReleased;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
MonitorElementPtr NOQueue::poll()
|
MonitorElementPtr NOQueue::poll()
|
||||||
{
|
{
|
||||||
Lock xx(mutex);
|
|
||||||
if(!gotMonitor) return NULLMonitorElement;
|
if(!gotMonitor) return NULLMonitorElement;
|
||||||
|
MonitorLocalPtr ml = monitorLocal.lock();
|
||||||
|
if(ml==NULL) return NULLMonitorElement;
|
||||||
|
ml->getPVCopy()->updateCopyFromBitSet(
|
||||||
|
pvCopyStructure, changedBitSet);
|
||||||
getConvert()->copyStructure(pvCopyStructure,monitorElement->pvStructurePtr);
|
getConvert()->copyStructure(pvCopyStructure,monitorElement->pvStructurePtr);
|
||||||
BitSetUtil::compress(changedBitSet,pvCopyStructure);
|
BitSetUtil::compress(changedBitSet,pvCopyStructure);
|
||||||
BitSetUtil::compress(overrunBitSet,pvCopyStructure);
|
BitSetUtil::compress(overrunBitSet,pvCopyStructure);
|
||||||
@ -435,7 +459,6 @@ MonitorElementPtr NOQueue::poll()
|
|||||||
|
|
||||||
void NOQueue::release(MonitorElementPtr const &monitorElement)
|
void NOQueue::release(MonitorElementPtr const &monitorElement)
|
||||||
{
|
{
|
||||||
Lock xx(mutex);
|
|
||||||
gotMonitor = false;
|
gotMonitor = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -450,12 +473,13 @@ RealQueue::RealQueue(
|
|||||||
|
|
||||||
Status RealQueue::start()
|
Status RealQueue::start()
|
||||||
{
|
{
|
||||||
Lock xx(mutex);
|
|
||||||
queue.clear();
|
queue.clear();
|
||||||
monitorElement = queue.getFree();
|
monitorElement = queue.getFree();
|
||||||
monitorElement->changedBitSet->clear();
|
monitorElement->changedBitSet->clear();
|
||||||
monitorElement->overrunBitSet->clear();
|
monitorElement->overrunBitSet->clear();
|
||||||
monitorLocal->getPVCopyMonitor()->startMonitoring(
|
MonitorLocalPtr ml = monitorLocal.lock();
|
||||||
|
if(ml==NULL) return wasDestroyedStatus;
|
||||||
|
ml->getPVCopyMonitor()->startMonitoring(
|
||||||
monitorElement->changedBitSet,
|
monitorElement->changedBitSet,
|
||||||
monitorElement->overrunBitSet);
|
monitorElement->overrunBitSet);
|
||||||
return Status::Ok;
|
return Status::Ok;
|
||||||
@ -467,9 +491,10 @@ void RealQueue::stop()
|
|||||||
|
|
||||||
bool RealQueue::dataChanged()
|
bool RealQueue::dataChanged()
|
||||||
{
|
{
|
||||||
Lock xx(mutex);
|
|
||||||
PVStructurePtr pvStructure = monitorElement->pvStructurePtr;
|
PVStructurePtr pvStructure = monitorElement->pvStructurePtr;
|
||||||
monitorLocal->getPVCopy()->updateCopyFromBitSet(
|
MonitorLocalPtr ml = monitorLocal.lock();
|
||||||
|
if(ml==NULL) return false;
|
||||||
|
ml->getPVCopy()->updateCopyFromBitSet(
|
||||||
pvStructure,monitorElement->changedBitSet);
|
pvStructure,monitorElement->changedBitSet);
|
||||||
if(queue.getNumberFree()==0) {
|
if(queue.getNumberFree()==0) {
|
||||||
if(queueIsFull) return false;
|
if(queueIsFull) return false;
|
||||||
@ -485,7 +510,7 @@ bool RealQueue::dataChanged()
|
|||||||
convert->copy(pvStructure,newElement->pvStructurePtr);
|
convert->copy(pvStructure,newElement->pvStructurePtr);
|
||||||
newElement->changedBitSet->clear();
|
newElement->changedBitSet->clear();
|
||||||
newElement->overrunBitSet->clear();
|
newElement->overrunBitSet->clear();
|
||||||
monitorLocal->getPVCopyMonitor()->switchBitSets(
|
ml->getPVCopyMonitor()->switchBitSets(
|
||||||
newElement->changedBitSet,newElement->overrunBitSet);
|
newElement->changedBitSet,newElement->overrunBitSet);
|
||||||
queue.setUsed(monitorElement);
|
queue.setUsed(monitorElement);
|
||||||
monitorElement = newElement;
|
monitorElement = newElement;
|
||||||
@ -494,13 +519,11 @@ bool RealQueue::dataChanged()
|
|||||||
|
|
||||||
MonitorElementPtr RealQueue::poll()
|
MonitorElementPtr RealQueue::poll()
|
||||||
{
|
{
|
||||||
Lock xx(mutex);
|
|
||||||
return queue.getUsed();
|
return queue.getUsed();
|
||||||
}
|
}
|
||||||
|
|
||||||
void RealQueue::release(MonitorElementPtr const ¤tElement)
|
void RealQueue::release(MonitorElementPtr const ¤tElement)
|
||||||
{
|
{
|
||||||
Lock xx(mutex);
|
|
||||||
queue.releaseUsed(currentElement);
|
queue.releaseUsed(currentElement);
|
||||||
queueIsFull = false;
|
queueIsFull = false;
|
||||||
}
|
}
|
||||||
|
@ -16,6 +16,7 @@
|
|||||||
#include <pv/thread.h>
|
#include <pv/thread.h>
|
||||||
|
|
||||||
#include <pv/channelProviderLocal.h>
|
#include <pv/channelProviderLocal.h>
|
||||||
|
#include <pv/pvCopy.h>
|
||||||
|
|
||||||
|
|
||||||
namespace epics { namespace pvDatabase {
|
namespace epics { namespace pvDatabase {
|
||||||
@ -121,6 +122,11 @@ size_t PVCopy::getCopyOffset(PVRecordFieldPtr const &recordPVField)
|
|||||||
if((recordNode->recordPVField.get())==recordPVField.get()) {
|
if((recordNode->recordPVField.get())==recordPVField.get()) {
|
||||||
return headNode->structureOffset;
|
return headNode->structureOffset;
|
||||||
}
|
}
|
||||||
|
PVStructure * parent = recordPVField->getPVField()->getParent();
|
||||||
|
size_t offsetParent = parent->getFieldOffset();
|
||||||
|
size_t off = recordPVField->getPVField()->getFieldOffset();
|
||||||
|
size_t offdiff = off -offsetParent;
|
||||||
|
if(offdiff<recordNode->nfields) return headNode->structureOffset + offdiff;
|
||||||
return String::npos;
|
return String::npos;
|
||||||
}
|
}
|
||||||
CopyStructureNodePtr node = static_pointer_cast<CopyStructureNode>(headNode);
|
CopyStructureNodePtr node = static_pointer_cast<CopyStructureNode>(headNode);
|
||||||
@ -977,10 +983,10 @@ void PVCopyMonitor::startMonitoring(
|
|||||||
this->changeBitSet = changeBitSet;
|
this->changeBitSet = changeBitSet;
|
||||||
this->overrunBitSet = overrunBitSet;
|
this->overrunBitSet = overrunBitSet;
|
||||||
isGroupPut = false;
|
isGroupPut = false;
|
||||||
pvRecord->addListener(getPtrSelf());
|
|
||||||
addListener(headNode);
|
|
||||||
pvRecord->lock();
|
pvRecord->lock();
|
||||||
try {
|
try {
|
||||||
|
pvRecord->addListener(getPtrSelf());
|
||||||
|
addListener(headNode);
|
||||||
changeBitSet->clear();
|
changeBitSet->clear();
|
||||||
overrunBitSet->clear();
|
overrunBitSet->clear();
|
||||||
changeBitSet->set(0);
|
changeBitSet->set(0);
|
||||||
|
Reference in New Issue
Block a user