SharedPV separate close() and disconnect()

Previously, SharedPV::close() and StaticProvider::close()
would both disconnect all active clients, and put the SharedPV
in a closed (untyped) state.

SharedPV::close() remains unchanged.

StaticProvider::close() now only disconnects Channels created
through it, and leaves SharedPVs in the opened state.
This commit is contained in:
Michael Davidsaver
2019-07-07 16:33:13 -07:00
parent 50de6cc58e
commit aafb12f562
4 changed files with 25 additions and 8 deletions

View File

@ -114,10 +114,13 @@ public:
struct epicsShareClass ChannelBuilder {
POINTER_DEFINITIONS(ChannelBuilder);
virtual ~ChannelBuilder();
//! called to create a new Channel through the given ChannelProvider
virtual std::tr1::shared_ptr<epics::pvAccess::Channel> connect(const std::tr1::shared_ptr<epics::pvAccess::ChannelProvider>& provider,
const std::string& name,
const std::tr1::shared_ptr<epics::pvAccess::ChannelRequester>& requester) =0;
virtual void close(bool destroy=false) =0;
//! Disconnect all Channels created through the given ChannelProvider.
//! destroy==true if the ChannelProvider is shutting down.
virtual void disconnect(bool destroy, const epics::pvAccess::ChannelProvider* provider) =0;
};
private:
typedef std::map<std::string, std::tr1::shared_ptr<ChannelBuilder> > builders_t;

View File

@ -150,7 +150,7 @@ public:
//! close() is not final, even with destroy=true new clients may begin connecting, and open() may be called again.
//! A final close() should be performed after the removal from StaticProvider/DynamicProvider
//! which will prevent new clients.
virtual void close(bool destroy=false);
inline void close(bool destroy=false) { realClose(destroy, true, 0); }
//! Create a new container which may be used to prepare to call post().
//! This container will be owned exclusively by the caller.
@ -173,12 +173,16 @@ public:
virtual std::tr1::shared_ptr<epics::pvAccess::Channel> connect(
const std::tr1::shared_ptr<epics::pvAccess::ChannelProvider>& provider,
const std::string& channelName,
const std::tr1::shared_ptr<epics::pvAccess::ChannelRequester>& requester);
const std::tr1::shared_ptr<epics::pvAccess::ChannelRequester>& requester) OVERRIDE FINAL;
virtual void disconnect(bool destroy, const epics::pvAccess::ChannelProvider* provider) OVERRIDE FINAL;
void setDebug(int lvl);
int isDebug() const;
private:
void realClose(bool destroy, bool close, const epics::pvAccess::ChannelProvider* provider);
friend void epics::pvAccess::providerRegInit(void*);
static size_t num_instances;

View File

@ -138,7 +138,7 @@ void StaticProvider::close(bool destroy)
}
}
for(Impl::builders_t::iterator it(pvs.begin()), end(pvs.end()); it!=end; ++it) {
it->second->close(destroy);
it->second->disconnect(destroy, impl.get());
}
}
@ -168,7 +168,7 @@ std::tr1::shared_ptr<StaticProvider::ChannelBuilder> StaticProvider::remove(cons
}
}
if(ret)
ret->close(true);
ret->disconnect(true, impl.get());
return ret;
}

View File

@ -231,7 +231,7 @@ void SharedPV::open(const pvd::StructureConstPtr& type)
open(*value);
}
void SharedPV::close(bool destroy)
void SharedPV::realClose(bool destroy, bool closing, const epics::pvAccess::ChannelProvider* provider)
{
typedef std::vector<std::tr1::shared_ptr<pva::ChannelPutRequester> > xputs_t;
typedef std::vector<std::tr1::shared_ptr<pva::ChannelRPCRequester> > xrpcs_t;
@ -259,6 +259,8 @@ void SharedPV::close(bool destroy)
p_channel.reserve(channels.size());
FOR_EACH(puts_t::const_iterator, it, end, puts) {
if(provider && (*it)->channel->provider.lock().get()!=provider)
continue;
(*it)->mapper.reset();
p_put.push_back((*it)->requester.lock());
}
@ -274,8 +276,10 @@ void SharedPV::close(bool destroy)
}catch(std::tr1::bad_weak_ptr&) { /* ignore, racing dtor */ }
}
type.reset();
current.reset();
if(closing) {
type.reset();
current.reset();
}
}
if(destroy) {
@ -372,6 +376,12 @@ SharedPV::connect(const std::tr1::shared_ptr<epics::pvAccess::ChannelProvider> &
return ret;
}
void
SharedPV::disconnect(bool destroy, const epics::pvAccess::ChannelProvider* provider)
{
realClose(destroy, false, provider);
}
void SharedPV::setDebug(int lvl)
{
Guard G(mutex);