diff --git a/src/server/pva/sharedstate.h b/src/server/pva/sharedstate.h index e424dd7..a9e2991 100644 --- a/src/server/pva/sharedstate.h +++ b/src/server/pva/sharedstate.h @@ -206,7 +206,10 @@ private: //! Used for initial Monitor update and Get operations. epics::pvData::BitSet valid; - bool notifiedConn; // whether onFirstConnect() has been, or is being, called + // whether onFirstConnect() has been, or is being, called. + // Set when the first getField, Put, or Monitor (but not RPC) is created. + // Cleared when the last Channel is destroyed. + bool notifiedConn; int debugLvl; diff --git a/src/server/sharedstate_channel.cpp b/src/server/sharedstate_channel.cpp index f499ee1..59e1809 100644 --- a/src/server/sharedstate_channel.cpp +++ b/src/server/sharedstate_channel.cpp @@ -45,18 +45,10 @@ SharedChannel::SharedChannel(const std::tr1::shared_ptr &owner, this); } - SharedPV::Handler::shared_pointer handler; { Guard G(owner->mutex); - if(owner->channels.empty()) { - handler = owner->handler; - owner->notifiedConn = true; - } owner->channels.push_back(this); } - if(handler) { - handler->onFirstConnect(owner); - } } SharedChannel::~SharedChannel() @@ -111,15 +103,25 @@ std::tr1::shared_ptr SharedChannel::getChannelRequester() void SharedChannel::getField(pva::GetFieldRequester::shared_pointer const & requester,std::string const & subField) { epics::pvData::FieldConstPtr desc; + SharedPV::Handler::shared_pointer handler; { Guard G(owner->mutex); - if(owner->type) + if(owner->type) { desc = owner->type; - else - owner->getfields.push_back(requester); + } + + if(!owner->channels.empty() && !owner->notifiedConn) { + handler = owner->handler; + owner->notifiedConn = true; + } + owner->getfields.push_back(requester); } - if(desc) + if(desc) { requester->getDone(pvd::Status(), desc); + } + if(handler) { + handler->onFirstConnect(owner); + } } pva::ChannelPut::shared_pointer SharedChannel::createChannelPut( @@ -130,6 +132,7 @@ pva::ChannelPut::shared_pointer SharedChannel::createChannelPut( pvd::StructureConstPtr type; std::string warning; + SharedPV::Handler::shared_pointer handler; try { { Guard G(owner->mutex); @@ -140,6 +143,11 @@ pva::ChannelPut::shared_pointer SharedChannel::createChannelPut( type = ret->mapper.requested(); warning = ret->mapper.warnings(); } + + if(!owner->channels.empty() && !owner->notifiedConn) { + handler = owner->handler; + owner->notifiedConn = true; + } } if(!warning.empty()) requester->message(warning, pvd::warningMessage); @@ -150,6 +158,9 @@ pva::ChannelPut::shared_pointer SharedChannel::createChannelPut( type.reset(); requester->channelPutConnect(pvd::Status::error(e.what()), ret, type); } + if(handler) { + handler->onFirstConnect(owner); + } return ret; } @@ -172,6 +183,7 @@ pva::Monitor::shared_pointer SharedChannel::createMonitor( pvd::PVStructure::shared_pointer const & pvRequest) { SharedMonitorFIFO::Config mconf; + SharedPV::Handler::shared_pointer handler; mconf.dropEmptyUpdates = owner->config.dropEmptyUpdates; mconf.mapperMode = owner->config.mapperMode; std::tr1::shared_ptr ret(new SharedMonitorFIFO(shared_from_this(), requester, pvRequest, &mconf)); @@ -185,9 +197,17 @@ pva::Monitor::shared_pointer SharedChannel::createMonitor( // post initial update ret->post(*owner->current, owner->valid); } + + if(!owner->channels.empty() && !owner->notifiedConn) { + handler = owner->handler; + owner->notifiedConn = true; + } } if(notify) ret->notify(); + if(handler) { + handler->onFirstConnect(owner); + } return ret; }