more ref. count tracking and break some loops

This commit is contained in:
Michael Davidsaver
2016-01-29 16:15:34 -05:00
parent 9d561f63a6
commit aecd8471e1
6 changed files with 43 additions and 4 deletions

View File

@@ -37,7 +37,18 @@ ChannelCacheEntry::CRequester::getRequesterName()
return "GWClient";
}
ChannelCacheEntry::CRequester::~CRequester() {}
size_t ChannelCacheEntry::CRequester::num_instances;
ChannelCacheEntry::CRequester::CRequester(const ChannelCacheEntry::shared_pointer& p)
:chan(p)
{
epicsAtomicIncrSizeT(&num_instances);
}
ChannelCacheEntry::CRequester::~CRequester()
{
epicsAtomicDecrSizeT(&num_instances);
}
void
ChannelCacheEntry::CRequester::message(std::string const & message, pvd::MessageType messageType)
@@ -142,9 +153,26 @@ ChannelCache::ChannelCache(const pva::ChannelProvider::shared_pointer& prov)
ChannelCache::~ChannelCache()
{
Guard G(cacheLock);
cleanTimer->destroy();
timerQueue->release();
delete cleaner;
entries_t E;
E.swap(entries);
FOREACH(it, end, E)
{
ChannelCacheEntry *ent = it->second.get();
if(ent->channel) {
epics::pvAccess::Channel::shared_pointer chan;
chan.swap(ent->channel);
UnGuard U(G);
chan->destroy();
}
}
}
ChannelCacheEntry::shared_pointer

View File

@@ -128,7 +128,9 @@ struct ChannelCacheEntry
// ChannelCacheEntry -> pva::Channel -> CRequester
struct CRequester : public epics::pvAccess::ChannelRequester
{
CRequester(const ChannelCacheEntry::shared_pointer& p) : chan(p) {}
static size_t num_instances;
CRequester(const ChannelCacheEntry::shared_pointer& p);
virtual ~CRequester();
ChannelCacheEntry::weak_pointer chan;
// for Requester

View File

@@ -43,6 +43,11 @@ GWChannel::message(std::string const & message, pvd::MessageType messageType)
void
GWChannel::destroy()
{
epics::pvAccess::ChannelRequester::shared_pointer req;
{
Guard G(entry->mutex());
req.swap(requester);
}
}
std::tr1::shared_ptr<pva::ChannelProvider>

View File

@@ -12,7 +12,7 @@ struct GWChannel : public epics::pvAccess::Channel
weak_pointer weakref;
const ChannelCacheEntry::shared_pointer entry;
const epics::pvAccess::ChannelRequester::shared_pointer requester;
epics::pvAccess::ChannelRequester::shared_pointer requester;
const std::string address; // address of client on GW server side
const epics::pvAccess::ChannelProvider::weak_pointer server_provder;

View File

@@ -148,6 +148,8 @@ MonitorCacheEntry::monitorEvent(pvd::MonitorPtr const & monitor)
continue;
}
// we only come out of overflow when downstream release()s an element to us
// empty.empty() does not imply inoverflow,
// however inoverflow does imply empty.empty()
assert(!usr->inoverflow);
if(usr->filled.empty())

View File

@@ -176,10 +176,12 @@ MAIN(testmon)
int ok = 1;
size_t temp;
#define TESTC(name) temp=epicsAtomicGetSizeT(&name::num_instances); ok &= temp==0; testDiag("num. live " #name " %u", (unsigned)temp)
TESTC(GWChannel);
TESTC(ChannelCacheEntry::CRequester);
TESTC(ChannelCacheEntry);
TESTC(MonitorCacheEntry);
TESTC(MonitorUser);
#undef TESTC
testOk(temp, "All instances free'd");
testOk(ok, "All instances free'd");
return testDone();
}