more ownership

This commit is contained in:
Michael Davidsaver
2017-07-11 17:33:52 +02:00
parent c1d2db0b2f
commit 9b433a54f6
7 changed files with 36 additions and 40 deletions

View File

@ -90,7 +90,7 @@ private:
buffer_t inuse, empty;
public:
BaseMonitor(const requester_t::shared_pointer& requester,
BaseMonitor(const requester_t::weak_pointer& requester,
const epics::pvData::PVStructure::shared_pointer& pvReq)
:requester(requester)
,inoverflow(false)

View File

@ -99,11 +99,7 @@ ChannelCacheEntry::CRequester::channelStateChange(pva::Channel::shared_pointer c
FOREACH(it, end, interested)
{
GWChannel *chan = it->get();
pva::ChannelRequester::shared_pointer req;
{
Guard G(chan->entry->mutex());
req = chan->requester;
}
pva::ChannelRequester::shared_pointer req(chan->requester.lock());
if(req)
req->channelStateChange(*it, connectionState);
}

View File

@ -16,7 +16,7 @@ size_t GWChannel::num_instances;
GWChannel::GWChannel(const ChannelCacheEntry::shared_pointer& e,
const epics::pvAccess::ChannelProvider::weak_pointer& srvprov,
const pva::ChannelRequester::shared_pointer& r,
const epics::pvAccess::ChannelRequester::weak_pointer &r,
const std::string& addr)
:entry(e)
,requester(r)
@ -45,18 +45,12 @@ GWChannel::message(std::string const & message, pvd::MessageType messageType)
void
GWChannel::destroy()
{
epics::pvAccess::ChannelRequester::shared_pointer req;
{
Guard G(entry->mutex());
req.swap(requester);
}
}
{}
std::tr1::shared_ptr<pva::ChannelProvider>
GWChannel::getProvider()
{
return server_provder.lock();
return pva::ChannelProvider::shared_pointer(server_provder);
}
std::string
@ -81,7 +75,7 @@ GWChannel::getChannelName()
std::tr1::shared_ptr<pva::ChannelRequester>
GWChannel::getChannelRequester()
{
return requester;
return pva::ChannelRequester::shared_pointer(requester);
}
@ -124,6 +118,7 @@ GWChannel::createChannelPut(
pva::ChannelPutRequester::shared_pointer const & channelPutRequester,
pvd::PVStructure::shared_pointer const & pvRequest)
{
//TODO: allow ChannelPut::get()
if(!p2pReadOnly)
return entry->channel->createChannelPut(channelPutRequester, pvRequest);
else
@ -194,13 +189,7 @@ GWChannel::createMonitor(
{
UnGuard U(G);
// Create upstream monitor
// This would create a strong ref. loop between ent and ent->mon.
// Instead we get clever and pass a "fake" strong ref.
// and ensure that ~MonitorCacheEntry destroy()s the client Monitor
MonitorCacheEntry::shared_pointer fakereal(ment.get(), noclean());
M = entry->channel->createMonitor(fakereal, pvRequest);
M = entry->channel->createMonitor(ment, pvRequest);
}
ment->mon = M;

View File

@ -12,13 +12,13 @@ struct GWChannel : public epics::pvAccess::Channel
weak_pointer weakref;
const ChannelCacheEntry::shared_pointer entry;
epics::pvAccess::ChannelRequester::shared_pointer requester;
const requester_type::weak_pointer requester;
const std::string address; // address of client on GW server side
const epics::pvAccess::ChannelProvider::weak_pointer server_provder;
GWChannel(const ChannelCacheEntry::shared_pointer& e,
const epics::pvAccess::ChannelProvider::weak_pointer& srvprov,
const epics::pvAccess::ChannelRequester::shared_pointer&,
const requester_type::weak_pointer&,
const std::string& addr);
virtual ~GWChannel();

View File

@ -153,7 +153,7 @@ PDBGroupChannel::createMonitor(
PDBGroupGet::PDBGroupGet(const PDBGroupChannel::shared_pointer &channel,
const pva::ChannelGetRequester::shared_pointer &requester,
const requester_type::weak_pointer &requester,
const pvd::PVStructure::shared_pointer &pvReq)
:channel(channel)
,requester(requester)
@ -166,7 +166,9 @@ PDBGroupGet::PDBGroupGet(const PDBGroupChannel::shared_pointer &channel,
try {
atomic = atomicopt->getAs<pvd::boolean>();
}catch(std::exception& e){
requester->message("Unable to parse 'atomic' request option. Default is false.", pvd::warningMessage);
requester_type::shared_pointer req(requester.lock());
if(req)
req->message("Unable to parse 'atomic' request option. Default is false.", pvd::warningMessage);
}
}
pvf->getSubFieldT<pvd::PVBoolean>("record._options.atomic")->put(atomic);
@ -205,12 +207,14 @@ void PDBGroupGet::get()
//TODO: report unused fields as changed?
changed->clear();
changed->set(0);
requester->getDone(pvd::Status(), shared_from_this(), pvf, changed);
requester_type::shared_pointer req(requester.lock());
if(req)
req->getDone(pvd::Status(), shared_from_this(), pvf, changed);
}
PDBGroupPut::PDBGroupPut(const PDBGroupChannel::shared_pointer& channel,
const pva::ChannelPutRequester::shared_pointer& requester,
const requester_type::weak_pointer& requester,
const epics::pvData::PVStructure::shared_pointer &pvReq)
:channel(channel)
,requester(requester)
@ -223,7 +227,9 @@ PDBGroupPut::PDBGroupPut(const PDBGroupChannel::shared_pointer& channel,
try {
atomic = atomicopt->getAs<pvd::boolean>();
}catch(std::exception& e){
requester->message("Unable to parse 'atomic' request option. Default is false.", pvd::warningMessage);
requester_type::shared_pointer req(requester.lock());
if(req)
req->message("Unable to parse 'atomic' request option. Default is false.", pvd::warningMessage);
}
}
pvf->getSubFieldT<pvd::PVBoolean>("record._options.atomic")->put(atomic);
@ -270,7 +276,9 @@ void PDBGroupPut::put(pvd::PVStructure::shared_pointer const & value,
}
}
requester->putDone(pvd::Status(), shared_from_this());
requester_type::shared_pointer req(requester.lock());
if(req)
req->putDone(pvd::Status(), shared_from_this());
}
void PDBGroupPut::get()
@ -295,11 +303,14 @@ void PDBGroupPut::get()
//TODO: report unused fields as changed?
changed->clear();
changed->set(0);
requester->getDone(pvd::Status(), shared_from_this(), pvf, changed);
requester_type::shared_pointer req(requester.lock());
if(req)
req->getDone(pvd::Status(), shared_from_this(), pvf, changed);
}
PDBGroupMonitor::PDBGroupMonitor(const PDBGroupPV::shared_pointer& pv,
const requester_t::shared_pointer& requester,
const epics::pvAccess::MonitorRequester::weak_pointer &requester,
const pvd::PVStructure::shared_pointer& pvReq)
:BaseMonitor(requester, pvReq)
,pv(pv)

View File

@ -96,7 +96,7 @@ struct PDBGroupGet : public epics::pvAccess::ChannelGet,
public std::tr1::enable_shared_from_this<PDBGroupGet>
{
PDBGroupChannel::shared_pointer channel;
epics::pvAccess::ChannelGetRequester::shared_pointer requester;
requester_type::weak_pointer requester;
bool atomic;
epics::pvData::BitSetPtr changed;
@ -104,7 +104,7 @@ struct PDBGroupGet : public epics::pvAccess::ChannelGet,
std::vector<std::tr1::shared_ptr<PVIF> > pvif;
PDBGroupGet(const PDBGroupChannel::shared_pointer& channel,
const epics::pvAccess::ChannelGetRequester::shared_pointer& requester,
const requester_type::weak_pointer &requester,
const epics::pvData::PVStructure::shared_pointer& pvReq);
virtual ~PDBGroupGet() {}
@ -122,7 +122,7 @@ struct PDBGroupPut : public epics::pvAccess::ChannelPut,
{
typedef epics::pvAccess::ChannelPutRequester requester_t;
PDBGroupChannel::shared_pointer channel;
requester_t::shared_pointer requester;
requester_type::weak_pointer requester;
bool atomic;
epics::pvData::BitSetPtr changed;
@ -130,7 +130,7 @@ struct PDBGroupPut : public epics::pvAccess::ChannelPut,
std::vector<std::tr1::shared_ptr<PVIF> > pvif;
PDBGroupPut(const PDBGroupChannel::shared_pointer &channel,
const epics::pvAccess::ChannelPutRequester::shared_pointer &requester,
const requester_type::weak_pointer &requester,
const epics::pvData::PVStructure::shared_pointer& pvReq);
virtual ~PDBGroupPut() {}
@ -155,7 +155,7 @@ struct PDBGroupMonitor : public BaseMonitor
bool atomic;
PDBGroupMonitor(const PDBGroupPV::shared_pointer& pv,
const requester_t::shared_pointer& requester,
const requester_type::weak_pointer& requester,
const epics::pvData::PVStructure::shared_pointer& pvReq);
virtual ~PDBGroupMonitor() {destroy();}

View File

@ -79,11 +79,11 @@ struct TestMonitor {
pvd::Monitor::shared_pointer mon(client->createMonitor(mreq, makeRequest(2)));
if(!mon) testAbort("Failed to create monitor");
testOk1(mreq->eventCnt==0);
testEqual(mreq->eventCnt, 0u);
testOk1(mon->start().isSuccess());
upstream->dispatch(); // trigger monitorEvent() from upstream to gateway
testOk1(mreq->eventCnt==1);
testEqual(mreq->eventCnt, 1u);
pva::MonitorElementPtr elem(mon->poll());
testOk1(!!elem.get());
if(!!elem.get()) testEqual(toString(*elem->changedBitSet), "{0}");