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

View File

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

View File

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

View File

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

View File

@ -313,6 +313,14 @@ void MonitorLocal::unlisten(PVRecordPtr const & pvRecord)
{
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);
}