Merge pull request #17 from mrkraimer/master

on-line delete; notify clients when a PVRecord is deleted
This commit is contained in:
Marty Kraimer
2016-06-24 15:04:44 -04:00
committed by GitHub
5 changed files with 57 additions and 87 deletions

View File

@ -48,7 +48,7 @@ PVRecord::PVRecord(
PVRecord::~PVRecord() PVRecord::~PVRecord()
{ {
if(traceLevel>1) { if(traceLevel>0) {
cout << "~PVRecord() " << recordName << endl; cout << "~PVRecord() " << recordName << endl;
} }
destroy(); destroy();
@ -66,44 +66,44 @@ void PVRecord::initPVRecord()
void PVRecord::destroy() void PVRecord::destroy()
{ {
if(traceLevel>1) { if(traceLevel>0) {
cout << "PVRecord::destroy() " << recordName << endl; cout << "PVRecord::destroy() " << recordName << endl;
} }
epicsGuard<epics::pvData::Mutex> guard(mutex);
if(isDestroyed) {
return;
}
isDestroyed = true;
pvTimeStamp.detach();
for(std::list<PVRecordClientWPtr>::iterator iter = pvRecordClientList.begin();
iter!=pvRecordClientList.end();
iter++ )
{ {
PVRecordClientPtr client = iter->lock(); epicsGuard<epics::pvData::Mutex> guard(mutex);
if(client) { if(isDestroyed) {
if(traceLevel>1) { return;
cout << "PVRecord::destroy() calling client->detach " << recordName << endl;
}
epicsGuardRelease<epics::pvData::Mutex> unguard(guard);
client->detach(shared_from_this());
} }
isDestroyed = true;
} }
PVDatabasePtr pvDatabase(PVDatabase::getMaster());
if(pvDatabase) pvDatabase->removeRecord(shared_from_this());
pvTimeStamp.detach();
for(std::list<PVListenerWPtr>::iterator iter = pvListenerList.begin(); for(std::list<PVListenerWPtr>::iterator iter = pvListenerList.begin();
iter!=pvListenerList.end(); iter!=pvListenerList.end();
iter++ ) iter++ )
{ {
PVListenerPtr listener = iter->lock(); PVListenerPtr listener = iter->lock();
if(listener) { if(!listener) continue;
if(traceLevel>1) { if(traceLevel>0) {
cout << "PVRecord::destroy() calling listener->unlisten " << recordName << endl; cout << "PVRecord::destroy() calling listener->unlisten " << recordName << endl;
}
epicsGuardRelease<epics::pvData::Mutex> unguard(guard);
listener->unlisten(shared_from_this());
} }
listener->unlisten(shared_from_this());
} }
PVDatabasePtr pvDatabase(PVDatabase::getMaster()); pvListenerList.clear();
if(pvDatabase) pvDatabase->removeRecord(shared_from_this()); std::list<PVRecordClientPtr>::iterator iter;
for (iter = pvRecordClientList.begin();
iter!=pvRecordClientList.end();
iter++ )
{
PVRecordClientPtr client = *iter;
if(!client) continue;
if(traceLevel>0) {
cout << "PVRecord::destroy() calling client->detach " << recordName << endl;
}
client->detach(shared_from_this());
}
pvRecordClientList.clear();
} }
void PVRecord::process() void PVRecord::process()
@ -198,17 +198,19 @@ bool PVRecord::addPVRecordClient(PVRecordClientPtr const & pvRecordClient)
if(isDestroyed) { if(isDestroyed) {
return false; return false;
} }
std::list<PVRecordClientWPtr>::iterator iter; std::list<PVRecordClientPtr>::iterator iter;
for (iter = pvRecordClientList.begin(); for (iter = pvRecordClientList.begin();
iter!=pvRecordClientList.end(); iter!=pvRecordClientList.end();
iter++ ) iter++ )
{ {
PVRecordClientPtr client = iter->lock(); PVRecordClientPtr client = *iter;
if(!client.get()) continue; if(client==pvRecordClient) {
if(client.get()==pvRecordClient.get()) {
return false; return false;
} }
} }
if(traceLevel>1) {
cout << "PVRecord::addPVRecordClient() calling pvRecordClientList.push_back(pvRecordClient)" << recordName << endl;
}
pvRecordClientList.push_back(pvRecordClient); pvRecordClientList.push_back(pvRecordClient);
return true; return true;
} }
@ -222,14 +224,14 @@ bool PVRecord::removePVRecordClient(PVRecordClientPtr const & pvRecordClient)
if(isDestroyed) { if(isDestroyed) {
return false; return false;
} }
std::list<PVRecordClientWPtr>::iterator iter; std::list<PVRecordClientPtr>::iterator iter;
for (iter = pvRecordClientList.begin(); for (iter = pvRecordClientList.begin();
iter!=pvRecordClientList.end(); iter!=pvRecordClientList.end();
iter++ ) iter++ )
{ {
PVRecordClientPtr client = iter->lock(); PVRecordClientPtr client = *iter;
if(!client.get()) continue; if(!client) continue;
if(client.get()==pvRecordClient.get()) { if(client==pvRecordClient) {
pvRecordClientList.erase(iter); pvRecordClientList.erase(iter);
return true; return true;
} }
@ -237,31 +239,6 @@ bool PVRecord::removePVRecordClient(PVRecordClientPtr const & pvRecordClient)
return false; return false;
} }
void PVRecord::detachClients()
{
if(traceLevel>1) {
cout << "PVRecord::detachClients() " << recordName << endl;
}
epicsGuard<epics::pvData::Mutex> guard(mutex);
if(isDestroyed) {
return;
}
std::list<PVRecordClientWPtr>::iterator iter;
for (iter = pvRecordClientList.begin();
iter!=pvRecordClientList.end();
iter++ )
{
PVRecordClientPtr client = iter->lock();
if(!client) continue;
epicsGuardRelease <epics::pvData::Mutex> unguard(guard);
if(traceLevel>1) {
cout << "PVRecord::detachClients() calling client->detach " << recordName << endl;
}
client->detach(shared_from_this());
}
pvRecordClientList.clear();
}
bool PVRecord::addListener( bool PVRecord::addListener(
PVListenerPtr const & pvListener, PVListenerPtr const & pvListener,
PVCopyPtr const & pvCopy) PVCopyPtr const & pvCopy)

View File

@ -393,7 +393,7 @@ protected:
return shared_from_this(); return shared_from_this();
} }
private: private:
epics::pvAccess::ChannelRequester::weak_pointer requester; epics::pvAccess::ChannelRequester::shared_pointer requester;
ChannelProviderLocalPtr provider; ChannelProviderLocalPtr provider;
PVRecordPtr pvRecord; PVRecordPtr pvRecord;
bool beingDestroyed; bool beingDestroyed;

View File

@ -51,7 +51,6 @@ typedef std::tr1::weak_ptr<PVRecordStructure> PVRecordStructureWPtr;
class PVRecordClient; class PVRecordClient;
typedef std::tr1::shared_ptr<PVRecordClient> PVRecordClientPtr; typedef std::tr1::shared_ptr<PVRecordClient> PVRecordClientPtr;
typedef std::tr1::weak_ptr<PVRecordClient> PVRecordClientWPtr;
class PVListener; class PVListener;
typedef std::tr1::shared_ptr<PVListener> PVListenerPtr; typedef std::tr1::shared_ptr<PVListener> PVListenerPtr;
@ -167,10 +166,6 @@ public:
* @return <b>true</b> if the client is removed. * @return <b>true</b> if the client is removed.
*/ */
bool removePVRecordClient(PVRecordClientPtr const & pvRecordClient); bool removePVRecordClient(PVRecordClientPtr const & pvRecordClient);
/**
* remove all attached clients.
*/
void detachClients();
/** /**
* Add a PVListener. * Add a PVListener.
* This must be called before calling pvRecordField.addListener. * This must be called before calling pvRecordField.addListener.
@ -258,7 +253,7 @@ private:
epics::pvData::PVStructurePtr pvStructure; epics::pvData::PVStructurePtr pvStructure;
PVRecordStructurePtr pvRecordStructure; PVRecordStructurePtr pvRecordStructure;
std::list<PVListenerWPtr> pvListenerList; std::list<PVListenerWPtr> pvListenerList;
std::list<PVRecordClientWPtr> pvRecordClientList; std::list<PVRecordClientPtr> pvRecordClientList;
epics::pvData::Mutex mutex; epics::pvData::Mutex mutex;
std::size_t depthGroupPut; std::size_t depthGroupPut;
int traceLevel; int traceLevel;

View File

@ -1329,7 +1329,6 @@ ChannelLocal::~ChannelLocal()
void ChannelLocal::destroy() void ChannelLocal::destroy()
{ {
ChannelRequester::shared_pointer requester(this->requester.lock());
if(pvRecord->getTraceLevel()>0) { if(pvRecord->getTraceLevel()>0) {
cout << "ChannelLocal::destroy()" cout << "ChannelLocal::destroy()"
<< " recordName " << pvRecord->getRecordName() << " recordName " << pvRecord->getRecordName()
@ -1349,47 +1348,45 @@ void ChannelLocal::destroy()
void ChannelLocal::detach(PVRecordPtr const & pvRecord) void ChannelLocal::detach(PVRecordPtr const & pvRecord)
{ {
if(pvRecord->getTraceLevel()>0) { if(pvRecord->getTraceLevel()>0) {
ChannelRequester::shared_pointer requester(this->requester.lock());
cout << "ChannelLocal::detach() " cout << "ChannelLocal::detach() "
<< " recordName " << pvRecord->getRecordName() << " recordName " << pvRecord->getRecordName()
<< " requester exists " << (requester ? "true" : "false") << " requester exists " << (requester ? "true" : "false")
<< endl; << endl;
} }
destroy(); if(!requester) return;
requester->channelStateChange(shared_from_this(),Channel::DESTROYED);
} }
string ChannelLocal::getRequesterName() string ChannelLocal::getRequesterName()
{ {
ChannelRequester::shared_pointer req = requester.lock();
if(pvRecord->getTraceLevel()>1) { if(pvRecord->getTraceLevel()>1) {
cout << "ChannelLocal::getRequesterName() " cout << "ChannelLocal::getRequesterName() "
<< " recordName " << pvRecord->getRecordName() << " recordName " << pvRecord->getRecordName()
<< " requester exists " << (req ? "true" : "false") << " requester exists " << (requester ? "true" : "false")
<< endl; << endl;
} }
if(!req) return string(); if(!requester) return string();
return req->getRequesterName(); return requester->getRequesterName();
} }
void ChannelLocal::message( void ChannelLocal::message(
string const &message, string const &message,
MessageType messageType) MessageType messageType)
{ {
ChannelRequester::shared_pointer req = requester.lock();
if(pvRecord->getTraceLevel()>1) { if(pvRecord->getTraceLevel()>1) {
cout << "ChannelLocal::message() " cout << "ChannelLocal::message() "
<< " recordName " << pvRecord->getRecordName() << " recordName " << pvRecord->getRecordName()
<< " requester exists " << (req ? "true" : "false") << " requester exists " << (requester ? "true" : "false")
<< endl; << endl;
} }
{ {
Lock xx(mutex); Lock xx(mutex);
if(beingDestroyed) return; if(beingDestroyed) return;
} }
if(req) { if(requester) {
req->message(message,messageType); requester->message(message,messageType);
return; return;
} }
cout << pvRecord->getRecordName() cout << pvRecord->getRecordName()
@ -1417,7 +1414,7 @@ string ChannelLocal::getChannelName()
ChannelRequester::shared_pointer ChannelLocal::getChannelRequester() ChannelRequester::shared_pointer ChannelLocal::getChannelRequester()
{ {
return requester.lock(); return requester;
} }
bool ChannelLocal::isConnected() bool ChannelLocal::isConnected()
@ -1458,7 +1455,6 @@ ChannelProcess::shared_pointer ChannelLocal::createChannelProcess(
PVStructure::shared_pointer const & pvRequest) PVStructure::shared_pointer const & pvRequest)
{ {
if(pvRecord->getTraceLevel()>0) { if(pvRecord->getTraceLevel()>0) {
ChannelRequester::shared_pointer requester(this->requester.lock());
cout << "ChannelLocal::createChannelProcess() " cout << "ChannelLocal::createChannelProcess() "
<< " recordName " << pvRecord->getRecordName() << " recordName " << pvRecord->getRecordName()
<< " requester exists " << (requester ? "true" : "false") << " requester exists " << (requester ? "true" : "false")
@ -1478,7 +1474,6 @@ ChannelGet::shared_pointer ChannelLocal::createChannelGet(
PVStructure::shared_pointer const &pvRequest) PVStructure::shared_pointer const &pvRequest)
{ {
if(pvRecord->getTraceLevel()>0) { if(pvRecord->getTraceLevel()>0) {
ChannelRequester::shared_pointer requester(this->requester.lock());
cout << "ChannelLocal::createChannelGet() " cout << "ChannelLocal::createChannelGet() "
<< " recordName " << pvRecord->getRecordName() << " recordName " << pvRecord->getRecordName()
<< " requester exists " << (requester ? "true" : "false") << " requester exists " << (requester ? "true" : "false")
@ -1498,7 +1493,6 @@ ChannelPut::shared_pointer ChannelLocal::createChannelPut(
PVStructure::shared_pointer const &pvRequest) PVStructure::shared_pointer const &pvRequest)
{ {
if(pvRecord->getTraceLevel()>0) { if(pvRecord->getTraceLevel()>0) {
ChannelRequester::shared_pointer requester(this->requester.lock());
cout << "ChannelLocal::createChannelPut() " cout << "ChannelLocal::createChannelPut() "
<< " recordName " << pvRecord->getRecordName() << " recordName " << pvRecord->getRecordName()
<< " requester exists " << (requester ? "true" : "false") << " requester exists " << (requester ? "true" : "false")
@ -1519,7 +1513,6 @@ ChannelPutGet::shared_pointer ChannelLocal::createChannelPutGet(
PVStructure::shared_pointer const &pvRequest) PVStructure::shared_pointer const &pvRequest)
{ {
if(pvRecord->getTraceLevel()>0) { if(pvRecord->getTraceLevel()>0) {
ChannelRequester::shared_pointer requester(this->requester.lock());
cout << "ChannelLocal::createChannelPutGet() " cout << "ChannelLocal::createChannelPutGet() "
<< " recordName " << pvRecord->getRecordName() << " recordName " << pvRecord->getRecordName()
<< " requester exists " << (requester ? "true" : "false") << " requester exists " << (requester ? "true" : "false")
@ -1540,7 +1533,6 @@ ChannelRPC::shared_pointer ChannelLocal::createChannelRPC(
PVStructure::shared_pointer const & pvRequest) PVStructure::shared_pointer const & pvRequest)
{ {
if(pvRecord->getTraceLevel()>0) { if(pvRecord->getTraceLevel()>0) {
ChannelRequester::shared_pointer requester(this->requester.lock());
cout << "ChannelLocal::createChannelRPC() " cout << "ChannelLocal::createChannelRPC() "
<< " recordName " << pvRecord->getRecordName() << " recordName " << pvRecord->getRecordName()
<< " requester exists " << (requester ? "true" : "false") << " requester exists " << (requester ? "true" : "false")
@ -1561,7 +1553,6 @@ Monitor::shared_pointer ChannelLocal::createMonitor(
PVStructure::shared_pointer const &pvRequest) PVStructure::shared_pointer const &pvRequest)
{ {
if(pvRecord->getTraceLevel()>0) { if(pvRecord->getTraceLevel()>0) {
ChannelRequester::shared_pointer requester(this->requester.lock());
cout << "ChannelLocal::createMonitor() " cout << "ChannelLocal::createMonitor() "
<< " recordName " << pvRecord->getRecordName() << " recordName " << pvRecord->getRecordName()
<< " requester exists " << (requester ? "true" : "false") << " requester exists " << (requester ? "true" : "false")
@ -1581,7 +1572,6 @@ ChannelArray::shared_pointer ChannelLocal::createChannelArray(
PVStructure::shared_pointer const &pvRequest) PVStructure::shared_pointer const &pvRequest)
{ {
if(pvRecord->getTraceLevel()>0) { if(pvRecord->getTraceLevel()>0) {
ChannelRequester::shared_pointer requester(this->requester.lock());
cout << "ChannelLocal::createChannelArray() " cout << "ChannelLocal::createChannelArray() "
<< " recordName " << pvRecord->getRecordName() << " recordName " << pvRecord->getRecordName()
<< " requester exists " << (requester ? "true" : "false") << " requester exists " << (requester ? "true" : "false")

View File

@ -313,6 +313,14 @@ void MonitorLocal::unlisten(PVRecordPtr const & pvRecord)
{ {
cout << "PVCopyMonitor::unlisten\n"; cout << "PVCopyMonitor::unlisten\n";
} }
MonitorRequesterPtr requester = monitorRequester.lock();
if(requester) {
if(pvRecord->getTraceLevel()>1)
{
cout << "PVCopyMonitor::unlisten calling requester->unlisten\n";
}
requester->unlisten(getPtrSelf());
}
pvRecord->removeListener(getPtrSelf(),pvCopy); pvRecord->removeListener(getPtrSelf(),pvCopy);
} }