24 Commits

Author SHA1 Message Date
Marty Kraimer
5d823307f0 make records double00, ..., double04 2014-06-25 09:16:31 -04:00
Marty Kraimer
d41d5726d2 add records for testing easyPVAJava multiChannel 2014-06-24 15:05:19 -04:00
Matej Sekoranja
723f98bc44 added extern C on epicsExportRegistrar 2014-06-20 09:16:35 +02:00
Matej Sekoranja
1544147bdd win dll linkage 2014-06-20 08:56:39 +02:00
Matej Sekoranja
0447441cfa toString replaced with <<operator 2014-06-20 08:38:54 +02:00
Matej Sekoranja
8ce42ebb9a String -> std::string, toString methods removed, take 2 2014-06-19 14:55:44 +02:00
Matej Sekoranja
c39b966121 String -> std::string, toString methods removed 2014-06-19 14:30:40 +02:00
Marty Kraimer
61edf17cdf fix bug related to stride 2014-06-13 09:53:46 -04:00
Matej Sekoranja
39f537d7da win port: visibility declarations added/fixed 2014-06-13 11:43:22 +02:00
Matej Sekoranja
ba496de2d3 VxWorks fix: there is no Status::Status type 2014-06-13 11:04:29 +02:00
Marty Kraimer
38574ed76f support for ChannelArray UnionArray 2014-06-12 15:27:26 -04:00
Marty Kraimer
92be294bbf merge feature/changesAfter3_0_2; resolve conflicts 2014-06-10 15:53:37 -04:00
Marty Kraimer
35429bf4df flow: Merged <feature> 'changesAfter3_0_2' to <develop> ('default'). 2014-06-10 09:05:48 -04:00
Marty Kraimer
552925dfe6 flow: Closed <feature> 'changesAfter3_0_2'. 2014-06-10 08:55:18 -04:00
Marty Kraimer
d1791393ad Added tag before_merge_changesAfter3_0_2 for changeset abdc90bf52a0 2014-06-10 08:53:33 -04:00
Matej Sekoranja
3dbad700f7 channelList implemented 2014-06-09 22:19:52 +02:00
Marty Kraimer
c06e33e197 better implementation of ChannelArray::getLength 2014-06-09 07:55:08 -04:00
Marty Kraimer
1d8f01517a more work on stride 2014-06-06 11:28:41 -04:00
Marty Kraimer
8c1b142e48 working on support for stride for ChannelArray 2014-06-05 10:23:51 -04:00
Marty Kraimer
ca27cb5e3c changes for new pvAccess API 2014-06-04 10:48:12 -04:00
Marty Kraimer
a5fa17aca7 pvAccess added method cancel 2014-04-23 11:01:14 -04:00
Marty Kraimer
fe62a7181f use copy and monitor from pvDataCPP; imlement example plugin; algorithm => plugin 2014-04-23 09:25:58 -04:00
Marty Kraimer
342ab45dc8 changes for changesAfter3_0_2
pvCopy modified and moved to pvDataCPP
2014-04-01 14:07:43 -04:00
Marty Kraimer
127830e3c7 flow: Created branch 'feature/changesAfter3_0_2'. 2014-03-25 07:18:10 -04:00
109 changed files with 1692 additions and 2052 deletions

View File

@@ -7,5 +7,5 @@ db/
dbd/
documentation/html
envPaths
RELEASE.local
configure/.*\.local
/O\..*

View File

@@ -1 +1,2 @@
bba6a2491bdf73681cef01caf0bd89c87d7989cd 0.9.1
abdc90bf52a0c31e24e2f9a079ef72350ee31686 before_merge_changesAfter3_0_2

View File

@@ -1,25 +1,27 @@
# Makefile for the EPICS V4 pvDatabase module
#Makefile at top of application tree
TOP = .
include $(TOP)/configure/CONFIG
DIRS := $(DIRS) $(filter-out $(DIRS), configure)
DIRS := $(DIRS) $(filter-out $(DIRS), src)
DIRS := $(DIRS) $(filter-out $(DIRS), test)
DIRS := $(DIRS) $(filter-out $(DIRS), arrayPerformance)
DIRS := $(DIRS) $(filter-out $(DIRS), $(wildcard example*))
DIRS := configure
EMBEDDED_TOPS := $(EMBEDDED_TOPS) $(filter-out $(EMBEDDED_TOPS), test)
EMBEDDED_TOPS := $(EMBEDDED_TOPS) $(filter-out $(EMBEDDED_TOPS), arrayPerformance)
EMBEDDED_TOPS := $(EMBEDDED_TOPS) $(filter-out $(EMBEDDED_TOPS), $(wildcard example*))
DIRS += src
src_DEPEND_DIRS = configure
define DIR_template
$(1)_DEPEND_DIRS = configure
endef
$(foreach dir, $(filter-out configure,$(DIRS)),$(eval $(call DIR_template,$(dir))))
EMBEDDED_TOPS := $(wildcard *Top)
EMBEDDED_TOPS += $(wildcard example*)
DIRS += $(EMBEDDED_TOPS)
define dir_DEP
define EMB_template
$(1)_DEPEND_DIRS = src
endef
$(foreach dir, $(EMBEDDED_TOPS),$(eval $(call EMB_template,$(dir))))
$(foreach dir, $(EMBEDDED_TOPS), $(eval $(call dir_DEP,$(dir))))
exampleDatabase_DEPEND_DIRS += testTop
examplePowerSupply_DEPEND_DIRS += testTop
#exampleDatabase_DEPEND_DIRS += test
#examplePowerSupply_DEPEND_DIRS += test
include $(TOP)/configure/RULES_TOP

View File

@@ -1,8 +1,6 @@
# Makefile at top of application tree
#Makefile at top of application tree
TOP = .
include $(TOP)/configure/CONFIG
DIRS += configure
DIRS += src

View File

@@ -14,11 +14,26 @@
# Set CHECK_RELEASE to NO to disable checking completely.
# Set CHECK_RELEASE to WARN to perform consistency checking but
# continue building anyway if conflicts are found.
CHECK_RELEASE = WARN
#CHECK_RELEASE = YES
# Set this when you only want to compile this application
# for a subset of the cross-compiled target architectures
# that Base is built for.
#CROSS_COMPILER_TARGET_ARCHS = vxWorks-68040
# To install files into a location other than $(TOP) define
# INSTALL_LOCATION here.
#INSTALL_LOCATION=</path/name/to/install/top>
-include $(TOP)/../configure/CONFIG_SITE.local
-include $(TOP)/../../CONFIG_SITE.local
# Set this when your IOC and the host use different paths
# to access the application. This will be needed to boot
# from a Microsoft FTP server or with some NFS mounts.
# You must rebuild in the iocBoot directory for this to
# take effect.
#IOCS_APPL_TOP = </IOC/path/to/application/top>
INSTALL_INCLUDE = $(INSTALL_LOCATION)/include/pv
USR_INCLUDES += -I $(INSTALL_LOCATION)/include
-include $(TOP)/configure/CONFIG_SITE.local
-include $(TOP)/../CONFIG.local

View File

@@ -1,4 +1,4 @@
# pvDatabaseCPP/arrayPerfTop RELEASE - Location of external support modules
# pvDatabaseCPP/arrayPerformance RELEASE - Location of external support modules
#
# IF YOU CHANGE this file or any file it includes you must
# subsequently do a "gnumake rebuild" in the application's
@@ -16,9 +16,8 @@
# EPICS V4 Developers: Do not edit the locations in this file!
#
# Create a file RELEASE.local pointing to your PVASRV, PVACCESS,
# PVDATA, PVCOMMON and EPICS_BASE build directories, e.g.
# PVASRV = /path/to/epics/pvaSrvCPP
# Create a file RELEASE.local pointing to your places
# for the dependencies, e.g.
# PVACCESS = /path/to/epics/pvAccessCPP
# PVDATA = /path/to/epics/pvDataCPP
# PVCOMMON = /path/to/epics/pvCommonCPP
@@ -28,14 +27,14 @@
# use the following definitions:
PVDATABASE = $(TOP)/..
-include $(TOP)/../configure/RELEASE.local
-include $(TOP)/../../RELEASE.local
-include $(TOP)/../configure/RELEASE.local
# If you copied this example from pvDatabaseCPP to be built as a
# standalone TOP, adjust and use the following definitions:
# standalone TOP, define
# PVDATABASE = /path/to/epics/pvDatabaseCPP
# in the appropriate RELEASE[.local],
# and use the following definitions instead:
#PVDATABASE = /path/to/epics/pvDatabaseCPP
#-include $(TOP)/configure/RELEASE.local
#-include $(TOP)/../RELEASE.local
#-include $(TOP)/configure/RELEASE.local

View File

@@ -26,7 +26,7 @@ using std::endl;
using std::ostringstream;
ArrayPerformancePtr ArrayPerformance::create(
epics::pvData::String const & recordName,
std::string const & recordName,
size_t size,
double delay)
{
@@ -39,7 +39,7 @@ ArrayPerformancePtr ArrayPerformance::create(
}
ArrayPerformance::ArrayPerformance(
epics::pvData::String const & recordName,
std::string const & recordName,
epics::pvData::PVStructurePtr const & pvStructure,
size_t size,
double delay)

View File

@@ -44,7 +44,7 @@ class epicsShareClass ArrayPerformance :
public:
POINTER_DEFINITIONS(ArrayPerformance);
static ArrayPerformancePtr create(
epics::pvData::String const & recordName,
std::string const & recordName,
size_t size,
double delay);
virtual ~ArrayPerformance();
@@ -53,7 +53,7 @@ public:
virtual void process();
virtual void destroy();
private:
ArrayPerformance(epics::pvData::String const & recordName,
ArrayPerformance(std::string const & recordName,
epics::pvData::PVStructurePtr const & pvStructure,
size_t size,
double delay);
@@ -81,7 +81,7 @@ private:
ArrayPerformancePtr arrayPerformance;
bool isDestroyed;
bool runReturned;
epics::pvData::String threadName;
std::string threadName;
epics::pvData::Mutex mutex;
epics::pvData::int64 value;
std::auto_ptr<epicsThread> thread;

View File

@@ -39,15 +39,15 @@ using namespace epics::pvDatabase;
int main(int argc,char *argv[])
{
bool result(false);
String recordName;
string recordName;
recordName = "arrayPerformance";
size_t size = 10000000;
double delay = .0001;
String providerName("local");
string providerName("local");
size_t nMonitor = 1;
int queueSize = 2;
double waitTime = 0.0;
if(argc==2 && String(argv[1])==String("-help")) {
if(argc==2 && string(argv[1])==string("-help")) {
cout << "arrayPerformanceMain recordName size";
cout << " delay providerName nMonitor queueSize waitTime" << endl;
cout << "default" << endl;
@@ -83,7 +83,7 @@ int main(int argc,char *argv[])
pvRecord = ArrayPerformance::create(recordName,size,delay);
result = master->addRecord(pvRecord);
PVRecordPtr arrayPreformance = pvRecord;
arrayPreformance->setTraceLevel(1);
arrayPreformance->setTraceLevel(0);
pvRecord = TraceRecord::create("traceRecordPGRPC");
result = master->addRecord(pvRecord);
if(!result) cout<< "record " << recordName << " not added" << endl;

View File

@@ -24,9 +24,10 @@ using std::tr1::dynamic_pointer_cast;
using std::cout;
using std::endl;
using std::ostringstream;
using std::string;
static String requesterName("longArrayGet");
static String request("value,timeStamp,alarm");
static string requesterName("longArrayGet");
static string request("value,timeStamp,alarm");
static epics::pvData::Mutex printMutex;
class LongArrayChannelRequester;
@@ -52,8 +53,8 @@ public:
isDestroyed = true;
longArrayChannelGet.reset();
}
virtual String getRequesterName() { return requesterName;}
virtual void message(String const & message, MessageType messageType)
virtual string getRequesterName() { return requesterName;}
virtual void message(string const & message, MessageType messageType)
{
Lock guard(printMutex);
cout << requesterName << " message " << message << endl;
@@ -93,18 +94,21 @@ public:
isDestroyed = true;
longArrayChannelGet.reset();
}
virtual String getRequesterName() { return requesterName;}
virtual void message(String const & message, MessageType messageType)
virtual string getRequesterName() { return requesterName;}
virtual void message(string const & message, MessageType messageType)
{
Lock guard(printMutex);
cout << requesterName << " message " << message << endl;
}
virtual void channelGetConnect(
Status const & status,
ChannelGet::shared_pointer const & channelGet,
StructureConstPtr const &structure);
virtual void getDone(
Status const & status,
ChannelGet::shared_pointer const & channelGet,
PVStructurePtr const &pvStructure,
BitSetPtr const &bitSet);
virtual void getDone(Status const & status);
BitSetPtr const & bitSet);
private:
LongArrayChannelGetRequesterPtr getPtrSelf()
{
@@ -123,8 +127,8 @@ class LongArrayChannelGet :
{
public:
LongArrayChannelGet(
String providerName,
String channelName,
string providerName,
string channelName,
int iterBetweenCreateChannel,
int iterBetweenCreateChannelGet,
double delayTime)
@@ -141,7 +145,7 @@ public:
bool init();
virtual void destroy();
virtual void run();
void message(String const & message, MessageType messageType)
void message(string const & message, MessageType messageType)
{
Lock guard(printMutex);
cout << requesterName << " message " << message << endl;
@@ -155,23 +159,26 @@ public:
virtual void channelGetConnect(
Status const & status,
ChannelGet::shared_pointer const & channelGet,
StructureConstPtr const &structure);
virtual void getDone(
Status const & status,
ChannelGet::shared_pointer channelGet,
PVStructurePtr const &pvStructure,
BitSetPtr const &bitSet);
virtual void getDone(Status const & status);
BitSetPtr const & bitSet);
private:
LongArrayChannelGetPtr getPtrSelf()
{
return shared_from_this();
}
size_t checkResult();
String providerName;
String channelName;
string providerName;
string channelName;
int iterBetweenCreateChannel;
int iterBetweenCreateChannelGet;
double delayTime;
bool isDestroyed;
bool runReturned;
epics::pvData::String threadName;
std::string threadName;
Status status;
Event event;
Mutex mutex;
@@ -197,7 +204,7 @@ void LongArrayChannelRequester::channelStateChange(
Channel::shared_pointer const & channel,
Channel::ConnectionState connectionState)
{
String mess(Channel::ConnectionStateNames[connectionState]);
string mess(Channel::ConnectionStateNames[connectionState]);
message(mess,infoMessage);
Lock guard(mutex);
if(isDestroyed) return;
@@ -206,21 +213,24 @@ void LongArrayChannelRequester::channelStateChange(
void LongArrayChannelGetRequester::channelGetConnect(
Status const & status,
ChannelGet::shared_pointer const & channelGet,
PVStructurePtr const &pvStructure,
BitSetPtr const &bitSet)
ChannelGet::shared_pointer const & channelGet,
StructureConstPtr const &structure)
{
Lock guard(mutex);
if(isDestroyed) return;
longArrayChannelGet->channelGetConnect(
status,channelGet,pvStructure,bitSet);
status,channelGet,structure);
}
void LongArrayChannelGetRequester::getDone(Status const & status)
void LongArrayChannelGetRequester::getDone(
Status const & status,
ChannelGet::shared_pointer const & channelGet,
PVStructurePtr const &pvStructure,
BitSetPtr const & bitSet)
{
Lock guard(mutex);
if(isDestroyed) return;
longArrayChannelGet->getDone(status);
longArrayChannelGet->getDone(status,channelGet,pvStructure,bitSet);
}
void LongArrayChannelGet::channelCreated(
@@ -241,12 +251,10 @@ void LongArrayChannelGet::channelStateChange(
(connectionState==Channel::CONNECTED ? infoMessage : errorMessage);
message("channelStateChange",messageType);
}
void LongArrayChannelGet::channelGetConnect(
Status const & status,
ChannelGet::shared_pointer const & channelGet,
PVStructurePtr const &pvStructure,
BitSetPtr const &bitSet)
StructureConstPtr const &structure)
{
this->status = status;
if(!status.isOK()) {
@@ -255,9 +263,8 @@ void LongArrayChannelGet::channelGetConnect(
return;
}
this->channelGet = channelGet;
this->pvStructure = pvStructure;
this->bitSet = bitSet;
bool structureOK(true);
PVStructurePtr pvStructure = getPVDataCreate()->createPVStructure(structure);
PVFieldPtr pvField = pvStructure->getSubField("timeStamp");
if(pvField==NULL) structureOK = false;
pvField = pvStructure->getSubField("value");
@@ -273,7 +280,7 @@ void LongArrayChannelGet::channelGetConnect(
}
}
if(!structureOK) {
String mess("channelGetConnect: illegal structure");
string mess("channelGetConnect: illegal structure");
message(mess,errorMessage);
this->status = Status(Status::STATUSTYPE_ERROR,mess);
}
@@ -284,7 +291,7 @@ void LongArrayChannelGet::channelGetConnect(
bool LongArrayChannelGet::init()
{
ChannelProvider::shared_pointer channelProvider =
getChannelAccess()->getProvider(providerName);
getChannelProviderRegistry()->getProvider(providerName);
if(channelProvider==NULL) {
cout << "provider " << providerName << " not found" << endl;
return false;
@@ -355,7 +362,7 @@ void LongArrayChannelGet::run()
int numChannelCreate = 0;
size_t nElements = 0;
while(true) {
channelGet->get(false);
channelGet->get();
event.wait();
if(isDestroyed) {
runReturned = true;
@@ -398,7 +405,7 @@ void LongArrayChannelGet::run()
longArrayChannelRequester->destroy();
channel->destroy();
ChannelProvider::shared_pointer channelProvider =
getChannelAccess()->getProvider(providerName);
getChannelProviderRegistry()->getProvider(providerName);
longArrayChannelRequester.reset(new LongArrayChannelRequester(getPtrSelf()));
channel = channelProvider->createChannel(
channelName,
@@ -445,10 +452,14 @@ void LongArrayChannelGet::run()
}
}
void LongArrayChannelGet::getDone(Status const & status)
void LongArrayChannelGet::getDone(
Status const & status,
ChannelGet::shared_pointer channelGet,
PVStructurePtr const &pvStructure,
BitSetPtr const & bitSet)
{
this->pvStructure = pvStructure;
this->bitSet = bitSet;
event.signal();
}
@@ -477,8 +488,8 @@ size_t LongArrayChannelGet::checkResult()
LongArrayGetPtr LongArrayGet::create(
String const &providerName,
String const & channelName,
string const &providerName,
string const & channelName,
int iterBetweenCreateChannel,
int iterBetweenCreateChannelGet,
double delayTime)
@@ -495,8 +506,8 @@ LongArrayGetPtr LongArrayGet::create(
}
LongArrayGet::LongArrayGet(
String const &providerName,
String const & channelName,
string const &providerName,
string const & channelName,
int iterBetweenCreateChannel,
int iterBetweenCreateChannelGet,
double delayTime)

View File

@@ -49,8 +49,8 @@ class epicsShareClass LongArrayGet :
public:
POINTER_DEFINITIONS(LongArrayGet);
static LongArrayGetPtr create(
epics::pvData::String const & providerName,
epics::pvData::String const & channelName,
std::string const & providerName,
std::string const & channelName,
int iterBetweenCreateChannel = 0,
int iterBetweenCreateChannelGet = 0,
double delayTime = 0.0);
@@ -62,15 +62,15 @@ private:
return shared_from_this();
}
LongArrayGet(
epics::pvData::String const & providerName,
epics::pvData::String const & channelName,
std::string const & providerName,
std::string const & channelName,
int iterBetweenCreateChannel = 0,
int iterBetweenCreateChannelGet = 0,
double delayTime = 0.0);
bool init();
epics::pvData::String providerName;
epics::pvData::String channelName;
std::string providerName;
std::string channelName;
int iterBetweenCreateChannel;
int iterBetweenCreateChannelGet;
double delayTime;

View File

@@ -38,11 +38,11 @@ using namespace epics::pvDatabase;
int main(int argc,char *argv[])
{
String channelName("arrayPerformance");
string channelName("arrayPerformance");
int iterBetweenCreateChannel = 0;
int iterBetweenCreateChannelGet = 0;
double delayTime = 1.0;
if(argc==2 && String(argv[1])==String("-help")) {
if(argc==2 && string(argv[1])==string("-help")) {
cout << "longArrayGetMain channelName ";
cout << "iterBetweenCreateChannel iterBetweenCreateChannelGet delayTime" << endl;
cout << "default" << endl;

View File

@@ -25,11 +25,12 @@ using std::tr1::static_pointer_cast;
using std::tr1::dynamic_pointer_cast;
using std::cout;
using std::endl;
using std::string;
using std::ostringstream;
static String requesterName("longArrayMonitor");
static string requesterName("longArrayMonitor");
static void messagePvt(String const & message, MessageType messageType)
static void messagePvt(string const & message, MessageType messageType)
{
cout << requesterName << " message " << message << endl;
}
@@ -43,8 +44,8 @@ public:
{}
virtual ~LAMChannelRequester(){}
virtual void destroy(){longArrayMonitor.reset();}
virtual String getRequesterName() { return requesterName;}
virtual void message(String const & message, MessageType messageType)
virtual string getRequesterName() { return requesterName;}
virtual void message(string const & message, MessageType messageType)
{ messagePvt(message,messageType);}
virtual void channelCreated(const Status& status, Channel::shared_pointer const & channel);
virtual void channelStateChange(Channel::shared_pointer const & channel, Channel::ConnectionState connectionState);
@@ -83,8 +84,8 @@ public:
void init();
virtual void destroy();
virtual void run();
virtual String getRequesterName() { return requesterName;}
virtual void message(String const & message, MessageType messageType)
virtual string getRequesterName() { return requesterName;}
virtual void message(string const & message, MessageType messageType)
{ messagePvt(message,messageType);}
virtual void monitorConnect(Status const & status,
MonitorPtr const & monitor, StructureConstPtr const & structure);
@@ -95,7 +96,7 @@ private:
double waitTime;
bool isDestroyed;
bool runReturned;
epics::pvData::String threadName;
std::string threadName;
Event event;
Mutex mutex;
std::auto_ptr<epicsThread> thread;
@@ -150,7 +151,7 @@ void LAMMonitorRequester::monitorConnect(Status const & status,
}
}
if(!structureOK) {
String message("monitorConnect: illegal structure");
string message("monitorConnect: illegal structure");
messagePvt(message,errorMessage);
longArrayMonitor->status = Status(Status::STATUSTYPE_ERROR,message);
}
@@ -200,12 +201,8 @@ void LAMMonitorRequester::run()
out << "first " << first << " last " << last ;
BitSetPtr changed = monitorElement->changedBitSet;
BitSetPtr overrun = monitorElement->overrunBitSet;
String buffer;
changed->toString(&buffer);
out << " changed " << buffer;
buffer.clear();
overrun->toString(&buffer);
out << " overrun " << buffer;
out << " changed " << *changed;
out << " overrun " << *overrun;
double elementsPerSec = nElements;
elementsPerSec /= diff;
if(elementsPerSec>10.0e9) {
@@ -246,8 +243,8 @@ void LAMMonitorRequester::unlisten(MonitorPtr const & monitor)
LongArrayMonitorPtr LongArrayMonitor::create(
String const &providerName,
String const & channelName,
string const &providerName,
string const & channelName,
int queueSize,
double waitTime)
{
@@ -261,15 +258,16 @@ LongArrayMonitor::LongArrayMonitor() {}
LongArrayMonitor::~LongArrayMonitor() {}
bool LongArrayMonitor::init(
String const &providerName,
String const &channelName,
string const &providerName,
string const &channelName,
int queueSize,
double waitTime)
{
channelRequester = LAMChannelRequesterPtr(new LAMChannelRequester(getPtrSelf()));
monitorRequester = LAMMonitorRequesterPtr(new LAMMonitorRequester(getPtrSelf(),waitTime));
monitorRequester->init();
ChannelProvider::shared_pointer channelProvider = getChannelAccess()->getProvider(providerName);
ChannelProvider::shared_pointer channelProvider =
getChannelProviderRegistry()->getProvider(providerName);
if(channelProvider==NULL) {
cout << "provider " << providerName << " not found" << endl;
return false;
@@ -277,7 +275,7 @@ bool LongArrayMonitor::init(
channel = channelProvider->createChannel(channelName,channelRequester,0);
event.wait();
if(!status.isOK()) return false;
String request("record[queueSize=");
string request("record[queueSize=");
char buff[20];
sprintf(buff,"%d",queueSize);
request += buff;

View File

@@ -49,8 +49,8 @@ class epicsShareClass LongArrayMonitor :
public:
POINTER_DEFINITIONS(LongArrayMonitor);
static LongArrayMonitorPtr create(
epics::pvData::String const & providerName,
epics::pvData::String const & channelName,
std::string const & providerName,
std::string const & channelName,
int queueSize = 1,
double waitTime = 0.0);
~LongArrayMonitor();
@@ -60,8 +60,8 @@ public:
private:
static epics::pvData::Mutex printMutex;
bool init(
epics::pvData::String const & providerName,
epics::pvData::String const & channelName,
std::string const & providerName,
std::string const & channelName,
int queueSize,
double waitTime);
LongArrayMonitorPtr getPtrSelf()

View File

@@ -38,10 +38,10 @@ using namespace epics::pvDatabase;
int main(int argc,char *argv[])
{
String channelName("arrayPerformance");
string channelName("arrayPerformance");
int queueSize = 2;
double waitTime = 0.0;
if(argc==2 && String(argv[1])==String("-help")) {
if(argc==2 && string(argv[1])==string("-help")) {
cout << "longArrayMonitorMain channelName queueSize waitTime" << endl;
cout << "default" << endl;
cout << "longArrayMonitorMain " << channelName << " ";

View File

@@ -24,9 +24,10 @@ using std::tr1::dynamic_pointer_cast;
using std::cout;
using std::endl;
using std::ostringstream;
using std::string;
static String requesterName("longArrayPut");
static String request("value");
static string requesterName("longArrayPut");
static string request("value");
static epics::pvData::Mutex printMutex;
class LongArrayChannelPut :
@@ -37,8 +38,8 @@ class LongArrayChannelPut :
{
public:
LongArrayChannelPut(
String providerName,
String channelName,
string providerName,
string channelName,
size_t arraySize,
int iterBetweenCreateChannel,
int iterBetweenCreateChannelPut,
@@ -57,8 +58,8 @@ public:
bool init();
virtual void destroy();
virtual void run();
virtual String getRequesterName() { return requesterName;}
virtual void message(String const & message, MessageType messageType)
virtual string getRequesterName() { return requesterName;}
virtual void message(string const & message, MessageType messageType)
{
Lock guard(printMutex);
cout << requesterName << " message " << message << endl;
@@ -70,26 +71,31 @@ public:
Channel::shared_pointer const & channel,
Channel::ConnectionState connectionState);
virtual void channelPutConnect(
Status const & status,
ChannelPut::shared_pointer const & channelPut,
StructureConstPtr const &structure);
virtual void putDone(
Status const & status,
ChannelPut::shared_pointer const & channelPut);
virtual void getDone(
Status const & status,
ChannelPut::shared_pointer const & channelPut,
PVStructurePtr const &pvStructure,
BitSetPtr const &bitSet);
virtual void putDone(Status const & status);
virtual void getDone(Status const & status){}
BitSetPtr const & bitSet){}
private:
LongArrayChannelPutPtr getPtrSelf()
{
return shared_from_this();
}
String providerName;
String channelName;
string providerName;
string channelName;
size_t arraySize;
int iterBetweenCreateChannel;
int iterBetweenCreateChannelPut;
double delayTime;
bool isDestroyed;
bool runReturned;
epics::pvData::String threadName;
std::string threadName;
Status status;
Event event;
Mutex mutex;
@@ -103,7 +109,7 @@ private:
bool LongArrayChannelPut::init()
{
ChannelProvider::shared_pointer channelProvider = getChannelAccess()->getProvider(providerName);
ChannelProvider::shared_pointer channelProvider = getChannelProviderRegistry()->getProvider(providerName);
if(channelProvider==NULL) {
cout << "provider " << providerName << " not found" << endl;
return false;
@@ -168,8 +174,7 @@ void LongArrayChannelPut::channelStateChange(
void LongArrayChannelPut::channelPutConnect(
Status const & status,
ChannelPut::shared_pointer const & channelPut,
PVStructurePtr const &pvStructure,
BitSetPtr const &bitSet)
StructureConstPtr const &structure)
{
this->status = status;
if(!status.isOK()) {
@@ -178,8 +183,8 @@ void LongArrayChannelPut::channelPutConnect(
return;
}
this->channelPut = channelPut;
this->pvStructure = pvStructure;
this->bitSet = bitSet;
pvStructure = getPVDataCreate()->createPVStructure(structure);
bitSet = BitSetPtr(new BitSet(pvStructure->getNumberFields()));
bool structureOK(true);
PVFieldPtr pvField = pvStructure->getSubField("value");
if(pvField==NULL) {
@@ -194,7 +199,7 @@ void LongArrayChannelPut::channelPutConnect(
}
}
if(!structureOK) {
String mess("channelPutConnect: illegal structure");
string mess("channelPutConnect: illegal structure");
message(mess,errorMessage);
this->status = Status(Status::STATUSTYPE_ERROR,mess);
}
@@ -222,7 +227,7 @@ void LongArrayChannelPut::run()
shared_vector<const int64> data(freeze(xxx));
pvLongArray->replace(data);
bitSet->set(pvLongArray->getFieldOffset());
channelPut->put(false);
channelPut->put(pvStructure,bitSet);
event.wait();
if(isDestroyed) {
runReturned = true;
@@ -264,7 +269,7 @@ void LongArrayChannelPut::run()
channel->destroy();
epicsThreadSleep(1.0);
ChannelProvider::shared_pointer channelProvider =
getChannelAccess()->getProvider(providerName);
getChannelProviderRegistry()->getProvider(providerName);
channel = channelProvider->createChannel(
channelName,getPtrSelf(),0);
event.wait();
@@ -310,15 +315,17 @@ void LongArrayChannelPut::run()
}
}
void LongArrayChannelPut::putDone(Status const & status)
void LongArrayChannelPut::putDone(
Status const & status,
ChannelPut::shared_pointer const & channelPut)
{
event.signal();
}
LongArrayPutPtr LongArrayPut::create(
String const &providerName,
String const & channelName,
string const &providerName,
string const & channelName,
size_t arraySize,
int iterBetweenCreateChannel,
int iterBetweenCreateChannelPut,
@@ -337,8 +344,8 @@ LongArrayPutPtr LongArrayPut::create(
}
LongArrayPut::LongArrayPut(
String const &providerName,
String const & channelName,
string const &providerName,
string const & channelName,
size_t arraySize,
int iterBetweenCreateChannel,
int iterBetweenCreateChannelPut,

View File

@@ -48,8 +48,8 @@ class epicsShareClass LongArrayPut :
public:
POINTER_DEFINITIONS(LongArrayPut);
static LongArrayPutPtr create(
epics::pvData::String const & providerName,
epics::pvData::String const & channelName,
std::string const & providerName,
std::string const & channelName,
size_t arraySize = 100,
int iterBetweenCreateChannel = 0,
int iterBetweenCreateChannelPut = 0,
@@ -62,16 +62,16 @@ private:
return shared_from_this();
}
LongArrayPut(
epics::pvData::String const & providerName,
epics::pvData::String const & channelName,
std::string const & providerName,
std::string const & channelName,
size_t arraySize,
int iterBetweenCreateChannel,
int iterBetweenCreateChannelPut,
double delayTime);
bool init();
epics::pvData::String providerName;
epics::pvData::String channelName;
std::string providerName;
std::string channelName;
size_t arraySize;
int iterBetweenCreateChannel;
int iterBetweenCreateChannelPut;

View File

@@ -38,12 +38,12 @@ using namespace epics::pvDatabase;
int main(int argc,char *argv[])
{
String channelName("arrayPerformance");
string channelName("arrayPerformance");
size_t arraySize = 10;
int iterBetweenCreateChannel = 0;
int iterBetweenCreateChannelPut = 0;
double delayTime = 1.0;
if(argc==2 && String(argv[1])==String("-help")) {
if(argc==2 && string(argv[1])==string("-help")) {
cout << "longArrayPutMain channelName arraySize ";
cout << "iterBetweenCreateChannel iterBetweenCreateChannelPut delayTime" << endl;
cout << "default" << endl;

View File

@@ -140,7 +140,7 @@ int main(int argc,char *argv[])
size_t size = 50000000;
double delay = .01;
size_t nThread = 1;
if(argc==2 && String(argv[1])==String("-help")) {
if(argc==2 && string(argv[1])==string("-help")) {
cout << "vectorPerformanceMain size delay nThread" << endl;
cout << "default" << endl;
cout << "vectorPerformance ";

View File

@@ -14,11 +14,15 @@
# Set CHECK_RELEASE to NO to disable checking completely.
# Set CHECK_RELEASE to WARN to perform consistency checking but
# continue building anyway if conflicts are found.
CHECK_RELEASE = YES
#CHECK_RELEASE = YES
# To install files into a location other than $(TOP) define
# INSTALL_LOCATION here.
#INSTALL_LOCATION=</path/name/to/install/top>
INSTALL_INCLUDE = $(INSTALL_LOCATION)/include/pv
USR_INCLUDES += -I $(INSTALL_LOCATION)/include
-include $(TOP)/../CONFIG_SITE.local
-include $(TOP)/configure/CONFIG_SITE.local
-include $(TOP)/../CONFIG.local

View File

@@ -1,11 +1,8 @@
# Sample RELEASE.local file
V4 = /home/install/epics/v4
PVASRV = $(V4)/pvaSrv
PVACCESS = $(V4)/pvAccessCPP
PVDATA = $(V4)/pvDataCPP
PVCOMMON = $(V4)/pvCommonCPP
EPICS_BASE = /home/install/epics/base-3.14.12.3
TEMPLATE_TOP=$(EPICS_BASE)/templates/makeBaseApp/top
EPICS_BASE=/home/install/epics/base
PVCOMMON=/home/hg/pvCommonCPP
PVDATA=/home/hg/pvDataCPP
PVACCESS=/home/hg/pvAccessCPP
PVASRV=/home/hg/pvaSrv

View File

@@ -24,5 +24,5 @@
# PVCOMMON = /path/to/epics/pvCommonCPP
# EPICS_BASE = /path/to/epics/base
-include $(TOP)/configure/RELEASE.local
-include $(TOP)/../RELEASE.local
-include $(TOP)/configure/RELEASE.local

View File

@@ -575,10 +575,10 @@ public:
virtual void destroy();
static PVRecordPtr create(
epics::pvData::String const &amp; recordName,
std::string const &amp; recordName,
epics::pvData::PVStructurePtr const &amp; pvStructure);
virtual ~PVRecord();
epics::pvData::String getRecordName();
std::string getRecordName();
PVRecordStructurePtr getPVRecordStructure();
PVRecordFieldPtr findPVRecordField(
epics::pvData::PVFieldPtr const &amp; pvField);
@@ -596,13 +596,13 @@ public:
bool removeListener(PVListenerPtr const &amp; pvListener);
void beginGroupPut();
void endGroupPut();
epics::pvData::String getRequesterName() {return getRecordName();}
std::string getRequesterName() {return getRecordName();}
virtual void message(
epics::pvData::String const &amp; message,
std::string const &amp; message,
epics::pvData::MessageType messageType);
void message(
PVRecordFieldPtr const &amp; pvRecordField,
epics::pvData::String const &amp; message,
std::string const &amp; message,
epics::pvData::MessageType messageType);
void toString(epics::pvData::StringBuilder buf);
void toString(epics::pvData::StringBuilder buf,int indentLevel);
@@ -610,7 +610,7 @@ public:
void setTraceLevel(int level);
protected:
PVRecord(
epics::pvData::String const &amp; recordName,
std::string const &amp; recordName,
epics::pvData::PVStructurePtr const &amp; pvStructure);
void initPVRecord();
epics::pvData::PVStructurePtr getPVStructure();
@@ -742,14 +742,14 @@ public:
virtual void destroy();
PVRecordStructurePtr getParent();
epics::pvData::PVFieldPtr getPVField();
epics::pvData::String getFullFieldName();
epics::pvData::String getFullName();
std::string getFullFieldName();
std::string getFullName();
PVRecordPtr getPVRecord();
bool addListener(PVListenerPtr const &amp; pvListener);
virtual void removeListener(PVListenerPtr const &amp; pvListener);
virtual void postPut();
virtual void message(
epics::pvData::String const &amp; message,
std::string const &amp; message,
epics::pvData::MessageType messageType);
protected:
PVRecordFieldPtr getPtrSelf()
@@ -896,13 +896,13 @@ public:
static PVDatabasePtr getMaster();
virtual ~PVDatabase();
virtual void destroy();
PVRecordPtr findRecord(epics::pvData::String const&amp; recordName);
PVRecordPtr findRecord(std::string const&amp; recordName);
bool addRecord(PVRecordPtr const &amp; record);
epics::pvData::PVStringArrayPtr getRecordNames();
bool removeRecord(PVRecordPtr const &amp; record);
virtual epics::pvData::String getRequesterName();
virtual std::string getRequesterName();
virtual void message(
epics::pvData::String const &amp;message,
std::string const &amp;message,
epics::pvData::MessageType messageType);
private:
PVDatabase();
@@ -1227,13 +1227,13 @@ class ExampleServer :
public:
POINTER_DEFINITIONS(ExampleServer);
static ExampleServerPtr create(
epics::pvData::String const &amp; recordName);
std::string const &amp; recordName);
virtual ~ExampleServer();
virtual void destroy();
virtual bool init();
virtual void process();
private:
ExampleServer(epics::pvData::String const &amp; recordName,
ExampleServer(std::string const &amp; recordName,
epics::pvData::PVStructurePtr const &amp; pvStructure);
epics::pvData::PVStringPtr pvArgumentValue;
@@ -1271,7 +1271,7 @@ private:
<p>The implementation of create method is:</p>
<pre>
ExampleServerPtr ExampleServer::create(
epics::pvData::String const &amp; recordName)
std::string const &amp; recordName)
{
StandardPVFieldPtr standardPVField = getStandardPVField();
PVDataCreatePtr pvDataCreate = getPVDataCreate();
@@ -1302,7 +1302,7 @@ This:
<p>The private constructor method is:</p>
<pre>
ExampleServer::ExampleServer(
epics::pvData::String const &amp; recordName,
std::string const &amp; recordName,
epics::pvData::PVStructurePtr const &amp; pvStructure)
: PVRecord(recordName,pvStructure)
{
@@ -1576,9 +1576,9 @@ class ExampleLink :
public:
POINTER_DEFINITIONS(ExampleLink);
static ExampleLinkPtr create(
epics::pvData::String const &amp; recordName,
epics::pvData::String const &amp; providerName,
epics::pvData::String const &amp; channelName
std::string const &amp; recordName,
std::string const &amp; providerName,
std::string const &amp; channelName
);
virtual ~ExampleLink() {}
virtual void destroy();

View File

@@ -20,5 +20,9 @@ CHECK_RELEASE = WARN
# INSTALL_LOCATION here.
#INSTALL_LOCATION=</path/name/to/install/top>
INSTALL_INCLUDE = $(INSTALL_LOCATION)/include/pv
USR_INCLUDES += -I $(INSTALL_LOCATION)/include
-include $(TOP)/../configure/CONFIG_SITE.local
-include $(TOP)/../../CONFIG_SITE.local
-include $(TOP)/../CONFIG.local

View File

@@ -27,7 +27,7 @@
# If this example is built in a directory under pvDatabaseCPP,
# use the following definitions:
PVDATABASETEST = $(TOP)/../testTop
PVDATABASETEST = $(TOP)/../test
PVDATABASE = $(TOP)/..
-include $(TOP)/../configure/RELEASE.local

View File

@@ -3,23 +3,26 @@ TOP=../..
include $(TOP)/configure/CONFIG
#----------------------------------------
# ADD MACRO DEFINITIONS AFTER THIS LINE
#=============================
#==================================================
# Build an IOC support library
#
DBD += exampleDatabase.dbd
exampleDatabase_DBD += base.dbd
exampleDatabase_DBD += PVAServerRegister.dbd
exampleDatabase_DBD += registerChannelProviderLocal.dbd
exampleDatabase_DBD += dbPv.dbd
exampleDatabase_DBD += powerSupplyRegister.dbd
exampleDatabase_DBD += exampleDatabaseRegister.dbd
#=============================
# build an ioc application
PROD_IOC += exampleDatabase
# <name>_registerRecordDeviceDriver.cpp will be created from <name>.dbd
exampleDatabase_SRCS += exampleDatabase_registerRecordDeviceDriver.cpp
exampleDatabase_SRCS_DEFAULT += exampleDatabaseMain.cpp
exampleDatabase_SRCS_vxWorks += -nil-
# The following adds support from base/src/vxWorks
exampleDatabase_OBJS_vxWorks += $(EPICS_BASE_BIN)/vxComLibrary

View File

@@ -0,0 +1,7 @@
include "base.dbd"
include "PVAServerRegister.dbd"
include "registerChannelProviderLocal.dbd"
include "dbPv.dbd"
include "powerSupplyRegister.dbd"
registrar("exampleDatabaseRegister")
registrar("exampleMonitorPluginRegister")

View File

@@ -7,7 +7,12 @@ dbLoadDatabase("dbd/exampleDatabase.dbd")
exampleDatabase_registerRecordDeviceDriver(pdbbase)
## Load record instances
dbLoadRecords("db/dbScalar.db","name=double00,type=ao")
dbLoadRecords("db/dbScalar.db","name=double01,type=ao")
dbLoadRecords("db/dbScalar.db","name=double02,type=ao")
dbLoadRecords("db/dbScalar.db","name=double03,type=ao")
dbLoadRecords("db/dbScalar.db","name=double04,type=ao")
dbLoadRecords("db/dbScalar.db","name=double05,type=ao")
dbLoadRecords("db/dbStringArray.db","name=stringArray01")
dbLoadRecords("db/dbEnum.db","name=enum01")
dbLoadRecords("db/dbCounter.db","name=counter01");
@@ -17,5 +22,6 @@ iocInit()
dbl
epicsThreadSleep(2.0)
exampleDatabase
exampleMonitorPlugin
startPVAServer
pvdbl

View File

@@ -4,17 +4,20 @@ include $(TOP)/configure/CONFIG
#----------------------------------------
# ADD MACRO DEFINITIONS AFTER THIS LINE
DBD += exampleDatabaseRegister.dbd
DBD += exampleDatabase.dbd
INC += exampleDatabase.h
INC += exampleMonitorPlugin.h
LIBRARY += exampleDatabase
exampleDatabase_SRCS += exampleDatabase.cpp
exampleDatabase_SRCS += exampleMonitorPlugin.cpp
exampleDatabase_SRCS += exampleDatabaseRegister.cpp
exampleDatabase_LIBS += powerSupply
exampleDatabase_SRCS += exampleMonitorPluginRegister.cpp
exampleDatabase_LIBS += pvDatabase
exampleDatabase_LIBS += pvAccess
exampleDatabase_LIBS += pvData
exampleDatabase_LIBS += Com
exampleDatabase_LIBS += $(EPICS_BASE_IOC_LIBS)
PROD_HOST += exampleDatabaseMain

View File

@@ -26,8 +26,8 @@
#include <pv/recordList.h>
#include <pv/traceRecord.h>
#include <powerSupply.h>
#include <exampleDatabase.h>
#include <pv/powerSupply.h>
#include <pv/exampleDatabase.h>
using namespace std;
using std::tr1::static_pointer_cast;
@@ -42,18 +42,57 @@ static StandardPVFieldPtr standardPVField = getStandardPVField();
static void createStructureArrayRecord(
PVDatabasePtr const &master,
ScalarType scalarType,
String const &recordName)
string const &recordName)
{
StructureConstPtr structure = standardField->scalar(
pvDouble,
String("value,alarm,timeStamp"));
StringArray names(2);
FieldConstPtrArray fields(2);
names[0] = "timeStamp";
names[0] = "name";
names[1] = "value";
fields[0] = standardField->timeStamp();
fields[1] = fieldCreate->createStructureArray(structure);
fields[0] = fieldCreate->createScalar(pvString);
fields[1] = fieldCreate->createScalar(pvString);
StringArray topNames(1);
FieldConstPtrArray topFields(1);
topNames[0] = "value";
topFields[0] = fieldCreate->createStructureArray(
fieldCreate->createStructure(names, fields));
StructureConstPtr top = fieldCreate->createStructure(topNames,topFields);
PVStructurePtr pvStructure = pvDataCreate->createPVStructure(top);
PVRecordPtr pvRecord = PVRecord::create(recordName,pvStructure);
bool result = master->addRecord(pvRecord);
if(!result) cout<< "record " << recordName << " not added" << endl;
}
static void createRegularUnionArrayRecord(
PVDatabasePtr const &master,
string const &recordName)
{
StringArray unionNames(2);
FieldConstPtrArray unionFields(2);
unionNames[0] = "string";
unionNames[1] = "stringArray";
unionFields[0] = fieldCreate->createScalar(pvString);
unionFields[1] = fieldCreate->createScalarArray(pvString);
StringArray names(1);
FieldConstPtrArray fields(1);
fields[0] = fieldCreate->createUnionArray(fieldCreate->createUnion(unionNames,unionFields));
names[0] = "value";
StructureConstPtr top = fieldCreate->createStructure(names,fields);
PVStructurePtr pvStructure = pvDataCreate->createPVStructure(top);
PVRecordPtr pvRecord = PVRecord::create(recordName,pvStructure);
bool result = master->addRecord(pvRecord);
if(!result) cout<< "record " << recordName << " not added" << endl;
}
static void createVariantUnionArrayRecord(
PVDatabasePtr const &master,
string const &recordName)
{
StringArray names(1);
FieldConstPtrArray fields(1);
fields[0] = fieldCreate->createVariantUnionArray();
names[0] = "value";
StructureConstPtr top = fieldCreate->createStructure(names,fields);
PVStructurePtr pvStructure = pvDataCreate->createPVStructure(top);
PVRecordPtr pvRecord = PVRecord::create(recordName,pvStructure);
@@ -64,10 +103,10 @@ static void createStructureArrayRecord(
static void createRecords(
PVDatabasePtr const &master,
ScalarType scalarType,
String const &recordNamePrefix,
String const &properties)
string const &recordNamePrefix,
string const &properties)
{
String recordName = recordNamePrefix;
string recordName = recordNamePrefix;
PVStructurePtr pvStructure = standardPVField->scalar(scalarType,properties);
PVRecordPtr pvRecord = PVRecord::create(recordName,pvStructure);
bool result = master->addRecord(pvRecord);
@@ -82,13 +121,13 @@ void ExampleDatabase::create()
{
PVDatabasePtr master = PVDatabase::getMaster();
PVRecordPtr pvRecord;
String recordName;
string recordName;
bool result(false);
recordName = "traceRecordPGRPC";
pvRecord = TraceRecord::create(recordName);
result = master->addRecord(pvRecord);
if(!result) cout<< "record " << recordName << " not added" << endl;
String properties;
string properties;
properties = "alarm,timeStamp";
createRecords(master,pvBoolean,"exampleBoolean",properties);
createRecords(master,pvByte,"exampleByte",properties);
@@ -97,8 +136,15 @@ void ExampleDatabase::create()
createRecords(master,pvLong,"exampleLong",properties);
createRecords(master,pvFloat,"exampleFloat",properties);
createRecords(master,pvDouble,"exampleDouble",properties);
createRecords(master,pvDouble,"exampleDouble01",properties);
createRecords(master,pvDouble,"exampleDouble02",properties);
createRecords(master,pvDouble,"exampleDouble03",properties);
createRecords(master,pvDouble,"exampleDouble04",properties);
createRecords(master,pvDouble,"exampleDouble05",properties);
createRecords(master,pvString,"exampleString",properties);
createStructureArrayRecord(master,pvDouble,"exampleStructureArray");
createStructureArrayRecord(master,"exampleStructureArray");
createRegularUnionArrayRecord(master,"exampleRegularUnionArray");
createVariantUnionArrayRecord(master,"exampleVariantUnionArray");
recordName = "examplePowerSupply";
PVStructurePtr pvStructure = createPowerSupply();
PowerSupplyPtr psr =

View File

@@ -0,0 +1,2 @@
registrar("exampleDatabaseRegister")
registrar("exampleMonitorPluginRegister")

View File

@@ -22,7 +22,8 @@
#include <pv/channelProviderLocal.h>
#include <pv/serverContext.h>
#include <exampleDatabase.h>
#include <pv/exampleDatabase.h>
#include <pv/exampleMonitorPlugin.h>
using namespace std;
using std::tr1::static_pointer_cast;
@@ -36,13 +37,12 @@ int main(int argc,char *argv[])
PVDatabasePtr master = PVDatabase::getMaster();
ChannelProviderLocalPtr channelProvider = getChannelProviderLocal();
ExampleDatabase::create();
ExampleMonitorPlugin::create();
ServerContext::shared_pointer ctx =
startPVAServer(PVACCESS_ALL_PROVIDERS,0,true,true);
cout << "exampleDatabase\n";
PVStringArrayPtr pvNames = master->getRecordNames();
String buffer;
pvNames->toString(&buffer);
cout << "recordNames" << endl << buffer << endl;
cout << "recordNames" << endl << *pvNames << endl;
string str;
while(true) {
cout << "Type exit to stop: \n";
@@ -55,4 +55,3 @@ int main(int argc,char *argv[])
channelProvider->destroy();
return 0;
}

View File

@@ -33,7 +33,7 @@
#include <epicsExport.h>
#include <exampleDatabase.h>
#include <pv/exampleDatabase.h>
using namespace epics::pvData;
using namespace epics::pvAccess;

View File

@@ -1 +0,0 @@
registrar("exampleDatabaseRegister")

View File

@@ -0,0 +1,99 @@
/* exampleMonitorPlugin.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 2014.04.16
*/
#include <pv/convert.h>
#include <pv/monitorPlugin.h>
#include <pv/exampleMonitorPlugin.h>
using namespace epics::pvData;
using std::cout;
using std::endl;
using std::string;
namespace epics { namespace pvDatabase {
static string pluginName("onChange");
static ConvertPtr convert(getConvert());
class OnChangePlugin;
typedef std::tr1::shared_ptr<OnChangePlugin> OnChangePluginPtr;
class OnChangePluginCreator;
typedef std::tr1::shared_ptr<OnChangePluginCreator> OnChangePluginCreatorPtr;
class OnChangePlugin : public MonitorPlugin
{
public:
virtual ~OnChangePlugin(){}
OnChangePlugin() {}
bool init(
FieldConstPtr const &field,
StructureConstPtr const &top,
PVStructurePtr const &pvFieldOptions)
{
pvField = getPVDataCreate()->createPVField(field);
raiseMonitor = true;
if(pvFieldOptions!=NULL) {
PVStringPtr pvString =
pvFieldOptions->getSubField<PVString>("raiseMonitor");
if(pvString!=NULL) {
string value = pvString->get();
if(value.compare("false")==0) raiseMonitor = false;
}
}
return true;
}
virtual string &getName(){return pluginName;}
virtual bool causeMonitor(
PVFieldPtr const &pvNew,
PVStructurePtr const &pvTop,
MonitorElementPtr const &monitorElement)
{
bool isSame = convert->equals(pvNew,pvField);
if(isSame) return false;
convert->copy(pvNew,pvField);
return raiseMonitor;
}
private:
PVFieldPtr pvField;
bool raiseMonitor;
};
class OnChangePluginCreator : public MonitorPluginCreator
{
public:
virtual string &getName(){return pluginName;}
virtual MonitorPluginPtr create(
FieldConstPtr const &field,
StructureConstPtr const &top,
PVStructurePtr const &pvFieldOptions)
{
OnChangePluginPtr plugin(new OnChangePlugin());
bool result = plugin->init(field,top,pvFieldOptions);
if(!result) return MonitorPluginPtr();
return plugin;
}
};
void ExampleMonitorPlugin::create()
{
static OnChangePluginCreatorPtr plugin;
static Mutex mutex;
Lock xx(mutex);
if(plugin==NULL) {
plugin = OnChangePluginCreatorPtr(new OnChangePluginCreator());
MonitorPluginManager::get()->addPlugin(pluginName,plugin);
}
}
}}

View File

@@ -0,0 +1,29 @@
/* exampleMonitorPlugin.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 2014.04.16
*/
#ifndef EXAMPLEMONITORPLUGIN_H
#define EXAMPLEMONITORPLUGIN_H
#include <shareLib.h>
#include <pv/pvDatabase.h>
#include <pv/monitorPlugin.h>
namespace epics { namespace pvDatabase {
class epicsShareClass ExampleMonitorPlugin{
public:
static void create();
};
}}
#endif /* EXAMPLEMONITORPLUGIN_H */

View File

@@ -0,0 +1,64 @@
/*exampleMonitorPlugin.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.07.24
*/
/* Author: Marty Kraimer */
#include <cstddef>
#include <cstdlib>
#include <cstddef>
#include <string>
#include <cstdio>
#include <memory>
#include <cantProceed.h>
#include <epicsStdio.h>
#include <epicsMutex.h>
#include <epicsEvent.h>
#include <epicsThread.h>
#include <iocsh.h>
#include <epicsExport.h>
#include <pv/pvIntrospect.h>
#include <pv/pvData.h>
#include <pv/pvAccess.h>
#include <pv/pvDatabase.h>
#include <pv/exampleMonitorPlugin.h>
using namespace epics::pvData;
using namespace epics::pvAccess;
using namespace epics::pvDatabase;
static const iocshFuncDef exampleMonitorPluginFuncDef = {
"exampleMonitorPlugin", 0,0 };
static void exampleMonitorPluginCallFunc(const iocshArgBuf *args)
{
ExampleMonitorPlugin::create();
}
static void exampleMonitorPluginRegister(void)
{
std::cout << "exampleMonitorPluginRegister\n";
static int firstTime = 1;
if (firstTime) {
firstTime = 0;
iocshRegister(&exampleMonitorPluginFuncDef, exampleMonitorPluginCallFunc);
}
std::cout << "exampleMonitorPluginRegister returning\n";
}
extern "C" {
epicsExportRegistrar(exampleMonitorPluginRegister);
}

View File

@@ -1,8 +1,6 @@
# Makefile at top of application tree
#Makefile at top of application tree
TOP = .
include $(TOP)/configure/CONFIG
DIRS += configure
DIRS += src
@@ -12,7 +10,6 @@ DIRS += ioc
ioc_DEPEND_DIRS = src
DIRS += iocBoot
iocBoot_DEPEND_DIRS = src
include $(TOP)/configure/RULES_TOP

View File

@@ -14,11 +14,26 @@
# Set CHECK_RELEASE to NO to disable checking completely.
# Set CHECK_RELEASE to WARN to perform consistency checking but
# continue building anyway if conflicts are found.
CHECK_RELEASE = WARN
#CHECK_RELEASE = YES
# Set this when you only want to compile this application
# for a subset of the cross-compiled target architectures
# that Base is built for.
#CROSS_COMPILER_TARGET_ARCHS = vxWorks-68040
# To install files into a location other than $(TOP) define
# INSTALL_LOCATION here.
#INSTALL_LOCATION=</path/name/to/install/top>
-include $(TOP)/../configure/CONFIG_SITE.local
-include $(TOP)/../../CONFIG_SITE.local
# Set this when your IOC and the host use different paths
# to access the application. This will be needed to boot
# from a Microsoft FTP server or with some NFS mounts.
# You must rebuild in the iocBoot directory for this to
# take effect.
#IOCS_APPL_TOP = </IOC/path/to/application/top>
INSTALL_INCLUDE = $(INSTALL_LOCATION)/include/pv
USR_INCLUDES += -I $(INSTALL_LOCATION)/include
-include $(TOP)/configure/CONFIG_SITE.local
-include $(TOP)/../CONFIG.local

View File

@@ -16,9 +16,8 @@
# EPICS V4 Developers: Do not edit the locations in this file!
#
# Create a file RELEASE.local pointing to your PVASRV, PVACCESS,
# PVDATA, PVCOMMON and EPICS_BASE build directories, e.g.
# PVASRV = /path/to/epics/pvaSrvCPP
# Create a file RELEASE.local pointing to your places
# for the dependencies, e.g.
# PVACCESS = /path/to/epics/pvAccessCPP
# PVDATA = /path/to/epics/pvDataCPP
# PVCOMMON = /path/to/epics/pvCommonCPP
@@ -28,14 +27,14 @@
# use the following definitions:
PVDATABASE = $(TOP)/..
-include $(TOP)/../configure/RELEASE.local
-include $(TOP)/../../RELEASE.local
-include $(TOP)/../configure/RELEASE.local
# If you copied this example from pvDatabaseCPP to be built as a
# standalone TOP, adjust and use the following definitions:
# standalone TOP, define
# PVDATABASE = /path/to/epics/pvDatabaseCPP
# in the appropriate RELEASE[.local],
# and use the following definitions instead:
#PVDATABASE = /path/to/epics/pvDatabaseCPP
#-include $(TOP)/configure/RELEASE.local
#-include $(TOP)/../RELEASE.local
#-include $(TOP)/configure/RELEASE.local

View File

@@ -3,22 +3,27 @@ TOP=../..
include $(TOP)/configure/CONFIG
#----------------------------------------
# ADD MACRO DEFINITIONS AFTER THIS LINE
#=============================
#==================================================
# Build an IOC support library
#
#=============================
# build an ioc application
DBD += exampleLink.dbd
exampleLink_DBD += base.dbd
exampleLink_DBD += PVAServerRegister.dbd
exampleLink_DBD += PVAClientRegister.dbd
exampleLink_DBD += registerChannelProviderLocal.dbd
exampleLink_DBD += exampleLinkRegister.dbd
PROD_IOC += exampleLink
# <name>_registerRecordDeviceDriver.cpp will be created from <name>.dbd
exampleLink_SRCS += exampleLink_registerRecordDeviceDriver.cpp
exampleLink_SRCS_DEFAULT += exampleLinkMain.cpp
exampleLink_SRCS_vxWorks += -nil-
# The following adds support from base/src/vxWorks
exampleLink_OBJS_vxWorks += $(EPICS_BASE_BIN)/vxComLibrary
@@ -27,6 +32,7 @@ exampleLink_LIBS += pvDatabase
exampleLink_LIBS += pvaSrv
exampleLink_LIBS += pvAccess
exampleLink_LIBS += pvData
exampleLink_LIBS += Com
exampleLink_LIBS += $(EPICS_BASE_IOC_LIBS)
#===========================

View File

@@ -0,0 +1,5 @@
include "base.dbd"
include "PVAServerRegister.dbd"
include "PVAClientRegister.dbd"
include "registerChannelProviderLocal.dbd"
registrar("exampleLinkRegister")

View File

@@ -3,8 +3,13 @@ TOP=..
include $(TOP)/configure/CONFIG
#----------------------------------------
# ADD MACRO DEFINITIONS AFTER THIS LINE
#=============================
DBD += exampleLinkRegister.dbd
#==================================================
# Build an IOC support library
#
DBD += exampleLink.dbd
INC += exampleLink.h

View File

@@ -9,25 +9,24 @@
* @date 2013.08.02
*/
#include <pv/exampleLink.h>
#include <pv/standardPVField.h>
#include <pv/convert.h>
#define epicsExportSharedSymbols
#include <exampleLink.h>
namespace epics { namespace pvDatabase {
using namespace epics::pvData;
using namespace epics::pvAccess;
using std::tr1::static_pointer_cast;
using std::tr1::dynamic_pointer_cast;
using std::cout;
using std::endl;
using std::string;
namespace epics { namespace pvDatabase {
ExampleLinkPtr ExampleLink::create(
String const & recordName,
String const & providerName,
String const & channelName)
string const & recordName,
string const & providerName,
string const & channelName)
{
PVStructurePtr pvStructure = getStandardPVField()->scalarArray(
pvDouble,"alarm.timeStamp");
@@ -39,9 +38,9 @@ ExampleLinkPtr ExampleLink::create(
}
ExampleLink::ExampleLink(
String const & recordName,
String providerName,
String channelName,
string const & recordName,
string providerName,
string channelName,
PVStructurePtr const & pvStructure)
: PVRecord(recordName,pvStructure),
providerName(providerName),
@@ -67,9 +66,8 @@ bool ExampleLink::init()
if(pvValue==NULL) {
return false;
}
ChannelAccess::shared_pointer channelAccess = getChannelAccess();
ChannelProvider::shared_pointer provider =
channelAccess->getProvider(providerName);
getChannelProviderRegistry()->getProvider(providerName);
if(provider==NULL) {
cout << getRecordName() << " provider "
<< providerName << " does not exist" << endl;
@@ -107,7 +105,7 @@ bool ExampleLink::init()
void ExampleLink::process()
{
status = Status::Ok;
channelGet->get(false);
channelGet->get();
event.wait();
timeStamp.getCurrent();
pvTimeStamp.set(timeStamp);
@@ -145,20 +143,23 @@ void ExampleLink::channelStateChange(
void ExampleLink::channelGetConnect(
const Status& status,
ChannelGet::shared_pointer const & channelGet,
PVStructure::shared_pointer const & pvStructure,
BitSet::shared_pointer const & bitSet)
StructureConstPtr const & structure)
{
this->status = status;
this->channelGet = channelGet;
this->getPVStructure = pvStructure;
event.signal();
}
void ExampleLink::getDone(
const Status& status,
ChannelGet::shared_pointer const & channelGet,
PVStructurePtr const & pvStructure,
BitSetPtr const & bitSet)
{
this->status = status;
getPVStructure = pvStructure;
this->bitSet = bitSet;
event.signal();
}
void ExampleLink::getDone(const Status& status)
{
this->status = status;
event.signal();
}
}}

View File

@@ -8,15 +8,11 @@
* @author mrk
* @date 2013.08.02
*/
#ifndef EXAMPLELINK_H
#define EXAMPLELINK_H
#ifndef EXAMPLEPVADOUBLEARRAYGET_H
#define EXAMPLEPVADOUBLEARRAYGET_H
#ifdef epicsExportSharedSymbols
# define examplelinkEpicsExportSharedSymbols
# undef epicsExportSharedSymbols
#endif
#include <shareLib.h>
//#include <shareLib.h>
#include <pv/timeStamp.h>
#include <pv/pvTimeStamp.h>
#include <pv/alarm.h>
@@ -26,14 +22,6 @@
#include <pv/pvAccess.h>
#include <pv/serverContext.h>
#ifdef examplelinkEpicsExportSharedSymbols
# define epicsExportSharedSymbols
# undef examplelinkEpicsExportSharedSymbols
# include <shareLib.h>
#endif
namespace epics { namespace pvDatabase {
@@ -48,9 +36,9 @@ class epicsShareClass ExampleLink :
public:
POINTER_DEFINITIONS(ExampleLink);
static ExampleLinkPtr create(
epics::pvData::String const & recordName,
epics::pvData::String const & providerName,
epics::pvData::String const & channelName
std::string const & recordName,
std::string const & providerName,
std::string const & channelName
);
virtual ~ExampleLink() {}
virtual void destroy();
@@ -65,23 +53,26 @@ public:
virtual void channelGetConnect(
const epics::pvData::Status& status,
epics::pvAccess::ChannelGet::shared_pointer const & channelGet,
epics::pvData::PVStructure::shared_pointer const & pvStructure,
epics::pvData::BitSet::shared_pointer const & bitSet);
virtual void getDone(const epics::pvData::Status& status);
virtual epics::pvData::String getRequesterName() {return channelName;}
epics::pvData::StructureConstPtr const & structure);
virtual void getDone(
const epics::pvData::Status& status,
epics::pvAccess::ChannelGet::shared_pointer const & channelGet,
epics::pvData::PVStructurePtr const & pvStructure,
epics::pvData::BitSetPtr const &bitSet);
virtual std::string getRequesterName() {return channelName;}
virtual void message(
epics::pvData::String const & message,
std::string const & message,
epics::pvData::MessageType messageType)
{
std::cout << "Why is ExampleLink::message called\n";
}
private:
ExampleLink(epics::pvData::String const & recordName,
epics::pvData::String providerName,
epics::pvData::String channelName,
ExampleLink(std::string const & recordName,
std::string providerName,
std::string channelName,
epics::pvData::PVStructurePtr const & pvStructure);
epics::pvData::String providerName;
epics::pvData::String channelName;
std::string providerName;
std::string channelName;
epics::pvData::ConvertPtr convert;
epics::pvData::PVDoubleArrayPtr pvValue;
epics::pvData::PVTimeStamp pvTimeStamp;
@@ -99,4 +90,4 @@ private:
}}
#endif /* EXAMPLELINK_H */
#endif /* EXAMPLEPVADOUBLEARRAYGET_H */

View File

@@ -0,0 +1 @@
registrar("exampleLinkRegister")

View File

@@ -27,22 +27,22 @@
#include <epicsThread.h>
#include <iocsh.h>
#include <epicsExport.h>
#include <pv/pvIntrospect.h>
#include <pv/pvData.h>
#include <pv/standardField.h>
#include <pv/standardPVField.h>
#include <pv/pvAccess.h>
#include <pv/pvDatabase.h>
#include <epicsExport.h>
#include <exampleLink.h>
#include <pv/exampleLink.h>
using namespace epics::pvData;
using namespace epics::pvAccess;
using namespace epics::pvDatabase;
using std::cout;
using std::endl;
using std::string;
static StandardPVFieldPtr standardPVField = getStandardPVField();
@@ -59,7 +59,7 @@ static void exampleLinkCallFunc(const iocshArgBuf *args)
PVDatabasePtr master = PVDatabase::getMaster();
PVRecordPtr pvRecord;
bool result(false);
String recordName;
string recordName;
PVStructurePtr pvStructure = standardPVField->scalarArray(
pvDouble,"alarm,timeStamp");
pvRecord = PVRecord::create("doubleArray",pvStructure);
@@ -86,4 +86,4 @@ static void exampleLinkRegister(void)
extern "C" {
epicsExportRegistrar(exampleLinkRegister);
}
}

View File

@@ -14,11 +14,26 @@
# Set CHECK_RELEASE to NO to disable checking completely.
# Set CHECK_RELEASE to WARN to perform consistency checking but
# continue building anyway if conflicts are found.
CHECK_RELEASE = WARN
#CHECK_RELEASE = YES
# Set this when you only want to compile this application
# for a subset of the cross-compiled target architectures
# that Base is built for.
#CROSS_COMPILER_TARGET_ARCHS = vxWorks-68040
# To install files into a location other than $(TOP) define
# INSTALL_LOCATION here.
#INSTALL_LOCATION=</path/name/to/install/top>
-include $(TOP)/../configure/CONFIG_SITE.local
-include $(TOP)/../../CONFIG_SITE.local
# Set this when your IOC and the host use different paths
# to access the application. This will be needed to boot
# from a Microsoft FTP server or with some NFS mounts.
# You must rebuild in the iocBoot directory for this to
# take effect.
#IOCS_APPL_TOP = </IOC/path/to/application/top>
INSTALL_INCLUDE = $(INSTALL_LOCATION)/include/pv
USR_INCLUDES += -I $(INSTALL_LOCATION)/include
-include $(TOP)/configure/CONFIG_SITE.local
-include $(TOP)/../CONFIG.local

View File

@@ -16,9 +16,8 @@
# EPICS V4 Developers: Do not edit the locations in this file!
#
# Create a file RELEASE.local pointing to your PVASRV, PVACCESS,
# PVDATA, PVCOMMON and EPICS_BASE build directories, e.g.
# PVASRV = /path/to/epics/pvaSrvCPP
# Create a file RELEASE.local pointing to your places
# for the dependencies, e.g.
# PVACCESS = /path/to/epics/pvAccessCPP
# PVDATA = /path/to/epics/pvDataCPP
# PVCOMMON = /path/to/epics/pvCommonCPP
@@ -27,17 +26,17 @@
# If this example is built in a directory under pvDatabaseCPP,
# use the following definitions:
PVDATABASETEST = $(TOP)/../testTop
PVDATABASE = $(TOP)/..
-include $(TOP)/../configure/RELEASE.local
PVDATABASETEST = $(TOP)/../test
-include $(TOP)/../../RELEASE.local
-include $(TOP)/../configure/RELEASE.local
# If you copied this example from pvDatabaseCPP to be built as a
# standalone TOP, adjust and use the following definitions:
#PVDATABASETEST = /path/to/epics/pvDatabaseCPP/testTop
#PVDATABASE = /path/to/epics/pvDatabaseCPP
# standalone TOP, define
# PVDATABASE = /path/to/epics/pvDatabaseCPP
# PVDATABASETEST = /path/to/epics/pvDatabaseCPP/test
# in the appropriate RELEASE[.local],
# and use the following definitions instead:
#-include $(TOP)/../RELEASE.local
#-include $(TOP)/configure/RELEASE.local

View File

@@ -3,22 +3,26 @@ TOP=../..
include $(TOP)/configure/CONFIG
#----------------------------------------
# ADD MACRO DEFINITIONS AFTER THIS LINE
#=============================
#==================================================
# Build an IOC support library
#
DBD += powerSupply.dbd
powerSupply_DBD += base.dbd
powerSupply_DBD += PVAServerRegister.dbd
powerSupply_DBD += registerChannelProviderLocal.dbd
powerSupply_DBD += dbPv.dbd
powerSupply_DBD += powerSupplyRegister.dbd
#=============================
# build an ioc application
PROD_IOC += powerSupply
# <name>_registerRecordDeviceDriver.cpp will be created from <name>.dbd
powerSupply_SRCS += powerSupply_registerRecordDeviceDriver.cpp
powerSupply_SRCS_DEFAULT += powerSupplyMain.cpp
powerSupply_SRCS_vxWorks += -nil-
# The following adds support from base/src/vxWorks
powerSupply_OBJS_vxWorks += $(EPICS_BASE_BIN)/vxComLibrary

View File

@@ -0,0 +1,5 @@
include "base.dbd"
include "PVAServerRegister.dbd"
include "registerChannelProviderLocal.dbd"
include "dbPv.dbd"
include "powerSupplyRegister.dbd"

View File

@@ -3,14 +3,21 @@ TOP=..
include $(TOP)/configure/CONFIG
#----------------------------------------
# ADD MACRO DEFINITIONS AFTER THIS LINE
#=============================
#==================================================
# Build an IOC support library
#
PROD_HOST += powerSupplyMain
powerSupplyMain_SRCS += powerSupplyMain.cpp
powerSupplyMain_LIBS += powerSupply
powerSupplyMain_LIBS += pvDatabase
powerSupplyMain_LIBS += pvAccess
powerSupplyMain_LIBS += pvData
powerSupplyMain_LIBS += Com
powerSupplyMain_LIBS += powerSupply
#===========================

View File

@@ -20,12 +20,11 @@
#include <pv/standardField.h>
#include <pv/standardPVField.h>
#include <pv/powerSupply.h>
#include <pv/traceRecord.h>
#include <pv/channelProviderLocal.h>
#include <pv/serverContext.h>
#include <powerSupply.h>
using namespace std;
using std::tr1::static_pointer_cast;
using namespace epics::pvData;
@@ -39,7 +38,7 @@ int main(int argc,char *argv[])
ChannelProviderLocalPtr channelProvider = getChannelProviderLocal();
PVRecordPtr pvRecord;
bool result(false);
String recordName;
string recordName;
recordName = "powerSupply";
PVStructurePtr pv = createPowerSupply();
pvRecord = PowerSupply::create(recordName,pv);

View File

@@ -1,8 +1,6 @@
# Makefile at top of application tree
#Makefile at top of application tree
TOP = .
include $(TOP)/configure/CONFIG
DIRS += configure
DIRS += src
@@ -12,7 +10,6 @@ DIRS += ioc
ioc_DEPEND_DIRS = src
DIRS += iocBoot
iocBoot_DEPEND_DIRS = src
include $(TOP)/configure/RULES_TOP

View File

@@ -14,11 +14,26 @@
# Set CHECK_RELEASE to NO to disable checking completely.
# Set CHECK_RELEASE to WARN to perform consistency checking but
# continue building anyway if conflicts are found.
CHECK_RELEASE = WARN
#CHECK_RELEASE = YES
# Set this when you only want to compile this application
# for a subset of the cross-compiled target architectures
# that Base is built for.
#CROSS_COMPILER_TARGET_ARCHS = vxWorks-68040
# To install files into a location other than $(TOP) define
# INSTALL_LOCATION here.
#INSTALL_LOCATION=</path/name/to/install/top>
-include $(TOP)/../configure/CONFIG_SITE.local
-include $(TOP)/../../CONFIG_SITE.local
# Set this when your IOC and the host use different paths
# to access the application. This will be needed to boot
# from a Microsoft FTP server or with some NFS mounts.
# You must rebuild in the iocBoot directory for this to
# take effect.
#IOCS_APPL_TOP = </IOC/path/to/application/top>
INSTALL_INCLUDE = $(INSTALL_LOCATION)/include/pv
USR_INCLUDES += -I $(INSTALL_LOCATION)/include
-include $(TOP)/configure/CONFIG_SITE.local
-include $(TOP)/../CONFIG.local

View File

@@ -16,9 +16,8 @@
# EPICS V4 Developers: Do not edit the locations in this file!
#
# Create a file RELEASE.local pointing to your PVASRV, PVACCESS,
# PVDATA, PVCOMMON and EPICS_BASE build directories, e.g.
# PVASRV = /path/to/epics/pvaSrvCPP
# Create a file RELEASE.local pointing to your places
# for the dependencies, e.g.
# PVACCESS = /path/to/epics/pvAccessCPP
# PVDATA = /path/to/epics/pvDataCPP
# PVCOMMON = /path/to/epics/pvCommonCPP
@@ -28,14 +27,14 @@
# use the following definitions:
PVDATABASE = $(TOP)/..
-include $(TOP)/../configure/RELEASE.local
-include $(TOP)/../../RELEASE.local
-include $(TOP)/../configure/RELEASE.local
# If you copied this example from pvDatabaseCPP to be built as a
# standalone TOP, adjust and use the following definitions:
# standalone TOP, define
# PVDATABASE = /path/to/epics/pvDatabaseCPP
# in the appropriate RELEASE[.local],
# and use the following definitions instead:
#PVDATABASE = /path/to/epics/pvDatabaseCPP
#-include $(TOP)/configure/RELEASE.local
#-include $(TOP)/../RELEASE.local
#-include $(TOP)/configure/RELEASE.local

View File

@@ -3,22 +3,26 @@ TOP=../..
include $(TOP)/configure/CONFIG
#----------------------------------------
# ADD MACRO DEFINITIONS AFTER THIS LINE
#=============================
#==================================================
# Build an IOC support library
#
DBD += exampleServer.dbd
exampleServer_DBD += base.dbd
exampleServer_DBD += PVAServerRegister.dbd
exampleServer_DBD += registerChannelProviderLocal.dbd
exampleServer_DBD += dbPv.dbd
exampleServer_DBD += exampleServerRegister.dbd
#=============================
# build an ioc application
PROD_IOC += exampleServer
# <name>_registerRecordDeviceDriver.cpp will be created from <name>.dbd
exampleServer_SRCS += exampleServer_registerRecordDeviceDriver.cpp
exampleServer_SRCS_DEFAULT += exampleServerMain.cpp
exampleServer_SRCS_vxWorks += -nil-
# The following adds support from base/src/vxWorks
exampleServer_OBJS_vxWorks += $(EPICS_BASE_BIN)/vxComLibrary

View File

@@ -0,0 +1,5 @@
include "base.dbd"
include "PVAServerRegister.dbd"
include "registerChannelProviderLocal.dbd"
include "dbPv.dbd"
include "exampleServer.dbd"

View File

@@ -3,8 +3,14 @@ TOP=..
include $(TOP)/configure/CONFIG
#----------------------------------------
# ADD MACRO DEFINITIONS AFTER THIS LINE
#=============================
DBD += exampleServerRegister.dbd
#==================================================
# Build an IOC support library
#
DBD += exampleServer.dbd
INC += exampleServer.h
@@ -14,6 +20,7 @@ exampleServer_SRCS += exampleServerRegister.cpp
exampleServer_LIBS += pvDatabase
exampleServer_LIBS += pvAccess
exampleServer_LIBS += pvData
exampleServer_LIBS += Com
exampleServer_LIBS += $(EPICS_BASE_IOC_LIBS)
PROD_HOST += exampleServerMain

View File

@@ -10,19 +10,18 @@
*/
#include <pv/standardPVField.h>
#include <pv/exampleServer.h>
#define epicsExportSharedSymbols
#include <exampleServer.h>
namespace epics { namespace exampleServer {
using namespace epics::pvData;
using namespace epics::pvDatabase;
using std::tr1::static_pointer_cast;
using std::string;
namespace epics { namespace exampleServer {
ExampleServerPtr ExampleServer::create(
String const & recordName)
string const & recordName)
{
StandardPVFieldPtr standardPVField = getStandardPVField();
PVDataCreatePtr pvDataCreate = getPVDataCreate();
@@ -44,7 +43,7 @@ ExampleServerPtr ExampleServer::create(
}
ExampleServer::ExampleServer(
String const & recordName,
string const & recordName,
PVStructurePtr const & pvStructure)
: PVRecord(recordName,pvStructure)
{
@@ -74,7 +73,7 @@ bool ExampleServer::init()
void ExampleServer::process()
{
pvResultValue->put(String("Hello ") + pvArgumentValue->get());
pvResultValue->put(string("Hello ") + pvArgumentValue->get());
timeStamp.getCurrent();
pvTimeStamp.set(timeStamp);
}

View File

@@ -8,26 +8,15 @@
* @author mrk
* @date 2013.04.02
*/
#ifndef EXAMPLESERVER_H
#define EXAMPLESERVER_H
#ifdef epicsExportSharedSymbols
# define exampleServerEpicsExportSharedSymbols
# undef epicsExportSharedSymbols
#endif
#ifndef EXAMPLECOUNTER_H
#define EXAMPLECOUNTER_H
#include <shareLib.h>
#include <pv/pvDatabase.h>
#include <pv/timeStamp.h>
#include <pv/pvTimeStamp.h>
#ifdef exampleServerEpicsExportSharedSymbols
# define epicsExportSharedSymbols
# undef exampleServerEpicsExportSharedSymbols
# include <shareLib.h>
#endif
namespace epics { namespace exampleServer {
@@ -40,13 +29,13 @@ class epicsShareClass ExampleServer :
public:
POINTER_DEFINITIONS(ExampleServer);
static ExampleServerPtr create(
epics::pvData::String const & recordName);
std::string const & recordName);
virtual ~ExampleServer();
virtual void destroy();
virtual bool init();
virtual void process();
private:
ExampleServer(epics::pvData::String const & recordName,
ExampleServer(std::string const & recordName,
epics::pvData::PVStructurePtr const & pvStructure);
epics::pvData::PVStringPtr pvArgumentValue;
@@ -58,4 +47,4 @@ private:
}}
#endif /* EXAMPLESERVER_H */
#endif /* EXAMPLECOUNTER_H */

View File

@@ -0,0 +1 @@
registrar("exampleServerRegister")

View File

@@ -20,12 +20,11 @@
#include <pv/standardField.h>
#include <pv/standardPVField.h>
#include <pv/exampleServer.h>
#include <pv/traceRecord.h>
#include <pv/channelProviderLocal.h>
#include <pv/serverContext.h>
#include <exampleServer.h>
using namespace std;
using std::tr1::static_pointer_cast;
using namespace epics::pvData;
@@ -39,7 +38,7 @@ int main(int argc,char *argv[])
ChannelProviderLocalPtr channelProvider = getChannelProviderLocal();
PVRecordPtr pvRecord;
bool result(false);
String recordName;
string recordName;
recordName = "exampleServer";
pvRecord = ExampleServer::create(recordName);
result = master->addRecord(pvRecord);

View File

@@ -27,14 +27,13 @@
#include <epicsThread.h>
#include <iocsh.h>
#include <epicsExport.h>
#include <pv/pvIntrospect.h>
#include <pv/pvData.h>
#include <pv/pvAccess.h>
#include <pv/pvDatabase.h>
#include <epicsExport.h>
#include <exampleServer.h>
#include <pv/exampleServer.h>
using namespace epics::pvData;
using namespace epics::pvAccess;

View File

@@ -3,9 +3,6 @@
TOP = ..
include $(TOP)/configure/CONFIG
INSTALL_INCLUDE = $(INSTALL_LOCATION)/include/pv
USR_INCLUDES += -I$(INSTALL_LOCATION)/include
PVDATABASE_SRC = $(TOP)/src
LIBRARY += pvDatabase

View File

@@ -70,7 +70,7 @@ void PVDatabase::unlock() {
mutex.unlock();
}
PVRecordPtr PVDatabase::findRecord(String const& recordName)
PVRecordPtr PVDatabase::findRecord(string const& recordName)
{
lock();
try {
@@ -104,13 +104,13 @@ PVStringArrayPtr PVDatabase::getRecordNames()
PVStringArrayPtr pvStringArray = static_pointer_cast<PVStringArray>
(getPVDataCreate()->createPVScalarArray(pvString));
size_t len = recordMap.size();
shared_vector<String> names(len);
shared_vector<string> names(len);
PVRecordMap::iterator iter;
size_t i = 0;
for(iter = recordMap.begin(); iter!=recordMap.end(); ++iter) {
names[i++] = (*iter).first;
}
shared_vector<const String> temp(freeze(names));
shared_vector<const string> temp(freeze(names));
pvStringArray->replace(temp);
unlock();
return pvStringArray;
@@ -128,7 +128,7 @@ bool PVDatabase::addRecord(PVRecordPtr const & record)
unlock();
return false;
}
String recordName = record->getRecordName();
string recordName = record->getRecordName();
PVRecordMap::iterator iter = recordMap.find(recordName);
if(iter!=recordMap.end()) {
unlock();
@@ -152,7 +152,7 @@ bool PVDatabase::removeRecord(PVRecordPtr const & record)
unlock();
return false;
}
String recordName = record->getRecordName();
string recordName = record->getRecordName();
PVRecordMap::iterator iter = recordMap.find(recordName);
if(iter!=recordMap.end()) {
PVRecordPtr pvRecord = (*iter).second;

View File

@@ -35,7 +35,7 @@ namespace epics { namespace pvDatabase {
class PVRecord;
typedef std::tr1::shared_ptr<PVRecord> PVRecordPtr;
typedef std::map<epics::pvData::String,PVRecordPtr> PVRecordMap;
typedef std::map<std::string,PVRecordPtr> PVRecordMap;
class PVRecordField;
typedef std::tr1::shared_ptr<PVRecordField> PVRecordFieldPtr;
@@ -77,7 +77,7 @@ public:
*/
virtual void start() {}
/**
* Must be implemented by derived classes.
* Optional method.
* It is the method that makes a record smart.
* If it encounters errors it should raise alarms and/or
* call the <b>message</b> method provided by the base class.
@@ -97,7 +97,7 @@ public:
* @return A shared pointer to the newly created record.
*/
static PVRecordPtr create(
epics::pvData::String const & recordName,
std::string const & recordName,
epics::pvData::PVStructurePtr const & pvStructure);
/**
* The Destructor. Must be virtual.
@@ -107,12 +107,12 @@ public:
* Get the name of the record.
* @return The name.
*/
epics::pvData::String getRecordName();
std::string getRecordName() const;
/**
* Get the top level PVStructure.
* @return The shared pointer.
*/
PVRecordStructurePtr getPVRecordStructure();
PVRecordStructurePtr getPVRecordStructure() const;
/**
* Find the PVRecordField for the PVField.
* @param pvField The PVField.
@@ -183,17 +183,6 @@ public:
* Ends a group of puts.
*/
void endGroupPut();
/**
* Calls the next method with indentLevel = 0.
* @param buf String Builder.
*/
void toString(epics::pvData::StringBuilder buf);
/**
* Dumps the data from the top level PVStructure.
* @param buf String Builder.
* @param indentLevel The indentation level.
*/
void toString(epics::pvData::StringBuilder buf,int indentLevel);
/**
* get trace level (0,1,2) means (nothing,lifetime,process)
* @return the level
@@ -211,7 +200,7 @@ protected:
* @param pvStructure The top level PVStructutre
*/
PVRecord(
epics::pvData::String const & recordName,
std::string const & recordName,
epics::pvData::PVStructurePtr const & pvStructure);
/**
* Initializes the base class. Must be called by derived classes.
@@ -230,7 +219,7 @@ private:
PVRecordFieldPtr findPVRecordField(
PVRecordStructurePtr const & pvrs,
epics::pvData::PVFieldPtr const & pvField);
epics::pvData::String recordName;
std::string recordName;
epics::pvData::PVStructurePtr pvStructure;
epics::pvData::ConvertPtr convert;
PVRecordStructurePtr pvRecordStructure;
@@ -242,6 +231,8 @@ private:
bool isDestroyed;
};
epicsShareExtern std::ostream& operator<<(std::ostream& o, const PVRecord& record);
/**
* Interface for a field of a record.
* One exists for each field of the top level PVStructure.
@@ -284,12 +275,12 @@ public:
* Get the full name of the field, i.e. field,field,..
* @return The full name.
*/
epics::pvData::String getFullFieldName();
std::string getFullFieldName();
/**
* Get the recordName plus the full name of the field, i.e. recordName.field,field,..
* @return The name.
*/
epics::pvData::String getFullName();
std::string getFullName();
/**
* Returns the PVRecord to which this field belongs.
* @return The shared pointer,
@@ -331,8 +322,8 @@ private:
bool isStructure;
PVRecordStructurePtr parent;
PVRecordPtr pvRecord;
epics::pvData::String fullName;
epics::pvData::String fullFieldName;
std::string fullName;
std::string fullFieldName;
friend class PVRecordStructure;
friend class PVRecord;
};
@@ -481,7 +472,7 @@ public:
* @param recordName The record to find.
* @return The shared pointer.
*/
PVRecordPtr findRecord(epics::pvData::String const& recordName);
PVRecordPtr findRecord(std::string const& recordName);
/**
* Add a record.
* @param The record to add.

View File

@@ -22,7 +22,7 @@ using namespace std;
namespace epics { namespace pvDatabase {
PVRecordPtr PVRecord::create(
String const &recordName,
string const &recordName,
PVStructurePtr const & pvStructure)
{
PVRecordPtr pvRecord(new PVRecord(recordName,pvStructure));
@@ -35,7 +35,7 @@ PVRecordPtr PVRecord::create(
PVRecord::PVRecord(
String const & recordName,
string const & recordName,
PVStructurePtr const & pvStructure)
: recordName(recordName),
pvStructure(pvStructure),
@@ -103,9 +103,9 @@ void PVRecord::destroy()
}
}
String PVRecord::getRecordName() {return recordName;}
string PVRecord::getRecordName() const {return recordName;}
PVRecordStructurePtr PVRecord::getPVRecordStructure() {return pvRecordStructure;}
PVRecordStructurePtr PVRecord::getPVRecordStructure() const {return pvRecordStructure;}
PVStructurePtr PVRecord::getPVStructure() {return pvStructure;}
@@ -346,15 +346,14 @@ void PVRecord::endGroupPut()
}
}
void PVRecord::toString(StringBuilder buf)
std::ostream& operator<<(std::ostream& o, const PVRecord& record)
{
toString(buf,0);
}
void PVRecord::toString(StringBuilder buf,int indentLevel)
{
*buf += "\nrecord " + recordName + " ";
pvRecordStructure->getPVStructure()->toString(buf, indentLevel);
o << format::indent() << "record " << record.getRecordName() << endl;
{
format::indent_scope s(o);
o << *record.getPVRecordStructure()->getPVStructure();
}
return o;
}
PVRecordField::PVRecordField(
@@ -373,7 +372,7 @@ void PVRecordField::init()
fullFieldName = pvField->getFieldName();
PVRecordStructurePtr pvParent = parent;
while(pvParent.get()!= NULL) {
String parentName = pvParent->getPVField()->getFieldName();
string parentName = pvParent->getPVField()->getFieldName();
if(parentName.size()>0) {
fullFieldName = pvParent->getPVField()->getFieldName()
+ '.' + fullFieldName;
@@ -404,9 +403,9 @@ PVRecordStructurePtr PVRecordField::getParent() {return parent;}
PVFieldPtr PVRecordField::getPVField() {return pvField;}
String PVRecordField::getFullFieldName() {return fullFieldName; }
string PVRecordField::getFullFieldName() {return fullFieldName; }
String PVRecordField::getFullName() {return fullName; }
string PVRecordField::getFullName() {return fullName; }
PVRecordPtr PVRecordField::getPVRecord() {return pvRecord;}

View File

@@ -3,13 +3,13 @@
SRC_DIRS += $(PVDATABASE_SRC)/pvAccess
INC += channelProviderLocal.h
INC += pvCopy.h
INC += monitorAlgorithm.h
INC += pvCopyMonitor.h
DBD += registerChannelProviderLocal.dbd
LIBSRCS += channelProviderLocal.cpp
LIBSRCS += pvCopy.cpp
LIBSRCS += monitorFactory.cpp
LIBSRCS += channelLocal.cpp
LIBSRCS += pvCopyMonitor.cpp
LIBSRCS += monitorFactory.cpp
LIBSRCS += registerChannelProviderLocal.cpp

View File

@@ -12,7 +12,6 @@
#include <sstream>
#include <epicsThread.h>
#include <pv/timeStamp.h>
#include <pv/convert.h>
#include <pv/pvSubArrayCopy.h>
@@ -21,15 +20,37 @@
#include <pv/channelProviderLocal.h>
namespace epics { namespace pvDatabase {
using namespace epics::pvData;
using namespace epics::pvAccess;
using std::tr1::static_pointer_cast;
using std::tr1::dynamic_pointer_cast;
using std::cout;
using std::endl;
using std::string;
namespace epics { namespace pvDatabase {
static ConvertPtr convert = getConvert();
static StructureConstPtr nullStructure;
static PVStructurePtr nullPVStructure;
static BitSetPtr nullBitSet;
static Status channelDestroyedStatus(
Status::STATUSTYPE_ERROR,
"was destroyed"
);
static Status illegalOffsetStatus(
Status::STATUSTYPE_ERROR,
"count must be >0"
);
static Status illegalCountStatus(
Status::STATUSTYPE_ERROR,
"count must be >0"
);
static Status illegalStrideStatus(
Status::STATUSTYPE_ERROR,
"stride must be >0"
);
class ChannelProcessLocal;
typedef std::tr1::shared_ptr<ChannelProcessLocal> ChannelProcessLocalPtr;
@@ -49,7 +70,7 @@ typedef std::tr1::shared_ptr<ChannelArrayLocal> ChannelArrayLocalPtr;
static bool getProcess(PVStructurePtr pvRequest,bool processDefault)
{
PVFieldPtr pvField = pvRequest->getSubField("record._options.process");
if(pvField.get()==NULL || pvField->getField()->getType()!=scalar) {
if(pvField==NULL || pvField->getField()->getType()!=scalar) {
return processDefault;
}
ScalarConstPtr scalar = static_pointer_cast<const Scalar>(
@@ -82,8 +103,12 @@ public:
ChannelProcessRequester::shared_pointer const & channelProcessRequester,
PVStructurePtr const & pvRequest,
PVRecordPtr const &pvRecord);
virtual void process(bool lastRequest);
virtual void process();
virtual void destroy();
virtual std::tr1::shared_ptr<Channel> getChannel()
{return channelLocal;}
virtual void cancel(){}
virtual void lastRequest() {}
virtual void lock() {mutex.lock();}
virtual void unlock() {mutex.unlock();}
private:
@@ -105,7 +130,6 @@ private:
{
}
bool isDestroyed;
bool callProcess;
ChannelLocalPtr channelLocal;
ChannelProcessRequester::shared_pointer channelProcessRequester;
PVRecordPtr pvRecord;
@@ -167,13 +191,11 @@ void ChannelProcessLocal::destroy()
channelLocal.reset();
}
void ChannelProcessLocal::process(bool lastRequest)
void ChannelProcessLocal::process()
{
if(isDestroyed) {
Status status(
Status::STATUSTYPE_ERROR,
"was destroyed");
channelProcessRequester->processDone(status);
channelProcessRequester->processDone(channelDestroyedStatus,getPtrSelf());
return;
}
if(pvRecord->getTraceLevel()>1)
@@ -193,8 +215,7 @@ void ChannelProcessLocal::process(bool lastRequest)
}
pvRecord->unlock();
}
channelProcessRequester->processDone(Status::Ok);
if(lastRequest) destroy();
channelProcessRequester->processDone(Status::Ok,getPtrSelf());
}
class ChannelGetLocal :
@@ -215,8 +236,12 @@ public:
ChannelGetRequester::shared_pointer const & channelGetRequester,
PVStructurePtr const & pvRequest,
PVRecordPtr const &pvRecord);
virtual void get(bool lastRequest);
virtual void get();
virtual void destroy();
virtual std::tr1::shared_ptr<Channel> getChannel()
{return channelLocal;}
virtual void cancel(){}
virtual void lastRequest() {}
virtual void lock() {mutex.lock();}
virtual void unlock() {mutex.unlock();}
private:
@@ -263,21 +288,18 @@ ChannelGetLocalPtr ChannelGetLocal::create(
PVRecordPtr const &pvRecord)
{
PVCopyPtr pvCopy = PVCopy::create(
pvRecord,
pvRecord->getPVRecordStructure()->getPVStructure(),
pvRequest,
"");
if(pvCopy.get()==NULL) {
if(pvCopy==NULL) {
Status status(
Status::STATUSTYPE_ERROR,
"invalid pvRequest");
ChannelGet::shared_pointer channelGet;
PVStructurePtr pvStructure;
BitSetPtr bitSet;
channelGetRequester->channelGetConnect(
status,
channelGet,
pvStructure,
bitSet);
nullStructure);
ChannelGetLocalPtr localGet;
return localGet;
}
@@ -296,7 +318,8 @@ ChannelGetLocalPtr ChannelGetLocal::create(
cout << "ChannelGetLocal::create";
cout << " recordName " << pvRecord->getRecordName() << endl;
}
channelGetRequester->channelGetConnect(Status::Ok, get, pvStructure,bitSet);
channelGetRequester->channelGetConnect(
Status::Ok,get,pvStructure->getStructure());
return get;
}
@@ -316,13 +339,11 @@ void ChannelGetLocal::destroy()
channelLocal.reset();
}
void ChannelGetLocal::get(bool lastRequest)
void ChannelGetLocal::get()
{
if(isDestroyed) {
Status status(
Status::STATUSTYPE_ERROR,
"was destroyed");
channelGetRequester->getDone(status);
channelGetRequester->getDone(
channelDestroyedStatus,getPtrSelf(),nullPVStructure,nullBitSet);
return;
}
bitSet->clear();
@@ -344,12 +365,15 @@ void ChannelGetLocal::get(bool lastRequest)
bitSet->set(0);
firstTime = false;
}
channelGetRequester->getDone(Status::Ok);
channelGetRequester->getDone(
Status::Ok,
getPtrSelf(),
pvStructure,
bitSet);
if(pvRecord->getTraceLevel()>1)
{
cout << "ChannelGetLocal::get" << endl;
}
if(lastRequest) destroy();
}
class ChannelPutLocal :
@@ -370,9 +394,13 @@ public:
ChannelPutRequester::shared_pointer const & channelPutRequester,
PVStructurePtr const & pvRequest,
PVRecordPtr const &pvRecord);
virtual void put(bool lastRequest);
virtual void put(PVStructurePtr const &pvStructure,BitSetPtr const &bitSet);
virtual void get();
virtual void destroy();
virtual std::tr1::shared_ptr<Channel> getChannel()
{return channelLocal;}
virtual void cancel(){}
virtual void lastRequest() {}
virtual void lock() {mutex.lock();}
virtual void unlock() {mutex.unlock();}
private:
@@ -385,8 +413,6 @@ private:
ChannelLocalPtr const &channelLocal,
ChannelPutRequester::shared_pointer const & channelPutRequester,
PVCopyPtr const &pvCopy,
PVStructurePtr const&pvStructure,
BitSetPtr const & bitSet,
PVRecordPtr const &pvRecord)
:
isDestroyed(false),
@@ -394,8 +420,6 @@ private:
channelLocal(channelLocal),
channelPutRequester(channelPutRequester),
pvCopy(pvCopy),
pvStructure(pvStructure),
bitSet(bitSet),
pvRecord(pvRecord)
{
}
@@ -404,8 +428,6 @@ private:
ChannelLocalPtr channelLocal;
ChannelPutRequester::shared_pointer channelPutRequester;
PVCopyPtr pvCopy;
PVStructurePtr pvStructure;
BitSetPtr bitSet;
PVRecordPtr pvRecord;
Mutex mutex;
};
@@ -417,10 +439,10 @@ ChannelPutLocalPtr ChannelPutLocal::create(
PVRecordPtr const &pvRecord)
{
PVCopyPtr pvCopy = PVCopy::create(
pvRecord,
pvRecord->getPVRecordStructure()->getPVStructure(),
pvRequest,
"");
if(pvCopy.get()==NULL) {
if(pvCopy==NULL) {
Status status(
Status::STATUSTYPE_ERROR,
"invalid pvRequest");
@@ -430,22 +452,18 @@ ChannelPutLocalPtr ChannelPutLocal::create(
channelPutRequester->channelPutConnect(
status,
channelPut,
pvStructure,
bitSet);
nullStructure);
ChannelPutLocalPtr localPut;
return localPut;
}
PVStructurePtr pvStructure = pvCopy->createPVStructure();
BitSetPtr bitSet(new BitSet(pvStructure->getNumberFields()));
ChannelPutLocalPtr put(new ChannelPutLocal(
getProcess(pvRequest,true),
channelLocal,
channelPutRequester,
pvCopy,
pvStructure,
bitSet,
pvRecord));
channelPutRequester->channelPutConnect(Status::Ok, put, pvStructure,bitSet);
channelPutRequester->channelPutConnect(
Status::Ok, put, pvCopy->getStructure());
if(pvRecord->getTraceLevel()>0)
{
cout << "ChannelPutLocal::create";
@@ -472,12 +490,12 @@ void ChannelPutLocal::destroy()
void ChannelPutLocal::get()
{
if(isDestroyed) {
Status status(
Status::STATUSTYPE_ERROR,
"was destroyed");
channelPutRequester->getDone(status);
channelPutRequester->getDone(
channelDestroyedStatus,getPtrSelf(),nullPVStructure,nullBitSet);
return;
}
PVStructurePtr pvStructure = pvCopy->createPVStructure();
BitSetPtr bitSet(new BitSet(pvStructure->getNumberFields()));
bitSet->clear();
bitSet->set(0);
pvRecord->lock();
@@ -488,26 +506,25 @@ void ChannelPutLocal::get()
throw;
}
pvRecord->unlock();
channelPutRequester->getDone(Status::Ok);
channelPutRequester->getDone(
Status::Ok,getPtrSelf(),pvStructure,bitSet);
if(pvRecord->getTraceLevel()>1)
{
cout << "ChannelPutLocal::get" << endl;
}
}
void ChannelPutLocal::put(bool lastRequest)
void ChannelPutLocal::put(
PVStructurePtr const &pvStructure,BitSetPtr const &bitSet)
{
if(isDestroyed) {
Status status(
Status::STATUSTYPE_ERROR,
"was destroyed");
channelPutRequester->getDone(status);
channelPutRequester->putDone(channelDestroyedStatus,getPtrSelf());
return;
}
pvRecord->lock();
try {
pvRecord->beginGroupPut();
pvCopy->updateRecord(pvStructure, bitSet);
pvCopy->updateMaster(pvStructure, bitSet);
if(callProcess) {
pvRecord->process();
}
@@ -517,12 +534,11 @@ void ChannelPutLocal::put(bool lastRequest)
throw;
}
pvRecord->unlock();
channelPutRequester->putDone(Status::Ok);
channelPutRequester->putDone(Status::Ok,getPtrSelf());
if(pvRecord->getTraceLevel()>1)
{
cout << "ChannelPutLocal::put" << endl;
}
if(lastRequest) destroy();
}
@@ -544,10 +560,16 @@ public:
ChannelPutGetRequester::shared_pointer const & channelPutGetRequester,
PVStructurePtr const & pvRequest,
PVRecordPtr const &pvRecord);
virtual void putGet(bool lastRequest);
virtual void putGet(
PVStructurePtr const &pvPutStructure,
BitSetPtr const &putBitSet);
virtual void getPut();
virtual void getGet();
virtual void destroy();
virtual std::tr1::shared_ptr<Channel> getChannel()
{return channelLocal;}
virtual void cancel(){}
virtual void lastRequest() {}
virtual void lock() {mutex.lock();}
virtual void unlock() {mutex.unlock();}
private:
@@ -561,9 +583,7 @@ private:
ChannelPutGetRequester::shared_pointer const & channelPutGetRequester,
PVCopyPtr const &pvPutCopy,
PVCopyPtr const &pvGetCopy,
PVStructurePtr const&pvPutStructure,
PVStructurePtr const&pvGetStructure,
BitSetPtr const & putBitSet,
BitSetPtr const & getBitSet,
PVRecordPtr const &pvRecord)
:
@@ -573,9 +593,7 @@ private:
channelPutGetRequester(channelPutGetRequester),
pvPutCopy(pvPutCopy),
pvGetCopy(pvGetCopy),
pvPutStructure(pvPutStructure),
pvGetStructure(pvGetStructure),
putBitSet(putBitSet),
getBitSet(getBitSet),
pvRecord(pvRecord)
{
@@ -586,9 +604,7 @@ private:
ChannelPutGetRequester::shared_pointer channelPutGetRequester;
PVCopyPtr pvPutCopy;
PVCopyPtr pvGetCopy;
PVStructurePtr pvPutStructure;
PVStructurePtr pvGetStructure;
BitSetPtr putBitSet;
BitSetPtr getBitSet;
PVRecordPtr pvRecord;
Mutex mutex;
@@ -601,50 +617,35 @@ ChannelPutGetLocalPtr ChannelPutGetLocal::create(
PVRecordPtr const &pvRecord)
{
PVCopyPtr pvPutCopy = PVCopy::create(
pvRecord,
pvRecord->getPVRecordStructure()->getPVStructure(),
pvRequest,
"putField");
PVCopyPtr pvGetCopy = PVCopy::create(
pvRecord,
pvRecord->getPVRecordStructure()->getPVStructure(),
pvRequest,
"getField");
if(pvPutCopy.get()==NULL || pvGetCopy.get()==NULL) {
if(pvPutCopy==NULL || pvGetCopy==NULL) {
Status status(
Status::STATUSTYPE_ERROR,
"invalid pvRequest");
ChannelPutGet::shared_pointer channelPutGet;
PVStructurePtr pvStructure;
BitSetPtr bitSet;
channelPutGetRequester->channelPutGetConnect(
status,
channelPutGet,
pvStructure,
pvStructure);
nullStructure,
nullStructure);
ChannelPutGetLocalPtr localPutGet;
return localPutGet;
}
PVStructurePtr pvPutStructure = pvPutCopy->createPVStructure();
PVStructurePtr pvGetStructure = pvGetCopy->createPVStructure();
BitSetPtr putBitSet(new BitSet(pvPutStructure->getNumberFields()));
BitSetPtr getBitSet(new BitSet(pvGetStructure->getNumberFields()));
pvRecord->lock();
try {
pvPutCopy->initCopy(pvPutStructure,putBitSet);
pvGetCopy->initCopy(pvGetStructure,getBitSet);
} catch(...) {
pvRecord->unlock();
throw;
}
pvRecord->unlock();
ChannelPutGetLocalPtr putGet(new ChannelPutGetLocal(
getProcess(pvRequest,true),
channelLocal,
channelPutGetRequester,
pvPutCopy,
pvGetCopy,
pvPutStructure,
pvGetStructure,
putBitSet,
getBitSet,
pvRecord));
if(pvRecord->getTraceLevel()>0)
@@ -653,7 +654,7 @@ ChannelPutGetLocalPtr ChannelPutGetLocal::create(
cout << " recordName " << pvRecord->getRecordName() << endl;
}
channelPutGetRequester->channelPutGetConnect(
Status::Ok, putGet, pvPutStructure,pvGetStructure);
Status::Ok, putGet, pvPutCopy->getStructure(),pvGetCopy->getStructure());
return putGet;
}
@@ -673,22 +674,20 @@ void ChannelPutGetLocal::destroy()
channelLocal.reset();
}
void ChannelPutGetLocal::putGet(bool lastRequest)
void ChannelPutGetLocal::putGet(
PVStructurePtr const &pvPutStructure,BitSetPtr const &putBitSet)
{
if(isDestroyed) {
Status status(
Status::STATUSTYPE_ERROR,
"was destroyed");
channelPutGetRequester->putGetDone(status);
channelPutGetRequester->putGetDone(
channelDestroyedStatus,getPtrSelf(),nullPVStructure,nullBitSet);
return;
}
putBitSet->clear();
putBitSet->set(0);
pvRecord->lock();
try {
pvRecord->beginGroupPut();
pvPutCopy->updateRecord(pvPutStructure, putBitSet);
pvPutCopy->updateMaster(pvPutStructure, putBitSet);
if(callProcess) pvRecord->process();
getBitSet->clear();
pvGetCopy->updateCopySetBitSet(pvGetStructure, getBitSet);
pvRecord->endGroupPut();
} catch(...) {
@@ -696,36 +695,33 @@ void ChannelPutGetLocal::putGet(bool lastRequest)
throw;
}
pvRecord->unlock();
getBitSet->clear();
getBitSet->set(0);
channelPutGetRequester->putGetDone(Status::Ok);
channelPutGetRequester->putGetDone(
Status::Ok,getPtrSelf(),pvGetStructure,getBitSet);
if(pvRecord->getTraceLevel()>1)
{
cout << "ChannelPutGetLocal::putGet" << endl;
}
if(lastRequest) destroy();
}
void ChannelPutGetLocal::getPut()
{
if(isDestroyed) {
Status status(
Status::STATUSTYPE_ERROR,
"was destroyed");
channelPutGetRequester->getPutDone(status);
channelPutGetRequester->getPutDone(
channelDestroyedStatus,getPtrSelf(),nullPVStructure,nullBitSet);
return;
}
PVStructurePtr pvPutStructure = pvPutCopy->createPVStructure();
BitSetPtr putBitSet(new BitSet(pvPutStructure->getNumberFields()));
pvRecord->lock();
try {
pvPutCopy->updateCopySetBitSet(pvPutStructure, putBitSet);
pvPutCopy->initCopy(pvPutStructure, putBitSet);
} catch(...) {
pvRecord->unlock();
throw;
}
pvRecord->unlock();
putBitSet->clear();
putBitSet->set(0);
channelPutGetRequester->getPutDone(Status::Ok);
channelPutGetRequester->getPutDone(
Status::Ok,getPtrSelf(),pvPutStructure,putBitSet);
if(pvRecord->getTraceLevel()>1)
{
cout << "ChannelPutGetLocal::getPut" << endl;
@@ -735,12 +731,11 @@ void ChannelPutGetLocal::getPut()
void ChannelPutGetLocal::getGet()
{
if(isDestroyed) {
Status status(
Status::STATUSTYPE_ERROR,
"was destroyed");
channelPutGetRequester->getGetDone(status);
channelPutGetRequester->getGetDone(
channelDestroyedStatus,getPtrSelf(),nullPVStructure,nullBitSet);
return;
}
getBitSet->clear();
pvRecord->lock();
try {
pvGetCopy->updateCopySetBitSet(pvGetStructure, getBitSet);
@@ -749,9 +744,8 @@ void ChannelPutGetLocal::getGet()
throw;
}
pvRecord->unlock();
getBitSet->clear();
getBitSet->set(0);
channelPutGetRequester->getGetDone(Status::Ok);
channelPutGetRequester->getGetDone(
Status::Ok,getPtrSelf(),pvGetStructure,getBitSet);
if(pvRecord->getTraceLevel()>1)
{
cout << "ChannelPutGetLocal::getGet" << endl;
@@ -778,10 +772,17 @@ public:
ChannelArrayRequester::shared_pointer const & channelArrayRequester,
PVStructurePtr const & pvRequest,
PVRecordPtr const &pvRecord);
virtual void getArray(bool lastRequest,int offset, int count);
virtual void putArray(bool lastRequest,int offset, int count);
virtual void setLength(bool lastRequest,int length, int capacity);
virtual void getArray(size_t offset, size_t count, size_t stride);
virtual void putArray(
PVArrayPtr const &putArray,
size_t offset, size_t count, size_t stride);
virtual void getLength();
virtual void setLength(size_t length, size_t capacity);
virtual void destroy();
virtual std::tr1::shared_ptr<Channel> getChannel()
{return channelLocal;}
virtual void cancel(){}
virtual void lastRequest() {}
virtual void lock() {mutex.lock();}
virtual void unlock() {mutex.unlock();}
private:
@@ -797,7 +798,6 @@ private:
PVRecordPtr const &pvRecord)
:
isDestroyed(false),
callProcess(callProcess),
channelLocal(channelLocal),
channelArrayRequester(channelArrayRequester),
pvArray(pvArray),
@@ -806,7 +806,6 @@ private:
{
}
bool isDestroyed;
bool callProcess;
ChannelLocalPtr channelLocal;
ChannelArrayRequester::shared_pointer channelArrayRequester;
PVArrayPtr pvArray;
@@ -827,14 +826,14 @@ ChannelArrayLocalPtr ChannelArrayLocal::create(
Status status(
Status::STATUSTYPE_ERROR,"invalid pvRequest");
ChannelArrayLocalPtr channelArray;
PVScalarArrayPtr pvArray;
channelArrayRequester->channelArrayConnect(status,channelArray,pvArray);
ArrayConstPtr array;
channelArrayRequester->channelArrayConnect(status,channelArray,array);
return channelArray;
}
PVFieldPtr pvField = pvFields[0];
String fieldName("");
string fieldName("");
while(true) {
String name = pvField->getFieldName();
string name = pvField->getFieldName();
if(fieldName.size()>0) fieldName += '.';
fieldName += name;
PVStructurePtr pvs = static_pointer_cast<PVStructure>(pvField);
@@ -847,17 +846,21 @@ ChannelArrayLocalPtr ChannelArrayLocal::create(
Status status(
Status::STATUSTYPE_ERROR,fieldName +" not found");
ChannelArrayLocalPtr channelArray;
PVScalarArrayPtr pvArray;
channelArrayRequester->channelArrayConnect(status,channelArray,pvArray);
ArrayConstPtr array;
channelArrayRequester->channelArrayConnect(
status,channelArray,array);
return channelArray;
}
if(pvField->getField()->getType()!=scalarArray && pvField->getField()->getType()!=structureArray)
if(pvField->getField()->getType()!=scalarArray
&& pvField->getField()->getType()!=structureArray
&& pvField->getField()->getType()!=unionArray)
{
Status status(
Status::STATUSTYPE_ERROR,fieldName +" not array");
ChannelArrayLocalPtr channelArray;
PVArrayPtr pvArray;
channelArrayRequester->channelArrayConnect(status,channelArray,pvArray);
ArrayConstPtr array;
channelArrayRequester->channelArrayConnect(
status,channelArray,array);
return channelArray;
}
PVArrayPtr pvArray = static_pointer_cast<PVArray>(pvField);
@@ -866,26 +869,66 @@ ChannelArrayLocalPtr ChannelArrayLocal::create(
PVScalarArrayPtr xxx = static_pointer_cast<PVScalarArray>(pvField);
pvCopy = getPVDataCreate()->createPVScalarArray(
xxx->getScalarArray()->getElementType());
} else {
ChannelArrayLocalPtr array(new ChannelArrayLocal(
channelLocal,
channelArrayRequester,
pvArray,
pvCopy,
pvRecord));
if(pvRecord->getTraceLevel()>0)
{
cout << "ChannelArrayLocal::create";
cout << " recordName " << pvRecord->getRecordName() << endl;
}
channelArrayRequester->channelArrayConnect(
Status::Ok, array, pvCopy->getArray());
return array;
}
if(pvField->getField()->getType()==structureArray) {
PVStructureArrayPtr xxx = static_pointer_cast<PVStructureArray>(pvField);
pvCopy = getPVDataCreate()->createPVStructureArray(
xxx->getStructureArray());
xxx->getStructureArray()->getStructure());
ChannelArrayLocalPtr array(new ChannelArrayLocal(
channelLocal,
channelArrayRequester,
pvArray,
pvCopy,
pvRecord));
if(pvRecord->getTraceLevel()>0)
{
cout << "ChannelArrayLocal::create";
cout << " recordName " << pvRecord->getRecordName() << endl;
}
channelArrayRequester->channelArrayConnect(
Status::Ok, array, pvCopy->getArray());
return array;
}
if(pvField->getField()->getType()==unionArray) {
PVUnionArrayPtr xxx = static_pointer_cast<PVUnionArray>(pvField);
pvCopy = getPVDataCreate()->createPVUnionArray(
xxx->getUnionArray()->getUnion());
ChannelArrayLocalPtr array(new ChannelArrayLocal(
channelLocal,
channelArrayRequester,
pvArray,
pvCopy,
pvRecord));
if(pvRecord->getTraceLevel()>0)
{
cout << "ChannelArrayLocal::create";
cout << " recordName " << pvRecord->getRecordName() << endl;
}
channelArrayRequester->channelArrayConnect(
Status::Ok, array, pvCopy->getArray());
return array;
}
ChannelArrayLocalPtr array(new ChannelArrayLocal(
channelLocal,
channelArrayRequester,
pvArray,
pvCopy,
pvRecord));
if(pvRecord->getTraceLevel()>0)
{
cout << "ChannelArrayLocal::create";
cout << " recordName " << pvRecord->getRecordName() << endl;
}
channelArrayRequester->channelArrayConnect(
Status::Ok, array, pvCopy);
return array;
Status status(Status::STATUSTYPE_ERROR,
"Logic error. Should not reach this code");
ChannelArrayLocalPtr channelArray;
ArrayConstPtr array;
channelArrayRequester->channelArrayConnect(status,channelArray,array);
return channelArray;
}
@@ -904,72 +947,120 @@ void ChannelArrayLocal::destroy()
channelLocal.reset();
}
void ChannelArrayLocal::getArray(bool lastRequest,int offset, int count)
void ChannelArrayLocal::getArray(size_t offset, size_t count, size_t stride)
{
if(isDestroyed) {
Status status(
Status::STATUSTYPE_ERROR,
"was destroyed");
channelArrayRequester->getArrayDone(status);
channelArrayRequester->getArrayDone(channelDestroyedStatus,getPtrSelf(),pvCopy);
return;
}
if(pvRecord->getTraceLevel()>1)
{
cout << "ChannelArrayLocal::getArray" << endl;
}
if(offset<0) {
channelArrayRequester->getArrayDone(illegalOffsetStatus,getPtrSelf(),pvCopy);
return;
}
if(stride<0) {
channelArrayRequester->getArrayDone(illegalStrideStatus,getPtrSelf(),pvCopy);
return;
}
const char *exceptionMessage = NULL;
pvRecord->lock();
try {
if(count<0) count = pvArray->getLength();
size_t capacity = pvArray->getCapacity();
if(capacity!=0) {
pvCopy->setCapacity(capacity);
pvCopy->setLength(count);
copy(*pvArray.get(),offset,*pvCopy.get(),0,count);
bool ok = false;
while(true) {
size_t length = pvArray->getLength();
if(length<=0) break;
if(count<=0) {
count = (length -offset + stride -1)/stride;
if(count>0) ok = true;
break;
}
size_t maxcount = (length -offset + stride -1)/stride;
if(count>maxcount) count = maxcount;
ok = true;
break;
}
} catch(...) {
pvRecord->unlock();
throw;
if(ok) {
pvCopy->setLength(count);
copy(pvArray,offset,stride,pvCopy,0,1,count);
}
} catch(std::exception e) {
exceptionMessage = e.what();
}
pvRecord->unlock();
channelArrayRequester->getArrayDone(Status::Ok);
if(lastRequest) destroy();
Status status = Status::Ok;
if(exceptionMessage!=NULL) {
status = Status(Status::STATUSTYPE_ERROR,exceptionMessage);
}
channelArrayRequester->getArrayDone(status,getPtrSelf(),pvCopy);
}
void ChannelArrayLocal::putArray(bool lastRequest,int offset, int count)
void ChannelArrayLocal::putArray(
PVArrayPtr const & pvArray, size_t offset, size_t count, size_t stride)
{
if(isDestroyed) {
Status status(
Status::STATUSTYPE_ERROR,
"was destroyed");
channelArrayRequester->putArrayDone(status);
channelArrayRequester->putArrayDone(channelDestroyedStatus,getPtrSelf());
return;
}
if(pvRecord->getTraceLevel()>1)
{
cout << "ChannelArrayLocal::putArray" << endl;
}
if(offset<0) {
channelArrayRequester->putArrayDone(illegalOffsetStatus,getPtrSelf());
return;
}
if(count<0) {
channelArrayRequester->putArrayDone(illegalCountStatus,getPtrSelf());
return;
}
if(stride<0) {
channelArrayRequester->putArrayDone(illegalStrideStatus,getPtrSelf());
return;
}
size_t newLength = offset + count*stride;
pvArray->setLength(newLength);
const char *exceptionMessage = NULL;
pvRecord->lock();
try {
if(count<=0) count = pvCopy->getLength();
if(pvArray->getCapacity()<count) pvArray->setCapacity(count);
if(pvArray->getLength()<count) pvArray->setLength(count);
copy(*pvCopy.get(),0,*pvArray.get(),offset,count);
} catch(...) {
pvRecord->unlock();
throw;
copy(pvArray,0,1,this->pvArray,offset,stride,count);
} catch(std::exception e) {
exceptionMessage = e.what();
}
pvRecord->unlock();
channelArrayRequester->putArrayDone(Status::Ok);
if(lastRequest) destroy();
Status status = Status::Ok;
if(exceptionMessage!=NULL) {
status = Status(Status::STATUSTYPE_ERROR,exceptionMessage);
}
channelArrayRequester->putArrayDone(status,getPtrSelf());
}
void ChannelArrayLocal::setLength(bool lastRequest,int length, int capacity)
void ChannelArrayLocal::getLength()
{
size_t length = 0;
size_t capacity = 0;
const char *exceptionMessage = NULL;
pvRecord->lock();
try {
length = pvArray->getLength();
capacity = pvArray->getCapacity();
} catch(std::exception e) {
exceptionMessage = e.what();
}
pvRecord->unlock();
Status status = Status::Ok;
if(exceptionMessage!=NULL) {
status = Status(Status::STATUSTYPE_ERROR,exceptionMessage);
}
channelArrayRequester->getLengthDone(status,getPtrSelf(),length,capacity);
}
void ChannelArrayLocal::setLength(size_t length, size_t capacity)
{
if(isDestroyed) {
Status status(
Status::STATUSTYPE_ERROR,
"was destroyed");
channelArrayRequester->setLengthDone(status);
channelArrayRequester->setLengthDone(channelDestroyedStatus,getPtrSelf());
return;
}
if(pvRecord->getTraceLevel()>1)
@@ -982,14 +1073,14 @@ void ChannelArrayLocal::setLength(bool lastRequest,int length, int capacity)
Status status(
Status::STATUSTYPE_ERROR,
"capacityImnutable");
channelArrayRequester->setLengthDone(status);
channelArrayRequester->setLengthDone(status,getPtrSelf());
pvRecord->unlock();
return;
}
if(capacity>0) {
if(capacity>=0) {
if(pvArray->getCapacity()!=capacity) pvArray->setCapacity(capacity);
}
if(length>0) {
if(length>=0) {
if(pvArray->getLength()!=length) pvArray->setLength(length);
}
} catch(...) {
@@ -997,7 +1088,7 @@ void ChannelArrayLocal::setLength(bool lastRequest,int length, int capacity)
throw;
}
pvRecord->unlock();
channelArrayRequester->setLengthDone(Status::Ok);
channelArrayRequester->setLengthDone(Status::Ok,getPtrSelf());
}
@@ -1060,21 +1151,21 @@ void ChannelLocal::detach(PVRecordPtr const & pvRecord)
}
String ChannelLocal::getRequesterName()
string ChannelLocal::getRequesterName()
{
return requester->getRequesterName();
}
void ChannelLocal::message(
String const &message,
string const &message,
MessageType messageType)
{
requester->message(message,messageType);
}
String ChannelLocal::getRemoteAddress()
string ChannelLocal::getRemoteAddress()
{
return String("local");
return string("local");
}
Channel::ConnectionState ChannelLocal::getConnectionState()
@@ -1082,7 +1173,7 @@ Channel::ConnectionState ChannelLocal::getConnectionState()
return Channel::CONNECTED;
}
String ChannelLocal::getChannelName()
string ChannelLocal::getChannelName()
{
return pvRecord->getRecordName();
}
@@ -1098,7 +1189,7 @@ bool ChannelLocal::isConnected()
}
void ChannelLocal::getField(GetFieldRequester::shared_pointer const &requester,
String const &subField)
string const &subField)
{
if(subField.size()<1) {
StructureConstPtr structure =
@@ -1113,14 +1204,14 @@ void ChannelLocal::getField(GetFieldRequester::shared_pointer const &requester,
return;
}
Status status(Status::STATUSTYPE_ERROR,
String("client asked for illegal field"));
"client asked for illegal field");
requester->getDone(status,FieldConstPtr());
}
AccessRights ChannelLocal::getAccessRights(
PVField::shared_pointer const &pvField)
{
throw std::logic_error(String("Not Implemented"));
throw std::logic_error("Not Implemented");
}
ChannelProcess::shared_pointer ChannelLocal::createChannelProcess(
@@ -1180,7 +1271,7 @@ ChannelRPC::shared_pointer ChannelLocal::createChannelRPC(
PVStructure::shared_pointer const & pvRequest)
{
Status status(Status::STATUSTYPE_ERROR,
String("ChannelRPC not supported"));
"ChannelRPC not supported");
channelRPCRequester->channelRPCConnect(status,ChannelRPC::shared_pointer());
return ChannelRPC::shared_pointer();
}
@@ -1212,12 +1303,12 @@ ChannelArray::shared_pointer ChannelLocal::createChannelArray(
void ChannelLocal::printInfo()
{
cout << "ChannelLocal provides access to service" << endl;
printInfo(std::cout);
}
void ChannelLocal::printInfo(StringBuilder out)
void ChannelLocal::printInfo(std::ostream& out)
{
*out += "ChannelLocal provides access to service";
out << "ChannelLocal provides access to service";
}
}}

View File

@@ -8,14 +8,14 @@
* @author Marty Kraimer
* @date 2013.04
*/
#define epicsExportSharedSymbols
#include <pv/serverContext.h>
#include <pv/channelProviderLocal.h>
#include <pv/traceRecord.h>
#include <pv/syncChannelFind.h>
namespace epics { namespace pvDatabase {
#define epicsExportSharedSymbols
#include <pv/channelProviderLocal.h>
#include <pv/traceRecord.h>
using namespace epics::pvData;
using namespace epics::pvAccess;
@@ -23,8 +23,11 @@ using std::tr1::static_pointer_cast;
using std::tr1::dynamic_pointer_cast;
using std::cout;
using std::endl;
using std::string;
static String providerName("local");
namespace epics { namespace pvDatabase {
static string providerName("local");
class LocalChannelProviderFactory;
@@ -35,7 +38,7 @@ class LocalChannelProviderFactory : public ChannelProviderFactory
public:
POINTER_DEFINITIONS(LocalChannelProviderFactory);
virtual String getFactoryName() { return providerName;}
virtual string getFactoryName() { return providerName;}
static LocalChannelProviderFactoryPtr create(
ChannelProviderLocalPtr const &channelProvider)
{
@@ -95,13 +98,13 @@ void ChannelProviderLocal::destroy()
pvDatabase->destroy();
}
String ChannelProviderLocal::getProviderName()
string ChannelProviderLocal::getProviderName()
{
return providerName;
}
ChannelFind::shared_pointer ChannelProviderLocal::channelFind(
String const & channelName,
string const & channelName,
ChannelFindRequester::shared_pointer const &channelFindRequester)
{
Lock xx(mutex);
@@ -113,7 +116,7 @@ ChannelFind::shared_pointer ChannelProviderLocal::channelFind(
true);
} else {
Status notFoundStatus(Status::STATUSTYPE_ERROR,String("pv not found"));
Status notFoundStatus(Status::STATUSTYPE_ERROR,"pv not found");
channelFindRequester->channelFindResult(
notFoundStatus,
channelFinder,
@@ -122,8 +125,21 @@ ChannelFind::shared_pointer ChannelProviderLocal::channelFind(
return channelFinder;
}
ChannelFind::shared_pointer ChannelProviderLocal::channelList(
ChannelListRequester::shared_pointer const & channelListRequester)
{
PVStringArrayPtr records;
{
Lock guard(mutex);
records = pvDatabase->getRecordNames();
}
channelListRequester->channelListResult(Status::Ok, channelFinder, records->view(), false);
return channelFinder;
}
Channel::shared_pointer ChannelProviderLocal::createChannel(
String const & channelName,
string const & channelName,
ChannelRequester::shared_pointer const &channelRequester,
short priority)
{
@@ -131,10 +147,10 @@ Channel::shared_pointer ChannelProviderLocal::createChannel(
}
Channel::shared_pointer ChannelProviderLocal::createChannel(
String const & channelName,
string const & channelName,
ChannelRequester::shared_pointer const &channelRequester,
short priority,
String const &address)
string const &address)
{
Lock xx(mutex);
PVRecordPtr pvRecord = pvDatabase->findRecord(channelName);
@@ -147,7 +163,7 @@ Channel::shared_pointer ChannelProviderLocal::createChannel(
pvRecord->addPVRecordClient(channel);
return channel;
}
Status notFoundStatus(Status::STATUSTYPE_ERROR,String("pv not found"));
Status notFoundStatus(Status::STATUSTYPE_ERROR,"pv not found");
channelRequester->channelCreated(
notFoundStatus,
Channel::shared_pointer());

View File

@@ -11,13 +11,11 @@
#ifndef CHANNELPROVIDERLOCAL_H
#define CHANNELPROVIDERLOCAL_H
#ifdef epicsExportSharedSymbols
# define channelProviderLocalEpicsExportSharedSymbols
# undef epicsExportSharedSymbols
#endif
#include <string>
#include <cstring>
#include <stdexcept>
@@ -29,17 +27,17 @@
#include <pv/lock.h>
#include <pv/pvType.h>
#include <pv/pvData.h>
#include <pv/monitorPlugin.h>
#include <pv/pvCopy.h>
#include <pv/pvAccess.h>
#include <pv/status.h>
#ifdef channelProviderLocalEpicsExportSharedSymbols
# define epicsExportSharedSymbols
# undef channelProviderLocalEpicsExportSharedSymbols
# include <shareLib.h>
#endif
#include <pv/pvDatabase.h>
#include <pv/monitorAlgorithm.h>
namespace epics { namespace pvDatabase {
@@ -69,15 +67,10 @@ public:
PVRecordPtr const & pvRecord,
epics::pvData::MonitorRequester::shared_pointer const & monitorRequester,
epics::pvData::PVStructurePtr const & pvRequest);
void registerMonitorAlgorithmCreate(
MonitorAlgorithmCreatePtr const &monitorAlgorithmCreate);
MonitorAlgorithmCreatePtr getMonitorAlgorithmCreate(
epics::pvData::String algorithmName);
private:
MonitorFactory();
friend class MonitorLocal;
friend MonitorFactoryPtr getMonitorFactory();
std::multiset<MonitorAlgorithmCreatePtr> monitorAlgorithmCreateList;
bool isDestroyed;
epics::pvData::Mutex mutex;
};
@@ -93,19 +86,21 @@ public:
POINTER_DEFINITIONS(ChannelProviderLocal);
virtual ~ChannelProviderLocal();
virtual void destroy();
virtual epics::pvData::String getProviderName();
virtual std::string getProviderName();
virtual epics::pvAccess::ChannelFind::shared_pointer channelFind(
epics::pvData::String const &channelName,
std::string const &channelName,
epics::pvAccess::ChannelFindRequester::shared_pointer const & channelFindRequester);
virtual epics::pvAccess::ChannelFind::shared_pointer channelList(
epics::pvAccess::ChannelListRequester::shared_pointer const & channelListRequester);
virtual epics::pvAccess::Channel::shared_pointer createChannel(
epics::pvData::String const &channelName,
std::string const &channelName,
epics::pvAccess::ChannelRequester::shared_pointer const &channelRequester,
short priority);
virtual epics::pvAccess::Channel::shared_pointer createChannel(
epics::pvData::String const &channelName,
std::string const &channelName,
epics::pvAccess::ChannelRequester::shared_pointer const &channelRequester,
short priority,
epics::pvData::String const &address);
std::string const &address);
private:
shared_pointer getPtrSelf()
{
@@ -134,22 +129,22 @@ public:
);
virtual ~ChannelLocal();
virtual void destroy();
virtual epics::pvData::String getRequesterName();
virtual std::string getRequesterName();
virtual void message(
epics::pvData::String const & message,
std::string const & message,
epics::pvData::MessageType messageType);
virtual epics::pvAccess::ChannelProvider::shared_pointer getProvider()
{
return provider;
}
virtual epics::pvData::String getRemoteAddress();
virtual std::string getRemoteAddress();
virtual epics::pvAccess::Channel::ConnectionState getConnectionState();
virtual epics::pvData::String getChannelName();
virtual std::string getChannelName();
virtual epics::pvAccess::ChannelRequester::shared_pointer getChannelRequester();
virtual bool isConnected();
virtual void getField(
epics::pvAccess::GetFieldRequester::shared_pointer const &requester,
epics::pvData::String const & subField);
std::string const & subField);
virtual epics::pvAccess::AccessRights getAccessRights(
epics::pvData::PVField::shared_pointer const &pvField);
virtual epics::pvAccess::ChannelProcess::shared_pointer createChannelProcess(
@@ -174,7 +169,7 @@ public:
epics::pvAccess::ChannelArrayRequester::shared_pointer const &requester,
epics::pvData::PVStructurePtr const &pvRequest);
virtual void printInfo();
virtual void printInfo(epics::pvData::StringBuilder out);
virtual void printInfo(std::ostream& out);
virtual void detach(PVRecordPtr const &pvRecord);
protected:
shared_pointer getPtrSelf()

View File

@@ -1,60 +0,0 @@
/* monitorAlgorithm.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 Marty Kraimer
* @date 2013.04
*/
#ifndef MONITORALGORITHM_H
#define MONITORALGORITHM_H
#include <shareLib.h>
#include <pv/pvCopy.h>
namespace epics { namespace pvDatabase {
class MonitorAlgorithm;
typedef std::tr1::shared_ptr<MonitorAlgorithm> MonitorAlgorithmPtr;
class MonitorAlgorithmCreate;
typedef std::tr1::shared_ptr<MonitorAlgorithmCreate> MonitorAlgorithmCreatePtr;
class epicsShareClass MonitorAlgorithm
{
public:
POINTER_DEFINITIONS(MonitorAlgorithm);
virtual ~MonitorAlgorithm(){}
virtual epics::pvData::String getAlgorithmName(){return algorithmName;}
virtual bool causeMonitor() = 0;
virtual void monitorIssued() = 0;
protected:
MonitorAlgorithm(epics::pvData::String algorithmName)
: algorithmName(algorithmName)
{}
epics::pvData::String algorithmName;
};
class epicsShareClass MonitorAlgorithmCreate
{
public:
POINTER_DEFINITIONS(MonitorAlgorithmCreate);
virtual ~MonitorAlgorithmCreate(){}
virtual epics::pvData::String getAlgorithmName(){return algorithmName;}
virtual MonitorAlgorithmPtr create(
PVRecordPtr const &pvRecord,
epics::pvData::MonitorRequester::shared_pointer const &requester,
PVRecordFieldPtr const &fromPVRecord,
epics::pvData::PVStructurePtr const &pvOptions) = 0;
protected:
MonitorAlgorithmCreate(epics::pvData::String algorithmName)
: algorithmName(algorithmName)
{}
epics::pvData::String algorithmName;
};
}}
#endif /* MONITORALGORITHM_H */

View File

@@ -18,37 +18,30 @@
#define epicsExportSharedSymbols
#include <pv/pvCopyMonitor.h>
#include <pv/channelProviderLocal.h>
namespace epics { namespace pvDatabase {
using namespace epics::pvData;
using namespace epics::pvAccess;
using std::tr1::static_pointer_cast;
using std::cout;
using std::endl;
using std::string;
namespace epics { namespace pvDatabase {
static MonitorAlgorithmCreatePtr nullMonitorAlgorithmCreate;
static MonitorPtr nullMonitor;
static MonitorElementPtr NULLMonitorElement;
static Status wasDestroyedStatus(Status::STATUSTYPE_ERROR,"was destroyed");
static ConvertPtr convert = getConvert();
//class MonitorFieldNode;
//typedef std::tr1::shared_ptr<MonitorFieldNode> MonitorFieldNodePtr;
class ElementQueue;
typedef std::tr1::shared_ptr<ElementQueue> ElementQueuePtr;
class MultipleElementQueue;
typedef std::tr1::shared_ptr<MultipleElementQueue> MultipleElementQueuePtr;
//class MonitorFieldNode
//{
//public:
// MonitorAlgorithmPtr monitorAlgorithm;
// size_t bitOffset; // pv pvCopy
//};
class ElementQueue :
public Monitor,
public std::tr1::enable_shared_from_this<ElementQueue>
@@ -87,9 +80,7 @@ public:
private:
std::tr1::weak_ptr<MonitorLocal> monitorLocal;
MonitorElementQueuePtr queue;
BitSetPtr changedBitSet;
BitSetPtr overrunBitSet;
MonitorElementPtr latestMonitorElement;
MonitorElementPtr activeElement;
bool queueIsFull;
};
@@ -267,7 +258,9 @@ bool MonitorLocal::init(PVStructurePtr const & pvRequest)
pvField = pvRequest->getSubField("field");
if(pvField.get()==NULL) {
pvCopy = PVCopy::create(pvRecord,pvRequest,"");
pvCopy = PVCopy::create(
pvRecord->getPVRecordStructure()->getPVStructure(),
pvRequest,"");
if(pvCopy.get()==NULL) {
monitorRequester->message("illegal pvRequest",errorMessage);
return false;
@@ -277,13 +270,16 @@ bool MonitorLocal::init(PVStructurePtr const & pvRequest)
monitorRequester->message("illegal pvRequest",errorMessage);
return false;
}
pvCopy = PVCopy::create(pvRecord,pvRequest,"field");
pvCopy = PVCopy::create(
pvRecord->getPVRecordStructure()->getPVStructure(),
pvRequest,"field");
if(pvCopy.get()==NULL) {
monitorRequester->message("illegal pvRequest",errorMessage);
return false;
}
}
pvCopyMonitor = pvCopy->createPVCopyMonitor(getPtrSelf());
pvCopyMonitor = PVCopyMonitor::create(
getPtrSelf(),pvRecord,pvCopy);
// MARTY MUST IMPLEMENT periodic
if(queueSize<2) queueSize = 2;
std::vector<MonitorElementPtr> monitorElementArray;
@@ -348,29 +344,6 @@ MonitorPtr MonitorFactory::createMonitor(
return monitor;
}
void MonitorFactory::registerMonitorAlgorithmCreate(
MonitorAlgorithmCreatePtr const &monitorAlgorithmCreate)
{
Lock xx(mutex);
if(isDestroyed) return;
// monitorAlgorithmCreateList.insert(monitorAlgorithmCreate);
}
MonitorAlgorithmCreatePtr MonitorFactory::getMonitorAlgorithmCreate(
String algorithmName)
{
Lock xx(mutex);
if(isDestroyed) return nullMonitorAlgorithmCreate;
// std::multiset<MonitorAlgorithmCreatePtr>::iterator iter;
// for(iter = monitorAlgorithmCreateList.begin();
// iter!= monitorAlgorithmCreateList.end();
// ++iter)
// {
// if((*iter)->getAlgorithmName().compare(algorithmName))
// return *iter;
// }
return nullMonitorAlgorithmCreate;
}
MultipleElementQueue::MultipleElementQueue(
MonitorLocalPtr const &monitorLocal,
@@ -378,8 +351,6 @@ MultipleElementQueue::MultipleElementQueue(
size_t nfields)
: monitorLocal(monitorLocal),
queue(queue),
changedBitSet(new BitSet(nfields)),
overrunBitSet(new BitSet(nfields)),
queueIsFull(false)
{
}
@@ -388,11 +359,13 @@ Status MultipleElementQueue::start()
{
queue->clear();
queueIsFull = false;
changedBitSet->clear();
overrunBitSet->clear();
activeElement = queue->getFree();
activeElement->changedBitSet->clear();
activeElement->overrunBitSet->clear();
MonitorLocalPtr ml = monitorLocal.lock();
if(ml==NULL) return wasDestroyedStatus;
ml->getPVCopyMonitor()->startMonitoring(changedBitSet,overrunBitSet);
ml->getPVCopyMonitor()->setMonitorElement(activeElement);
ml->getPVCopyMonitor()->startMonitoring();
return Status::Ok;
}
@@ -405,55 +378,41 @@ bool MultipleElementQueue::dataChanged()
{
MonitorLocalPtr ml = monitorLocal.lock();
if(ml==NULL) return false;
if(queueIsFull) {
MonitorElementPtr monitorElement = latestMonitorElement;
PVStructurePtr pvStructure = monitorElement->pvStructurePtr;
ml->getPVCopy()->updateCopyFromBitSet(pvStructure,changedBitSet);
(*monitorElement->changedBitSet)|= (*changedBitSet);
(*monitorElement->overrunBitSet)|= (*changedBitSet);
changedBitSet->clear();
overrunBitSet->clear();
return false;
}
MonitorElementPtr monitorElement = queue->getFree();
if(monitorElement==NULL) {
throw std::logic_error(String("MultipleElementQueue::dataChanged() logic error"));
}
if(queue->getNumberFree()==0){
queueIsFull = true;
latestMonitorElement = monitorElement;
}
PVStructurePtr pvStructure = monitorElement->pvStructurePtr;
if(queueIsFull) return false;
ml->getPVCopy()->updateCopyFromBitSet(
pvStructure,changedBitSet);
BitSetUtil::compress(changedBitSet,pvStructure);
BitSetUtil::compress(overrunBitSet,pvStructure);
monitorElement->changedBitSet->clear();
(*monitorElement->changedBitSet)|=(*changedBitSet);
monitorElement->overrunBitSet->clear();
(*monitorElement->overrunBitSet)|=(*overrunBitSet);
changedBitSet->clear();
overrunBitSet->clear();
queue->setUsed(monitorElement);
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()
{
return queue->getUsed();
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 &currentElement)
void MultipleElementQueue::release(MonitorElementPtr const &element)
{
if(queueIsFull) {
MonitorElementPtr monitorElement = latestMonitorElement;
PVStructurePtr pvStructure = monitorElement->pvStructurePtr;
BitSetUtil::compress(monitorElement->changedBitSet,pvStructure);
BitSetUtil::compress(monitorElement->overrunBitSet,pvStructure);
queueIsFull = false;
latestMonitorElement.reset();
queue->releaseUsed(element);
if(!queueIsFull) return;
queueIsFull = false;
if(!activeElement->changedBitSet->isEmpty()) {
dataChanged();
}
queue->releaseUsed(currentElement);
}
MonitorFactoryPtr getMonitorFactory()

View File

@@ -1,869 +0,0 @@
/* pvCopy.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 Marty Kraimer
* @date 2013.04
*/
#include <string>
#include <stdexcept>
#include <memory>
#include <sstream>
#include <pv/thread.h>
#define epicsExportSharedSymbols
#include <pv/channelProviderLocal.h>
#include <pv/pvCopy.h>
namespace epics { namespace pvDatabase {
using namespace epics::pvData;
using std::tr1::static_pointer_cast;
using std::tr1::dynamic_pointer_cast;
using std::size_t;
using std::cout;
using std::endl;
static PVCopyPtr NULLPVCopy;
static FieldConstPtr NULLField;
static StructureConstPtr NULLStructure;
static PVStructurePtr NULLPVStructure;
static CopyNodePtr NULLCopyNode;
static CopyRecordNodePtr NULLCopyRecordNode;
struct CopyNode {
CopyNode()
: isStructure(false),
structureOffset(0),
nfields(0)
{}
bool isStructure;
size_t structureOffset; // In the copy
size_t nfields;
PVStructurePtr options;
};
struct CopyRecordNode : public CopyNode{
PVRecordFieldPtr recordPVField;
};
typedef std::vector<CopyNodePtr> CopyNodePtrArray;
typedef std::tr1::shared_ptr<CopyNodePtrArray> CopyNodePtrArrayPtr;
struct CopyStructureNode : public CopyNode {
CopyNodePtrArrayPtr nodes;
};
PVCopyPtr PVCopy::create(
PVRecordPtr const &pvRecord,
PVStructurePtr const &pvRequest,
String const & structureName)
{
PVStructurePtr pvStructure(pvRequest);
if(structureName.size()>0) {
if(pvRequest->getStructure()->getNumberFields()>0) {
pvStructure = pvRequest->getStructureField(structureName);
if(pvStructure.get()==NULL) return NULLPVCopy;
}
} else if(pvStructure->getSubField("field")!=NULL) {
pvStructure = pvRequest->getStructureField("field");
}
PVCopyPtr pvCopy = PVCopyPtr(new PVCopy(pvRecord));
bool result = pvCopy->init(pvStructure);
if(!result) pvCopy.reset();
return pvCopy;
}
PVCopy::PVCopy(
PVRecordPtr const &pvRecord)
: pvRecord(pvRecord)
{
}
void PVCopy::destroy()
{
if(pvRecord->getTraceLevel()>0)
{
cout << "PVCopy::destroy" << endl;
}
headNode.reset();
}
PVRecordPtr PVCopy::getPVRecord()
{
return pvRecord;
}
StructureConstPtr PVCopy::getStructure()
{
return structure;
}
PVStructurePtr PVCopy::createPVStructure()
{
if(cacheInitStructure.get()!=NULL) {
PVStructurePtr save = cacheInitStructure;
cacheInitStructure.reset();
return save;
}
PVStructurePtr pvStructure =
getPVDataCreate()->createPVStructure(structure);
return pvStructure;
}
PVStructurePtr PVCopy::getOptions(
PVStructurePtr const &copyPVStructure,std::size_t fieldOffset)
{
CopyNodePtr node = headNode;
while(true) {
if(!node->isStructure) {
if(node->structureOffset==fieldOffset) return node->options;
return NULLPVStructure;
}
CopyStructureNodePtr structNode = static_pointer_cast<CopyStructureNode>(node);
CopyNodePtrArrayPtr nodes = structNode->nodes;
boolean okToContinue = false;
for(size_t i=0; i< nodes->size(); i++) {
node = (*nodes)[i];
size_t soff = node->structureOffset;
if(fieldOffset>=soff && fieldOffset<soff+node->nfields) {
if(fieldOffset==soff) return node->options;
if(!node->isStructure) {
return NULLPVStructure;
}
okToContinue = true;
break;
}
}
if(okToContinue) continue;
throw std::invalid_argument("fieldOffset not valid");
}
}
size_t PVCopy::getCopyOffset(PVRecordFieldPtr const &recordPVField)
{
if(!headNode->isStructure) {
CopyRecordNodePtr recordNode = static_pointer_cast<CopyRecordNode>(headNode);
if((recordNode->recordPVField.get())==recordPVField.get()) {
return headNode->structureOffset;
}
PVStructure * parent = recordPVField->getPVField()->getParent();
size_t offsetParent = parent->getFieldOffset();
size_t off = recordPVField->getPVField()->getFieldOffset();
size_t offdiff = off -offsetParent;
if(offdiff<recordNode->nfields) return headNode->structureOffset + offdiff;
return String::npos;
}
CopyStructureNodePtr node = static_pointer_cast<CopyStructureNode>(headNode);
CopyRecordNodePtr recordNode = getCopyOffset(node,recordPVField);
if(recordNode.get()!=NULL) return recordNode->structureOffset;
return String::npos;
}
size_t PVCopy::getCopyOffset(
PVRecordStructurePtr const &recordPVStructure,
PVRecordFieldPtr const &recordPVField)
{
CopyRecordNodePtr recordNode;
if(!headNode->isStructure) {
recordNode = static_pointer_cast<CopyRecordNode>(headNode);
if(recordNode->recordPVField.get()!=recordPVStructure.get()) return String::npos;
} else {
CopyStructureNodePtr node = static_pointer_cast<CopyStructureNode>(headNode);
recordNode = getCopyOffset(node,recordPVField);
}
if(recordNode.get()==NULL) return String::npos;
size_t diff = recordPVField->getPVField()->getFieldOffset()
- recordPVStructure->getPVStructure()->getFieldOffset();
return recordNode->structureOffset + diff;
}
PVRecordFieldPtr PVCopy::getRecordPVField(size_t structureOffset)
{
CopyRecordNodePtr recordNode;
if(!headNode->isStructure) {
recordNode = static_pointer_cast<CopyRecordNode>(headNode);
} else {
CopyStructureNodePtr node = static_pointer_cast<CopyStructureNode>(headNode);
recordNode = getRecordNode(node,structureOffset);
}
if(recordNode.get()==NULL) {
throw std::invalid_argument(
"PVCopy::getRecordPVField: setstructureOffset not valid");
}
size_t diff = structureOffset - recordNode->structureOffset;
PVRecordFieldPtr pvRecordField = recordNode->recordPVField;
if(diff==0) return pvRecordField;
PVStructurePtr pvStructure
= static_pointer_cast<PVStructure>(pvRecordField->getPVField());
PVFieldPtr pvField = pvStructure->getSubField(
pvRecordField->getPVField()->getFieldOffset() + diff);
return pvRecord->findPVRecordField(pvField);
}
void PVCopy::initCopy(
PVStructurePtr const &copyPVStructure,
BitSetPtr const &bitSet)
{
bitSet->clear();
bitSet->set(0);
pvRecord->lock();
try {
updateCopyFromBitSet(copyPVStructure,bitSet);
} catch(...) {
pvRecord->unlock();
throw;
}
pvRecord->unlock();
}
void PVCopy::updateCopySetBitSet(
PVStructurePtr const &copyPVStructure,
BitSetPtr const &bitSet)
{
if(headNode->isStructure) {
CopyStructureNodePtr node = static_pointer_cast<CopyStructureNode>(headNode);
updateStructureNodeSetBitSet(copyPVStructure,node,bitSet);
} else {
CopyRecordNodePtr recordNode = static_pointer_cast<CopyRecordNode>(headNode);
PVRecordFieldPtr pvRecordField= recordNode->recordPVField;
PVFieldPtr copyPVField = copyPVStructure;
PVFieldPtrArray const & pvCopyFields = copyPVStructure->getPVFields();
if(pvCopyFields.size()==1) {
copyPVField = pvCopyFields[0];
}
PVFieldPtr pvField = pvRecordField->getPVField();
if(pvField->getField()->getType()==epics::pvData::structure) {
updateSubFieldSetBitSet(copyPVField,pvRecordField,bitSet);
return;
}
if(pvCopyFields.size()!=1) {
throw std::logic_error("Logic error");
}
ConvertPtr convert = getConvert();
bool isEqual = convert->equals(copyPVField,pvField);
if(!isEqual) {
convert->copy(pvField, copyPVField);
bitSet->set(copyPVField->getFieldOffset());
}
}
}
void PVCopy::updateCopyFromBitSet(
PVStructurePtr const &copyPVStructure,
BitSetPtr const &bitSet)
{
bool doAll = bitSet->get(0);
if(headNode->isStructure) {
CopyStructureNodePtr node = static_pointer_cast<CopyStructureNode>(headNode);
updateStructureNodeFromBitSet(copyPVStructure,node,bitSet,true,doAll);
} else {
CopyRecordNodePtr recordNode = static_pointer_cast<CopyRecordNode>(headNode);
PVFieldPtrArray const & pvCopyFields = copyPVStructure->getPVFields();
if(pvCopyFields.size()==1) {
updateSubFieldFromBitSet(
pvCopyFields[0],
recordNode->recordPVField,bitSet,
true,doAll);
} else {
updateSubFieldFromBitSet(
copyPVStructure,
recordNode->recordPVField,bitSet,
true,doAll);
}
}
}
void PVCopy::updateRecord(
PVStructurePtr const &copyPVStructure,
BitSetPtr const &bitSet)
{
bool doAll = bitSet->get(0);
pvRecord->beginGroupPut();
if(headNode->isStructure) {
CopyStructureNodePtr node =
static_pointer_cast<CopyStructureNode>(headNode);
updateStructureNodeFromBitSet(
copyPVStructure,node,bitSet,false,doAll);
} else {
CopyRecordNodePtr recordNode =
static_pointer_cast<CopyRecordNode>(headNode);
PVFieldPtrArray const & pvCopyFields =
copyPVStructure->getPVFields();
if(pvCopyFields.size()==1) {
updateSubFieldFromBitSet(
pvCopyFields[0],
recordNode->recordPVField,bitSet,
false,doAll);
} else {
updateSubFieldFromBitSet(
copyPVStructure,
recordNode->recordPVField,bitSet,
false,doAll);
}
}
pvRecord->endGroupPut();
}
PVCopyMonitorPtr PVCopy::createPVCopyMonitor(
PVCopyMonitorRequesterPtr const &pvCopyMonitorRequester)
{
PVCopyMonitorPtr pvCopyMonitor( new PVCopyMonitor(
pvRecord,headNode,getPtrSelf(),pvCopyMonitorRequester));
return pvCopyMonitor;
}
epics::pvData::String PVCopy::dump()
{
String builder;
dump(&builder,headNode,0);
return builder;
}
void PVCopy::dump(String *builder,CopyNodePtr const &node,int indentLevel)
{
getConvert()->newLine(builder,indentLevel);
std::stringstream ss;
ss << (node->isStructure ? "structureNode" : "recordNode");
ss << " structureOffset " << node->structureOffset;
ss << " nfields " << node->nfields;
*builder += ss.str();
PVStructurePtr options = node->options;
if(options.get()!=NULL) {
getConvert()->newLine(builder,indentLevel +1);
options->toString(builder);
getConvert()->newLine(builder,indentLevel);
}
if(!node->isStructure) {
CopyRecordNodePtr recordNode = static_pointer_cast<CopyRecordNode>(node);
String name = recordNode->recordPVField->getFullName();
*builder += " recordField " + name;
return;
}
CopyStructureNodePtr structureNode =
static_pointer_cast<CopyStructureNode>(node);
CopyNodePtrArrayPtr nodes = structureNode->nodes;
for(size_t i=0; i<nodes->size(); ++i) {
if((*nodes)[i].get()==NULL) {
getConvert()->newLine(builder,indentLevel +1);
ss.str("");
ss << "node[" << i << "] is null";
*builder += ss.str();
continue;
}
dump(builder,(*nodes)[i],indentLevel+1);
}
}
bool PVCopy::init(epics::pvData::PVStructurePtr const &pvRequest)
{
PVRecordStructurePtr pvRecordStructure = pvRecord->getPVRecordStructure();
size_t len = pvRequest->getPVFields().size();
bool entireRecord = false;
if(len==String::npos) entireRecord = true;
if(len==0) entireRecord = true;
PVStructurePtr pvOptions;
if(len==1 && pvRequest->getSubField("_options")!=NULL) {
pvOptions = pvRequest->getStructureField("_options");
}
if(entireRecord) {
structure = pvRecordStructure->getPVStructure()->getStructure();
CopyRecordNodePtr recordNode(new CopyRecordNode());
headNode = recordNode;
recordNode->options = pvOptions;
recordNode->isStructure = false;
recordNode->structureOffset = 0;
recordNode->recordPVField = pvRecordStructure;
recordNode->nfields = pvRecordStructure->getPVStructure()->getNumberFields();
return true;
}
structure = createStructure(pvRecordStructure->getPVStructure(),pvRequest);
if(structure==NULL) return false;
cacheInitStructure = createPVStructure();
headNode = createStructureNodes(
pvRecord->getPVRecordStructure(),
pvRequest,
cacheInitStructure);
return true;
}
epics::pvData::String PVCopy::dump(
String const &value,
CopyNodePtr const &node,
int indentLevel)
{
throw std::logic_error(String("Not Implemented"));
}
StructureConstPtr PVCopy::createStructure(
PVStructurePtr const &pvRecord,
PVStructurePtr const &pvFromRequest)
{
if(pvFromRequest->getStructure()->getNumberFields()==0) {
return pvRecord->getStructure();
}
PVFieldPtrArray const &pvFromRequestFields = pvFromRequest->getPVFields();
StringArray const &fromRequestFieldNames = pvFromRequest->getStructure()->getFieldNames();
size_t length = pvFromRequestFields.size();
if(length==0) return NULLStructure;
FieldConstPtrArray fields; fields.reserve(length);
StringArray fieldNames; fields.reserve(length);
for(size_t i=0; i<length; ++i) {
String const &fieldName = fromRequestFieldNames[i];
PVFieldPtr pvRecordField = pvRecord->getSubField(fieldName);
if(pvRecordField==NULL) continue;
FieldConstPtr field = pvRecordField->getField();
if(field->getType()==epics::pvData::structure) {
PVStructurePtr pvRequestStructure = static_pointer_cast<PVStructure>(
pvFromRequestFields[i]);
if(pvRequestStructure->getNumberFields()>0) {
StringArray const &names = pvRequestStructure->getStructure()->
getFieldNames();
size_t num = names.size();
if(num>0 && names[0].compare("_options")==0) --num;
if(num>0) {
if(pvRecordField->getField()->getType()!=epics::pvData::structure) continue;
fieldNames.push_back(fieldName);
fields.push_back(createStructure(
static_pointer_cast<PVStructure>(pvRecordField),
pvRequestStructure));
continue;
}
}
}
fieldNames.push_back(fieldName);
fields.push_back(field);
}
size_t numsubfields = fields.size();
if(numsubfields==0) return NULLStructure;
return getFieldCreate()->createStructure(fieldNames, fields);
}
CopyNodePtr PVCopy::createStructureNodes(
PVRecordStructurePtr const &pvRecordStructure,
PVStructurePtr const &pvFromRequest,
PVStructurePtr const &pvFromCopy)
{
PVFieldPtrArray const & copyPVFields = pvFromCopy->getPVFields();
PVStructurePtr pvOptions;
PVFieldPtr pvField = pvFromRequest->getSubField("_options");
if(pvField!=NULL) pvOptions = static_pointer_cast<PVStructure>(pvField);
size_t number = copyPVFields.size();
CopyNodePtrArrayPtr nodes(new CopyNodePtrArray());
nodes->reserve(number);
for(size_t i=0; i<number; i++) {
PVFieldPtr copyPVField = copyPVFields[i];
String fieldName = copyPVField->getFieldName();
PVStructurePtr requestPVStructure = static_pointer_cast<PVStructure>(
pvFromRequest->getSubField(fieldName));
PVStructurePtr pvSubFieldOptions;
PVFieldPtr pvField = requestPVStructure->getSubField("_options");
if(pvField!=NULL) pvSubFieldOptions = static_pointer_cast<PVStructure>(pvField);
PVRecordFieldPtr pvRecordField;
PVRecordFieldPtrArrayPtr pvRecordFields = pvRecordStructure->getPVRecordFields();
for(size_t j=0; i<pvRecordFields->size(); j++ ) {
if((*pvRecordFields)[j]->getPVField()->getFieldName().compare(fieldName)==0) {
pvRecordField = (*pvRecordFields)[j];
break;
}
}
size_t numberRequest = requestPVStructure->getPVFields().size();
if(pvSubFieldOptions!=NULL) numberRequest--;
if(numberRequest>0) {
nodes->push_back(createStructureNodes(
static_pointer_cast<PVRecordStructure>(pvRecordField),
requestPVStructure,
static_pointer_cast<PVStructure>(copyPVField)));
continue;
}
CopyRecordNodePtr recordNode(new CopyRecordNode());
recordNode->options = pvSubFieldOptions;
recordNode->isStructure = false;
recordNode->recordPVField = pvRecordField;
recordNode->nfields = copyPVField->getNumberFields();
recordNode->structureOffset = copyPVField->getFieldOffset();
nodes->push_back(recordNode);
}
CopyStructureNodePtr structureNode(new CopyStructureNode());
structureNode->isStructure = true;
structureNode->nodes = nodes;
structureNode->structureOffset = pvFromCopy->getFieldOffset();
structureNode->nfields = pvFromCopy->getNumberFields();
structureNode->options = pvOptions;
return structureNode;
}
void PVCopy::updateStructureNodeSetBitSet(
PVStructurePtr const &pvCopy,
CopyStructureNodePtr const &structureNode,
epics::pvData::BitSetPtr const &bitSet)
{
for(size_t i=0; i<structureNode->nodes->size(); i++) {
CopyNodePtr node = (*structureNode->nodes)[i];
PVFieldPtr pvField = pvCopy->getSubField(node->structureOffset);
if(node->isStructure) {
PVStructurePtr xxx = static_pointer_cast<PVStructure>(pvField);
CopyStructureNodePtr yyy =
static_pointer_cast<CopyStructureNode>(node);
updateStructureNodeSetBitSet(xxx,yyy,bitSet);
} else {
CopyRecordNodePtr recordNode =
static_pointer_cast<CopyRecordNode>(node);
updateSubFieldSetBitSet(pvField,recordNode->recordPVField,bitSet);
}
}
}
void PVCopy::updateSubFieldSetBitSet(
PVFieldPtr const &pvCopy,
PVRecordFieldPtr const &pvRecord,
BitSetPtr const &bitSet)
{
FieldConstPtr field = pvCopy->getField();
Type type = field->getType();
if(type!=epics::pvData::structure) {
ConvertPtr convert = getConvert();
bool isEqual = convert->equals(pvCopy,pvRecord->getPVField());
if(isEqual) {
if(type==structureArray) {
// always act as though a change occurred.
// Note that array elements are shared.
bitSet->set(pvCopy->getFieldOffset());
}
}
if(isEqual) return;
convert->copy(pvRecord->getPVField(), pvCopy);
bitSet->set(pvCopy->getFieldOffset());
return;
}
PVStructurePtr pvCopyStructure = static_pointer_cast<PVStructure>(pvCopy);
PVFieldPtrArray const & pvCopyFields = pvCopyStructure->getPVFields();
PVRecordStructurePtr pvRecordStructure =
static_pointer_cast<PVRecordStructure>(pvRecord);
PVRecordFieldPtrArrayPtr pvRecordFields =
pvRecordStructure->getPVRecordFields();
size_t length = pvCopyFields.size();
for(size_t i=0; i<length; i++) {
updateSubFieldSetBitSet(pvCopyFields[i],(*pvRecordFields)[i],bitSet);
}
}
void PVCopy::updateStructureNodeFromBitSet(
PVStructurePtr const &pvCopy,
CopyStructureNodePtr const &structureNode,
BitSetPtr const &bitSet,
bool toCopy,
bool doAll)
{
size_t offset = structureNode->structureOffset;
if(!doAll) {
size_t nextSet = bitSet->nextSetBit(offset);
if(nextSet==String::npos) return;
}
if(offset>=pvCopy->getNextFieldOffset()) return;
if(!doAll) doAll = bitSet->get(offset);
CopyNodePtrArrayPtr nodes = structureNode->nodes;
for(size_t i=0; i<nodes->size(); i++) {
CopyNodePtr node = (*nodes)[i];
PVFieldPtr pvField = pvCopy->getSubField(node->structureOffset);
if(node->isStructure) {
PVStructurePtr xxx = static_pointer_cast<PVStructure>(pvField);
CopyStructureNodePtr subStructureNode =
static_pointer_cast<CopyStructureNode>(node);
updateStructureNodeFromBitSet(
xxx,subStructureNode,bitSet,toCopy,doAll);
} else {
CopyRecordNodePtr recordNode =
static_pointer_cast<CopyRecordNode>(node);
updateSubFieldFromBitSet(
pvField,recordNode->recordPVField,bitSet,toCopy,doAll);
}
}
}
void PVCopy::updateSubFieldFromBitSet(
PVFieldPtr const &pvCopy,
PVRecordFieldPtr const &pvRecordField,
BitSetPtr const &bitSet,
bool toCopy,
bool doAll)
{
if(!doAll) {
doAll = bitSet->get(pvCopy->getFieldOffset());
}
if(!doAll) {
size_t offset = pvCopy->getFieldOffset();
size_t nextSet = bitSet->nextSetBit(offset);
if(nextSet==String::npos) return;
if(nextSet>=pvCopy->getNextFieldOffset()) return;
}
ConvertPtr convert = getConvert();
if(pvCopy->getField()->getType()==epics::pvData::structure) {
PVStructurePtr pvCopyStructure =
static_pointer_cast<PVStructure>(pvCopy);
PVFieldPtrArray const & pvCopyFields = pvCopyStructure->getPVFields();
if(pvRecordField->getPVField()->getField()->getType()
!=epics::pvData::structure)
{
if(pvCopyFields.size()!=1) {
throw std::logic_error(String("Logic error"));
}
if(toCopy) {
convert->copy(pvRecordField->getPVField(), pvCopyFields[0]);
} else {
convert->copy(pvCopyFields[0], pvRecordField->getPVField());
}
return;
}
PVRecordStructurePtr pvRecordStructure =
static_pointer_cast<PVRecordStructure>(pvRecordField);
PVRecordFieldPtrArrayPtr pvRecordFields =
pvRecordStructure->getPVRecordFields();
for(size_t i=0; i<pvCopyFields.size(); i++) {
updateSubFieldFromBitSet(
pvCopyFields[i],
(*pvRecordFields)[i],
bitSet,toCopy,doAll);
}
} else {
if(toCopy) {
convert->copy(pvRecordField->getPVField(), pvCopy);
} else {
convert->copy(pvCopy, pvRecordField->getPVField());
}
}
}
CopyRecordNodePtr PVCopy::getCopyOffset(
CopyStructureNodePtr const &structureNode,
PVRecordFieldPtr const &recordPVField)
{
size_t offset = recordPVField->getPVField()->getFieldOffset();
CopyNodePtrArrayPtr nodes = structureNode->nodes;
for(size_t i=0; i< nodes->size(); i++) {
CopyNodePtr node = (*nodes)[i];
if(!node->isStructure) {
CopyRecordNodePtr recordNode =
static_pointer_cast<CopyRecordNode>(node);
size_t off = recordNode->recordPVField->getPVField()->
getFieldOffset();
size_t nextOffset = recordNode->recordPVField->getPVField()->
getNextFieldOffset();
if(offset>= off && offset<nextOffset) return recordNode;
} else {
CopyStructureNodePtr subNode =
static_pointer_cast<CopyStructureNode>(node);
CopyRecordNodePtr recordNode =
getCopyOffset(subNode,recordPVField);
if(recordNode.get()!=NULL) return recordNode;
}
}
return NULLCopyRecordNode;
}
CopyRecordNodePtr PVCopy::getRecordNode(
CopyStructureNodePtr const &structureNode,
std::size_t structureOffset)
{
CopyNodePtrArrayPtr nodes = structureNode->nodes;
for(size_t i=0; i< nodes->size(); i++) {
CopyNodePtr node = (*nodes)[i];
if(structureOffset>=(node->structureOffset + node->nfields)) continue;
if(!node->isStructure) {
CopyRecordNodePtr recordNode =
static_pointer_cast<CopyRecordNode>(node);
return recordNode;
}
CopyStructureNodePtr subNode =
static_pointer_cast<CopyStructureNode>(node);
return getRecordNode(subNode,structureOffset);
}
return NULLCopyRecordNode;
}
PVCopyMonitor::PVCopyMonitor(
PVRecordPtr const &pvRecord,
CopyNodePtr const &headNode,
PVCopyPtr const &pvCopy,
PVCopyMonitorRequesterPtr const &pvCopyMonitorRequester
)
: pvRecord(pvRecord),
headNode(headNode),
pvCopy(pvCopy),
pvCopyMonitorRequester(pvCopyMonitorRequester),
isGroupPut(false),
dataChanged(false),
isMonitoring(false)
{
}
PVCopyMonitor::~PVCopyMonitor()
{
if(pvRecord->getTraceLevel()>0)
{
cout << "~PVCopyMonitor" << endl;
}
}
void PVCopyMonitor::destroy()
{
if(pvRecord->getTraceLevel()>0)
{
cout << "PVCopyMonitor::destroy()" << endl;
}
stopMonitoring();
pvCopyMonitorRequester.reset();
pvCopy.reset();
}
void PVCopyMonitor::startMonitoring(
BitSetPtr const &changeBitSet,
BitSetPtr const &overrunBitSet)
{
if(pvRecord->getTraceLevel()>0)
{
cout << "PVCopyMonitor::startMonitoring()" << endl;
}
Lock xx(mutex);
if(isMonitoring) return;
isMonitoring = true;
this->changeBitSet = changeBitSet;
this->overrunBitSet = overrunBitSet;
isGroupPut = false;
pvRecord->lock();
try {
pvRecord->addListener(getPtrSelf());
addListener(headNode);
changeBitSet->clear();
overrunBitSet->clear();
changeBitSet->set(0);
pvCopyMonitorRequester->dataChanged();
pvRecord->unlock();
} catch(...) {
pvRecord->unlock();
}
}
void PVCopyMonitor::stopMonitoring()
{
if(pvRecord->getTraceLevel()>0)
{
cout << "PVCopyMonitor::stopMonitoring()" << endl;
}
Lock xx(mutex);
if(!isMonitoring) return;
isMonitoring = false;
pvRecord->removeListener(getPtrSelf());
}
void PVCopyMonitor::switchBitSets(
BitSetPtr const &newChangeBitSet,
BitSetPtr const &newOverrunBitSet)
{
changeBitSet = newChangeBitSet;
overrunBitSet = newOverrunBitSet;
}
void PVCopyMonitor::detach(PVRecordPtr const & pvRecord)
{
if(pvRecord->getTraceLevel()>0)
{
cout << "PVCopyMonitor::detach()" << endl;
}
}
void PVCopyMonitor::dataPut(PVRecordFieldPtr const & pvRecordField)
{
CopyNodePtr node = findNode(headNode,pvRecordField);
if(node.get()==NULL) {
throw std::logic_error("Logic error");
}
size_t offset = node->structureOffset;
bool isSet = changeBitSet->get(offset);
changeBitSet->set(offset);
if(isSet) overrunBitSet->set(offset);
if(!isGroupPut) pvCopyMonitorRequester->dataChanged();
dataChanged = true;
}
void PVCopyMonitor::dataPut(
PVRecordStructurePtr const & requested,
PVRecordFieldPtr const & pvRecordField)
{
CopyNodePtr node = findNode(headNode,requested);
if(node.get()==NULL || node->isStructure) {
throw std::logic_error("Logic error");
}
CopyRecordNodePtr recordNode = static_pointer_cast<CopyRecordNode>(node);
size_t offset = recordNode->structureOffset
+ (pvRecordField->getPVField()->getFieldOffset()
- recordNode->recordPVField->getPVField()->getFieldOffset());
bool isSet = changeBitSet->get(offset);
changeBitSet->set(offset);
if(isSet) overrunBitSet->set(offset);
if(!isGroupPut) pvCopyMonitorRequester->dataChanged();
dataChanged = true;
}
void PVCopyMonitor::beginGroupPut(PVRecordPtr const & pvRecord)
{
isGroupPut = true;
dataChanged = false;
}
void PVCopyMonitor::endGroupPut(PVRecordPtr const & pvRecord)
{
isGroupPut = false;
if(dataChanged) {
dataChanged = false;
pvCopyMonitorRequester->dataChanged();
}
}
void PVCopyMonitor::unlisten(PVRecordPtr const & pvRecord)
{
pvCopyMonitorRequester->unlisten();
}
void PVCopyMonitor::addListener(CopyNodePtr const & node)
{
if(!node->isStructure) {
PVRecordFieldPtr pvRecordField =
pvCopy->getRecordPVField(node->structureOffset);
pvRecordField->addListener(getPtrSelf());
return;
}
CopyStructureNodePtr structureNode =
static_pointer_cast<CopyStructureNode>(node);
for(size_t i=0; i< structureNode->nodes->size(); i++) {
addListener((*structureNode->nodes)[i]);
}
}
CopyNodePtr PVCopyMonitor::findNode(
CopyNodePtr const & node,
PVRecordFieldPtr const & pvRecordField)
{
if(!node->isStructure) {
CopyRecordNodePtr recordNode = static_pointer_cast<CopyRecordNode>(node);
if(recordNode->recordPVField==pvRecordField) return node;
return NULLCopyNode;
}
CopyStructureNodePtr structureNode = static_pointer_cast<CopyStructureNode>(node);
for(size_t i=0; i<structureNode->nodes->size(); i++) {
CopyNodePtr xxx = findNode((*structureNode->nodes)[i],pvRecordField);
if(xxx.get()!=NULL) return xxx;
}
return NULLCopyNode;
}
}}

View File

@@ -1,195 +0,0 @@
/* pvCopy.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 Marty Kraimer
* @date 2013.04
*/
#ifndef PVCOPY_H
#define PVCOPY_H
#include <string>
#include <stdexcept>
#include <memory>
#include <shareLib.h>
#include <pv/pvAccess.h>
#include <pv/pvDatabase.h>
namespace epics { namespace pvDatabase {
class PVCopy;
typedef std::tr1::shared_ptr<PVCopy> PVCopyPtr;
class PVCopyMonitor;
typedef std::tr1::shared_ptr<PVCopyMonitor> PVCopyMonitorPtr;
class PVCopyMonitorRequester;
typedef std::tr1::shared_ptr<PVCopyMonitorRequester> PVCopyMonitorRequesterPtr;
struct CopyNode;
typedef std::tr1::shared_ptr<CopyNode> CopyNodePtr;
struct CopyRecordNode;
typedef std::tr1::shared_ptr<CopyRecordNode> CopyRecordNodePtr;
struct CopyStructureNode;
typedef std::tr1::shared_ptr<CopyStructureNode> CopyStructureNodePtr;
class epicsShareClass PVCopy :
public std::tr1::enable_shared_from_this<PVCopy>
{
public:
POINTER_DEFINITIONS(PVCopy);
static PVCopyPtr create(
PVRecordPtr const &pvRecord,
epics::pvData::PVStructurePtr const &pvRequest,
epics::pvData::String const & structureName);
virtual ~PVCopy(){}
virtual void destroy();
PVRecordPtr getPVRecord();
epics::pvData::StructureConstPtr getStructure();
epics::pvData::PVStructurePtr createPVStructure();
std::size_t getCopyOffset(PVRecordFieldPtr const &recordPVField);
std::size_t getCopyOffset(
PVRecordStructurePtr const &recordPVStructure,
PVRecordFieldPtr const &recordPVField);
PVRecordFieldPtr getRecordPVField(std::size_t structureOffset);
void initCopy(
epics::pvData::PVStructurePtr const &copyPVStructure,
epics::pvData::BitSetPtr const &bitSet);
void updateCopySetBitSet(
epics::pvData::PVStructurePtr const &copyPVStructure,
epics::pvData::BitSetPtr const &bitSet);
void updateCopyFromBitSet(
epics::pvData::PVStructurePtr const &copyPVStructure,
epics::pvData::BitSetPtr const &bitSet);
void updateRecord(
epics::pvData::PVStructurePtr const &copyPVStructure,
epics::pvData::BitSetPtr const &bitSet);
PVCopyMonitorPtr createPVCopyMonitor(
PVCopyMonitorRequesterPtr const &pvCopyMonitorRequester);
epics::pvData::PVStructurePtr getOptions(
epics::pvData::PVStructurePtr const &copyPVStructure,std::size_t fieldOffset);
epics::pvData::String dump();
private:
void dump(
epics::pvData::String *builder,
CopyNodePtr const &node,
int indentLevel);
PVCopyPtr getPtrSelf()
{
return shared_from_this();
}
PVRecordPtr pvRecord;
epics::pvData::StructureConstPtr structure;
CopyNodePtr headNode;
epics::pvData::PVStructurePtr cacheInitStructure;
private:
PVCopy(PVRecordPtr const &pvRecord);
friend class PVCopyMonitor;
bool init(epics::pvData::PVStructurePtr const &pvRequest);
epics::pvData::String dump(
epics::pvData::String const &value,
CopyNodePtr const &node,
int indentLevel);
epics::pvData::StructureConstPtr createStructure(
epics::pvData::PVStructurePtr const &pvRecord,
epics::pvData::PVStructurePtr const &pvFromRequest);
CopyNodePtr createStructureNodes(
PVRecordStructurePtr const &pvRecordStructure,
epics::pvData::PVStructurePtr const &pvFromRequest,
epics::pvData::PVStructurePtr const &pvFromField);
void updateStructureNodeSetBitSet(
epics::pvData::PVStructurePtr const &pvCopy,
CopyStructureNodePtr const &structureNode,
epics::pvData::BitSetPtr const &bitSet);
void updateSubFieldSetBitSet(
epics::pvData::PVFieldPtr const &pvCopy,
PVRecordFieldPtr const &pvRecord,
epics::pvData::BitSetPtr const &bitSet);
void updateStructureNodeFromBitSet(
epics::pvData::PVStructurePtr const &pvCopy,
CopyStructureNodePtr const &structureNode,
epics::pvData::BitSetPtr const &bitSet,
bool toCopy,
bool doAll);
void updateSubFieldFromBitSet(
epics::pvData::PVFieldPtr const &pvCopy,
PVRecordFieldPtr const &pvRecordField,
epics::pvData::BitSetPtr const &bitSet,
bool toCopy,
bool doAll);
CopyRecordNodePtr getCopyOffset(
CopyStructureNodePtr const &structureNode,
PVRecordFieldPtr const &recordPVField);
CopyRecordNodePtr getRecordNode(
CopyStructureNodePtr const &structureNode,
std::size_t structureOffset);
};
class epicsShareClass PVCopyMonitor :
public PVListener,
public std::tr1::enable_shared_from_this<PVCopyMonitor>
{
public:
POINTER_DEFINITIONS(PVCopyMonitor);
virtual ~PVCopyMonitor();
virtual void destroy();
void startMonitoring(
epics::pvData::BitSetPtr const &changeBitSet,
epics::pvData::BitSetPtr const &overrunBitSet);
void stopMonitoring();
void switchBitSets(
epics::pvData::BitSetPtr const &newChangeBitSet,
epics::pvData::BitSetPtr const &newOverrunBitSet);
// following are PVListener methods
virtual void detach(PVRecordPtr const & pvRecord);
virtual void dataPut(PVRecordFieldPtr const & pvRecordField);
virtual void dataPut(
PVRecordStructurePtr const & requested,
PVRecordFieldPtr const & pvRecordField);
virtual void beginGroupPut(PVRecordPtr const & pvRecord);
virtual void endGroupPut(PVRecordPtr const & pvRecord);
virtual void unlisten(PVRecordPtr const & pvRecord);
private:
void addListener(CopyNodePtr const & node);
CopyNodePtr findNode(
CopyNodePtr const & node,
PVRecordFieldPtr const & pvRecordField);
PVCopyMonitorPtr getPtrSelf()
{
return shared_from_this();
}
PVCopyMonitor(
PVRecordPtr const &pvRecord,
CopyNodePtr const &headNode,
PVCopyPtr const &pvCopy,
PVCopyMonitorRequesterPtr const &pvCopyMonitorRequester);
friend class PVCopy;
PVRecordPtr pvRecord;
CopyNodePtr headNode;
PVCopyPtr pvCopy;
PVCopyMonitorRequesterPtr pvCopyMonitorRequester;
epics::pvData::BitSetPtr changeBitSet;
epics::pvData::BitSetPtr overrunBitSet;
bool isGroupPut;
bool dataChanged;
bool isMonitoring;
epics::pvData::Mutex mutex;
};
class epicsShareClass PVCopyMonitorRequester
{
public:
POINTER_DEFINITIONS(PVCopyMonitorRequester);
virtual ~PVCopyMonitorRequester() {}
virtual void dataChanged() = 0;
virtual void unlisten() = 0;
};
}}
#endif /* PVCOPY_H */

View File

@@ -0,0 +1,309 @@
/* pvCopyMonitor.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 Marty Kraimer
* @date 2013.04
*/
#include <string>
#include <stdexcept>
#include <memory>
#include <sstream>
#include <pv/thread.h>
#define epicsExportSharedSymbols
#include <pv/channelProviderLocal.h>
#include <pv/pvCopyMonitor.h>
using namespace epics::pvData;
using std::tr1::static_pointer_cast;
using std::tr1::dynamic_pointer_cast;
using std::size_t;
using std::cout;
using std::endl;
using std::string;
namespace epics { namespace pvDatabase {
struct PVCopyMonitorFieldNode
{
MonitorPluginPtr monitorPlugin;
size_t offset; // in pvCopy
};
PVCopyMonitorPtr PVCopyMonitor::create(
PVCopyMonitorRequesterPtr const &pvCopyMonitorRequester,
PVRecordPtr const &pvRecord,
PVCopyPtr const & pvCopy)
{
PVCopyMonitorPtr pvCopyMonitor( new PVCopyMonitor(
pvRecord,pvCopy,pvCopyMonitorRequester));
pvCopyMonitor->init(pvRecord->getPVRecordStructure()->getPVStructure());
return pvCopyMonitor;
}
PVCopyMonitor::PVCopyMonitor(
PVRecordPtr const &pvRecord,
PVCopyPtr const &pvCopy,
PVCopyMonitorRequesterPtr const &pvCopyMonitorRequester
)
: pvRecord(pvRecord),
pvCopy(pvCopy),
pvCopyMonitorRequester(pvCopyMonitorRequester),
isGroupPut(false),
dataChanged(false),
isMonitoring(false)
{
}
PVCopyMonitor::~PVCopyMonitor()
{
if(pvRecord->getTraceLevel()>0)
{
cout << "~PVCopyMonitor" << endl;
}
}
// pvField is in top level structure of PVRecord.
void PVCopyMonitor::init(PVFieldPtr const &pvField)
{
size_t offset = pvCopy->getCopyOffset(pvField);
if(offset==string::npos) return;
PVStructurePtr pvOptions = pvCopy->getOptions(offset);
if(pvOptions!=NULL) {
PVStringPtr pvName = pvOptions->getSubField<PVString>("plugin");
if(pvName!=NULL) {
string pluginName = pvName->get();
MonitorPluginManagerPtr manager = MonitorPluginManager::get();
MonitorPluginCreatorPtr pluginCreator = manager->findPlugin(pluginName);
if(pluginCreator!=NULL) {
StructureConstPtr top = pvCopy->getStructure();
FieldConstPtr field = pvField->getField();
MonitorPluginPtr monitorPlugin = pluginCreator->create(field,top,pvOptions);
if(monitorPlugin!=NULL) {
PVCopyMonitorFieldNodePtr fieldNode(new PVCopyMonitorFieldNode());
fieldNode->monitorPlugin = monitorPlugin;
fieldNode->offset = offset;
monitorFieldNodeList.push_back(fieldNode);
}
}
}
}
if(pvField->getField()->getType()!=structure) return;
PVStructurePtr pv = static_pointer_cast<PVStructure>(pvField);
const PVFieldPtrArray &pvFields = pv->getPVFields();
for(size_t i=0; i<pvFields.size(); ++i ) init(pvFields[i]);
}
MonitorPluginPtr PVCopyMonitor::getMonitorPlugin(size_t offset)
{
std::list<PVCopyMonitorFieldNodePtr>::iterator iter;
for (iter = monitorFieldNodeList.begin();iter!=monitorFieldNodeList.end();++iter)
{
if((*iter)->offset==offset) return (*iter)->monitorPlugin;
}
return MonitorPluginPtr();
}
void PVCopyMonitor::destroy()
{
if(pvRecord->getTraceLevel()>0)
{
cout << "PVCopyMonitor::destroy()" << endl;
}
stopMonitoring();
pvCopyMonitorRequester.reset();
pvCopy.reset();
}
void PVCopyMonitor::startMonitoring()
{
if(pvRecord->getTraceLevel()>0)
{
cout << "PVCopyMonitor::startMonitoring()" << endl;
}
Lock xx(mutex);
if(isMonitoring) return;
isMonitoring = true;
isGroupPut = false;
std::list<PVCopyMonitorFieldNodePtr>::iterator iter;
for (iter = monitorFieldNodeList.begin();iter!=monitorFieldNodeList.end();++iter)
{
(*iter)->monitorPlugin->startMonitoring();
}
pvRecord->lock();
try {
pvRecord->addListener(getPtrSelf());
pvCopy->traverseMaster(getPtrSelf());
monitorElement->changedBitSet->clear();
monitorElement->overrunBitSet->clear();
monitorElement->changedBitSet->set(0);
pvCopyMonitorRequester->dataChanged();
pvRecord->unlock();
} catch(...) {
pvRecord->unlock();
}
}
void PVCopyMonitor::nextMasterPVField(epics::pvData::PVFieldPtr const &pvField)
{
pvRecord->findPVRecordField(pvField)->addListener(getPtrSelf());
}
void PVCopyMonitor::stopMonitoring()
{
if(pvRecord->getTraceLevel()>0)
{
cout << "PVCopyMonitor::stopMonitoring()" << endl;
}
Lock xx(mutex);
if(!isMonitoring) return;
std::list<PVCopyMonitorFieldNodePtr>::iterator iter;
for (iter = monitorFieldNodeList.begin();iter!=monitorFieldNodeList.end();++iter)
{
(*iter)->monitorPlugin->stopMonitoring();
}
isMonitoring = false;
pvRecord->removeListener(getPtrSelf());
}
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)
{
if(pvRecord->getTraceLevel()>0)
{
cout << "PVCopyMonitor::detach()" << endl;
}
}
void PVCopyMonitor::dataPut(PVRecordFieldPtr const & pvRecordField)
{
if(pvRecord->getTraceLevel()>0)
{
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);
}
if(causeMonitor) {
if(!isGroupPut) pvCopyMonitorRequester->dataChanged();
dataChanged = true;
}
}
void PVCopyMonitor::dataPut(
PVRecordStructurePtr const & requested,
PVRecordFieldPtr const & pvRecordField)
{
if(pvRecord->getTraceLevel()>0)
{
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);
}
if(causeMonitor) {
if(!isGroupPut) pvCopyMonitorRequester->dataChanged();
dataChanged = true;
}
}
void PVCopyMonitor::beginGroupPut(PVRecordPtr const & pvRecord)
{
if(pvRecord->getTraceLevel()>0)
{
cout << "PVCopyMonitor::beginGroupPut()" << endl;
}
isGroupPut = true;
dataChanged = false;
std::list<PVCopyMonitorFieldNodePtr>::iterator iter;
for (iter = monitorFieldNodeList.begin();
iter!=monitorFieldNodeList.end();
++iter)
{
(*iter)->monitorPlugin->beginGroupPut();
}
}
void PVCopyMonitor::endGroupPut(PVRecordPtr const & pvRecord)
{
if(pvRecord->getTraceLevel()>0)
{
cout << "PVCopyMonitor::endGroupPut() dataChanged " << dataChanged << endl;
}
isGroupPut = false;
std::list<PVCopyMonitorFieldNodePtr>::iterator iter;
for (iter = monitorFieldNodeList.begin();iter!=monitorFieldNodeList.end();++iter)
{
(*iter)->monitorPlugin->endGroupPut();
}
if(dataChanged) {
dataChanged = false;
pvCopyMonitorRequester->dataChanged();
}
}
void PVCopyMonitor::unlisten(PVRecordPtr const & pvRecord)
{
pvCopyMonitorRequester->unlisten();
}
}}

View File

@@ -0,0 +1,109 @@
/* pvCopyMonitor.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 Marty Kraimer
* @date 2013.04
*/
#ifndef PVCOPYMONITOR_H
#define PVCOPYMONITOR_H
#ifdef epicsExportSharedSymbols
# define pvCopyMonitorEpicsExportSharedSymbols
# undef epicsExportSharedSymbols
#endif
#include <string>
#include <stdexcept>
#include <memory>
#include <list>
#include <shareLib.h>
#include <pv/monitorPlugin.h>
#include <pv/pvCopy.h>
#include <pv/pvAccess.h>
#ifdef pvCopyMonitorEpicsExportSharedSymbols
# define epicsExportSharedSymbols
# undef pvCopyMonitorEpicsExportSharedSymbols
#endif
#include <pv/pvDatabase.h>
namespace epics { namespace pvDatabase {
class PVCopyMonitor;
typedef std::tr1::shared_ptr<PVCopyMonitor> PVCopyMonitorPtr;
class PVCopyMonitorRequester;
typedef std::tr1::shared_ptr<PVCopyMonitorRequester> PVCopyMonitorRequesterPtr;
struct PVCopyMonitorFieldNode;
typedef std::tr1::shared_ptr<PVCopyMonitorFieldNode> PVCopyMonitorFieldNodePtr;
class epicsShareClass PVCopyMonitor :
public PVListener,
public epics::pvData::PVCopyTraverseMasterCallback,
public std::tr1::enable_shared_from_this<PVCopyMonitor>
{
public:
POINTER_DEFINITIONS(PVCopyMonitor);
static PVCopyMonitorPtr create(
PVCopyMonitorRequesterPtr const &pvCopyMonitorRequester,
PVRecordPtr const &pvRecord,
epics::pvData::PVCopyPtr const & pvCopy);
virtual ~PVCopyMonitor();
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);
virtual void dataPut(
PVRecordStructurePtr const & requested,
PVRecordFieldPtr const & pvRecordField);
virtual void beginGroupPut(PVRecordPtr const & pvRecord);
virtual void endGroupPut(PVRecordPtr const & pvRecord);
virtual void unlisten(PVRecordPtr const & pvRecord);
// following is PVCopyTraverseMasterCallback method
virtual void nextMasterPVField(epics::pvData::PVFieldPtr const &pvField);
private:
PVCopyMonitorPtr getPtrSelf()
{
return shared_from_this();
}
PVCopyMonitor(
PVRecordPtr const &pvRecord,
epics::pvData::PVCopyPtr const &pvCopy,
PVCopyMonitorRequesterPtr const &pvCopyMonitorRequester);
void init(epics::pvData::PVFieldPtr const &pvField);
epics::pvData::MonitorPluginPtr getMonitorPlugin(size_t offset);
PVRecordPtr pvRecord;
epics::pvData::PVCopyPtr pvCopy;
PVCopyMonitorRequesterPtr pvCopyMonitorRequester;
epics::pvData::MonitorElementPtr monitorElement;
bool isGroupPut;
bool dataChanged;
bool isMonitoring;
epics::pvData::Mutex mutex;
std::list<PVCopyMonitorFieldNodePtr> monitorFieldNodeList;
};
class epicsShareClass PVCopyMonitorRequester
{
public:
POINTER_DEFINITIONS(PVCopyMonitorRequester);
virtual ~PVCopyMonitorRequester() {}
virtual void dataChanged() = 0;
virtual void unlisten() = 0;
};
}}
#endif /* PVCOPYMONITOR_H */

View File

@@ -31,6 +31,8 @@
#include <pv/pvAccess.h>
#include <pv/serverContext.h>
#define epicsExportSharedSymbols
#include <pv/channelProviderLocal.h>
using std::cout;

View File

@@ -20,7 +20,7 @@ using namespace std;
namespace epics { namespace pvDatabase {
RecordListRecordPtr RecordListRecord::create(
epics::pvData::String const & recordName)
std::string const & recordName)
{
FieldCreatePtr fieldCreate = getFieldCreate();
PVDataCreatePtr pvDataCreate = getPVDataCreate();
@@ -52,7 +52,7 @@ RecordListRecordPtr RecordListRecord::create(
}
RecordListRecord::RecordListRecord(
epics::pvData::String const & recordName,
std::string const & recordName,
epics::pvData::PVStructurePtr const & pvStructure)
: PVRecord(recordName,pvStructure)
{
@@ -93,11 +93,11 @@ void RecordListRecord::process()
{
PVStringArrayPtr pvNames = PVDatabase::getMaster()->getRecordNames();
names->replace(pvNames->view());
String message("");
string message("");
if(database->get().compare("master")!=0) {
message += " can only access master ";
}
String regEx = regularExpression->get();
string regEx = regularExpression->get();
if(regEx.compare("")!=0 && regEx.compare(".*")!=0) {
message += " regularExpression not implemented ";
}

View File

@@ -26,13 +26,13 @@ class epicsShareClass RecordListRecord :
public:
POINTER_DEFINITIONS(RecordListRecord);
static RecordListRecordPtr create(
epics::pvData::String const & recordName);
std::string const & recordName);
virtual ~RecordListRecord();
virtual void destroy();
virtual bool init();
virtual void process();
private:
RecordListRecord(epics::pvData::String const & recordName,
RecordListRecord(std::string const & recordName,
epics::pvData::PVStructurePtr const & pvStructure);
epics::pvData::PVStringPtr database;
epics::pvData::PVStringPtr regularExpression;

View File

@@ -20,7 +20,7 @@ using namespace std;
namespace epics { namespace pvDatabase {
TraceRecordPtr TraceRecord::create(
epics::pvData::String const & recordName)
std::string const & recordName)
{
FieldCreatePtr fieldCreate = getFieldCreate();
PVDataCreatePtr pvDataCreate = getPVDataCreate();
@@ -50,7 +50,7 @@ TraceRecordPtr TraceRecord::create(
}
TraceRecord::TraceRecord(
epics::pvData::String const & recordName,
std::string const & recordName,
epics::pvData::PVStructurePtr const & pvStructure)
: PVRecord(recordName,pvStructure),
pvDatabase(PVDatabase::getMaster()),
@@ -82,7 +82,7 @@ bool TraceRecord::init()
void TraceRecord::process()
{
String name = pvRecordName->get();
string name = pvRecordName->get();
PVRecordPtr pvRecord = pvDatabase->findRecord(name);
if(pvRecord==NULL) {
pvResult->put(name + " not found");

View File

@@ -27,14 +27,14 @@ class epicsShareClass TraceRecord :
public:
POINTER_DEFINITIONS(TraceRecord);
static TraceRecordPtr create(
epics::pvData::String const & recordName);
std::string const & recordName);
virtual ~TraceRecord();
virtual void destroy();
virtual bool init();
virtual void process();
private:
TraceRecord(
epics::pvData::String const & recordName,
std::string const & recordName,
epics::pvData::PVStructurePtr const & pvStructure);
PVDatabasePtr pvDatabase;
epics::pvData::PVStringPtr pvRecordName;

View File

@@ -1,8 +1,6 @@
# Makefile at top of application tree
#Makefile at top of application tree
TOP = .
include $(TOP)/configure/CONFIG
DIRS += configure
DIRS += src

View File

@@ -14,11 +14,26 @@
# Set CHECK_RELEASE to NO to disable checking completely.
# Set CHECK_RELEASE to WARN to perform consistency checking but
# continue building anyway if conflicts are found.
CHECK_RELEASE = YES
#CHECK_RELEASE = YES
# Set this when you only want to compile this application
# for a subset of the cross-compiled target architectures
# that Base is built for.
#CROSS_COMPILER_TARGET_ARCHS = vxWorks-68040
# To install files into a location other than $(TOP) define
# INSTALL_LOCATION here.
#INSTALL_LOCATION=</path/name/to/install/top>
-include $(TOP)/../configure/CONFIG_SITE.local
-include $(TOP)/../../CONFIG.local
# Set this when your IOC and the host use different paths
# to access the application. This will be needed to boot
# from a Microsoft FTP server or with some NFS mounts.
# You must rebuild in the iocBoot directory for this to
# take effect.
#IOCS_APPL_TOP = </IOC/path/to/application/top>
INSTALL_INCLUDE = $(INSTALL_LOCATION)/include/pv
USR_INCLUDES += -I $(INSTALL_LOCATION)/include
-include $(TOP)/configure/CONFIG_SITE.local
-include $(TOP)/../CONFIG.local

View File

@@ -6,4 +6,3 @@ TARGETS = $(CONFIG_TARGETS)
CONFIGS += $(subst ../,,$(wildcard $(CONFIG_INSTALLS)))
include $(TOP)/configure/RULES

View File

@@ -1,4 +1,4 @@
# pvDatabaseCPP/testTop RELEASE - Location of external support modules
# pvDatabaseCPP/test RELEASE - Location of external support modules
#
# IF YOU CHANGE this file or any file it includes you must
# subsequently do a "gnumake rebuild" in the application's
@@ -16,9 +16,8 @@
# EPICS V4 Developers: Do not edit the locations in this file!
#
# Create a file RELEASE.local pointing to your PVASRV, PVACCESS,
# PVDATA, PVCOMMON and EPICS_BASE build directories, e.g.
# PVASRV = /path/to/epics/pvaSrvCPP
# Create a file RELEASE.local pointing to your places
# for the dependencies, e.g.
# PVACCESS = /path/to/epics/pvAccessCPP
# PVDATA = /path/to/epics/pvDataCPP
# PVCOMMON = /path/to/epics/pvCommonCPP
@@ -28,14 +27,14 @@
# use the following definitions:
PVDATABASE = $(TOP)/..
-include $(TOP)/../configure/RELEASE.local
-include $(TOP)/../../RELEASE.local
-include $(TOP)/../configure/RELEASE.local
# If you copied these tests from pvDatabaseCPP to be built as a
# standalone TOP, adjust and use the following definitions:
# standalone TOP, define
# PVDATABASE = /path/to/epics/pvDatabaseCPP
# in the appropriate RELEASE[.local],
# and use the following definitions instead:
#PVDATABASE = /path/to/epics/pvDatabaseCPP
#-include $(TOP)/configure/RELEASE.local
#-include $(TOP)/../RELEASE.local
#-include $(TOP)/configure/RELEASE.local

Some files were not shown because too many files have changed in this diff Show More