also address issue 35

This commit is contained in:
mrkraimer
2018-05-24 10:21:28 -04:00
parent 87ccf78a9b
commit 6239ef0c0c
7 changed files with 464 additions and 350 deletions

View File

@ -21,21 +21,37 @@ using namespace std;
namespace epics { namespace pvDatabase {
#define DEBUG_LEVEL 0
static PVDatabasePtr pvDatabaseMaster;
bool PVDatabase::getMasterFirstCall = true;
PVDatabasePtr PVDatabase::getMaster()
{
if(!pvDatabaseMaster) pvDatabaseMaster = PVDatabasePtr(new PVDatabase());
if(getMasterFirstCall) {
getMasterFirstCall = false;
pvDatabaseMaster = PVDatabasePtr(new PVDatabase());
}
return pvDatabaseMaster;
}
PVDatabase::PVDatabase()
{
if(DEBUG_LEVEL>0) cout << "PVDatabase::PVDatabase()\n";
}
PVDatabase::~PVDatabase()
{
cout << "PVDatabase::~PVDatabase()\n";
if(DEBUG_LEVEL>0) cout << "PVDatabase::~PVDatabase()\n";
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;
}
for(size_t i=0; i<len; ++i) removeRecord(findRecord(names[i]));
}
void PVDatabase::lock() {
@ -83,7 +99,6 @@ bool PVDatabase::removeRecord(PVRecordPtr const & record)
if(iter!=recordMap.end()) {
PVRecordPtr pvRecord = (*iter).second;
recordMap.erase(iter);
if(pvRecord) pvRecord->destroy();
return true;
}
return false;

View File

@ -46,11 +46,62 @@ PVRecord::PVRecord(
{
}
void PVRecord::notifyClients()
{
{
epicsGuard<epics::pvData::Mutex> guard(mutex);
if(traceLevel>0) {
cout << "PVRecord::notifyClients() " << recordName
<< " isDestroyed " << (isDestroyed ? "true" : "false")
<< endl;
}
if(isDestroyed) {
return;
}
isDestroyed = true;
}
pvTimeStamp.detach();
for(std::list<PVListenerWPtr>::iterator iter = pvListenerList.begin();
iter!=pvListenerList.end();
iter++ )
{
PVListenerPtr listener = iter->lock();
if(!listener) continue;
if(traceLevel>0) {
cout << "PVRecord::notifyClients() calling listener->unlisten "
<< recordName << endl;
}
listener->unlisten(shared_from_this());
}
pvListenerList.clear();
for (std::list<PVRecordClientWPtr>::iterator iter = clientList.begin();
iter!=clientList.end();
iter++ )
{
PVRecordClientPtr client = iter->lock();
if(!client) continue;
if(traceLevel>0) {
cout << "PVRecord::notifyClients() calling client->detach "
<< recordName << endl;
}
client->detach(shared_from_this());
}
if(traceLevel>0) {
cout << "PVRecord::notifyClients() calling clientList.clear() "
<< recordName << endl;
}
clientList.clear();
if(traceLevel>0) {
cout << "PVRecord::notifyClients() returning " << recordName << endl;
}
}
PVRecord::~PVRecord()
{
if(traceLevel>0) {
cout << "~PVRecord() " << recordName << endl;
}
notifyClients();
}
void PVRecord::initPVRecord()
@ -65,45 +116,9 @@ void PVRecord::initPVRecord()
void PVRecord::destroy()
{
{
epicsGuard<epics::pvData::Mutex> guard(mutex);
if(traceLevel>0) {
cout << "PVRecord::destroy() " << recordName
<< " isDestroyed " << (isDestroyed ? "true" : "false")
<< endl;
}
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) continue;
if(traceLevel>0) {
cout << "PVRecord::destroy() calling listener->unlisten " << recordName << endl;
}
listener->unlisten(shared_from_this());
}
pvListenerList.clear();
for (std::list<PVRecordClientPtr>::iterator iter = clientList.begin();
iter!=clientList.end();
iter++ )
{
PVRecordClientPtr client = *iter;
if(!client) continue;
if(traceLevel>0) {
cout << "PVRecord::destroy() calling client->detach " << recordName << endl;
}
client->detach(shared_from_this());
}
clientList.clear();
notifyClients();
}
void PVRecord::process()
@ -194,47 +209,31 @@ bool PVRecord::addPVRecordClient(PVRecordClientPtr const & pvRecordClient)
if(isDestroyed) {
return false;
}
std::list<PVRecordClientPtr>::iterator iter;
// clean clientList
bool clientListClean = false;
while(!clientListClean) {
if(clientList.empty()) break;
clientListClean = true;
std::list<PVRecordClientWPtr>::iterator iter;
for (iter = clientList.begin();
iter!=clientList.end();
iter++ )
{
PVRecordClientPtr client = *iter;
if(client==pvRecordClient) {
return false;
}
}
PVRecordClientPtr client = iter->lock();
if(client) continue;
if(traceLevel>1) {
cout << "PVRecord::addPVRecordClient() calling clientList.push_back(pvRecordClient)" << recordName << endl;
cout << "PVRecord::addPVRecordClient() erasing client"
<< recordName << endl;
}
clientList.erase(iter);
clientListClean = false;
break;
}
}
clientList.push_back(pvRecordClient);
return true;
}
bool PVRecord::removePVRecordClient(PVRecordClientPtr const & pvRecordClient)
{
if(traceLevel>1) {
cout << "PVRecord::removePVRecordClient() " << recordName << endl;
}
epicsGuard<epics::pvData::Mutex> guard(mutex);
if(isDestroyed) {
return false;
}
std::list<PVRecordClientPtr>::iterator iter;
for (iter = clientList.begin();
iter!=clientList.end();
iter++ )
{
PVRecordClientPtr client = *iter;
if(!client) continue;
if(client==pvRecordClient) {
clientList.erase(iter);
return true;
}
}
return false;
}
bool PVRecord::addListener(
PVListenerPtr const & pvListener,
PVCopyPtr const & pvCopy)
@ -246,15 +245,6 @@ bool PVRecord::addListener(
if(isDestroyed) {
return false;
}
std::list<PVListenerWPtr>::iterator iter;
for (iter = pvListenerList.begin(); iter!=pvListenerList.end(); iter++ )
{
PVListenerPtr listener = iter->lock();
if(!listener.get()) continue;
if(listener.get()==pvListener.get()) {
return false;
}
}
pvListenerList.push_back(pvListener);
this->pvListener = pvListener;
isAddListener = true;
@ -394,14 +384,6 @@ bool PVRecordField::addListener(PVListenerPtr const & pvListener)
if(pvRecord && pvRecord->getTraceLevel()>1) {
cout << "PVRecordField::addListener() " << getFullName() << endl;
}
std::list<PVListenerWPtr>::iterator iter;
for (iter = pvListenerList.begin(); iter!=pvListenerList.end(); iter++ ) {
PVListenerPtr listener = iter->lock();
if(!listener.get()) continue;
if(listener.get()==pvListener.get()) {
return false;
}
}
pvListenerList.push_back(pvListener);
return true;
}
@ -450,7 +432,8 @@ void PVRecordField::postSubField()
{
callListener();
if(isStructure) {
PVRecordStructurePtr pvrs = static_pointer_cast<PVRecordStructure>(shared_from_this());
PVRecordStructurePtr pvrs =
static_pointer_cast<PVRecordStructure>(shared_from_this());
PVRecordFieldPtrArrayPtr pvRecordFields = pvrs->getPVRecordFields();
PVRecordFieldPtrArray::iterator iter;
for(iter = pvRecordFields->begin() ; iter !=pvRecordFields->end(); iter++) {

View File

@ -43,8 +43,10 @@ namespace epics { namespace pvDatabase {
class ChannelProviderLocal;
typedef std::tr1::shared_ptr<ChannelProviderLocal> ChannelProviderLocalPtr;
typedef std::tr1::weak_ptr<ChannelProviderLocal> ChannelProviderLocalWPtr;
class ChannelLocal;
typedef std::tr1::shared_ptr<ChannelLocal> ChannelLocalPtr;
typedef std::tr1::weak_ptr<ChannelLocal> ChannelLocalWPtr;
epicsShareFunc epics::pvData::MonitorPtr createMonitorLocal(
@ -82,11 +84,13 @@ public:
virtual void destroy() EPICS_DEPRECATED {};
/**
* @brief Returns the channel provider name.
*
* @return <b>local</b>
*/
virtual std::string getProviderName();
/**
* @brief Returns either a null channelFind or a channelFind for records in the PVDatabase.
*
* @param channelName The name of the channel desired.
* @param channelFindRequester The client callback.
* @return shared pointer to ChannelFind.
@ -162,10 +166,10 @@ public:
* @brief ChannelFind method.
*
*/
virtual void cancel();
virtual void cancel() {}
private:
friend epicsShareFunc ChannelProviderLocalPtr getChannelProviderLocal();
PVDatabasePtr pvDatabase;
PVDatabaseWPtr pvDatabase;
int traceLevel;
friend class ChannelProviderLocalRun;
};
@ -206,8 +210,7 @@ public:
* @brief Detach from the record.
*
* This is called when a record is being removed from the database.
* Calls destroy.
* @param pvRecord The record being destroyed.
* @param pvRecord The record being removed.
*/
virtual void detach(PVRecordPtr const &pvRecord);
/**
@ -227,10 +230,7 @@ public:
* @brief Get the channel provider
* @return The provider.
*/
virtual epics::pvAccess::ChannelProvider::shared_pointer getProvider()
{
return provider;
}
virtual epics::pvAccess::ChannelProvider::shared_pointer getProvider();
/**
* @brief Get the remote address
* @return <b>local</b>
@ -369,8 +369,8 @@ protected:
}
private:
epics::pvAccess::ChannelRequester::shared_pointer requester;
ChannelProviderLocalPtr provider;
PVRecordPtr pvRecord;
ChannelProviderLocalWPtr provider;
PVRecordWPtr pvRecord;
epics::pvData::Mutex mutex;
};

View File

@ -13,7 +13,6 @@
#include <list>
#include <map>
#include <deque>
#include <pv/pvData.h>
#include <pv/pvCopy.h>
@ -46,6 +45,7 @@ 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;
@ -53,6 +53,7 @@ typedef std::tr1::weak_ptr<PVListener> PVListenerWPtr;
class PVDatabase;
typedef std::tr1::shared_ptr<PVDatabase> PVDatabasePtr;
typedef std::tr1::weak_ptr<PVDatabase> PVDatabaseWPtr;
/**
* @brief Base interface for a PVRecord.
@ -97,12 +98,16 @@ public:
*/
virtual void process();
/**
* @brief Optional method for derived class.
* @brief Destroy the record.
*
* Destroy the PVRecord. Release any resources used and
* get rid of listeners and requesters.
* If derived class overrides this then it must call PVRecord::destroy()
* after it has destroyed any resorces it uses.
*
* Note: for most classes destroy no longer exists or has been deprecated.
* This method makes it possible to remove a record from a database
* while the database is still running.
*/
virtual void destroy();
/**
@ -195,13 +200,6 @@ public:
* @return <b>true</b> if the client is added.
*/
bool addPVRecordClient(PVRecordClientPtr const & pvRecordClient);
/**
* @brief Remove a client.
*
* @param pvRecordClient The client.
* @return <b>true</b> if the client is removed.
*/
bool removePVRecordClient(PVRecordClientPtr const & pvRecordClient);
/**
* @brief Add a PVListener.
*
@ -268,23 +266,23 @@ private:
PVRecordFieldPtr findPVRecordField(
PVRecordStructurePtr const & pvrs,
epics::pvData::PVFieldPtr const & pvField);
void notifyClients();
std::string recordName;
epics::pvData::PVStructurePtr pvStructure;
PVRecordStructurePtr pvRecordStructure;
std::list<PVListenerWPtr> pvListenerList;
std::list<PVRecordClientPtr> clientList;
std::list<PVRecordClientWPtr> clientList;
epics::pvData::Mutex mutex;
std::size_t depthGroupPut;
int traceLevel;
bool isDestroyed;
epics::pvData::PVTimeStamp pvTimeStamp;
epics::pvData::TimeStamp timeStamp;
// following only valid while addListener or removeListener is active.
bool isAddListener;
PVListenerWPtr pvListener;
epics::pvData::PVTimeStamp pvTimeStamp;
epics::pvData::TimeStamp timeStamp;
};
epicsShareFunc std::ostream& operator<<(std::ostream& o, const PVRecord& record);
@ -527,6 +525,7 @@ private:
void unlock();
PVRecordMap recordMap;
epics::pvData::Mutex mutex;
static bool getMasterFirstCall;
};
}}

View File

@ -31,25 +31,6 @@ using std::string;
namespace epics { namespace pvDatabase {
static StructureConstPtr nullStructure;
static PVStructurePtr nullPVStructure;
static BitSetPtr nullBitSet;
static Status channelDestroyedStatus(
Status::STATUSTYPE_ERROR,
"was destroyed"
);
static Status illegalOffsetStatus(
Status::STATUSTYPE_ERROR,
"count must be >0"
);
static Status illegalCountStatus(
Status::STATUSTYPE_ERROR,
"count must be >0"
);
static Status illegalStrideStatus(
Status::STATUSTYPE_ERROR,
"stride must be >0"
);
class ChannelProcessLocal;
typedef std::tr1::shared_ptr<ChannelProcessLocal> ChannelProcessLocalPtr;
@ -59,8 +40,6 @@ class ChannelPutLocal;
typedef std::tr1::shared_ptr<ChannelPutLocal> ChannelPutLocalPtr;
class ChannelPutGetLocal;
typedef std::tr1::shared_ptr<ChannelPutGetLocal> ChannelPutGetLocalPtr;
class ChannelMonitorLocal;
typedef std::tr1::shared_ptr<ChannelMonitorLocal> ChannelMonitorLocalPtr;
class ChannelRPCLocal;
typedef std::tr1::shared_ptr<ChannelRPCLocal> ChannelRPCLocalPtr;
class ChannelArrayLocal;
@ -90,13 +69,7 @@ class ChannelProcessLocal :
{
public:
POINTER_DEFINITIONS(ChannelProcessLocal);
virtual ~ChannelProcessLocal()
{
if(pvRecord->getTraceLevel()>0)
{
cout << "~ChannelProcessLocal() " << endl;
}
}
virtual ~ChannelProcessLocal();
static ChannelProcessLocalPtr create(
ChannelLocalPtr const &channelLocal,
ChannelProcessRequester::shared_pointer const & channelProcessRequester,
@ -104,12 +77,11 @@ public:
PVRecordPtr const &pvRecord);
virtual void process();
virtual void destroy() EPICS_DEPRECATED {};
virtual std::tr1::shared_ptr<Channel> getChannel()
{return channelLocal;}
virtual std::tr1::shared_ptr<Channel> getChannel();
virtual void cancel(){}
virtual void lock();
virtual void unlock();
virtual void lastRequest() {}
virtual void lock() {pvRecord->lock();}
virtual void unlock() {pvRecord->unlock();}
private:
shared_pointer getPtrSelf()
{
@ -127,9 +99,9 @@ private:
nProcess(nProcess)
{
}
ChannelLocalPtr channelLocal;
ChannelLocalWPtr channelLocal;
ChannelProcessRequester::weak_pointer channelProcessRequester;
PVRecordPtr pvRecord;
PVRecordWPtr pvRecord;
int nProcess;
Mutex mutex;
};
@ -172,21 +144,50 @@ ChannelProcessLocalPtr ChannelProcessLocal::create(
return process;
}
ChannelProcessLocal::~ChannelProcessLocal()
{
PVRecordPtr pvr(pvRecord.lock());
if(pvr && pvr->getTraceLevel()>0) {
cout << "~ChannelProcessLocal() " << pvr->getRecordName() << endl;
}
}
std::tr1::shared_ptr<Channel> ChannelProcessLocal::getChannel()
{
ChannelLocalPtr channel(channelLocal.lock());
return channel;
}
void ChannelProcessLocal::lock()
{
PVRecordPtr pvr(pvRecord.lock());
if(!pvr) throw std::logic_error("pvRecord is deleted");
pvr->lock();
}
void ChannelProcessLocal::unlock()
{
PVRecordPtr pvr(pvRecord.lock());
if(!pvr) throw std::logic_error("pvRecord is deleted");
pvr->unlock();
}
void ChannelProcessLocal::process()
{
ChannelProcessRequester::shared_pointer requester = channelProcessRequester.lock();
if(!requester) return;
if(pvRecord->getTraceLevel()>1)
PVRecordPtr pvr(pvRecord.lock());
if(!pvr) throw std::logic_error("pvRecord is deleted");
if(pvr->getTraceLevel()>1)
{
cout << "ChannelProcessLocal::process";
cout << " nProcess " << nProcess << endl;
}
try {
for(int i=0; i< nProcess; i++) {
epicsGuard <PVRecord> guard(*pvRecord);
pvRecord->beginGroupPut();
pvRecord->process();
pvRecord->endGroupPut();
epicsGuard <PVRecord> guard(*pvr);
pvr->beginGroupPut();
pvr->process();
pvr->endGroupPut();
}
requester->processDone(Status::Ok,getPtrSelf());
} catch(std::exception& ex) {
@ -201,13 +202,7 @@ class ChannelGetLocal :
{
public:
POINTER_DEFINITIONS(ChannelGetLocal);
virtual ~ChannelGetLocal()
{
if(pvRecord->getTraceLevel()>0)
{
cout << "~ChannelGetLocal()" << endl;
}
}
virtual ~ChannelGetLocal();
static ChannelGetLocalPtr create(
ChannelLocalPtr const &channelLocal,
ChannelGetRequester::shared_pointer const & channelGetRequester,
@ -215,12 +210,11 @@ public:
PVRecordPtr const &pvRecord);
virtual void get();
virtual void destroy() EPICS_DEPRECATED {};
virtual std::tr1::shared_ptr<Channel> getChannel()
{return channelLocal;}
virtual std::tr1::shared_ptr<Channel> getChannel();
virtual void cancel(){}
virtual void lock();
virtual void unlock();
virtual void lastRequest() {}
virtual void lock() {pvRecord->lock();}
virtual void unlock() {pvRecord->unlock();}
private:
shared_pointer getPtrSelf()
{
@ -247,12 +241,12 @@ private:
}
bool firstTime;
bool callProcess;
ChannelLocalPtr channelLocal;
ChannelLocalWPtr channelLocal;
ChannelGetRequester::weak_pointer channelGetRequester;
PVCopyPtr pvCopy;
PVStructurePtr pvStructure;
BitSetPtr bitSet;
PVRecordPtr pvRecord;
PVRecordWPtr pvRecord;
Mutex mutex;
};
@ -298,19 +292,48 @@ ChannelGetLocalPtr ChannelGetLocal::create(
return get;
}
ChannelGetLocal::~ChannelGetLocal()
{
PVRecordPtr pvr(pvRecord.lock());
if(pvr && pvr->getTraceLevel()>0) {
cout << "~ChannelGetLocal() " << pvr->getRecordName() << endl;
}
}
std::tr1::shared_ptr<Channel> ChannelGetLocal::getChannel()
{
ChannelLocalPtr channel(channelLocal.lock());
return channel;
}
void ChannelGetLocal::lock()
{
PVRecordPtr pvr(pvRecord.lock());
if(!pvr) throw std::logic_error("pvRecord is deleted");
pvr->lock();
}
void ChannelGetLocal::unlock()
{
PVRecordPtr pvr(pvRecord.lock());
if(!pvr) throw std::logic_error("pvRecord is deleted");
pvr->unlock();
}
void ChannelGetLocal::get()
{
ChannelGetRequester::shared_pointer requester = channelGetRequester.lock();
if(!requester) return;
PVRecordPtr pvr(pvRecord.lock());
if(!pvr) throw std::logic_error("pvRecord is deleted");
try {
bitSet->clear();
{
epicsGuard <PVRecord> guard(*pvRecord);
epicsGuard <PVRecord> guard(*pvr);
if(callProcess) {
pvRecord->beginGroupPut();
pvRecord->process();
pvRecord->endGroupPut();
pvr->beginGroupPut();
pvr->process();
pvr->endGroupPut();
}
pvCopy->updateCopySetBitSet(pvStructure, bitSet);
}
@ -324,7 +347,7 @@ void ChannelGetLocal::get()
getPtrSelf(),
pvStructure,
bitSet);
if(pvRecord->getTraceLevel()>1)
if(pvr->getTraceLevel()>1)
{
cout << "ChannelGetLocal::get" << endl;
}
@ -341,13 +364,7 @@ class ChannelPutLocal :
{
public:
POINTER_DEFINITIONS(ChannelPutLocal);
virtual ~ChannelPutLocal()
{
if(pvRecord->getTraceLevel()>0)
{
cout << "~ChannelPutLocal()" << endl;
}
}
virtual ~ChannelPutLocal();
static ChannelPutLocalPtr create(
ChannelLocalPtr const &channelLocal,
ChannelPutRequester::shared_pointer const & channelPutRequester,
@ -356,12 +373,11 @@ public:
virtual void put(PVStructurePtr const &pvStructure,BitSetPtr const &bitSet);
virtual void get();
virtual void destroy() EPICS_DEPRECATED {};
virtual std::tr1::shared_ptr<Channel> getChannel()
{return channelLocal;}
virtual std::tr1::shared_ptr<Channel> getChannel();
virtual void cancel(){}
virtual void lock();
virtual void unlock();
virtual void lastRequest() {}
virtual void lock() {pvRecord->lock();}
virtual void unlock() {pvRecord->unlock();}
private:
shared_pointer getPtrSelf()
{
@ -382,10 +398,10 @@ private:
{
}
bool callProcess;
ChannelLocalPtr channelLocal;
ChannelLocalWPtr channelLocal;
ChannelPutRequester::weak_pointer channelPutRequester;
PVCopyPtr pvCopy;
PVRecordPtr pvRecord;
PVRecordWPtr pvRecord;
Mutex mutex;
};
@ -429,22 +445,52 @@ ChannelPutLocalPtr ChannelPutLocal::create(
return put;
}
ChannelPutLocal::~ChannelPutLocal()
{
PVRecordPtr pvr(pvRecord.lock());
if(pvr && pvr->getTraceLevel()>0) {
cout << "~ChannelPutLocal() " << pvr->getRecordName() << endl;
}
}
std::tr1::shared_ptr<Channel> ChannelPutLocal::getChannel()
{
ChannelLocalPtr channel(channelLocal.lock());
return channel;
}
void ChannelPutLocal::lock()
{
PVRecordPtr pvr(pvRecord.lock());
if(!pvr) throw std::logic_error("pvRecord is deleted");
pvr->lock();
}
void ChannelPutLocal::unlock()
{
PVRecordPtr pvr(pvRecord.lock());
if(!pvr) throw std::logic_error("pvRecord is deleted");
pvr->unlock();
}
void ChannelPutLocal::get()
{
ChannelPutRequester::shared_pointer requester = channelPutRequester.lock();
if(!requester) return;
PVRecordPtr pvr(pvRecord.lock());
if(!pvr) throw std::logic_error("pvRecord is deleted");
try {
PVStructurePtr pvStructure = pvCopy->createPVStructure();
BitSetPtr bitSet(new BitSet(pvStructure->getNumberFields()));
bitSet->clear();
bitSet->set(0);
{
epicsGuard <PVRecord> guard(*pvRecord);
epicsGuard <PVRecord> guard(*pvr);
pvCopy->updateCopyFromBitSet(pvStructure, bitSet);
}
requester->getDone(
Status::Ok,getPtrSelf(),pvStructure,bitSet);
if(pvRecord->getTraceLevel()>1)
if(pvr->getTraceLevel()>1)
{
cout << "ChannelPutLocal::get" << endl;
}
@ -461,18 +507,20 @@ void ChannelPutLocal::put(
{
ChannelPutRequester::shared_pointer requester = channelPutRequester.lock();
if(!requester) return;
PVRecordPtr pvr(pvRecord.lock());
if(!pvr) throw std::logic_error("pvRecord is deleted");
try {
{
epicsGuard <PVRecord> guard(*pvRecord);
pvRecord->beginGroupPut();
epicsGuard <PVRecord> guard(*pvr);
pvr->beginGroupPut();
pvCopy->updateMaster(pvStructure, bitSet);
if(callProcess) {
pvRecord->process();
pvr->process();
}
pvRecord->endGroupPut();
pvr->endGroupPut();
}
requester->putDone(Status::Ok,getPtrSelf());
if(pvRecord->getTraceLevel()>1)
if(pvr->getTraceLevel()>1)
{
cout << "ChannelPutLocal::put" << endl;
}
@ -489,13 +537,7 @@ class ChannelPutGetLocal :
{
public:
POINTER_DEFINITIONS(ChannelPutGetLocal);
virtual ~ChannelPutGetLocal()
{
if(pvRecord->getTraceLevel()>0)
{
cout << "~ChannelPutGetLocal()" << endl;
}
}
virtual ~ChannelPutGetLocal();
static ChannelPutGetLocalPtr create(
ChannelLocalPtr const &channelLocal,
ChannelPutGetRequester::shared_pointer const & channelPutGetRequester,
@ -507,12 +549,11 @@ public:
virtual void getPut();
virtual void getGet();
virtual void destroy() EPICS_DEPRECATED {};
virtual std::tr1::shared_ptr<Channel> getChannel()
{return channelLocal;}
virtual std::tr1::shared_ptr<Channel> getChannel();
virtual void cancel(){}
virtual void lock();
virtual void unlock();
virtual void lastRequest() {}
virtual void lock() {pvRecord->lock();}
virtual void unlock() {pvRecord->unlock();}
private:
shared_pointer getPtrSelf()
{
@ -539,13 +580,13 @@ private:
{
}
bool callProcess;
ChannelLocalPtr channelLocal;
ChannelLocalWPtr channelLocal;
ChannelPutGetRequester::weak_pointer channelPutGetRequester;
PVCopyPtr pvPutCopy;
PVCopyPtr pvGetCopy;
PVStructurePtr pvGetStructure;
BitSetPtr getBitSet;
PVRecordPtr pvRecord;
PVRecordWPtr pvRecord;
Mutex mutex;
};
@ -597,25 +638,54 @@ ChannelPutGetLocalPtr ChannelPutGetLocal::create(
return putGet;
}
ChannelPutGetLocal::~ChannelPutGetLocal()
{
PVRecordPtr pvr(pvRecord.lock());
if(pvr && pvr->getTraceLevel()>0) {
cout << "~ChannelPutGetLocal() " << pvr->getRecordName() << endl;
}
}
std::tr1::shared_ptr<Channel> ChannelPutGetLocal::getChannel()
{
ChannelLocalPtr channel(channelLocal.lock());
return channel;
}
void ChannelPutGetLocal::lock()
{
PVRecordPtr pvr(pvRecord.lock());
if(!pvr) throw std::logic_error("pvRecord is deleted");
pvr->lock();
}
void ChannelPutGetLocal::unlock()
{
PVRecordPtr pvr(pvRecord.lock());
if(!pvr) throw std::logic_error("pvRecord is deleted");
pvr->unlock();
}
void ChannelPutGetLocal::putGet(
PVStructurePtr const &pvPutStructure,BitSetPtr const &putBitSet)
{
ChannelPutGetRequester::shared_pointer requester = channelPutGetRequester.lock();
if(!requester) return;
PVRecordPtr pvr(pvRecord.lock());
if(!pvr) throw std::logic_error("pvRecord is deleted");
try {
{
epicsGuard <PVRecord> guard(*pvRecord);
pvRecord->beginGroupPut();
epicsGuard <PVRecord> guard(*pvr);
pvr->beginGroupPut();
pvPutCopy->updateMaster(pvPutStructure, putBitSet);
if(callProcess) pvRecord->process();
if(callProcess) pvr->process();
getBitSet->clear();
pvGetCopy->updateCopySetBitSet(pvGetStructure, getBitSet);
pvRecord->endGroupPut();
pvr->endGroupPut();
}
requester->putGetDone(
Status::Ok,getPtrSelf(),pvGetStructure,getBitSet);
if(pvRecord->getTraceLevel()>1)
if(pvr->getTraceLevel()>1)
{
cout << "ChannelPutGetLocal::putGet" << endl;
}
@ -629,16 +699,18 @@ void ChannelPutGetLocal::getPut()
{
ChannelPutGetRequester::shared_pointer requester = channelPutGetRequester.lock();
if(!requester) return;
PVRecordPtr pvr(pvRecord.lock());
if(!pvr) throw std::logic_error("pvRecord is deleted");
try {
PVStructurePtr pvPutStructure = pvPutCopy->createPVStructure();
BitSetPtr putBitSet(new BitSet(pvPutStructure->getNumberFields()));
{
epicsGuard <PVRecord> guard(*pvRecord);
epicsGuard <PVRecord> guard(*pvr);
pvPutCopy->initCopy(pvPutStructure, putBitSet);
}
requester->getPutDone(
Status::Ok,getPtrSelf(),pvPutStructure,putBitSet);
if(pvRecord->getTraceLevel()>1)
if(pvr->getTraceLevel()>1)
{
cout << "ChannelPutGetLocal::getPut" << endl;
}
@ -654,15 +726,17 @@ void ChannelPutGetLocal::getGet()
{
ChannelPutGetRequester::shared_pointer requester = channelPutGetRequester.lock();
if(!requester) return;
PVRecordPtr pvr(pvRecord.lock());
if(!pvr) throw std::logic_error("pvRecord is deleted");
try {
getBitSet->clear();
{
epicsGuard <PVRecord> guard(*pvRecord);
epicsGuard <PVRecord> guard(*pvr);
pvGetCopy->updateCopySetBitSet(pvGetStructure, getBitSet);
}
requester->getGetDone(
Status::Ok,getPtrSelf(),pvGetStructure,getBitSet);
if(pvRecord->getTraceLevel()>1)
if(pvr->getTraceLevel()>1)
{
cout << "ChannelPutGetLocal::getGet" << endl;
}
@ -696,19 +770,11 @@ public:
channelLocal(channelLocal),
channelRPCRequester(channelRPCRequester),
service(service),
pvRecord(pvRecord),
isLastRequest()
pvRecord(pvRecord)
{
}
virtual ~ChannelRPCLocal()
{
if(pvRecord->getTraceLevel()>0)
{
cout << "~ChannelRPCLocal()" << endl;
}
}
virtual ~ChannelRPCLocal();
void processRequest(RPCService::shared_pointer const & service,
PVStructurePtr const & pvArgument);
@ -724,37 +790,21 @@ public:
PVStructurePtr const & pvArgument);
virtual void request(PVStructurePtr const & pvArgument);
void lastRequest()
{
isLastRequest.set();
}
virtual Channel::shared_pointer getChannel()
{
return channelLocal;
}
virtual Channel::shared_pointer getChannel();
virtual void cancel() {}
virtual void destroy() EPICS_DEPRECATED {};
virtual void lock() {}
virtual void unlock() {}
virtual void lastRequest() {}
private:
shared_pointer getPtrSelf()
{
return shared_from_this();
}
ChannelLocalPtr channelLocal;
ChannelLocalWPtr channelLocal;
ChannelRPCRequester::weak_pointer channelRPCRequester;
RPCServiceAsync::shared_pointer service;
PVRecordPtr pvRecord;
AtomicBoolean isLastRequest;
PVRecordWPtr pvRecord;
};
ChannelRPCLocalPtr ChannelRPCLocal::create(
@ -788,6 +838,21 @@ ChannelRPCLocalPtr ChannelRPCLocal::create(
return rpc;
}
ChannelRPCLocal::~ChannelRPCLocal()
{
PVRecordPtr pvr(pvRecord.lock());
if(pvr && pvr->getTraceLevel()>0) {
cout << "~ChannelRPCLocal() " << pvr->getRecordName() << endl;
}
}
std::tr1::shared_ptr<Channel> ChannelRPCLocal::getChannel()
{
ChannelLocalPtr channel(channelLocal.lock());
return channel;
}
void ChannelRPCLocal::processRequest(
RPCService::shared_pointer const & service,
PVStructurePtr const & pvArgument)
@ -823,9 +888,6 @@ void ChannelRPCLocal::processRequest(
}
ChannelRPCRequester::shared_pointer requester = channelRPCRequester.lock();
if(requester) requester->requestDone(status, getPtrSelf(), result);
if (isLastRequest.get())
destroy();
}
void ChannelRPCLocal::processRequest(
@ -842,8 +904,6 @@ void ChannelRPCLocal::processRequest(
Status errorStatus(Status::STATUSTYPE_FATAL, ex.what());
ChannelRPCRequester::shared_pointer requester = channelRPCRequester.lock();
if(requester) requester->requestDone(errorStatus, getPtrSelf(), PVStructurePtr());
if (isLastRequest.get())
destroy();
}
catch (...)
{
@ -852,9 +912,6 @@ void ChannelRPCLocal::processRequest(
"Unexpected exception caught while calling RPCServiceAsync.request(PVStructure, RPCResponseCallback).");
ChannelRPCRequester::shared_pointer requester = channelRPCRequester.lock();
if(requester) requester->requestDone(errorStatus, shared_from_this(), PVStructurePtr());
if (isLastRequest.get())
destroy();
}
// we wait for callback to be called
@ -863,9 +920,9 @@ void ChannelRPCLocal::processRequest(
void ChannelRPCLocal::request(PVStructurePtr const & pvArgument)
{
if(pvRecord->getTraceLevel()>1)
{
cout << "ChannelRPCLocal::request" << endl;
PVRecordPtr pvr(pvRecord.lock());
if(pvr && pvr->getTraceLevel()>0) {
cout << "ChannelRPCLocal::request " << pvr->getRecordName() << endl;
}
RPCService::shared_pointer rpcService =
std::tr1::dynamic_pointer_cast<RPCService>(service);
@ -893,13 +950,7 @@ class ChannelArrayLocal :
{
public:
POINTER_DEFINITIONS(ChannelArrayLocal);
virtual ~ChannelArrayLocal()
{
if(pvRecord->getTraceLevel()>0)
{
cout << "~ChannelArrayLocal()" << endl;
}
}
virtual ~ChannelArrayLocal();
static ChannelArrayLocalPtr create(
ChannelLocalPtr const &channelLocal,
ChannelArrayRequester::shared_pointer const & channelArrayRequester,
@ -912,12 +963,11 @@ public:
virtual void getLength();
virtual void setLength(size_t length);
virtual void destroy() EPICS_DEPRECATED {};
virtual std::tr1::shared_ptr<Channel> getChannel()
{return channelLocal;}
virtual std::tr1::shared_ptr<Channel> getChannel();
virtual void cancel(){}
virtual void lock();
virtual void unlock();
virtual void lastRequest() {}
virtual void lock() {pvRecord->lock();}
virtual void unlock() {pvRecord->unlock();}
private:
shared_pointer getPtrSelf()
{
@ -938,11 +988,11 @@ private:
{
}
ChannelLocalPtr channelLocal;
ChannelLocalWPtr channelLocal;
ChannelArrayRequester::weak_pointer channelArrayRequester;
PVArrayPtr pvArray;
PVArrayPtr pvCopy;
PVRecordPtr pvRecord;
PVRecordWPtr pvRecord;
Mutex mutex;
};
@ -1030,19 +1080,47 @@ ChannelArrayLocalPtr ChannelArrayLocal::create(
return array;
}
ChannelArrayLocal::~ChannelArrayLocal()
{
PVRecordPtr pvr(pvRecord.lock());
if(pvr && pvr->getTraceLevel()>0) {
cout << "~ChannelArrayLocal() " << pvr->getRecordName() << endl;
}
}
std::tr1::shared_ptr<Channel> ChannelArrayLocal::getChannel()
{
ChannelLocalPtr channel(channelLocal.lock());
return channel;
}
void ChannelArrayLocal::lock()
{
PVRecordPtr pvr(pvRecord.lock());
if(!pvr) throw std::logic_error("pvRecord is deleted");
pvr->lock();
}
void ChannelArrayLocal::unlock()
{
PVRecordPtr pvr(pvRecord.lock());
if(!pvr) throw std::logic_error("pvRecord is deleted");
pvr->unlock();
}
void ChannelArrayLocal::getArray(size_t offset, size_t count, size_t stride)
{
ChannelArrayRequester::shared_pointer requester = channelArrayRequester.lock();
if(!requester) return;
if(pvRecord->getTraceLevel()>1)
PVRecordPtr pvr(pvRecord.lock());
if(!pvr) throw std::logic_error("pvRecord is deleted");
if(pvr->getTraceLevel()>1)
{
cout << "ChannelArrayLocal::getArray" << endl;
}
const char *exceptionMessage = NULL;
try {
bool ok = false;
epicsGuard <PVRecord> guard(*pvRecord);
epicsGuard <PVRecord> guard(*pvr);
while(true) {
size_t length = pvArray->getLength();
if(length<=0) break;
@ -1075,8 +1153,9 @@ void ChannelArrayLocal::putArray(
{
ChannelArrayRequester::shared_pointer requester = channelArrayRequester.lock();
if(!requester) return;
if(pvRecord->getTraceLevel()>1)
PVRecordPtr pvr(pvRecord.lock());
if(!pvr) throw std::logic_error("pvRecord is deleted");
if(pvr->getTraceLevel()>1)
{
cout << "ChannelArrayLocal::putArray" << endl;
}
@ -1084,7 +1163,7 @@ void ChannelArrayLocal::putArray(
if(newLength<pvArray->getLength()) pvArray->setLength(newLength);
const char *exceptionMessage = NULL;
try {
epicsGuard <PVRecord> guard(*pvRecord);
epicsGuard <PVRecord> guard(*pvr);
copy(pvArray,0,1,this->pvArray,offset,stride,count);
} catch(std::exception e) {
exceptionMessage = e.what();
@ -1100,10 +1179,12 @@ void ChannelArrayLocal::getLength()
{
ChannelArrayRequester::shared_pointer requester = channelArrayRequester.lock();
if(!requester) return;
PVRecordPtr pvr(pvRecord.lock());
if(!pvr) throw std::logic_error("pvRecord is deleted");
size_t length = 0;
const char *exceptionMessage = NULL;
try {
epicsGuard <PVRecord> guard(*pvRecord);
epicsGuard <PVRecord> guard(*pvr);
length = pvArray->getLength();
} catch(std::exception e) {
exceptionMessage = e.what();
@ -1119,14 +1200,15 @@ void ChannelArrayLocal::setLength(size_t length)
{
ChannelArrayRequester::shared_pointer requester = channelArrayRequester.lock();
if(!requester) return;
if(pvRecord->getTraceLevel()>1)
PVRecordPtr pvr(pvRecord.lock());
if(!pvr) throw std::logic_error("pvRecord is deleted");
if(pvr->getTraceLevel()>1)
{
cout << "ChannelArrayLocal::setLength" << endl;
}
try {
{
epicsGuard <PVRecord> guard(*pvRecord);
epicsGuard <PVRecord> guard(*pvr);
if(pvArray->getLength()!=length) pvArray->setLength(length);
}
requester->setLengthDone(Status::Ok,getPtrSelf());
@ -1157,13 +1239,18 @@ ChannelLocal::ChannelLocal(
ChannelLocal::~ChannelLocal()
{
if(pvRecord->getTraceLevel()>0)
PVRecordPtr pvr(pvRecord.lock());
if(!pvr) return;
if(pvr->getTraceLevel()>0)
{
cout << "~ChannelLocal()" << endl;
}
pvRecord->removePVRecordClient(getPtrSelf());
}
ChannelProvider::shared_pointer ChannelLocal::getProvider()
{
return provider.lock();
}
void ChannelLocal::detach(PVRecordPtr const & pvRecord)
{
@ -1180,9 +1267,10 @@ void ChannelLocal::detach(PVRecordPtr const & pvRecord)
string ChannelLocal::getRequesterName()
{
if(pvRecord->getTraceLevel()>1) {
PVRecordPtr pvr(pvRecord.lock());
if(pvr && pvr->getTraceLevel()>0) {
cout << "ChannelLocal::getRequesterName() "
<< " recordName " << pvRecord->getRecordName()
<< " recordName " << pvr->getRecordName()
<< " requester exists " << (requester ? "true" : "false")
<< endl;
}
@ -1195,9 +1283,10 @@ void ChannelLocal::message(
string const &message,
MessageType messageType)
{
if(pvRecord->getTraceLevel()>1) {
PVRecordPtr pvr(pvRecord.lock());
if(pvr && pvr->getTraceLevel()>1) {
cout << "ChannelLocal::message() "
<< " recordName " << pvRecord->getRecordName()
<< " recordName " << pvr->getRecordName()
<< " requester exists " << (requester ? "true" : "false")
<< endl;
}
@ -1205,7 +1294,9 @@ void ChannelLocal::message(
requester->message(message,messageType);
return;
}
cout << pvRecord->getRecordName()
string recordName("record deleted");
if(pvr) recordName = pvr->getRecordName();
cout << recordName
<< " message " << message
<< " messageType " << getMessageTypeName(messageType)
<< endl;
@ -1223,7 +1314,10 @@ Channel::ConnectionState ChannelLocal::getConnectionState()
string ChannelLocal::getChannelName()
{
return pvRecord->getRecordName();
PVRecordPtr pvr(pvRecord.lock());
string name("record deleted");
if(pvr) name = pvr->getRecordName();
return name;
}
ChannelRequester::shared_pointer ChannelLocal::getChannelRequester()
@ -1239,14 +1333,16 @@ bool ChannelLocal::isConnected()
void ChannelLocal::getField(GetFieldRequester::shared_pointer const &requester,
string const &subField)
{
PVRecordPtr pvr(pvRecord.lock());
if(!pvr) throw std::logic_error("pvRecord is deleted");
if(subField.size()<1) {
StructureConstPtr structure =
pvRecord->getPVRecordStructure()->getPVStructure()->getStructure();
pvr->getPVRecordStructure()->getPVStructure()->getStructure();
requester->getDone(Status::Ok,structure);
return;
}
PVFieldPtr pvField =
pvRecord->getPVRecordStructure()->getPVStructure()->getSubField(subField);
pvr->getPVRecordStructure()->getPVStructure()->getSubField(subField);
if(pvField) {
requester->getDone(Status::Ok,pvField->getField());
return;
@ -1266,9 +1362,11 @@ ChannelProcess::shared_pointer ChannelLocal::createChannelProcess(
ChannelProcessRequester::shared_pointer const & channelProcessRequester,
PVStructure::shared_pointer const & pvRequest)
{
if(pvRecord->getTraceLevel()>0) {
PVRecordPtr pvr(pvRecord.lock());
if(!pvr) throw std::logic_error("pvRecord is deleted");
if(pvr->getTraceLevel()>0) {
cout << "ChannelLocal::createChannelProcess() "
<< " recordName " << pvRecord->getRecordName()
<< " recordName " << pvr->getRecordName()
<< " requester exists " << (requester ? "true" : "false")
<< endl;
}
@ -1277,7 +1375,7 @@ ChannelProcess::shared_pointer ChannelLocal::createChannelProcess(
getPtrSelf(),
channelProcessRequester,
pvRequest,
pvRecord);
pvr);
return channelProcess;
}
@ -1285,9 +1383,11 @@ ChannelGet::shared_pointer ChannelLocal::createChannelGet(
ChannelGetRequester::shared_pointer const &channelGetRequester,
PVStructure::shared_pointer const &pvRequest)
{
if(pvRecord->getTraceLevel()>0) {
PVRecordPtr pvr(pvRecord.lock());
if(!pvr) throw std::logic_error("pvRecord is deleted");
if(pvr->getTraceLevel()>0) {
cout << "ChannelLocal::createChannelGet() "
<< " recordName " << pvRecord->getRecordName()
<< " recordName " << pvr->getRecordName()
<< " requester exists " << (requester ? "true" : "false")
<< endl;
}
@ -1296,7 +1396,7 @@ ChannelGet::shared_pointer ChannelLocal::createChannelGet(
getPtrSelf(),
channelGetRequester,
pvRequest,
pvRecord);
pvr);
return channelGet;
}
@ -1304,9 +1404,11 @@ ChannelPut::shared_pointer ChannelLocal::createChannelPut(
ChannelPutRequester::shared_pointer const &channelPutRequester,
PVStructure::shared_pointer const &pvRequest)
{
if(pvRecord->getTraceLevel()>0) {
PVRecordPtr pvr(pvRecord.lock());
if(!pvr) throw std::logic_error("pvRecord is deleted");
if(pvr->getTraceLevel()>0) {
cout << "ChannelLocal::createChannelPut() "
<< " recordName " << pvRecord->getRecordName()
<< " recordName " << pvr->getRecordName()
<< " requester exists " << (requester ? "true" : "false")
<< endl;
}
@ -1316,7 +1418,7 @@ ChannelPut::shared_pointer ChannelLocal::createChannelPut(
getPtrSelf(),
channelPutRequester,
pvRequest,
pvRecord);
pvr);
return channelPut;
}
@ -1324,9 +1426,11 @@ ChannelPutGet::shared_pointer ChannelLocal::createChannelPutGet(
ChannelPutGetRequester::shared_pointer const &channelPutGetRequester,
PVStructure::shared_pointer const &pvRequest)
{
if(pvRecord->getTraceLevel()>0) {
PVRecordPtr pvr(pvRecord.lock());
if(!pvr) throw std::logic_error("pvRecord is deleted");
if(pvr->getTraceLevel()>0) {
cout << "ChannelLocal::createChannelPutGet() "
<< " recordName " << pvRecord->getRecordName()
<< " recordName " << pvr->getRecordName()
<< " requester exists " << (requester ? "true" : "false")
<< endl;
}
@ -1336,7 +1440,7 @@ ChannelPutGet::shared_pointer ChannelLocal::createChannelPutGet(
getPtrSelf(),
channelPutGetRequester,
pvRequest,
pvRecord);
pvr);
return channelPutGet;
}
@ -1344,9 +1448,11 @@ ChannelRPC::shared_pointer ChannelLocal::createChannelRPC(
ChannelRPCRequester::shared_pointer const & channelRPCRequester,
PVStructure::shared_pointer const & pvRequest)
{
if(pvRecord->getTraceLevel()>0) {
PVRecordPtr pvr(pvRecord.lock());
if(!pvr) throw std::logic_error("pvRecord is deleted");
if(pvr->getTraceLevel()>0) {
cout << "ChannelLocal::createChannelRPC() "
<< " recordName " << pvRecord->getRecordName()
<< " recordName " << pvr->getRecordName()
<< " requester exists " << (requester ? "true" : "false")
<< endl;
}
@ -1356,7 +1462,7 @@ ChannelRPC::shared_pointer ChannelLocal::createChannelRPC(
getPtrSelf(),
channelRPCRequester,
pvRequest,
pvRecord);
pvr);
return channelRPC;
}
@ -1364,15 +1470,17 @@ Monitor::shared_pointer ChannelLocal::createMonitor(
MonitorRequester::shared_pointer const &monitorRequester,
PVStructure::shared_pointer const &pvRequest)
{
if(pvRecord->getTraceLevel()>0) {
PVRecordPtr pvr(pvRecord.lock());
if(!pvr) throw std::logic_error("pvRecord is deleted");
if(pvr->getTraceLevel()>0) {
cout << "ChannelLocal::createMonitor() "
<< " recordName " << pvRecord->getRecordName()
<< " recordName " << pvr->getRecordName()
<< " requester exists " << (requester ? "true" : "false")
<< endl;
}
MonitorPtr monitor = createMonitorLocal(
pvRecord,
pvr,
monitorRequester,
pvRequest);
return monitor;
@ -1382,9 +1490,11 @@ ChannelArray::shared_pointer ChannelLocal::createChannelArray(
ChannelArrayRequester::shared_pointer const &channelArrayRequester,
PVStructure::shared_pointer const &pvRequest)
{
if(pvRecord->getTraceLevel()>0) {
PVRecordPtr pvr(pvRecord.lock());
if(!pvr) throw std::logic_error("pvRecord is deleted");
if(pvr->getTraceLevel()>0) {
cout << "ChannelLocal::createChannelArray() "
<< " recordName " << pvRecord->getRecordName()
<< " recordName " << pvr->getRecordName()
<< " requester exists " << (requester ? "true" : "false")
<< endl;
}
@ -1393,7 +1503,7 @@ ChannelArray::shared_pointer ChannelLocal::createChannelArray(
getPtrSelf(),
channelArrayRequester,
pvRequest,
pvRecord);
pvr);
return channelArray;
}

View File

@ -11,14 +11,12 @@
#include <epicsThread.h>
#include <pv/serverContext.h>
#include <pv/syncChannelFind.h>
#define epicsExportSharedSymbols
#include <pv/channelProviderLocal.h>
#include <pv/traceRecord.h>
using namespace epics::pvData;
using namespace epics::pvAccess;
@ -30,9 +28,6 @@ using std::string;
namespace epics { namespace pvDatabase {
class LocalChannelProviderFactory;
typedef std::tr1::shared_ptr<LocalChannelProviderFactory> LocalChannelProviderFactoryPtr;
static string providerName("local");
static ChannelProviderLocalPtr channelProvider;
@ -48,8 +43,8 @@ public:
}
virtual ChannelProvider::shared_pointer newInstance()
{
cout << "LocalChannelProviderFactory::newInstance()\n";
throw std::logic_error("newInstance not Implemented");
throw std::logic_error(
"LocalChannelProviderFactory::newInstance() not Implemented");
}
};
@ -72,6 +67,9 @@ ChannelProviderLocal::ChannelProviderLocal()
: pvDatabase(PVDatabase::getMaster()),
traceLevel(0)
{
if(traceLevel>0) {
cout << "ChannelProviderLocal::ChannelProviderLocal()\n";
}
}
ChannelProviderLocal::~ChannelProviderLocal()
@ -86,11 +84,6 @@ std::tr1::shared_ptr<ChannelProvider> ChannelProviderLocal::getChannelProvider()
return shared_from_this();
}
void ChannelProviderLocal::cancel()
{
}
string ChannelProviderLocal::getProviderName()
{
return providerName;
@ -103,7 +96,15 @@ ChannelFind::shared_pointer ChannelProviderLocal::channelFind(
if(traceLevel>1) {
cout << "ChannelProviderLocal::channelFind " << "channelName" << endl;
}
PVRecordPtr pvRecord = pvDatabase->findRecord(channelName);
PVDatabasePtr pvdb(pvDatabase.lock());
if(!pvdb) {
Status notFoundStatus(Status::STATUSTYPE_ERROR,"pvDatabase was deleted");
channelFindRequester->channelFindResult(
notFoundStatus,
shared_from_this(),
false);
}
PVRecordPtr pvRecord = pvdb->findRecord(channelName);
if(pvRecord) {
channelFindRequester->channelFindResult(
Status::Ok,
@ -126,8 +127,11 @@ ChannelFind::shared_pointer ChannelProviderLocal::channelList(
if(traceLevel>1) {
cout << "ChannelProviderLocal::channelList\n";
}
PVStringArrayPtr records(pvDatabase->getRecordNames());
channelListRequester->channelListResult(Status::Ok, shared_from_this(), records->view(), false);
PVDatabasePtr pvdb(pvDatabase.lock());
if(!pvdb)throw std::logic_error("pvDatabase was deleted");
PVStringArrayPtr records(pvdb->getRecordNames());
channelListRequester->channelListResult(
Status::Ok, shared_from_this(), records->view(), false);
return shared_from_this();
}
@ -139,22 +143,23 @@ Channel::shared_pointer ChannelProviderLocal::createChannel(
if(traceLevel>1) {
cout << "ChannelProviderLocal::createChannel " << "channelName" << endl;
}
PVRecordPtr pvRecord = pvDatabase->findRecord(channelName);
ChannelLocalPtr channel;
Status status = Status::Ok;
PVDatabasePtr pvdb(pvDatabase.lock());
if(!pvdb) {
status = Status::error("pvDatabase was deleted");
} else {
PVRecordPtr pvRecord = pvdb->findRecord(channelName);
if(pvRecord) {
ChannelLocalPtr channel(new ChannelLocal(
channel = ChannelLocalPtr(new ChannelLocal(
shared_from_this(),channelRequester,pvRecord));
channelRequester->channelCreated(
Status::Ok,
channel);
pvRecord->addPVRecordClient(channel);
return channel;
} else {
status = Status::error("pv not found");
}
Status notFoundStatus(Status::STATUSTYPE_ERROR,"pv not found");
channelRequester->channelCreated(
notFoundStatus,
Channel::shared_pointer());
return Channel::shared_pointer();
}
channelRequester->channelCreated(status,channel);
return channel;
}
Channel::shared_pointer ChannelProviderLocal::createChannel(

View File

@ -34,10 +34,11 @@ typedef std::tr1::shared_ptr<MonitorLocal> MonitorLocalPtr;
static MonitorPtr nullMonitor;
static MonitorElementPtr NULLMonitorElement;
static Status failedToCreateMonitorStatus(Status::STATUSTYPE_ERROR,"failed to create monitor");
static Status failedToCreateMonitorStatus(
Status::STATUSTYPE_ERROR,"failed to create monitor");
static Status alreadyStartedStatus(Status::STATUSTYPE_ERROR,"already started");
static Status notStartedStatus(Status::STATUSTYPE_ERROR,"not started");
static Status destroyedStatus(Status::STATUSTYPE_ERROR,"record is destroyed");
static Status deletedStatus(Status::STATUSTYPE_ERROR,"record is deleted");
class MonitorElementQueue;
typedef std::tr1::shared_ptr<MonitorElementQueue> MonitorElementQueuePtr;
@ -129,7 +130,7 @@ class MonitorLocal :
public PVListener,
public std::tr1::enable_shared_from_this<MonitorLocal>
{
enum MonitorState {idle,active,destroyed};
enum MonitorState {idle,active,deleted};
public:
POINTER_DEFINITIONS(MonitorLocal);
virtual ~MonitorLocal();
@ -199,7 +200,7 @@ Status MonitorLocal::start()
{
Lock xx(mutex);
if(state==active) return alreadyStartedStatus;
if(state==destroyed) return destroyedStatus;
if(state==deleted) return deletedStatus;
}
pvRecord->addListener(getPtrSelf(),pvCopy);
epicsGuard <PVRecord> guard(*pvRecord);
@ -223,7 +224,7 @@ Status MonitorLocal::stop()
{
Lock xx(mutex);
if(state==idle) return notStartedStatus;
if(state==destroyed) return destroyedStatus;
if(state==deleted) return deletedStatus;
state = idle;
}
pvRecord->removeListener(getPtrSelf(),pvCopy);
@ -373,7 +374,7 @@ void MonitorLocal::unlisten(PVRecordPtr const & pvRecord)
}
{
Lock xx(mutex);
state = destroyed;
state = deleted;
}
MonitorRequesterPtr requester = monitorRequester.lock();
if(requester) {
@ -458,7 +459,8 @@ MonitorPtr createMonitorLocal(
if(!result) {
MonitorPtr monitor;
StructureConstPtr structure;
monitorRequester->monitorConnect(failedToCreateMonitorStatus,monitor,structure);
monitorRequester->monitorConnect(
failedToCreateMonitorStatus,monitor,structure);
return nullMonitor;
}
if(pvRecord->getTraceLevel()>0)