Merge pull request #18 from mrkraimer/master
Compatibility with pvDatabaseJava; on-line delete; database termination
This commit is contained in:
@ -43,22 +43,21 @@ PVDatabase::~PVDatabase()
|
||||
}
|
||||
|
||||
void PVDatabase::destroy()
|
||||
{
|
||||
{
|
||||
epicsGuard<epics::pvData::Mutex> guard(mutex);
|
||||
if(isDestroyed) {
|
||||
return;
|
||||
}
|
||||
isDestroyed = true;
|
||||
PVRecordMap::iterator iter;
|
||||
while(true) {
|
||||
iter = recordMap.begin();
|
||||
if(iter==recordMap.end()) break;
|
||||
}
|
||||
for(PVRecordMap::iterator iter = recordMap.begin(); iter != recordMap.end(); iter++) {
|
||||
PVRecordPtr pvRecord = (*iter).second;
|
||||
recordMap.erase(iter);
|
||||
if(pvRecord) {
|
||||
pvRecord->destroy();
|
||||
}
|
||||
}
|
||||
recordMap.clear();
|
||||
}
|
||||
|
||||
void PVDatabase::lock() {
|
||||
@ -83,27 +82,6 @@ PVRecordPtr PVDatabase::findRecord(string const& recordName)
|
||||
return xxx;
|
||||
}
|
||||
|
||||
PVStringArrayPtr PVDatabase::getRecordNames()
|
||||
{
|
||||
epicsGuard<epics::pvData::Mutex> guard(mutex);
|
||||
PVStringArrayPtr xxx;
|
||||
if(isDestroyed) {
|
||||
return xxx;
|
||||
}
|
||||
PVStringArrayPtr pvStringArray = static_pointer_cast<PVStringArray>
|
||||
(getPVDataCreate()->createPVScalarArray(pvString));
|
||||
size_t len = recordMap.size();
|
||||
shared_vector<string> names(len);
|
||||
PVRecordMap::iterator iter;
|
||||
size_t i = 0;
|
||||
for(iter = recordMap.begin(); iter!=recordMap.end(); ++iter) {
|
||||
names[i++] = (*iter).first;
|
||||
}
|
||||
shared_vector<const string> temp(freeze(names));
|
||||
pvStringArray->replace(temp);
|
||||
return pvStringArray;
|
||||
}
|
||||
|
||||
bool PVDatabase::addRecord(PVRecordPtr const & record)
|
||||
{
|
||||
epicsGuard<epics::pvData::Mutex> guard(mutex);
|
||||
@ -131,10 +109,31 @@ bool PVDatabase::removeRecord(PVRecordPtr const & record)
|
||||
if(iter!=recordMap.end()) {
|
||||
PVRecordPtr pvRecord = (*iter).second;
|
||||
recordMap.erase(iter);
|
||||
if(pvRecord.get()!=NULL) pvRecord->destroy();
|
||||
if(pvRecord) pvRecord->destroy();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
PVStringArrayPtr PVDatabase::getRecordNames()
|
||||
{
|
||||
epicsGuard<epics::pvData::Mutex> guard(mutex);
|
||||
PVStringArrayPtr xxx;
|
||||
if(isDestroyed) {
|
||||
return xxx;
|
||||
}
|
||||
PVStringArrayPtr pvStringArray = static_pointer_cast<PVStringArray>
|
||||
(getPVDataCreate()->createPVScalarArray(pvString));
|
||||
size_t len = recordMap.size();
|
||||
shared_vector<string> names(len);
|
||||
PVRecordMap::iterator iter;
|
||||
size_t i = 0;
|
||||
for(iter = recordMap.begin(); iter!=recordMap.end(); ++iter) {
|
||||
names[i++] = (*iter).first;
|
||||
}
|
||||
shared_vector<const string> temp(freeze(names));
|
||||
pvStringArray->replace(temp);
|
||||
return pvStringArray;
|
||||
}
|
||||
|
||||
}}
|
||||
|
@ -66,11 +66,13 @@ void PVRecord::initPVRecord()
|
||||
|
||||
void PVRecord::destroy()
|
||||
{
|
||||
if(traceLevel>0) {
|
||||
cout << "PVRecord::destroy() " << recordName << endl;
|
||||
}
|
||||
{
|
||||
epicsGuard<epics::pvData::Mutex> guard(mutex);
|
||||
if(traceLevel>0) {
|
||||
cout << "PVRecord::destroy() " << recordName
|
||||
<< " isDestroyed " << (isDestroyed ? "true" : "false")
|
||||
<< endl;
|
||||
}
|
||||
if(isDestroyed) {
|
||||
return;
|
||||
}
|
||||
@ -91,9 +93,8 @@ void PVRecord::destroy()
|
||||
listener->unlisten(shared_from_this());
|
||||
}
|
||||
pvListenerList.clear();
|
||||
std::list<PVRecordClientPtr>::iterator iter;
|
||||
for (iter = pvRecordClientList.begin();
|
||||
iter!=pvRecordClientList.end();
|
||||
for (std::list<PVRecordClientPtr>::iterator iter = clientList.begin();
|
||||
iter!=clientList.end();
|
||||
iter++ )
|
||||
{
|
||||
PVRecordClientPtr client = *iter;
|
||||
@ -103,7 +104,7 @@ void PVRecord::destroy()
|
||||
}
|
||||
client->detach(shared_from_this());
|
||||
}
|
||||
pvRecordClientList.clear();
|
||||
clientList.clear();
|
||||
}
|
||||
|
||||
void PVRecord::process()
|
||||
@ -117,11 +118,6 @@ void PVRecord::process()
|
||||
}
|
||||
}
|
||||
|
||||
string PVRecord::getRecordName() const {return recordName;}
|
||||
|
||||
PVRecordStructurePtr PVRecord::getPVRecordStructure() const {return pvRecordStructure;}
|
||||
|
||||
PVStructurePtr PVRecord::getPVStructure() {return pvStructure;}
|
||||
|
||||
PVRecordFieldPtr PVRecord::findPVRecordField(PVFieldPtr const & pvField)
|
||||
{
|
||||
@ -199,8 +195,8 @@ bool PVRecord::addPVRecordClient(PVRecordClientPtr const & pvRecordClient)
|
||||
return false;
|
||||
}
|
||||
std::list<PVRecordClientPtr>::iterator iter;
|
||||
for (iter = pvRecordClientList.begin();
|
||||
iter!=pvRecordClientList.end();
|
||||
for (iter = clientList.begin();
|
||||
iter!=clientList.end();
|
||||
iter++ )
|
||||
{
|
||||
PVRecordClientPtr client = *iter;
|
||||
@ -209,9 +205,9 @@ bool PVRecord::addPVRecordClient(PVRecordClientPtr const & pvRecordClient)
|
||||
}
|
||||
}
|
||||
if(traceLevel>1) {
|
||||
cout << "PVRecord::addPVRecordClient() calling pvRecordClientList.push_back(pvRecordClient)" << recordName << endl;
|
||||
cout << "PVRecord::addPVRecordClient() calling clientList.push_back(pvRecordClient)" << recordName << endl;
|
||||
}
|
||||
pvRecordClientList.push_back(pvRecordClient);
|
||||
clientList.push_back(pvRecordClient);
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -225,14 +221,14 @@ bool PVRecord::removePVRecordClient(PVRecordClientPtr const & pvRecordClient)
|
||||
return false;
|
||||
}
|
||||
std::list<PVRecordClientPtr>::iterator iter;
|
||||
for (iter = pvRecordClientList.begin();
|
||||
iter!=pvRecordClientList.end();
|
||||
for (iter = clientList.begin();
|
||||
iter!=clientList.end();
|
||||
iter++ )
|
||||
{
|
||||
PVRecordClientPtr client = *iter;
|
||||
if(!client) continue;
|
||||
if(client==pvRecordClient) {
|
||||
pvRecordClientList.erase(iter);
|
||||
clientList.erase(iter);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@ -517,24 +513,4 @@ PVRecordFieldPtrArrayPtr PVRecordStructure::getPVRecordFields()
|
||||
|
||||
PVStructurePtr PVRecordStructure::getPVStructure() {return pvStructure.lock();}
|
||||
|
||||
void PVRecordStructure::removeListener(PVListenerPtr const & pvListener)
|
||||
{
|
||||
PVRecordField::removeListener(pvListener);
|
||||
size_t numFields = pvRecordFields->size();
|
||||
for(size_t i=0; i<numFields; i++) {
|
||||
PVRecordFieldPtr pvRecordField = (*pvRecordFields.get())[i];
|
||||
pvRecordField->removeListener(pvListener);
|
||||
}
|
||||
}
|
||||
|
||||
void PVRecordStructure::postPut()
|
||||
{
|
||||
PVRecordField::postPut();
|
||||
size_t numFields = pvRecordFields->size();
|
||||
for(size_t i=0; i<numFields; i++) {
|
||||
PVRecordFieldPtr pvRecordField = (*pvRecordFields.get())[i];
|
||||
pvRecordField->callListener();
|
||||
}
|
||||
}
|
||||
|
||||
}}
|
||||
|
@ -100,6 +100,7 @@ private:
|
||||
|
||||
epicsShareFunc ChannelProviderLocalPtr getChannelProviderLocal();
|
||||
|
||||
|
||||
/**
|
||||
* @brief ChannelProvider for PVDatabase.
|
||||
*
|
||||
@ -229,6 +230,12 @@ public:
|
||||
* The remote pvAccess server does this cleanup.
|
||||
*/
|
||||
virtual void destroy();
|
||||
/**
|
||||
* This is called when a record is being removed from the database.
|
||||
* Calls destroy.
|
||||
* @param pvRecord The record being destroyed.
|
||||
*/
|
||||
virtual void detach(PVRecordPtr const &pvRecord);
|
||||
/**
|
||||
* Get the requester name.
|
||||
* @return returns the name of the channel requester.
|
||||
@ -381,12 +388,6 @@ public:
|
||||
* @param out the stream on which the message is displayed.
|
||||
*/
|
||||
virtual void printInfo(std::ostream& out);
|
||||
/**
|
||||
* This is called when a record is being removed from the database.
|
||||
* Calls destroy.
|
||||
* @param pvRecord The record being destroyed.
|
||||
*/
|
||||
virtual void detach(PVRecordPtr const &pvRecord);
|
||||
protected:
|
||||
shared_pointer getPtrSelf()
|
||||
{
|
||||
@ -396,7 +397,7 @@ private:
|
||||
epics::pvAccess::ChannelRequester::shared_pointer requester;
|
||||
ChannelProviderLocalPtr provider;
|
||||
PVRecordPtr pvRecord;
|
||||
bool beingDestroyed;
|
||||
bool isDestroyed;
|
||||
epics::pvData::Mutex mutex;
|
||||
};
|
||||
|
||||
|
@ -115,12 +115,17 @@ public:
|
||||
* Get the name of the record.
|
||||
* @return The name.
|
||||
*/
|
||||
std::string getRecordName() const;
|
||||
std::string getRecordName() const { return recordName;}
|
||||
/**
|
||||
* Get the top level PVRecordStructure.
|
||||
* @return The shared pointer.
|
||||
*/
|
||||
PVRecordStructurePtr getPVRecordStructure() const;
|
||||
PVRecordStructurePtr getPVRecordStructure() const { return pvRecordStructure;}
|
||||
/**
|
||||
* Convenience method for derived classes.
|
||||
* @return The top level PVStructure.
|
||||
*/
|
||||
epics::pvData::PVStructurePtr getPVStructure() const { return pvStructure;}
|
||||
/**
|
||||
* Find the PVRecordField for the PVField.
|
||||
* @param pvField The PVField.
|
||||
@ -232,11 +237,6 @@ protected:
|
||||
* Initializes the base class. Must be called by derived classes.
|
||||
*/
|
||||
void initPVRecord();
|
||||
/**
|
||||
* Convience method for derived classes.
|
||||
* @return The shared pointer to the top level PVStructure.
|
||||
*/
|
||||
epics::pvData::PVStructurePtr getPVStructure();
|
||||
/** Get shared pointer to self
|
||||
* @return The shared pointer.
|
||||
*/
|
||||
@ -253,7 +253,7 @@ private:
|
||||
epics::pvData::PVStructurePtr pvStructure;
|
||||
PVRecordStructurePtr pvRecordStructure;
|
||||
std::list<PVListenerWPtr> pvListenerList;
|
||||
std::list<PVRecordClientPtr> pvRecordClientList;
|
||||
std::list<PVRecordClientPtr> clientList;
|
||||
epics::pvData::Mutex mutex;
|
||||
std::size_t depthGroupPut;
|
||||
int traceLevel;
|
||||
@ -378,17 +378,12 @@ public:
|
||||
* @return The shared pointer.
|
||||
*/
|
||||
epics::pvData::PVStructurePtr getPVStructure();
|
||||
/**
|
||||
* Called by implementation code of PVRecord.
|
||||
*/
|
||||
virtual void postPut();
|
||||
protected:
|
||||
/**
|
||||
* Called by implementation code of PVRecord.
|
||||
*/
|
||||
virtual void init();
|
||||
private:
|
||||
virtual void removeListener(PVListenerPtr const & pvListener);
|
||||
epics::pvData::PVStructure::weak_pointer pvStructure;
|
||||
PVRecordFieldPtrArrayPtr pvRecordFields;
|
||||
friend class PVRecord;
|
||||
|
@ -65,7 +65,6 @@ private:
|
||||
PVDatabasePtr pvDatabase;
|
||||
epics::pvData::PVStringPtr pvRecordName;
|
||||
epics::pvData::PVStringPtr pvResult;
|
||||
bool isDestroyed;
|
||||
};
|
||||
|
||||
}}
|
||||
|
@ -66,7 +66,6 @@ private:
|
||||
epics::pvData::PVStringPtr pvRecordName;
|
||||
epics::pvData::PVIntPtr pvLevel;
|
||||
epics::pvData::PVStringPtr pvResult;
|
||||
bool isDestroyed;
|
||||
};
|
||||
|
||||
}}
|
||||
|
@ -1309,7 +1309,7 @@ ChannelLocal::ChannelLocal(
|
||||
requester(requester),
|
||||
provider(provider),
|
||||
pvRecord(pvRecord),
|
||||
beingDestroyed(false)
|
||||
isDestroyed(false)
|
||||
{
|
||||
if(pvRecord->getTraceLevel()>0) {
|
||||
cout << "ChannelLocal::ChannelLocal()"
|
||||
@ -1325,6 +1325,7 @@ ChannelLocal::~ChannelLocal()
|
||||
{
|
||||
cout << "~ChannelLocal()" << endl;
|
||||
}
|
||||
destroy();
|
||||
}
|
||||
|
||||
void ChannelLocal::destroy()
|
||||
@ -1332,16 +1333,15 @@ void ChannelLocal::destroy()
|
||||
if(pvRecord->getTraceLevel()>0) {
|
||||
cout << "ChannelLocal::destroy()"
|
||||
<< " recordName " << pvRecord->getRecordName()
|
||||
<< " beingDestroyed " << beingDestroyed
|
||||
<< " isDestroyed " << isDestroyed
|
||||
<< " requester exists " << (requester ? "true" : "false")
|
||||
<< endl;
|
||||
}
|
||||
{
|
||||
Lock xx(mutex);
|
||||
if(beingDestroyed) return;
|
||||
beingDestroyed = true;
|
||||
if(isDestroyed) return;
|
||||
isDestroyed = true;
|
||||
}
|
||||
message("being destroyed",fatalErrorMessage);
|
||||
pvRecord->removePVRecordClient(getPtrSelf());
|
||||
}
|
||||
|
||||
@ -1383,7 +1383,7 @@ void ChannelLocal::message(
|
||||
}
|
||||
{
|
||||
Lock xx(mutex);
|
||||
if(beingDestroyed) return;
|
||||
if(isDestroyed) return;
|
||||
}
|
||||
if(requester) {
|
||||
requester->message(message,messageType);
|
||||
@ -1403,7 +1403,7 @@ string ChannelLocal::getRemoteAddress()
|
||||
Channel::ConnectionState ChannelLocal::getConnectionState()
|
||||
{
|
||||
Lock xx(mutex);
|
||||
if(beingDestroyed) return Channel::DESTROYED;
|
||||
if(isDestroyed) return Channel::DESTROYED;
|
||||
return Channel::CONNECTED;
|
||||
}
|
||||
|
||||
@ -1420,7 +1420,7 @@ ChannelRequester::shared_pointer ChannelLocal::getChannelRequester()
|
||||
bool ChannelLocal::isConnected()
|
||||
{
|
||||
Lock xx(mutex);
|
||||
if(beingDestroyed) return false;
|
||||
if(isDestroyed) return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -53,7 +53,7 @@ public:
|
||||
}
|
||||
virtual ChannelProvider::shared_pointer newInstance()
|
||||
{
|
||||
return channelProvider;
|
||||
throw std::logic_error("newInstance not Implemented");
|
||||
}
|
||||
private:
|
||||
LocalChannelProviderFactory(
|
||||
@ -76,7 +76,7 @@ ChannelProviderLocalPtr getChannelProviderLocal()
|
||||
channelProviderLocal->channelFinder =
|
||||
SyncChannelFind::shared_pointer(new SyncChannelFind(xxx));
|
||||
LocalChannelProviderFactoryPtr factory(LocalChannelProviderFactory::create(channelProviderLocal));
|
||||
registerChannelProviderFactory(factory);
|
||||
|
||||
}
|
||||
return channelProviderLocal;
|
||||
}
|
||||
@ -89,7 +89,6 @@ ChannelProviderLocal::ChannelProviderLocal()
|
||||
|
||||
ChannelProviderLocal::~ChannelProviderLocal()
|
||||
{
|
||||
// TODO should I call destroy() here
|
||||
destroy();
|
||||
}
|
||||
|
||||
@ -99,6 +98,7 @@ void ChannelProviderLocal::destroy()
|
||||
if(beingDestroyed) return;
|
||||
beingDestroyed = true;
|
||||
pvDatabase->destroy();
|
||||
pvDatabase.reset();
|
||||
}
|
||||
|
||||
string ChannelProviderLocal::getProviderName()
|
||||
@ -145,15 +145,6 @@ Channel::shared_pointer ChannelProviderLocal::createChannel(
|
||||
string const & channelName,
|
||||
ChannelRequester::shared_pointer const &channelRequester,
|
||||
short priority)
|
||||
{
|
||||
return createChannel(channelName,channelRequester,priority,"");
|
||||
}
|
||||
|
||||
Channel::shared_pointer ChannelProviderLocal::createChannel(
|
||||
string const & channelName,
|
||||
ChannelRequester::shared_pointer const &channelRequester,
|
||||
short priority,
|
||||
string const &address)
|
||||
{
|
||||
Lock xx(mutex);
|
||||
PVRecordPtr pvRecord = pvDatabase->findRecord(channelName);
|
||||
@ -171,6 +162,17 @@ Channel::shared_pointer ChannelProviderLocal::createChannel(
|
||||
notFoundStatus,
|
||||
Channel::shared_pointer());
|
||||
return Channel::shared_pointer();
|
||||
|
||||
}
|
||||
|
||||
Channel::shared_pointer ChannelProviderLocal::createChannel(
|
||||
string const & channelName,
|
||||
ChannelRequester::shared_pointer const &channelRequester,
|
||||
short priority,
|
||||
string const &address)
|
||||
{
|
||||
if(!address.empty()) throw std::invalid_argument("address not allowed for local implementation");
|
||||
return createChannel(channelName, channelRequester, priority);
|
||||
}
|
||||
|
||||
}}
|
||||
|
@ -109,6 +109,7 @@ MonitorLocal::~MonitorLocal()
|
||||
{
|
||||
cout << "MonitorLocal::~MonitorLocal()" << endl;
|
||||
}
|
||||
destroy();
|
||||
}
|
||||
|
||||
void MonitorLocal::destroy()
|
||||
@ -121,16 +122,11 @@ void MonitorLocal::destroy()
|
||||
Lock xx(mutex);
|
||||
if(state==destroyed) return;
|
||||
}
|
||||
if(pvCopy) pvCopy->destroy();
|
||||
if(state==active) stop();
|
||||
{
|
||||
Lock xx(mutex);
|
||||
state = destroyed;
|
||||
}
|
||||
{
|
||||
Lock xx(queueMutex);
|
||||
queue.reset();
|
||||
}
|
||||
pvCopy.reset();
|
||||
}
|
||||
|
||||
Status MonitorLocal::start()
|
||||
|
@ -43,8 +43,7 @@ RemoveRecord::RemoveRecord(
|
||||
std::string const & recordName,
|
||||
epics::pvData::PVStructurePtr const & pvStructure)
|
||||
: PVRecord(recordName,pvStructure),
|
||||
pvDatabase(PVDatabase::getMaster()),
|
||||
isDestroyed(false)
|
||||
pvDatabase(PVDatabase::getMaster())
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -44,8 +44,7 @@ TraceRecord::TraceRecord(
|
||||
std::string const & recordName,
|
||||
epics::pvData::PVStructurePtr const & pvStructure)
|
||||
: PVRecord(recordName,pvStructure),
|
||||
pvDatabase(PVDatabase::getMaster()),
|
||||
isDestroyed(false)
|
||||
pvDatabase(PVDatabase::getMaster())
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -61,6 +61,7 @@ static void test()
|
||||
PVRecordPtr pvRecord(PVRecord::create(recordName,pvStructure));
|
||||
RecordClientPtr exampleRecordClient(RecordClient::create(pvRecord));
|
||||
ListenerPtr exampleListener(Listener::create(pvRecord));
|
||||
if(debug) pvRecord->setTraceLevel(3);
|
||||
master->addRecord(pvRecord);
|
||||
pvRecord = master->findRecord("exampleDouble");
|
||||
testOk1(pvRecord.get()!=0);
|
||||
|
Reference in New Issue
Block a user