use weak pointer for callbacks
This commit is contained in:
@ -23,6 +23,7 @@ using namespace epics::pvData;
|
||||
using namespace epics::pvDatabase;
|
||||
using std::tr1::static_pointer_cast;
|
||||
using std::string;
|
||||
using namespace std;
|
||||
|
||||
namespace epics { namespace exampleRPC {
|
||||
|
||||
@ -31,6 +32,7 @@ PVStructurePtr ExampleRPCService::request(
|
||||
PVStructure::shared_pointer const & args
|
||||
) throw (epics::pvAccess::RPCRequestException)
|
||||
{
|
||||
|
||||
bool haveControl = pvRecord->takeControl();
|
||||
if (!haveControl)
|
||||
throw pvAccess::RPCRequestException(Status::STATUSTYPE_ERROR,
|
||||
@ -40,22 +42,28 @@ PVStructurePtr ExampleRPCService::request(
|
||||
PVDataCreatePtr pvDataCreate = getPVDataCreate();
|
||||
|
||||
PVStructureArrayPtr valueField = args->getSubField<PVStructureArray>("value");
|
||||
if (valueField.get() == 0)
|
||||
if (valueField.get() == 0) {
|
||||
pvRecord->releaseControl();
|
||||
throw pvAccess::RPCRequestException(Status::STATUSTYPE_ERROR,
|
||||
"No structure array value field");
|
||||
}
|
||||
|
||||
StructureConstPtr valueFieldStructure = valueField->
|
||||
getStructureArray()->getStructure();
|
||||
|
||||
ScalarConstPtr xField = valueFieldStructure->getField<Scalar>("x");
|
||||
if (xField.get() == 0 || xField->getScalarType() != pvDouble)
|
||||
if (xField.get() == 0 || xField->getScalarType() != pvDouble) {
|
||||
pvRecord->releaseControl();
|
||||
throw pvAccess::RPCRequestException(Status::STATUSTYPE_ERROR,
|
||||
"value field's structure has no double field x");
|
||||
}
|
||||
|
||||
ScalarConstPtr yField = valueFieldStructure->getField<Scalar>("y");
|
||||
if (xField.get() == 0 || xField->getScalarType() != pvDouble)
|
||||
if (xField.get() == 0 || xField->getScalarType() != pvDouble) {
|
||||
pvRecord->releaseControl();
|
||||
throw pvAccess::RPCRequestException(Status::STATUSTYPE_ERROR,
|
||||
"value field's structure has no double field y");
|
||||
}
|
||||
|
||||
PVStructureArray::const_svector vals = valueField->view();
|
||||
|
||||
@ -89,22 +97,28 @@ void ExampleRPCServiceAsync::request(
|
||||
PVDataCreatePtr pvDataCreate = getPVDataCreate();
|
||||
|
||||
PVStructureArrayPtr valueField = args->getSubField<PVStructureArray>("value");
|
||||
if (valueField.get() == 0)
|
||||
if (valueField.get() == 0) {
|
||||
pvRecord->releaseControl();
|
||||
throw pvAccess::RPCRequestException(Status::STATUSTYPE_ERROR,
|
||||
"No structure array value field");
|
||||
}
|
||||
|
||||
StructureConstPtr valueFieldStructure = valueField->
|
||||
getStructureArray()->getStructure();
|
||||
|
||||
ScalarConstPtr xField = valueFieldStructure->getField<Scalar>("x");
|
||||
if (xField.get() == 0 || xField->getScalarType() != pvDouble)
|
||||
if (xField.get() == 0 || xField->getScalarType() != pvDouble) {
|
||||
pvRecord->releaseControl();
|
||||
throw pvAccess::RPCRequestException(Status::STATUSTYPE_ERROR,
|
||||
"value field's structure has no double field x");
|
||||
}
|
||||
|
||||
ScalarConstPtr yField = valueFieldStructure->getField<Scalar>("y");
|
||||
if (yField.get() == 0 || yField->getScalarType() != pvDouble)
|
||||
if (yField.get() == 0 || yField->getScalarType() != pvDouble) {
|
||||
pvRecord->releaseControl();
|
||||
throw pvAccess::RPCRequestException(Status::STATUSTYPE_ERROR,
|
||||
"value field's structure has no double field y");
|
||||
}
|
||||
|
||||
PVStructureArray::const_svector vals = valueField->view();
|
||||
|
||||
|
@ -13,6 +13,7 @@
|
||||
#include <iostream>
|
||||
|
||||
using namespace epics::pvData;
|
||||
using namespace std;
|
||||
|
||||
|
||||
static StructureConstPtr makeDeviceStructure()
|
||||
@ -81,6 +82,14 @@ int main (int argc, char *argv[])
|
||||
usage();
|
||||
return 1;
|
||||
}
|
||||
|
||||
if(argc<2)
|
||||
{
|
||||
std::cerr << APP_NAME << " requires at least 2 arguments."
|
||||
<< std::endl;
|
||||
usage();
|
||||
return 1;
|
||||
}
|
||||
// Start the pvAccess client side.
|
||||
epics::pvAccess::ClientFactory::start();
|
||||
|
||||
|
@ -49,9 +49,11 @@ typedef std::tr1::shared_ptr<PVRecordStructure> PVRecordStructurePtr;
|
||||
|
||||
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;
|
||||
typedef std::tr1::weak_ptr<PVListener> PVListenerWPtr;
|
||||
|
||||
class PVDatabase;
|
||||
typedef std::tr1::shared_ptr<PVDatabase> PVDatabasePtr;
|
||||
@ -249,8 +251,8 @@ private:
|
||||
std::string recordName;
|
||||
epics::pvData::PVStructurePtr pvStructure;
|
||||
PVRecordStructurePtr pvRecordStructure;
|
||||
std::list<PVListenerPtr> pvListenerList;
|
||||
std::list<PVRecordClientPtr> pvRecordClientList;
|
||||
std::list<PVListenerWPtr> pvListenerList;
|
||||
std::list<PVRecordClientWPtr> pvRecordClientList;
|
||||
epics::pvData::Mutex mutex;
|
||||
std::size_t depthGroupPut;
|
||||
int traceLevel;
|
||||
@ -261,7 +263,7 @@ private:
|
||||
|
||||
// following only valid while addListener or removeListener is active.
|
||||
bool isAddListener;
|
||||
PVListenerPtr pvListener;
|
||||
PVListenerWPtr pvListener;
|
||||
};
|
||||
|
||||
epicsShareExtern std::ostream& operator<<(std::ostream& o, const PVRecord& record);
|
||||
@ -339,7 +341,7 @@ private:
|
||||
virtual void removeListener(PVListenerPtr const & pvListener);
|
||||
void callListener();
|
||||
|
||||
std::list<PVListenerPtr> pvListenerList;
|
||||
std::list<PVListenerWPtr> pvListenerList;
|
||||
epics::pvData::PVFieldPtr pvField;
|
||||
bool isStructure;
|
||||
PVRecordStructurePtr parent;
|
||||
|
@ -77,22 +77,28 @@ void PVRecord::destroy()
|
||||
isDestroyed = true;
|
||||
pvTimeStamp.detach();
|
||||
|
||||
std::list<PVRecordClientPtr>::iterator clientIter;
|
||||
std::list<PVRecordClientWPtr>::iterator clientIter;
|
||||
while(true) {
|
||||
clientIter = pvRecordClientList.begin();
|
||||
if(clientIter==pvRecordClientList.end()) break;
|
||||
PVRecordClientPtr client = clientIter->lock();
|
||||
if(client.get()) {
|
||||
unlock();
|
||||
client->detach(getPtrSelf());
|
||||
lock();
|
||||
}
|
||||
pvRecordClientList.erase(clientIter);
|
||||
unlock();
|
||||
(*clientIter)->detach(getPtrSelf());
|
||||
lock();
|
||||
}
|
||||
std::list<PVListenerPtr>::iterator listenerIter;
|
||||
std::list<PVListenerWPtr>::iterator listenerIter;
|
||||
while(true) {
|
||||
listenerIter = pvListenerList.begin();
|
||||
if(listenerIter==pvListenerList.end()) break;
|
||||
unlock();
|
||||
(*listenerIter)->unlisten(getPtrSelf());
|
||||
lock();
|
||||
PVListenerPtr listener = listenerIter->lock();
|
||||
if(listener.get()) {
|
||||
unlock();
|
||||
listener->unlisten(getPtrSelf());
|
||||
lock();
|
||||
}
|
||||
pvListenerList.erase(listenerIter);
|
||||
|
||||
}
|
||||
@ -200,12 +206,14 @@ bool PVRecord::addPVRecordClient(PVRecordClientPtr const & pvRecordClient)
|
||||
unlock();
|
||||
return false;
|
||||
}
|
||||
std::list<PVRecordClientPtr>::iterator iter;
|
||||
std::list<PVRecordClientWPtr>::iterator iter;
|
||||
for (iter = pvRecordClientList.begin();
|
||||
iter!=pvRecordClientList.end();
|
||||
iter++ )
|
||||
{
|
||||
if((*iter).get()==pvRecordClient.get()) {
|
||||
PVRecordClientPtr client = iter->lock();
|
||||
if(!client.get()) continue;
|
||||
if(client.get()==pvRecordClient.get()) {
|
||||
unlock();
|
||||
return false;
|
||||
}
|
||||
@ -230,12 +238,14 @@ bool PVRecord::removePVRecordClient(PVRecordClientPtr const & pvRecordClient)
|
||||
unlock();
|
||||
return false;
|
||||
}
|
||||
std::list<PVRecordClientPtr>::iterator iter;
|
||||
std::list<PVRecordClientWPtr>::iterator iter;
|
||||
for (iter = pvRecordClientList.begin();
|
||||
iter!=pvRecordClientList.end();
|
||||
iter++ )
|
||||
{
|
||||
if((*iter).get()==pvRecordClient.get()) {
|
||||
PVRecordClientPtr client = iter->lock();
|
||||
if(!client.get()) continue;
|
||||
if(client.get()==pvRecordClient.get()) {
|
||||
pvRecordClientList.erase(iter);
|
||||
unlock();
|
||||
return true;
|
||||
@ -260,13 +270,15 @@ void PVRecord::detachClients()
|
||||
unlock();
|
||||
return;
|
||||
}
|
||||
std::list<PVRecordClientPtr>::iterator iter;
|
||||
std::list<PVRecordClientWPtr>::iterator iter;
|
||||
for (iter = pvRecordClientList.begin();
|
||||
iter!=pvRecordClientList.end();
|
||||
iter++ )
|
||||
{
|
||||
PVRecordClientPtr client = iter->lock();
|
||||
if(!client.get()) continue;
|
||||
unlock();
|
||||
(*iter)->detach(getPtrSelf());
|
||||
client->detach(getPtrSelf());
|
||||
lock();
|
||||
}
|
||||
pvRecordClientList.clear();
|
||||
@ -290,10 +302,12 @@ bool PVRecord::addListener(
|
||||
unlock();
|
||||
return false;
|
||||
}
|
||||
std::list<PVListenerPtr>::iterator iter;
|
||||
std::list<PVListenerWPtr>::iterator iter;
|
||||
for (iter = pvListenerList.begin(); iter!=pvListenerList.end(); iter++ )
|
||||
{
|
||||
if((*iter).get()==pvListener.get()) {
|
||||
PVListenerPtr listener = iter->lock();
|
||||
if(!listener.get()) continue;
|
||||
if(listener.get()==pvListener.get()) {
|
||||
unlock();
|
||||
return false;
|
||||
}
|
||||
@ -314,10 +328,12 @@ bool PVRecord::addListener(
|
||||
void PVRecord::nextMasterPVField(PVFieldPtr const & pvField)
|
||||
{
|
||||
PVRecordFieldPtr pvRecordField = findPVRecordField(pvField);
|
||||
if(isAddListener) {
|
||||
pvRecordField->addListener(pvListener);
|
||||
PVListenerPtr listener = pvListener.lock();
|
||||
if(!listener.get()) return;
|
||||
if(isAddListener) {
|
||||
pvRecordField->addListener(listener);
|
||||
} else {
|
||||
pvRecordField->removeListener(pvListener);
|
||||
pvRecordField->removeListener(listener);
|
||||
}
|
||||
}
|
||||
|
||||
@ -334,15 +350,17 @@ bool PVRecord::removeListener(
|
||||
unlock();
|
||||
return false;
|
||||
}
|
||||
std::list<PVListenerPtr>::iterator iter;
|
||||
std::list<PVListenerWPtr>::iterator iter;
|
||||
for (iter = pvListenerList.begin(); iter!=pvListenerList.end(); iter++ )
|
||||
{
|
||||
if((*iter).get()==pvListener.get()) {
|
||||
PVListenerPtr listener = iter->lock();
|
||||
if(!listener.get()) continue;
|
||||
if(listener.get()==pvListener.get()) {
|
||||
pvListenerList.erase(iter);
|
||||
this->pvListener = pvListener;
|
||||
isAddListener = false;
|
||||
pvCopy->traverseMaster(getPtrSelf());
|
||||
this->pvListener = PVListenerPtr();;
|
||||
this->pvListener = PVListenerPtr();
|
||||
unlock();
|
||||
return true;
|
||||
}
|
||||
@ -361,10 +379,12 @@ void PVRecord::beginGroupPut()
|
||||
if(traceLevel>2) {
|
||||
cout << "PVRecord::beginGroupPut() " << recordName << endl;
|
||||
}
|
||||
std::list<PVListenerPtr>::iterator iter;
|
||||
std::list<PVListenerWPtr>::iterator iter;
|
||||
for (iter = pvListenerList.begin(); iter!=pvListenerList.end(); iter++)
|
||||
{
|
||||
(*iter).get()->beginGroupPut(getPtrSelf());
|
||||
PVListenerPtr listener = iter->lock();
|
||||
if(!listener.get()) continue;
|
||||
listener->beginGroupPut(getPtrSelf());
|
||||
}
|
||||
}
|
||||
|
||||
@ -374,10 +394,12 @@ void PVRecord::endGroupPut()
|
||||
if(traceLevel>2) {
|
||||
cout << "PVRecord::endGroupPut() " << recordName << endl;
|
||||
}
|
||||
std::list<PVListenerPtr>::iterator iter;
|
||||
std::list<PVListenerWPtr>::iterator iter;
|
||||
for (iter = pvListenerList.begin(); iter!=pvListenerList.end(); iter++)
|
||||
{
|
||||
(*iter).get()->endGroupPut(getPtrSelf());
|
||||
PVListenerPtr listener = iter->lock();
|
||||
if(!listener.get()) continue;
|
||||
listener->endGroupPut(getPtrSelf());
|
||||
}
|
||||
}
|
||||
|
||||
@ -449,9 +471,11 @@ bool PVRecordField::addListener(PVListenerPtr const & pvListener)
|
||||
if(pvRecord->getTraceLevel()>1) {
|
||||
cout << "PVRecordField::addListener() " << getFullName() << endl;
|
||||
}
|
||||
std::list<PVListenerPtr>::iterator iter;
|
||||
std::list<PVListenerWPtr>::iterator iter;
|
||||
for (iter = pvListenerList.begin(); iter!=pvListenerList.end(); iter++ ) {
|
||||
if((*iter).get()==pvListener.get()) {
|
||||
PVListenerPtr listener = iter->lock();
|
||||
if(!listener.get()) continue;
|
||||
if(listener.get()==pvListener.get()) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@ -464,9 +488,11 @@ void PVRecordField::removeListener(PVListenerPtr const & pvListener)
|
||||
if(pvRecord->getTraceLevel()>1) {
|
||||
cout << "PVRecordField::removeListener() " << getFullName() << endl;
|
||||
}
|
||||
std::list<PVListenerPtr>::iterator iter;
|
||||
std::list<PVListenerWPtr>::iterator iter;
|
||||
for (iter = pvListenerList.begin(); iter!=pvListenerList.end(); iter++ ) {
|
||||
if((*iter).get()==pvListener.get()) {
|
||||
PVListenerPtr listener = iter->lock();
|
||||
if(!listener.get()) continue;
|
||||
if(listener.get()==pvListener.get()) {
|
||||
pvListenerList.erase(iter);
|
||||
return;
|
||||
}
|
||||
@ -484,10 +510,12 @@ void PVRecordField::postPut()
|
||||
void PVRecordField::postParent(PVRecordFieldPtr const & subField)
|
||||
{
|
||||
PVRecordStructurePtr pvrs = static_pointer_cast<PVRecordStructure>(getPtrSelf());
|
||||
std::list<PVListenerPtr>::iterator iter;
|
||||
std::list<PVListenerWPtr>::iterator iter;
|
||||
for(iter = pvListenerList.begin(); iter != pvListenerList.end(); ++iter)
|
||||
{
|
||||
(*iter)->dataPut(pvrs,subField);
|
||||
PVListenerPtr listener = iter->lock();
|
||||
if(!listener.get()) continue;
|
||||
listener->dataPut(pvrs,subField);
|
||||
}
|
||||
if(parent) parent->postParent(subField);
|
||||
}
|
||||
@ -507,9 +535,11 @@ void PVRecordField::postSubField()
|
||||
|
||||
void PVRecordField::callListener()
|
||||
{
|
||||
std::list<PVListenerPtr>::iterator iter;
|
||||
std::list<PVListenerWPtr>::iterator iter;
|
||||
for (iter = pvListenerList.begin(); iter!=pvListenerList.end(); iter++ ) {
|
||||
(*iter)->dataPut(getPtrSelf());
|
||||
PVListenerPtr listener = iter->lock();
|
||||
if(!listener.get()) continue;
|
||||
listener->dataPut(getPtrSelf());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -129,7 +129,7 @@ private:
|
||||
}
|
||||
bool isDestroyed;
|
||||
ChannelLocalPtr channelLocal;
|
||||
ChannelProcessRequester::shared_pointer channelProcessRequester;
|
||||
ChannelProcessRequester::weak_pointer channelProcessRequester;
|
||||
PVRecordPtr pvRecord;
|
||||
int nProcess;
|
||||
Mutex mutex;
|
||||
@ -192,8 +192,10 @@ void ChannelProcessLocal::destroy()
|
||||
|
||||
void ChannelProcessLocal::process()
|
||||
{
|
||||
ChannelProcessRequester::shared_pointer requester = channelProcessRequester.lock();
|
||||
if(!requester.get()) return;
|
||||
if(isDestroyed) {
|
||||
channelProcessRequester->processDone(channelDestroyedStatus,getPtrSelf());
|
||||
requester->processDone(channelDestroyedStatus,getPtrSelf());
|
||||
return;
|
||||
}
|
||||
if(pvRecord->getTraceLevel()>1)
|
||||
@ -213,7 +215,7 @@ void ChannelProcessLocal::process()
|
||||
}
|
||||
pvRecord->unlock();
|
||||
}
|
||||
channelProcessRequester->processDone(Status::Ok,getPtrSelf());
|
||||
requester->processDone(Status::Ok,getPtrSelf());
|
||||
}
|
||||
|
||||
class ChannelGetLocal :
|
||||
@ -271,7 +273,7 @@ private:
|
||||
bool isDestroyed;
|
||||
bool callProcess;
|
||||
ChannelLocalPtr channelLocal;
|
||||
ChannelGetRequester::shared_pointer channelGetRequester;
|
||||
ChannelGetRequester::weak_pointer channelGetRequester;
|
||||
PVCopyPtr pvCopy;
|
||||
PVStructurePtr pvStructure;
|
||||
BitSetPtr bitSet;
|
||||
@ -339,8 +341,10 @@ void ChannelGetLocal::destroy()
|
||||
|
||||
void ChannelGetLocal::get()
|
||||
{
|
||||
ChannelGetRequester::shared_pointer requester = channelGetRequester.lock();
|
||||
if(!requester.get()) return;
|
||||
if(isDestroyed) {
|
||||
channelGetRequester->getDone(
|
||||
requester->getDone(
|
||||
channelDestroyedStatus,getPtrSelf(),nullPVStructure,nullBitSet);
|
||||
return;
|
||||
}
|
||||
@ -363,7 +367,7 @@ void ChannelGetLocal::get()
|
||||
bitSet->set(0);
|
||||
firstTime = false;
|
||||
}
|
||||
channelGetRequester->getDone(
|
||||
requester->getDone(
|
||||
Status::Ok,
|
||||
getPtrSelf(),
|
||||
pvStructure,
|
||||
@ -424,7 +428,7 @@ private:
|
||||
bool isDestroyed;
|
||||
bool callProcess;
|
||||
ChannelLocalPtr channelLocal;
|
||||
ChannelPutRequester::shared_pointer channelPutRequester;
|
||||
ChannelPutRequester::weak_pointer channelPutRequester;
|
||||
PVCopyPtr pvCopy;
|
||||
PVRecordPtr pvRecord;
|
||||
Mutex mutex;
|
||||
@ -487,8 +491,10 @@ void ChannelPutLocal::destroy()
|
||||
|
||||
void ChannelPutLocal::get()
|
||||
{
|
||||
ChannelPutRequester::shared_pointer requester = channelPutRequester.lock();
|
||||
if(!requester.get()) return;
|
||||
if(isDestroyed) {
|
||||
channelPutRequester->getDone(
|
||||
requester->getDone(
|
||||
channelDestroyedStatus,getPtrSelf(),nullPVStructure,nullBitSet);
|
||||
return;
|
||||
}
|
||||
@ -504,7 +510,7 @@ void ChannelPutLocal::get()
|
||||
throw;
|
||||
}
|
||||
pvRecord->unlock();
|
||||
channelPutRequester->getDone(
|
||||
requester->getDone(
|
||||
Status::Ok,getPtrSelf(),pvStructure,bitSet);
|
||||
if(pvRecord->getTraceLevel()>1)
|
||||
{
|
||||
@ -515,8 +521,10 @@ void ChannelPutLocal::get()
|
||||
void ChannelPutLocal::put(
|
||||
PVStructurePtr const &pvStructure,BitSetPtr const &bitSet)
|
||||
{
|
||||
ChannelPutRequester::shared_pointer requester = channelPutRequester.lock();
|
||||
if(!requester.get()) return;
|
||||
if(isDestroyed) {
|
||||
channelPutRequester->putDone(channelDestroyedStatus,getPtrSelf());
|
||||
requester->putDone(channelDestroyedStatus,getPtrSelf());
|
||||
return;
|
||||
}
|
||||
pvRecord->lock();
|
||||
@ -532,7 +540,7 @@ void ChannelPutLocal::put(
|
||||
throw;
|
||||
}
|
||||
pvRecord->unlock();
|
||||
channelPutRequester->putDone(Status::Ok,getPtrSelf());
|
||||
requester->putDone(Status::Ok,getPtrSelf());
|
||||
if(pvRecord->getTraceLevel()>1)
|
||||
{
|
||||
cout << "ChannelPutLocal::put" << endl;
|
||||
@ -578,7 +586,7 @@ private:
|
||||
ChannelPutGetLocal(
|
||||
bool callProcess,
|
||||
ChannelLocalPtr const &channelLocal,
|
||||
ChannelPutGetRequester::shared_pointer const & channelPutGetRequester,
|
||||
ChannelPutGetRequester::weak_pointer const & channelPutGetRequester,
|
||||
PVCopyPtr const &pvPutCopy,
|
||||
PVCopyPtr const &pvGetCopy,
|
||||
PVStructurePtr const&pvGetStructure,
|
||||
@ -599,7 +607,7 @@ private:
|
||||
bool isDestroyed;
|
||||
bool callProcess;
|
||||
ChannelLocalPtr channelLocal;
|
||||
ChannelPutGetRequester::shared_pointer channelPutGetRequester;
|
||||
ChannelPutGetRequester::weak_pointer channelPutGetRequester;
|
||||
PVCopyPtr pvPutCopy;
|
||||
PVCopyPtr pvGetCopy;
|
||||
PVStructurePtr pvGetStructure;
|
||||
@ -675,8 +683,10 @@ void ChannelPutGetLocal::destroy()
|
||||
void ChannelPutGetLocal::putGet(
|
||||
PVStructurePtr const &pvPutStructure,BitSetPtr const &putBitSet)
|
||||
{
|
||||
ChannelPutGetRequester::shared_pointer requester = channelPutGetRequester.lock();
|
||||
if(!requester.get()) return;
|
||||
if(isDestroyed) {
|
||||
channelPutGetRequester->putGetDone(
|
||||
requester->putGetDone(
|
||||
channelDestroyedStatus,getPtrSelf(),nullPVStructure,nullBitSet);
|
||||
return;
|
||||
}
|
||||
@ -693,7 +703,7 @@ void ChannelPutGetLocal::putGet(
|
||||
throw;
|
||||
}
|
||||
pvRecord->unlock();
|
||||
channelPutGetRequester->putGetDone(
|
||||
requester->putGetDone(
|
||||
Status::Ok,getPtrSelf(),pvGetStructure,getBitSet);
|
||||
if(pvRecord->getTraceLevel()>1)
|
||||
{
|
||||
@ -703,8 +713,10 @@ void ChannelPutGetLocal::putGet(
|
||||
|
||||
void ChannelPutGetLocal::getPut()
|
||||
{
|
||||
ChannelPutGetRequester::shared_pointer requester = channelPutGetRequester.lock();
|
||||
if(!requester.get()) return;
|
||||
if(isDestroyed) {
|
||||
channelPutGetRequester->getPutDone(
|
||||
requester->getPutDone(
|
||||
channelDestroyedStatus,getPtrSelf(),nullPVStructure,nullBitSet);
|
||||
return;
|
||||
}
|
||||
@ -718,7 +730,7 @@ void ChannelPutGetLocal::getPut()
|
||||
throw;
|
||||
}
|
||||
pvRecord->unlock();
|
||||
channelPutGetRequester->getPutDone(
|
||||
requester->getPutDone(
|
||||
Status::Ok,getPtrSelf(),pvPutStructure,putBitSet);
|
||||
if(pvRecord->getTraceLevel()>1)
|
||||
{
|
||||
@ -728,8 +740,10 @@ void ChannelPutGetLocal::getPut()
|
||||
|
||||
void ChannelPutGetLocal::getGet()
|
||||
{
|
||||
ChannelPutGetRequester::shared_pointer requester = channelPutGetRequester.lock();
|
||||
if(!requester.get()) return;
|
||||
if(isDestroyed) {
|
||||
channelPutGetRequester->getGetDone(
|
||||
requester->getGetDone(
|
||||
channelDestroyedStatus,getPtrSelf(),nullPVStructure,nullBitSet);
|
||||
return;
|
||||
}
|
||||
@ -742,7 +756,7 @@ void ChannelPutGetLocal::getGet()
|
||||
throw;
|
||||
}
|
||||
pvRecord->unlock();
|
||||
channelPutGetRequester->getGetDone(
|
||||
requester->getGetDone(
|
||||
Status::Ok,getPtrSelf(),pvGetStructure,getBitSet);
|
||||
if(pvRecord->getTraceLevel()>1)
|
||||
{
|
||||
@ -793,7 +807,9 @@ public:
|
||||
virtual void requestDone(Status const & status,
|
||||
PVStructurePtr const & result)
|
||||
{
|
||||
channelRPCRequester->requestDone(status, getPtrSelf(), result);
|
||||
ChannelRPCRequester::shared_pointer requester = channelRPCRequester.lock();
|
||||
if(!requester.get()) return;
|
||||
requester->requestDone(status, getPtrSelf(), result);
|
||||
|
||||
if (isLastRequest.get())
|
||||
destroy();
|
||||
@ -831,7 +847,7 @@ private:
|
||||
|
||||
AtomicBoolean isDestroyed;
|
||||
ChannelLocalPtr channelLocal;
|
||||
ChannelRPCRequester::shared_pointer channelRPCRequester;
|
||||
ChannelRPCRequester::weak_pointer channelRPCRequester;
|
||||
Service::shared_pointer service;
|
||||
PVRecordPtr pvRecord;
|
||||
AtomicBoolean isLastRequest;
|
||||
@ -901,8 +917,8 @@ void ChannelRPCLocal::processRequest(
|
||||
{
|
||||
status = Status(Status::STATUSTYPE_FATAL, "RPCService.request(PVStructure) returned null.");
|
||||
}
|
||||
|
||||
channelRPCRequester->requestDone(status, getPtrSelf(), result);
|
||||
ChannelRPCRequester::shared_pointer requester = channelRPCRequester.lock();
|
||||
if(requester.get()) requester->requestDone(status, getPtrSelf(), result);
|
||||
|
||||
if (isLastRequest.get())
|
||||
destroy();
|
||||
@ -920,9 +936,8 @@ void ChannelRPCLocal::processRequest(
|
||||
{
|
||||
// handle user unexpected errors
|
||||
Status errorStatus(Status::STATUSTYPE_FATAL, ex.what());
|
||||
|
||||
channelRPCRequester->requestDone(errorStatus, getPtrSelf(), PVStructurePtr());
|
||||
|
||||
ChannelRPCRequester::shared_pointer requester = channelRPCRequester.lock();
|
||||
if(requester.get()) requester->requestDone(errorStatus, getPtrSelf(), PVStructurePtr());
|
||||
if (isLastRequest.get())
|
||||
destroy();
|
||||
}
|
||||
@ -931,8 +946,8 @@ void ChannelRPCLocal::processRequest(
|
||||
// handle user unexpected errors
|
||||
Status errorStatus(Status::STATUSTYPE_FATAL,
|
||||
"Unexpected exception caught while calling RPCServiceAsync.request(PVStructure, RPCResponseCallback).");
|
||||
|
||||
channelRPCRequester->requestDone(errorStatus, shared_from_this(), PVStructurePtr());
|
||||
ChannelRPCRequester::shared_pointer requester = channelRPCRequester.lock();
|
||||
if(requester.get()) requester->requestDone(errorStatus, shared_from_this(), PVStructurePtr());
|
||||
|
||||
if (isLastRequest.get())
|
||||
destroy();
|
||||
@ -1032,7 +1047,7 @@ private:
|
||||
}
|
||||
bool isDestroyed;
|
||||
ChannelLocalPtr channelLocal;
|
||||
ChannelArrayRequester::shared_pointer channelArrayRequester;
|
||||
ChannelArrayRequester::weak_pointer channelArrayRequester;
|
||||
PVArrayPtr pvArray;
|
||||
PVArrayPtr pvCopy;
|
||||
PVRecordPtr pvRecord;
|
||||
@ -1141,8 +1156,10 @@ void ChannelArrayLocal::destroy()
|
||||
|
||||
void ChannelArrayLocal::getArray(size_t offset, size_t count, size_t stride)
|
||||
{
|
||||
ChannelArrayRequester::shared_pointer requester = channelArrayRequester.lock();
|
||||
if(!requester.get()) return;
|
||||
if(isDestroyed) {
|
||||
channelArrayRequester->getArrayDone(channelDestroyedStatus,getPtrSelf(),pvCopy);
|
||||
requester->getArrayDone(channelDestroyedStatus,getPtrSelf(),pvCopy);
|
||||
return;
|
||||
}
|
||||
if(pvRecord->getTraceLevel()>1)
|
||||
@ -1150,11 +1167,11 @@ void ChannelArrayLocal::getArray(size_t offset, size_t count, size_t stride)
|
||||
cout << "ChannelArrayLocal::getArray" << endl;
|
||||
}
|
||||
if(offset<0) {
|
||||
channelArrayRequester->getArrayDone(illegalOffsetStatus,getPtrSelf(),pvCopy);
|
||||
requester->getArrayDone(illegalOffsetStatus,getPtrSelf(),pvCopy);
|
||||
return;
|
||||
}
|
||||
if(stride<0) {
|
||||
channelArrayRequester->getArrayDone(illegalStrideStatus,getPtrSelf(),pvCopy);
|
||||
requester->getArrayDone(illegalStrideStatus,getPtrSelf(),pvCopy);
|
||||
return;
|
||||
}
|
||||
const char *exceptionMessage = NULL;
|
||||
@ -1186,14 +1203,16 @@ void ChannelArrayLocal::getArray(size_t offset, size_t count, size_t stride)
|
||||
if(exceptionMessage!=NULL) {
|
||||
status = Status(Status::STATUSTYPE_ERROR,exceptionMessage);
|
||||
}
|
||||
channelArrayRequester->getArrayDone(status,getPtrSelf(),pvCopy);
|
||||
requester->getArrayDone(status,getPtrSelf(),pvCopy);
|
||||
}
|
||||
|
||||
void ChannelArrayLocal::putArray(
|
||||
PVArrayPtr const & pvArray, size_t offset, size_t count, size_t stride)
|
||||
{
|
||||
ChannelArrayRequester::shared_pointer requester = channelArrayRequester.lock();
|
||||
if(!requester.get()) return;
|
||||
if(isDestroyed) {
|
||||
channelArrayRequester->putArrayDone(channelDestroyedStatus,getPtrSelf());
|
||||
requester->putArrayDone(channelDestroyedStatus,getPtrSelf());
|
||||
return;
|
||||
}
|
||||
if(pvRecord->getTraceLevel()>1)
|
||||
@ -1201,15 +1220,15 @@ void ChannelArrayLocal::putArray(
|
||||
cout << "ChannelArrayLocal::putArray" << endl;
|
||||
}
|
||||
if(offset<0) {
|
||||
channelArrayRequester->putArrayDone(illegalOffsetStatus,getPtrSelf());
|
||||
requester->putArrayDone(illegalOffsetStatus,getPtrSelf());
|
||||
return;
|
||||
}
|
||||
if(count<0) {
|
||||
channelArrayRequester->putArrayDone(illegalCountStatus,getPtrSelf());
|
||||
requester->putArrayDone(illegalCountStatus,getPtrSelf());
|
||||
return;
|
||||
}
|
||||
if(stride<0) {
|
||||
channelArrayRequester->putArrayDone(illegalStrideStatus,getPtrSelf());
|
||||
requester->putArrayDone(illegalStrideStatus,getPtrSelf());
|
||||
return;
|
||||
}
|
||||
size_t newLength = offset + count*stride;
|
||||
@ -1226,11 +1245,13 @@ void ChannelArrayLocal::putArray(
|
||||
if(exceptionMessage!=NULL) {
|
||||
status = Status(Status::STATUSTYPE_ERROR,exceptionMessage);
|
||||
}
|
||||
channelArrayRequester->putArrayDone(status,getPtrSelf());
|
||||
requester->putArrayDone(status,getPtrSelf());
|
||||
}
|
||||
|
||||
void ChannelArrayLocal::getLength()
|
||||
{
|
||||
ChannelArrayRequester::shared_pointer requester = channelArrayRequester.lock();
|
||||
if(!requester.get()) return;
|
||||
size_t length = 0;
|
||||
const char *exceptionMessage = NULL;
|
||||
pvRecord->lock();
|
||||
@ -1244,13 +1265,15 @@ void ChannelArrayLocal::getLength()
|
||||
if(exceptionMessage!=NULL) {
|
||||
status = Status(Status::STATUSTYPE_ERROR,exceptionMessage);
|
||||
}
|
||||
channelArrayRequester->getLengthDone(status,getPtrSelf(),length);
|
||||
requester->getLengthDone(status,getPtrSelf(),length);
|
||||
}
|
||||
|
||||
void ChannelArrayLocal::setLength(size_t length)
|
||||
{
|
||||
ChannelArrayRequester::shared_pointer requester = channelArrayRequester.lock();
|
||||
if(!requester.get()) return;
|
||||
if(isDestroyed) {
|
||||
channelArrayRequester->setLengthDone(channelDestroyedStatus,getPtrSelf());
|
||||
requester->setLengthDone(channelDestroyedStatus,getPtrSelf());
|
||||
return;
|
||||
}
|
||||
if(pvRecord->getTraceLevel()>1)
|
||||
@ -1267,7 +1290,7 @@ void ChannelArrayLocal::setLength(size_t length)
|
||||
throw;
|
||||
}
|
||||
pvRecord->unlock();
|
||||
channelArrayRequester->setLengthDone(Status::Ok,getPtrSelf());
|
||||
requester->setLengthDone(Status::Ok,getPtrSelf());
|
||||
}
|
||||
|
||||
|
||||
@ -1315,14 +1338,18 @@ void ChannelLocal::detach(PVRecordPtr const & pvRecord)
|
||||
|
||||
string ChannelLocal::getRequesterName()
|
||||
{
|
||||
return requester->getRequesterName();
|
||||
ChannelRequester::shared_pointer req = requester.lock();
|
||||
if(!req.get()) return string();
|
||||
return req->getRequesterName();
|
||||
}
|
||||
|
||||
void ChannelLocal::message(
|
||||
string const &message,
|
||||
MessageType messageType)
|
||||
{
|
||||
requester->message(message,messageType);
|
||||
ChannelRequester::shared_pointer req = requester.lock();
|
||||
if(!req.get()) return;
|
||||
req->message(message,messageType);
|
||||
}
|
||||
|
||||
string ChannelLocal::getRemoteAddress()
|
||||
@ -1344,7 +1371,7 @@ string ChannelLocal::getChannelName()
|
||||
|
||||
ChannelRequester::shared_pointer ChannelLocal::getChannelRequester()
|
||||
{
|
||||
return requester;
|
||||
return requester.lock();
|
||||
}
|
||||
|
||||
bool ChannelLocal::isConnected()
|
||||
|
@ -394,7 +394,7 @@ protected:
|
||||
}
|
||||
private:
|
||||
ChannelProviderLocalPtr provider;
|
||||
epics::pvAccess::ChannelRequester::shared_pointer requester;
|
||||
epics::pvAccess::ChannelRequester::weak_pointer requester;
|
||||
PVRecordPtr pvRecord;
|
||||
bool beingDestroyed;
|
||||
epics::pvData::Mutex mutex;
|
||||
|
@ -41,6 +41,7 @@ static Status notStartedStatus(Status::STATUSTYPE_ERROR,"not started");
|
||||
|
||||
typedef Queue<MonitorElement> MonitorElementQueue;
|
||||
typedef std::tr1::shared_ptr<MonitorElementQueue> MonitorElementQueuePtr;
|
||||
typedef std::tr1::shared_ptr<MonitorRequester> MonitorRequesterPtr;
|
||||
|
||||
|
||||
|
||||
@ -78,7 +79,7 @@ private:
|
||||
{
|
||||
return shared_from_this();
|
||||
}
|
||||
MonitorRequester::shared_pointer monitorRequester;
|
||||
MonitorRequester::weak_pointer monitorRequester;
|
||||
PVRecordPtr pvRecord;
|
||||
MonitorState state;
|
||||
PVCopyPtr pvCopy;
|
||||
@ -221,7 +222,9 @@ void MonitorLocal::releaseActiveElement()
|
||||
activeElement->changedBitSet->clear();
|
||||
activeElement->overrunBitSet->clear();
|
||||
}
|
||||
monitorRequester->monitorEvent(getPtrSelf());
|
||||
MonitorRequesterPtr requester = monitorRequester.lock();
|
||||
if(!requester.get()) return;
|
||||
requester->monitorEvent(getPtrSelf());
|
||||
return;
|
||||
}
|
||||
|
||||
@ -323,6 +326,8 @@ bool MonitorLocal::init(PVStructurePtr const & pvRequest)
|
||||
PVFieldPtr pvField;
|
||||
size_t queueSize = 2;
|
||||
PVStructurePtr pvOptions = pvRequest->getSubField<PVStructure>("record._options");
|
||||
MonitorRequesterPtr requester = monitorRequester.lock();
|
||||
if(!requester.get()) return false;
|
||||
if(pvOptions) {
|
||||
PVStringPtr pvString = pvOptions->getSubField<PVString>("queueSize");
|
||||
if(pvString) {
|
||||
@ -333,7 +338,7 @@ bool MonitorLocal::init(PVStructurePtr const & pvRequest)
|
||||
ss >> size;
|
||||
queueSize = size;
|
||||
} catch (...) {
|
||||
monitorRequester->message("queueSize " +pvString->get() + " illegal",errorMessage);
|
||||
requester->message("queueSize " +pvString->get() + " illegal",errorMessage);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@ -344,19 +349,19 @@ bool MonitorLocal::init(PVStructurePtr const & pvRequest)
|
||||
pvRecord->getPVRecordStructure()->getPVStructure(),
|
||||
pvRequest,"");
|
||||
if(!pvCopy) {
|
||||
monitorRequester->message("illegal pvRequest",errorMessage);
|
||||
requester->message("illegal pvRequest",errorMessage);
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
if(pvField->getField()->getType()!=structure) {
|
||||
monitorRequester->message("illegal pvRequest",errorMessage);
|
||||
requester->message("illegal pvRequest",errorMessage);
|
||||
return false;
|
||||
}
|
||||
pvCopy = PVCopy::create(
|
||||
pvRecord->getPVRecordStructure()->getPVStructure(),
|
||||
pvRequest,"field");
|
||||
if(!pvCopy) {
|
||||
monitorRequester->message("illegal pvRequest",errorMessage);
|
||||
requester->message("illegal pvRequest",errorMessage);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@ -370,7 +375,7 @@ bool MonitorLocal::init(PVStructurePtr const & pvRequest)
|
||||
monitorElementArray.push_back(monitorElement);
|
||||
}
|
||||
queue = MonitorElementQueuePtr(new MonitorElementQueue(monitorElementArray));
|
||||
monitorRequester->monitorConnect(
|
||||
requester->monitorConnect(
|
||||
Status::Ok,
|
||||
getPtrSelf(),
|
||||
pvCopy->getStructure());
|
||||
|
@ -26,6 +26,7 @@
|
||||
#include <epicsThread.h>
|
||||
#include <iocsh.h>
|
||||
#include <shareLib.h>
|
||||
#include <epicsExit.h>
|
||||
|
||||
#include <pv/pvAccess.h>
|
||||
#include <pv/serverContext.h>
|
||||
@ -52,6 +53,9 @@ extern "C" void pvdbl(const iocshArgBuf *args)
|
||||
for(size_t i=0; i<xxx.size(); ++i) cout<< xxx[i] << endl;
|
||||
}
|
||||
|
||||
static void channelProviderLocalExitHandler(void* /*pPrivate*/) {
|
||||
getChannelProviderLocal()->destroy();
|
||||
}
|
||||
|
||||
static void registerChannelProviderLocal(void)
|
||||
{
|
||||
@ -60,6 +64,7 @@ static void registerChannelProviderLocal(void)
|
||||
firstTime = 0;
|
||||
iocshRegister(&pvdblFuncDef, pvdbl);
|
||||
getChannelProviderLocal();
|
||||
epicsAtExit(channelProviderLocalExitHandler, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user