more ref. count tracking and break some loops
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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())
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user