pva/client.h Allow callbacks to unref Operations

Keep a local (internal) shared_ptr whenever
user callbacks are run.  This allows user
callbacks to drop (reset()/dtor) Operations
or Monitors safely.

Ref must to captured before mutex is locked,
which is safe as the internal weak_ptr is
not changed after build() (despite being non-const)
This commit is contained in:
Michael Davidsaver
2018-06-29 11:19:24 -07:00
parent f29ef3121e
commit 80db41f1c4
4 changed files with 19 additions and 2 deletions

View File

@@ -83,6 +83,7 @@ struct RPCer : public pva::ChannelRPCRequester,
// called automatically via wrapped_shared_from_this
virtual void cancel()
{
std::tr1::shared_ptr<RPCer> keepalive(internal_shared_from_this());
Guard G(mutex);
if(started && op) op->cancel();
callEvent(G, pvac::GetEvent::Cancel);
@@ -98,6 +99,7 @@ struct RPCer : public pva::ChannelRPCRequester,
const epics::pvData::Status& status,
pva::ChannelRPC::shared_pointer const & operation)
{
std::tr1::shared_ptr<RPCer> keepalive(internal_shared_from_this());
Guard G(mutex);
if(!cb || started) return;
@@ -117,6 +119,7 @@ struct RPCer : public pva::ChannelRPCRequester,
virtual void channelDisconnect(bool destroy) OVERRIDE FINAL
{
std::tr1::shared_ptr<RPCer> keepalive(internal_shared_from_this());
Guard G(mutex);
event.message = "Disconnect";
@@ -128,6 +131,7 @@ struct RPCer : public pva::ChannelRPCRequester,
pva::ChannelRPC::shared_pointer const & operation,
epics::pvData::PVStructure::shared_pointer const & pvResponse)
{
std::tr1::shared_ptr<RPCer> keepalive(internal_shared_from_this());
Guard G(mutex);
if(!cb) return;