on-line delete; notify clients when a PVRecord is deleted
This commit is contained in:
@ -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)
|
||||||
|
@ -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;
|
||||||
|
@ -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;
|
||||||
|
@ -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")
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user