working single put()

This commit is contained in:
Michael Davidsaver
2016-03-02 19:22:25 -05:00
parent b61fdbecd1
commit e5b886b59d
4 changed files with 166 additions and 1 deletions

View File

@@ -108,9 +108,11 @@ PDBSinglePut::PDBSinglePut(PDBSingleChannel::shared_pointer channel,
void PDBSinglePut::put(pvd::PVStructure::shared_pointer const & value,
pvd::BitSet::shared_pointer const & changed)
{
// assume value may be a different struct each time
std::auto_ptr<PVIF> putpvif(PVIF::attach(channel->pv->chan, value));
{
DBScanLocker L(channel->pv->chan);
pvif->get(*changed);
putpvif->get(*changed);
}
requester->putDone(pvd::Status(), shared_from_this());
}

View File

@@ -28,6 +28,52 @@ void testFieldEqual(const pvd::PVStructurePtr& val, const char *name, typename P
}
}
struct PVPut
{
TestChannelRequester::shared_pointer chreq;
pva::Channel::shared_pointer chan;
TestChannelFieldRequester::shared_pointer fldreq;
TestChannelPutRequester::shared_pointer putreq;
pva::ChannelPut::shared_pointer chput;
pvd::PVStructurePtr putval;
pvd::BitSetPtr putchanged;
PVPut(const pva::ChannelProvider::shared_pointer& prov, const char *name)
:chreq(new TestChannelRequester())
,chan(prov->createChannel(name, chreq))
,fldreq(new TestChannelFieldRequester())
,putreq(new TestChannelPutRequester())
{
if(!chan || !chan->isConnected())
throw std::runtime_error("channel not connected");
chan->getField(fldreq, "");
if(!fldreq->done || !fldreq->fielddesc || fldreq->fielddesc->getType()!=pvd::structure)
throw std::runtime_error("Failed to get fielddesc");
putval = pvd::getPVDataCreate()->createPVStructure(std::tr1::static_pointer_cast<const pvd::Structure>(fldreq->fielddesc));
chput = chan->createChannelPut(putreq, putval);
if(!chput)
throw std::runtime_error("Failed to create put op");
putchanged.reset(new pvd::BitSet());
}
~PVPut() {
chput->destroy();
chan->destroy();
}
void put() {
putreq->donePut = false;
chput->put(putval, putchanged);
if(!putreq->donePut)
throw std::runtime_error("Put operation fails");
}
pvd::PVStructurePtr get() {
putreq->doneGet = false;
chput->get();
if(!putreq->doneGet || !putreq->value)
throw std::runtime_error("Get operation fails");
return putreq->value;
}
};
pvd::PVStructurePtr pvget(const pva::ChannelProvider::shared_pointer& prov, const char *name,
bool atomic)
{
@@ -108,6 +154,27 @@ void testGroupGet(const PDBProvider::shared_pointer& prov)
testFieldEqual<pvd::PVInt>(value, "fld4.value", 40);
}
void testSinglePut(const PDBProvider::shared_pointer& prov)
{
testDiag("test single put");
testdbPutFieldOk("rec1", DBR_DOUBLE, 1.0);
PVPut put(prov, "rec1.VAL");
pvd::PVDoublePtr val(put.putval->getSubFieldT<pvd::PVDouble>("value"));
val->put(2.0);
put.putchanged->clear();
put.put();
testdbGetFieldEqual("rec1", DBR_DOUBLE, 1.0);
put.putchanged->set(val->getFieldOffset());
put.put();
testdbGetFieldEqual("rec1", DBR_DOUBLE, 2.0);
}
} // namespace
extern "C"
@@ -129,6 +196,8 @@ MAIN(testpdb)
PDBProvider::shared_pointer prov(new PDBProvider());
testSingleGet(prov);
testGroupGet(prov);
testSinglePut(prov);
}
testDiag("check to see that all dbChannel are closed before IOC shuts down");
testEqual(epics::atomic::get(PDBGroupPV::ninstances), 0u);

View File

@@ -102,6 +102,47 @@ void TestChannelGetRequester::getDone(const epics::pvData::Status &status,
done = true;
}
TestChannelPutRequester::TestChannelPutRequester()
:connected(false)
,doneGet(false)
,donePut(false)
{}
TestChannelPutRequester::~TestChannelPutRequester() {}
void TestChannelPutRequester::channelPutConnect(
const epics::pvData::Status& status,
epics::pvAccess::ChannelPut::shared_pointer const & channelPut,
epics::pvData::Structure::const_shared_pointer const & structure)
{
statusConnect = status;
put = channelPut;
fielddesc = structure;
connected = true;
}
void TestChannelPutRequester::putDone(
const epics::pvData::Status& status,
epics::pvAccess::ChannelPut::shared_pointer const & channelPut)
{
statusPut = status;
put = channelPut;
donePut = true;
}
void TestChannelPutRequester::getDone(
const epics::pvData::Status& status,
epics::pvAccess::ChannelPut::shared_pointer const & channelPut,
epics::pvData::PVStructure::shared_pointer const & pvStructure,
epics::pvData::BitSet::shared_pointer const & bitSet)
{
statusGet = status;
put = channelPut;
value = pvStructure;
changed = bitSet;
doneGet = true;
}
static size_t countTestChannelMonitorRequester;
TestChannelMonitorRequester::TestChannelMonitorRequester()

View File

@@ -98,6 +98,28 @@ struct TestChannelRequester : public epics::pvAccess::ChannelRequester
bool waitForConnect();
};
struct TestChannelFieldRequester : public epics::pvAccess::GetFieldRequester
{
POINTER_DEFINITIONS(TestChannelFieldRequester);
DUMBREQUESTER(TestChannelFieldRequester)
bool done;
epics::pvData::Status status;
epics::pvData::FieldConstPtr fielddesc;
TestChannelFieldRequester() :done(false) {}
virtual ~TestChannelFieldRequester() {}
virtual void getDone(
const epics::pvData::Status& status,
epics::pvData::FieldConstPtr const & field)
{
this->status = status;
fielddesc = field;
done = true;
}
};
struct TestChannelGetRequester : public epics::pvAccess::ChannelGetRequester
{
POINTER_DEFINITIONS(TestChannelGetRequester);
@@ -125,6 +147,37 @@ struct TestChannelGetRequester : public epics::pvAccess::ChannelGetRequester
epics::pvData::BitSet::shared_pointer const & bitSet);
};
struct TestChannelPutRequester : public epics::pvAccess::ChannelPutRequester
{
POINTER_DEFINITIONS(TestChannelPutRequester);
DUMBREQUESTER(TestChannelPutRequester)
bool connected, doneGet, donePut;
epics::pvData::Status statusConnect, statusPut, statusGet;
epics::pvAccess::ChannelPut::shared_pointer put;
epics::pvData::Structure::const_shared_pointer fielddesc;
epics::pvData::PVStructure::shared_pointer value;
epics::pvData::BitSet::shared_pointer changed;
TestChannelPutRequester();
virtual ~TestChannelPutRequester();
virtual void channelPutConnect(
const epics::pvData::Status& status,
epics::pvAccess::ChannelPut::shared_pointer const & channelPut,
epics::pvData::Structure::const_shared_pointer const & structure);
virtual void putDone(
const epics::pvData::Status& status,
epics::pvAccess::ChannelPut::shared_pointer const & channelPut);
virtual void getDone(
const epics::pvData::Status& status,
epics::pvAccess::ChannelPut::shared_pointer const & channelPut,
epics::pvData::PVStructure::shared_pointer const & pvStructure,
epics::pvData::BitSet::shared_pointer const & bitSet);
};
struct TestChannelMonitorRequester : public epics::pvData::MonitorRequester
{
POINTER_DEFINITIONS(TestChannelMonitorRequester);