10 #include <epicsThread.h> 11 #include <epicsGuard.h> 15 #include <pv/standardField.h> 16 #include <pv/standardPVField.h> 17 #include <pv/timeStamp.h> 18 #include <pv/pvTimeStamp.h> 20 #include <pv/pvAlarm.h> 21 #include <pv/pvAccess.h> 22 #include <pv/serverContext.h> 23 #include <pv/rpcService.h> 25 #include <epicsExport.h> 26 #define epicsExportSharedSymbols 32 namespace epics {
namespace pvDatabase {
35 std::string
const & recordName,
double delay,
36 int asLevel,std::string
const & asGroup)
38 FieldCreatePtr fieldCreate = getFieldCreate();
39 PVDataCreatePtr pvDataCreate = getPVDataCreate();
40 StructureConstPtr topStructure = fieldCreate->createFieldBuilder()->
41 addNestedStructure(
"argument")->
42 add(
"command",pvString)->
43 add(
"recordName",pvString)->
45 addNestedStructure(
"result") ->
46 add(
"status",pvString) ->
49 PVStructurePtr pvStructure = pvDataCreate->createPVStructure(topStructure);
52 if(!pvRecord->init()) pvRecord.reset();
57 PvdbcrProcessRecord::PvdbcrProcessRecord(
58 std::string
const & recordName,
59 epics::pvData::PVStructurePtr
const & pvStructure,
double delay,
60 int asLevel,std::string
const & asGroup)
61 :
PVRecord(recordName,pvStructure,asLevel,asGroup),
63 pvDatabase(PVDatabase::getMaster())
67 bool PvdbcrProcessRecord::init()
70 PVStructurePtr pvStructure = getPVStructure();
71 pvCommand = pvStructure->getSubField<PVString>(
"argument.command");
72 pvRecordName = pvStructure->getSubField<PVString>(
"argument.recordName");
73 if(!pvRecordName)
return false;
74 pvResult = pvStructure->getSubField<PVString>(
"result.status");
75 if(!pvResult)
return false;
80 void PvdbcrProcessRecord::setDelay(
double delay) {this->delay = delay;}
82 double PvdbcrProcessRecord::getDelay() {
return delay;}
84 void PvdbcrProcessRecord::startThread()
89 epicsThreadGetStackSize(epicsThreadStackSmall),
90 epicsThreadPriorityLow));
94 void PvdbcrProcessRecord::stop()
100 void PvdbcrProcessRecord::process()
102 string recordName = pvRecordName->get();
103 string command = pvCommand->get();
104 if(command.compare(
"add")==0) {
105 epicsGuard<epics::pvData::Mutex> guard(mutex);
106 std::map<std::string,PVRecordPtr>::iterator iter = pvRecordMap.find(recordName);
107 if(iter!=pvRecordMap.end()) {
108 pvResult->put(recordName +
" already present");
111 PVRecordPtr pvRecord = pvDatabase->findRecord(recordName);
113 pvResult->put(recordName +
" not in pvDatabase");
116 pvRecordMap.insert(PVRecordMap::value_type(recordName,pvRecord));
117 pvResult->put(
"success");
119 }
else if(command.compare(
"remove")==0) {
120 epicsGuard<epics::pvData::Mutex> guard(mutex);
121 std::map<std::string,PVRecordPtr>::iterator iter = pvRecordMap.find(recordName);
122 if(iter==pvRecordMap.end()) {
123 pvResult->put(recordName +
" not found");
126 pvRecordMap.erase(iter);
127 pvResult->put(
"success");
130 pvResult->put(command +
" not a valid command: only add and remove are valid");
135 void PvdbcrProcessRecord::run()
138 if(runStop.tryWait()) {
142 if(delay>0.0) epicsThreadSleep(delay);
143 epicsGuard<epics::pvData::Mutex> guard(mutex);
144 PVRecordMap::iterator iter;
145 for(iter = pvRecordMap.begin(); iter!=pvRecordMap.end(); ++iter) {
148 pvRecord->beginGroupPut();
151 }
catch (std::exception& ex) {
152 std::cout <<
"record " << pvRecord->getRecordName() <<
"exception " << ex.what() <<
"\n";
154 std::cout<<
"record " << pvRecord->getRecordName() <<
" process exception\n";
156 pvRecord->endGroupPut();
163 static const iocshArg arg0 = {
"recordName", iocshArgString };
164 static const iocshArg arg1 = {
"delay", iocshArgDouble };
165 static const iocshArg arg2 = {
"asLevel", iocshArgInt };
166 static const iocshArg arg3 = {
"asGroup", iocshArgString };
167 static const iocshArg *args[] = {&arg0,&arg1,&arg2,&arg3};
169 static const iocshFuncDef pvdbcrProcessRecordFuncDef = {
"pvdbcrProcessRecord", 4,args};
171 static void pvdbcrProcessRecordCallFunc(
const iocshArgBuf *args)
173 char *sval = args[0].sval;
175 throw std::runtime_error(
"pvdbcrProcessRecord recordName not specified");
177 string recordName = string(sval);
178 double delay = args[1].dval;
179 if(delay<0.0) delay = 1.0;
180 int asLevel = args[2].ival;
181 string asGroup(
"DEFAULT");
184 asGroup = string(sval);
188 record->setAsLevel(asLevel);
189 record->setAsGroup(asGroup);
191 bool result = master->addRecord(record);
192 if(!result) cout <<
"recordname " << recordName <<
" not added" << endl;
195 static void pvdbcrProcessRecord(
void)
197 static int firstTime = 1;
200 iocshRegister(&pvdbcrProcessRecordFuncDef, pvdbcrProcessRecordCallFunc);
PvdbcrProcessRecord A record that processes other records in the master database. ...
epicsExportRegistrar(pvdbcrProcessRecord)
Base interface for a PVRecord.
std::tr1::shared_ptr< PVDatabase > PVDatabasePtr
static PVDatabasePtr getMaster()
Get the master database.
std::tr1::shared_ptr< PVRecord > PVRecordPtr
std::tr1::shared_ptr< PvdbcrProcessRecord > PvdbcrProcessRecordPtr
static PvdbcrProcessRecordPtr create(std::string const &recordName, double delay=1.0, int asLevel=0, std::string const &asGroup=std::string("DEFAULT"))
Create a record.
std::tr1::shared_ptr< epicsThread > EpicsThreadPtr