From 1756d70f4dc81b1afae87e35e6c14f0e61632881 Mon Sep 17 00:00:00 2001 From: Michael Davidsaver Date: Tue, 11 Jul 2017 16:00:44 +0200 Subject: [PATCH] adapt to new ownership rules --- common/pvahelper.h | 132 ++++++++------------------------------ pdbApp/pdb.cpp | 2 +- pdbApp/pdb.h | 3 +- pdbApp/pdbsingle.cpp | 59 +++++++++-------- pdbApp/pdbsingle.h | 14 ++-- testApp/check_consist.cpp | 2 +- 6 files changed, 70 insertions(+), 142 deletions(-) diff --git a/common/pvahelper.h b/common/pvahelper.h index 7aac495..247ec71 100644 --- a/common/pvahelper.h +++ b/common/pvahelper.h @@ -19,7 +19,7 @@ bool getS(const epics::pvData::PVStructurePtr& S, const char *name, T& val) struct BaseChannel : public epics::pvAccess::Channel { BaseChannel(const std::string& name, - const std::tr1::shared_ptr& prov, + const std::tr1::weak_ptr& prov, const epics::pvAccess::ChannelRequester::shared_pointer& req, const epics::pvData::StructureConstPtr& dtype ) @@ -27,110 +27,33 @@ struct BaseChannel : public epics::pvAccess::Channel {} virtual ~BaseChannel() {} - epicsMutex lock; + mutable epicsMutex lock; typedef epicsGuard guard_t; + const std::string pvname; - std::tr1::shared_ptr provider; - typedef epics::pvAccess::ChannelRequester::shared_pointer requester_t; - requester_t requester; + const epics::pvAccess::ChannelProvider::weak_pointer provider; + const requester_type::weak_pointer requester; const epics::pvData::StructureConstPtr fielddesc; // assume Requester methods not called after destory() - virtual std::string getRequesterName() { guard_t G(lock); return requester->getRequesterName(); } + virtual std::string getRequesterName() OVERRIDE + { return getChannelRequester()->getRequesterName(); } - virtual void destroy() { - std::tr1::shared_ptr prov; - requester_t req; - { - guard_t G(lock); - provider.swap(prov); - requester.swap(req); - } - } + virtual void destroy() OVERRIDE FINAL {} - virtual std::tr1::shared_ptr getProvider() { guard_t G(lock); return provider; } - virtual std::string getRemoteAddress() { guard_t G(lock); return requester->getRequesterName(); } - virtual ConnectionState getConnectionState() { return epics::pvAccess::Channel::CONNECTED; } - virtual std::string getChannelName() { return pvname; } - virtual std::tr1::shared_ptr getChannelRequester() { guard_t G(lock); return requester; } - virtual bool isConnected() { return getConnectionState()==epics::pvAccess::Channel::CONNECTED; } + virtual std::tr1::shared_ptr getProvider() OVERRIDE FINAL + { return epics::pvAccess::ChannelProvider::shared_pointer(provider); } + virtual std::string getRemoteAddress() OVERRIDE + { return getRequesterName(); } - virtual void getField(epics::pvAccess::GetFieldRequester::shared_pointer const & requester,std::string const & subField) + virtual std::string getChannelName() OVERRIDE FINAL { return pvname; } + virtual std::tr1::shared_ptr getChannelRequester() OVERRIDE FINAL + { return requester_type::shared_pointer(requester); } + + virtual void getField(epics::pvAccess::GetFieldRequester::shared_pointer const & requester,std::string const & subField) OVERRIDE { requester->getDone(epics::pvData::Status(), fielddesc); } - virtual epics::pvAccess::AccessRights getAccessRights(const epics::pvData::PVField::shared_pointer &pvField) - { return epics::pvAccess::readWrite; } - - virtual epics::pvAccess::ChannelProcess::shared_pointer createChannelProcess( - epics::pvAccess::ChannelProcessRequester::shared_pointer const & requester, - epics::pvData::PVStructure::shared_pointer const & pvRequest) - { - epics::pvAccess::ChannelProcess::shared_pointer ret; - requester->channelProcessConnect(epics::pvData::Status(epics::pvData::Status::STATUSTYPE_FATAL, "Not implemented"), ret); - return ret; - } - - virtual epics::pvAccess::ChannelGet::shared_pointer createChannelGet( - epics::pvAccess::ChannelGetRequester::shared_pointer const & requester, - epics::pvData::PVStructure::shared_pointer const & pvRequest) - { - epics::pvAccess::ChannelGet::shared_pointer ret; - requester->channelGetConnect(epics::pvData::Status(epics::pvData::Status::STATUSTYPE_FATAL, "Not implemented"), - ret, epics::pvData::StructureConstPtr()); - return ret; - } - - virtual epics::pvAccess::ChannelPut::shared_pointer createChannelPut( - epics::pvAccess::ChannelPutRequester::shared_pointer const & requester, - epics::pvData::PVStructure::shared_pointer const & pvRequest) - { - epics::pvAccess::ChannelPut::shared_pointer ret; - requester->channelPutConnect(epics::pvData::Status(epics::pvData::Status::STATUSTYPE_FATAL, "Not implemented"), - ret, epics::pvData::StructureConstPtr()); - return ret; - } - - virtual epics::pvAccess::ChannelPutGet::shared_pointer createChannelPutGet( - epics::pvAccess::ChannelPutGetRequester::shared_pointer const & requester, - epics::pvData::PVStructure::shared_pointer const & pvRequest) - { - epics::pvAccess::ChannelPutGet::shared_pointer ret; - requester->channelPutGetConnect(epics::pvData::Status(epics::pvData::Status::STATUSTYPE_FATAL, "Not implemented"), - ret, epics::pvData::StructureConstPtr(), epics::pvData::StructureConstPtr()); - return ret; - } - - virtual epics::pvAccess::ChannelRPC::shared_pointer createChannelRPC( - epics::pvAccess::ChannelRPCRequester::shared_pointer const & requester, - epics::pvData::PVStructure::shared_pointer const & pvRequest) - { - epics::pvAccess::ChannelRPC::shared_pointer ret; - requester->channelRPCConnect(epics::pvData::Status(epics::pvData::Status::STATUSTYPE_FATAL, "Not implemented"), ret); - return ret; - } - - virtual epics::pvData::Monitor::shared_pointer createMonitor( - epics::pvData::MonitorRequester::shared_pointer const & requester, - epics::pvData::PVStructure::shared_pointer const & pvRequest) - { - epics::pvData::Monitor::shared_pointer ret; - requester->monitorConnect(epics::pvData::Status(epics::pvData::Status::STATUSTYPE_FATAL, "Not implemented"), - ret, epics::pvData::StructureConstPtr()); - return ret; - } - - virtual epics::pvAccess::ChannelArray::shared_pointer createChannelArray( - epics::pvAccess::ChannelArrayRequester::shared_pointer const & requester, - epics::pvData::PVStructure::shared_pointer const & pvRequest) - { - epics::pvAccess::ChannelArray::shared_pointer ret; - requester->channelArrayConnect(epics::pvData::Status(epics::pvData::Status::STATUSTYPE_FATAL, "Not implemented"), - ret, epics::pvData::Array::const_shared_pointer()); - return ret; - } - - virtual void printInfo() { printInfo(std::cout); } - virtual void printInfo(std::ostream& out) { + virtual void printInfo(std::ostream& out) OVERRIDE { out<<"Channel '"< guard_t; private: - requester_t::shared_pointer requester; + const requester_t::weak_pointer requester; epics::pvData::PVStructurePtr complete; epics::pvData::BitSet changed, overflow; @@ -186,13 +109,11 @@ public: epics::pvData::StructureConstPtr dtype(value->getStructure()); epics::pvData::PVDataCreatePtr create(epics::pvData::getPVDataCreate()); BaseMonitor::shared_pointer self(shared_from_this()); - requester_t::shared_pointer req; + requester_t::shared_pointer req(requester.lock()); { guard_t G(lock); assert(!complete); // can't call twice - req = requester; - complete = value; empty.resize(nbuffers); for(size_t i=0; imonitorConnect(sts, self, dtype); + if(req) + req->monitorConnect(sts, self, dtype); } struct no_overflow {}; @@ -218,7 +140,7 @@ public: if(empty.empty()) return false; if(p_postone()) - req = requester; + req = requester.lock(); inoverflow = false; } if(req) req->monitorEvent(shared_from_this()); @@ -240,7 +162,7 @@ public: } else { if(p_postone()) - req = requester; + req = requester.lock(); oflow = inoverflow = false; } } @@ -267,7 +189,7 @@ public: changed |= updated; if(p_postone()) - req = requester; + req = requester.lock(); oflow = inoverflow = false; } } @@ -292,7 +214,7 @@ public: changed |= updated; if(p_postone()) - req = requester; + req = requester.lock(); oflow = inoverflow = false; } } @@ -332,7 +254,6 @@ public: virtual void destroy() { - requester_t::shared_pointer req; bool run; { guard_t G(lock); @@ -340,7 +261,6 @@ public: if(run) { running = false; } - requester.swap(req); } if(run) this->onStop(); diff --git a/pdbApp/pdb.cpp b/pdbApp/pdb.cpp index f97ca80..b3a32f5 100644 --- a/pdbApp/pdb.cpp +++ b/pdbApp/pdb.cpp @@ -313,7 +313,7 @@ struct PDBProcessor size_t PDBProvider::ninstances; -PDBProvider::PDBProvider() +PDBProvider::PDBProvider(const epics::pvAccess::Configuration::shared_pointer &) { PDBProcessor proc; pvd::FieldCreatePtr fcreate(pvd::getFieldCreate()); diff --git a/pdbApp/pdb.h b/pdbApp/pdb.h index 41f3fa7..c0d96f9 100644 --- a/pdbApp/pdb.h +++ b/pdbApp/pdb.h @@ -3,6 +3,7 @@ #include +#include #include #include "weakmap.h" @@ -29,7 +30,7 @@ struct PDBProvider : public epics::pvAccess::ChannelProvider, { POINTER_DEFINITIONS(PDBProvider); - PDBProvider(); + explicit PDBProvider(const epics::pvAccess::Configuration::shared_pointer& =epics::pvAccess::Configuration::shared_pointer()); virtual ~PDBProvider(); virtual void destroy(); virtual std::string getProviderName(); diff --git a/pdbApp/pdbsingle.cpp b/pdbApp/pdbsingle.cpp index 16ae830..823e08f 100644 --- a/pdbApp/pdbsingle.cpp +++ b/pdbApp/pdbsingle.cpp @@ -168,7 +168,9 @@ void commonGet(PVIF *pvif, pvd::BitSet* changed) void PDBSingleGet::get() { commonGet(pvif.get(), changed.get()); - 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); } @@ -257,13 +259,17 @@ void PDBSinglePut::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 PDBSinglePut::get() { commonGet(pvif.get(), changed.get()); - 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); } PDBSingleMonitor::PDBSingleMonitor(const PDBSinglePV::shared_pointer& pv, @@ -276,54 +282,55 @@ PDBSingleMonitor::PDBSingleMonitor(const PDBSinglePV::shared_pointer& pv, void PDBSingleMonitor::destroy() { BaseMonitor::destroy(); - PDBSinglePV::shared_pointer pv; - { - Guard G(lock); - this->pv.swap(pv); - } } void PDBSingleMonitor::onStart() { - guard_t G(pv->lock); + PDBSinglePV::shared_pointer PV(pv.lock()); + if(!PV) return; + guard_t G(PV->lock); - pv->scratch.clear(); - pv->scratch.set(0); - if(pv->interested.empty()) { + PV->scratch.clear(); + PV->scratch.set(0); + if(PV->interested.empty()) { // first subscriber - pv->hadevent_VALUE = false; - pv->hadevent_PROPERTY = false; - db_event_enable(pv->evt_VALUE.subscript); - db_event_enable(pv->evt_PROPERTY.subscript); - db_post_single_event(pv->evt_VALUE.subscript); - db_post_single_event(pv->evt_PROPERTY.subscript); - } else if(pv->hadevent_VALUE && pv->hadevent_PROPERTY) { + PV->hadevent_VALUE = false; + PV->hadevent_PROPERTY = false; + db_event_enable(PV->evt_VALUE.subscript); + db_event_enable(PV->evt_PROPERTY.subscript); + db_post_single_event(PV->evt_VALUE.subscript); + db_post_single_event(PV->evt_PROPERTY.subscript); + } else if(PV->hadevent_VALUE && PV->hadevent_PROPERTY) { // new subscriber and already had initial update post(); } // else new subscriber, but no initial update. so just wait shared_pointer self(std::tr1::static_pointer_cast(shared_from_this())); - pv->interested.insert(self); + PV->interested.insert(self); } void PDBSingleMonitor::onStop() { - guard_t G(pv->lock); + PDBSinglePV::shared_pointer PV(pv.lock()); + if(PV) return; + guard_t G(PV->lock); shared_pointer self(std::tr1::static_pointer_cast(shared_from_this())); - if(pv->interested.erase(self)==0) { + if(PV->interested.erase(self)==0) { fprintf(stderr, "%s: oops\n", __FUNCTION__); } - if(pv->interested.empty()) { + if(PV->interested.empty()) { // last subscriber - db_event_disable(pv->evt_VALUE.subscript); - db_event_disable(pv->evt_PROPERTY.subscript); + db_event_disable(PV->evt_VALUE.subscript); + db_event_disable(PV->evt_PROPERTY.subscript); } } void PDBSingleMonitor::requestUpdate() { - Guard G(pv->lock); + PDBSinglePV::shared_pointer PV(pv.lock()); + if(PV) return; + guard_t G(PV->lock); post(); } diff --git a/pdbApp/pdbsingle.h b/pdbApp/pdbsingle.h index bb8a21d..fb6569e 100644 --- a/pdbApp/pdbsingle.h +++ b/pdbApp/pdbsingle.h @@ -69,15 +69,15 @@ struct PDBSingleChannel : public BaseChannel, virtual epics::pvAccess::ChannelGet::shared_pointer createChannelGet( epics::pvAccess::ChannelGetRequester::shared_pointer const & channelGetRequester, - epics::pvData::PVStructure::shared_pointer const & pvRequest); + epics::pvData::PVStructure::shared_pointer const & pvRequest) OVERRIDE FINAL; virtual epics::pvAccess::ChannelPut::shared_pointer createChannelPut( epics::pvAccess::ChannelPutRequester::shared_pointer const & requester, - epics::pvData::PVStructure::shared_pointer const & pvRequest); + epics::pvData::PVStructure::shared_pointer const & pvRequest) OVERRIDE FINAL; virtual epics::pvData::Monitor::shared_pointer createMonitor( epics::pvData::MonitorRequester::shared_pointer const & requester, - epics::pvData::PVStructure::shared_pointer const & pvRequest); + epics::pvData::PVStructure::shared_pointer const & pvRequest) OVERRIDE FINAL; - virtual void printInfo(std::ostream& out); + virtual void printInfo(std::ostream& out) OVERRIDE FINAL; }; struct PDBSingleGet : public epics::pvAccess::ChannelGet, @@ -85,7 +85,7 @@ struct PDBSingleGet : public epics::pvAccess::ChannelGet, { typedef epics::pvAccess::ChannelGetRequester requester_t; PDBSingleChannel::shared_pointer channel; - requester_t::shared_pointer requester; + requester_t::weak_pointer requester; epics::pvData::BitSetPtr changed; epics::pvData::PVStructurePtr pvf; @@ -110,7 +110,7 @@ struct PDBSinglePut : public epics::pvAccess::ChannelPut, { typedef epics::pvAccess::ChannelPutRequester requester_t; PDBSingleChannel::shared_pointer channel; - requester_t::shared_pointer requester; + requester_t::weak_pointer requester; epics::pvData::BitSetPtr changed; epics::pvData::PVStructurePtr pvf; @@ -141,7 +141,7 @@ struct PDBSingleMonitor : public BaseMonitor { POINTER_DEFINITIONS(PDBSingleMonitor); - PDBSinglePV::shared_pointer pv; + PDBSinglePV::weak_pointer pv; PDBSingleMonitor(const PDBSinglePV::shared_pointer& pv, const requester_t::shared_pointer& requester, diff --git a/testApp/check_consist.cpp b/testApp/check_consist.cpp index d1876a5..28af92f 100644 --- a/testApp/check_consist.cpp +++ b/testApp/check_consist.cpp @@ -40,7 +40,7 @@ int main(int argc, char *argv[]) pva::ClientFactory::start(); - pva::ChannelProvider::shared_pointer prov(pva::getChannelProviderRegistry()->getProvider("pva")); + pva::ChannelProvider::shared_pointer prov(pva::ChannelProviderRegistry::clients()->getProvider("pva")); if(!prov) throw std::runtime_error("No pva provider?!?"); Destroyer prov_d(prov);