37 Commits
3.1.0 ... 4.0.2

Author SHA1 Message Date
dhickin
b8769aa0ca Fixed filenames of previous versions in html docs. 2014-12-04 17:17:22 +00:00
dhickin
a938f2325c Created dated version (20141009) of latest html doc. 2014-12-04 17:13:04 +00:00
dhickin
7743f3e3fd make "local" *.local files take precedence over those in TOP/.. 2014-12-03 16:52:01 +00:00
dhickin
e9ce6a2f0b include CONFIG_SITE.local instead of CONFIG.local at top-level. 2014-12-03 16:10:25 +00:00
Marty Kraimer
1ed48c15f1 Added tag 4.0.1 for changeset 541b0a7a645c 2014-11-11 07:07:34 -05:00
Marty Kraimer
d27f929595 merge from default branch 2014-11-11 06:52:56 -05:00
Matej Sekoranja
b4e17f271b win32 vs2013 compilation fix 2014-11-11 09:05:25 +01:00
Marty Kraimer
79f407486a in the future remove recordList since pvAccess provides pvlist 2014-11-10 10:24:07 -05:00
Matej Sekoranja
3c359728f7 Added tag 4.0.0 for changeset 85d46a2614f9 2014-10-29 13:17:22 +01:00
Matej Sekoranja
7b9693562a merge 2014-10-29 13:15:33 +01:00
Matej Sekoranja
f1c39ca5d2 clang compilation fixes 2014-10-16 07:30:42 +02:00
Marty Kraimer
16b1775b98 Added tag 4.0.0 for changeset 42dbe8a17f85 2014-10-15 08:37:24 -04:00
Marty Kraimer
f6ee7333bb merge changes from default 2014-10-15 07:29:49 -04:00
Matej Sekoranja
9f45bdfa75 missing epicsShareClass PowerSupply 2014-10-14 21:26:07 +02:00
Matej Sekoranja
03aa15b5f7 added missing lib for win32 2014-10-14 20:41:36 +02:00
Matej Sekoranja
8093952ca2 win32 test dll linkage 2014-10-14 07:40:34 +02:00
Marty Kraimer
2bea54e218 updated pvDatabaseCPP.html and TODO 2014-10-09 09:33:13 -04:00
dhickin
e81230dba5 Corrected spelling of synchrotron in licence. 2014-10-04 02:45:53 +01:00
dhickin
50b8f306c3 Spelling and typos. 2014-10-04 01:39:14 +01:00
Marty Kraimer
65be8e5678 Added tag 4.0.0 for changeset e2e041fa7d04 2014-10-01 09:01:22 -04:00
Marty Kraimer
dbb9310adc flow: Created branch 'release/4.0'. 2014-10-01 08:58:34 -04:00
Matej Sekoranja
50fbb396e8 win32 compilation of test and examples 2014-09-13 23:40:41 +02:00
Matej Sekoranja
ff19fe1cd8 win32 linkage 2014-09-13 23:01:29 +02:00
Matej Sekoranja
230938220e win compilation 2014-09-13 00:18:25 +02:00
Matej Sekoranja
334ed3b70a hopefully fixed windows exports 2014-09-12 10:00:00 +02:00
Marty Kraimer
4c7e51d8ad prepare documentation for pre release 2014-09-03 09:13:45 -04:00
Marty Kraimer
4973a6297e fixed bug in creating implementation of channelArray 2014-08-29 09:33:42 -04:00
Marty Kraimer
f0d1481a28 nanoSecond => nanosecond 2014-08-20 06:36:40 -04:00
Marty Kraimer
d5235db54c mainly documentation changes; did much testing 2014-08-11 14:18:49 -04:00
Marty Kraimer
b125035a11 fixed connection problems 2014-08-07 14:36:35 -04:00
Marty Kraimer
9551b0e4c6 fixed bugs in implementation of montor; connection problems still exist 2014-08-07 08:02:53 -04:00
Marty Kraimer
d6aa03815e changes because of ChannelArray API change; update TODO.md; add RELEASE_NOTES.html and TODO.html 2014-07-22 08:53:32 -04:00
Marty Kraimer
ce0d62fbbc changed upcoming release number. 2014-07-10 13:38:06 -04:00
Marty Kraimer
2fe3e66047 updated documentation; fixed bugs while updating documentation 2014-07-10 13:25:58 -04:00
dhickin
fa53d72258 Corrected includes for CONFIG_SITE files. 2014-07-02 12:27:00 +01:00
Marty Kraimer
b010cf0849 add some records for testing easyPVAJava 2014-07-02 07:11:50 -04:00
Matej Sekoranja
7fd707cb4b Added tag 3.1.0 for changeset 395f48d5196d 2014-07-02 00:12:37 +02:00
79 changed files with 7512 additions and 828 deletions

View File

@@ -1,2 +1,9 @@
bba6a2491bdf73681cef01caf0bd89c87d7989cd 0.9.1 bba6a2491bdf73681cef01caf0bd89c87d7989cd 0.9.1
abdc90bf52a0c31e24e2f9a079ef72350ee31686 before_merge_changesAfter3_0_2 abdc90bf52a0c31e24e2f9a079ef72350ee31686 before_merge_changesAfter3_0_2
395f48d5196dde5bf7f24a1849aee3f8d92e91b8 3.1.0
e2e041fa7d04a37836a4343589077001588ae031 4.0.0
e2e041fa7d04a37836a4343589077001588ae031 4.0.0
42dbe8a17f851861a16be7d426ef1206324aa197 4.0.0
42dbe8a17f851861a16be7d426ef1206324aa197 4.0.0
85d46a2614f925ccb423d6abd5dfe20d42fb5099 4.0.0
541b0a7a645c63d136e397994ed0ab7178cf02cf 4.0.1

View File

@@ -2,7 +2,7 @@
Copyright (c) 2008 Martin R. Kraimer Copyright (c) 2008 Martin R. Kraimer
Copyright (c) 2006 The University of Chicago, as Operator of Argonne Copyright (c) 2006 The University of Chicago, as Operator of Argonne
National Laboratory. National Laboratory.
Copyright (c) 2006 Deutsches Elektronen-Synchroton, Copyright (c) 2006 Deutsches Elektronen-Synchrotron,
Member of the Helmholtz Association, (DESY), HAMBURG, GERMANY. Member of the Helmholtz Association, (DESY), HAMBURG, GERMANY.
Copyright (c) 2007 Control System Laboratory, Copyright (c) 2007 Control System Laboratory,
(COSYLAB) Ljubljana Slovenia (COSYLAB) Ljubljana Slovenia

View File

@@ -35,5 +35,5 @@
INSTALL_INCLUDE = $(INSTALL_LOCATION)/include/pv INSTALL_INCLUDE = $(INSTALL_LOCATION)/include/pv
USR_INCLUDES += -I $(INSTALL_LOCATION)/include USR_INCLUDES += -I $(INSTALL_LOCATION)/include
-include $(TOP)/configure/CONFIG_SITE.local -include $(TOP)/../../CONFIG_SITE.local
-include $(TOP)/../CONFIG.local -include $(TOP)/../configure/CONFIG_SITE.local

View File

@@ -60,7 +60,7 @@ bool ArrayPerformance::init()
initPVRecord(); initPVRecord();
PVScalarArrayPtr pvScalarArray = getPVStructure()->getScalarArrayField("value",pvLong); PVScalarArrayPtr pvScalarArray = getPVStructure()->getScalarArrayField("value",pvLong);
if(pvScalarArray==NULL) return false; if(!pvScalarArray) return false;
pvValue = static_pointer_cast<PVLongArray>(pvScalarArray); pvValue = static_pointer_cast<PVLongArray>(pvScalarArray);
ArrayPerformancePtr xxx = dynamic_pointer_cast<ArrayPerformance>(getPtrSelf()); ArrayPerformancePtr xxx = dynamic_pointer_cast<ArrayPerformance>(getPtrSelf());
arrayPerformanceThread = ArrayPerformanceThreadPtr(new ArrayPerformanceThread(xxx)); arrayPerformanceThread = ArrayPerformanceThreadPtr(new ArrayPerformanceThread(xxx));
@@ -182,14 +182,18 @@ void ArrayPerformanceThread::run()
nSinceLastReport = 0; nSinceLastReport = 0;
} }
++nSinceLastReport; ++nSinceLastReport;
shared_vector<int64> xxx(arrayPerformance->size,value++);
shared_vector<const int64> data(freeze(xxx));
arrayPerformance->lock(); arrayPerformance->lock();
try { try {
arrayPerformance->beginGroupPut(); if(arrayPerformance->getTraceLevel()>1) {
arrayPerformance->pvValue->replace(data); cout << "arrayPerformance size " << arrayPerformance->size;
arrayPerformance->process(); cout << " value " << value +1 << endl;
arrayPerformance->endGroupPut(); }
shared_vector<int64> xxx(arrayPerformance->size,value++);
shared_vector<const int64> data(freeze(xxx));
arrayPerformance->beginGroupPut();
arrayPerformance->pvValue->replace(data);
arrayPerformance->process();
arrayPerformance->endGroupPut();
} catch(...) { } catch(...) {
arrayPerformance->unlock(); arrayPerformance->unlock();
throw; throw;

View File

@@ -17,7 +17,6 @@
# undef epicsExportSharedSymbols # undef epicsExportSharedSymbols
#endif #endif
#include <shareLib.h>
#include <epicsThread.h> #include <epicsThread.h>
#include <pv/standardPVField.h> #include <pv/standardPVField.h>
#include <pv/timeStamp.h> #include <pv/timeStamp.h>

View File

@@ -266,9 +266,9 @@ void LongArrayChannelGet::channelGetConnect(
bool structureOK(true); bool structureOK(true);
PVStructurePtr pvStructure = getPVDataCreate()->createPVStructure(structure); PVStructurePtr pvStructure = getPVDataCreate()->createPVStructure(structure);
PVFieldPtr pvField = pvStructure->getSubField("timeStamp"); PVFieldPtr pvField = pvStructure->getSubField("timeStamp");
if(pvField==NULL) structureOK = false; if(!pvField) structureOK = false;
pvField = pvStructure->getSubField("value"); pvField = pvStructure->getSubField("value");
if(pvField==NULL) { if(!pvField) {
structureOK = false; structureOK = false;
} else { } else {
FieldConstPtr field = pvField->getField(); FieldConstPtr field = pvField->getField();
@@ -292,7 +292,7 @@ bool LongArrayChannelGet::init()
{ {
ChannelProvider::shared_pointer channelProvider = ChannelProvider::shared_pointer channelProvider =
getChannelProviderRegistry()->getProvider(providerName); getChannelProviderRegistry()->getProvider(providerName);
if(channelProvider==NULL) { if(!channelProvider) {
cout << "provider " << providerName << " not found" << endl; cout << "provider " << providerName << " not found" << endl;
return false; return false;
} }
@@ -305,7 +305,7 @@ bool LongArrayChannelGet::init()
if(!status.isOK()) return false; if(!status.isOK()) return false;
CreateRequest::shared_pointer createRequest = CreateRequest::create(); CreateRequest::shared_pointer createRequest = CreateRequest::create();
PVStructurePtr pvRequest = createRequest->createRequest(request); PVStructurePtr pvRequest = createRequest->createRequest(request);
if(pvRequest==NULL) { if(!pvRequest) {
cout << "request logic error " << createRequest->getMessage() << endl; cout << "request logic error " << createRequest->getMessage() << endl;
return false; return false;
} }
@@ -334,10 +334,10 @@ void LongArrayChannelGet::destroy()
if(runReturned) break; if(runReturned) break;
epicsThreadSleep(.01); epicsThreadSleep(.01);
} }
if(longArrayChannelRequester!=NULL) { if(longArrayChannelRequester) {
longArrayChannelRequester->destroy(); longArrayChannelRequester->destroy();
} }
if(longArrayChannelGetRequester!=NULL) { if(longArrayChannelGetRequester) {
longArrayChannelGetRequester->destroy(); longArrayChannelGetRequester->destroy();
} }
thread->exitWait(); thread->exitWait();
@@ -433,7 +433,7 @@ void LongArrayChannelGet::run()
CreateRequest::create(); CreateRequest::create();
PVStructurePtr pvRequest = PVStructurePtr pvRequest =
createRequest->createRequest(request); createRequest->createRequest(request);
if(pvRequest==NULL) { if(!pvRequest) {
cout << "request logic error " << createRequest->getMessage() << endl; cout << "request logic error " << createRequest->getMessage() << endl;
return ; return ;
} }

View File

@@ -17,8 +17,6 @@
# undef epicsExportSharedSymbols # undef epicsExportSharedSymbols
#endif #endif
#include <shareLib.h>
#include <pv/event.h> #include <pv/event.h>
#include <pv/lock.h> #include <pv/lock.h>
#include <pv/standardPVField.h> #include <pv/standardPVField.h>

View File

@@ -138,9 +138,9 @@ void LAMMonitorRequester::monitorConnect(Status const & status,
} }
bool structureOK(true); bool structureOK(true);
FieldConstPtr field = structure->getField("timeStamp"); FieldConstPtr field = structure->getField("timeStamp");
if(field==NULL) structureOK = false; if(!field) structureOK = false;
field = structure->getField("value"); field = structure->getField("value");
if(field==NULL) { if(!field) {
structureOK = false; structureOK = false;
} else { } else {
if(field->getType()!=scalarArray) { if(field->getType()!=scalarArray) {
@@ -179,9 +179,9 @@ void LAMMonitorRequester::run()
{ {
Lock xx(mutex); Lock xx(mutex);
monitorElement = longArrayMonitor->monitor->poll(); monitorElement = longArrayMonitor->monitor->poll();
if(monitorElement!=NULL) pvStructure = monitorElement->pvStructurePtr; if(monitorElement) pvStructure = monitorElement->pvStructurePtr;
} }
if(monitorElement==NULL) break; if(!monitorElement) break;
if(waitTime>0.0) epicsThreadSleep(waitTime); if(waitTime>0.0) epicsThreadSleep(waitTime);
pvTimeStamp.attach(pvStructure->getSubField("timeStamp")); pvTimeStamp.attach(pvStructure->getSubField("timeStamp"));
pvTimeStamp.get(timeStamp); pvTimeStamp.get(timeStamp);
@@ -268,7 +268,7 @@ bool LongArrayMonitor::init(
monitorRequester->init(); monitorRequester->init();
ChannelProvider::shared_pointer channelProvider = ChannelProvider::shared_pointer channelProvider =
getChannelProviderRegistry()->getProvider(providerName); getChannelProviderRegistry()->getProvider(providerName);
if(channelProvider==NULL) { if(!channelProvider) {
cout << "provider " << providerName << " not found" << endl; cout << "provider " << providerName << " not found" << endl;
return false; return false;
} }
@@ -282,7 +282,7 @@ bool LongArrayMonitor::init(
request += "]field(value,timeStamp,alarm)"; request += "]field(value,timeStamp,alarm)";
CreateRequest::shared_pointer createRequest = CreateRequest::create(); CreateRequest::shared_pointer createRequest = CreateRequest::create();
PVStructurePtr pvRequest = createRequest->createRequest(request); PVStructurePtr pvRequest = createRequest->createRequest(request);
if(pvRequest==NULL) { if(!pvRequest) {
cout << "request logic error " << createRequest->getMessage() << endl; cout << "request logic error " << createRequest->getMessage() << endl;
return false; return false;
} }

View File

@@ -16,7 +16,6 @@
# undef epicsExportSharedSymbols # undef epicsExportSharedSymbols
#endif #endif
#include <shareLib.h>
#include <pv/event.h> #include <pv/event.h>
#include <pv/lock.h> #include <pv/lock.h>
#include <pv/standardPVField.h> #include <pv/standardPVField.h>

View File

@@ -110,7 +110,7 @@ private:
bool LongArrayChannelPut::init() bool LongArrayChannelPut::init()
{ {
ChannelProvider::shared_pointer channelProvider = getChannelProviderRegistry()->getProvider(providerName); ChannelProvider::shared_pointer channelProvider = getChannelProviderRegistry()->getProvider(providerName);
if(channelProvider==NULL) { if(!channelProvider) {
cout << "provider " << providerName << " not found" << endl; cout << "provider " << providerName << " not found" << endl;
return false; return false;
} }
@@ -119,7 +119,7 @@ bool LongArrayChannelPut::init()
if(!status.isOK()) return false; if(!status.isOK()) return false;
CreateRequest::shared_pointer createRequest = CreateRequest::create(); CreateRequest::shared_pointer createRequest = CreateRequest::create();
PVStructurePtr pvRequest = createRequest->createRequest(request); PVStructurePtr pvRequest = createRequest->createRequest(request);
if(pvRequest==NULL) { if(!pvRequest) {
cout << "request logic error " << createRequest->getMessage() << endl; cout << "request logic error " << createRequest->getMessage() << endl;
return false; return false;
} }
@@ -187,7 +187,7 @@ void LongArrayChannelPut::channelPutConnect(
bitSet = BitSetPtr(new BitSet(pvStructure->getNumberFields())); bitSet = BitSetPtr(new BitSet(pvStructure->getNumberFields()));
bool structureOK(true); bool structureOK(true);
PVFieldPtr pvField = pvStructure->getSubField("value"); PVFieldPtr pvField = pvStructure->getSubField("value");
if(pvField==NULL) { if(!pvField) {
structureOK = false; structureOK = false;
} else { } else {
FieldConstPtr field = pvField->getField(); FieldConstPtr field = pvField->getField();
@@ -267,7 +267,6 @@ void LongArrayChannelPut::run()
if(iterBetweenCreateChannel!=0) { if(iterBetweenCreateChannel!=0) {
if(numChannelCreate>=iterBetweenCreateChannel) { if(numChannelCreate>=iterBetweenCreateChannel) {
channel->destroy(); channel->destroy();
epicsThreadSleep(1.0);
ChannelProvider::shared_pointer channelProvider = ChannelProvider::shared_pointer channelProvider =
getChannelProviderRegistry()->getProvider(providerName); getChannelProviderRegistry()->getProvider(providerName);
channel = channelProvider->createChannel( channel = channelProvider->createChannel(
@@ -295,7 +294,7 @@ void LongArrayChannelPut::run()
channelPut->destroy(); channelPut->destroy();
CreateRequest::shared_pointer createRequest = CreateRequest::create(); CreateRequest::shared_pointer createRequest = CreateRequest::create();
PVStructurePtr pvRequest = createRequest->createRequest(request); PVStructurePtr pvRequest = createRequest->createRequest(request);
if(pvRequest==NULL) { if(!pvRequest) {
cout << "request logic error " << createRequest->getMessage() << endl; cout << "request logic error " << createRequest->getMessage() << endl;
return ; return ;
} }

View File

@@ -17,7 +17,6 @@
# undef epicsExportSharedSymbols # undef epicsExportSharedSymbols
#endif #endif
#include <shareLib.h>
#include <pv/event.h> #include <pv/event.h>
#include <pv/lock.h> #include <pv/lock.h>
#include <pv/standardPVField.h> #include <pv/standardPVField.h>

View File

@@ -25,4 +25,3 @@ USR_INCLUDES += -I $(INSTALL_LOCATION)/include
-include $(TOP)/../CONFIG_SITE.local -include $(TOP)/../CONFIG_SITE.local
-include $(TOP)/configure/CONFIG_SITE.local -include $(TOP)/configure/CONFIG_SITE.local

View File

@@ -0,0 +1,25 @@
<h1>Release 4.0 IN DEVELOPMENT</h1>
<p>The main changes since release 3.0.2 are:</p>
<ul>
<li>array semantics now enforce Copy On Write.</li>
<li>String no longer defined.</li>
<li>toString replaced by stream I/O </li>
<li>union is new type.</li>
<li>copy and monitor use new code in pvDataCPP</li>
</ul>
<h2>New Semantics for Arrays</h2>
<p>pvDatabaseCPP has been changed to use the new array implementation from pvDataCPP.</p>
<h2>String no longer defined</h2>
<p>String is replaced by std::string.</p>
<h2>toString replaced by stream I/O</h2>
<p>All uses of toString have been changed to use the steam I/O that pvDataCPP implements.</p>
<h2>union is a new basic type.</h2>
<p>exampleDatabase now has example records for union and union array.
There are records for regular union and for variant union.</p>
<h2>copy</h2>
<p>The implementation of copy and monitor for pvAccess has been changed
to use the new monitor and copy support from pvDataCPP.</p>
<h2>monitorPlugin</h2>
<p>exampleDatabase now has a example plugin that implements onChange.</p>
<h1>Release 0.9.2</h1>
<p>This was the starting point for RELEASE_NOTES</p>

View File

@@ -0,0 +1,50 @@
Release 4.0 IN DEVELOPMENT
===========
The main changes since release 3.0.2 are:
* array semantics now enforce Copy On Write.
* String no longer defined.
* toString replaced by stream I/O
* union is new type.
* copy and monitor use new code in pvDataCPP
New Semantics for Arrays
--------
pvDatabaseCPP has been changed to use the new array implementation from pvDataCPP.
String no longer defined
---------
String is replaced by std::string.
toString replaced by stream I/O
---------
All uses of toString have been changed to use the steam I/O that pvDataCPP implements.
union is a new basic type.
------------
exampleDatabase now has example records for union and union array.
There are records for regular union and for variant union.
copy
----
The implementation of copy and monitor for pvAccess has been changed
to use the new monitor and copy support from pvDataCPP.
monitorPlugin
-------------
exampleDatabase now has a example plugin that implements onChange.
Release 0.9.2
==========
This was the starting point for RELEASE_NOTES

13
documentation/TODO.html Normal file
View File

@@ -0,0 +1,13 @@
<h1>TODO</h1>
<h2>recordList</h2>
<p>This is putGet support that provides a list of all the records in an IOC.
Since pvAccess implements pvlist this is no longer needed.
Remove it from pvDatabaseCPP and pvIOCCPP.
Also remove channelList from swtshell.</p>
<h2>monitorPlugin</h2>
<p>A debate is on-going about what semantics should be.</p>
<h2>Must test record delete.</h2>
<p>Must test removing a record from the PVDatabase while a pvAccess client
is attached. Also why do both unlisten and detach exists?</p>
<h2>create more regression tests</h2>
<p>Currently only some simple tests exist. Most of the testing has been via the examples</p>

28
documentation/TODO.md Normal file
View File

@@ -0,0 +1,28 @@
TODO
===========
recordList
----------
This is putGet support that provides a list of all the records in an IOC.
Since pvAccess implements pvlist this is no longer needed.
Remove it from pvDatabaseCPP and pvIOCCPP.
Also remove channelList from swtshell.
monitorPlugin
-------------
A debate is on-going about what semantics should be.
Must test record delete.
-------------------
Must test removing a record from the PVDatabase while a pvAccess client
is attached. Also why do both unlisten and detach exists?
create more regression tests
----------------
Currently only some simple tests exist. Most of the testing has been via the examples

File diff suppressed because it is too large Load Diff

View File

@@ -46,7 +46,7 @@
</dd> </dd>
<dt>This version:</dt> <dt>This version:</dt>
<dd><a <dd><a
href="pvDatabaseCPP.html">pvDatabaseCPP.html</a> href="pvDatabaseCPP_20121127.html">pvDatabaseCPP_20121127.html</a>
</dd> </dd>
<dt>Previous version:</dt> <dt>Previous version:</dt>
<dd>None</dd> <dd>None</dd>

View File

@@ -46,7 +46,7 @@
</dd> </dd>
<dt>This version:</dt> <dt>This version:</dt>
<dd><a <dd><a
href="pvDatabaseCPP_20121211.html">pvDatabaseCPP20121211.html</a> href="pvDatabaseCPP_20121211.html">pvDatabaseCPP_20121211.html</a>
</dd> </dd>
<dt>Previous version:</dt> <dt>Previous version:</dt>
<dd><a <dd><a

View File

@@ -46,11 +46,11 @@
</dd> </dd>
<dt>This version:</dt> <dt>This version:</dt>
<dd><a <dd><a
href="pvDatabaseCPP_20130417.html">pvDatabaseCPP20130417.html</a> href="pvDatabaseCPP_20130417.html">pvDatabaseCPP_20130417.html</a>
</dd> </dd>
<dt>Previous version:</dt> <dt>Previous version:</dt>
<dd><a <dd><a
href="pvDatabaseCPP_20121211.html">pvDatabaseCPP20121211.html</a> href="pvDatabaseCPP_20121211.html">pvDatabaseCPP_20121211.html</a>
</dd> </dd>
<dt>Editors:</dt> <dt>Editors:</dt>
<dd>Marty Kraimer, BNL</dd> <dd>Marty Kraimer, BNL</dd>

View File

@@ -46,11 +46,11 @@
</dd> </dd>
<dt>This version:</dt> <dt>This version:</dt>
<dd><a <dd><a
href="pvDatabaseCPP_20130516.html">pvDatabaseCPP20130516.html</a> href="pvDatabaseCPP_20130516.html">pvDatabaseCPP_20130516.html</a>
</dd> </dd>
<dt>Previous version:</dt> <dt>Previous version:</dt>
<dd><a <dd><a
href="pvDatabaseCPP_20130417.html">pvDatabaseCPP20130417.html</a> href="pvDatabaseCPP_20130417.html">pvDatabaseCPP_20130417.html</a>
</dd> </dd>
<dt>Editors:</dt> <dt>Editors:</dt>
<dd>Marty Kraimer, BNL</dd> <dd>Marty Kraimer, BNL</dd>

View File

@@ -46,11 +46,11 @@
</dd> </dd>
<dt>This version:</dt> <dt>This version:</dt>
<dd><a <dd><a
href="pvDatabaseCPP_20130523.html">pvDatabaseCPP20130523.html</a> href="pvDatabaseCPP_20130523.html">pvDatabaseCPP_20130523.html</a>
</dd> </dd>
<dt>Previous version:</dt> <dt>Previous version:</dt>
<dd><a <dd><a
href="pvDatabaseCPP_20130516.html">pvDatabaseCPP20130516.html</a> href="pvDatabaseCPP_20130516.html">pvDatabaseCPP_20130516.html</a>
</dd> </dd>
<dt>Editors:</dt> <dt>Editors:</dt>
<dd>Marty Kraimer, BNL</dd> <dd>Marty Kraimer, BNL</dd>

View File

@@ -46,11 +46,11 @@
</dd> </dd>
<dt>This version:</dt> <dt>This version:</dt>
<dd><a <dd><a
href="pvDatabaseCPP_20130627.html">pvDatabaseCPP20130627.html</a> href="pvDatabaseCPP_20130627.html">pvDatabaseCPP_20130627.html</a>
</dd> </dd>
<dt>Previous version:</dt> <dt>Previous version:</dt>
<dd><a <dd><a
href="pvDatabaseCPP_20130523.html">pvDatabaseCPP20130523.html</a> href="pvDatabaseCPP_20130523.html">pvDatabaseCPP_20130523.html</a>
</dd> </dd>
<dt>Editors:</dt> <dt>Editors:</dt>
<dd>Marty Kraimer, BNL</dd> <dd>Marty Kraimer, BNL</dd>

View File

@@ -46,11 +46,11 @@
</dd> </dd>
<dt>This version:</dt> <dt>This version:</dt>
<dd><a <dd><a
href= "pvDatabaseCPP_20130725.html">pvDatabaseCPP20130725.html</a> href= "pvDatabaseCPP_20130725.html">pvDatabase_CPP20130725.html</a>
</dd> </dd>
<dt>Previous version:</dt> <dt>Previous version:</dt>
<dd><a <dd><a
href="pvDatabaseCPP_20130627.html">pvDatabaseCPP20130627.html</a> href="pvDatabaseCPP_20130627.html">pvDatabase_CPP20130627.html</a>
</dd> </dd>
<dt>Editors:</dt> <dt>Editors:</dt>
<dd>Marty Kraimer, BNL</dd> <dd>Marty Kraimer, BNL</dd>

View File

@@ -46,10 +46,10 @@
</dd> </dd>
<dt>This version:</dt> <dt>This version:</dt>
<dd><a <dd><a
href= "pvDatabaseCPP_20130828.html">pvDatabaseCPP20130828.html</a> href= "pvDatabaseCPP_20130828.html">pvDatabase_CPP20130828.html</a>
</dd> </dd>
<dt>Previous version:</dt> <dt>Previous version:</dt>
<dd><a href="pvDatabaseCPP_20130725.html">pvDatabaseCPP20130725.html</a> <dd><a href="pvDatabaseCPP_20130725.html">pvDatabase_CPP20130725.html</a>
</dd> </dd>
<dt>Editors:</dt> <dt>Editors:</dt>
<dd>Marty Kraimer, BNL</dd> <dd>Marty Kraimer, BNL</dd>

View File

@@ -46,11 +46,11 @@
</dd> </dd>
<dt>This version:</dt> <dt>This version:</dt>
<dd><a <dd><a
href= "pvDatabaseCPP_20130904.html">pvDatabaseCPP20130904.html</a> href= "pvDatabaseCPP_20130904.html">pvDatabaseCPP_20130904.html</a>
</dd> </dd>
<dt>Previous version:</dt> <dt>Previous version:</dt>
<dd><a <dd><a
href= "pvDatabaseCPP_20130828.html">pvDatabaseCPP20130828.html</a> href= "pvDatabaseCPP_20130828.html">pvDatabaseCPP_20130828.html</a>
</dd> </dd>
<dt>Editors:</dt> <dt>Editors:</dt>
<dd>Marty Kraimer, BNL</dd> <dd>Marty Kraimer, BNL</dd>

View File

@@ -46,11 +46,11 @@
</dd> </dd>
<dt>This version:</dt> <dt>This version:</dt>
<dd><a <dd><a
href= "pvDatabaseCPP_20131112.html">pvDatabaseCPP20131112.html</a> href= "pvDatabaseCPP_20131112.html">pvDatabaseCPP_20131112.html</a>
</dd> </dd>
<dt>Previous version:</dt> <dt>Previous version:</dt>
<dd><a <dd><a
href= "pvDatabaseCPP_20130904.html">pvDatabaseCPP20130904.html</a> href= "pvDatabaseCPP_20130904.html">pvDatabaseCPP_20130904.html</a>
</dd> </dd>
<dt>Editors:</dt> <dt>Editors:</dt>
<dd>Marty Kraimer, BNL</dd> <dd>Marty Kraimer, BNL</dd>

View File

@@ -46,11 +46,11 @@
</dd> </dd>
<dt>This version:</dt> <dt>This version:</dt>
<dd><a <dd><a
href= "pvDatabaseCPP_20131113.html">pvDatabaseCPP20131113.html</a> href= "pvDatabaseCPP_20131113.html">pvDatabaseCPP_20131113.html</a>
</dd> </dd>
<dt>Previous version:</dt> <dt>Previous version:</dt>
<dd><a <dd><a
href= "pvDatabaseCPP_20131112.html">pvDatabaseCPP20131112.html</a> href= "pvDatabaseCPP_20131112.html">pvDatabaseCPP_20131112.html</a>
</dd> </dd>
<dt>Editors:</dt> <dt>Editors:</dt>
<dd>Marty Kraimer, BNL</dd> <dd>Marty Kraimer, BNL</dd>

View File

@@ -46,11 +46,11 @@
</dd> </dd>
<dt>This version:</dt> <dt>This version:</dt>
<dd><a <dd><a
href= "pvDatabaseCPP_20131120.html">pvDatabaseCPP20131120.html</a> href= "pvDatabaseCPP_20131120.html">pvDatabaseCPP_20131120.html</a>
</dd> </dd>
<dt>Previous version:</dt> <dt>Previous version:</dt>
<dd><a <dd><a
href= "pvDatabaseCPP_20131112.html">pvDatabaseCPP20131112.html</a> href= "pvDatabaseCPP_20131112.html">pvDatabaseCPP_20131112.html</a>
</dd> </dd>
<dt>Editors:</dt> <dt>Editors:</dt>
<dd>Marty Kraimer, BNL</dd> <dd>Marty Kraimer, BNL</dd>

View File

@@ -46,11 +46,11 @@
</dd> </dd>
<dt>This version:</dt> <dt>This version:</dt>
<dd><a <dd><a
href= "pvDatabaseCPP_20131121.html">pvDatabaseCPP20131121.html</a> href= "pvDatabaseCPP_20131121.html">pvDatabaseCPP_20131121.html</a>
</dd> </dd>
<dt>Previous version:</dt> <dt>Previous version:</dt>
<dd><a <dd><a
href= "pvDatabaseCPP_20131120.html">pvDatabaseCPP20131120.html</a> href= "pvDatabaseCPP_20131120.html">pvDatabaseCPP_20131120.html</a>
</dd> </dd>
<dt>Editors:</dt> <dt>Editors:</dt>
<dd>Marty Kraimer, BNL</dd> <dd>Marty Kraimer, BNL</dd>

View File

@@ -46,11 +46,11 @@
</dd> </dd>
<dt>This version:</dt> <dt>This version:</dt>
<dd><a <dd><a
href= "pvDatabaseCPP_20140207.html">pvDatabaseCPP20140207.html</a> href= "pvDatabaseCPP_20140207.html">pvDatabaseCPP_20140207.html</a>
</dd> </dd>
<dt>Previous version:</dt> <dt>Previous version:</dt>
<dd><a <dd><a
href= "pvDatabaseCPP_20131121.html">pvDatabaseCPP20131121.html</a> href= "pvDatabaseCPP_20131121.html">pvDatabaseCPP_20131121.html</a>
</dd> </dd>
<dt>Editors:</dt> <dt>Editors:</dt>
<dd>Marty Kraimer, BNL</dd> <dd>Marty Kraimer, BNL</dd>

View File

@@ -46,11 +46,11 @@
</dd> </dd>
<dt>This version:</dt> <dt>This version:</dt>
<dd><a <dd><a
href= "pvDatabaseCPP_20140219.html">pvDatabaseCPP20140219.html</a> href= "pvDatabaseCPP_20140219.html">pvDatabaseCPP_20140219.html</a>
</dd> </dd>
<dt>Previous version:</dt> <dt>Previous version:</dt>
<dd><a <dd><a
href= "pvDatabaseCPP_20140207.html">pvDatabaseCPP20140207.html</a> href= "pvDatabaseCPP_20140207.html">pvDatabaseCPP_20140207.html</a>
</dd> </dd>
<dt>Editors:</dt> <dt>Editors:</dt>
<dd>Marty Kraimer, BNL</dd> <dd>Marty Kraimer, BNL</dd>

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -23,6 +23,5 @@ CHECK_RELEASE = WARN
INSTALL_INCLUDE = $(INSTALL_LOCATION)/include/pv INSTALL_INCLUDE = $(INSTALL_LOCATION)/include/pv
USR_INCLUDES += -I $(INSTALL_LOCATION)/include USR_INCLUDES += -I $(INSTALL_LOCATION)/include
-include $(TOP)/../configure/CONFIG_SITE.local
-include $(TOP)/../../CONFIG_SITE.local -include $(TOP)/../../CONFIG_SITE.local
-include $(TOP)/../CONFIG.local -include $(TOP)/../configure/CONFIG_SITE.local

View File

@@ -17,6 +17,7 @@ DB += dbString.db
DB += dbStringArray.db DB += dbStringArray.db
DB += dbEnum.db DB += dbEnum.db
DB += dbCounter.db DB += dbCounter.db
DB += dbDouble.db
#---------------------------------------------------- #----------------------------------------------------
# If <anyname>.db template is not named <anyname>*.template add # If <anyname>.db template is not named <anyname>*.template add

View File

@@ -0,0 +1,3 @@
record(ao, "$(name)")
{
}

View File

@@ -7,15 +7,17 @@ dbLoadDatabase("dbd/exampleDatabase.dbd")
exampleDatabase_registerRecordDeviceDriver(pdbbase) exampleDatabase_registerRecordDeviceDriver(pdbbase)
## Load record instances ## Load record instances
dbLoadRecords("db/dbScalar.db","name=double00,type=ao") dbLoadRecords("db/dbDouble.db","name=double00")
dbLoadRecords("db/dbScalar.db","name=double01,type=ao") dbLoadRecords("db/dbDouble.db","name=double01")
dbLoadRecords("db/dbScalar.db","name=double02,type=ao") dbLoadRecords("db/dbDouble.db","name=double02")
dbLoadRecords("db/dbScalar.db","name=double03,type=ao") dbLoadRecords("db/dbDouble.db","name=double03")
dbLoadRecords("db/dbScalar.db","name=double04,type=ao") dbLoadRecords("db/dbDouble.db","name=double04")
dbLoadRecords("db/dbScalar.db","name=double05,type=ao") dbLoadRecords("db/dbDouble.db","name=double05")
dbLoadRecords("db/dbStringArray.db","name=stringArray01") dbLoadRecords("db/dbStringArray.db","name=stringArray01")
dbLoadRecords("db/dbEnum.db","name=enum01") dbLoadRecords("db/dbEnum.db","name=enum01")
dbLoadRecords("db/dbCounter.db","name=counter01"); dbLoadRecords("db/dbCounter.db","name=counter01");
dbLoadRecords("db/dbArray.db","name=doubleArray,type=DOUBLE");
cd ${TOP}/iocBoot/${IOC} cd ${TOP}/iocBoot/${IOC}
iocInit() iocInit()

View File

@@ -14,6 +14,7 @@ exampleDatabase_SRCS += exampleDatabase.cpp
exampleDatabase_SRCS += exampleMonitorPlugin.cpp exampleDatabase_SRCS += exampleMonitorPlugin.cpp
exampleDatabase_SRCS += exampleDatabaseRegister.cpp exampleDatabase_SRCS += exampleDatabaseRegister.cpp
exampleDatabase_SRCS += exampleMonitorPluginRegister.cpp exampleDatabase_SRCS += exampleMonitorPluginRegister.cpp
exampleDatabase_LIBS += powerSupply
exampleDatabase_LIBS += pvDatabase exampleDatabase_LIBS += pvDatabase
exampleDatabase_LIBS += pvAccess exampleDatabase_LIBS += pvAccess
exampleDatabase_LIBS += pvData exampleDatabase_LIBS += pvData

View File

@@ -27,6 +27,8 @@
#include <pv/traceRecord.h> #include <pv/traceRecord.h>
#include <pv/powerSupply.h> #include <pv/powerSupply.h>
#define epicsExportSharedSymbols
#include <pv/exampleDatabase.h> #include <pv/exampleDatabase.h>
using namespace std; using namespace std;
@@ -147,17 +149,20 @@ void ExampleDatabase::create()
createVariantUnionArrayRecord(master,"exampleVariantUnionArray"); createVariantUnionArrayRecord(master,"exampleVariantUnionArray");
recordName = "examplePowerSupply"; recordName = "examplePowerSupply";
PVStructurePtr pvStructure = createPowerSupply(); PVStructurePtr pvStructure = createPowerSupply();
PowerSupplyPtr psr = PowerSupplyPtr psr = PowerSupply::create(recordName,pvStructure);
PowerSupply::create(recordName,pvStructure); if(!psr) {
if(psr.get()==NULL) { cout << "PowerSupply::create failed" << endl;
cout << "PowerSupply::create failed" << endl; } else {
return; result = master->addRecord(psr);
if(!result) cout<< "record " << recordName << " not added" << endl;
} }
result = master->addRecord(psr);
if(!result) cout<< "record " << recordName << " not added" << endl;
recordName = "laptoprecordListPGRPC"; recordName = "laptoprecordListPGRPC";
pvRecord = RecordListRecord::create(recordName); pvRecord = RecordListRecord::create(recordName);
result = master->addRecord(pvRecord); if(!pvRecord) {
if(!result) cout<< "record " << recordName << " not added" << endl; cout << "RecordListRecord::create failed" << endl;
} else {
result = master->addRecord(pvRecord);
if(!result) cout<< "record " << recordName << " not added" << endl;
}
} }

View File

@@ -16,15 +16,15 @@
# undef epicsExportSharedSymbols # undef epicsExportSharedSymbols
#endif #endif
#include <shareLib.h>
#include <pv/pvDatabase.h> #include <pv/pvDatabase.h>
#ifdef exampledatabaseEpicsExportSharedSymbols #ifdef exampledatabaseEpicsExportSharedSymbols
# define epicsExportSharedSymbols # define epicsExportSharedSymbols
# undef exampledatabaseEpicsExportSharedSymbols # undef exampledatabaseEpicsExportSharedSymbols
# include <shareLib.h>
#endif #endif
#include <shareLib.h>
namespace epics { namespace pvDatabase { namespace epics { namespace pvDatabase {
class epicsShareClass ExampleDatabase{ class epicsShareClass ExampleDatabase{

View File

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

View File

@@ -11,6 +11,8 @@
#include <pv/convert.h> #include <pv/convert.h>
#include <pv/monitorPlugin.h> #include <pv/monitorPlugin.h>
#define epicsExportSharedSymbols
#include <pv/exampleMonitorPlugin.h> #include <pv/exampleMonitorPlugin.h>
using namespace epics::pvData; using namespace epics::pvData;
@@ -40,10 +42,10 @@ public:
{ {
pvField = getPVDataCreate()->createPVField(field); pvField = getPVDataCreate()->createPVField(field);
raiseMonitor = true; raiseMonitor = true;
if(pvFieldOptions!=NULL) { if(pvFieldOptions) {
PVStringPtr pvString = PVStringPtr pvString =
pvFieldOptions->getSubField<PVString>("raiseMonitor"); pvFieldOptions->getSubField<PVString>("raiseMonitor");
if(pvString!=NULL) { if(pvString) {
string value = pvString->get(); string value = pvString->get();
if(value.compare("false")==0) raiseMonitor = false; if(value.compare("false")==0) raiseMonitor = false;
} }
@@ -88,7 +90,7 @@ void ExampleMonitorPlugin::create()
static OnChangePluginCreatorPtr plugin; static OnChangePluginCreatorPtr plugin;
static Mutex mutex; static Mutex mutex;
Lock xx(mutex); Lock xx(mutex);
if(plugin==NULL) { if(!plugin) {
plugin = OnChangePluginCreatorPtr(new OnChangePluginCreator()); plugin = OnChangePluginCreatorPtr(new OnChangePluginCreator());
MonitorPluginManager::get()->addPlugin(pluginName,plugin); MonitorPluginManager::get()->addPlugin(pluginName,plugin);
} }

View File

@@ -11,11 +11,22 @@
#ifndef EXAMPLEMONITORPLUGIN_H #ifndef EXAMPLEMONITORPLUGIN_H
#define EXAMPLEMONITORPLUGIN_H #define EXAMPLEMONITORPLUGIN_H
#include <shareLib.h> #ifdef epicsExportSharedSymbols
# define examplemonitorPluginEpicsExportSharedSymbols
# undef epicsExportSharedSymbols
#endif
#include <pv/pvDatabase.h> #include <pv/pvDatabase.h>
#include <pv/monitorPlugin.h> #include <pv/monitorPlugin.h>
#ifdef examplemonitorPluginEpicsExportSharedSymbols
# define epicsExportSharedSymbols
# undef examplemonitorPluginEpicsExportSharedSymbols
#endif
#include <shareLib.h>
namespace epics { namespace pvDatabase { namespace epics { namespace pvDatabase {
class epicsShareClass ExampleMonitorPlugin{ class epicsShareClass ExampleMonitorPlugin{

View File

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

View File

@@ -35,5 +35,5 @@
INSTALL_INCLUDE = $(INSTALL_LOCATION)/include/pv INSTALL_INCLUDE = $(INSTALL_LOCATION)/include/pv
USR_INCLUDES += -I $(INSTALL_LOCATION)/include USR_INCLUDES += -I $(INSTALL_LOCATION)/include
-include $(TOP)/configure/CONFIG_SITE.local -include $(TOP)/../../CONFIG_SITE.local
-include $(TOP)/../CONFIG.local -include $(TOP)/../configure/CONFIG_SITE.local

View File

@@ -13,4 +13,4 @@ cd ${TOP}/iocBoot/${IOC}
iocInit() iocInit()
startPVAClient startPVAClient
startPVAServer startPVAServer
exampleLinkCreateRecord exampleLinkRemote pvAccess doubleArray exampleLinkCreateRecord exampleLink pvAccess doubleArray

View File

@@ -9,10 +9,12 @@
* @date 2013.08.02 * @date 2013.08.02
*/ */
#include <pv/exampleLink.h>
#include <pv/standardPVField.h> #include <pv/standardPVField.h>
#include <pv/convert.h> #include <pv/convert.h>
#define epicsExportSharedSymbols
#include <pv/exampleLink.h>
using namespace epics::pvData; using namespace epics::pvData;
using namespace epics::pvAccess; using namespace epics::pvAccess;
using std::tr1::static_pointer_cast; using std::tr1::static_pointer_cast;
@@ -63,12 +65,12 @@ bool ExampleLink::init()
pvAlarm.attach(pvStructure->getSubField("alarm")); pvAlarm.attach(pvStructure->getSubField("alarm"));
pvValue = static_pointer_cast<PVDoubleArray>( pvValue = static_pointer_cast<PVDoubleArray>(
pvStructure->getScalarArrayField("value",pvDouble)); pvStructure->getScalarArrayField("value",pvDouble));
if(pvValue==NULL) { if(!pvValue) {
return false; return false;
} }
ChannelProvider::shared_pointer provider = ChannelProvider::shared_pointer provider =
getChannelProviderRegistry()->getProvider(providerName); getChannelProviderRegistry()->getProvider(providerName);
if(provider==NULL) { if(!provider) {
cout << getRecordName() << " provider " cout << getRecordName() << " provider "
<< providerName << " does not exist" << endl; << providerName << " does not exist" << endl;
return false; return false;
@@ -95,7 +97,7 @@ bool ExampleLink::init()
} }
getPVValue = static_pointer_cast<PVDoubleArray>( getPVValue = static_pointer_cast<PVDoubleArray>(
getPVStructure->getScalarArrayField("value",pvDouble)); getPVStructure->getScalarArrayField("value",pvDouble));
if(getPVValue==NULL) { if(!getPVValue) {
cout << getRecordName() << " get value not PVDoubleArray" << endl; cout << getRecordName() << " get value not PVDoubleArray" << endl;
return false; return false;
} }
@@ -147,6 +149,7 @@ void ExampleLink::channelGetConnect(
{ {
this->status = status; this->status = status;
this->channelGet = channelGet; this->channelGet = channelGet;
getPVStructure = getPVDataCreate()->createPVStructure(structure);
event.signal(); event.signal();
} }
@@ -157,7 +160,7 @@ void ExampleLink::getDone(
BitSetPtr const & bitSet) BitSetPtr const & bitSet)
{ {
this->status = status; this->status = status;
getPVStructure = pvStructure; convert->copyStructure(pvStructure,getPVStructure);
this->bitSet = bitSet; this->bitSet = bitSet;
event.signal(); event.signal();
} }

View File

@@ -11,7 +11,10 @@
#ifndef EXAMPLEPVADOUBLEARRAYGET_H #ifndef EXAMPLEPVADOUBLEARRAYGET_H
#define EXAMPLEPVADOUBLEARRAYGET_H #define EXAMPLEPVADOUBLEARRAYGET_H
#include <shareLib.h> #ifdef epicsExportSharedSymbols
# define exampleLinkEpicsExportSharedSymbols
# undef epicsExportSharedSymbols
#endif
#include <pv/timeStamp.h> #include <pv/timeStamp.h>
#include <pv/pvTimeStamp.h> #include <pv/pvTimeStamp.h>
@@ -22,6 +25,13 @@
#include <pv/pvAccess.h> #include <pv/pvAccess.h>
#include <pv/serverContext.h> #include <pv/serverContext.h>
#ifdef exampleLinkEpicsExportSharedSymbols
# define epicsExportSharedSymbols
# undef exampleLinkEpicsExportSharedSymbols
#endif
#include <shareLib.h>
namespace epics { namespace pvDatabase { namespace epics { namespace pvDatabase {

View File

@@ -27,14 +27,14 @@
#include <epicsThread.h> #include <epicsThread.h>
#include <iocsh.h> #include <iocsh.h>
#include <epicsExport.h>
#include <pv/pvIntrospect.h> #include <pv/pvIntrospect.h>
#include <pv/pvData.h> #include <pv/pvData.h>
#include <pv/standardField.h> #include <pv/standardField.h>
#include <pv/standardPVField.h> #include <pv/standardPVField.h>
#include <pv/pvAccess.h> #include <pv/pvAccess.h>
#include <pv/pvDatabase.h> #include <pv/pvDatabase.h>
#include <epicsExport.h>
#include <pv/exampleLink.h> #include <pv/exampleLink.h>
using namespace epics::pvData; using namespace epics::pvData;
@@ -70,8 +70,8 @@ static void exampleLinkCallFunc(const iocshArgBuf *args)
char *providerName = args[1].sval; char *providerName = args[1].sval;
char *channelName = args[2].sval; char *channelName = args[2].sval;
ExampleLinkPtr record = ExampleLink::create(recordName,providerName,channelName); ExampleLinkPtr record = ExampleLink::create(recordName,providerName,channelName);
if(record!=NULL) if(record)
result = master->addRecord(record); result = master->addRecord(record);
if(!result) cout << "recordname" << " not added" << endl; if(!result) cout << "recordname" << " not added" << endl;
} }

View File

@@ -35,5 +35,5 @@
INSTALL_INCLUDE = $(INSTALL_LOCATION)/include/pv INSTALL_INCLUDE = $(INSTALL_LOCATION)/include/pv
USR_INCLUDES += -I $(INSTALL_LOCATION)/include USR_INCLUDES += -I $(INSTALL_LOCATION)/include
-include $(TOP)/configure/CONFIG_SITE.local -include $(TOP)/../../CONFIG_SITE.local
-include $(TOP)/../CONFIG.local -include $(TOP)/../configure/CONFIG_SITE.local

View File

@@ -20,6 +20,7 @@
#include <pv/standardField.h> #include <pv/standardField.h>
#include <pv/standardPVField.h> #include <pv/standardPVField.h>
#include <pv/recordList.h>
#include <pv/powerSupply.h> #include <pv/powerSupply.h>
#include <pv/traceRecord.h> #include <pv/traceRecord.h>
#include <pv/channelProviderLocal.h> #include <pv/channelProviderLocal.h>
@@ -48,7 +49,10 @@ int main(int argc,char *argv[])
pvRecord = TraceRecord::create(recordName); pvRecord = TraceRecord::create(recordName);
result = master->addRecord(pvRecord); result = master->addRecord(pvRecord);
if(!result) cout<< "record " << recordName << " not added" << endl; if(!result) cout<< "record " << recordName << " not added" << endl;
pvRecord.reset(); recordName = "laptoprecordListPGRPC";
pvRecord = RecordListRecord::create(recordName);
result = master->addRecord(pvRecord);
if(!result) cout<< "record " << recordName << " not added" << endl;
ServerContext::shared_pointer pvaServer = ServerContext::shared_pointer pvaServer =
startPVAServer(PVACCESS_ALL_PROVIDERS,0,true,true); startPVAServer(PVACCESS_ALL_PROVIDERS,0,true,true);
cout << "powerSupply\n"; cout << "powerSupply\n";

View File

@@ -35,5 +35,5 @@
INSTALL_INCLUDE = $(INSTALL_LOCATION)/include/pv INSTALL_INCLUDE = $(INSTALL_LOCATION)/include/pv
USR_INCLUDES += -I $(INSTALL_LOCATION)/include USR_INCLUDES += -I $(INSTALL_LOCATION)/include
-include $(TOP)/configure/CONFIG_SITE.local -include $(TOP)/../../CONFIG_SITE.local
-include $(TOP)/../CONFIG.local -include $(TOP)/../configure/CONFIG_SITE.local

View File

@@ -1,4 +1,5 @@
include "base.dbd" include "base.dbd"
include "PVAClientRegister.dbd"
include "PVAServerRegister.dbd" include "PVAServerRegister.dbd"
include "registerChannelProviderLocal.dbd" include "registerChannelProviderLocal.dbd"
include "dbPv.dbd" include "dbPv.dbd"

View File

@@ -9,7 +9,9 @@
* @date 2013.04.02 * @date 2013.04.02
*/ */
#include <pv/standardPVField.h> #include <pv/standardField.h>
#define epicsExportSharedSymbols
#include <pv/exampleServer.h> #include <pv/exampleServer.h>
using namespace epics::pvData; using namespace epics::pvData;
@@ -23,19 +25,20 @@ namespace epics { namespace exampleServer {
ExampleServerPtr ExampleServer::create( ExampleServerPtr ExampleServer::create(
string const & recordName) string const & recordName)
{ {
StandardPVFieldPtr standardPVField = getStandardPVField(); StandardFieldPtr standardField = getStandardField();
FieldCreatePtr fieldCreate = getFieldCreate();
PVDataCreatePtr pvDataCreate = getPVDataCreate(); PVDataCreatePtr pvDataCreate = getPVDataCreate();
PVStructurePtr pvArgument = standardPVField->scalar(pvString,""); StructureConstPtr topStructure = fieldCreate->createFieldBuilder()->
PVStructurePtr pvResult = standardPVField->scalar(pvString,"timeStamp"); addNestedStructure("argument")->
StringArray names; add("value",pvString)->
names.reserve(2); endNested()->
PVFieldPtrArray fields; addNestedStructure("result") ->
fields.reserve(2); add("value",pvString) ->
names.push_back("argument"); add("timeStamp",standardField->timeStamp()) ->
fields.push_back(pvArgument); endNested()->
names.push_back("result"); createStructure();
fields.push_back(pvResult); PVStructurePtr pvStructure = pvDataCreate->createPVStructure(topStructure);
PVStructurePtr pvStructure = pvDataCreate->createPVStructure(names,fields);
ExampleServerPtr pvRecord( ExampleServerPtr pvRecord(
new ExampleServer(recordName,pvStructure)); new ExampleServer(recordName,pvStructure));
if(!pvRecord->init()) pvRecord.reset(); if(!pvRecord->init()) pvRecord.reset();

View File

@@ -11,12 +11,23 @@
#ifndef EXAMPLECOUNTER_H #ifndef EXAMPLECOUNTER_H
#define EXAMPLECOUNTER_H #define EXAMPLECOUNTER_H
#include <shareLib.h> #ifdef epicsExportSharedSymbols
# define exampleServerEpicsExportSharedSymbols
# undef epicsExportSharedSymbols
#endif
#include <pv/pvDatabase.h> #include <pv/pvDatabase.h>
#include <pv/timeStamp.h> #include <pv/timeStamp.h>
#include <pv/pvTimeStamp.h> #include <pv/pvTimeStamp.h>
#ifdef exampleServerEpicsExportSharedSymbols
# define epicsExportSharedSymbols
# undef exampleServerEpicsExportSharedSymbols
#endif
#include <shareLib.h>
namespace epics { namespace exampleServer { namespace epics { namespace exampleServer {

View File

@@ -22,6 +22,7 @@
#include <pv/standardPVField.h> #include <pv/standardPVField.h>
#include <pv/exampleServer.h> #include <pv/exampleServer.h>
#include <pv/traceRecord.h> #include <pv/traceRecord.h>
#include <pv/recordList.h>
#include <pv/channelProviderLocal.h> #include <pv/channelProviderLocal.h>
#include <pv/serverContext.h> #include <pv/serverContext.h>
@@ -42,15 +43,20 @@ int main(int argc,char *argv[])
recordName = "exampleServer"; recordName = "exampleServer";
pvRecord = ExampleServer::create(recordName); pvRecord = ExampleServer::create(recordName);
result = master->addRecord(pvRecord); result = master->addRecord(pvRecord);
cout << "result of addRecord " << recordName << " " << result << endl; if(!result) cout<< "record " << recordName << " not added" << endl;
recordName = "traceRecordPGRPC"; recordName = "traceRecordPGRPC";
pvRecord = TraceRecord::create(recordName); pvRecord = TraceRecord::create(recordName);
result = master->addRecord(pvRecord); result = master->addRecord(pvRecord);
if(!result) cout<< "record " << recordName << " not added" << endl; if(!result) cout<< "record " << recordName << " not added" << endl;
pvRecord.reset(); recordName = "laptoprecordListPGRPC";
pvRecord = RecordListRecord::create(recordName);
result = master->addRecord(pvRecord);
if(!result) cout<< "record " << recordName << " not added" << endl;
ServerContext::shared_pointer pvaServer = ServerContext::shared_pointer pvaServer =
startPVAServer(PVACCESS_ALL_PROVIDERS,0,true,true); startPVAServer(PVACCESS_ALL_PROVIDERS,0,true,true);
cout << "exampleServer\n"; PVStringArrayPtr pvNames = master->getRecordNames();
shared_vector<const string> names = pvNames->view();
for(size_t i=0; i<names.size(); ++i) cout << names[i] << endl;
string str; string str;
while(true) { while(true) {
cout << "Type exit to stop: \n"; cout << "Type exit to stop: \n";

View File

@@ -27,12 +27,13 @@
#include <epicsThread.h> #include <epicsThread.h>
#include <iocsh.h> #include <iocsh.h>
#include <epicsExport.h>
#include <pv/pvIntrospect.h> #include <pv/pvIntrospect.h>
#include <pv/pvData.h> #include <pv/pvData.h>
#include <pv/pvAccess.h> #include <pv/pvAccess.h>
#include <pv/pvDatabase.h> #include <pv/pvDatabase.h>
#include <pv/recordList.h>
#include <epicsExport.h>
#include <pv/exampleServer.h> #include <pv/exampleServer.h>
using namespace epics::pvData; using namespace epics::pvData;
@@ -50,10 +51,19 @@ static const iocshFuncDef exampleServerFuncDef = {
"exampleServerCreateRecord", 1, testArgs}; "exampleServerCreateRecord", 1, testArgs};
static void exampleServerCallFunc(const iocshArgBuf *args) static void exampleServerCallFunc(const iocshArgBuf *args)
{ {
PVDatabasePtr master = PVDatabase::getMaster();
char *recordName = args[0].sval; char *recordName = args[0].sval;
ExampleServerPtr record = ExampleServer::create(recordName); ExampleServerPtr record = ExampleServer::create(recordName);
bool result = PVDatabase::getMaster()->addRecord(record); bool result = master->addRecord(record);
if(!result) cout << "recordname" << " not added" << endl; if(!result) cout << "recordname" << " not added" << endl;
PVRecordPtr pvRecord = RecordListRecord::create(
"laptoprecordListPGRPC");
if(!pvRecord) {
cout << "RecordListRecord::create failed" << endl;
} else {
result = master->addRecord(pvRecord);
if(!result) cout<< "record " << recordName << " not added" << endl;
}
} }
static void exampleServerRegister(void) static void exampleServerRegister(void)

View File

@@ -52,3 +52,73 @@ test/src/powerSupplyRegister.cpp
test/src/testExampleRecord.cpp test/src/testExampleRecord.cpp
test/src/testPVCopy.cpp test/src/testPVCopy.cpp
test/src/testPVRecord.cpp test/src/testPVRecord.cpp
arrayPerformance/include/pv/arrayPerformance.h
arrayPerformance/include/pv/longArrayGet.h
arrayPerformance/include/pv/longArrayMonitor.h
arrayPerformance/include/pv/longArrayPut.h
arrayPerformance/src/arrayPerformance.cpp
arrayPerformance/src/arrayPerformance.h
arrayPerformance/src/arrayPerformanceMain.cpp
arrayPerformance/src/longArrayGet.cpp
arrayPerformance/src/longArrayGet.h
arrayPerformance/src/longArrayGetMain.cpp
arrayPerformance/src/longArrayMonitor.cpp
arrayPerformance/src/longArrayMonitor.h
arrayPerformance/src/longArrayMonitorMain.cpp
arrayPerformance/src/longArrayPut.cpp
arrayPerformance/src/longArrayPut.h
arrayPerformance/src/longArrayPutMain.cpp
arrayPerformance/src/vectorPerformanceMain.cpp
exampleDatabase/include/pv/exampleDatabase.h
exampleDatabase/include/pv/exampleMonitorPlugin.h
exampleDatabase/ioc/src/O.darwin-x86/exampleDatabase_registerRecordDeviceDriver.cpp
exampleDatabase/ioc/src/exampleDatabaseMain.cpp
exampleDatabase/src/exampleDatabase.cpp
exampleDatabase/src/exampleDatabase.h
exampleDatabase/src/exampleDatabaseMain.cpp
exampleDatabase/src/exampleDatabaseRegister.cpp
exampleDatabase/src/exampleMonitorPlugin.cpp
exampleDatabase/src/exampleMonitorPlugin.h
exampleDatabase/src/exampleMonitorPluginRegister.cpp
exampleLink/include/pv/exampleLink.h
exampleLink/ioc/src/O.darwin-x86/exampleLink_registerRecordDeviceDriver.cpp
exampleLink/ioc/src/exampleLinkMain.cpp
exampleLink/src/exampleLink.cpp
exampleLink/src/exampleLink.h
exampleLink/src/exampleLinkRegister.cpp
examplePowerSupply/ioc/src/O.darwin-x86/powerSupply_registerRecordDeviceDriver.cpp
examplePowerSupply/ioc/src/powerSupplyMain.cpp
examplePowerSupply/src/powerSupplyMain.cpp
exampleServer/include/pv/exampleServer.h
exampleServer/ioc/src/O.darwin-x86/exampleServer_registerRecordDeviceDriver.cpp
exampleServer/ioc/src/exampleServerMain.cpp
exampleServer/src/exampleServer.cpp
exampleServer/src/exampleServer.h
exampleServer/src/exampleServerMain.cpp
exampleServer/src/exampleServerRegister.cpp
include/pv/channelProviderLocal.h
include/pv/pvCopyMonitor.h
include/pv/pvDatabase.h
include/pv/recordList.h
include/pv/traceRecord.h
src/database/pvDatabase.cpp
src/database/pvDatabase.h
src/database/pvRecord.cpp
src/pvAccess/channelLocal.cpp
src/pvAccess/channelProviderLocal.cpp
src/pvAccess/channelProviderLocal.h
src/pvAccess/monitorFactory.cpp
src/pvAccess/pvCopyMonitor.cpp
src/pvAccess/pvCopyMonitor.h
src/pvAccess/registerChannelProviderLocal.cpp
src/special/recordList.cpp
src/special/recordList.h
src/special/traceRecord.cpp
src/special/traceRecord.h
test/include/pv/powerSupply.h
test/src/powerSupply.cpp
test/src/powerSupply.h
test/src/powerSupplyRegister.cpp
test/src/testExampleRecord.cpp
test/src/testPVCopy.cpp
test/src/testPVRecord.cpp

View File

@@ -27,9 +27,10 @@
#ifdef pvdatabaseEpicsExportSharedSymbols #ifdef pvdatabaseEpicsExportSharedSymbols
# define epicsExportSharedSymbols # define epicsExportSharedSymbols
# undef pvdatabaseEpicsExportSharedSymbols # undef pvdatabaseEpicsExportSharedSymbols
# include <shareLib.h>
#endif #endif
#include <shareLib.h>
namespace epics { namespace pvDatabase { namespace epics { namespace pvDatabase {

View File

@@ -371,7 +371,7 @@ void PVRecordField::init()
{ {
fullFieldName = pvField->getFieldName(); fullFieldName = pvField->getFieldName();
PVRecordStructurePtr pvParent = parent; PVRecordStructurePtr pvParent = parent;
while(pvParent.get()!= NULL) { while(pvParent) {
string parentName = pvParent->getPVField()->getFieldName(); string parentName = pvParent->getPVField()->getFieldName();
if(parentName.size()>0) { if(parentName.size()>0) {
fullFieldName = pvParent->getPVField()->getFieldName() fullFieldName = pvParent->getPVField()->getFieldName()
@@ -434,7 +434,7 @@ void PVRecordField::removeListener(PVListenerPtr const & pvListener)
void PVRecordField::postPut() void PVRecordField::postPut()
{ {
if(parent!=NULL) { if(parent) {
parent->postParent(getPtrSelf()); parent->postParent(getPtrSelf());
} }
postSubField(); postSubField();
@@ -448,7 +448,7 @@ void PVRecordField::postParent(PVRecordFieldPtr const & subField)
{ {
(*iter)->dataPut(pvrs,subField); (*iter)->dataPut(pvrs,subField);
} }
if(parent!=NULL) parent->postParent(subField); if(parent) parent->postParent(subField);
} }
void PVRecordField::postSubField() void PVRecordField::postSubField()

View File

@@ -70,7 +70,7 @@ typedef std::tr1::shared_ptr<ChannelArrayLocal> ChannelArrayLocalPtr;
static bool getProcess(PVStructurePtr pvRequest,bool processDefault) static bool getProcess(PVStructurePtr pvRequest,bool processDefault)
{ {
PVFieldPtr pvField = pvRequest->getSubField("record._options.process"); PVFieldPtr pvField = pvRequest->getSubField("record._options.process");
if(pvField==NULL || pvField->getField()->getType()!=scalar) { if(!pvField || pvField->getField()->getType()!=scalar) {
return processDefault; return processDefault;
} }
ScalarConstPtr scalar = static_pointer_cast<const Scalar>( ScalarConstPtr scalar = static_pointer_cast<const Scalar>(
@@ -146,13 +146,13 @@ ChannelProcessLocalPtr ChannelProcessLocal::create(
PVFieldPtr pvField; PVFieldPtr pvField;
PVStructurePtr pvOptions; PVStructurePtr pvOptions;
int nProcess = 1; int nProcess = 1;
if(pvRequest!=NULL) pvField = pvRequest->getSubField("record._options"); if(pvRequest) pvField = pvRequest->getSubField("record._options");
if(pvField.get()!=NULL) { if(pvField) {
pvOptions = static_pointer_cast<PVStructure>(pvField); pvOptions = static_pointer_cast<PVStructure>(pvField);
pvField = pvOptions->getSubField("nProcess"); pvField = pvOptions->getSubField("nProcess");
if(pvField.get()!=NULL) { if(pvField) {
PVStringPtr pvString = pvOptions->getStringField("nProcess"); PVStringPtr pvString = pvOptions->getStringField("nProcess");
if(pvString.get()!=NULL) { if(pvString) {
int size; int size;
std::stringstream ss; std::stringstream ss;
ss << pvString->get(); ss << pvString->get();
@@ -291,7 +291,7 @@ ChannelGetLocalPtr ChannelGetLocal::create(
pvRecord->getPVRecordStructure()->getPVStructure(), pvRecord->getPVRecordStructure()->getPVStructure(),
pvRequest, pvRequest,
""); "");
if(pvCopy==NULL) { if(!pvCopy) {
Status status( Status status(
Status::STATUSTYPE_ERROR, Status::STATUSTYPE_ERROR,
"invalid pvRequest"); "invalid pvRequest");
@@ -442,7 +442,7 @@ ChannelPutLocalPtr ChannelPutLocal::create(
pvRecord->getPVRecordStructure()->getPVStructure(), pvRecord->getPVRecordStructure()->getPVStructure(),
pvRequest, pvRequest,
""); "");
if(pvCopy==NULL) { if(!pvCopy) {
Status status( Status status(
Status::STATUSTYPE_ERROR, Status::STATUSTYPE_ERROR,
"invalid pvRequest"); "invalid pvRequest");
@@ -624,7 +624,7 @@ ChannelPutGetLocalPtr ChannelPutGetLocal::create(
pvRecord->getPVRecordStructure()->getPVStructure(), pvRecord->getPVRecordStructure()->getPVStructure(),
pvRequest, pvRequest,
"getField"); "getField");
if(pvPutCopy==NULL || pvGetCopy==NULL) { if(!pvPutCopy || !pvGetCopy) {
Status status( Status status(
Status::STATUSTYPE_ERROR, Status::STATUSTYPE_ERROR,
"invalid pvRequest"); "invalid pvRequest");
@@ -777,7 +777,7 @@ public:
PVArrayPtr const &putArray, PVArrayPtr const &putArray,
size_t offset, size_t count, size_t stride); size_t offset, size_t count, size_t stride);
virtual void getLength(); virtual void getLength();
virtual void setLength(size_t length, size_t capacity); virtual void setLength(size_t length);
virtual void destroy(); virtual void destroy();
virtual std::tr1::shared_ptr<Channel> getChannel() virtual std::tr1::shared_ptr<Channel> getChannel()
{return channelLocal;} {return channelLocal;}
@@ -841,8 +841,12 @@ ChannelArrayLocalPtr ChannelArrayLocal::create(
if(pvfs.size()!=1) break; if(pvfs.size()!=1) break;
pvField = pvfs[0]; pvField = pvfs[0];
} }
size_t indfield = fieldName.find_first_of("field.");
if(indfield==0) {
fieldName = fieldName.substr(6);
}
pvField = pvRecord->getPVRecordStructure()->getPVStructure()->getSubField(fieldName); pvField = pvRecord->getPVRecordStructure()->getPVStructure()->getSubField(fieldName);
if(pvField==NULL) { if(!pvField) {
Status status( Status status(
Status::STATUSTYPE_ERROR,fieldName +" not found"); Status::STATUSTYPE_ERROR,fieldName +" not found");
ChannelArrayLocalPtr channelArray; ChannelArrayLocalPtr channelArray;
@@ -1021,7 +1025,7 @@ void ChannelArrayLocal::putArray(
return; return;
} }
size_t newLength = offset + count*stride; size_t newLength = offset + count*stride;
pvArray->setLength(newLength); if(newLength<pvArray->getLength()) pvArray->setLength(newLength);
const char *exceptionMessage = NULL; const char *exceptionMessage = NULL;
pvRecord->lock(); pvRecord->lock();
try { try {
@@ -1040,12 +1044,10 @@ void ChannelArrayLocal::putArray(
void ChannelArrayLocal::getLength() void ChannelArrayLocal::getLength()
{ {
size_t length = 0; size_t length = 0;
size_t capacity = 0;
const char *exceptionMessage = NULL; const char *exceptionMessage = NULL;
pvRecord->lock(); pvRecord->lock();
try { try {
length = pvArray->getLength(); length = pvArray->getLength();
capacity = pvArray->getCapacity();
} catch(std::exception e) { } catch(std::exception e) {
exceptionMessage = e.what(); exceptionMessage = e.what();
} }
@@ -1054,10 +1056,10 @@ void ChannelArrayLocal::getLength()
if(exceptionMessage!=NULL) { if(exceptionMessage!=NULL) {
status = Status(Status::STATUSTYPE_ERROR,exceptionMessage); status = Status(Status::STATUSTYPE_ERROR,exceptionMessage);
} }
channelArrayRequester->getLengthDone(status,getPtrSelf(),length,capacity); channelArrayRequester->getLengthDone(status,getPtrSelf(),length);
} }
void ChannelArrayLocal::setLength(size_t length, size_t capacity) void ChannelArrayLocal::setLength(size_t length)
{ {
if(isDestroyed) { if(isDestroyed) {
channelArrayRequester->setLengthDone(channelDestroyedStatus,getPtrSelf()); channelArrayRequester->setLengthDone(channelDestroyedStatus,getPtrSelf());
@@ -1069,17 +1071,6 @@ void ChannelArrayLocal::setLength(size_t length, size_t capacity)
} }
pvRecord->lock(); pvRecord->lock();
try { try {
if(capacity>=0 && !pvArray->isCapacityMutable()) {
Status status(
Status::STATUSTYPE_ERROR,
"capacityImnutable");
channelArrayRequester->setLengthDone(status,getPtrSelf());
pvRecord->unlock();
return;
}
if(capacity>=0) {
if(pvArray->getCapacity()!=capacity) pvArray->setCapacity(capacity);
}
if(length>=0) { if(length>=0) {
if(pvArray->getLength()!=length) pvArray->setLength(length); if(pvArray->getLength()!=length) pvArray->setLength(length);
} }
@@ -1199,7 +1190,7 @@ void ChannelLocal::getField(GetFieldRequester::shared_pointer const &requester,
} }
PVFieldPtr pvField = PVFieldPtr pvField =
pvRecord->getPVRecordStructure()->getPVStructure()->getSubField(subField); pvRecord->getPVRecordStructure()->getPVStructure()->getSubField(subField);
if(pvField.get()!=NULL) { if(pvField) {
requester->getDone(Status::Ok,pvField->getField()); requester->getDone(Status::Ok,pvField->getField());
return; return;
} }
@@ -1308,7 +1299,7 @@ void ChannelLocal::printInfo()
void ChannelLocal::printInfo(std::ostream& out) void ChannelLocal::printInfo(std::ostream& out)
{ {
out << "ChannelLocal provides access to service"; out << "ChannelLocal provides access to a record in the local PVDatabase";
} }
}} }}

View File

@@ -71,8 +71,10 @@ ChannelProviderLocalPtr getChannelProviderLocal()
if(channelProviderLocal.get()==NULL) { if(channelProviderLocal.get()==NULL) {
channelProviderLocal = ChannelProviderLocalPtr( channelProviderLocal = ChannelProviderLocalPtr(
new ChannelProviderLocal()); new ChannelProviderLocal());
ChannelProvider::shared_pointer xxx = dynamic_pointer_cast<ChannelProvider>(channelProviderLocal); ChannelProvider::shared_pointer xxx =
channelProviderLocal->channelFinder = SyncChannelFind::shared_pointer(new SyncChannelFind(xxx)); dynamic_pointer_cast<ChannelProvider>(channelProviderLocal);
channelProviderLocal->channelFinder =
SyncChannelFind::shared_pointer(new SyncChannelFind(xxx));
LocalChannelProviderFactory::create(channelProviderLocal); LocalChannelProviderFactory::create(channelProviderLocal);
} }
return channelProviderLocal; return channelProviderLocal;

View File

@@ -22,8 +22,6 @@
#include <memory> #include <memory>
#include <set> #include <set>
#include <shareLib.h>
#include <pv/lock.h> #include <pv/lock.h>
#include <pv/pvType.h> #include <pv/pvType.h>
#include <pv/pvData.h> #include <pv/pvData.h>
@@ -37,6 +35,8 @@
# undef channelProviderLocalEpicsExportSharedSymbols # undef channelProviderLocalEpicsExportSharedSymbols
#endif #endif
#include <shareLib.h>
#include <pv/pvDatabase.h> #include <pv/pvDatabase.h>
@@ -57,12 +57,32 @@ typedef std::tr1::shared_ptr<ChannelLocal> ChannelLocalPtr;
epicsShareExtern MonitorFactoryPtr getMonitorFactory(); epicsShareExtern MonitorFactoryPtr getMonitorFactory();
/** MonitorFactory
* This class provides a static method to create a monitor for a PVRecord
*/
class epicsShareClass MonitorFactory class epicsShareClass MonitorFactory
{ {
public: public:
POINTER_DEFINITIONS(MonitorFactory); POINTER_DEFINITIONS(MonitorFactory);
/**
* Destructor
*/
virtual ~MonitorFactory(); virtual ~MonitorFactory();
/**
* Destroy the monitor factory.
*/
virtual void destroy(); virtual void destroy();
/**
* Create a monitor on a record.
* This is called by the local channel provider.
* @param pvRecord The record to monitor.
* @param monitorRequester The client callback.
* @param pvRequest Options specified by the client.
* This includes the subset of the fields in the record to monitor.
* @return A shared pointer to the newly created monitor.
* If the monitor can not be created a null monitor is returned.
* This means the pvRequest specified options that could not be satisfied.
*/
epics::pvData::MonitorPtr createMonitor( epics::pvData::MonitorPtr createMonitor(
PVRecordPtr const & pvRecord, PVRecordPtr const & pvRecord,
epics::pvData::MonitorRequester::shared_pointer const & monitorRequester, epics::pvData::MonitorRequester::shared_pointer const & monitorRequester,
@@ -78,24 +98,79 @@ private:
epicsShareExtern ChannelProviderLocalPtr getChannelProviderLocal(); epicsShareExtern ChannelProviderLocalPtr getChannelProviderLocal();
/**
* An implementation of channelProvider that provides access to records in PVDatabase.
*/
class epicsShareClass ChannelProviderLocal : class epicsShareClass ChannelProviderLocal :
public epics::pvAccess::ChannelProvider, public epics::pvAccess::ChannelProvider,
public std::tr1::enable_shared_from_this<ChannelProviderLocal> public std::tr1::enable_shared_from_this<ChannelProviderLocal>
{ {
public: public:
POINTER_DEFINITIONS(ChannelProviderLocal); POINTER_DEFINITIONS(ChannelProviderLocal);
/**
* Destructor
*/
virtual ~ChannelProviderLocal(); virtual ~ChannelProviderLocal();
/**
* Destroy the channel provider.
* Probably never called.
*/
virtual void destroy(); virtual void destroy();
/**
* Returns the channel provider name.
* @return <b>local</b>
*/
virtual std::string getProviderName(); virtual std::string getProviderName();
/**
* Returns either a null channelFind or a channelFind for records in the PVDatabase.
* @param channelName The name of the channel desired.
* @param channelFindRequester The client callback.
* @return shared pointer to ChannelFind.
* This is null if the channelName is not the name of a record in the PVDatabase.
* It is an implementation of SyncChannelFind if the channelName is the name
* of a record in the PVDatabase.
* The interface for SyncChannelFind is defined by pvAccessCPP.
* The channelFindResult method of channelFindRequester is called before the
* method returns.
*/
virtual epics::pvAccess::ChannelFind::shared_pointer channelFind( virtual epics::pvAccess::ChannelFind::shared_pointer channelFind(
std::string const &channelName, std::string const &channelName,
epics::pvAccess::ChannelFindRequester::shared_pointer const & channelFindRequester); epics::pvAccess::ChannelFindRequester::shared_pointer const & channelFindRequester);
/**
* Calls method channelListRequester::channelListResult which provides the
* caller with a list of the record names on the PVDatabase.
* A record name is the same as a channel name.
* @param channelListRequester The client callback.
* @return shared pointer to ChannelFind.
* The interface for SyncChannelFind is defined by pvAccessCPP.
*/
virtual epics::pvAccess::ChannelFind::shared_pointer channelList( virtual epics::pvAccess::ChannelFind::shared_pointer channelList(
epics::pvAccess::ChannelListRequester::shared_pointer const & channelListRequester); epics::pvAccess::ChannelListRequester::shared_pointer const & channelListRequester);
/**
* Create a channel for a record.
* This method just calls the next method with a address of "".
* @param channelName The name of the channel desired.
* @param channelRequester The client callback.
* @param priority The priority.
* @return shared pointer to Channel.
*/
virtual epics::pvAccess::Channel::shared_pointer createChannel( virtual epics::pvAccess::Channel::shared_pointer createChannel(
std::string const &channelName, std::string const &channelName,
epics::pvAccess::ChannelRequester::shared_pointer const &channelRequester, epics::pvAccess::ChannelRequester::shared_pointer const &channelRequester,
short priority); short priority);
/**
* Create a channel for a record.
* @param channelName The name of the channel desired.
* @param channelRequester The callback to call with the result.
* @param priority The priority.
* This is ignored.
* @param address The address.
* This is ignored.
* @return shared pointer to Channel.
* This is null if the channelName is not the name of a record in the PVDatabase.
* Otherwise it is a newly created channel inteface.
* ChannelRequester::channelCreated is called to give the result.
*/
virtual epics::pvAccess::Channel::shared_pointer createChannel( virtual epics::pvAccess::Channel::shared_pointer createChannel(
std::string const &channelName, std::string const &channelName,
epics::pvAccess::ChannelRequester::shared_pointer const &channelRequester, epics::pvAccess::ChannelRequester::shared_pointer const &channelRequester,
@@ -115,6 +190,10 @@ private:
friend class ChannelProviderLocalRun; friend class ChannelProviderLocalRun;
}; };
/**
* A Channel for accessing a record in the PVDatabase.
* It is a complete implementation of Channel
*/
class epicsShareClass ChannelLocal : class epicsShareClass ChannelLocal :
public epics::pvAccess::Channel, public epics::pvAccess::Channel,
public PVRecordClient, public PVRecordClient,
@@ -122,54 +201,185 @@ class epicsShareClass ChannelLocal :
{ {
public: public:
POINTER_DEFINITIONS(ChannelLocal); POINTER_DEFINITIONS(ChannelLocal);
/** Constructor
* @param channelProvider The channel provider.
* @param requester The client callback.
* @param pvRecord The record the channel will access.
*/
ChannelLocal( ChannelLocal(
ChannelProviderLocalPtr const &channelProvider, ChannelProviderLocalPtr const &channelProvider,
epics::pvAccess::ChannelRequester::shared_pointer const & requester, epics::pvAccess::ChannelRequester::shared_pointer const & requester,
PVRecordPtr const & pvRecord PVRecordPtr const & pvRecord
); );
/**
* Destructor
*/
virtual ~ChannelLocal(); virtual ~ChannelLocal();
/**
* Destroy the channel.
* It cleans up all resources used to access the record.
* Note that this assumes that client has destroyed any objects that
* have been created for the channel like channelGet, etc.
* The remote pvAccess server does this cleanup.
*/
virtual void destroy(); virtual void destroy();
/**
* Get the requester name.
* @param returns the name of the channel requester.
*/
virtual std::string getRequesterName(); virtual std::string getRequesterName();
/**
* Passes the message to the channel requester.
* @param message The message.
* @param messageType The message type.
*/
virtual void message( virtual void message(
std::string const & message, std::string const & message,
epics::pvData::MessageType messageType); epics::pvData::MessageType messageType);
/**
* Get the channel provider
* @return The provider.
*/
virtual epics::pvAccess::ChannelProvider::shared_pointer getProvider() virtual epics::pvAccess::ChannelProvider::shared_pointer getProvider()
{ {
return provider; return provider;
} }
/**
* Get the remote address
* @return <b>local</b>
*/
virtual std::string getRemoteAddress(); virtual std::string getRemoteAddress();
/**
* Get the connection state.
* @return Channel::CONNECTED.
*/
virtual epics::pvAccess::Channel::ConnectionState getConnectionState(); virtual epics::pvAccess::Channel::ConnectionState getConnectionState();
/**
* Get the channel name.
* @return the record name.
*/
virtual std::string getChannelName(); virtual std::string getChannelName();
/**
* Get the channel requester
* @return The channel requester.
*/
virtual epics::pvAccess::ChannelRequester::shared_pointer getChannelRequester(); virtual epics::pvAccess::ChannelRequester::shared_pointer getChannelRequester();
/**
* Is the channel connected?
* @return true
*/
virtual bool isConnected(); virtual bool isConnected();
/**
* Get the introspection interface for subField.
* The introspection interface is given via GetFieldRequester::getDone.
* @param requester The client callback.
* @param The subField of the record.
* If an empty string then the interface for the top level structure of
* the record is provided.
*/
virtual void getField( virtual void getField(
epics::pvAccess::GetFieldRequester::shared_pointer const &requester, epics::pvAccess::GetFieldRequester::shared_pointer const &requester,
std::string const & subField); std::string const & subField);
/**
* Get the access rights for the record.
* This throws an exception because it is assumed that access rights are
* handled by a higher level.
*/
virtual epics::pvAccess::AccessRights getAccessRights( virtual epics::pvAccess::AccessRights getAccessRights(
epics::pvData::PVField::shared_pointer const &pvField); epics::pvData::PVField::shared_pointer const &pvField);
/**
* Create a channelProcess.
* See pvAccess.html for details.
* @param requester The client callback.
* @param pvRequest The options specified by the client.
* @return A shared pointer to the newly created implementation.
* The implementation is null if pvRequest has invalid options.
*/
virtual epics::pvAccess::ChannelProcess::shared_pointer createChannelProcess( virtual epics::pvAccess::ChannelProcess::shared_pointer createChannelProcess(
epics::pvAccess::ChannelProcessRequester::shared_pointer const &requester, epics::pvAccess::ChannelProcessRequester::shared_pointer const &requester,
epics::pvData::PVStructurePtr const &pvRequest); epics::pvData::PVStructurePtr const &pvRequest);
/**
* Create a channelGet.
* See pvAccess.html for details.
* @param requester The client callback.
* @param pvRequest The options specified by the client.
* @return A shared pointer to the newly created implementation.
* The implementation is null if pvRequest has invalid options.
*/
virtual epics::pvAccess::ChannelGet::shared_pointer createChannelGet( virtual epics::pvAccess::ChannelGet::shared_pointer createChannelGet(
epics::pvAccess::ChannelGetRequester::shared_pointer const &requester, epics::pvAccess::ChannelGetRequester::shared_pointer const &requester,
epics::pvData::PVStructurePtr const &pvRequest); epics::pvData::PVStructurePtr const &pvRequest);
/**
* Create a channelPut.
* See pvAccess.html for details.
* @param requester The client callback.
* @param pvRequest The options specified by the client.
* @return A shared pointer to the newly created implementation.
* The implementation is null if pvRequest has invalid options.
*/
virtual epics::pvAccess::ChannelPut::shared_pointer createChannelPut( virtual epics::pvAccess::ChannelPut::shared_pointer createChannelPut(
epics::pvAccess::ChannelPutRequester::shared_pointer const &requester, epics::pvAccess::ChannelPutRequester::shared_pointer const &requester,
epics::pvData::PVStructurePtr const &pvRequest); epics::pvData::PVStructurePtr const &pvRequest);
/**
* Create a channelPutGet.
* See pvAccess.html for details.
* @param requester The client callback.
* @param pvRequest The options specified by the client.
* @return A shared pointer to the newly created implementation.
* The implementation is null if pvRequest has invalid options.
*/
virtual epics::pvAccess::ChannelPutGet::shared_pointer createChannelPutGet( virtual epics::pvAccess::ChannelPutGet::shared_pointer createChannelPutGet(
epics::pvAccess::ChannelPutGetRequester::shared_pointer const &requester, epics::pvAccess::ChannelPutGetRequester::shared_pointer const &requester,
epics::pvData::PVStructurePtr const &pvRequest); epics::pvData::PVStructurePtr const &pvRequest);
/**
* Create a channelRPC.
* This is not implemented because pvAccessCPP implements channelRPC.
* The server side of remote pvAccess implements a channel provider
* just for channelRPC.
* @param requester The client callback
* @param pvRequest The options specified by the client.
* @return null.
*/
virtual epics::pvAccess::ChannelRPC::shared_pointer createChannelRPC( virtual epics::pvAccess::ChannelRPC::shared_pointer createChannelRPC(
epics::pvAccess::ChannelRPCRequester::shared_pointer const &requester, epics::pvAccess::ChannelRPCRequester::shared_pointer const &requester,
epics::pvData::PVStructurePtr const &pvRequest); epics::pvData::PVStructurePtr const &pvRequest);
/**
* Create a monitor.
* See pvAccess.html for details.
* @param requester The client callback.
* @param pvRequest The options specified by the client.
* @return A shared pointer to the newly created implementation.
* The implementation is null if pvRequest has invalid options.
*/
virtual epics::pvData::Monitor::shared_pointer createMonitor( virtual epics::pvData::Monitor::shared_pointer createMonitor(
epics::pvData::MonitorRequester::shared_pointer const &requester, epics::pvData::MonitorRequester::shared_pointer const &requester,
epics::pvData::PVStructurePtr const &pvRequest); epics::pvData::PVStructurePtr const &pvRequest);
/**
* Create a channelArray.
* See pvAccess.html for details.
* @param requester The client callback.
* @param pvRequest The options specified by the client.
* @return A shared pointer to the newly created implementation.
* The implementation is null if pvRequest has invalid options.
*/
virtual epics::pvAccess::ChannelArray::shared_pointer createChannelArray( virtual epics::pvAccess::ChannelArray::shared_pointer createChannelArray(
epics::pvAccess::ChannelArrayRequester::shared_pointer const &requester, epics::pvAccess::ChannelArrayRequester::shared_pointer const &requester,
epics::pvData::PVStructurePtr const &pvRequest); epics::pvData::PVStructurePtr const &pvRequest);
/**
* calls printInfo(std::cout);
*/
virtual void printInfo(); virtual void printInfo();
/**
* displays a message
* "ChannelLocal provides access to a record in the local PVDatabase".
* @param out the stream on which the message is displayed.
*/
virtual void printInfo(std::ostream& out); virtual void printInfo(std::ostream& out);
/**
* This is called when a record is being removed from the database.
* Calls destroy.
* @record The record being destroyed.
*/
virtual void detach(PVRecordPtr const &pvRecord); virtual void detach(PVRecordPtr const &pvRecord);
protected: protected:
shared_pointer getPtrSelf() shared_pointer getPtrSelf()

View File

@@ -30,6 +30,7 @@ using std::string;
namespace epics { namespace pvDatabase { namespace epics { namespace pvDatabase {
static MonitorPtr nullMonitor; static MonitorPtr nullMonitor;
static MonitorElementPtr NULLMonitorElement; static MonitorElementPtr NULLMonitorElement;
static Status wasDestroyedStatus(Status::STATUSTYPE_ERROR,"was destroyed"); static Status wasDestroyedStatus(Status::STATUSTYPE_ERROR,"was destroyed");
@@ -37,52 +38,9 @@ static Status wasDestroyedStatus(Status::STATUSTYPE_ERROR,"was destroyed");
static ConvertPtr convert = getConvert(); static ConvertPtr convert = getConvert();
class ElementQueue;
typedef std::tr1::shared_ptr<ElementQueue> ElementQueuePtr;
class MultipleElementQueue;
typedef std::tr1::shared_ptr<MultipleElementQueue> MultipleElementQueuePtr;
class ElementQueue :
public Monitor,
public std::tr1::enable_shared_from_this<ElementQueue>
{
public:
POINTER_DEFINITIONS(ElementQueue);
virtual ~ElementQueue(){}
virtual bool dataChanged() = 0;
protected:
ElementQueuePtr getPtrSelf()
{
return shared_from_this();
}
};
typedef Queue<MonitorElement> MonitorElementQueue; typedef Queue<MonitorElement> MonitorElementQueue;
typedef std::tr1::shared_ptr<MonitorElementQueue> MonitorElementQueuePtr; typedef std::tr1::shared_ptr<MonitorElementQueue> MonitorElementQueuePtr;
class MultipleElementQueue :
public ElementQueue
{
public:
POINTER_DEFINITIONS(MultipleElementQueue);
virtual ~MultipleElementQueue(){}
MultipleElementQueue(
MonitorLocalPtr const &monitorLocal,
MonitorElementQueuePtr const &queue,
size_t nfields);
virtual void destroy(){}
virtual Status start();
virtual Status stop();
virtual bool dataChanged();
virtual MonitorElementPtr poll();
virtual void release(MonitorElementPtr const &monitorElement);
private:
std::tr1::weak_ptr<MonitorLocal> monitorLocal;
MonitorElementQueuePtr queue;
MonitorElementPtr activeElement;
bool queueIsFull;
};
class MonitorLocal : class MonitorLocal :
@@ -97,9 +55,10 @@ public:
virtual Status stop(); virtual Status stop();
virtual MonitorElementPtr poll(); virtual MonitorElementPtr poll();
virtual void destroy(); virtual void destroy();
virtual void dataChanged();
virtual void unlisten();
virtual void release(MonitorElementPtr const & monitorElement); virtual void release(MonitorElementPtr const & monitorElement);
MonitorElementPtr getActiveElement();
MonitorElementPtr releaseActiveElement();
void unlisten();
bool init(PVStructurePtr const & pvRequest); bool init(PVStructurePtr const & pvRequest);
MonitorLocal( MonitorLocal(
MonitorRequester::shared_pointer const & channelMonitorRequester, MonitorRequester::shared_pointer const & channelMonitorRequester,
@@ -116,7 +75,8 @@ private:
bool isDestroyed; bool isDestroyed;
bool firstMonitor; bool firstMonitor;
PVCopyPtr pvCopy; PVCopyPtr pvCopy;
ElementQueuePtr queue; MonitorElementQueuePtr queue;
MonitorElementPtr activeElement;
PVCopyMonitorPtr pvCopyMonitor; PVCopyMonitorPtr pvCopyMonitor;
Mutex mutex; Mutex mutex;
}; };
@@ -150,8 +110,6 @@ void MonitorLocal::destroy()
if(isDestroyed) return; if(isDestroyed) return;
isDestroyed = true; isDestroyed = true;
} }
unlisten();
stop();
pvCopyMonitor->destroy(); pvCopyMonitor->destroy();
pvCopy->destroy(); pvCopy->destroy();
pvCopyMonitor.reset(); pvCopyMonitor.reset();
@@ -161,69 +119,76 @@ void MonitorLocal::destroy()
Status MonitorLocal::start() Status MonitorLocal::start()
{ {
Lock xx(mutex);
if(pvRecord->getTraceLevel()>0) if(pvRecord->getTraceLevel()>0)
{ {
cout << "MonitorLocal::start() " << endl; cout << "MonitorLocal::start() " << endl;
} }
if(isDestroyed) return wasDestroyedStatus; if(isDestroyed) return wasDestroyedStatus;
firstMonitor = true; {
return queue->start(); Lock xx(mutex);
firstMonitor = true;
queue->clear();
activeElement = queue->getFree();
activeElement->changedBitSet->clear();
activeElement->overrunBitSet->clear();
}
pvCopyMonitor->startMonitoring(activeElement);
return Status::Ok;
} }
Status MonitorLocal::stop() Status MonitorLocal::stop()
{ {
pvCopyMonitor->stopMonitoring(); if(pvRecord->getTraceLevel()>0){
{ cout << "MonitorLocal::stop() " << endl;
Lock xx(mutex);
if(pvRecord->getTraceLevel()>0){
cout << "MonitorLocal::stop() " << endl;
}
if(!isDestroyed) queue->stop();
} }
if(isDestroyed) return Status::Ok;
pvCopyMonitor->stopMonitoring();
return Status::Ok; return Status::Ok;
} }
MonitorElementPtr MonitorLocal::poll() MonitorElementPtr MonitorLocal::poll()
{ {
Lock xx(mutex);
if(pvRecord->getTraceLevel()>1) if(pvRecord->getTraceLevel()>1)
{ {
cout << "MonitorLocal::poll() " << endl; cout << "MonitorLocal::poll() " << endl;
} }
if(isDestroyed) { if(isDestroyed) return NULLMonitorElement;
return NULLMonitorElement; Lock xx(mutex);
} return queue->getUsed();
return queue->poll();
} }
void MonitorLocal::release(MonitorElementPtr const & monitorElement) void MonitorLocal::release(MonitorElementPtr const & monitorElement)
{ {
Lock xx(mutex);
if(pvRecord->getTraceLevel()>1) if(pvRecord->getTraceLevel()>1)
{ {
cout << "MonitorLocal::release() " << endl; cout << "MonitorLocal::release() " << endl;
} }
if(isDestroyed) { if(isDestroyed) return;
return; Lock xx(mutex);
} queue->releaseUsed(monitorElement);
queue->release(monitorElement);
} }
void MonitorLocal::dataChanged() MonitorElementPtr MonitorLocal::releaseActiveElement()
{ {
if(pvRecord->getTraceLevel()>1) if(pvRecord->getTraceLevel()>1)
{ {
cout << "MonitorLocal::dataChanged() " "firstMonitor " << firstMonitor << endl; cout << "MonitorLocal::releaseActiveElement() " << endl;
} }
bool getMonitorEvent = false; if(isDestroyed) return activeElement;
{ {
Lock xx(mutex); Lock xx(mutex);
if(isDestroyed) return; MonitorElementPtr newActive = queue->getFree();
getMonitorEvent = queue->dataChanged(); if(!newActive) return activeElement;
firstMonitor = false; pvCopy->updateCopyFromBitSet(activeElement->pvStructurePtr,activeElement->changedBitSet);
BitSetUtil::compress(activeElement->changedBitSet,activeElement->pvStructurePtr);
BitSetUtil::compress(activeElement->overrunBitSet,activeElement->pvStructurePtr);
queue->setUsed(activeElement);
activeElement = newActive;
activeElement->changedBitSet->clear();
activeElement->overrunBitSet->clear();
} }
if(getMonitorEvent) monitorRequester->monitorEvent(getPtrSelf()); monitorRequester->monitorEvent(getPtrSelf());
return activeElement;
} }
void MonitorLocal::unlisten() void MonitorLocal::unlisten()
@@ -292,11 +257,7 @@ bool MonitorLocal::init(PVStructurePtr const & pvRequest)
new MonitorElement(pvStructure)); new MonitorElement(pvStructure));
monitorElementArray.push_back(monitorElement); monitorElementArray.push_back(monitorElement);
} }
MonitorElementQueuePtr elementQueue(new MonitorElementQueue(monitorElementArray)); queue = MonitorElementQueuePtr(new MonitorElementQueue(monitorElementArray));
queue = MultipleElementQueuePtr(new MultipleElementQueue(
getPtrSelf(),
elementQueue,
nfields));
// MARTY MUST IMPLEMENT algorithm // MARTY MUST IMPLEMENT algorithm
monitorRequester->monitorConnect( monitorRequester->monitorConnect(
Status::Ok, Status::Ok,
@@ -345,75 +306,6 @@ MonitorPtr MonitorFactory::createMonitor(
} }
MultipleElementQueue::MultipleElementQueue(
MonitorLocalPtr const &monitorLocal,
MonitorElementQueuePtr const &queue,
size_t nfields)
: monitorLocal(monitorLocal),
queue(queue),
queueIsFull(false)
{
}
Status MultipleElementQueue::start()
{
queue->clear();
queueIsFull = false;
activeElement = queue->getFree();
activeElement->changedBitSet->clear();
activeElement->overrunBitSet->clear();
MonitorLocalPtr ml = monitorLocal.lock();
if(ml==NULL) return wasDestroyedStatus;
ml->getPVCopyMonitor()->setMonitorElement(activeElement);
ml->getPVCopyMonitor()->startMonitoring();
return Status::Ok;
}
Status MultipleElementQueue::stop()
{
return Status::Ok;
}
bool MultipleElementQueue::dataChanged()
{
MonitorLocalPtr ml = monitorLocal.lock();
if(ml==NULL) return false;
if(queueIsFull) return false;
ml->getPVCopy()->updateCopyFromBitSet(
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()
{
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 &element)
{
queue->releaseUsed(element);
if(!queueIsFull) return;
queueIsFull = false;
if(!activeElement->changedBitSet->isEmpty()) {
dataChanged();
}
}
MonitorFactoryPtr getMonitorFactory() MonitorFactoryPtr getMonitorFactory()
{ {

View File

@@ -58,7 +58,8 @@ PVCopyMonitor::PVCopyMonitor(
pvCopyMonitorRequester(pvCopyMonitorRequester), pvCopyMonitorRequester(pvCopyMonitorRequester),
isGroupPut(false), isGroupPut(false),
dataChanged(false), dataChanged(false),
isMonitoring(false) isMonitoring(false),
isDestroyed(false)
{ {
} }
@@ -76,17 +77,17 @@ void PVCopyMonitor::init(PVFieldPtr const &pvField)
size_t offset = pvCopy->getCopyOffset(pvField); size_t offset = pvCopy->getCopyOffset(pvField);
if(offset==string::npos) return; if(offset==string::npos) return;
PVStructurePtr pvOptions = pvCopy->getOptions(offset); PVStructurePtr pvOptions = pvCopy->getOptions(offset);
if(pvOptions!=NULL) { if(pvOptions) {
PVStringPtr pvName = pvOptions->getSubField<PVString>("plugin"); PVStringPtr pvName = pvOptions->getSubField<PVString>("plugin");
if(pvName!=NULL) { if(pvName) {
string pluginName = pvName->get(); string pluginName = pvName->get();
MonitorPluginManagerPtr manager = MonitorPluginManager::get(); MonitorPluginManagerPtr manager = MonitorPluginManager::get();
MonitorPluginCreatorPtr pluginCreator = manager->findPlugin(pluginName); MonitorPluginCreatorPtr pluginCreator = manager->findPlugin(pluginName);
if(pluginCreator!=NULL) { if(pluginCreator) {
StructureConstPtr top = pvCopy->getStructure(); StructureConstPtr top = pvCopy->getStructure();
FieldConstPtr field = pvField->getField(); FieldConstPtr field = pvField->getField();
MonitorPluginPtr monitorPlugin = pluginCreator->create(field,top,pvOptions); MonitorPluginPtr monitorPlugin = pluginCreator->create(field,top,pvOptions);
if(monitorPlugin!=NULL) { if(monitorPlugin) {
PVCopyMonitorFieldNodePtr fieldNode(new PVCopyMonitorFieldNode()); PVCopyMonitorFieldNodePtr fieldNode(new PVCopyMonitorFieldNode());
fieldNode->monitorPlugin = monitorPlugin; fieldNode->monitorPlugin = monitorPlugin;
fieldNode->offset = offset; fieldNode->offset = offset;
@@ -117,17 +118,22 @@ void PVCopyMonitor::destroy()
{ {
cout << "PVCopyMonitor::destroy()" << endl; cout << "PVCopyMonitor::destroy()" << endl;
} }
if(isDestroyed) return;
Lock xx(mutex);
isDestroyed = true;
stopMonitoring(); stopMonitoring();
pvCopyMonitorRequester.reset(); pvCopyMonitorRequester.reset();
pvCopy.reset(); pvCopy.reset();
} }
void PVCopyMonitor::startMonitoring() void PVCopyMonitor::startMonitoring(MonitorElementPtr const & startElement)
{ {
if(pvRecord->getTraceLevel()>0) if(pvRecord->getTraceLevel()>0)
{ {
cout << "PVCopyMonitor::startMonitoring()" << endl; cout << "PVCopyMonitor::startMonitoring()" << endl;
} }
if(isDestroyed) return;
monitorElement = startElement;
Lock xx(mutex); Lock xx(mutex);
if(isMonitoring) return; if(isMonitoring) return;
isMonitoring = true; isMonitoring = true;
@@ -137,14 +143,14 @@ void PVCopyMonitor::startMonitoring()
{ {
(*iter)->monitorPlugin->startMonitoring(); (*iter)->monitorPlugin->startMonitoring();
} }
pvRecord->addListener(getPtrSelf());
pvRecord->lock(); pvRecord->lock();
try { try {
pvRecord->addListener(getPtrSelf());
pvCopy->traverseMaster(getPtrSelf()); pvCopy->traverseMaster(getPtrSelf());
monitorElement->changedBitSet->clear(); monitorElement->changedBitSet->clear();
monitorElement->overrunBitSet->clear(); monitorElement->overrunBitSet->clear();
monitorElement->changedBitSet->set(0); monitorElement->changedBitSet->set(0);
pvCopyMonitorRequester->dataChanged(); monitorElement = pvCopyMonitorRequester->releaseActiveElement();
pvRecord->unlock(); pvRecord->unlock();
} catch(...) { } catch(...) {
pvRecord->unlock(); pvRecord->unlock();
@@ -162,41 +168,19 @@ void PVCopyMonitor::stopMonitoring()
{ {
cout << "PVCopyMonitor::stopMonitoring()" << endl; cout << "PVCopyMonitor::stopMonitoring()" << endl;
} }
Lock xx(mutex); if(isDestroyed) return;
if(!isMonitoring) return; if(!isMonitoring) return;
pvRecord->removeListener(getPtrSelf());
Lock xx(mutex);
std::list<PVCopyMonitorFieldNodePtr>::iterator iter; std::list<PVCopyMonitorFieldNodePtr>::iterator iter;
for (iter = monitorFieldNodeList.begin();iter!=monitorFieldNodeList.end();++iter) for (iter = monitorFieldNodeList.begin();iter!=monitorFieldNodeList.end();++iter)
{ {
(*iter)->monitorPlugin->stopMonitoring(); (*iter)->monitorPlugin->stopMonitoring();
} }
isMonitoring = false; 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) void PVCopyMonitor::detach(PVRecordPtr const & pvRecord)
{ {
@@ -208,27 +192,34 @@ void PVCopyMonitor::detach(PVRecordPtr const & pvRecord)
void PVCopyMonitor::dataPut(PVRecordFieldPtr const & pvRecordField) void PVCopyMonitor::dataPut(PVRecordFieldPtr const & pvRecordField)
{ {
if(pvRecord->getTraceLevel()>0) if(pvRecord->getTraceLevel()>1)
{ {
cout << "PVCopyMonitor::dataPut(pvRecordField)" << endl; cout << "PVCopyMonitor::dataPut(pvRecordField)" << endl;
} }
size_t offset = pvCopy->getCopyOffset(pvRecordField->getPVField()); if(isDestroyed) return;
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; bool causeMonitor = true;
if(monitorPlugin!=NULL) { {
causeMonitor = monitorPlugin->causeMonitor( Lock xx(mutex);
pvRecordField->getPVField(), size_t offset = pvCopy->getCopyOffset(pvRecordField->getPVField());
pvRecord->getPVRecordStructure()->getPVStructure(), BitSetPtr const &changedBitSet = monitorElement->changedBitSet;
monitorElement); BitSetPtr const &overrunBitSet = monitorElement->overrunBitSet;
bool isSet = changedBitSet->get(offset);
changedBitSet->set(offset);
if(isSet) overrunBitSet->set(offset);
MonitorPluginPtr monitorPlugin = getMonitorPlugin(offset);
if(monitorPlugin) {
causeMonitor = monitorPlugin->causeMonitor(
pvRecordField->getPVField(),
pvRecord->getPVRecordStructure()->getPVStructure(),
monitorElement);
}
if(causeMonitor) dataChanged = true;
} }
if(causeMonitor) { if(causeMonitor) {
if(!isGroupPut) pvCopyMonitorRequester->dataChanged(); if(!isGroupPut) {
dataChanged = true; monitorElement = pvCopyMonitorRequester->releaseActiveElement();
dataChanged = false;
}
} }
} }
@@ -236,42 +227,53 @@ void PVCopyMonitor::dataPut(
PVRecordStructurePtr const & requested, PVRecordStructurePtr const & requested,
PVRecordFieldPtr const & pvRecordField) PVRecordFieldPtr const & pvRecordField)
{ {
if(pvRecord->getTraceLevel()>0) if(pvRecord->getTraceLevel()>1)
{ {
cout << "PVCopyMonitor::dataPut(requested,pvRecordField)" << endl; cout << "PVCopyMonitor::dataPut(requested,pvRecordField)" << endl;
} }
BitSetPtr const &changedBitSet = monitorElement->changedBitSet; if(isDestroyed) return;
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; bool causeMonitor = true;
if(monitorPlugin!=NULL) { {
causeMonitor = monitorPlugin->causeMonitor( Lock xx(mutex);
requested->getPVField(), BitSetPtr const &changedBitSet = monitorElement->changedBitSet;
pvRecord->getPVRecordStructure()->getPVStructure(), BitSetPtr const &overrunBitSet = monitorElement->overrunBitSet;
monitorElement); 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);
if(monitorPlugin) {
causeMonitor = monitorPlugin->causeMonitor(
requested->getPVField(),
pvRecord->getPVRecordStructure()->getPVStructure(),
monitorElement);
}
if(causeMonitor) dataChanged = true;
} }
if(causeMonitor) { if(causeMonitor) {
if(!isGroupPut) pvCopyMonitorRequester->dataChanged(); if(!isGroupPut) {
dataChanged = true; monitorElement = pvCopyMonitorRequester->releaseActiveElement();
dataChanged = false;
}
} }
} }
void PVCopyMonitor::beginGroupPut(PVRecordPtr const & pvRecord) void PVCopyMonitor::beginGroupPut(PVRecordPtr const & pvRecord)
{ {
if(pvRecord->getTraceLevel()>0) if(pvRecord->getTraceLevel()>1)
{ {
cout << "PVCopyMonitor::beginGroupPut()" << endl; cout << "PVCopyMonitor::beginGroupPut()" << endl;
} }
isGroupPut = true; if(isDestroyed) return;
dataChanged = false; {
Lock xx(mutex);
isGroupPut = true;
dataChanged = false;
}
std::list<PVCopyMonitorFieldNodePtr>::iterator iter; std::list<PVCopyMonitorFieldNodePtr>::iterator iter;
for (iter = monitorFieldNodeList.begin(); for (iter = monitorFieldNodeList.begin();
iter!=monitorFieldNodeList.end(); iter!=monitorFieldNodeList.end();
@@ -283,27 +285,34 @@ void PVCopyMonitor::beginGroupPut(PVRecordPtr const & pvRecord)
void PVCopyMonitor::endGroupPut(PVRecordPtr const & pvRecord) void PVCopyMonitor::endGroupPut(PVRecordPtr const & pvRecord)
{ {
if(pvRecord->getTraceLevel()>0) if(pvRecord->getTraceLevel()>1)
{ {
cout << "PVCopyMonitor::endGroupPut() dataChanged " << dataChanged << endl; cout << "PVCopyMonitor::endGroupPut() dataChanged " << dataChanged << endl;
} }
isGroupPut = false; if(isDestroyed) return;
std::list<PVCopyMonitorFieldNodePtr>::iterator iter; std::list<PVCopyMonitorFieldNodePtr>::iterator iter;
for (iter = monitorFieldNodeList.begin();iter!=monitorFieldNodeList.end();++iter) for (iter = monitorFieldNodeList.begin();iter!=monitorFieldNodeList.end();++iter)
{ {
(*iter)->monitorPlugin->endGroupPut(); (*iter)->monitorPlugin->endGroupPut();
} }
{
Lock xx(mutex);
isGroupPut = false;
}
if(dataChanged) { if(dataChanged) {
dataChanged = false; monitorElement = pvCopyMonitorRequester->releaseActiveElement();
pvCopyMonitorRequester->dataChanged(); dataChanged = false;
} }
} }
void PVCopyMonitor::unlisten(PVRecordPtr const & pvRecord) void PVCopyMonitor::unlisten(PVRecordPtr const & pvRecord)
{ {
if(pvRecord->getTraceLevel()>1)
{
cout << "PVCopyMonitor::unlisten\n";
}
if(isDestroyed) return;
pvCopyMonitorRequester->unlisten(); pvCopyMonitorRequester->unlisten();
} }
}} }}

View File

@@ -21,8 +21,6 @@
#include <memory> #include <memory>
#include <list> #include <list>
#include <shareLib.h>
#include <pv/monitorPlugin.h> #include <pv/monitorPlugin.h>
#include <pv/pvCopy.h> #include <pv/pvCopy.h>
#include <pv/pvAccess.h> #include <pv/pvAccess.h>
@@ -32,6 +30,8 @@
# undef pvCopyMonitorEpicsExportSharedSymbols # undef pvCopyMonitorEpicsExportSharedSymbols
#endif #endif
#include <shareLib.h>
#include <pv/pvDatabase.h> #include <pv/pvDatabase.h>
namespace epics { namespace pvDatabase { namespace epics { namespace pvDatabase {
@@ -45,6 +45,10 @@ struct PVCopyMonitorFieldNode;
typedef std::tr1::shared_ptr<PVCopyMonitorFieldNode> PVCopyMonitorFieldNodePtr; typedef std::tr1::shared_ptr<PVCopyMonitorFieldNode> PVCopyMonitorFieldNodePtr;
/**
* PVCopyMonitor
* This class manages changes to fields being monitored in a PVRecord.
*/
class epicsShareClass PVCopyMonitor : class epicsShareClass PVCopyMonitor :
public PVListener, public PVListener,
public epics::pvData::PVCopyTraverseMasterCallback, public epics::pvData::PVCopyTraverseMasterCallback,
@@ -52,26 +56,80 @@ class epicsShareClass PVCopyMonitor :
{ {
public: public:
POINTER_DEFINITIONS(PVCopyMonitor); POINTER_DEFINITIONS(PVCopyMonitor);
/**
* Factory method to create a PVCopyMonoitor
* @param pvCopyMonitorRequester This is usually MonitorLocal.
* @param pvRecord The record being monitored.
* @param pvCopy An instance of pvCopy
* @return A shared pointer to a PVCopyMonitor.
*/
static PVCopyMonitorPtr create( static PVCopyMonitorPtr create(
PVCopyMonitorRequesterPtr const &pvCopyMonitorRequester, PVCopyMonitorRequesterPtr const &pvCopyMonitorRequester,
PVRecordPtr const &pvRecord, PVRecordPtr const &pvRecord,
epics::pvData::PVCopyPtr const & pvCopy); epics::pvData::PVCopyPtr const & pvCopy);
/**
* Destructor
*/
virtual ~PVCopyMonitor(); virtual ~PVCopyMonitor();
/**
* Destroy the PVCopyMonitor
*/
virtual void destroy(); virtual void destroy();
void startMonitoring(); /**
* Calls pvRecord methods to start monitoring for calls to postPut.
* @param monitorElement the initial monotorElement
* This holds the change and overrun bitSets that are updated
* when postPut is called.
*/
void startMonitoring(
epics::pvData::MonitorElementPtr const & monitorElement);
/**
* Calls pvRecord methods to stop monitoring for calls to postPut.
*/
void stopMonitoring(); void stopMonitoring();
void setMonitorElement(epics::pvData::MonitorElementPtr const &monitorElement);
void monitorDone(epics::pvData::MonitorElementPtr const &monitorElement);
// following are PVListener methods // following are PVListener methods
/**
* The record is being removed from the PVDatabase.
* @param The record being removed.
*/
virtual void detach(PVRecordPtr const & pvRecord); virtual void detach(PVRecordPtr const & pvRecord);
/**
* A postPut has been issued to a field being monitored.
* @param pvRecordField The field.
*/
virtual void dataPut(PVRecordFieldPtr const & pvRecordField); virtual void dataPut(PVRecordFieldPtr const & pvRecordField);
/**
* A postPut has been issued to a subfield of a field being monitored.
* @param requested The field being monitored.
* @param pvRecordField The field being modified.
*/
virtual void dataPut( virtual void dataPut(
PVRecordStructurePtr const & requested, PVRecordStructurePtr const & requested,
PVRecordFieldPtr const & pvRecordField); PVRecordFieldPtr const & pvRecordField);
/**
* A group of puts are being changed.
* No monitors should be issued until endGroupPut is called.
* @param pvRecord The record.
*/
virtual void beginGroupPut(PVRecordPtr const & pvRecord); virtual void beginGroupPut(PVRecordPtr const & pvRecord);
/**
* The end of a group of puts.
* If any fields have changed value since beginGroupPut a monitor
* can be issued.
* @param pvRecord The record.
*/
virtual void endGroupPut(PVRecordPtr const & pvRecord); virtual void endGroupPut(PVRecordPtr const & pvRecord);
/**
* The record is being removed from the database.
* @param pvRecord The record.
*/
virtual void unlisten(PVRecordPtr const & pvRecord); virtual void unlisten(PVRecordPtr const & pvRecord);
// following is PVCopyTraverseMasterCallback method // following is PVCopyTraverseMasterCallback method
/**
* The PVCopyTraverseMasterCallback callback
* Called for every field of PVRecord that is being monoitored.
* @param pvField The field in the PVRecord.
*/
virtual void nextMasterPVField(epics::pvData::PVFieldPtr const &pvField); virtual void nextMasterPVField(epics::pvData::PVFieldPtr const &pvField);
private: private:
PVCopyMonitorPtr getPtrSelf() PVCopyMonitorPtr getPtrSelf()
@@ -91,6 +149,7 @@ private:
bool isGroupPut; bool isGroupPut;
bool dataChanged; bool dataChanged;
bool isMonitoring; bool isMonitoring;
bool isDestroyed;
epics::pvData::Mutex mutex; epics::pvData::Mutex mutex;
std::list<PVCopyMonitorFieldNodePtr> monitorFieldNodeList; std::list<PVCopyMonitorFieldNodePtr> monitorFieldNodeList;
}; };
@@ -100,7 +159,7 @@ class epicsShareClass PVCopyMonitorRequester
public: public:
POINTER_DEFINITIONS(PVCopyMonitorRequester); POINTER_DEFINITIONS(PVCopyMonitorRequester);
virtual ~PVCopyMonitorRequester() {} virtual ~PVCopyMonitorRequester() {}
virtual void dataChanged() = 0; virtual epics::pvData::MonitorElementPtr releaseActiveElement() = 0;
virtual void unlisten() = 0; virtual void unlisten() = 0;
}; };

View File

@@ -27,12 +27,12 @@
#include <iocsh.h> #include <iocsh.h>
#include <shareLib.h> #include <shareLib.h>
#include <epicsExport.h>
#include <pv/pvAccess.h> #include <pv/pvAccess.h>
#include <pv/serverContext.h> #include <pv/serverContext.h>
#define epicsExportSharedSymbols // this declared epicsExportSharedSymbols
#include <epicsExport.h>
#include <pv/channelProviderLocal.h> #include <pv/channelProviderLocal.h>
using std::cout; using std::cout;

View File

@@ -24,26 +24,16 @@ RecordListRecordPtr RecordListRecord::create(
{ {
FieldCreatePtr fieldCreate = getFieldCreate(); FieldCreatePtr fieldCreate = getFieldCreate();
PVDataCreatePtr pvDataCreate = getPVDataCreate(); PVDataCreatePtr pvDataCreate = getPVDataCreate();
StringArray argNames(2); StructureConstPtr topStructure = fieldCreate->createFieldBuilder()->
FieldConstPtrArray argFields(2); addNestedStructure("argument")->
argNames[0] = "database"; add("database",pvString)->
argFields[0] = fieldCreate->createScalar(pvString); add("regularExpression",pvString)->
argNames[1] = "regularExpression"; endNested()->
argFields[1] = fieldCreate->createScalar(pvString); addNestedStructure("result") ->
StringArray resNames(2); add("status",pvString) ->
FieldConstPtrArray resFields(2); addArray("names",pvString) ->
resNames[0] = "status"; endNested()->
resFields[0] = fieldCreate->createScalar(pvString); createStructure();
resNames[1] = "names";
resFields[1] = fieldCreate->createScalarArray(pvString);
StringArray topNames(2);
FieldConstPtrArray topFields(2);
topNames[0] = "argument";
topFields[0] = fieldCreate->createStructure(argNames,argFields);
topNames[1] = "result";
topFields[1] = fieldCreate->createStructure(resNames,resFields);
StructureConstPtr topStructure =
fieldCreate->createStructure(topNames,topFields);
PVStructurePtr pvStructure = pvDataCreate->createPVStructure(topStructure); PVStructurePtr pvStructure = pvDataCreate->createPVStructure(topStructure);
RecordListRecordPtr pvRecord( RecordListRecordPtr pvRecord(
new RecordListRecord(recordName,pvStructure)); new RecordListRecord(recordName,pvStructure));
@@ -83,16 +73,16 @@ bool RecordListRecord::init()
std::cerr << "no result.names" << std::endl; std::cerr << "no result.names" << std::endl;
return false; return false;
} }
names = static_pointer_cast<PVStringArray>( name = static_pointer_cast<PVStringArray>(
pvStructure->getScalarArrayField("result.names",pvString)); pvStructure->getScalarArrayField("result.names",pvString));
if(names.get()==NULL) return false; if(name.get()==NULL) return false;
return true; return true;
} }
void RecordListRecord::process() void RecordListRecord::process()
{ {
PVStringArrayPtr pvNames = PVDatabase::getMaster()->getRecordNames(); PVStringArrayPtr pvNames = PVDatabase::getMaster()->getRecordNames();
names->replace(pvNames->view()); name->replace(pvNames->view());
string message(""); string message("");
if(database->get().compare("master")!=0) { if(database->get().compare("master")!=0) {
message += " can only access master "; message += " can only access master ";

View File

@@ -20,16 +20,39 @@ namespace epics { namespace pvDatabase {
class RecordListRecord; class RecordListRecord;
typedef std::tr1::shared_ptr<RecordListRecord> RecordListRecordPtr; typedef std::tr1::shared_ptr<RecordListRecord> RecordListRecordPtr;
/**
* This is a record that provides a PVStringArray that
* has the record names of all records in the local PVDatabase.
* It is meant to be used by a channelPutGet request.
*/
class epicsShareClass RecordListRecord : class epicsShareClass RecordListRecord :
public PVRecord public PVRecord
{ {
public: public:
POINTER_DEFINITIONS(RecordListRecord); POINTER_DEFINITIONS(RecordListRecord);
/**
* Factory methods to create RecordListRecord.
* @param recordName The name for the RecordListRecord.
* @return A shared pointer to RecordListRecord..
*/
static RecordListRecordPtr create( static RecordListRecordPtr create(
std::string const & recordName); std::string const & recordName);
/**
* destructor
*/
virtual ~RecordListRecord(); virtual ~RecordListRecord();
/**
* Clean up any resources used.
*/
virtual void destroy(); virtual void destroy();
/**
* standard init method required by PVRecord
* @return true unless record name already exists.
*/
virtual bool init(); virtual bool init();
/*
* Generated the list of record names.
*/
virtual void process(); virtual void process();
private: private:
RecordListRecord(std::string const & recordName, RecordListRecord(std::string const & recordName,
@@ -37,7 +60,7 @@ private:
epics::pvData::PVStringPtr database; epics::pvData::PVStringPtr database;
epics::pvData::PVStringPtr regularExpression; epics::pvData::PVStringPtr regularExpression;
epics::pvData::PVStringPtr status; epics::pvData::PVStringPtr status;
epics::pvData::PVStringArrayPtr names; epics::pvData::PVStringArrayPtr name;
}; };
}} }}

View File

@@ -24,24 +24,15 @@ TraceRecordPtr TraceRecord::create(
{ {
FieldCreatePtr fieldCreate = getFieldCreate(); FieldCreatePtr fieldCreate = getFieldCreate();
PVDataCreatePtr pvDataCreate = getPVDataCreate(); PVDataCreatePtr pvDataCreate = getPVDataCreate();
StringArray topNames(2); StructureConstPtr topStructure = fieldCreate->createFieldBuilder()->
FieldConstPtrArray topFields(2); addNestedStructure("argument")->
topNames[0] = "argument"; add("recordName",pvString)->
topNames[1] = "result"; add("level",pvInt)->
StringArray argNames(2); endNested()->
FieldConstPtrArray argFields(2); addNestedStructure("result") ->
argNames[0] = "recordName"; add("status",pvString) ->
argNames[1] = "level"; endNested()->
argFields[0] = fieldCreate->createScalar(pvString); createStructure();
argFields[1] = fieldCreate->createScalar(pvInt);
topFields[0] = fieldCreate->createStructure(argNames,argFields);
StringArray resNames(1);
FieldConstPtrArray resFields(1);
resNames[0] = "status";
resFields[0] = fieldCreate->createScalar(pvString);
topFields[1] = fieldCreate->createStructure(resNames,resFields);
StructureConstPtr topStructure =
fieldCreate->createStructure(topNames,topFields);
PVStructurePtr pvStructure = pvDataCreate->createPVStructure(topStructure); PVStructurePtr pvStructure = pvDataCreate->createPVStructure(topStructure);
TraceRecordPtr pvRecord( TraceRecordPtr pvRecord(
new TraceRecord(recordName,pvStructure)); new TraceRecord(recordName,pvStructure));
@@ -72,11 +63,11 @@ bool TraceRecord::init()
initPVRecord(); initPVRecord();
PVStructurePtr pvStructure = getPVStructure(); PVStructurePtr pvStructure = getPVStructure();
pvRecordName = pvStructure->getStringField("argument.recordName"); pvRecordName = pvStructure->getStringField("argument.recordName");
if(pvRecordName==NULL) return false; if(!pvRecordName) return false;
pvLevel = pvStructure->getIntField("argument.level"); pvLevel = pvStructure->getIntField("argument.level");
if(pvLevel==NULL) return false; if(!pvLevel) return false;
pvResult = pvStructure->getStringField("result.status"); pvResult = pvStructure->getStringField("result.status");
if(pvResult==NULL) return false; if(!pvResult) return false;
return true; return true;
} }
@@ -84,7 +75,7 @@ void TraceRecord::process()
{ {
string name = pvRecordName->get(); string name = pvRecordName->get();
PVRecordPtr pvRecord = pvDatabase->findRecord(name); PVRecordPtr pvRecord = pvDatabase->findRecord(name);
if(pvRecord==NULL) { if(!pvRecord) {
pvResult->put(name + " not found"); pvResult->put(name + " not found");
return; return;
} }

View File

@@ -18,6 +18,12 @@
namespace epics { namespace pvDatabase { namespace epics { namespace pvDatabase {
/**
* A record to set the trace value for another record
* It is meant to be used via a channelPutGet request.
* The argument has two fields: recordName and level.
* The result has a field named status.
*/
class TraceRecord; class TraceRecord;
typedef std::tr1::shared_ptr<TraceRecord> TraceRecordPtr; typedef std::tr1::shared_ptr<TraceRecord> TraceRecordPtr;
@@ -26,11 +32,29 @@ class epicsShareClass TraceRecord :
{ {
public: public:
POINTER_DEFINITIONS(TraceRecord); POINTER_DEFINITIONS(TraceRecord);
/**
* Factory methods to create TraceRecord.
* @param recordName The name for the TraceRecord.
* @return A shared pointer to TraceRecord..
*/
static TraceRecordPtr create( static TraceRecordPtr create(
std::string const & recordName); std::string const & recordName);
/**
* destructor
*/
virtual ~TraceRecord(); virtual ~TraceRecord();
/**
* Clean up any resources used.
*/
virtual void destroy(); virtual void destroy();
/**
* standard init method required by PVRecord
* @return true unless record name already exists.
*/
virtual bool init(); virtual bool init();
/**
* Set the trace level.
*/
virtual void process(); virtual void process();
private: private:
TraceRecord( TraceRecord(

View File

@@ -35,5 +35,5 @@
INSTALL_INCLUDE = $(INSTALL_LOCATION)/include/pv INSTALL_INCLUDE = $(INSTALL_LOCATION)/include/pv
USR_INCLUDES += -I $(INSTALL_LOCATION)/include USR_INCLUDES += -I $(INSTALL_LOCATION)/include
-include $(TOP)/configure/CONFIG_SITE.local -include $(TOP)/../../CONFIG_SITE.local
-include $(TOP)/../CONFIG.local -include $(TOP)/../configure/CONFIG_SITE.local

View File

@@ -9,12 +9,17 @@
* @date 2013.04.02 * @date 2013.04.02
*/ */
#include "powerSupply.h"
#include <pv/standardField.h> #include <pv/standardField.h>
#include <pv/standardPVField.h> #include <pv/standardPVField.h>
#define epicsExportSharedSymbols
#include "powerSupply.h"
using namespace epics::pvData; using namespace epics::pvData;
using std::string; using std::string;
using std::cout;
using std::cerr;
using std::endl;
namespace epics { namespace pvDatabase { namespace epics { namespace pvDatabase {
@@ -24,24 +29,23 @@ PVStructurePtr createPowerSupply()
StandardFieldPtr standardField = getStandardField(); StandardFieldPtr standardField = getStandardField();
PVDataCreatePtr pvDataCreate = getPVDataCreate(); PVDataCreatePtr pvDataCreate = getPVDataCreate();
size_t nfields = 5;
StringArray names;
names.reserve(nfields);
FieldConstPtrArray powerSupply;
powerSupply.reserve(nfields);
names.push_back("alarm");
powerSupply.push_back(standardField->alarm());
names.push_back("timeStamp");
powerSupply.push_back(standardField->timeStamp());
string properties("alarm,display");
names.push_back("voltage");
powerSupply.push_back(standardField->scalar(pvDouble,properties));
names.push_back("power");
powerSupply.push_back(standardField->scalar(pvDouble,properties));
names.push_back("current");
powerSupply.push_back(standardField->scalar(pvDouble,properties));
return pvDataCreate->createPVStructure( return pvDataCreate->createPVStructure(
fieldCreate->createStructure(names,powerSupply)); fieldCreate->createFieldBuilder()->
add("alarm",standardField->alarm()) ->
add("timeStamp",standardField->timeStamp()) ->
addNestedStructure("power") ->
add("value",pvDouble) ->
add("alarm",standardField->alarm()) ->
endNested()->
addNestedStructure("voltage") ->
add("value",pvDouble) ->
add("alarm",standardField->alarm()) ->
endNested()->
addNestedStructure("current") ->
add("value",pvDouble) ->
add("alarm",standardField->alarm()) ->
endNested()->
createStructure());
} }
PowerSupplyPtr PowerSupply::create( PowerSupplyPtr PowerSupply::create(
@@ -77,62 +81,40 @@ bool PowerSupply::init()
PVFieldPtr pvField; PVFieldPtr pvField;
bool result; bool result;
pvField = pvStructure->getSubField("timeStamp"); pvField = pvStructure->getSubField("timeStamp");
if(pvField.get()==NULL) { if(!pvField) {
std::cerr << "no timeStamp" << std::endl; cerr << "no timeStamp" << endl;
return false; return false;
} }
result = pvTimeStamp.attach(pvField); result = pvTimeStamp.attach(pvField);
if(!result) { if(!result) {
std::cerr << "no timeStamp" << std::endl; cerr << "no timeStamp" << endl;
return false; return false;
} }
pvField = pvStructure->getSubField("alarm"); pvField = pvStructure->getSubField("alarm");
if(pvField.get()==NULL) { if(!pvField) {
std::cerr << "no alarm" << std::endl; cerr << "no alarm" << endl;
return false; return false;
} }
result = pvAlarm.attach(pvField); result = pvAlarm.attach(pvField);
if(!result) { if(!result) {
std::cerr << "no alarm" << std::endl; cerr << "no alarm" << endl;
return false; return false;
} }
string name; pvCurrent = pvStructure->getSubField<PVDouble>("current.value");
name = "current.value"; if(!pvCurrent) {
pvField = pvStructure->getSubField(name); cerr << "no current\n";
if(pvField.get()==NULL) {
name = "current";
pvField = pvStructure->getSubField(name);
}
if(pvField.get()==NULL) {
std::cerr << "no current" << std::endl;
return false; return false;
} }
pvCurrent = pvStructure->getDoubleField(name); pvVoltage = pvStructure->getSubField<PVDouble>("voltage.value");
if(pvCurrent.get()==NULL) return false; if(!pvVoltage) {
name = "voltage.value"; cerr << "no current\n";
pvField = pvStructure->getSubField(name);
if(pvField.get()==NULL) {
name = "voltage";
pvField = pvStructure->getSubField(name);
}
if(pvField.get()==NULL) {
std::cerr << "no voltage" << std::endl;
return false; return false;
} }
pvVoltage = pvStructure->getDoubleField(name); pvPower = pvStructure->getSubField<PVDouble>("power.value");
if(pvVoltage.get()==NULL) return false; if(!pvPower) {
name = "power.value"; cerr << "no powert\n";
pvField = pvStructure->getSubField(name);
if(pvField.get()==NULL) {
name = "power";
pvField = pvStructure->getSubField(name);
}
if(pvField.get()==NULL) {
std::cerr << "no power" << std::endl;
return false; return false;
} }
pvPower = pvStructure->getDoubleField(name);
if(pvPower.get()==NULL) return false;
return true; return true;
} }

View File

@@ -11,13 +11,25 @@
#ifndef POWERSUPPLY_H #ifndef POWERSUPPLY_H
#define POWERSUPPLY_H #define POWERSUPPLY_H
#include <shareLib.h>
#include <pv/pvDatabase.h> #ifdef epicsExportSharedSymbols
# define powerSupplyEpicsExportSharedSymbols
# undef epicsExportSharedSymbols
#endif
#include <pv/timeStamp.h> #include <pv/timeStamp.h>
#include <pv/alarm.h> #include <pv/alarm.h>
#include <pv/pvTimeStamp.h> #include <pv/pvTimeStamp.h>
#include <pv/pvAlarm.h> #include <pv/pvAlarm.h>
#include <pv/pvDatabase.h>
#ifdef powerSupplyEpicsExportSharedSymbols
# define epicsExportSharedSymbols
# undef powerSupplyEpicsExportSharedSymbols
#endif
#include <shareLib.h>
namespace epics { namespace pvDatabase { namespace epics { namespace pvDatabase {
@@ -26,7 +38,7 @@ epicsShareExtern epics::pvData::PVStructurePtr createPowerSupply();
class PowerSupply; class PowerSupply;
typedef std::tr1::shared_ptr<PowerSupply> PowerSupplyPtr; typedef std::tr1::shared_ptr<PowerSupply> PowerSupplyPtr;
class PowerSupply : class epicsShareClass PowerSupply :
public PVRecord public PVRecord
{ {
public: public:

View File

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

View File

@@ -23,14 +23,14 @@
#include <epicsEvent.h> #include <epicsEvent.h>
#include <epicsThread.h> #include <epicsThread.h>
#include <epicsExport.h>
#include <pv/standardField.h> #include <pv/standardField.h>
#include <pv/standardPVField.h> #include <pv/standardPVField.h>
#include <pv/pvData.h> #include <pv/pvData.h>
#include <pv/pvAccess.h> #include <pv/pvAccess.h>
#include "powerSupply.h" #include "powerSupply.h"
#include <epicsExport.h>
using namespace std; using namespace std;
using std::tr1::static_pointer_cast; using std::tr1::static_pointer_cast;
using namespace epics::pvData; using namespace epics::pvData;

View File

@@ -236,21 +236,21 @@ static void scalarTest()
valueNameRecord = request = "value"; valueNameRecord = request = "value";
CreateRequest::shared_pointer createRequest = CreateRequest::create(); CreateRequest::shared_pointer createRequest = CreateRequest::create();
pvRequest = createRequest->createRequest(request); pvRequest = createRequest->createRequest(request);
cout << "request " << request << endl << "pvRequest" << pvRequest->dumpValue(cout) << endl ; cout << "request " << request << endl << "pvRequest" << *pvRequest << endl ;
pvCopy = PVCopy::create(pvRecord->getPVRecordStructure()->getPVStructure(),pvRequest,""); pvCopy = PVCopy::create(pvRecord->getPVRecordStructure()->getPVStructure(),pvRequest,"");
valueNameCopy = "value"; valueNameCopy = "value";
testPVScalar(valueNameRecord,valueNameCopy,pvRecord,pvCopy); testPVScalar(valueNameRecord,valueNameCopy,pvRecord,pvCopy);
request = ""; request = "";
valueNameRecord = "value"; valueNameRecord = "value";
pvRequest = createRequest->createRequest(request); pvRequest = createRequest->createRequest(request);
cout << "request " << request << endl << "pvRequest" << pvRequest->dumpValue(cout) << endl ; cout << "request " << request << endl << "pvRequest" << *pvRequest << endl ;
pvCopy = PVCopy::create(pvRecord->getPVRecordStructure()->getPVStructure(),pvRequest,""); pvCopy = PVCopy::create(pvRecord->getPVRecordStructure()->getPVStructure(),pvRequest,"");
valueNameCopy = "value"; valueNameCopy = "value";
testPVScalar(valueNameRecord,valueNameCopy,pvRecord,pvCopy); testPVScalar(valueNameRecord,valueNameCopy,pvRecord,pvCopy);
request = "alarm,timeStamp,value"; request = "alarm,timeStamp,value";
valueNameRecord = "value"; valueNameRecord = "value";
pvRequest = createRequest->createRequest(request); pvRequest = createRequest->createRequest(request);
cout << "request " << request << endl << "pvRequest" << pvRequest->dumpValue(cout) << endl ; cout << "request " << request << endl << "pvRequest" << *pvRequest << endl ;
pvCopy = PVCopy::create(pvRecord->getPVRecordStructure()->getPVStructure(),pvRequest,""); pvCopy = PVCopy::create(pvRecord->getPVRecordStructure()->getPVStructure(),pvRequest,"");
valueNameCopy = "value"; valueNameCopy = "value";
testPVScalar(valueNameRecord,valueNameCopy,pvRecord,pvCopy); testPVScalar(valueNameRecord,valueNameCopy,pvRecord,pvCopy);
@@ -273,21 +273,21 @@ static void arrayTest()
pvRecord = createScalarArray("doubleArrayRecord",pvDouble,"alarm,timeStamp"); pvRecord = createScalarArray("doubleArrayRecord",pvDouble,"alarm,timeStamp");
valueNameRecord = request = "value"; valueNameRecord = request = "value";
pvRequest = createRequest->createRequest(request); pvRequest = createRequest->createRequest(request);
cout << "request " << request << endl << "pvRequest" << pvRequest->dumpValue(cout) << endl ; cout << "request " << request << endl << "pvRequest" << *pvRequest << endl ;
pvCopy = PVCopy::create(pvRecord->getPVRecordStructure()->getPVStructure(),pvRequest,""); pvCopy = PVCopy::create(pvRecord->getPVRecordStructure()->getPVStructure(),pvRequest,"");
valueNameCopy = "value"; valueNameCopy = "value";
testPVScalarArray(pvDouble,valueNameRecord,valueNameCopy,pvRecord,pvCopy); testPVScalarArray(pvDouble,valueNameRecord,valueNameCopy,pvRecord,pvCopy);
request = ""; request = "";
valueNameRecord = "value"; valueNameRecord = "value";
pvRequest = createRequest->createRequest(request); pvRequest = createRequest->createRequest(request);
cout << "request " << request << endl << "pvRequest" << pvRequest->dumpValue(cout) << endl ; cout << "request " << request << endl << "pvRequest" << *pvRequest << endl ;
pvCopy = PVCopy::create(pvRecord->getPVRecordStructure()->getPVStructure(),pvRequest,""); pvCopy = PVCopy::create(pvRecord->getPVRecordStructure()->getPVStructure(),pvRequest,"");
valueNameCopy = "value"; valueNameCopy = "value";
testPVScalarArray(pvDouble,valueNameRecord,valueNameCopy,pvRecord,pvCopy); testPVScalarArray(pvDouble,valueNameRecord,valueNameCopy,pvRecord,pvCopy);
request = "alarm,timeStamp,value"; request = "alarm,timeStamp,value";
valueNameRecord = "value"; valueNameRecord = "value";
pvRequest = createRequest->createRequest(request); pvRequest = createRequest->createRequest(request);
cout << "request " << request << endl << "pvRequest" << pvRequest->dumpValue(cout) << endl ; cout << "request " << request << endl << "pvRequest" << *pvRequest << endl ;
pvCopy = PVCopy::create(pvRecord->getPVRecordStructure()->getPVStructure(),pvRequest,""); pvCopy = PVCopy::create(pvRecord->getPVRecordStructure()->getPVStructure(),pvRequest,"");
valueNameCopy = "value"; valueNameCopy = "value";
testPVScalarArray(pvDouble,valueNameRecord,valueNameCopy,pvRecord,pvCopy); testPVScalarArray(pvDouble,valueNameRecord,valueNameCopy,pvRecord,pvCopy);
@@ -311,28 +311,28 @@ static void powerSupplyTest()
pvRecord = PowerSupply::create("powerSupply",pv); pvRecord = PowerSupply::create("powerSupply",pv);
valueNameRecord = request = "power.value"; valueNameRecord = request = "power.value";
pvRequest = createRequest->createRequest(request); pvRequest = createRequest->createRequest(request);
cout << "request " << request << endl << "pvRequest" << pvRequest->dumpValue(cout) << endl ; cout << "request " << request << endl << "pvRequest" << *pvRequest << endl ;
pvCopy = PVCopy::create(pvRecord->getPVRecordStructure()->getPVStructure(),pvRequest,""); pvCopy = PVCopy::create(pvRecord->getPVRecordStructure()->getPVStructure(),pvRequest,"");
valueNameCopy = "power.value"; valueNameCopy = "power.value";
testPVScalar(valueNameRecord,valueNameCopy,pvRecord,pvCopy); testPVScalar(valueNameRecord,valueNameCopy,pvRecord,pvCopy);
request = ""; request = "";
valueNameRecord = "power.value"; valueNameRecord = "power.value";
pvRequest = createRequest->createRequest(request); pvRequest = createRequest->createRequest(request);
cout << "request " << request << endl << "pvRequest" << pvRequest->dumpValue(cout) << endl ; cout << "request " << request << endl << "pvRequest" << *pvRequest << endl ;
pvCopy = PVCopy::create(pvRecord->getPVRecordStructure()->getPVStructure(),pvRequest,""); pvCopy = PVCopy::create(pvRecord->getPVRecordStructure()->getPVStructure(),pvRequest,"");
valueNameCopy = "power.value"; valueNameCopy = "power.value";
testPVScalar(valueNameRecord,valueNameCopy,pvRecord,pvCopy); testPVScalar(valueNameRecord,valueNameCopy,pvRecord,pvCopy);
request = "alarm,timeStamp,voltage.value,power.value,current.value"; request = "alarm,timeStamp,voltage.value,power.value,current.value";
valueNameRecord = "power.value"; valueNameRecord = "power.value";
pvRequest = createRequest->createRequest(request); pvRequest = createRequest->createRequest(request);
cout << "request " << request << endl << "pvRequest" << pvRequest->dumpValue(cout) << endl ; cout << "request " << request << endl << "pvRequest" << *pvRequest << endl ;
pvCopy = PVCopy::create(pvRecord->getPVRecordStructure()->getPVStructure(),pvRequest,""); pvCopy = PVCopy::create(pvRecord->getPVRecordStructure()->getPVStructure(),pvRequest,"");
valueNameCopy = "power.value"; valueNameCopy = "power.value";
testPVScalar(valueNameRecord,valueNameCopy,pvRecord,pvCopy); testPVScalar(valueNameRecord,valueNameCopy,pvRecord,pvCopy);
request = "alarm,timeStamp,voltage{value,alarm},power{value,alarm,display},current.value"; request = "alarm,timeStamp,voltage{value,alarm},power{value,alarm,display},current.value";
valueNameRecord = "power.value"; valueNameRecord = "power.value";
pvRequest = createRequest->createRequest(request); pvRequest = createRequest->createRequest(request);
cout << "request " << request << endl << "pvRequest" << pvRequest->dumpValue(cout) << endl ; cout << "request " << request << endl << "pvRequest" << *pvRequest << endl ;
pvCopy = PVCopy::create(pvRecord->getPVRecordStructure()->getPVStructure(),pvRequest,""); pvCopy = PVCopy::create(pvRecord->getPVRecordStructure()->getPVStructure(),pvRequest,"");
valueNameCopy = "power.value"; valueNameCopy = "power.value";
testPVScalar(valueNameRecord,valueNameCopy,pvRecord,pvCopy); testPVScalar(valueNameRecord,valueNameCopy,pvRecord,pvCopy);