fixed bugs in implementation of montor; connection problems still exist

This commit is contained in:
Marty Kraimer
2014-08-07 08:02:53 -04:00
parent d6aa03815e
commit 9551b0e4c6
10 changed files with 152 additions and 224 deletions

View File

@ -182,14 +182,18 @@ void ArrayPerformanceThread::run()
nSinceLastReport = 0;
}
++nSinceLastReport;
shared_vector<int64> xxx(arrayPerformance->size,value++);
shared_vector<const int64> data(freeze(xxx));
arrayPerformance->lock();
try {
arrayPerformance->beginGroupPut();
arrayPerformance->pvValue->replace(data);
arrayPerformance->process();
arrayPerformance->endGroupPut();
if(arrayPerformance->getTraceLevel()>1) {
cout << "arrayPerformance size " << arrayPerformance->size;
cout << " value " << value +1 << endl;
}
shared_vector<int64> xxx(arrayPerformance->size,value++);
shared_vector<const int64> data(freeze(xxx));
arrayPerformance->beginGroupPut();
arrayPerformance->pvValue->replace(data);
arrayPerformance->process();
arrayPerformance->endGroupPut();
} catch(...) {
arrayPerformance->unlock();
throw;

View File

@ -13,4 +13,4 @@ cd ${TOP}/iocBoot/${IOC}
iocInit()
startPVAClient
startPVAServer
exampleLinkCreateRecord exampleLinkRemote pvAccess doubleArray
exampleLinkCreateRecord exampleLink pvAccess doubleArray

View File

@ -147,6 +147,7 @@ void ExampleLink::channelGetConnect(
{
this->status = status;
this->channelGet = channelGet;
getPVStructure = getPVDataCreate()->createPVStructure(structure);
event.signal();
}
@ -157,7 +158,7 @@ void ExampleLink::getDone(
BitSetPtr const & bitSet)
{
this->status = status;
getPVStructure = pvStructure;
convert->copyStructure(pvStructure,getPVStructure);
this->bitSet = bitSet;
event.signal();
}

View File

@ -20,6 +20,7 @@
#include <pv/standardField.h>
#include <pv/standardPVField.h>
#include <pv/recordList.h>
#include <pv/powerSupply.h>
#include <pv/traceRecord.h>
#include <pv/channelProviderLocal.h>
@ -48,7 +49,10 @@ int main(int argc,char *argv[])
pvRecord = TraceRecord::create(recordName);
result = master->addRecord(pvRecord);
if(!result) cout<< "record " << recordName << " not added" << endl;
pvRecord.reset();
recordName = "laptoprecordListPGRPC";
pvRecord = RecordListRecord::create(recordName);
result = master->addRecord(pvRecord);
if(!result) cout<< "record " << recordName << " not added" << endl;
ServerContext::shared_pointer pvaServer =
startPVAServer(PVACCESS_ALL_PROVIDERS,0,true,true);
cout << "powerSupply\n";

View File

@ -48,7 +48,7 @@ int main(int argc,char *argv[])
pvRecord = TraceRecord::create(recordName);
result = master->addRecord(pvRecord);
if(!result) cout<< "record " << recordName << " not added" << endl;
recordName = "recordListPGRPC";
recordName = "laptoprecordListPGRPC";
pvRecord = RecordListRecord::create(recordName);
result = master->addRecord(pvRecord);
if(!result) cout<< "record " << recordName << " not added" << endl;

View File

@ -33,6 +33,7 @@
#include <pv/pvData.h>
#include <pv/pvAccess.h>
#include <pv/pvDatabase.h>
#include <pv/recordList.h>
#include <pv/exampleServer.h>
using namespace epics::pvData;
@ -50,10 +51,19 @@ static const iocshFuncDef exampleServerFuncDef = {
"exampleServerCreateRecord", 1, testArgs};
static void exampleServerCallFunc(const iocshArgBuf *args)
{
PVDatabasePtr master = PVDatabase::getMaster();
char *recordName = args[0].sval;
ExampleServerPtr record = ExampleServer::create(recordName);
bool result = PVDatabase::getMaster()->addRecord(record);
bool result = master->addRecord(record);
if(!result) cout << "recordname" << " not added" << endl;
PVRecordPtr pvRecord = RecordListRecord::create(
"laptoprecordListPGRPC");
if(pvRecord==NULL) {
cout << "RecordListRecord::create failed" << endl;
} else {
result = master->addRecord(pvRecord);
if(!result) cout<< "record " << recordName << " not added" << endl;
}
}
static void exampleServerRegister(void)

View File

@ -30,6 +30,7 @@ using std::string;
namespace epics { namespace pvDatabase {
static MonitorPtr nullMonitor;
static MonitorElementPtr NULLMonitorElement;
static Status wasDestroyedStatus(Status::STATUSTYPE_ERROR,"was destroyed");
@ -37,52 +38,9 @@ static Status wasDestroyedStatus(Status::STATUSTYPE_ERROR,"was destroyed");
static ConvertPtr convert = getConvert();
class ElementQueue;
typedef std::tr1::shared_ptr<ElementQueue> ElementQueuePtr;
class MultipleElementQueue;
typedef std::tr1::shared_ptr<MultipleElementQueue> MultipleElementQueuePtr;
class ElementQueue :
public Monitor,
public std::tr1::enable_shared_from_this<ElementQueue>
{
public:
POINTER_DEFINITIONS(ElementQueue);
virtual ~ElementQueue(){}
virtual bool dataChanged() = 0;
protected:
ElementQueuePtr getPtrSelf()
{
return shared_from_this();
}
};
typedef Queue<MonitorElement> MonitorElementQueue;
typedef std::tr1::shared_ptr<MonitorElementQueue> MonitorElementQueuePtr;
class MultipleElementQueue :
public ElementQueue
{
public:
POINTER_DEFINITIONS(MultipleElementQueue);
virtual ~MultipleElementQueue(){}
MultipleElementQueue(
MonitorLocalPtr const &monitorLocal,
MonitorElementQueuePtr const &queue,
size_t nfields);
virtual void destroy(){}
virtual Status start();
virtual Status stop();
virtual bool dataChanged();
virtual MonitorElementPtr poll();
virtual void release(MonitorElementPtr const &monitorElement);
private:
std::tr1::weak_ptr<MonitorLocal> monitorLocal;
MonitorElementQueuePtr queue;
MonitorElementPtr activeElement;
bool queueIsFull;
};
class MonitorLocal :
@ -97,9 +55,10 @@ public:
virtual Status stop();
virtual MonitorElementPtr poll();
virtual void destroy();
virtual void dataChanged();
virtual void unlisten();
virtual void release(MonitorElementPtr const & monitorElement);
MonitorElementPtr getActiveElement();
MonitorElementPtr releaseActiveElement();
void unlisten();
bool init(PVStructurePtr const & pvRequest);
MonitorLocal(
MonitorRequester::shared_pointer const & channelMonitorRequester,
@ -116,7 +75,10 @@ private:
bool isDestroyed;
bool firstMonitor;
PVCopyPtr pvCopy;
ElementQueuePtr queue;
// MultipleElementQueuePtr queue;
MonitorElementQueuePtr queue;
MonitorElementPtr activeElement;
bool queueIsFull;
PVCopyMonitorPtr pvCopyMonitor;
Mutex mutex;
};
@ -161,69 +123,93 @@ void MonitorLocal::destroy()
Status MonitorLocal::start()
{
Lock xx(mutex);
if(pvRecord->getTraceLevel()>0)
{
cout << "MonitorLocal::start() " << endl;
}
Lock xx(mutex);
if(isDestroyed) return wasDestroyedStatus;
firstMonitor = true;
return queue->start();
queue->clear();
queueIsFull = false;
activeElement = queue->getFree();
activeElement->changedBitSet->clear();
activeElement->overrunBitSet->clear();
pvCopyMonitor->startMonitoring();
return Status::Ok;
}
Status MonitorLocal::stop()
{
pvCopyMonitor->stopMonitoring();
{
Lock xx(mutex);
if(pvRecord->getTraceLevel()>0){
cout << "MonitorLocal::stop() " << endl;
}
if(!isDestroyed) queue->stop();
if(pvRecord->getTraceLevel()>0){
cout << "MonitorLocal::stop() " << endl;
}
Lock xx(mutex);
pvCopyMonitor->stopMonitoring();
return Status::Ok;
}
MonitorElementPtr MonitorLocal::poll()
{
Lock xx(mutex);
if(pvRecord->getTraceLevel()>1)
{
cout << "MonitorLocal::poll() " << endl;
}
Lock xx(mutex);
if(isDestroyed) {
return NULLMonitorElement;
}
return queue->poll();
return queue->getUsed();
}
void MonitorLocal::release(MonitorElementPtr const & monitorElement)
{
Lock xx(mutex);
if(pvRecord->getTraceLevel()>1)
{
cout << "MonitorLocal::release() " << endl;
}
Lock xx(mutex);
if(isDestroyed) {
return;
}
queue->release(monitorElement);
queue->releaseUsed(monitorElement);
queueIsFull = false;
}
void MonitorLocal::dataChanged()
MonitorElementPtr MonitorLocal::getActiveElement()
{
if(pvRecord->getTraceLevel()>1)
if(pvRecord->getTraceLevel()>0)
{
cout << "MonitorLocal::dataChanged() " "firstMonitor " << firstMonitor << endl;
cout << "MonitorLocal::getActiveElement() " << endl;
}
Lock xx(mutex);
return activeElement;
}
MonitorElementPtr MonitorLocal::releaseActiveElement()
{
if(pvRecord->getTraceLevel()>0)
{
cout << "MonitorLocal::releaseActiveElement() " << endl;
}
bool getMonitorEvent = false;
{
Lock xx(mutex);
if(isDestroyed) return;
getMonitorEvent = queue->dataChanged();
firstMonitor = false;
if(queueIsFull) return activeElement;
pvCopy->updateCopyFromBitSet(activeElement->pvStructurePtr,activeElement->changedBitSet);
BitSetUtil::compress(activeElement->changedBitSet,activeElement->pvStructurePtr);
BitSetUtil::compress(activeElement->overrunBitSet,activeElement->pvStructurePtr);
queue->setUsed(activeElement);
activeElement = queue->getFree();
if(activeElement==NULL) {
throw std::logic_error("MultipleLocal::releaseActiveElement logic error");
}
if(queue->getNumberFree()==0) queueIsFull = true;
activeElement->changedBitSet->clear();
activeElement->overrunBitSet->clear();
}
if(getMonitorEvent) monitorRequester->monitorEvent(getPtrSelf());
monitorRequester->monitorEvent(getPtrSelf());
return activeElement;
}
void MonitorLocal::unlisten()
@ -292,11 +278,7 @@ bool MonitorLocal::init(PVStructurePtr const & pvRequest)
new MonitorElement(pvStructure));
monitorElementArray.push_back(monitorElement);
}
MonitorElementQueuePtr elementQueue(new MonitorElementQueue(monitorElementArray));
queue = MultipleElementQueuePtr(new MultipleElementQueue(
getPtrSelf(),
elementQueue,
nfields));
queue = MonitorElementQueuePtr(new MonitorElementQueue(monitorElementArray));
// MARTY MUST IMPLEMENT algorithm
monitorRequester->monitorConnect(
Status::Ok,
@ -345,75 +327,6 @@ MonitorPtr MonitorFactory::createMonitor(
}
MultipleElementQueue::MultipleElementQueue(
MonitorLocalPtr const &monitorLocal,
MonitorElementQueuePtr const &queue,
size_t nfields)
: monitorLocal(monitorLocal),
queue(queue),
queueIsFull(false)
{
}
Status MultipleElementQueue::start()
{
queue->clear();
queueIsFull = false;
activeElement = queue->getFree();
activeElement->changedBitSet->clear();
activeElement->overrunBitSet->clear();
MonitorLocalPtr ml = monitorLocal.lock();
if(ml==NULL) return wasDestroyedStatus;
ml->getPVCopyMonitor()->setMonitorElement(activeElement);
ml->getPVCopyMonitor()->startMonitoring();
return Status::Ok;
}
Status MultipleElementQueue::stop()
{
return Status::Ok;
}
bool MultipleElementQueue::dataChanged()
{
MonitorLocalPtr ml = monitorLocal.lock();
if(ml==NULL) return false;
if(queueIsFull) return false;
ml->getPVCopy()->updateCopyFromBitSet(
activeElement->pvStructurePtr,activeElement->changedBitSet);
BitSetUtil::compress(activeElement->changedBitSet,activeElement->pvStructurePtr);
BitSetUtil::compress(activeElement->overrunBitSet,activeElement->pvStructurePtr);
queue->setUsed(activeElement);
activeElement = queue->getFree();
if(activeElement==NULL) {
throw std::logic_error("MultipleElementQueue::dataChanged() logic error");
}
if(queue->getNumberFree()==0) queueIsFull = true;
activeElement->changedBitSet->clear();
activeElement->overrunBitSet->clear();
ml->getPVCopyMonitor()->setMonitorElement(activeElement);
return true;
}
MonitorElementPtr MultipleElementQueue::poll()
{
MonitorLocalPtr ml = monitorLocal.lock();
if(ml==NULL) return MonitorElementPtr();
MonitorElementPtr monitorElement = queue->getUsed();
if(monitorElement==NULL) return monitorElement;
ml->getPVCopyMonitor()->monitorDone(monitorElement);
return monitorElement;
}
void MultipleElementQueue::release(MonitorElementPtr const &element)
{
queue->releaseUsed(element);
if(!queueIsFull) return;
queueIsFull = false;
if(!activeElement->changedBitSet->isEmpty()) {
dataChanged();
}
}
MonitorFactoryPtr getMonitorFactory()
{

View File

@ -137,6 +137,10 @@ void PVCopyMonitor::startMonitoring()
{
(*iter)->monitorPlugin->startMonitoring();
}
monitorElement = pvCopyMonitorRequester->getActiveElement();
if(monitorElement==NULL) {
throw std::logic_error("getActiveElement should not return null");
}
pvRecord->lock();
try {
pvRecord->addListener(getPtrSelf());
@ -144,7 +148,7 @@ void PVCopyMonitor::startMonitoring()
monitorElement->changedBitSet->clear();
monitorElement->overrunBitSet->clear();
monitorElement->changedBitSet->set(0);
pvCopyMonitorRequester->dataChanged();
monitorElement = pvCopyMonitorRequester->releaseActiveElement();
pvRecord->unlock();
} catch(...) {
pvRecord->unlock();
@ -174,29 +178,6 @@ void PVCopyMonitor::stopMonitoring()
}
void PVCopyMonitor::setMonitorElement(MonitorElementPtr const &xxx)
{
if(pvRecord->getTraceLevel()>0)
{
cout << "PVCopyMonitor::setMonitorElement()" << endl;
}
monitorElement = xxx;
}
void PVCopyMonitor::monitorDone(MonitorElementPtr const &monitorElement)
{
if(pvRecord->getTraceLevel()>0)
{
cout << "PVCopyMonitor::monitorDone()" << endl;
}
std::list<PVCopyMonitorFieldNodePtr>::iterator iter;
for (iter = monitorFieldNodeList.begin();iter!=monitorFieldNodeList.end();++iter)
{
PVCopyMonitorFieldNodePtr fieldNode = *iter;
MonitorPluginPtr monitorPlugin = fieldNode->monitorPlugin;
monitorPlugin->monitorDone(monitorElement);
}
}
void PVCopyMonitor::detach(PVRecordPtr const & pvRecord)
{
@ -208,27 +189,33 @@ void PVCopyMonitor::detach(PVRecordPtr const & pvRecord)
void PVCopyMonitor::dataPut(PVRecordFieldPtr const & pvRecordField)
{
if(pvRecord->getTraceLevel()>0)
if(pvRecord->getTraceLevel()>1)
{
cout << "PVCopyMonitor::dataPut(pvRecordField)" << endl;
}
size_t offset = pvCopy->getCopyOffset(pvRecordField->getPVField());
BitSetPtr const &changedBitSet = monitorElement->changedBitSet;
BitSetPtr const &overrunBitSet = monitorElement->overrunBitSet;
bool isSet = changedBitSet->get(offset);
changedBitSet->set(offset);
if(isSet) overrunBitSet->set(offset);
MonitorPluginPtr monitorPlugin = getMonitorPlugin(offset);
bool causeMonitor = true;
if(monitorPlugin!=NULL) {
causeMonitor = monitorPlugin->causeMonitor(
pvRecordField->getPVField(),
pvRecord->getPVRecordStructure()->getPVStructure(),
monitorElement);
{
Lock xx(mutex);
size_t offset = pvCopy->getCopyOffset(pvRecordField->getPVField());
BitSetPtr const &changedBitSet = monitorElement->changedBitSet;
BitSetPtr const &overrunBitSet = monitorElement->overrunBitSet;
bool isSet = changedBitSet->get(offset);
changedBitSet->set(offset);
if(isSet) overrunBitSet->set(offset);
MonitorPluginPtr monitorPlugin = getMonitorPlugin(offset);
if(monitorPlugin!=NULL) {
causeMonitor = monitorPlugin->causeMonitor(
pvRecordField->getPVField(),
pvRecord->getPVRecordStructure()->getPVStructure(),
monitorElement);
}
if(causeMonitor) dataChanged = true;
}
if(causeMonitor) {
if(!isGroupPut) pvCopyMonitorRequester->dataChanged();
dataChanged = true;
if(!isGroupPut) {
monitorElement = pvCopyMonitorRequester->releaseActiveElement();
dataChanged = false;
}
}
}
@ -236,31 +223,37 @@ void PVCopyMonitor::dataPut(
PVRecordStructurePtr const & requested,
PVRecordFieldPtr const & pvRecordField)
{
if(pvRecord->getTraceLevel()>0)
if(pvRecord->getTraceLevel()>1)
{
cout << "PVCopyMonitor::dataPut(requested,pvRecordField)" << endl;
}
BitSetPtr const &changedBitSet = monitorElement->changedBitSet;
BitSetPtr const &overrunBitSet = monitorElement->overrunBitSet;
size_t offsetCopyRequested = pvCopy->getCopyOffset(
requested->getPVField());
size_t offset = offsetCopyRequested
+ (pvRecordField->getPVField()->getFieldOffset()
- requested->getPVField()->getFieldOffset());
bool isSet = changedBitSet->get(offset);
changedBitSet->set(offset);
if(isSet) overrunBitSet->set(offset);
MonitorPluginPtr monitorPlugin = getMonitorPlugin(offsetCopyRequested);
bool causeMonitor = true;
if(monitorPlugin!=NULL) {
causeMonitor = monitorPlugin->causeMonitor(
requested->getPVField(),
pvRecord->getPVRecordStructure()->getPVStructure(),
monitorElement);
{
Lock xx(mutex);
BitSetPtr const &changedBitSet = monitorElement->changedBitSet;
BitSetPtr const &overrunBitSet = monitorElement->overrunBitSet;
size_t offsetCopyRequested = pvCopy->getCopyOffset(
requested->getPVField());
size_t offset = offsetCopyRequested
+ (pvRecordField->getPVField()->getFieldOffset()
- requested->getPVField()->getFieldOffset());
bool isSet = changedBitSet->get(offset);
changedBitSet->set(offset);
if(isSet) overrunBitSet->set(offset);
MonitorPluginPtr monitorPlugin = getMonitorPlugin(offsetCopyRequested);
if(monitorPlugin!=NULL) {
causeMonitor = monitorPlugin->causeMonitor(
requested->getPVField(),
pvRecord->getPVRecordStructure()->getPVStructure(),
monitorElement);
}
if(causeMonitor) dataChanged = true;
}
if(causeMonitor) {
if(!isGroupPut) pvCopyMonitorRequester->dataChanged();
dataChanged = true;
if(!isGroupPut) {
monitorElement = pvCopyMonitorRequester->releaseActiveElement();
dataChanged = false;
}
}
}
@ -270,8 +263,11 @@ void PVCopyMonitor::beginGroupPut(PVRecordPtr const & pvRecord)
{
cout << "PVCopyMonitor::beginGroupPut()" << endl;
}
isGroupPut = true;
dataChanged = false;
{
Lock xx(mutex);
isGroupPut = true;
dataChanged = false;
}
std::list<PVCopyMonitorFieldNodePtr>::iterator iter;
for (iter = monitorFieldNodeList.begin();
iter!=monitorFieldNodeList.end();
@ -287,15 +283,18 @@ void PVCopyMonitor::endGroupPut(PVRecordPtr const & pvRecord)
{
cout << "PVCopyMonitor::endGroupPut() dataChanged " << dataChanged << endl;
}
isGroupPut = false;
std::list<PVCopyMonitorFieldNodePtr>::iterator iter;
for (iter = monitorFieldNodeList.begin();iter!=monitorFieldNodeList.end();++iter)
{
(*iter)->monitorPlugin->endGroupPut();
}
{
Lock xx(mutex);
isGroupPut = false;
}
if(dataChanged) {
dataChanged = false;
pvCopyMonitorRequester->dataChanged();
monitorElement = pvCopyMonitorRequester->releaseActiveElement();
dataChanged = false;
}
}
@ -304,6 +303,4 @@ void PVCopyMonitor::unlisten(PVRecordPtr const & pvRecord)
pvCopyMonitorRequester->unlisten();
}
}}

View File

@ -60,8 +60,6 @@ public:
virtual void destroy();
void startMonitoring();
void stopMonitoring();
void setMonitorElement(epics::pvData::MonitorElementPtr const &monitorElement);
void monitorDone(epics::pvData::MonitorElementPtr const &monitorElement);
// following are PVListener methods
virtual void detach(PVRecordPtr const & pvRecord);
virtual void dataPut(PVRecordFieldPtr const & pvRecordField);
@ -100,7 +98,8 @@ class epicsShareClass PVCopyMonitorRequester
public:
POINTER_DEFINITIONS(PVCopyMonitorRequester);
virtual ~PVCopyMonitorRequester() {}
virtual void dataChanged() = 0;
virtual epics::pvData::MonitorElementPtr getActiveElement() = 0;
virtual epics::pvData::MonitorElementPtr releaseActiveElement() = 0;
virtual void unlisten() = 0;
};

View File

@ -31,7 +31,7 @@ RecordListRecordPtr RecordListRecord::create(
endNested()->
addNestedStructure("result") ->
add("status",pvString) ->
addArray("name",pvString) ->
addArray("names",pvString) ->
endNested()->
createStructure();
PVStructurePtr pvStructure = pvDataCreate->createPVStructure(topStructure);
@ -68,13 +68,13 @@ bool RecordListRecord::init()
if(regularExpression.get()==NULL) return false;
status = pvStructure->getStringField("result.status");
if(status.get()==NULL) return false;
PVFieldPtr pvField = pvStructure->getSubField("result.name");
PVFieldPtr pvField = pvStructure->getSubField("result.names");
if(pvField.get()==NULL) {
std::cerr << "no result.name" << std::endl;
std::cerr << "no result.names" << std::endl;
return false;
}
name = static_pointer_cast<PVStringArray>(
pvStructure->getScalarArrayField("result.name",pvString));
pvStructure->getScalarArrayField("result.names",pvString));
if(name.get()==NULL) return false;
return true;
}