diff --git a/documentation/RELEASE_NOTES.md b/documentation/RELEASE_NOTES.md index 0f13396..641d4a1 100644 --- a/documentation/RELEASE_NOTES.md +++ b/documentation/RELEASE_NOTES.md @@ -2,10 +2,11 @@ This document summarizes the changes to the module between releases. -## Release 4.6.0 (EPICS 7.0.5.* March 2021) +## Release 4.6.0 (EPICS 7.0.5.* April 2021) * Access Security is now supported. * special has been revised and extended. +* addRecord, removeRecord, processRecord, and traceRecord are replaced by pvdbcr versions. * support is DEPRECATED ## Release 4.5.3 (EPICS 7.0.5 Feb 2021) diff --git a/src/special/Makefile b/src/special/Makefile index 95aa467..fe47e3e 100644 --- a/src/special/Makefile +++ b/src/special/Makefile @@ -2,16 +2,6 @@ SRC_DIRS += $(PVDATABASE_SRC)/special -DBD += traceRecordRegister.dbd -DBD += removeRecordRegister.dbd -DBD += addRecordRegister.dbd -DBD += processRecordRegister.dbd - -LIBSRCS += traceRecordRegister.cpp -LIBSRCS += removeRecordRegister.cpp -LIBSRCS += addRecordRegister.cpp -LIBSRCS += processRecordRegister.cpp - DBD += pvdbcrTraceRecordRegister.dbd DBD += pvdbcrRemoveRecordRegister.dbd DBD += pvdbcrAddRecordRegister.dbd diff --git a/src/special/addRecordRegister.cpp b/src/special/addRecordRegister.cpp deleted file mode 100644 index d39d0cd..0000000 --- a/src/special/addRecordRegister.cpp +++ /dev/null @@ -1,158 +0,0 @@ -/* - * Copyright information and license terms for this software can be - * found in the file LICENSE that is included with the distribution - */ - -/** - * @author mrk - * @date 2021.03.12 - */ -#include -#include -#include -#include -#include -#include -#include -#include -#include - -// The following must be the last include for code exampleLink uses -#include -#define epicsExportSharedSymbols -#include "pv/pvStructureCopy.h" -#include "pv/channelProviderLocal.h" -#include "pv/pvDatabase.h" -using std::tr1::static_pointer_cast; -using namespace epics::pvData; -using namespace epics::pvAccess; -using namespace epics::pvDatabase; -using namespace std; - -class AddRecord; -typedef std::tr1::shared_ptr AddRecordPtr; - - -class epicsShareClass AddRecord : - public PVRecord -{ -private: - AddRecord( - std::string const & recordName, - epics::pvData::PVStructurePtr const & pvStructure); - PVStringPtr pvRecordName; - epics::pvData::PVStringPtr pvResult; -public: - POINTER_DEFINITIONS(AddRecord); - - static AddRecordPtr create( - std::string const & recordName); - virtual bool init(); - virtual void process(); -}; - -AddRecordPtr AddRecord::create( - std::string const & recordName) -{ - FieldCreatePtr fieldCreate = getFieldCreate(); - PVDataCreatePtr pvDataCreate = getPVDataCreate(); - StructureConstPtr topStructure = fieldCreate->createFieldBuilder()-> - addNestedStructure("argument")-> - add("recordName",pvString)-> - addNestedUnion("union") -> - endNested()-> - endNested()-> - addNestedStructure("result") -> - add("status",pvString) -> - endNested()-> - createStructure(); - PVStructurePtr pvStructure = pvDataCreate->createPVStructure(topStructure); - AddRecordPtr pvRecord( - new AddRecord(recordName,pvStructure)); - if(!pvRecord->init()) pvRecord.reset(); - return pvRecord; -} - -AddRecord::AddRecord( - std::string const & recordName, - PVStructurePtr const & pvStructure) -: PVRecord(recordName,pvStructure) -{ -} - -bool AddRecord::init() -{ - initPVRecord(); - PVStructurePtr pvStructure = getPVStructure(); - pvRecordName = pvStructure->getSubField("argument.recordName"); - if(!pvRecordName) return false; - pvResult = pvStructure->getSubField("result.status"); - if(!pvResult) return false; - return true; -} - -void AddRecord::process() -{ - PVDataCreatePtr pvDataCreate = getPVDataCreate(); - string name = pvRecordName->get(); - PVRecordPtr pvRecord = PVDatabase::getMaster()->findRecord(name); - if(pvRecord) { - pvResult->put(name + " already exists"); - return; - } - PVUnionPtr pvUnion = getPVStructure()->getSubField("argument.union"); - if(!pvUnion) { - pvResult->put(name + " argument.union is NULL"); - return; - } - PVFieldPtr pvField(pvUnion->get()); - if(!pvField) { - pvResult->put(name + " union has no value"); - return; - } - if(pvField->getField()->getType()!=epics::pvData::structure) { - pvResult->put(name + " union most be a structure"); - return; - } - StructureConstPtr st = static_pointer_cast(pvField->getField()); - PVStructurePtr pvStructure = pvDataCreate->createPVStructure(st); - PVRecordPtr pvRec = PVRecord::create(name,pvStructure); - bool result = PVDatabase::getMaster()->addRecord(pvRec); - if(result) { - pvResult->put("success"); - } else { - pvResult->put("failure"); - } -} - -static const iocshArg arg0 = { "recordName", iocshArgString }; -static const iocshArg *args[] = {&arg0}; - -static const iocshFuncDef addRecordFuncDef = {"addRecordCreate", 1,args}; - -static void addRecordCallFunc(const iocshArgBuf *args) -{ - cerr << "DEPRECATED use pvdbcrAddRecord instead\n"; - char *sval = args[0].sval; - if(!sval) { - throw std::runtime_error("addRecordCreate recordName not specified"); - } - string recordName = string(sval); - AddRecordPtr record = AddRecord::create(recordName); - PVDatabasePtr master = PVDatabase::getMaster(); - bool result = master->addRecord(record); - if(!result) cout << "recordname " << recordName << " not added" << endl; -} - -static void addRecordCreateRegister(void) -{ - static int firstTime = 1; - if (firstTime) { - firstTime = 0; - iocshRegister(&addRecordFuncDef, addRecordCallFunc); - } -} - -extern "C" { - epicsExportRegistrar(addRecordCreateRegister); -} diff --git a/src/special/addRecordRegister.dbd b/src/special/addRecordRegister.dbd deleted file mode 100644 index 3983cfb..0000000 --- a/src/special/addRecordRegister.dbd +++ /dev/null @@ -1 +0,0 @@ -registrar("addRecordRegister") diff --git a/src/special/processRecordRegister.cpp b/src/special/processRecordRegister.cpp deleted file mode 100644 index 9293b15..0000000 --- a/src/special/processRecordRegister.cpp +++ /dev/null @@ -1,222 +0,0 @@ -/* - * Copyright information and license terms for this software can be - * found in the file LICENSE that is included with the distribution - */ - -/** - * @author mrk - * @date 2021.03.12 - */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#define epicsExportSharedSymbols -#include "pv/pvStructureCopy.h" -#include "pv/channelProviderLocal.h" -#include "pv/pvDatabase.h" -using namespace epics::pvData; -using namespace epics::pvAccess; -using namespace epics::pvDatabase; -using namespace std; - -typedef std::tr1::shared_ptr EpicsThreadPtr; -class ProcessRecord; -typedef std::tr1::shared_ptr ProcessRecordPtr; - -class epicsShareClass ProcessRecord : - public PVRecord, - public epicsThreadRunable -{ -public: - POINTER_DEFINITIONS(ProcessRecord); - static ProcessRecordPtr create( - std::string const & recordName,double delay); - virtual bool init(); - virtual void process(); - virtual void run(); - void startThread(); - void stop(); -private: - ProcessRecord( - std::string const & recordName, - epics::pvData::PVStructurePtr const & pvStructure,double delay); - double delay; - EpicsThreadPtr thread; - epics::pvData::Event runStop; - epics::pvData::Event runReturn; - PVDatabasePtr pvDatabase; - PVRecordMap pvRecordMap; - epics::pvData::PVStringPtr pvCommand; - epics::pvData::PVStringPtr pvRecordName; - epics::pvData::PVStringPtr pvResult; - epics::pvData::Mutex mutex; -}; - -ProcessRecordPtr ProcessRecord::create( - std::string const & recordName,double delay) -{ - FieldCreatePtr fieldCreate = getFieldCreate(); - PVDataCreatePtr pvDataCreate = getPVDataCreate(); - StructureConstPtr topStructure = fieldCreate->createFieldBuilder()-> - addNestedStructure("argument")-> - add("command",pvString)-> - add("recordName",pvString)-> - endNested()-> - addNestedStructure("result") -> - add("status",pvString) -> - endNested()-> - createStructure(); - PVStructurePtr pvStructure = pvDataCreate->createPVStructure(topStructure); - ProcessRecordPtr pvRecord( - new ProcessRecord(recordName,pvStructure,delay)); - if(!pvRecord->init()) pvRecord.reset(); - return pvRecord; -} - -void ProcessRecord::startThread() -{ - thread = EpicsThreadPtr(new epicsThread( - *this, - "processRecord", - epicsThreadGetStackSize(epicsThreadStackSmall), - epicsThreadPriorityLow)); - thread->start(); -} - -void ProcessRecord::stop() -{ - runStop.signal(); - runReturn.wait(); -} - - -ProcessRecord::ProcessRecord( - std::string const & recordName, - epics::pvData::PVStructurePtr const & pvStructure,double delay) -: PVRecord(recordName,pvStructure), - delay(delay), - pvDatabase(PVDatabase::getMaster()) -{ -} - -bool ProcessRecord::init() -{ - initPVRecord(); - PVStructurePtr pvStructure = getPVStructure(); - pvCommand = pvStructure->getSubField("argument.command"); - pvRecordName = pvStructure->getSubField("argument.recordName"); - if(!pvRecordName) return false; - pvResult = pvStructure->getSubField("result.status"); - if(!pvResult) return false; - startThread(); - return true; -} - -void ProcessRecord::process() -{ - string recordName = pvRecordName->get(); - string command = pvCommand->get(); - if(command.compare("add")==0) { - epicsGuard guard(mutex); - std::map::iterator iter = pvRecordMap.find(recordName); - if(iter!=pvRecordMap.end()) { - pvResult->put(recordName + " already present"); - return; - } - PVRecordPtr pvRecord = pvDatabase->findRecord(recordName); - if(!pvRecord) { - pvResult->put(recordName + " not in pvDatabase"); - return; - } - pvRecordMap.insert(PVRecordMap::value_type(recordName,pvRecord)); - pvResult->put("success"); - return; - } else if(command.compare("remove")==0) { - epicsGuard guard(mutex); - std::map::iterator iter = pvRecordMap.find(recordName); - if(iter==pvRecordMap.end()) { - pvResult->put(recordName + " not found"); - return; - } - pvRecordMap.erase(iter); - pvResult->put("success"); - return; - } else { - pvResult->put(command + " not a valid command: only add and remove are valid"); - return; - } -} - -void ProcessRecord::run() -{ - while(true) { - if(runStop.tryWait()) { - runReturn.signal(); - return; - } - if(delay>0.0) epicsThreadSleep(delay); - epicsGuard guard(mutex); - PVRecordMap::iterator iter; - for(iter = pvRecordMap.begin(); iter!=pvRecordMap.end(); ++iter) { - PVRecordPtr pvRecord = (*iter).second; - pvRecord->lock(); - pvRecord->beginGroupPut(); - try { - pvRecord->process(); - } catch (std::exception& ex) { - std::cout << "record " << pvRecord->getRecordName() << "exception " << ex.what() << "\n"; - } catch (...) { - std::cout<< "record " << pvRecord->getRecordName() << " process exception\n"; - } - pvRecord->endGroupPut(); - pvRecord->unlock(); - } - } -} - -static const iocshArg arg0 = { "recordName", iocshArgString }; -static const iocshArg arg1 = { "delay", iocshArgDouble }; -static const iocshArg *args[] = {&arg0,&arg1}; - -static const iocshFuncDef processRecordFuncDef = {"processRecordCreate", 2,args}; - -static void processRecordCallFunc(const iocshArgBuf *args) -{ - cerr << "DEPRECATED use pvdbcrProcessRecord instead\n"; - char *sval = args[0].sval; - if(!sval) { - throw std::runtime_error("processRecord recordName not specified"); - } - string recordName = string(sval); - double delay = args[1].dval; - if(delay<0.0) delay = 1.0; - ProcessRecordPtr record = ProcessRecord::create(recordName,delay); - PVDatabasePtr master = PVDatabase::getMaster(); - bool result = master->addRecord(record); - if(!result) cout << "recordname " << recordName << " not added" << endl; -} - -static void processRecordRegister(void) -{ - static int firstTime = 1; - if (firstTime) { - firstTime = 0; - iocshRegister(&processRecordFuncDef, processRecordCallFunc); - } -} - -extern "C" { - epicsExportRegistrar(processRecordRegister); -} diff --git a/src/special/processRecordRegister.dbd b/src/special/processRecordRegister.dbd deleted file mode 100644 index fd8f945..0000000 --- a/src/special/processRecordRegister.dbd +++ /dev/null @@ -1 +0,0 @@ -registrar("processRecordRegister") diff --git a/src/special/removeRecordRegister.cpp b/src/special/removeRecordRegister.cpp deleted file mode 100644 index c1a264e..0000000 --- a/src/special/removeRecordRegister.cpp +++ /dev/null @@ -1,131 +0,0 @@ -/* - * Copyright information and license terms for this software can be - * found in the file LICENSE that is included with the distribution - */ - -/** - * @author mrk - * @date 2021.03.12 - */ -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#define epicsExportSharedSymbols -#include "pv/pvStructureCopy.h" -#include "pv/channelProviderLocal.h" -#include "pv/pvDatabase.h" -using namespace epics::pvData; -using namespace epics::pvAccess; -using namespace epics::pvDatabase; -using namespace std; - -class RemoveRecord; -typedef std::tr1::shared_ptr RemoveRecordPtr; - - -class epicsShareClass RemoveRecord : - public PVRecord -{ -public: - POINTER_DEFINITIONS(RemoveRecord); - static RemoveRecordPtr create( - std::string const & recordName); - virtual bool init(); - virtual void process(); -private: - RemoveRecord( - std::string const & recordName, - epics::pvData::PVStructurePtr const & pvStructure); - epics::pvData::PVStringPtr pvRecordName; - epics::pvData::PVStringPtr pvResult; -}; - -RemoveRecordPtr RemoveRecord::create( - std::string const & recordName) -{ - FieldCreatePtr fieldCreate = getFieldCreate(); - PVDataCreatePtr pvDataCreate = getPVDataCreate(); - StructureConstPtr topStructure = fieldCreate->createFieldBuilder()-> - addNestedStructure("argument")-> - add("recordName",pvString)-> - endNested()-> - addNestedStructure("result") -> - add("status",pvString) -> - endNested()-> - createStructure(); - PVStructurePtr pvStructure = pvDataCreate->createPVStructure(topStructure); - RemoveRecordPtr pvRecord( - new RemoveRecord(recordName,pvStructure)); - if(!pvRecord->init()) pvRecord.reset(); - return pvRecord; -} - -RemoveRecord::RemoveRecord( - std::string const & recordName, - epics::pvData::PVStructurePtr const & pvStructure) -: PVRecord(recordName,pvStructure) -{ -} - -bool RemoveRecord::init() -{ - initPVRecord(); - PVStructurePtr pvStructure = getPVStructure(); - pvRecordName = pvStructure->getSubField("argument.recordName"); - if(!pvRecordName) return false; - pvResult = pvStructure->getSubField("result.status"); - if(!pvResult) return false; - return true; -} - -void RemoveRecord::process() -{ - string name = pvRecordName->get(); - PVRecordPtr pvRecord = PVDatabase::getMaster()->findRecord(name); - if(!pvRecord) { - pvResult->put(name + " not found"); - return; - } - pvRecord->remove(); - pvResult->put("success"); -} - -static const iocshArg arg0 = { "recordName", iocshArgString }; -static const iocshArg *args[] = {&arg0}; - -static const iocshFuncDef removeRecordFuncDef = {"removeRecordCreate", 1,args}; - -static void removeRecordCallFunc(const iocshArgBuf *args) -{ - cerr << "DEPRECATED use pvdbcrRemoveRecord instead\n"; - char *sval = args[0].sval; - if(!sval) { - throw std::runtime_error("removeRecord recordName not specified"); - } - string recordName = string(sval); - RemoveRecordPtr record = RemoveRecord::create(recordName); - PVDatabasePtr master = PVDatabase::getMaster(); - bool result = master->addRecord(record); - if(!result) cout << "recordname " << recordName << " not added" << endl; -} - -static void removeRecordRegister(void) -{ - static int firstTime = 1; - if (firstTime) { - firstTime = 0; - iocshRegister(&removeRecordFuncDef, removeRecordCallFunc); - } -} - -extern "C" { - epicsExportRegistrar(removeRecordRegister); -} diff --git a/src/special/removeRecordRegister.dbd b/src/special/removeRecordRegister.dbd deleted file mode 100644 index aff2356..0000000 --- a/src/special/removeRecordRegister.dbd +++ /dev/null @@ -1 +0,0 @@ -registrar("removeRecordRegister") diff --git a/src/special/traceRecordRegister.cpp b/src/special/traceRecordRegister.cpp deleted file mode 100644 index c4f93ae..0000000 --- a/src/special/traceRecordRegister.cpp +++ /dev/null @@ -1,137 +0,0 @@ -/* - * Copyright information and license terms for this software can be - * found in the file LICENSE that is included with the distribution - */ - -/** - * @author mrk - * @date 2021.03.12 - */ -#include -#include -#include -#include -#include -#include -#include -#include -#include - -// The following must be the last include -#include -#define epicsExportSharedSymbols -#include "pv/pvStructureCopy.h" -#include "pv/channelProviderLocal.h" -#include "pv/pvDatabase.h" - -using namespace epics::pvData; -using namespace epics::pvAccess; -using namespace epics::pvDatabase; -using namespace std; - -class TraceRecord; -typedef std::tr1::shared_ptr TraceRecordPtr; - -class epicsShareClass TraceRecord : - public PVRecord -{ -public: - POINTER_DEFINITIONS(TraceRecord); - static TraceRecordPtr create( - std::string const & recordName); - virtual bool init(); - virtual void process(); -private: - TraceRecord( - std::string const & recordName, - epics::pvData::PVStructurePtr const & pvStructure); - epics::pvData::PVStringPtr pvRecordName; - epics::pvData::PVIntPtr pvLevel; - epics::pvData::PVStringPtr pvResult; -}; - -TraceRecordPtr TraceRecord::create( - std::string const & recordName) -{ - FieldCreatePtr fieldCreate = getFieldCreate(); - PVDataCreatePtr pvDataCreate = getPVDataCreate(); - StructureConstPtr topStructure = fieldCreate->createFieldBuilder()-> - addNestedStructure("argument")-> - add("recordName",pvString)-> - add("level",pvInt)-> - endNested()-> - addNestedStructure("result") -> - add("status",pvString) -> - endNested()-> - createStructure(); - PVStructurePtr pvStructure = pvDataCreate->createPVStructure(topStructure); - TraceRecordPtr pvRecord( - new TraceRecord(recordName,pvStructure)); - if(!pvRecord->init()) pvRecord.reset(); - return pvRecord; -} - -TraceRecord::TraceRecord( - std::string const & recordName, - epics::pvData::PVStructurePtr const & pvStructure) -: PVRecord(recordName,pvStructure) -{ -} - - -bool TraceRecord::init() -{ - initPVRecord(); - PVStructurePtr pvStructure = getPVStructure(); - pvRecordName = pvStructure->getSubField("argument.recordName"); - if(!pvRecordName) return false; - pvLevel = pvStructure->getSubField("argument.level"); - if(!pvLevel) return false; - pvResult = pvStructure->getSubField("result.status"); - if(!pvResult) return false; - return true; -} - -void TraceRecord::process() -{ - string name = pvRecordName->get(); - PVRecordPtr pvRecord = PVDatabase::getMaster()->findRecord(name); - if(!pvRecord) { - pvResult->put(name + " not found"); - return; - } - pvRecord->setTraceLevel(pvLevel->get()); - pvResult->put("success"); -} - -static const iocshArg arg0 = { "recordName", iocshArgString }; -static const iocshArg *args[] = {&arg0}; - -static const iocshFuncDef traceRecordFuncDef = {"traceRecordCreate", 1,args}; - -static void traceRecordCallFunc(const iocshArgBuf *args) -{ - cerr << "DEPRECATED use pvdbcrTraceRecord instead\n"; - char *sval = args[0].sval; - if(!sval) { - throw std::runtime_error("traceRecord recordName not specified"); - } - string recordName = string(sval); - TraceRecordPtr record = TraceRecord::create(recordName); - PVDatabasePtr master = PVDatabase::getMaster(); - bool result = master->addRecord(record); - if(!result) cout << "recordname " << recordName << " not added" << endl; -} - -static void traceRecordRegister(void) -{ - static int firstTime = 1; - if (firstTime) { - firstTime = 0; - iocshRegister(&traceRecordFuncDef, traceRecordCallFunc); - } -} - -extern "C" { - epicsExportRegistrar(traceRecordRegister); -} diff --git a/src/special/traceRecordRegister.dbd b/src/special/traceRecordRegister.dbd deleted file mode 100644 index 4dde906..0000000 --- a/src/special/traceRecordRegister.dbd +++ /dev/null @@ -1 +0,0 @@ -registrar("traceRecordRegister")