lock for ChannelCacheEntry

This commit is contained in:
Michael Davidsaver
2015-12-08 20:30:29 -05:00
parent 8abf5c20c6
commit a2cbc6cae4
4 changed files with 27 additions and 28 deletions

View File

@ -7,6 +7,7 @@
#define epicsExportSharedSymbols
#include "pva2pva.h"
#include "helper.h"
#include "chancache.h"
#include "channel.h"
@ -63,11 +64,6 @@ ChannelCacheEntry::CRequester::channelStateChange(pva::Channel::shared_pointer c
std::cout<<"Chan change '"<<chan->channelName<<"' is "
<<pva::Channel::ConnectionStateNames[connectionState]<<"\n";
ChannelCacheEntry::interested_t::vector_type interested;
// fanout notification
{
Guard G(chan->cache->cacheLock);
@ -84,13 +80,12 @@ ChannelCacheEntry::CRequester::channelStateChange(pva::Channel::shared_pointer c
default:
break;
}
interested = chan->interested.lock_vector(); // Copy to allow unlock during callback
}
for(ChannelCacheEntry::interested_t::vector_type::const_iterator
it=interested.begin(), end=interested.end();
it!=end; ++it)
// fanout notification
AUTO_VAL(interested, chan->interested.lock_vector()); // Copy
FOREACH(it, end, interested)
{
(*it)->requester->channelStateChange(*it, connectionState);
}

View File

@ -98,6 +98,9 @@ struct ChannelCacheEntry
const std::string channelName;
ChannelCache * const cache;
// to avoid yet another mutex borrow interested.mutex() for our members
inline epicsMutex& mutex() const { return interested.mutex(); }
// clientChannel
epics::pvAccess::Channel::shared_pointer channel;

View File

@ -158,7 +158,7 @@ GWChannel::createMonitor(
try {
{
Guard G(entry->cache->cacheLock);
Guard G(entry->mutex());
ment = entry->mon_entries.find(ser);
if(!ment) {

View File

@ -331,7 +331,7 @@ void statusServer(int lvl, const char *chanexpr)
bool dropflag;
const char *chstate;
{
Guard G(scp->cache.cacheLock);
Guard G(E.mutex());
chstate = pva::Channel::ConnectionStateNames[E.channel->getConnectionState()];
nsrv = E.interested.size();
nmon = E.mon_entries.size();
@ -484,28 +484,29 @@ void refCheck(int lvl)
GWServerChannelProvider *scp = dynamic_cast<GWServerChannelProvider*>(p);
if(!scp) continue;
ChannelCache::entries_t entries;
{
Guard G(scp->cache.cacheLock);
AUTO_REF(entries, scp->cache.entries);
entries = scp->cache.entries; // Copy
}
if(lvl>0) std::cout<<" Cache has "<<scp->cache.entries.size()<<" channels\n";
if(lvl>0) std::cout<<" Cache has "<<entries.size()<<" channels\n";
chan_count += entries.size();
chan_count += entries.size();
FOREACH(it, end, entries)
FOREACH(it, end, entries)
{
AUTO_VAL(M, it->second->mon_entries.lock_vector());
if(lvl>0) std::cout<<" Channel "<<it->second->channelName
<<" has "<<M.size()<<" Client Monitors\n";
mon_count += M.size();
FOREACH(it2, end2, M)
{
AUTO_VAL(M, it->second->mon_entries.lock_vector());
if(lvl>0) std::cout<<" Channel "<<it->second->channelName
<<" has "<<M.size()<<" Client Monitors\n";
mon_count += M.size();
FOREACH(it2, end2, M)
{
AUTO_REF(W, it2->second->interested);
if(lvl>0) std::cout<<" Used by "<<W.size()<<" Client Monitors\n";
mon_user_count += W.size();
}
AUTO_REF(W, it2->second->interested);
if(lvl>0) std::cout<<" Used by "<<W.size()<<" Client Monitors\n";
mon_user_count += W.size();
}
}
}