19 Commits
4.5.1 ... 4.5.2

Author SHA1 Message Date
Andrew Johnson
3f5bfd067f Update version numbers for release 2020-05-28 16:14:30 -05:00
mrkraimer
85165e6579 get ready for next epics7 release 2020-05-20 14:03:13 -04:00
Marty Kraimer
476a8f1e32 Merge pull request #56 from dirk-zimoch/CleanupWhitespace
Cleanup whitespace
2020-05-20 08:47:32 -04:00
31e883dbbc removed empty lines at end of file 2020-04-15 18:00:08 +02:00
57cbf66833 removed spaces at end of line 2020-04-15 17:58:14 +02:00
7f31332a80 replaced tabs with spaces 2020-04-15 17:54:47 +02:00
Marty Kraimer
12015309d8 Merge pull request #55 from epics-base/arrayfilterforunion
Arrayfilterforunion
2020-04-13 06:27:41 -04:00
mrkraimer
1e62844a22 testPlugin found bug: added unionArrayTest 2020-04-12 14:01:22 -04:00
mrkraimer
ad479309b0 fix bitset bug 2020-04-08 11:06:59 -04:00
mrkraimer
2f7c82757f pvArrayPlugin now supports union scalarArray 2020-04-07 12:53:01 -04:00
Marty Kraimer
634153a28d Merge pull request #54 from epics-base/issue53
Issue53
2020-02-18 05:39:58 -05:00
Heesterman, Peter J
e664037063 static analysis during the Codathon at Diamond. 2020-02-17 12:06:08 +00:00
mrkraimer
75c16bd423 pvDatabase::removeRecord and pvRecord::remove no longer call eachother directly 2020-02-12 09:13:19 -05:00
mrkraimer
083dffac3c pvDatabase::removeRecord and pvRecord::remove changes;descructors now have at most a print statement 2020-02-10 06:15:59 -05:00
mrkraimer
42ba054e5f add createdestroy example 2020-02-07 10:58:55 -05:00
mrkraimer
3173e9aeae problems with examples 2020-02-07 09:17:08 -05:00
mrkraimer
785d654129 first attempt to fix issue 53; add example 2020-02-07 08:54:18 -05:00
Ralph Lange
22ce4440b7 Fix bug preventing "whole structure" bitset(0) copy
(fixes #52)
(this should have a test added, but I am not familiar enough with the code)
2020-01-28 15:44:27 +01:00
Andrew Johnson
80baccfd9c Incr version and set development flag after release 2019-11-01 12:52:23 -05:00
45 changed files with 558 additions and 299 deletions

View File

@@ -38,7 +38,7 @@ PROJECT_NAME = pvDatabaseCPP
# could be handy for archiving the generated documentation or if some version # could be handy for archiving the generated documentation or if some version
# control system is used. # control system is used.
PROJECT_NUMBER = 4.5.1 PROJECT_NUMBER = 4.5.2
# Using the PROJECT_BRIEF tag one can provide an optional one line description # Using the PROJECT_BRIEF tag one can provide an optional one line description
# for a project that appears at the top of each page and should give viewer a # for a project that appears at the top of each page and should give viewer a

View File

@@ -2,7 +2,7 @@
EPICS_PVDATABASE_MAJOR_VERSION = 4 EPICS_PVDATABASE_MAJOR_VERSION = 4
EPICS_PVDATABASE_MINOR_VERSION = 5 EPICS_PVDATABASE_MINOR_VERSION = 5
EPICS_PVDATABASE_MAINTENANCE_VERSION = 1 EPICS_PVDATABASE_MAINTENANCE_VERSION = 2
# Development flag, set to zero for release versions # Development flag, set to zero for release versions

View File

@@ -2,6 +2,11 @@
This document summarizes the changes to the module between releases. This document summarizes the changes to the module between releases.
## Release 4.5.2 (EPICS 7.0.3.2 May 2020)
* plugin support is new
* fixed issues #53 and #52
## Release 4.5.1 (EPICS 7.0.3.1, Nov 2019) ## Release 4.5.1 (EPICS 7.0.3.1, Nov 2019)
* addRecord is new. * addRecord is new.

25
example/createdestroy/Makefile Executable file
View File

@@ -0,0 +1,25 @@
TOP=../..
include $(TOP)/configure/CONFIG
#----------------------------------------
# ADD MACRO DEFINITIONS AFTER THIS LINE
#=============================
#=============================
# Build the application
TESTPROD_HOST = createdestroy
createdestroy_SRCS += createdestroy.cpp
# Add all the support libraries needed by this application
#pvatest_LIBS += xxx
# Finally link to the EPICS Base libraries
createdestroy_LIBS += pvDatabase pvAccess pvData
createdestroy_LIBS += $(EPICS_BASE_IOC_LIBS)
#===========================
include $(TOP)/configure/RULES
#----------------------------------------
# ADD RULES AFTER THIS LINE

View File

@@ -0,0 +1,20 @@
# pvDatabaseCPP/example/createdestroy
This is an example that:
1) Gets the master PVDatabase
2) Create ChannelProviderLocal
3) Creates a ServerContext
Then it executes a forever loop that:
1) creates a pvRecord and adds it to the pvDatabase.
2) creates a pvac::ClientProvider
3) creates a pvac::ClientChannel
4) creates a monitor on the channel
5) runs a loop 10 times that: does a put to the channel, and then gets the data for any outstanding monitors
6) removes the pvRecord from the pvDatabase
It also has options to set trace level for the pvRecord and to periodically pause by asking for input.

View File

@@ -0,0 +1,179 @@
/******************************************************************************
* This is modeled after a test program created by Bertrand Bauvir from the ITER Organization
******************************************************************************/
#include <iostream>
#include <epicsGetopt.h>
#include <pv/pvData.h>
#include <pv/pvDatabase.h>
#include <pv/serverContext.h>
#include <pv/channelProviderLocal.h>
#include <pva/client.h>
#include <epicsEvent.h>
// Local header files
// Constants
#define DEFAULT_RECORD_NAME "examplechannel"
using std::tr1::static_pointer_cast;
class Record : public ::epics::pvDatabase::PVRecord
{
public:
std::shared_ptr<::epics::pvData::PVStructure> __pv;
static std::shared_ptr<Record> create (std::string const & name, std::shared_ptr<::epics::pvData::PVStructure> const & pvstruct);
Record (std::string const & name, std::shared_ptr<epics::pvData::PVStructure> const & pvstruct)
: epics::pvDatabase::PVRecord(name, pvstruct) { __pv = pvstruct; };
virtual void process (void);
};
std::shared_ptr<Record> Record::create (std::string const & name, std::shared_ptr<::epics::pvData::PVStructure> const & pvstruct)
{
std::shared_ptr<Record> pvrecord (new Record (name, pvstruct));
// Need to be explicitly called .. not part of the base constructor
if(!pvrecord->init()) pvrecord.reset();
return pvrecord;
}
void Record::process (void)
{
PVRecord::process();
std::string name = this->getRecordName();
std::cout << this->getRecordName()
<< " process\n";
}
class MyMonitor
{
private:
std::tr1::shared_ptr<::pvac::MonitorSync> monitor;
MyMonitor(std::tr1::shared_ptr<::pvac::ClientChannel> const &channel)
{
monitor = std::tr1::shared_ptr<::pvac::MonitorSync>(new ::pvac::MonitorSync(channel->monitor()));
}
public:
static std::tr1::shared_ptr<MyMonitor> create(std::tr1::shared_ptr<::pvac::ClientChannel> const &channel)
{
return std::tr1::shared_ptr<MyMonitor>(new MyMonitor(channel));
}
void getData();
};
void MyMonitor::getData()
{
while (true) {
if(!monitor->wait(.001)) break;
switch(monitor->event.event) {
case pvac::MonitorEvent::Fail:
std::cerr<<monitor->name()<<" : Error : "<<monitor->event.message<<"\n";
return;
case pvac::MonitorEvent::Cancel:
std::cout<<monitor->name()<<" <Cancel>\n";
return;
case pvac::MonitorEvent::Disconnect:
std::cout<<monitor->name()<<" <Disconnect>\n";
return;
case pvac::MonitorEvent::Data:
while(monitor->poll()) {
std::cout<<monitor->name()<<" : "<<monitor->root;
}
if(monitor->complete()) {
return;
}
}
}
}
int main (int argc, char** argv)
{
int verbose = 0;
unsigned loopctr = 0;
unsigned pausectr = 0;
bool allowExit = false;
bool callRecord = false;
bool callDatabase = false;
int opt;
while((opt = getopt(argc, argv, "v:ardh")) != -1) {
switch(opt) {
case 'v':
verbose = std::stoi(optarg);
break;
case 'a' :
allowExit = true;
break;
case 'r' :
callRecord = true;
break;
case 'd' :
callDatabase = true;
break;
case 'h':
std::cout << " -v level -a -r -d -h \n";
std::cout << "-r call pvRecord->remove -d call master->removeRecord\n";
std::cout << "default\n";
std::cout << "-v " << verbose
<< " -a false"
<< " -d"
<< "\n";
return 0;
default:
std::cerr<<"Unknown argument: "<<opt<<"\n";
return -1;
}
}
if(!callRecord && !callDatabase) callDatabase = true;
::epics::pvDatabase::PVDatabasePtr master = epics::pvDatabase::PVDatabase::getMaster();
::epics::pvDatabase::ChannelProviderLocalPtr channelProvider = epics::pvDatabase::getChannelProviderLocal();
epics::pvAccess::ServerContext::shared_pointer context
= epics::pvAccess::startPVAServer(epics::pvAccess::PVACCESS_ALL_PROVIDERS, 0, true, true);
std::string startset("starting set of puts valuectr = ");
while (true) {
loopctr++;
std::string name = DEFAULT_RECORD_NAME + std::to_string(loopctr);
// Create record
// Create record structure
::epics::pvData::FieldBuilderPtr builder = epics::pvData::getFieldCreate()->createFieldBuilder();
builder->add("value", ::epics::pvData::pvULong);
std::shared_ptr<::epics::pvData::PVStructure> pvstruct
= ::epics::pvData::getPVDataCreate()->createPVStructure(builder->createStructure());
std::shared_ptr<Record> pvrecord = Record::create(std::string(name), pvstruct);
master->addRecord(pvrecord);
pvrecord->setTraceLevel(verbose);
// Start PVA (local) client
std::tr1::shared_ptr<::pvac::ClientProvider> provider
= std::tr1::shared_ptr<::pvac::ClientProvider>(new ::pvac::ClientProvider ("pva"));
std::tr1::shared_ptr<::pvac::ClientChannel> channel
= std::tr1::shared_ptr<::pvac::ClientChannel>(new ::pvac::ClientChannel (provider->connect(name)));
std::tr1::shared_ptr<MyMonitor> mymonitor = MyMonitor::create(channel);
unsigned valuectr = loopctr;
std::cout << startset << loopctr << "\n";
for (int ind=0; ind<100; ind++) {
channel->put().set("value",valuectr++).exec();
mymonitor->getData();
}
pausectr++;
if(allowExit && pausectr>10) {
pausectr = 0;
std::cout << "Type exit to stop: \n";
int c = std::cin.peek(); // peek character
if ( c == EOF ) continue;
std::string str;
std::getline(std::cin,str);
if(str.compare("exit")==0) break;
}
if(callRecord) {
std::cout << "callRecord\n";
pvrecord->remove();
}
if(callDatabase) {
std::cout << "callDatabase\n";
master->removeRecord(pvrecord);
}
}
return (0);
}

View File

@@ -76,9 +76,19 @@ static vector<string> split(string const & colonSeparatedList) {
PVArrayFilterPtr PVArrayFilter::create( PVArrayFilterPtr PVArrayFilter::create(
const std::string & requestValue, const std::string & requestValue,
const PVFieldPtr & master) const PVFieldPtr & masterField)
{ {
Type type = master->getField()->getType(); bool masterIsUnion = false;
PVUnionPtr pvUnion;
Type type = masterField->getField()->getType();
if(type==epics::pvData::union_) {
pvUnion = std::tr1::static_pointer_cast<PVUnion>(masterField);
PVFieldPtr pvField = pvUnion->get();
if(pvField) {
masterIsUnion = true;
type = pvField->getField()->getType();
}
}
if(type!=scalarArray) { if(type!=scalarArray) {
PVArrayFilterPtr filter = PVArrayFilterPtr(); PVArrayFilterPtr filter = PVArrayFilterPtr();
return filter; return filter;
@@ -112,60 +122,82 @@ PVArrayFilterPtr PVArrayFilter::create(
PVArrayFilterPtr filter = PVArrayFilterPtr(); PVArrayFilterPtr filter = PVArrayFilterPtr();
return filter; return filter;
} }
PVScalarArrayPtr masterArray;
if(masterIsUnion) {
masterArray = static_pointer_cast<PVScalarArray>(pvUnion->get());
} else {
masterArray = static_pointer_cast<PVScalarArray>(masterField);
}
PVArrayFilterPtr filter = PVArrayFilterPtr filter =
PVArrayFilterPtr( PVArrayFilterPtr(
new PVArrayFilter( new PVArrayFilter(start,increment,end,masterField,masterArray));
start,increment,end,static_pointer_cast<PVScalarArray>(master)));
return filter; return filter;
} }
PVArrayFilter::PVArrayFilter(long start,long increment,long end,const PVScalarArrayPtr & masterArray) PVArrayFilter::PVArrayFilter(
long start,long increment,long end,
const PVFieldPtr & masterField,
const epics::pvData::PVScalarArrayPtr masterArray)
: start(start), : start(start),
increment(increment), increment(increment),
end(end), end(end),
masterField(masterField),
masterArray(masterArray) masterArray(masterArray)
{ {
} }
bool PVArrayFilter::filter(const PVFieldPtr & pvCopy,const BitSetPtr & bitSet,bool toCopy) bool PVArrayFilter::filter(const PVFieldPtr & pvField,const BitSetPtr & bitSet,bool toCopy)
{ {
PVScalarArrayPtr copyArray = static_pointer_cast<PVScalarArray>(pvCopy); PVFieldPtr pvCopy = pvField;
PVScalarArrayPtr copyArray;
bool isUnion = false;
Type type = masterField->getField()->getType();
if(type==epics::pvData::union_) {
isUnion = true;
PVUnionPtr pvMasterUnion = std::tr1::static_pointer_cast<PVUnion>(masterField);
PVUnionPtr pvCopyUnion = std::tr1::static_pointer_cast<PVUnion>(pvCopy);
if(toCopy) pvCopyUnion->copy(*pvMasterUnion);
PVFieldPtr pvField = pvCopyUnion->get();
copyArray = static_pointer_cast<PVScalarArray>(pvField);
} else {
copyArray = static_pointer_cast<PVScalarArray>(pvCopy);
}
long len = 0; long len = 0;
long start = this->start; long start = this->start;
long end = this->end; long end = this->end;
long no_elements = masterArray->getLength(); long no_elements = masterArray->getLength();
if(start<0) { if(start<0) {
start = no_elements+start; start = no_elements+start;
if(start<0) start = 0; if(start<0) start = 0;
} }
if (end < 0) { if (end < 0) {
end = no_elements + end; end = no_elements + end;
if (end < 0) end = 0; if (end < 0) end = 0;
} }
if(toCopy) { if(toCopy) {
if (end >= no_elements) end = no_elements - 1; if (end >= no_elements) end = no_elements - 1;
if (end - start >= 0) len = 1 + (end - start) / increment; if (end - start >= 0) len = 1 + (end - start) / increment;
if(len<=0 || start>=no_elements) { if(len<=0 || start>=no_elements) {
copyArray->setLength(0); copyArray->setLength(0);
return true; return true;
} }
long indfrom = start; long indfrom = start;
long indto = 0; long indto = 0;
copyArray->setCapacity(len); copyArray->setCapacity(len);
if(increment==1) { if(increment==1) {
copy(*masterArray,indfrom,1,*copyArray,indto,1,len); copy(*masterArray,indfrom,1,*copyArray,indto,1,len);
} else { } else {
for(long i=0; i<len; ++i) { for(long i=0; i<len; ++i) {
copy(*masterArray,indfrom,1,*copyArray,indto,1,1); copy(*masterArray,indfrom,1,*copyArray,indto,1,1);
indfrom += increment; indfrom += increment;
indto += 1; indto += 1;
} }
} }
copyArray->setLength(len); copyArray->setLength(len);
bitSet->set(pvCopy->getFieldOffset()); bitSet->set(pvField->getFieldOffset());
return true; return true;
} }
if (end - start >= 0) len = 1 + (end - start) / increment; if (end - start >= 0) len = 1 + (end - start) / increment;
if(len<=0) return true; if(len<=0) return true;
@@ -173,21 +205,21 @@ bool PVArrayFilter::filter(const PVFieldPtr & pvCopy,const BitSetPtr & bitSet,bo
long indfrom = 0; long indfrom = 0;
long indto = start; long indto = start;
if(increment==1) { if(increment==1) {
copy(*copyArray,indfrom,1,*masterArray,indto,1,len); copy(*copyArray,indfrom,1,*masterArray,indto,1,len);
} else { } else {
for(long i=0; i<len; ++i) { for(long i=0; i<len; ++i) {
copy(*copyArray,indfrom,1,*masterArray,indto,1,1); copy(*copyArray,indfrom,1,*masterArray,indto,1,1);
indfrom += 1; indfrom += 1;
indto += increment; indto += increment;
} }
} }
if(isUnion) masterField->postPut();
return true; return true;
} }
string PVArrayFilter::getName() string PVArrayFilter::getName()
{ {
return name; return name;
} }
}} }}

View File

@@ -244,7 +244,7 @@ void PVCopy::updateMasterCheckBitSet(
bitSet->clear(nextSet); bitSet->clear(nextSet);
PVStructurePtr pv = static_pointer_cast<PVStructure>(pvField); PVStructurePtr pv = static_pointer_cast<PVStructure>(pvField);
PVFieldPtrArray pvFieldArray = pv->getPVFields(); PVFieldPtrArray pvFieldArray = pv->getPVFields();
for(size_t i=0; i>pvFieldArray.size(); ++i) { for(size_t i=0; i<pvFieldArray.size(); ++i) {
PVFieldPtr pvField = pvFieldArray[i]; PVFieldPtr pvField = pvFieldArray[i];
bitSet->set(pvField->getFieldOffset()); bitSet->set(pvField->getFieldOffset());
} }
@@ -710,7 +710,7 @@ void PVCopy::setIgnore(CopyNodePtr const &node) {
CopyNodePtrArrayPtr nodes = structureNode->nodes; CopyNodePtrArrayPtr nodes = structureNode->nodes;
for(size_t i=0; i<nodes->size(); ++i) { for(size_t i=0; i<nodes->size(); ++i) {
CopyNodePtr node = (*nodes)[i]; CopyNodePtr node = (*nodes)[i];
setIgnore(node); } setIgnore(node); }
} else { } else {
size_t num = node->masterPVField->getNumberFields(); size_t num = node->masterPVField->getNumberFields();
if(num>1) { if(num>1) {

View File

@@ -128,8 +128,7 @@ bool PVDeadbandFilter::filter(const PVFieldPtr & pvCopy,const BitSetPtr & bitSet
string PVDeadbandFilter::getName() string PVDeadbandFilter::getName()
{ {
return name; return name;
} }
}} }}

View File

@@ -38,4 +38,3 @@ PVPluginPtr PVPluginRegistry::find(const std::string & name)
} }
}} }}

View File

@@ -120,8 +120,7 @@ bool PVTimestampFilter::filter(const PVFieldPtr & pvCopy,const BitSetPtr & bitSe
string PVTimestampFilter::getName() string PVTimestampFilter::getName()
{ {
return name; return name;
} }
}} }}

View File

@@ -56,14 +56,6 @@ PVDatabase::PVDatabase()
PVDatabase::~PVDatabase() PVDatabase::~PVDatabase()
{ {
if(DEBUG_LEVEL>0) cout << "PVDatabase::~PVDatabase()\n"; if(DEBUG_LEVEL>0) cout << "PVDatabase::~PVDatabase()\n";
size_t len = recordMap.size();
shared_vector<string> names(len);
PVRecordMap::iterator iter;
size_t i = 0;
for(iter = recordMap.begin(); iter!=recordMap.end(); ++iter) {
names[i++] = (*iter).first;
}
for(size_t i=0; i<len; ++i) removeRecord(findRecord(names[i]));
} }
void PVDatabase::lock() { void PVDatabase::lock() {
@@ -100,17 +92,28 @@ bool PVDatabase::addRecord(PVRecordPtr const & record)
return true; return true;
} }
bool PVDatabase::removeRecord(PVRecordPtr const & record) PVRecordWPtr PVDatabase::removeFromMap(PVRecordPtr const & record)
{ {
if(record->getTraceLevel()>0) {
cout << "PVDatabase::removeRecord " << record->getRecordName() << endl;
}
epicsGuard<epics::pvData::Mutex> guard(mutex); epicsGuard<epics::pvData::Mutex> guard(mutex);
string recordName = record->getRecordName(); string recordName = record->getRecordName();
PVRecordMap::iterator iter = recordMap.find(recordName); PVRecordMap::iterator iter = recordMap.find(recordName);
if(iter!=recordMap.end()) { if(iter!=recordMap.end()) {
PVRecordPtr pvRecord = (*iter).second; PVRecordPtr pvRecord = (*iter).second;
recordMap.erase(iter); recordMap.erase(iter);
return pvRecord->shared_from_this();
}
return PVRecordWPtr();
}
bool PVDatabase::removeRecord(PVRecordPtr const & record)
{
if(record->getTraceLevel()>0) {
cout << "PVDatabase::removeRecord " << record->getRecordName() << endl;
}
epicsGuard<epics::pvData::Mutex> guard(mutex);
PVRecordWPtr pvRecord = removeFromMap(record);
if(pvRecord.use_count()!=0) {
pvRecord.lock()->unlistenClients();
return true; return true;
} }
return false; return false;

View File

@@ -58,64 +58,16 @@ PVRecord::PVRecord(
{ {
} }
void PVRecord::notifyClients()
{
{
epicsGuard<epics::pvData::Mutex> guard(mutex);
if(traceLevel>0) {
cout << "PVRecord::notifyClients() " << recordName
<< endl;
}
}
pvTimeStamp.detach();
for(std::list<PVListenerWPtr>::iterator iter = pvListenerList.begin();
iter!=pvListenerList.end();
iter++ )
{
PVListenerPtr listener = iter->lock();
if(!listener) continue;
if(traceLevel>0) {
cout << "PVRecord::notifyClients() calling listener->unlisten "
<< recordName << endl;
}
listener->unlisten(shared_from_this());
}
pvListenerList.clear();
for (std::list<PVRecordClientWPtr>::iterator iter = clientList.begin();
iter!=clientList.end();
iter++ )
{
PVRecordClientPtr client = iter->lock();
if(!client) continue;
if(traceLevel>0) {
cout << "PVRecord::notifyClients() calling client->detach "
<< recordName << endl;
}
client->detach(shared_from_this());
}
if(traceLevel>0) {
cout << "PVRecord::notifyClients() calling clientList.clear() "
<< recordName << endl;
}
clientList.clear();
if(traceLevel>0) {
cout << "PVRecord::notifyClients() returning " << recordName << endl;
}
}
PVRecord::~PVRecord() PVRecord::~PVRecord()
{ {
if(traceLevel>0) { if(traceLevel>0) {
cout << "~PVRecord() " << recordName << endl; cout << "~PVRecord() " << recordName << endl;
} }
notifyClients();
} }
void PVRecord::remove() void PVRecord::unlistenClients()
{ {
PVDatabasePtr pvDatabase(PVDatabase::getMaster()); epicsGuard<epics::pvData::Mutex> guard(mutex);
if(pvDatabase) pvDatabase->removeRecord(shared_from_this());
pvTimeStamp.detach();
for(std::list<PVListenerWPtr>::iterator iter = pvListenerList.begin(); for(std::list<PVListenerWPtr>::iterator iter = pvListenerList.begin();
iter!=pvListenerList.end(); iter!=pvListenerList.end();
iter++ ) iter++ )
@@ -142,6 +94,19 @@ void PVRecord::remove()
clientList.clear(); clientList.clear();
} }
void PVRecord::remove()
{
if(traceLevel>0) {
cout << "PVRecord::remove() " << recordName << endl;
}
unlistenClients();
epicsGuard<epics::pvData::Mutex> guard(mutex);
PVDatabasePtr pvDatabase(PVDatabase::getMaster());
if(pvDatabase) pvDatabase->removeFromMap(shared_from_this());
pvTimeStamp.detach();
}
void PVRecord::initPVRecord() void PVRecord::initPVRecord()
{ {
PVRecordStructurePtr parent; PVRecordStructurePtr parent;

View File

@@ -87,4 +87,3 @@ private:
}} }}
#endif /* CONTROLSUPPORT_H */ #endif /* CONTROLSUPPORT_H */

View File

@@ -63,9 +63,13 @@ private:
long start; long start;
long increment; long increment;
long end; long end;
epics::pvData::PVFieldPtr masterField;
epics::pvData::PVScalarArrayPtr masterArray; epics::pvData::PVScalarArrayPtr masterArray;
PVArrayFilter(long start,long increment,long end,const epics::pvData::PVScalarArrayPtr & masterArray); PVArrayFilter(
long start,long increment,long end,
const epics::pvData::PVFieldPtr & masterField,
const epics::pvData::PVScalarArrayPtr masterArray);
public: public:
POINTER_DEFINITIONS(PVArrayFilter); POINTER_DEFINITIONS(PVArrayFilter);
virtual ~PVArrayFilter(); virtual ~PVArrayFilter();
@@ -95,4 +99,3 @@ public:
}} }}
#endif /* PVARRAYPLUGIN_H */ #endif /* PVARRAYPLUGIN_H */

View File

@@ -252,10 +252,12 @@ protected:
*/ */
void initPVRecord(); void initPVRecord();
private: private:
friend class PVDatabase;
void unlistenClients();
PVRecordFieldPtr findPVRecordField( PVRecordFieldPtr findPVRecordField(
PVRecordStructurePtr const & pvrs, PVRecordStructurePtr const & pvrs,
epics::pvData::PVFieldPtr const & pvField); epics::pvData::PVFieldPtr const & pvField);
void notifyClients();
std::string recordName; std::string recordName;
epics::pvData::PVStructurePtr pvStructure; epics::pvData::PVStructurePtr pvStructure;
@@ -499,6 +501,7 @@ public:
/** /**
* @brief Remove a record. * @brief Remove a record.
* @param record The record to remove. * @param record The record to remove.
*
* @return <b>true</b> if record was removed. * @return <b>true</b> if record was removed.
*/ */
bool removeRecord(PVRecordPtr const & record); bool removeRecord(PVRecordPtr const & record);
@@ -508,6 +511,9 @@ public:
*/ */
epics::pvData::PVStringArrayPtr getRecordNames(); epics::pvData::PVStringArrayPtr getRecordNames();
private: private:
friend class PVRecord;
PVRecordWPtr removeFromMap(PVRecordPtr const & record);
PVDatabase(); PVDatabase();
void lock(); void lock();
void unlock(); void unlock();
@@ -519,4 +525,3 @@ private:
}} }}
#endif /* PVDATABASE_H */ #endif /* PVDATABASE_H */

View File

@@ -100,4 +100,3 @@ public:
}} }}
#endif /* PVDEADBANDPLUGIN_H */ #endif /* PVDEADBANDPLUGIN_H */

View File

@@ -75,4 +75,3 @@ public:
}} }}
#endif /* PVSUPPORT_H */ #endif /* PVSUPPORT_H */

View File

@@ -98,4 +98,3 @@ public:
}} }}
#endif /* PVTIMESTAMPPLUGIN_H */ #endif /* PVTIMESTAMPPLUGIN_H */

View File

@@ -108,4 +108,3 @@ private:
}} }}
#endif /* SCALARALARMSUPPORT_H */ #endif /* SCALARALARMSUPPORT_H */

View File

@@ -68,7 +68,7 @@ static bool getProcess(PVStructurePtr pvRequest,bool processDefault)
return pvString->get().compare("true")==0 ? true : false; return pvString->get().compare("true")==0 ? true : false;
} else if(scalar->getScalarType()==pvBoolean) { } else if(scalar->getScalarType()==pvBoolean) {
PVBooleanPtr pvBoolean = static_pointer_cast<PVBoolean>(pvField); PVBooleanPtr pvBoolean = static_pointer_cast<PVBoolean>(pvField);
return pvBoolean->get(); return pvBoolean->get();
} }
return processDefault; return processDefault;
} }
@@ -132,7 +132,7 @@ ChannelProcessLocalPtr ChannelProcessLocal::create(
if(pvField) { if(pvField) {
PVStringPtr pvString = pvOptions->getSubField<PVString>("nProcess"); PVStringPtr pvString = pvOptions->getSubField<PVString>("nProcess");
if(pvString) { if(pvString) {
int size; int size=0;
std::stringstream ss; std::stringstream ss;
ss << pvString->get(); ss << pvString->get();
ss >> size; ss >> size;
@@ -156,10 +156,7 @@ ChannelProcessLocalPtr ChannelProcessLocal::create(
ChannelProcessLocal::~ChannelProcessLocal() ChannelProcessLocal::~ChannelProcessLocal()
{ {
PVRecordPtr pvr(pvRecord.lock()); //cout << "~ChannelProcessLocal()\n";
if(pvr && pvr->getTraceLevel()>0) {
cout << "~ChannelProcessLocal() " << pvr->getRecordName() << endl;
}
} }
std::tr1::shared_ptr<Channel> ChannelProcessLocal::getChannel() std::tr1::shared_ptr<Channel> ChannelProcessLocal::getChannel()
@@ -304,10 +301,7 @@ ChannelGetLocalPtr ChannelGetLocal::create(
ChannelGetLocal::~ChannelGetLocal() ChannelGetLocal::~ChannelGetLocal()
{ {
PVRecordPtr pvr(pvRecord.lock()); //cout << "~ChannelGetLocal()\n";
if(pvr && pvr->getTraceLevel()>0) {
cout << "~ChannelGetLocal() " << pvr->getRecordName() << endl;
}
} }
std::tr1::shared_ptr<Channel> ChannelGetLocal::getChannel() std::tr1::shared_ptr<Channel> ChannelGetLocal::getChannel()
@@ -469,10 +463,7 @@ ChannelPutLocalPtr ChannelPutLocal::create(
ChannelPutLocal::~ChannelPutLocal() ChannelPutLocal::~ChannelPutLocal()
{ {
PVRecordPtr pvr(pvRecord.lock()); //cout << "~ChannelPutLocal()\n";
if(pvr && pvr->getTraceLevel()>0) {
cout << "~ChannelPutLocal() " << pvr->getRecordName() << endl;
}
} }
std::tr1::shared_ptr<Channel> ChannelPutLocal::getChannel() std::tr1::shared_ptr<Channel> ChannelPutLocal::getChannel()
@@ -662,10 +653,7 @@ ChannelPutGetLocalPtr ChannelPutGetLocal::create(
ChannelPutGetLocal::~ChannelPutGetLocal() ChannelPutGetLocal::~ChannelPutGetLocal()
{ {
PVRecordPtr pvr(pvRecord.lock()); //cout << "~ChannelPutGetLocal()\n";
if(pvr && pvr->getTraceLevel()>0) {
cout << "~ChannelPutGetLocal() " << pvr->getRecordName() << endl;
}
} }
std::tr1::shared_ptr<Channel> ChannelPutGetLocal::getChannel() std::tr1::shared_ptr<Channel> ChannelPutGetLocal::getChannel()
@@ -862,10 +850,7 @@ ChannelRPCLocalPtr ChannelRPCLocal::create(
ChannelRPCLocal::~ChannelRPCLocal() ChannelRPCLocal::~ChannelRPCLocal()
{ {
PVRecordPtr pvr(pvRecord.lock()); //cout << "~ChannelRPCLocal()\n";
if(pvr && pvr->getTraceLevel()>0) {
cout << "~ChannelRPCLocal() " << pvr->getRecordName() << endl;
}
} }
std::tr1::shared_ptr<Channel> ChannelRPCLocal::getChannel() std::tr1::shared_ptr<Channel> ChannelRPCLocal::getChannel()
@@ -1104,10 +1089,7 @@ ChannelArrayLocalPtr ChannelArrayLocal::create(
ChannelArrayLocal::~ChannelArrayLocal() ChannelArrayLocal::~ChannelArrayLocal()
{ {
PVRecordPtr pvr(pvRecord.lock()); //cout << "~ChannelArrayLocal()\n";
if(pvr && pvr->getTraceLevel()>0) {
cout << "~ChannelArrayLocal() " << pvr->getRecordName() << endl;
}
} }
std::tr1::shared_ptr<Channel> ChannelArrayLocal::getChannel() std::tr1::shared_ptr<Channel> ChannelArrayLocal::getChannel()
@@ -1261,12 +1243,7 @@ ChannelLocal::ChannelLocal(
ChannelLocal::~ChannelLocal() ChannelLocal::~ChannelLocal()
{ {
PVRecordPtr pvr(pvRecord.lock()); // cout << "~ChannelLocal()" << endl;
if(!pvr) return;
if(pvr->getTraceLevel()>0)
{
cout << "~ChannelLocal()" << endl;
}
} }
ChannelProvider::shared_pointer ChannelLocal::getProvider() ChannelProvider::shared_pointer ChannelLocal::getProvider()

View File

@@ -191,10 +191,7 @@ MonitorLocal::MonitorLocal(
MonitorLocal::~MonitorLocal() MonitorLocal::~MonitorLocal()
{ {
if(pvRecord->getTraceLevel()>0) //cout << "MonitorLocal::~MonitorLocal()" << endl;
{
cout << "MonitorLocal::~MonitorLocal()" << endl;
}
} }
@@ -294,7 +291,7 @@ void MonitorLocal::dataPut(PVRecordFieldPtr const & pvRecordField)
{ {
if(pvRecord->getTraceLevel()>1) if(pvRecord->getTraceLevel()>1)
{ {
cout << "PVCopyMonitor::dataPut(pvRecordField)" << endl; cout << "MonitorLocal::dataPut(pvRecordField)" << endl;
} }
if(state!=active) return; if(state!=active) return;
{ {
@@ -319,7 +316,7 @@ void MonitorLocal::dataPut(
{ {
if(pvRecord->getTraceLevel()>1) if(pvRecord->getTraceLevel()>1)
{ {
cout << "PVCopyMonitor::dataPut(requested,pvRecordField)" << endl; cout << "MonitorLocal::dataPut(requested,pvRecordField)" << endl;
} }
if(state!=active) return; if(state!=active) return;
{ {
@@ -346,7 +343,7 @@ void MonitorLocal::beginGroupPut(PVRecordPtr const & pvRecord)
{ {
if(pvRecord->getTraceLevel()>1) if(pvRecord->getTraceLevel()>1)
{ {
cout << "PVCopyMonitor::beginGroupPut()" << endl; cout << "MonitorLocal::beginGroupPut()" << endl;
} }
if(state!=active) return; if(state!=active) return;
{ {
@@ -360,7 +357,7 @@ void MonitorLocal::endGroupPut(PVRecordPtr const & pvRecord)
{ {
if(pvRecord->getTraceLevel()>1) if(pvRecord->getTraceLevel()>1)
{ {
cout << "PVCopyMonitor::endGroupPut dataChanged " << dataChanged << endl; cout << "MonitorLocal::endGroupPut dataChanged " << dataChanged << endl;
} }
if(state!=active) return; if(state!=active) return;
{ {
@@ -377,7 +374,7 @@ void MonitorLocal::unlisten(PVRecordPtr const & pvRecord)
{ {
if(pvRecord->getTraceLevel()>1) if(pvRecord->getTraceLevel()>1)
{ {
cout << "PVCopyMonitor::unlisten\n"; cout << "MonitorLocal::unlisten\n";
} }
{ {
Lock xx(mutex); Lock xx(mutex);
@@ -387,7 +384,7 @@ void MonitorLocal::unlisten(PVRecordPtr const & pvRecord)
if(requester) { if(requester) {
if(pvRecord->getTraceLevel()>1) if(pvRecord->getTraceLevel()>1)
{ {
cout << "PVCopyMonitor::unlisten calling requester->unlisten\n"; cout << "MonitorLocal::unlisten calling requester->unlisten\n";
} }
requester->unlisten(getPtrSelf()); requester->unlisten(getPtrSelf());
} }

View File

@@ -115,4 +115,3 @@ void AddRecord::process()
}} }}

View File

@@ -164,4 +164,3 @@ void ProcessRecord::run()
}} }}

View File

@@ -90,4 +90,3 @@ void RemoveRecord::process()
}} }}

View File

@@ -93,4 +93,3 @@ void TraceRecord::process()
}} }}

View File

@@ -29,7 +29,7 @@ namespace epics { namespace pvDatabase {
ControlSupport::~ControlSupport() ControlSupport::~ControlSupport()
{ {
cout << "ControlSupport::~ControlSupport()\n"; //cout << "ControlSupport::~ControlSupport()\n";
} }
epics::pvData::StructureConstPtr ControlSupport::controlField(ScalarType scalarType) epics::pvData::StructureConstPtr ControlSupport::controlField(ScalarType scalarType)
@@ -135,4 +135,3 @@ void ControlSupport::reset()
}} }}

View File

@@ -30,7 +30,7 @@ namespace epics { namespace pvDatabase {
ScalarAlarmSupport::~ScalarAlarmSupport() ScalarAlarmSupport::~ScalarAlarmSupport()
{ {
cout << "ScalarAlarmSupport::~ScalarAlarmSupport()\n"; //cout << "ScalarAlarmSupport::~ScalarAlarmSupport()\n";
} }
@@ -216,4 +216,3 @@ void ScalarAlarmSupport::setAlarm(
}} }}

View File

@@ -26,7 +26,7 @@
#ifdef listenerEpicsExportSharedSymbols #ifdef listenerEpicsExportSharedSymbols
# define epicsExportSharedSymbols # define epicsExportSharedSymbols
# undef listenerEpicsExportSharedSymbols # undef listenerEpicsExportSharedSymbols
#endif #endif
#include <shareLib.h> #include <shareLib.h>

View File

@@ -25,7 +25,7 @@
#ifdef powerSupplyEpicsExportSharedSymbols #ifdef powerSupplyEpicsExportSharedSymbols
# define epicsExportSharedSymbols # define epicsExportSharedSymbols
# undef powerSupplyEpicsExportSharedSymbols # undef powerSupplyEpicsExportSharedSymbols
#endif #endif
#include <shareLib.h> #include <shareLib.h>

View File

@@ -25,7 +25,7 @@
#ifdef pvRecordClientEpicsExportSharedSymbols #ifdef pvRecordClientEpicsExportSharedSymbols
# define epicsExportSharedSymbols # define epicsExportSharedSymbols
# undef pvRecordClientEpicsExportSharedSymbols # undef pvRecordClientEpicsExportSharedSymbols
#endif #endif
#include <shareLib.h> #include <shareLib.h>

View File

@@ -134,4 +134,3 @@ MAIN(testExampleRecord)
test(); test();
return 0; return 0;
} }

View File

@@ -79,4 +79,3 @@ MAIN(testLocalProvider)
test(); test();
return 0; return 0;
} }

View File

@@ -75,4 +75,3 @@ MAIN(testPVAServer)
test(); test();
return 0; return 0;
} }

View File

@@ -401,4 +401,3 @@ MAIN(testPVCopy)
powerSupplyTest(); powerSupplyTest();
return 0; return 0;
} }

View File

@@ -103,4 +103,3 @@ MAIN(testPVRecord)
powerSupplyTest(); powerSupplyTest();
return 0; return 0;
} }

View File

@@ -145,6 +145,73 @@ static void arrayTest()
testOk1(nset==1); testOk1(nset==1);
} }
static void unionArrayTest()
{
if(debug) {cout << endl << endl << "****unionArrayTest****" << endl;}
bool result = false;
uint32 nset = 0;
size_t n = 10;
shared_vector<double> values(n);
for(size_t i=0; i<n; i++) values[i] = i + .06;
PVDoubleArrayPtr pvDoubleArray =
static_pointer_cast<PVDoubleArray>(PVDataCreate::getPVDataCreate()->createPVScalarArray(pvDouble));
const shared_vector<const double> yyy(freeze(values));
pvDoubleArray->putFrom(yyy);
StandardFieldPtr standardField = getStandardField();
FieldCreatePtr fieldCreate = getFieldCreate();
StructureConstPtr top = fieldCreate->createFieldBuilder()->
add("value",fieldCreate->createVariantUnion()) ->
add("timeStamp", standardField->timeStamp()) ->
addNestedStructure("subfield") ->
add("value",fieldCreate->createVariantUnion()) ->
endNested()->
createStructure();
PVStructurePtr pvRecordStructure(PVDataCreate::getPVDataCreate()->createPVStructure(top));
PVRecordPtr pvRecord(PVRecord::create("unionArrayRecord",pvRecordStructure));
PVUnionPtr pvUnion = pvRecord->getPVStructure()->getSubField<PVUnion>("value");
pvUnion->set(pvDoubleArray);
pvUnion = pvRecord->getPVStructure()->getSubField<PVUnion>("subfield.value");
pvUnion->set(pvDoubleArray);
if(debug) { cout << "initial\n" << pvRecordStructure << "\n";}
PVStructurePtr pvRequest(CreateRequest::create()->createRequest("value[array=1:3]"));
PVCopyPtr pvCopy(PVCopy::create(pvRecordStructure,pvRequest,""));
PVStructurePtr pvStructureCopy(pvCopy->createPVStructure());
BitSetPtr bitSet(new BitSet(pvStructureCopy->getNumberFields()));
PVDoubleArrayPtr pvValue(pvRecordStructure->getSubField<PVDoubleArray>("value"));
result = pvCopy->updateCopySetBitSet(pvStructureCopy,bitSet);
nset = bitSet->cardinality();
if(debug) {
cout << "after get value"
<< " result " << (result ? "true" : "false")
<< " nset " << nset
<< " bitSet " << *bitSet
<< " pvStructureCopy\n" << pvStructureCopy
<< "\n";
}
testOk1(result==true);
testOk1(nset==1);
pvRequest = CreateRequest::create()->createRequest("subfield.value[array=1:3]");
pvCopy = PVCopy::create(pvRecordStructure,pvRequest,"");
pvStructureCopy = pvCopy->createPVStructure();
bitSet = BitSetPtr(new BitSet(pvStructureCopy->getNumberFields()));
pvValue = pvRecordStructure->getSubField<PVDoubleArray>("subfield.value");
result = pvCopy->updateCopySetBitSet(pvStructureCopy,bitSet);
nset = bitSet->cardinality();
if(debug) {
cout << "after get subfield.value"
<< " result " << (result ? "true" : "false")
<< " nset " << nset
<< " bitSet " << *bitSet
<< " pvStructureCopy\n" << pvStructureCopy
<< "\n";
}
testOk1(result==true);
testOk1(nset==1);
}
static void timeStampTest() static void timeStampTest()
{ {
if(debug) {cout << endl << endl << "****timeStampTest****" << endl;} if(debug) {cout << endl << endl << "****timeStampTest****" << endl;}
@@ -267,12 +334,12 @@ static void ignoreTest()
MAIN(testPlugin) MAIN(testPlugin)
{ {
testPlan(22); testPlan(26);
PVDatabasePtr pvDatabase(PVDatabase::getMaster()); PVDatabasePtr pvDatabase(PVDatabase::getMaster());
deadbandTest(); deadbandTest();
arrayTest(); arrayTest();
unionArrayTest();
timeStampTest(); timeStampTest();
ignoreTest(); ignoreTest();
return 0; return 0;
} }