fix client Channel ref leak through Context search map

This commit is contained in:
Michael Davidsaver
2017-06-19 11:30:08 +02:00
parent f610f498fa
commit cd722388dc
3 changed files with 24 additions and 15 deletions

View File

@@ -158,7 +158,8 @@ private:
/**
* Set of registered channels.
*/
std::map<pvAccessID,SearchInstance::shared_pointer> m_channels;
typedef std::map<pvAccessID,SearchInstance::weak_pointer> m_channels_t;
m_channels_t m_channels;
/**
* Time of last frame send.

View File

@@ -134,7 +134,7 @@ void SimpleChannelSearchManagerImpl::unregisterSearchInstance(SearchInstance::sh
{
Lock guard(m_channelMutex);
pvAccessID id = channel->getSearchInstanceID();
std::map<pvAccessID,SearchInstance::shared_pointer>::iterator channelsIter = m_channels.find(id);
m_channels_t::iterator channelsIter = m_channels.find(id);
if(channelsIter != m_channels.end())
m_channels.erase(id);
}
@@ -142,19 +142,22 @@ void SimpleChannelSearchManagerImpl::unregisterSearchInstance(SearchInstance::sh
void SimpleChannelSearchManagerImpl::searchResponse(const GUID & guid, pvAccessID cid, int32_t /*seqNo*/, int8_t minorRevision, osiSockAddr* serverAddress)
{
Lock guard(m_channelMutex);
std::map<pvAccessID,SearchInstance::shared_pointer>::iterator channelsIter = m_channels.find(cid);
m_channels_t::iterator channelsIter = m_channels.find(cid);
if(channelsIter == m_channels.end())
{
guard.unlock();
Context::shared_pointer ctxt(m_context.lock());
// TODO: proper action if !ctxt???
if(!ctxt) return;
// enable duplicate reports
SearchInstance::shared_pointer si = std::tr1::dynamic_pointer_cast<SearchInstance>(m_context.lock()->getChannel(cid));
SearchInstance::shared_pointer si = std::tr1::dynamic_pointer_cast<SearchInstance>(ctxt->getChannel(cid));
if (si)
si->searchResponse(guid, minorRevision, serverAddress);
}
else
{
SearchInstance::shared_pointer si = channelsIter->second;
SearchInstance::shared_pointer si(channelsIter->second.lock());
// remove from search list
m_channels.erase(cid);
@@ -162,7 +165,8 @@ void SimpleChannelSearchManagerImpl::searchResponse(const GUID & guid, pvAccessI
guard.unlock();
// then notify SearchInstance
si->searchResponse(guid, minorRevision, serverAddress);
if(si)
si->searchResponse(guid, minorRevision, serverAddress);
}
}
@@ -275,10 +279,12 @@ void SimpleChannelSearchManagerImpl::boost()
{
Lock guard(m_channelMutex);
Lock guard2(m_userValueMutex);
std::map<pvAccessID,SearchInstance::shared_pointer>::iterator channelsIter = m_channels.begin();
m_channels_t::iterator channelsIter = m_channels.begin();
for(; channelsIter != m_channels.end(); channelsIter++)
{
int32_t& userValue = channelsIter->second->getUserValue();
SearchInstance::shared_pointer inst(channelsIter->second.lock());
if(!inst) continue;
int32_t& userValue = inst->getUserValue();
userValue = BOOST_VALUE;
}
}
@@ -306,9 +312,14 @@ void SimpleChannelSearchManagerImpl::callback()
{
Lock guard(m_channelMutex);
toSend.reserve(m_channels.size());
std::map<pvAccessID,SearchInstance::shared_pointer>::iterator channelsIter = m_channels.begin();
for(; channelsIter != m_channels.end(); channelsIter++)
toSend.push_back(channelsIter->second);
for(m_channels_t::iterator channelsIter = m_channels.begin();
channelsIter != m_channels.end(); channelsIter++)
{
SearchInstance::shared_pointer inst(channelsIter->second.lock());
if(!inst) continue;
toSend.push_back(inst);
}
}
vector<SearchInstance::shared_pointer>::iterator siter = toSend.begin();

View File

@@ -3286,10 +3286,6 @@ private:
new InternalChannelImpl(context, channelID, name, requester, priority, addresses));
ChannelImpl::shared_pointer thisPointer = tp;
static_cast<InternalChannelImpl*>(thisPointer.get())->activate();
{
ChannelImpl::shared_pointer wrap(thisPointer.get(), Destroyable::cleaner(thisPointer));
thisPointer.swap(wrap);
}
return thisPointer;
}
@@ -3315,6 +3311,7 @@ private:
private:
// intentionally returning non-const reference
int32_t& getUserValue() {
return m_userValue;
}