12 #include <epicsThread.h> 22 #include <pv/pvType.h> 23 #include <pv/pvData.h> 24 #include <pv/pvTimeStamp.h> 25 #include <pv/timeStamp.h> 26 #include <pv/rpcService.h> 27 #include <pv/pvAccess.h> 28 #include <pv/status.h> 29 #include <pv/serverContext.h> 31 #define epicsExportSharedSymbols 36 using std::tr1::static_pointer_cast;
41 namespace epics {
namespace pvDatabase {
44 std::string
const & recordName,
double delay)
46 FieldCreatePtr fieldCreate = getFieldCreate();
47 PVDataCreatePtr pvDataCreate = getPVDataCreate();
48 StructureConstPtr topStructure = fieldCreate->createFieldBuilder()->
49 addNestedStructure(
"argument")->
50 add(
"command",pvString)->
51 add(
"recordName",pvString)->
53 addNestedStructure(
"result") ->
54 add(
"status",pvString) ->
57 PVStructurePtr pvStructure = pvDataCreate->createPVStructure(topStructure);
60 if(!pvRecord->init()) pvRecord.reset();
64 void ProcessRecord::startThread()
69 epicsThreadGetStackSize(epicsThreadStackSmall),
70 epicsThreadPriorityLow));
74 void ProcessRecord::stop()
81 ProcessRecord::ProcessRecord(
82 std::string
const & recordName,
83 epics::pvData::PVStructurePtr
const & pvStructure,
double delay)
86 pvDatabase(PVDatabase::getMaster())
90 bool ProcessRecord::init()
93 PVStructurePtr pvStructure = getPVStructure();
94 pvCommand = pvStructure->getSubField<PVString>(
"argument.command");
95 pvRecordName = pvStructure->getSubField<PVString>(
"argument.recordName");
96 if(!pvRecordName)
return false;
97 pvResult = pvStructure->getSubField<PVString>(
"result.status");
98 if(!pvResult)
return false;
103 void ProcessRecord::process()
105 string recordName = pvRecordName->get();
106 string command = pvCommand->get();
107 if(command.compare(
"add")==0) {
108 epicsGuard<epics::pvData::Mutex> guard(mutex);
109 std::map<std::string,PVRecordPtr>::iterator iter = pvRecordMap.find(recordName);
110 if(iter!=pvRecordMap.end()) {
111 pvResult->put(recordName +
" already present");
114 PVRecordPtr pvRecord = pvDatabase->findRecord(recordName);
116 pvResult->put(recordName +
" not in pvDatabase");
119 pvRecordMap.insert(PVRecordMap::value_type(recordName,pvRecord));
120 pvResult->put(
"success");
122 }
else if(command.compare(
"remove")==0) {
123 epicsGuard<epics::pvData::Mutex> guard(mutex);
124 std::map<std::string,PVRecordPtr>::iterator iter = pvRecordMap.find(recordName);
125 if(iter==pvRecordMap.end()) {
126 pvResult->put(recordName +
" not found");
129 pvRecordMap.erase(iter);
130 pvResult->put(
"success");
133 pvResult->put(command +
" not a valid command: only add and remove are valid");
138 void ProcessRecord::run()
141 if(runStop.tryWait()) {
145 if(delay>0.0) epicsThreadSleep(delay);
146 epicsGuard<epics::pvData::Mutex> guard(mutex);
147 PVRecordMap::iterator iter;
148 for(iter = pvRecordMap.begin(); iter!=pvRecordMap.end(); ++iter) {
151 pvRecord->beginGroupPut();
154 }
catch (std::exception& ex) {
155 std::cout <<
"record " << pvRecord->getRecordName() <<
"exception " << ex.what() <<
"\n";
157 std::cout<<
"record " << pvRecord->getRecordName() <<
" process exception\n";
159 pvRecord->endGroupPut();
Base interface for a PVRecord.
std::tr1::shared_ptr< PVRecord > PVRecordPtr
Process another record in the same database.
std::tr1::shared_ptr< ProcessRecord > ProcessRecordPtr
std::tr1::shared_ptr< epicsThread > EpicsThreadPtr