pvDatabase::removeRecord and pvRecord::remove no longer call eachother directly

This commit is contained in:
mrkraimer
2020-02-12 09:13:19 -05:00
parent 083dffac3c
commit 75c16bd423
4 changed files with 77 additions and 43 deletions

View File

@ -93,28 +93,38 @@ int main (int argc, char** argv)
unsigned loopctr = 0; unsigned loopctr = 0;
unsigned pausectr = 0; unsigned pausectr = 0;
bool allowExit = false; bool allowExit = false;
int opt; bool callRecord = false;
while((opt = getopt(argc, argv, "v:ah")) != -1) { bool callDatabase = false;
switch(opt) { int opt;
case 'v': while((opt = getopt(argc, argv, "v:ardh")) != -1) {
verbose = std::stoi(optarg); switch(opt) {
break; case 'v':
case 'a' : verbose = std::stoi(optarg);
allowExit = true; break;
break; case 'a' :
case 'h': allowExit = true;
std::cout << " -v level -a -h \n"; break;
case 'r' :
callRecord = true;
break;
case 'd' :
callDatabase = true;
break;
case 'h':
std::cout << " -v level -a -r -d -h \n";
std::cout << "-r call pvRecord->remove -d call master->removeRecord\n";
std::cout << "default\n"; std::cout << "default\n";
std::cout << "-v " << verbose std::cout << "-v " << verbose
<< " -a false" << " -a false"
<< " -d"
<< "\n"; << "\n";
return 0; return 0;
default: default:
std::cerr<<"Unknown argument: "<<opt<<"\n"; std::cerr<<"Unknown argument: "<<opt<<"\n";
return -1; return -1;
} }
} }
if(!callRecord && !callDatabase) callDatabase = true;
::epics::pvDatabase::PVDatabasePtr master = epics::pvDatabase::PVDatabase::getMaster(); ::epics::pvDatabase::PVDatabasePtr master = epics::pvDatabase::PVDatabase::getMaster();
::epics::pvDatabase::ChannelProviderLocalPtr channelProvider = epics::pvDatabase::getChannelProviderLocal(); ::epics::pvDatabase::ChannelProviderLocalPtr channelProvider = epics::pvDatabase::getChannelProviderLocal();
epics::pvAccess::ServerContext::shared_pointer context epics::pvAccess::ServerContext::shared_pointer context
@ -142,12 +152,12 @@ int main (int argc, char** argv)
std::tr1::shared_ptr<MyMonitor> mymonitor = MyMonitor::create(channel); std::tr1::shared_ptr<MyMonitor> mymonitor = MyMonitor::create(channel);
unsigned valuectr = loopctr; unsigned valuectr = loopctr;
std::cout << startset << loopctr << "\n"; std::cout << startset << loopctr << "\n";
for (int ind=0; ind<10; ind++) { for (int ind=0; ind<100; ind++) {
channel->put().set("value",valuectr++).exec(); channel->put().set("value",valuectr++).exec();
mymonitor->getData(); mymonitor->getData();
} }
pausectr++; pausectr++;
if(allowExit && pausectr>500) { if(allowExit && pausectr>10) {
pausectr = 0; pausectr = 0;
std::cout << "Type exit to stop: \n"; std::cout << "Type exit to stop: \n";
int c = std::cin.peek(); // peek character int c = std::cin.peek(); // peek character
@ -156,8 +166,14 @@ int main (int argc, char** argv)
std::getline(std::cin,str); std::getline(std::cin,str);
if(str.compare("exit")==0) break; if(str.compare("exit")==0) break;
} }
pvrecord->remove(); if(callRecord) {
// master->removeRecord(pvrecord); std::cout << "callRecord\n";
pvrecord->remove();
}
if(callDatabase) {
std::cout << "callDatabase\n";
master->removeRecord(pvrecord);
}
} }
return (0); return (0);
} }

View File

@ -92,18 +92,28 @@ bool PVDatabase::addRecord(PVRecordPtr const & record)
return true; return true;
} }
bool PVDatabase::removeRecord(PVRecordPtr const & record,bool callRemove) PVRecordWPtr PVDatabase::removeFromMap(PVRecordPtr const & record)
{ {
if(record->getTraceLevel()>0) {
cout << "PVDatabase::removeRecord " << record->getRecordName() << endl;
}
epicsGuard<epics::pvData::Mutex> guard(mutex); epicsGuard<epics::pvData::Mutex> guard(mutex);
string recordName = record->getRecordName(); string recordName = record->getRecordName();
PVRecordMap::iterator iter = recordMap.find(recordName); PVRecordMap::iterator iter = recordMap.find(recordName);
if(iter!=recordMap.end()) { if(iter!=recordMap.end()) {
PVRecordPtr pvRecord = (*iter).second; PVRecordPtr pvRecord = (*iter).second;
if(callRemove) pvRecord->remove(false);
recordMap.erase(iter); recordMap.erase(iter);
return pvRecord->shared_from_this();
}
return PVRecordWPtr();
}
bool PVDatabase::removeRecord(PVRecordPtr const & record)
{
if(record->getTraceLevel()>0) {
cout << "PVDatabase::removeRecord " << record->getRecordName() << endl;
}
epicsGuard<epics::pvData::Mutex> guard(mutex);
PVRecordWPtr pvRecord = removeFromMap(record);
if(pvRecord.use_count()!=0) {
pvRecord.lock()->unlistenClients();
return true; return true;
} }
return false; return false;

View File

@ -65,17 +65,9 @@ PVRecord::~PVRecord()
} }
} }
void PVRecord::remove(bool callpvDatabaseRemoveRecord) void PVRecord::unlistenClients()
{ {
if(traceLevel>0) { epicsGuard<epics::pvData::Mutex> guard(mutex);
cout << "PVRecord::remove() " << recordName << endl;
}
epicsGuard<epics::pvData::Mutex> guard(mutex);
if(callpvDatabaseRemoveRecord) {
PVDatabasePtr pvDatabase(PVDatabase::getMaster());
if(pvDatabase) pvDatabase->removeRecord(shared_from_this(),false);
}
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++ )
@ -102,6 +94,19 @@ void PVRecord::remove(bool callpvDatabaseRemoveRecord)
clientList.clear(); clientList.clear();
} }
void PVRecord::remove()
{
if(traceLevel>0) {
cout << "PVRecord::remove() " << recordName << endl;
}
unlistenClients();
epicsGuard<epics::pvData::Mutex> guard(mutex);
PVDatabasePtr pvDatabase(PVDatabase::getMaster());
if(pvDatabase) pvDatabase->removeFromMap(shared_from_this());
pvTimeStamp.detach();
}
void PVRecord::initPVRecord() void PVRecord::initPVRecord()
{ {
PVRecordStructurePtr parent; PVRecordStructurePtr parent;

View File

@ -97,10 +97,8 @@ public:
* get rid of listeners and requesters. * get rid of listeners and requesters.
* If derived class overrides this then it must call PVRecord::remove() * If derived class overrides this then it must call PVRecord::remove()
* after it has destroyed any resorces it uses. * after it has destroyed any resorces it uses.
* @param callpvDatabaseRemoveRecord Should pvDatabase.removeRecord be called.
* Normally this is only set false by PVDatabase::removeRecord.
*/ */
virtual void remove(bool callpvDatabaseRemoveRecord = true); virtual void remove();
/** /**
* @brief Optional method for derived class. * @brief Optional method for derived class.
* *
@ -254,6 +252,9 @@ protected:
*/ */
void initPVRecord(); void initPVRecord();
private: private:
friend class PVDatabase;
void unlistenClients();
PVRecordFieldPtr findPVRecordField( PVRecordFieldPtr findPVRecordField(
PVRecordStructurePtr const & pvrs, PVRecordStructurePtr const & pvrs,
epics::pvData::PVFieldPtr const & pvField); epics::pvData::PVFieldPtr const & pvField);
@ -500,17 +501,19 @@ public:
/** /**
* @brief Remove a record. * @brief Remove a record.
* @param record The record to remove. * @param record The record to remove.
* @param callRemove Call pvRecord->remove() *
* Normally this is only set false by pvRecord.remove()
* @return <b>true</b> if record was removed. * @return <b>true</b> if record was removed.
*/ */
bool removeRecord(PVRecordPtr const & record,bool callRemove = true); bool removeRecord(PVRecordPtr const & record);
/** /**
* @brief Get the names of all the records in the database. * @brief Get the names of all the records in the database.
* @return The names. * @return The names.
*/ */
epics::pvData::PVStringArrayPtr getRecordNames(); epics::pvData::PVStringArrayPtr getRecordNames();
private: private:
friend class PVRecord;
PVRecordWPtr removeFromMap(PVRecordPtr const & record);
PVDatabase(); PVDatabase();
void lock(); void lock();
void unlock(); void unlock();