diff --git a/p2pApp/chancache.cpp b/p2pApp/chancache.cpp index fda56ab..825cf08 100644 --- a/p2pApp/chancache.cpp +++ b/p2pApp/chancache.cpp @@ -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 '"<channelName<<"' is " <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); } diff --git a/p2pApp/chancache.h b/p2pApp/chancache.h index 0f4612c..fdbfb5d 100644 --- a/p2pApp/chancache.h +++ b/p2pApp/chancache.h @@ -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; diff --git a/p2pApp/channel.cpp b/p2pApp/channel.cpp index 9520c22..442e78e 100644 --- a/p2pApp/channel.cpp +++ b/p2pApp/channel.cpp @@ -158,7 +158,7 @@ GWChannel::createMonitor( try { { - Guard G(entry->cache->cacheLock); + Guard G(entry->mutex()); ment = entry->mon_entries.find(ser); if(!ment) { diff --git a/p2pApp/server.cpp b/p2pApp/server.cpp index 00feeba..ba6ae4f 100644 --- a/p2pApp/server.cpp +++ b/p2pApp/server.cpp @@ -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(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 "<cache.entries.size()<<" channels\n"; + if(lvl>0) std::cout<<" Cache has "<second->mon_entries.lock_vector()); + + if(lvl>0) std::cout<<" Channel "<second->channelName + <<" has "<second->mon_entries.lock_vector()); - - if(lvl>0) std::cout<<" Channel "<second->channelName - <<" has "<second->interested); - if(lvl>0) std::cout<<" Used by "<second->interested); + if(lvl>0) std::cout<<" Used by "<