more code implemented. See pvDatabaseCPP.html for details

This commit is contained in:
Marty Kraimer
2013-04-18 15:16:26 -04:00
parent 124d28d33e
commit 26c977c0ae
16 changed files with 1725 additions and 201 deletions

View File

@@ -13,6 +13,8 @@
#include <pv/pvDatabase.h>
#include <pv/standardPVField.h>
#include <pv/timeStamp.h>
#include <pv/pvTimeStamp.h>
namespace epics { namespace pvDatabase {
@@ -27,20 +29,23 @@ public:
POINTER_DEFINITIONS(ExampleCounter);
static ExampleCounterPtr create(
epics::pvData::String const & recordName);
virtual ~ExampleCounter(){}
virtual ~ExampleCounter();
virtual void destroy();
virtual bool init();
virtual void process();
private:
ExampleCounter(epics::pvData::String const & recordName,
epics::pvData::PVStructurePtr const & pvStructure);
epics::pvData::PVLongPtr pvValue;
epics::pvData::PVTimeStamp pvTimeStamp;
epics::pvData::TimeStamp timeStamp;
};
ExampleCounterPtr ExampleCounter::create(
epics::pvData::String const & recordName)
{
epics::pvData::PVStructurePtr pvStructure =
epics::pvData::getStandardPVField()->scalar(epics::pvData::pvLong,"timeStamp");
epics::pvData::getStandardPVField()->scalar(epics::pvData::pvLong,"timeStamp,alarm");
ExampleCounterPtr pvRecord(
new ExampleCounter(recordName,pvStructure));
if(!pvRecord->init()) pvRecord.reset();
@@ -52,6 +57,17 @@ ExampleCounter::ExampleCounter(
epics::pvData::PVStructurePtr const & pvStructure)
: PVRecord(recordName,pvStructure)
{
pvTimeStamp.attach(pvStructure->getSubField("timeStamp"));
}
ExampleCounter::~ExampleCounter()
{
destroy();
}
void ExampleCounter::destroy()
{
PVRecord::destroy();
}
bool ExampleCounter::init()
@@ -67,6 +83,8 @@ bool ExampleCounter::init()
void ExampleCounter::process()
{
pvValue->put(pvValue->get() + 1.0);
timeStamp.getCurrent();
pvTimeStamp.set(timeStamp);
}
}}

View File

@@ -32,6 +32,7 @@ public:
epics::pvData::String const & recordName,
epics::pvData::PVStructurePtr const & pvStructure);
virtual ~PowerSupplyRecordTest();
virtual void destroy();
virtual bool init();
virtual void process();
void put(double power,double voltage);
@@ -72,6 +73,11 @@ PowerSupplyRecordTest::~PowerSupplyRecordTest()
destroy();
}
void PowerSupplyRecordTest::destroy()
{
PVRecord::destroy();
}
bool PowerSupplyRecordTest::init()
{
initPVRecord();

View File

@@ -18,8 +18,6 @@ using namespace std;
namespace epics { namespace pvDatabase {
PVDatabase::~PVDatabase() {}
PVDatabasePtr PVDatabase::getMaster()
{
static PVDatabasePtr master;
@@ -31,36 +29,98 @@ PVDatabasePtr PVDatabase::getMaster()
return master;
}
PVDatabase::PVDatabase() {}
PVDatabase::PVDatabase()
: thelock(mutex),
isDestroyed(false)
{
thelock.unlock();
}
PVDatabase::~PVDatabase()
{
destroy();
}
void PVDatabase::destroy()
{
lock();
if(isDestroyed) {
unlock();
return;
}
isDestroyed = true;
PVRecordMap::iterator iter;
while(true) {
iter = recordMap.begin();
if(iter==recordMap.end()) break;
PVRecordPtr pvRecord = (*iter).second;
recordMap.erase(iter);
unlock();
if(pvRecord.get()!=NULL) pvRecord->destroy();
lock();
}
}
void PVDatabase::lock() {thelock.lock();}
void PVDatabase::unlock() {thelock.unlock();}
PVRecordPtr PVDatabase::findRecord(String const& recordName)
{
PVRecordMap::iterator iter = recordMap.find(recordName);
if(iter!=recordMap.end()) {
lock_guard();
PVRecordPtr xxx;
if(isDestroyed) return xxx;
PVRecordMap::iterator iter = recordMap.find(recordName);
if(iter!=recordMap.end()) {
return (*iter).second;
}
PVRecordPtr xxx;
return xxx;
}
return xxx;
}
PVStringArrayPtr PVDatabase::getRecordNames()
{
lock_guard();
PVStringArrayPtr pvStringArray = static_pointer_cast<PVStringArray>
(getPVDataCreate()->createPVScalarArray(pvString));
size_t len = recordMap.size();
std::vector<String> names(len);
PVRecordMap::iterator iter;
size_t i = 0;
for(iter = recordMap.begin(); iter!=recordMap.end(); ++iter) {
names[i++] = (*iter).first;
}
pvStringArray->put(0,len,names,0);
return pvStringArray;
}
bool PVDatabase::addRecord(PVRecordPtr const & record)
{
String recordName = record->getRecordName();
PVRecordMap::iterator iter = recordMap.find(recordName);
if(iter!=recordMap.end()) return false;
recordMap.insert(PVRecordMap::value_type(recordName,record));
return true;
lock_guard();
if(isDestroyed) return false;
String recordName = record->getRecordName();
PVRecordMap::iterator iter = recordMap.find(recordName);
if(iter!=recordMap.end()) {
return false;
}
recordMap.insert(PVRecordMap::value_type(recordName,record));
return true;
}
bool PVDatabase::removeRecord(PVRecordPtr const & record)
{
String recordName = record->getRecordName();
PVRecordMap::iterator iter = recordMap.find(recordName);
if(iter!=recordMap.end()) {
recordMap.erase(iter);
return true;
}
return false;
lock();
if(isDestroyed) return false;
String recordName = record->getRecordName();
PVRecordMap::iterator iter = recordMap.find(recordName);
if(iter!=recordMap.end()) {
PVRecordPtr pvRecord = (*iter).second;
recordMap.erase(iter);
unlock();
if(pvRecord.get()!=NULL) pvRecord->destroy();
return true;
}
unlock();
return false;
}
String PVDatabase::getRequesterName()

View File

@@ -118,7 +118,7 @@ public:
* The record will automatically
* be unlocked when control leaves the block that has the call.
*/
inline void lock_guard() { epics::pvData::Lock theLock(mutex); }
inline void lock_guard() { epics::pvData::Lock thelock(mutex); }
/**
* Lock the record.
* Any code must lock while accessing a record.
@@ -488,6 +488,10 @@ public:
* Destructor
*/
virtual ~PVDatabase();
/**
* Destroy the PVDatabase.
*/
virtual void destroy();
/**
* Find a record.
* An empty pointer is returned if the record is not in the database.
@@ -507,6 +511,11 @@ public:
* @return <b>true</b> if record was removed.
*/
bool removeRecord(PVRecordPtr const & record);
/**
* Get the names of all the records in the database.
* @return The names.
*/
epics::pvData::PVStringArrayPtr getRecordNames();
/**
* Virtual method of Requester.
* @return The name.
@@ -523,7 +532,13 @@ public:
epics::pvData::MessageType messageType);
private:
PVDatabase();
void lock();
void unlock();
inline void lock_guard() { epics::pvData::Lock thelock(mutex); }
PVRecordMap recordMap;
epics::pvData::Mutex mutex;
epics::pvData::Lock thelock;
bool isDestroyed;
};

View File

@@ -68,29 +68,29 @@ void PVRecord::destroy()
isDestroyed = true;
std::list<RequesterPtr>::iterator requesterIter;
for (
requesterIter = requesterList.begin();
requesterIter!=requesterList.end();
requesterIter++ ) {
while(true) {
requesterIter = requesterList.begin();
if(requesterIter==requesterList.end()) break;
requesterList.erase(requesterIter);
unlock();
(*requesterIter)->message("record destroyed",fatalErrorMessage);
lock();
}
requesterList.clear();
std::list<PVRecordClientPtr>::iterator clientIter;
for (clientIter = pvRecordClientList.begin();
clientIter!=pvRecordClientList.end();
clientIter++ )
{
while(true) {
clientIter = pvRecordClientList.begin();
if(clientIter==pvRecordClientList.end()) break;
pvRecordClientList.erase(clientIter);
unlock();
(*clientIter)->detach(getPtrSelf());
lock();
}
pvRecordClientList.clear();
pvListenerList.clear();
pvRecordStructure->destroy();
pvRecordStructure.reset();
convert.reset();
pvStructure.reset();
unlock();
}
@@ -211,6 +211,10 @@ bool PVRecord::addPVRecordClient(PVRecordClientPtr const & pvRecordClient)
bool PVRecord::removePVRecordClient(PVRecordClientPtr const & pvRecordClient)
{
lock();
if(isDestroyed) {
unlock();
return false;
}
std::list<PVRecordClientPtr>::iterator iter;
for (iter = pvRecordClientList.begin();
iter!=pvRecordClientList.end();

111
src/database/recordList.cpp Normal file
View File

@@ -0,0 +1,111 @@
/* recordListTest.cpp */
/**
* Copyright - See the COPYRIGHT that is included with this distribution.
* EPICS pvData is distributed subject to a Software License Agreement found
* in file LICENSE that is included with this distribution.
*/
/**
* @author mrk
* @date 2013.04.18
*/
#include <pv/recordList.h>
using std::tr1::static_pointer_cast;
using namespace epics::pvData;
using namespace epics::pvAccess;
using namespace std;
namespace epics { namespace pvDatabase {
RecordListRecordPtr RecordListRecord::create(
epics::pvData::String const & recordName)
{
FieldCreatePtr fieldCreate = getFieldCreate();
PVDataCreatePtr pvDataCreate = getPVDataCreate();
StringArray argNames(2);
FieldConstPtrArray argFields(2);
argNames[0] = "database";
argFields[0] = fieldCreate->createScalar(pvString);
argNames[1] = "regularExpression";
argFields[1] = fieldCreate->createScalar(pvString);
StringArray resNames(2);
FieldConstPtrArray resFields(2);
resNames[0] = "status";
resFields[0] = fieldCreate->createScalar(pvString);
resNames[1] = "names";
resFields[1] = fieldCreate->createScalarArray(pvString);
StringArray topNames(2);
FieldConstPtrArray topFields(2);
topNames[0] = "arguments";
topFields[0] = fieldCreate->createStructure(argNames,argFields);
topNames[1] = "result";
topFields[1] = fieldCreate->createStructure(resNames,resFields);
StructureConstPtr topStructure =
fieldCreate->createStructure(topNames,topFields);
PVStructurePtr pvStructure = pvDataCreate->createPVStructure(topStructure);
RecordListRecordPtr pvRecord(
new RecordListRecord(recordName,pvStructure));
if(!pvRecord->init()) pvRecord.reset();
return pvRecord;
}
RecordListRecord::RecordListRecord(
epics::pvData::String const & recordName,
epics::pvData::PVStructurePtr const & pvStructure)
: PVRecord(recordName,pvStructure)
{
}
RecordListRecord::~RecordListRecord()
{
destroy();
}
void RecordListRecord::destroy()
{
PVRecord::destroy();
}
bool RecordListRecord::init()
{
initPVRecord();
PVStructurePtr pvStructure = getPVStructure();
database = pvStructure->getStringField("arguments.database");
if(database.get()==NULL) return false;
regularExpression = pvStructure->getStringField(
"arguments.regularExpression");
if(regularExpression.get()==NULL) return false;
status = pvStructure->getStringField("result.status");
if(status.get()==NULL) return false;
PVFieldPtr pvField = pvStructure->getSubField("result.names");
if(pvField.get()==NULL) {
std::cerr << "no result.names" << std::endl;
return false;
}
names = static_pointer_cast<PVStringArray>(
pvStructure->getScalarArrayField("result.names",pvString));
if(names.get()==NULL) return false;
return true;
}
void RecordListRecord::process()
{
PVStringArrayPtr pvNames = PVDatabase::getMaster()->getRecordNames();
std::vector<String> const & xxx = pvNames->getVector();
size_t n = xxx.size();
names->put(0,n,xxx,0);
String message("");
if(database->get().compare("master")!=0) {
message += " can only access master ";
}
String regEx = regularExpression->get();
if(regEx.compare("")!=0 && regEx.compare(".*")!=0) {
message += " regularExpression not implemented ";
}
status->put(message);
}
}}

44
src/database/recordList.h Normal file
View File

@@ -0,0 +1,44 @@
/* recordListTest.h */
/**
* Copyright - See the COPYRIGHT that is included with this distribution.
* EPICS pvData is distributed subject to a Software License Agreement found
* in file LICENSE that is included with this distribution.
*/
/**
* @author mrk
* @date 2013.04.18
*/
#ifndef RECORDLIST_H
#define RECORDLIST_H
#include <pv/pvDatabase.h>
namespace epics { namespace pvDatabase {
class RecordListRecord;
typedef std::tr1::shared_ptr<RecordListRecord> RecordListRecordPtr;
class RecordListRecord :
public PVRecord
{
public:
POINTER_DEFINITIONS(RecordListRecord);
static RecordListRecordPtr create(
epics::pvData::String const & recordName);
virtual ~RecordListRecord();
virtual void destroy();
virtual bool init();
virtual void process();
private:
RecordListRecord(epics::pvData::String const & recordName,
epics::pvData::PVStructurePtr const & pvStructure);
epics::pvData::PVStringPtr database;
epics::pvData::PVStringPtr regularExpression;
epics::pvData::PVStringPtr status;
epics::pvData::PVStringArrayPtr names;
};
}}
#endif /* RECORDLIST_H */