Skip to content

Commit 8c31857

Browse files
committed
switch from pvDatabase to SharedPV
1 parent a478483 commit 8c31857

File tree

2 files changed

+81
-69
lines changed

2 files changed

+81
-69
lines changed

ADApp/pluginSrc/NDPluginPva.cpp

+80-69
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,10 @@
22
#include <string.h>
33
#include <stdio.h>
44

5-
#include <pv/pvDatabase.h>
5+
#include <pv/pvAccess.h>
6+
#include <pva/server.h>
7+
#include <pva/sharedstate.h>
68
#include <pv/nt.h>
7-
#include <pv/channelProviderLocal.h>
89

910
#include <iocsh.h>
1011

@@ -16,74 +17,85 @@
1617

1718
static const char *driverName="NDPluginPva";
1819

19-
using namespace epics;
20-
using namespace epics::pvData;
21-
using namespace epics::pvAccess;
22-
using namespace epics::pvDatabase;
23-
using namespace epics::nt;
24-
using namespace std;
25-
26-
class NDPLUGIN_API NTNDArrayRecord :
27-
public PVRecord
28-
{
29-
30-
private:
31-
NTNDArrayRecord(string const & name, PVStructurePtr const & pvStructure)
32-
:PVRecord(name, pvStructure) {}
33-
34-
NTNDArrayPtr m_ntndArray;
35-
NTNDArrayConverterPtr m_converter;
36-
37-
public:
38-
POINTER_DEFINITIONS(NTNDArrayRecord);
39-
40-
virtual ~NTNDArrayRecord () {}
41-
static NTNDArrayRecordPtr create (string const & name);
42-
virtual bool init ();
43-
virtual void process () {}
44-
void update (NDArray *pArray);
20+
namespace pvd = epics::pvData;
21+
namespace pva = epics::pvAccess;
22+
namespace nt = epics::nt;
23+
24+
namespace {
25+
/* pvDatabase compatibility
26+
* Sends all fields which are assigned by NTNDArrayConverter,
27+
* regardless of whether they change.
28+
*/
29+
struct BitMarker : public pvd::PostHandler {
30+
const pvd::PVFieldPtr fld;
31+
const pvd::BitSetPtr mask;
32+
33+
BitMarker(const pvd::PVFieldPtr& fld,
34+
const pvd::BitSetPtr& mask)
35+
:fld(fld)
36+
,mask(mask)
37+
{}
38+
virtual ~BitMarker() {}
39+
40+
virtual void postPut() OVERRIDE FINAL
41+
{
42+
mask->set(fld->getFieldOffset());
43+
}
4544
};
46-
47-
NTNDArrayRecordPtr NTNDArrayRecord::create (string const & name)
48-
{
49-
NTNDArrayBuilderPtr builder = NTNDArray::createBuilder();
50-
builder->addDescriptor()->addTimeStamp()->addAlarm()->addDisplay();
51-
52-
NTNDArrayRecordPtr pvRecord(new NTNDArrayRecord(name,
53-
builder->createPVStructure()));
54-
55-
if(!pvRecord->init())
56-
pvRecord.reset();
57-
58-
return pvRecord;
59-
}
60-
61-
bool NTNDArrayRecord::init ()
62-
{
63-
initPVRecord();
64-
m_ntndArray = NTNDArray::wrap(getPVStructure());
65-
m_converter.reset(new NTNDArrayConverter(m_ntndArray));
66-
return true;
6745
}
6846

69-
void NTNDArrayRecord::update(NDArray *pArray)
47+
class NTNDArrayRecord
7048
{
71-
lock();
72-
73-
try
49+
public:
50+
pvas::StaticProvider provider;
51+
pvas::SharedPV::shared_pointer pv;
52+
53+
const pvd::PVStructurePtr current;
54+
// wraps 'current'
55+
const nt::NTNDArrayPtr m_ntndArray;
56+
NTNDArrayConverter m_converter;
57+
58+
pvd::BitSetPtr changes;
59+
60+
NTNDArrayRecord(const std::string& name)
61+
:provider(pvas::StaticProvider(name))
62+
,current(nt::NTNDArray::createBuilder()
63+
->addDescriptor()->addTimeStamp()->addAlarm()->addDisplay()
64+
->createPVStructure())
65+
,m_ntndArray(nt::NTNDArray::wrap(current))
66+
,m_converter(m_ntndArray)
67+
,changes(new pvd::BitSet(current->getNumberFields()))
7468
{
75-
beginGroupPut();
76-
m_converter->fromArray(pArray);
77-
endGroupPut();
69+
pvas::SharedPV::Config pv_conf;
70+
// pvDatabase compatibility mode for pvRequest handling
71+
pv_conf.mapperMode = pvd::PVRequestMapper::Slice;
72+
73+
pv = pvas::SharedPV::buildReadOnly(&pv_conf);
74+
pv->open(*current);
75+
provider.add(name, pv);
76+
77+
{
78+
const pvd::PVFieldPtrArray& fields(current->getPVFields());
79+
for(size_t i=0, N=fields.size(); i<N; i++) {
80+
std::tr1::shared_ptr<BitMarker> temp(new BitMarker(fields[i], changes));
81+
fields[i]->setPostHandler(temp);
82+
}
83+
}
7884
}
79-
catch(...)
85+
86+
void update(NDArray *pArray)
8087
{
81-
endGroupPut();
82-
unlock();
83-
throw;
88+
changes->clear();
89+
// through several levels of indirection, updates this->current
90+
// and through several more, updates this->changes
91+
m_converter.fromArray(pArray);
92+
93+
// SharedPV::post() makes a lightweight copy of *current,
94+
// so we may safely continue to change it.
95+
96+
pv->post(*current, *changes);
8497
}
85-
unlock();
86-
}
98+
};
8799

88100
/** Callback function that is called by the NDArray driver with new NDArray
89101
* data.
@@ -155,12 +167,12 @@ NDPluginPva::NDPluginPva(const char *portName, int queueSize,
155167
: NDPluginDriver(portName, queueSize, blockingCallbacks,
156168
NDArrayPort, NDArrayAddr, 1, maxBuffers, maxMemory, 0, 0,
157169
0, 1, priority, stackSize, 1, true),
158-
m_record(NTNDArrayRecord::create(pvName))
170+
m_record(new NTNDArrayRecord(pvName))
159171
{
160172
createParam(NDPluginPvaPvNameString, asynParamOctet, &NDPluginPvaPvName);
161173

162174
if(!m_record.get())
163-
throw runtime_error("failed to create NTNDArrayRecord");
175+
throw std::runtime_error("failed to create NTNDArrayRecord");
164176

165177
/* Set the plugin type string */
166178
setStringParam(NDPluginDriverPluginType, "NDPluginPva");
@@ -171,13 +183,12 @@ NDPluginPva::NDPluginPva(const char *portName, int queueSize,
171183
/* Try to connect to the NDArray port */
172184
connectToArrayPort();
173185

174-
PVDatabasePtr master = PVDatabase::getMaster();
175-
ChannelProviderLocalPtr channelProvider = getChannelProviderLocal();
176-
177-
if(!master->addRecord(m_record))
178-
throw runtime_error("couldn't add record to master database");
186+
pva::ChannelProviderRegistry::servers()
187+
->addSingleton(m_record->provider.provider());
179188
}
180189

190+
NDPluginPva::~NDPluginPva() {}
191+
181192
/* Configuration routine. Called directly, or from the iocsh function */
182193
extern "C" int NDPvaConfigure(const char *portName, int queueSize,
183194
int blockingCallbacks, const char *NDArrayPort, int NDArrayAddr,

ADApp/pluginSrc/NDPluginPva.h

+1
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ class NDPLUGIN_API NDPluginPva : public NDPluginDriver,
2323
NDPluginPva(const char *portName, int queueSize, int blockingCallbacks,
2424
const char *NDArrayPort, int NDArrayAddr, const char *pvName,
2525
int maxBuffers, size_t maxMemory, int priority, int stackSize);
26+
virtual ~NDPluginPva();
2627

2728
/* These methods override the virtual methods in the base class */
2829
void processCallbacks(NDArray *pArray);

0 commit comments

Comments
 (0)