SharedPV defer onFirstConnect() to first getField/Put/Monitor

This commit is contained in:
Michael Davidsaver
2018-10-07 19:27:29 -07:00
parent 165313d8f5
commit ed1bd1b962
2 changed files with 36 additions and 13 deletions

View File

@@ -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;

View File

@@ -45,18 +45,10 @@ SharedChannel::SharedChannel(const std::tr1::shared_ptr<SharedPV> &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<pva::ChannelRequester> 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<SharedMonitorFIFO> 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;
}