diff --git a/documentation/htmldoxygen/pvaClientGetRequester.html b/documentation/htmldoxygen/pvaClientGetRequester.html new file mode 100644 index 0000000..e2fe9f6 --- /dev/null +++ b/documentation/htmldoxygen/pvaClientGetRequester.html @@ -0,0 +1,44 @@ + + + + + + PvaClientGetRequester + + + + + + + + +

PvaClientGetRequester

+ +

+Not Yet Written +

+ + + + diff --git a/documentation/htmldoxygen/pvaClientPutRequester.html b/documentation/htmldoxygen/pvaClientPutRequester.html new file mode 100644 index 0000000..00aed26 --- /dev/null +++ b/documentation/htmldoxygen/pvaClientPutRequester.html @@ -0,0 +1,44 @@ + + + + + + PvaClientPutRequester + + + + + + + + +

PvaClientPutRequester

+ +

+Not Yet Written +

+ + + + diff --git a/src/pv/pvaClient.h b/src/pv/pvaClient.h index cbb3b57..560a5a2 100644 --- a/src/pv/pvaClient.h +++ b/src/pv/pvaClient.h @@ -59,8 +59,14 @@ class PvaClientField; typedef std::tr1::shared_ptr PvaClientFieldPtr; class PvaClientProcess; typedef std::tr1::shared_ptr PvaClientProcessPtr; +class PvaClientGetRequester; +typedef std::tr1::shared_ptr PvaClientGetRequesterPtr; +typedef std::tr1::weak_ptr PvaClientGetRequesterWPtr; class PvaClientGet; typedef std::tr1::shared_ptr PvaClientGetPtr; +class PvaClientPutRequester; +typedef std::tr1::shared_ptr PvaClientPutRequesterPtr; +typedef std::tr1::weak_ptr PvaClientPutRequesterWPtr; class PvaClientPut; typedef std::tr1::shared_ptr PvaClientPutPtr; class PvaClientPutGet; @@ -939,6 +945,7 @@ public: epics::pvAccess::Channel::shared_pointer const & channel, epics::pvData::PVStructurePtr const &pvRequest ); + /** @brief Destructor */ ~PvaClientProcess(); @@ -1009,29 +1016,82 @@ private: // because pvAccess holds a shared_ptr to ChannelGetRequester instead of weak_pointer class ChannelGetRequesterImpl; typedef std::tr1::shared_ptr ChannelGetRequesterImplPtr; + +/** + * @brief Optional client callback. + * + * Overview of PvaClientGetRequester + */ +class PvaClientGetRequester +{ +public: + POINTER_DEFINITIONS(PvaClientGetRequester); + virtual ~PvaClientGetRequester() {} + /** @brief A channelGet has connected. + * + * @param status The status returned by the server. + * @param clientGet The PvaClientGet that issued the request to create a ChannelGet. + */ + virtual void channelGetConnect( + const epics::pvData::Status& status, + PvaClientGetPtr const & clientGet); + /** @brief A get request is complete. + * + * @param status The status returned by the server. + * @param clientGet The PvaClientGet that issued the request to create a ChannelGet. + */ + virtual void getDone( + const epics::pvData::Status& status, + PvaClientGetPtr const & clientGet); +}; /** * @brief An easy to use alternative to ChannelGet. * * Overview of PvaClientGet */ -class epicsShareClass PvaClientGet +class epicsShareClass PvaClientGet : + public PvaClientChannelStateChangeRequester, + public std::tr1::enable_shared_from_this { public: POINTER_DEFINITIONS(PvaClientGet); /** @brief Create a PvaClientGet. - * @param &pvaClient Interface to PvaClient - * @param channel Interface to Channel + * @param pvaClient Interface to PvaClient + * @param pvaClientChannel Interface to PvaClientChannel * @param pvRequest The request structure. * @return The interface to the PvaClientGet. */ static PvaClientGetPtr create( PvaClientPtr const &pvaClient, - epics::pvAccess::Channel::shared_pointer const & channel, + PvaClientChannelPtr const & pvaClientChannel, epics::pvData::PVStructurePtr const &pvRequest ); + /** @brief Create a PvaClientGet. + * @param pvaClient Interface to PvaClient + * @param channelName channel name + * @param providerName provider name + * @param request The request. + * @param stateChangeRequester The state change requester. Can be null. + * @param GetRequester The Get requester. Can be null; + * @return The new instance. + */ + static PvaClientGetPtr create( + PvaClientPtr const &pvaClient, + std::string const & channelName, + std::string const & providerName, + std::string const & request, + PvaClientChannelStateChangeRequesterPtr const & stateChangeRequester + = PvaClientChannelStateChangeRequesterPtr(), + PvaClientGetRequesterPtr const & getRequester + = PvaClientGetRequesterPtr() + ); /** @brief Destructor */ ~PvaClientGet(); + /** @brief Set a user callback. + * @param pvaClientGetRequester The requester which must be implemented by the caller. + */ + void setRequester(PvaClientGetRequesterPtr const & pvaClientGetRequester); /** @brief Call issueConnect and then waitConnect. * * An exception is thrown if connect fails. @@ -1064,6 +1124,11 @@ public: * @return The interface. */ PvaClientGetDataPtr getData(); + /** @brief Get the PvaClientChannel; + * + * @return The interface. + */ + PvaClientChannelPtr getPvaClientChannel(); private: std::string getRequesterName(); void message(std::string const & message,epics::pvData::MessageType messageType); @@ -1079,14 +1144,14 @@ private: PvaClientGet( PvaClientPtr const &pvaClient, - epics::pvAccess::Channel::shared_pointer const & channel, + PvaClientChannelPtr const & pvaClientChannel, epics::pvData::PVStructurePtr const &pvRequest); void checkGetState(); enum GetConnectState {connectIdle,connectActive,connected}; PvaClient::weak_pointer pvaClient; - epics::pvAccess::Channel::weak_pointer channel; + PvaClientChannelPtr pvaClientChannel; epics::pvData::PVStructurePtr pvRequest; epics::pvData::Mutex mutex; epics::pvData::Event waitForConnect; @@ -1100,9 +1165,14 @@ private: GetConnectState connectState; + PvaClientChannelStateChangeRequesterWPtr pvaClientChannelStateChangeRequester; + PvaClientGetRequesterWPtr pvaClientGetRequester; + enum GetState {getIdle,getActive,getComplete}; GetState getState; ChannelGetRequesterImplPtr channelGetRequester; +public: + void channelStateChange(PvaClientChannelPtr const & pvaClientChannel, bool isConnected); friend class ChannelGetRequesterImpl; }; @@ -1112,12 +1182,50 @@ private: class ChannelPutRequesterImpl; typedef std::tr1::shared_ptr ChannelPutRequesterImplPtr; +/** + * @brief Optional client callback. + * + * Overview of PvaClientPutRequester + */ +class PvaClientPutRequester +{ +public: + POINTER_DEFINITIONS(PvaClientPutRequester); + virtual ~PvaClientPutRequester() {} + /** @brief A channelPut has connected. + * + * @param status The status returned by the server. + * @param clientPut The PvaClientPut that issued the request to create a ChannelPut. + */ + virtual void channelPutConnect( + const epics::pvData::Status& status, + PvaClientPutPtr const & clientPut); + /** @brief A get request is complete. + * + * @param status The status returned by the server. + * @param clientPut The PvaClientPut that issued the request to create a ChannelPut. + */ + virtual void getDone( + const epics::pvData::Status& status, + PvaClientPutPtr const & clientPut); + /** @brief A put request is complete. + * + * @param status The status returned by the server. + * @param clientPut The PvaClientPut that issued the request to create a ChannelPut. + */ + virtual void putDone( + const epics::pvData::Status& status, + PvaClientPutPtr const & clientPut); +}; + /** * @brief An easy to use alternative to ChannelPut. * * Overview of PvaClientPut */ -class epicsShareClass PvaClientPut +class epicsShareClass PvaClientPut : + public PvaClientChannelStateChangeRequester, + public std::tr1::enable_shared_from_this { public: POINTER_DEFINITIONS(PvaClientPut); @@ -1129,13 +1237,35 @@ public: */ static PvaClientPutPtr create( PvaClientPtr const &pvaClient, - epics::pvAccess::Channel::shared_pointer const & channel, + PvaClientChannelPtr const & pvaClientChannel, epics::pvData::PVStructurePtr const &pvRequest ); + /** @brief Create a PvaClientPut. + * @param pvaClient Interface to PvaClient + * @param channelName channel name + * @param providerName provider name + * @param request The request. + * @param stateChangeRequester The state change requester. Can be null. + * @param PutRequester The Put requester. Can be null; + * @return The new instance. + */ + static PvaClientPutPtr create( + PvaClientPtr const &pvaClient, + std::string const & channelName, + std::string const & providerName, + std::string const & request, + PvaClientChannelStateChangeRequesterPtr const & stateChangeRequester + = PvaClientChannelStateChangeRequesterPtr(), + PvaClientPutRequesterPtr const & putRequester + = PvaClientPutRequesterPtr() + ); /** @brief Destructor */ ~PvaClientPut(); - + /** @brief Set a user callback. + * @param pvaClientPutRequester The requester which must be implemented by the caller. + */ + void setRequester(PvaClientPutRequesterPtr const & pvaClientPutRequester); /** @brief Call issueConnect and then waitConnect. * * An exception is thrown if connect fails. @@ -1180,6 +1310,11 @@ public: * @return The interface. */ PvaClientPutDataPtr getData(); + /** @brief Get the PvaClientChannel; + * + * @return The interface. + */ + PvaClientChannelPtr getPvaClientChannel(); private : std::string getRequesterName(); void message(std::string const & message,epics::pvData::MessageType messageType); @@ -1197,14 +1332,14 @@ private : epics::pvAccess::ChannelPut::shared_pointer const & channelPut); PvaClientPut( PvaClientPtr const &pvaClient, - epics::pvAccess::Channel::shared_pointer const & channel, + PvaClientChannelPtr const & pvaClientChannel, epics::pvData::PVStructurePtr const &pvRequest); void checkPutState(); enum PutConnectState {connectIdle,connectActive,connected}; PvaClient::weak_pointer pvaClient; - epics::pvAccess::Channel::weak_pointer channel; + PvaClientChannelPtr pvaClientChannel; epics::pvData::PVStructurePtr pvRequest; epics::pvData::Mutex mutex; epics::pvData::Event waitForConnect; @@ -1219,6 +1354,10 @@ private : enum PutState {putIdle,getActive,putActive}; PutState putState; ChannelPutRequesterImplPtr channelPutRequester; + PvaClientChannelStateChangeRequesterWPtr pvaClientChannelStateChangeRequester; + PvaClientPutRequesterWPtr pvaClientPutRequester; +public: + void channelStateChange(PvaClientChannelPtr const & pvaClientChannel, bool isConnected); friend class ChannelPutRequesterImpl; }; @@ -1434,8 +1573,10 @@ public: std::string const & channelName, std::string const & providerName, std::string const & request, - PvaClientChannelStateChangeRequesterPtr const & stateChangeRequester, - PvaClientMonitorRequesterPtr const & monitorRequester + PvaClientChannelStateChangeRequesterPtr const & stateChangeRequester + = PvaClientChannelStateChangeRequesterPtr(), + PvaClientMonitorRequesterPtr const & monitorRequester + = PvaClientMonitorRequesterPtr() ); /** @brief Destructor */ @@ -1536,7 +1677,6 @@ private: bool userWait; MonitorRequesterImplPtr monitorRequester; - void init(); public: void channelStateChange(PvaClientChannelPtr const & channel, bool isConnected); void event(PvaClientMonitorPtr const & monitor); diff --git a/src/pvaClientChannel.cpp b/src/pvaClientChannel.cpp index 886018c..b17b45d 100644 --- a/src/pvaClientChannel.cpp +++ b/src/pvaClientChannel.cpp @@ -373,7 +373,7 @@ PvaClientGetPtr PvaClientChannel::createGet(PVStructurePtr const & pvRequest) if(connectState!=connected) connect(5.0); PvaClientPtr yyy = pvaClient.lock(); if(!yyy) throw std::runtime_error("PvaClient was destroyed"); - return PvaClientGet::create(yyy,channel,pvRequest); + return PvaClientGet::create(yyy,shared_from_this(),pvRequest); } @@ -406,7 +406,7 @@ PvaClientPutPtr PvaClientChannel::createPut(PVStructurePtr const & pvRequest) if(connectState!=connected) connect(5.0); PvaClientPtr yyy = pvaClient.lock(); if(!yyy) throw std::runtime_error("PvaClient was destroyed"); - return PvaClientPut::create(yyy,channel,pvRequest); + return PvaClientPut::create(yyy,shared_from_this(),pvRequest); } PvaClientPutGetPtr PvaClientChannel::createPutGet(string const & request) diff --git a/src/pvaClientGet.cpp b/src/pvaClientGet.cpp index 34e4f89..b5386d0 100644 --- a/src/pvaClientGet.cpp +++ b/src/pvaClientGet.cpp @@ -73,29 +73,57 @@ public: PvaClientGetPtr PvaClientGet::create( PvaClientPtr const &pvaClient, - Channel::shared_pointer const & channel, + PvaClientChannelPtr const & pvaClientChannel, PVStructurePtr const &pvRequest) { - PvaClientGetPtr epv(new PvaClientGet(pvaClient,channel,pvRequest)); - epv->channelGetRequester = ChannelGetRequesterImplPtr( - new ChannelGetRequesterImpl(epv,pvaClient)); - return epv; + PvaClientGetPtr clientGet(new PvaClientGet(pvaClient,pvaClientChannel,pvRequest)); + clientGet->channelGetRequester = ChannelGetRequesterImplPtr( + new ChannelGetRequesterImpl(clientGet,pvaClient)); + return clientGet; } +PvaClientGetPtr PvaClientGet::create( + PvaClientPtr const &pvaClient, + std::string const & channelName, + std::string const & providerName, + std::string const & request, + PvaClientChannelStateChangeRequesterPtr const & stateChangeRequester, + PvaClientGetRequesterPtr const & getRequester) +{ + if(PvaClient::getDebug()) { + cout<< "PvaClientGet::create(pvaClient,channelName,providerName,request,stateChangeRequester,getRequester)\n" + << " channelName " << channelName + << " providerName " << providerName + << " request " << request + << endl; + } + CreateRequest::shared_pointer createRequest(CreateRequest::create()); + PVStructurePtr pvRequest(createRequest->createRequest(request)); + if(!pvRequest) throw std::runtime_error(createRequest->getMessage()); + PvaClientChannelPtr pvaClientChannel = pvaClient->createChannel(channelName,providerName); + PvaClientGetPtr clientGet(new PvaClientGet(pvaClient,pvaClientChannel,pvRequest)); + clientGet->channelGetRequester = ChannelGetRequesterImplPtr( + new ChannelGetRequesterImpl(clientGet,pvaClient)); + if(stateChangeRequester) clientGet->pvaClientChannelStateChangeRequester = stateChangeRequester; + if(getRequester) clientGet->pvaClientGetRequester = getRequester; + pvaClientChannel->setStateChangeRequester(clientGet); + pvaClientChannel->issueConnect(); + return clientGet; +} PvaClientGet::PvaClientGet( PvaClientPtr const &pvaClient, - Channel::shared_pointer const & channel, + PvaClientChannelPtr const & pvaClientChannel, PVStructurePtr const &pvRequest) : pvaClient(pvaClient), - channel(channel), + pvaClientChannel(pvaClientChannel), pvRequest(pvRequest), connectState(connectIdle), getState(getIdle) { if(PvaClient::getDebug()) { cout << "PvaClientGet::PvaClientGet::PvaClientGet" - << " channelName " << channel->getChannelName() + << " channelName " << pvaClientChannel->getChannel()->getChannelName() << endl; } } @@ -103,18 +131,39 @@ PvaClientGet::PvaClientGet( PvaClientGet::~PvaClientGet() { if(PvaClient::getDebug()) { - string channelName("disconnected"); - Channel::shared_pointer chan(channel.lock()); - if(chan) channelName = chan->getChannelName(); - cout<< "PvaClientGet::~PvaClientGet" - << " channelName " << channelName + cout<< "PvaClientGet::~PvaClientGet" + << " channelName " << pvaClientChannel->getChannel()->getChannelName() << endl; } if(channelGet) channelGet->destroy(); } +void PvaClientGet::channelStateChange(PvaClientChannelPtr const & pvaClientChannel, bool isConnected) +{ + if(PvaClient::getDebug()) { + cout<< "PvaClientGet::channelStateChange" + << " channelName " << pvaClientChannel->getChannel()->getChannelName() + << " isConnected " << (isConnected ? "true" : "false") + << endl; + } + if(isConnected&&!channelGet) + { + connectState = connectActive; + channelGet = pvaClientChannel->getChannel()->createChannelGet(channelGetRequester,pvRequest); + } + PvaClientChannelStateChangeRequesterPtr req(pvaClientChannelStateChangeRequester.lock()); + if(req) { + req->channelStateChange(pvaClientChannel,isConnected); + } +} + void PvaClientGet::checkGetState() { + if(!pvaClientChannel->getChannel()->isConnected()) { + string message = string("channel ") + pvaClientChannel->getChannel()->getChannelName() + + " PvaClientGet::checkGetState channel not connected "; + throw std::runtime_error(message); + } if(connectState==connectIdle) connect(); if(getState==getIdle) get(); } @@ -140,11 +189,8 @@ void PvaClientGet::channelGetConnect( StructureConstPtr const & structure) { if(PvaClient::getDebug()) { - string channelName("disconnected"); - Channel::shared_pointer chan(channel.lock()); - if(chan) channelName = chan->getChannelName(); cout << "PvaClientGet::channelGetConnect" - << " channelName " << channelName + << " channelName " << pvaClientChannel->getChannel()->getChannelName() << " status.isOK " << (status.isOK() ? "true" : "false") << endl; } @@ -158,6 +204,10 @@ void PvaClientGet::channelGetConnect( pvaClientData->setMessagePrefix(channelGet->getChannel()->getChannelName()); } } + PvaClientGetRequesterPtr req(pvaClientGetRequester.lock()); + if(req) { + req->channelGetConnect(status,shared_from_this()); + } waitForConnect.signal(); } @@ -169,11 +219,8 @@ void PvaClientGet::getDone( BitSetPtr const & bitSet) { if(PvaClient::getDebug()) { - string channelName("disconnected"); - Channel::shared_pointer chan(channel.lock()); - if(chan) channelName = chan->getChannelName(); cout << "PvaClientGet::getDone" - << " channelName " << channelName + << " channelName " << pvaClientChannel->getChannel()->getChannelName() << " status.isOK " << (status.isOK() ? "true" : "false") << endl; } @@ -184,6 +231,10 @@ void PvaClientGet::getDone( pvaClientData->setData(pvStructure,bitSet); } } + PvaClientGetRequesterPtr req(pvaClientGetRequester.lock()); + if(req) { + req->getDone(status,shared_from_this()); + } waitForGet.signal(); } @@ -192,30 +243,20 @@ void PvaClientGet::connect() issueConnect(); Status status = waitConnect(); if(status.isOK()) return; - Channel::shared_pointer chan(channel.lock()); - string channelName("disconnected"); - if(chan) channelName = chan->getChannelName(); - string message = string("channel ") + channelName + string message = string("channel ") + pvaClientChannel->getChannel()->getChannelName() + " PvaClientGet::connect " + status.getMessage(); throw std::runtime_error(message); } void PvaClientGet::issueConnect() { - Channel::shared_pointer chan(channel.lock()); if(connectState!=connectIdle) { - string channelName("disconnected"); - if(chan) channelName = chan->getChannelName(); - string message = string("channel ") + channelName + string message = string("channel ") + pvaClientChannel->getChannel()->getChannelName() + " pvaClientGet already connected "; throw std::runtime_error(message); } - if(chan) { - connectState = connectActive; - channelGet = chan->createChannelGet(channelGetRequester,pvRequest); - return; - } - throw std::runtime_error("PvaClientGet::issueConnect channel was destroyed"); + connectState = connectActive; + channelGet = pvaClientChannel->getChannel()->createChannelGet(channelGetRequester,pvRequest); } Status PvaClientGet::waitConnect() @@ -227,10 +268,7 @@ Status PvaClientGet::waitConnect() return channelGetConnectStatus; } if(connectState!=connectActive) { - Channel::shared_pointer chan(channel.lock()); - string channelName("disconnected"); - if(chan) channelName = chan->getChannelName(); - string message = string("channel ") + channelName + string message = string("channel ") + pvaClientChannel->getChannel()->getChannelName() + " PvaClientGet::waitConnect illegal connect state "; throw std::runtime_error(message); } @@ -245,10 +283,7 @@ void PvaClientGet::get() issueGet(); Status status = waitGet(); if(status.isOK()) return; - Channel::shared_pointer chan(channel.lock()); - string channelName("disconnected"); - if(chan) channelName = chan->getChannelName(); - string message = string("channel ") + channelName + string message = string("channel ") + pvaClientChannel->getChannel()->getChannelName() + " PvaClientGet::get " + status.getMessage(); throw std::runtime_error(message); } @@ -257,10 +292,7 @@ void PvaClientGet::issueGet() { if(connectState==connectIdle) connect(); if(getState==getActive) { - Channel::shared_pointer chan(channel.lock()); - string channelName("disconnected"); - if(chan) channelName = chan->getChannelName(); - string message = string("channel ") + channelName + string message = string("channel ") + pvaClientChannel->getChannel()->getChannelName() + " PvaClientGet::issueGet get aleady active "; throw std::runtime_error(message); } @@ -276,10 +308,7 @@ Status PvaClientGet::waitGet() return channelGetStatus; } if(getState!=getActive){ - Channel::shared_pointer chan(channel.lock()); - string channelName("disconnected"); - if(chan) channelName = chan->getChannelName(); - string message = string("channel ") + channelName + string message = string("channel ") + pvaClientChannel->getChannel()->getChannelName() + " PvaClientGet::waitGet llegal get state"; throw std::runtime_error(message); } @@ -294,5 +323,21 @@ PvaClientGetDataPtr PvaClientGet::getData() return pvaClientData; } +void PvaClientGet::setRequester(PvaClientGetRequesterPtr const & pvaClientGetRequester) +{ + if(PvaClient::getDebug()) { + cout << "PvaClientGet::setRequester" + << " channelName " << pvaClientChannel->getChannel()->getChannelName() + << endl; + } + this->pvaClientGetRequester = pvaClientGetRequester; +} + +PvaClientChannelPtr PvaClientGet::getPvaClientChannel() +{ + return pvaClientChannel; +} + + }} diff --git a/src/pvaClientMonitor.cpp b/src/pvaClientMonitor.cpp index b1c2c04..db2b68b 100644 --- a/src/pvaClientMonitor.cpp +++ b/src/pvaClientMonitor.cpp @@ -118,15 +118,11 @@ PvaClientMonitorPtr PvaClientMonitor::create( new MonitorRequesterImpl(clientMonitor,pvaClient)); if(stateChangeRequester) clientMonitor->pvaClientChannelStateChangeRequester = stateChangeRequester; if(monitorRequester) clientMonitor->pvaClientMonitorRequester = monitorRequester; - clientMonitor->init(); + pvaClientChannel->setStateChangeRequester(clientMonitor); + pvaClientChannel->issueConnect(); return clientMonitor; } -void PvaClientMonitor::init() -{ - pvaClientChannel->setStateChangeRequester(shared_from_this()); - pvaClientChannel->issueConnect(); -} PvaClientMonitor::PvaClientMonitor( PvaClientPtr const &pvaClient, @@ -147,7 +143,6 @@ PvaClientMonitor::PvaClientMonitor( PvaClientMonitor::~PvaClientMonitor() { - if(PvaClient::getDebug()) cout<< "PvaClientMonitor::~PvaClientMonitor\n"; if(PvaClient::getDebug()) { cout<< "PvaClientMonitor::~PvaClientMonitor" << " channelName " << pvaClientChannel->getChannel()->getChannelName() diff --git a/src/pvaClientPut.cpp b/src/pvaClientPut.cpp index 8b21cb7..e267ef3 100644 --- a/src/pvaClientPut.cpp +++ b/src/pvaClientPut.cpp @@ -82,30 +82,58 @@ public: PvaClientPutPtr PvaClientPut::create( PvaClientPtr const &pvaClient, - Channel::shared_pointer const & channel, + PvaClientChannelPtr const & pvaClientChannel, PVStructurePtr const &pvRequest) { - PvaClientPutPtr epv(new PvaClientPut(pvaClient,channel,pvRequest)); - epv->channelPutRequester = ChannelPutRequesterImplPtr( - new ChannelPutRequesterImpl(epv,pvaClient)); - return epv; + PvaClientPutPtr clientPut(new PvaClientPut(pvaClient,pvaClientChannel,pvRequest)); + clientPut->channelPutRequester = ChannelPutRequesterImplPtr( + new ChannelPutRequesterImpl(clientPut,pvaClient)); + return clientPut; } +PvaClientPutPtr PvaClientPut::create( + PvaClientPtr const &pvaClient, + std::string const & channelName, + std::string const & providerName, + std::string const & request, + PvaClientChannelStateChangeRequesterPtr const & stateChangeRequester, + PvaClientPutRequesterPtr const & putRequester) +{ + if(PvaClient::getDebug()) { + cout<< "PvaClientPut::create(pvaClient,channelName,providerName,request,stateChangeRequester,putRequester)\n" + << " channelName " << channelName + << " providerName " << providerName + << " request " << request + << endl; + } + CreateRequest::shared_pointer createRequest(CreateRequest::create()); + PVStructurePtr pvRequest(createRequest->createRequest(request)); + if(!pvRequest) throw std::runtime_error(createRequest->getMessage()); + PvaClientChannelPtr pvaClientChannel = pvaClient->createChannel(channelName,providerName); + PvaClientPutPtr clientPut(new PvaClientPut(pvaClient,pvaClientChannel,pvRequest)); + clientPut->channelPutRequester = ChannelPutRequesterImplPtr( + new ChannelPutRequesterImpl(clientPut,pvaClient)); + if(stateChangeRequester) clientPut->pvaClientChannelStateChangeRequester = stateChangeRequester; + if(putRequester) clientPut->pvaClientPutRequester = putRequester; + pvaClientChannel->setStateChangeRequester(clientPut); + pvaClientChannel->issueConnect(); + return clientPut; +} PvaClientPut::PvaClientPut( PvaClientPtr const &pvaClient, - Channel::shared_pointer const & channel, + PvaClientChannelPtr const & pvaClientChannel, PVStructurePtr const &pvRequest) : pvaClient(pvaClient), - channel(channel), + pvaClientChannel(pvaClientChannel), pvRequest(pvRequest), connectState(connectIdle), putState(putIdle) { if(PvaClient::getDebug()) { cout<< "PvaClientPut::PvaClientPut" - << " channelName " << channel->getChannelName() + << " channelName " << pvaClientChannel->getChannel()->getChannelName() << endl; } } @@ -113,18 +141,39 @@ PvaClientPut::PvaClientPut( PvaClientPut::~PvaClientPut() { if(PvaClient::getDebug()) { - string channelName("disconnected"); - Channel::shared_pointer chan(channel.lock()); - if(chan) channelName = chan->getChannelName(); cout<< "PvaClientPut::~PvaClientPut" - << " channelName " << channelName + << " channelName " << pvaClientChannel->getChannel()->getChannelName() << endl; } if(channelPut) channelPut->destroy(); } +void PvaClientPut::channelStateChange(PvaClientChannelPtr const & pvaClientChannel, bool isConnected) +{ + if(PvaClient::getDebug()) { + cout<< "PvaClientPut::channelStateChange" + << " channelName " << pvaClientChannel->getChannel()->getChannelName() + << " isConnected " << (isConnected ? "true" : "false") + << endl; + } + if(isConnected&&!channelPut) + { + connectState = connectActive; + channelPut = pvaClientChannel->getChannel()->createChannelPut(channelPutRequester,pvRequest); + } + PvaClientChannelStateChangeRequesterPtr req(pvaClientChannelStateChangeRequester.lock()); + if(req) { + req->channelStateChange(pvaClientChannel,isConnected); + } +} + void PvaClientPut::checkPutState() { + if(!pvaClientChannel->getChannel()->isConnected()) { + string message = string("channel ") + pvaClientChannel->getChannel()->getChannelName() + + " PvaClientPut::checkPutState channel not connected "; + throw std::runtime_error(message); + } if(connectState==connectIdle){ connect(); get(); @@ -151,11 +200,8 @@ void PvaClientPut::channelPutConnect( StructureConstPtr const & structure) { if(PvaClient::getDebug()) { - string channelName("disconnected"); - Channel::shared_pointer chan(channel.lock()); - if(chan) channelName = chan->getChannelName(); cout << "PvaClientPut::channelPutConnect" - << " channelName " << channelName + << " channelName " << pvaClientChannel->getChannel()->getChannelName() << " status.isOK " << (status.isOK() ? "true" : "false") << endl; } @@ -168,6 +214,10 @@ void PvaClientPut::channelPutConnect( pvaClientData->setMessagePrefix(channelPut->getChannel()->getChannelName()); } } + PvaClientPutRequesterPtr req(pvaClientPutRequester.lock()); + if(req) { + req->channelPutConnect(status,shared_from_this()); + } waitForConnect.signal(); } @@ -179,11 +229,8 @@ void PvaClientPut::getDone( BitSetPtr const & bitSet) { if(PvaClient::getDebug()) { - string channelName("disconnected"); - Channel::shared_pointer chan(channel.lock()); - if(chan) channelName = chan->getChannelName(); cout << "PvaClientPut::getDone" - << " channelName " << channelName + << " channelName " << pvaClientChannel->getChannel()->getChannelName() << " status.isOK " << (status.isOK() ? "true" : "false") << endl; } @@ -195,6 +242,10 @@ void PvaClientPut::getDone( bs->clear(); *bs |= *bitSet; } + PvaClientPutRequesterPtr req(pvaClientPutRequester.lock()); + if(req) { + req->getDone(status,shared_from_this()); + } waitForGetPut.signal(); } @@ -203,15 +254,16 @@ void PvaClientPut::putDone( ChannelPut::shared_pointer const & channelPut) { if(PvaClient::getDebug()) { - string channelName("disconnected"); - Channel::shared_pointer chan(channel.lock()); - if(chan) channelName = chan->getChannelName(); cout << "PvaClientPut::putDone" - << " channelName " << channelName + << " channelName " << pvaClientChannel->getChannel()->getChannelName() << " status.isOK " << (status.isOK() ? "true" : "false") << endl; } channelGetPutStatus = status; + PvaClientPutRequesterPtr req(pvaClientPutRequester.lock()); + if(req) { + req->putDone(status,shared_from_this()); + } waitForGetPut.signal(); } @@ -220,11 +272,8 @@ void PvaClientPut::connect() issueConnect(); Status status = waitConnect(); if(status.isOK()) return; - Channel::shared_pointer chan(channel.lock()); - string channelName("disconnected"); - if(chan) channelName = chan->getChannelName(); string message = string("channel ") - + channelName + + pvaClientChannel->getChannel()->getChannelName() + " PvaClientPut::connect " + status.getMessage(); throw std::runtime_error(message); @@ -232,20 +281,14 @@ void PvaClientPut::connect() void PvaClientPut::issueConnect() { - Channel::shared_pointer chan(channel.lock()); if(connectState!=connectIdle) { - string channelName("disconnected"); - if(chan) channelName = chan->getChannelName(); - string message = string("channel ") + channelName + string message = string("channel ") + pvaClientChannel->getChannel()->getChannelName() + " pvaClientPut already connected "; throw std::runtime_error(message); } - if(chan) { - connectState = connectActive; - channelPut = chan->createChannelPut(channelPutRequester,pvRequest); - return; - } - throw std::runtime_error("PvaClientPut::issueConnect() but channel disconnected"); + connectState = connectActive; + channelPut = pvaClientChannel->getChannel()->createChannelPut(channelPutRequester,pvRequest); + } Status PvaClientPut::waitConnect() @@ -257,10 +300,7 @@ Status PvaClientPut::waitConnect() return channelPutConnectStatus; } if(connectState!=connectActive) { - Channel::shared_pointer chan(channel.lock()); - string channelName("disconnected"); - if(chan) channelName = chan->getChannelName(); - string message = string("channel ") + channelName + string message = string("channel ") + pvaClientChannel->getChannel()->getChannelName() + " PvaClientPut::waitConnect illegal connect state "; throw std::runtime_error(message); } @@ -275,11 +315,8 @@ void PvaClientPut::get() issueGet(); Status status = waitGet(); if(status.isOK()) return; - Channel::shared_pointer chan(channel.lock()); - string channelName("disconnected"); - if(chan) channelName = chan->getChannelName(); string message = string("channel ") - + channelName + + pvaClientChannel->getChannel()->getChannelName() + " PvaClientPut::get " + status.getMessage(); throw std::runtime_error(message); @@ -289,11 +326,8 @@ void PvaClientPut::issueGet() { if(connectState==connectIdle) connect(); if(putState!=putIdle) { - Channel::shared_pointer chan(channel.lock()); - string channelName("disconnected"); - if(chan) channelName = chan->getChannelName(); string message = string("channel ") - + channelName + + pvaClientChannel->getChannel()->getChannelName() + "PvaClientPut::issueGet get or put aleady active "; throw std::runtime_error(message); } @@ -304,11 +338,8 @@ void PvaClientPut::issueGet() Status PvaClientPut::waitGet() { if(putState!=getActive){ - Channel::shared_pointer chan(channel.lock()); - string channelName("disconnected"); - if(chan) channelName = chan->getChannelName(); string message = string("channel ") - + channelName + + pvaClientChannel->getChannel()->getChannelName() + " PvaClientPut::waitGet illegal put state"; throw std::runtime_error(message); } @@ -322,11 +353,8 @@ void PvaClientPut::put() issuePut(); Status status = waitPut(); if(status.isOK()) return; - Channel::shared_pointer chan(channel.lock()); - string channelName("disconnected"); - if(chan) channelName = chan->getChannelName(); string message = string("channel ") - + channelName + + pvaClientChannel->getChannel()->getChannelName() + " PvaClientPut::put " + status.getMessage(); throw std::runtime_error(message); @@ -336,11 +364,8 @@ void PvaClientPut::issuePut() { if(connectState==connectIdle) connect(); if(putState!=putIdle) { - Channel::shared_pointer chan(channel.lock()); - string channelName("disconnected"); - if(chan) channelName = chan->getChannelName(); string message = string("channel ") - + channelName + + pvaClientChannel->getChannel()->getChannelName() + "PvaClientPut::issueGet get or put aleady active "; throw std::runtime_error(message); } @@ -351,11 +376,8 @@ void PvaClientPut::issuePut() Status PvaClientPut::waitPut() { if(putState!=putActive){ - Channel::shared_pointer chan(channel.lock()); - string channelName("disconnected"); - if(chan) channelName = chan->getChannelName(); string message = string("channel ") - + channelName + + pvaClientChannel->getChannel()->getChannelName() + " PvaClientPut::waitPut illegal put state"; throw std::runtime_error(message); } @@ -371,5 +393,19 @@ PvaClientPutDataPtr PvaClientPut::getData() return pvaClientData; } +void PvaClientPut::setRequester(PvaClientPutRequesterPtr const & pvaClientPutRequester) +{ + if(PvaClient::getDebug()) { + cout << "PvaClientPut::setRequester" + << " channelName " << pvaClientChannel->getChannel()->getChannelName() + << endl; + } + this->pvaClientPutRequester = pvaClientPutRequester; +} + +PvaClientChannelPtr PvaClientPut::getPvaClientChannel() +{ + return pvaClientChannel; +} }}