diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 0000000..e4b2b82 --- /dev/null +++ b/.travis.yml @@ -0,0 +1,22 @@ +sudo: false +dist: trusty +language: c++ +compiler: + - gcc +addons: + apt: + packages: + - libreadline6-dev + - libncurses5-dev + - perl + - clang + - g++-mingw-w64-i686 +env: + - BRBASE=3.16 WINE=32 + - BRBASE=3.16 USR_CXXFLAGS=-std=c++11 CMPLR=clang + - BRBASE=3.15 + - BRBASE=3.14 +install: + - ./build-deps.sh +script: + - make -j2 diff --git a/build-deps.sh b/build-deps.sh new file mode 100755 index 0000000..4e0254b --- /dev/null +++ b/build-deps.sh @@ -0,0 +1,80 @@ +#!/bin/sh +set -e -x + +CURDIR="$PWD" + +cat << EOF > configure/RELEASE.local +EPICS_BASE=$HOME/.source/epics-base +PVDATA=$HOME/.source/pvDataCPP +PVACCESS=$HOME/.source/pvAccessCPP +NORMATIVETYPES=$HOME/.source/normativeTypesCPP +EOF +cat configure/RELEASE.local + +install -d "$HOME/.source" +cd "$HOME/.source" + +git clone --quiet --depth 5 --branch "${BRBASE:-master}" https://github.com/epics-base/epics-base.git epics-base +git clone --quiet --depth 5 --branch "${BRPVD:-master}" https://github.com/epics-base/pvDataCPP.git pvDataCPP +git clone --quiet --depth 5 --branch "${BRPVA:-master}" https://github.com/epics-base/pvAccessCPP.git pvAccessCPP +git clone --quiet --depth 5 --branch "${BRNT:-master}" https://github.com/epics-base/normativeTypesCPP.git normativeTypesCPP + +(cd epics-base && git log -n1 ) +(cd pvDataCPP && git log -n1 ) +(cd pvAccessCPP && git log -n1 ) +(cd normativeTypesCPP && git log -n1 ) + +EPICS_HOST_ARCH=`sh epics-base/startup/EpicsHostArch` + +# requires wine and g++-mingw-w64-i686 +if [ "$WINE" = "32" ] +then + echo "Cross mingw32" + sed -i -e '/CMPLR_PREFIX/d' epics-base/configure/os/CONFIG_SITE.linux-x86.win32-x86-mingw + cat << EOF >> epics-base/configure/os/CONFIG_SITE.linux-x86.win32-x86-mingw +CMPLR_PREFIX=i686-w64-mingw32- +EOF + cat << EOF >> epics-base/configure/CONFIG_SITE +CROSS_COMPILER_TARGET_ARCHS+=win32-x86-mingw +EOF +fi + +case "$CMPLR" in +clang) + echo "Host compiler is clang" + cat << EOF >> epics-base/configure/os/CONFIG_SITE.Common.$EPICS_HOST_ARCH +GNU = NO +CMPLR_CLASS = clang +CC = clang +CCC = clang++ +EOF + + # hack + sed -i -e 's/CMPLR_CLASS = gcc/CMPLR_CLASS = clang/' epics-base/configure/CONFIG.gnuCommon + + clang --version + ;; +*) + echo "Host compiler is default" + gcc --version + ;; +esac + +cat << EOF > pvDataCPP/configure/RELEASE.local +EPICS_BASE=$HOME/.source/epics-base +EOF + +cat << EOF > pvAccessCPP/configure/RELEASE.local +PVDATA=$HOME/.source/pvDataCPP +EPICS_BASE=$HOME/.source/epics-base +EOF + +cat << EOF > normativeTypesCPP/configure/RELEASE.local +PVDATA=$HOME/.source/pvDataCPP +EPICS_BASE=$HOME/.source/epics-base +EOF + +make -j2 -C epics-base +make -j2 -C pvDataCPP +make -j2 -C pvAccessCPP +make -j2 -C normativeTypesCPP diff --git a/documentation/htmldoxygen/pvaClientGetRequester.html b/documentation/htmldoxygen/pvaClientGetRequester.html index e2fe9f6..ad7fd7b 100644 --- a/documentation/htmldoxygen/pvaClientGetRequester.html +++ b/documentation/htmldoxygen/pvaClientGetRequester.html @@ -35,8 +35,23 @@

PvaClientGetRequester

+

This is a virtual class that can be implemented by a client that uses PvaClientGet. +It has the methods:

+
+virtual void channelGetConnect(
+    const Status& status,
+    PvaClientGetPtr const & clientGet) {}
+virtual void getDone(
+    const Status& status,
+    PvaClientGetPtr const & clientGet) = 0;
+
+ +

The client must call

+
+pvaClientGet->setRequester(shared_from_this());
+

-Not Yet Written +after creating an instance of PvaClientGet.

diff --git a/documentation/htmldoxygen/pvaClientMonitorRequester.html b/documentation/htmldoxygen/pvaClientMonitorRequester.html index 43d36bd..31daa94 100644 --- a/documentation/htmldoxygen/pvaClientMonitorRequester.html +++ b/documentation/htmldoxygen/pvaClientMonitorRequester.html @@ -35,10 +35,31 @@

PvaClientMonitorRequester

+

This is a virtual class that can be implemented by a client that uses PvaClientMonitor. +It has the methods:

+
+virtual void monitorConnect(
+    const Status& status,
+    PvaClientMonitorPtr const & clientMonitor,
+    StructureConstPtr const & structure) {}
+virtual void event(
+    PvaClientMonitor const & clientGet) = 0;
+virtual void unlisten()
+{
+     std::cerr << "PvaClientMonitorRequester::unlisten called"
+               << " but no PvaClientMonitorRequester::unlisten\n";
+}
+
+ +

The client must call

+
+pvaClientMonitor->setRequester(shared_from_this());
+

-Not Yet Written +after creating an instance of PvaClientMonitor.

+ diff --git a/documentation/htmldoxygen/pvaClientPutGetRequester.html b/documentation/htmldoxygen/pvaClientPutGetRequester.html new file mode 100644 index 0000000..6603f80 --- /dev/null +++ b/documentation/htmldoxygen/pvaClientPutGetRequester.html @@ -0,0 +1,66 @@ + + + + + + PvaClientPutGetRequester + + + + + + + + +

PvaClientPutGetRequester

+ +

This is a virtual class that can be implemented by a client that uses PvaClientPut. +It has the methods:

+
+virtual void channelPutGetConnect(
+    const Status& status,
+    PvaClientPutGetPtr const & clientPutGet) {}
+virtual void putGetDone(
+    const Status& status,
+    PvaClientPutGetPtr const & clientPutGet) {}
+virtual void getPutDone(
+    const Status& status,
+    PvaClientPutGetPtr const & clientPutGet) = 0;
+virtual void getGetDone(
+    const Status& status,
+    PvaClientPutGetPtr const & clientPutGet) = 0;
+
+ +

The client must call

+
+pvaClientPutGet->setRequester(shared_from_this());
+
+

+after creating an instance of PvaClientPutGet. +

+ + + + + diff --git a/documentation/htmldoxygen/pvaClientPutRequester.html b/documentation/htmldoxygen/pvaClientPutRequester.html index 00aed26..9206b6b 100644 --- a/documentation/htmldoxygen/pvaClientPutRequester.html +++ b/documentation/htmldoxygen/pvaClientPutRequester.html @@ -35,10 +35,29 @@

PvaClientPutRequester

+

This is a virtual class that can be implemented by a client that uses PvaClientPut. +It has the methods:

+
+virtual void channelPutConnect(
+    const Status& status,
+    PvaClientPutPtr const & clientPut) {}
+virtual void getDone(
+    const Status& status,
+    PvaClientPutPtr const & clientPut) {}
+virtual void putDone(
+    const Status& status,
+    PvaClientPutPtr const & clientPut) = 0;
+
+ +

The client must call

+
+pvaClientPut->setRequester(shared_from_this());
+

-Not Yet Written +after creating an instance of PvaClientPut.

+ diff --git a/src/pv/pvaClient.h b/src/pv/pvaClient.h index 53e8cbd..3031e38 100644 --- a/src/pv/pvaClient.h +++ b/src/pv/pvaClient.h @@ -58,6 +58,9 @@ class PvaClientChannel; typedef std::tr1::shared_ptr PvaClientChannelPtr; class PvaClientField; typedef std::tr1::shared_ptr PvaClientFieldPtr; +class PvaClientProcessRequester; +typedef std::tr1::shared_ptr PvaClientProcessRequesterPtr; +typedef std::tr1::weak_ptr PvaClientProcessRequesterWPtr; class PvaClientProcess; typedef std::tr1::shared_ptr PvaClientProcessPtr; class PvaClientGetRequester; @@ -70,6 +73,9 @@ typedef std::tr1::shared_ptr PvaClientPutRequesterPtr; typedef std::tr1::weak_ptr PvaClientPutRequesterWPtr; class PvaClientPut; typedef std::tr1::shared_ptr PvaClientPutPtr; +class PvaClientPutGetRequester; +typedef std::tr1::shared_ptr PvaClientPutGetRequesterPtr; +typedef std::tr1::weak_ptr PvaClientPutGetRequesterWPtr; class PvaClientPutGet; typedef std::tr1::shared_ptr PvaClientPutGetPtr; class PvaClientMonitor; @@ -196,7 +202,7 @@ typedef std::tr1::shared_ptr PvaClientPutCachePtr; * Overview of PvaClientChannelStateChangeRequester * */ -class PvaClientChannelStateChangeRequester +class epicsShareClass PvaClientChannelStateChangeRequester { public: POINTER_DEFINITIONS(PvaClientChannelStateChangeRequester); @@ -343,7 +349,7 @@ public: * @return The interface. */ PvaClientPutGetPtr createPutGet(epics::pvData::PVStructurePtr const & pvRequest); - /** @brief Create a PvaClientPutGet. + /** @brief Create a PvaClientArray. * * First call createRequest as implemented by pvDataJava and then call the next method. * @param request The syntax of request is defined by the copy facility of pvData. @@ -920,6 +926,35 @@ private: friend class PvaClientMonitor; }; +/** + * @brief Optional client callback. + * + * Overview of PvaClientProcessRequester + */ +class epicsShareClass PvaClientProcessRequester +{ +public: + POINTER_DEFINITIONS(PvaClientProcessRequester); + virtual ~PvaClientProcessRequester() {} + /** @brief A channelProcess has connected. + * + * @param status The status returned by the server. + * @param clientProcess The PvaClientProcess that issued the request to create a ChannelProcess. + */ + virtual void channelProcessConnect( + const epics::pvData::Status& status, + PvaClientProcessPtr const & clientProcess) + { + } + /** @brief A process request is complete. + * + * @param status The status returned by the server. + * @param clientProcess The PvaClientProcess that issued the process request. + */ + virtual void processDone( + const epics::pvData::Status& status, + PvaClientProcessPtr const & clientProcess) = 0; +}; // NOTE: must use separate class that implements ChannelProcessRequester, // because pvAccess holds a shared_ptr to ChannelProcessRequester instead of weak_pointer @@ -931,7 +966,9 @@ typedef std::tr1::shared_ptr ChannelProcessRequeste * * Overview of PvaClientProcess */ -class epicsShareClass PvaClientProcess +class epicsShareClass PvaClientProcess : + public PvaClientChannelStateChangeRequester, + public std::tr1::enable_shared_from_this { public: POINTER_DEFINITIONS(PvaClientProcess); @@ -943,13 +980,17 @@ public: */ static PvaClientProcessPtr create( PvaClientPtr const &pvaClient, - epics::pvAccess::Channel::shared_pointer const & channel, + PvaClientChannelPtr const & pvaClientChannel, epics::pvData::PVStructurePtr const &pvRequest ); /** @brief Destructor */ ~PvaClientProcess(); + /** @brief Set a user callback. + * @param pvaClientProcessRequester The requester which must be implemented by the caller. + */ + void setRequester(PvaClientProcessRequesterPtr const & pvaClientProcessRequester); /** @brief Call issueConnect and then waitConnect. * * An exception is thrown if connect fails. @@ -967,7 +1008,7 @@ public: epics::pvData::Status waitConnect(); /** @brief Call issueProcess and then waitProcess. * - * An exception is thrown if get fails. + * An exception is thrown if process fails. */ void process(); /** @brief Issue a process request and return immediately. @@ -977,6 +1018,11 @@ public: * @return status. */ epics::pvData::Status waitProcess(); + /** @brief Get the PvaClientChannel; + * + * @return The interface. + */ + PvaClientChannelPtr getPvaClientChannel(); private: std::string getRequesterName(); void message(std::string const & message,epics::pvData::MessageType messageType); @@ -989,13 +1035,14 @@ private: PvaClientProcess( PvaClientPtr const &pvaClient, - epics::pvAccess::Channel::shared_pointer const & channel, + PvaClientChannelPtr const & pvaClientChannel, epics::pvData::PVStructurePtr const &pvRequest); + void checkProcessState(); enum ProcessConnectState {connectIdle,connectActive,connected}; PvaClient::weak_pointer pvaClient; - epics::pvAccess::Channel::shared_pointer channel; + PvaClientChannelPtr pvaClientChannel; epics::pvData::PVStructurePtr pvRequest; epics::pvData::Mutex mutex; epics::pvData::Event waitForConnect; @@ -1007,9 +1054,13 @@ private: ProcessConnectState connectState; + PvaClientChannelStateChangeRequesterWPtr pvaClientChannelStateChangeRequester; + PvaClientProcessRequesterWPtr pvaClientProcessRequester; enum ProcessState {processIdle,processActive,processComplete}; ProcessState processState; ChannelProcessRequesterImplPtr channelProcessRequester; +public: + void channelStateChange(PvaClientChannelPtr const & pvaClientChannel, bool isConnected); friend class ChannelProcessRequesterImpl; }; @@ -1023,7 +1074,7 @@ typedef std::tr1::shared_ptr ChannelGetRequesterImplPtr * * Overview of PvaClientGetRequester */ -class PvaClientGetRequester +class epicsShareClass PvaClientGetRequester { public: POINTER_DEFINITIONS(PvaClientGetRequester); @@ -1035,15 +1086,17 @@ public: */ virtual void channelGetConnect( const epics::pvData::Status& status, - PvaClientGetPtr const & clientGet); + 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. + * @param clientGet The PvaClientGet that issued the get request */ virtual void getDone( const epics::pvData::Status& status, - PvaClientGetPtr const & clientGet); + PvaClientGetPtr const & clientGet) = 0; }; /** * @brief An easy to use alternative to ChannelGet. @@ -1067,25 +1120,7 @@ public: 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(); @@ -1158,7 +1193,6 @@ private: epics::pvData::Event waitForConnect; epics::pvData::Event waitForGet; PvaClientGetDataPtr pvaClientData; - std::string messagePrefix; epics::pvData::Status channelGetConnectStatus; epics::pvData::Status channelGetStatus; @@ -1188,7 +1222,7 @@ typedef std::tr1::shared_ptr ChannelPutRequesterImplPtr * * Overview of PvaClientPutRequester */ -class PvaClientPutRequester +class epicsShareClass PvaClientPutRequester { public: POINTER_DEFINITIONS(PvaClientPutRequester); @@ -1200,23 +1234,27 @@ public: */ virtual void channelPutConnect( const epics::pvData::Status& status, - PvaClientPutPtr const & clientPut); + 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. + * @param clientPut The PvaClientPut that issued the get request. */ virtual void getDone( const epics::pvData::Status& status, - PvaClientPutPtr const & clientPut); + 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. + * @param clientPut The PvaClientPut that issued the put request. */ virtual void putDone( const epics::pvData::Status& status, - PvaClientPutPtr const & clientPut); + PvaClientPutPtr const & clientPut) = 0; }; /** @@ -1241,25 +1279,6 @@ public: 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(); @@ -1352,7 +1371,7 @@ private : epics::pvAccess::ChannelPut::shared_pointer channelPut; PutConnectState connectState; - enum PutState {putIdle,getActive,putActive}; + enum PutState {putIdle,getActive,putActive,putComplete}; PutState putState; ChannelPutRequesterImplPtr channelPutRequester; PvaClientChannelStateChangeRequesterWPtr pvaClientChannelStateChangeRequester; @@ -1367,12 +1386,66 @@ public: class ChannelPutGetRequesterImpl; typedef std::tr1::shared_ptr ChannelPutGetRequesterImplPtr; +/** + * @brief Optional client callback. + * + * Overview of PvaClientPutGetRequester + */ +class epicsShareClass PvaClientPutGetRequester +{ +public: + POINTER_DEFINITIONS(PvaClientPutGetRequester); + virtual ~PvaClientPutGetRequester() {} + /** @brief A channelPutGet has connected. + * + * @param status The status returned by the server. + * @param clientPutGet The PvaClientPutGet that issued the request to create a ChannelPutGet. + */ + virtual void channelPutGetConnect( + const epics::pvData::Status& status, + PvaClientPutGetPtr const & clientPutGet) + { + } + /** @brief A putGet request is complete. + * + * @param status The status returned by the server. + * @param clientPutGet The PvaClientPutGet that issued the putGet request. + */ + virtual void putGetDone( + const epics::pvData::Status& status, + PvaClientPutGetPtr const & clientPutGet) = 0; + /** @brief A getPut request is complete. + * + * @param status The status returned by the server. + * @param clientPutGet The PvaClientPutGet that issued the getPut request. + */ + virtual void getPutDone( + const epics::pvData::Status& status, + PvaClientPutGetPtr const & clientPutGet) + { + } + /** @brief A getGet request is complete. + * + * @param status The status returned by the server. + * @param clientPutGet The PvaClientPutGet that issued the getGet request. + */ + virtual void getGetDone( + const epics::pvData::Status& status, + PvaClientPutGetPtr const & clientPutGet) + { + } + +}; + + /** * @brief An easy to use alternative to ChannelPutGet. * * Overview of PvaClientPutGet */ -class epicsShareClass PvaClientPutGet +class epicsShareClass PvaClientPutGet : + public PvaClientChannelStateChangeRequester, + public std::tr1::enable_shared_from_this { public: POINTER_DEFINITIONS(PvaClientPutGet); @@ -1384,12 +1457,16 @@ public: */ static PvaClientPutGetPtr create( PvaClientPtr const &pvaClient, - epics::pvAccess::Channel::shared_pointer const & channel, + PvaClientChannelPtr const & pvaClientChannel, epics::pvData::PVStructurePtr const &pvRequest ); /** @brief Destructor */ ~PvaClientPutGet(); + /** @brief Set a user callback. + * @param pvaClientPutGetRequester The requester which must be implemented by the caller. + */ + void setRequester(PvaClientPutGetRequesterPtr const & pvaClientPutGetRequester); /** @brief Call issueConnect and then waitConnect. * @@ -1454,6 +1531,11 @@ public: * @return The interface. */ PvaClientGetDataPtr getGetData(); + /** @brief Get the PvaClientChannel; + * + * @return The interface. + */ + PvaClientChannelPtr getPvaClientChannel(); private : std::string getRequesterName(); void message(std::string const & message,epics::pvData::MessageType messageType); @@ -1480,13 +1562,13 @@ private : PvaClientPutGet( PvaClientPtr const &pvaClient, - epics::pvAccess::Channel::shared_pointer const & channel, + PvaClientChannelPtr const & pvaClientChannel, epics::pvData::PVStructurePtr const &pvRequest); void checkPutGetState(); enum PutGetConnectState {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; @@ -1502,6 +1584,10 @@ private : enum PutGetState {putGetIdle,putGetActive,putGetComplete}; PutGetState putGetState; ChannelPutGetRequesterImplPtr channelPutGetRequester; + PvaClientChannelStateChangeRequesterWPtr pvaClientChannelStateChangeRequester; + PvaClientPutGetRequesterWPtr pvaClientPutGetRequester; +public: + void channelStateChange(PvaClientChannelPtr const & pvaClientChannel, bool isConnected); friend class ChannelPutGetRequesterImpl; }; @@ -1511,10 +1597,20 @@ private : * * Overview of PvaClientMonitorRequester */ -class PvaClientMonitorRequester +class epicsShareClass PvaClientMonitorRequester { public: POINTER_DEFINITIONS(PvaClientMonitorRequester); + /** @brief The server has returned a message that the monitor is connected. + * + * @param status Completion status. + * @param monitor The monitor + * @param structure The structure defining the data. + */ + virtual void monitorConnect(epics::pvData::Status const & status, + PvaClientMonitorPtr const & monitor, epics::pvData::StructureConstPtr const & structure) + { + } virtual ~PvaClientMonitorRequester() {} /** @brief A monitor event has occurred. * @param monitor The PvaClientMonitor that received the event. diff --git a/src/pvaClientChannel.cpp b/src/pvaClientChannel.cpp index b17b45d..e8da448 100644 --- a/src/pvaClientChannel.cpp +++ b/src/pvaClientChannel.cpp @@ -341,17 +341,19 @@ PvaClientProcessPtr PvaClientChannel::createProcess(PVStructurePtr const & pvRe if(connectState!=connected) connect(5.0); PvaClientPtr yyy = pvaClient.lock(); if(!yyy) throw std::runtime_error("PvaClient was destroyed"); - return PvaClientProcess::create(yyy,channel,pvRequest); + return PvaClientProcess::create(yyy,shared_from_this(),pvRequest); } PvaClientGetPtr PvaClientChannel::get(string const & request) { PvaClientGetPtr pvaClientGet = pvaClientGetCache->getGet(request); - if(pvaClientGet) return pvaClientGet; - pvaClientGet = createGet(request); - pvaClientGet->connect(); - pvaClientGetCache->addGet(request,pvaClientGet); + if(!pvaClientGet) { + pvaClientGet = createGet(request); + pvaClientGet->connect(); + pvaClientGetCache->addGet(request,pvaClientGet); + } + pvaClientGet->get(); return pvaClientGet; } @@ -381,10 +383,12 @@ PvaClientPutPtr PvaClientChannel::put(string const & request) { PvaClientPutPtr pvaClientPut = pvaClientPutCache->getPut(request); if(pvaClientPut) return pvaClientPut; - pvaClientPut = createPut(request); - pvaClientPut->connect(); - pvaClientPut->get(); - pvaClientPutCache->addPut(request,pvaClientPut); + if(!pvaClientPut) { + pvaClientPut = createPut(request); + pvaClientPut->connect(); + pvaClientPut->get(); + pvaClientPutCache->addPut(request,pvaClientPut); + } return pvaClientPut; } @@ -426,7 +430,7 @@ PvaClientPutGetPtr PvaClientChannel::createPutGet(PVStructurePtr const & pvReque if(connectState!=connected) connect(5.0); PvaClientPtr yyy = pvaClient.lock(); if(!yyy) throw std::runtime_error("PvaClient was destroyed"); - return PvaClientPutGet::create(yyy,channel,pvRequest); + return PvaClientPutGet::create(yyy,shared_from_this(),pvRequest); } diff --git a/src/pvaClientGet.cpp b/src/pvaClientGet.cpp index 83b964b..b9173d5 100644 --- a/src/pvaClientGet.cpp +++ b/src/pvaClientGet.cpp @@ -77,7 +77,7 @@ PvaClientGetPtr PvaClientGet::create( PVStructurePtr const &pvRequest) { if(PvaClient::getDebug()) { - cout<< "PvaClientGet::create(pvaClient,channelName,providerName,pvRequest)\n" + cout<< "PvaClientGet::create(pvaClient,channelName,pvRequest)\n" << " channelName " << pvaClientChannel->getChannel()->getChannelName() << " pvRequest " << pvRequest << endl; @@ -88,35 +88,6 @@ PvaClientGetPtr PvaClientGet::create( 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, PvaClientChannelPtr const & pvaClientChannel, @@ -141,7 +112,6 @@ PvaClientGet::~PvaClientGet() << " channelName " << pvaClientChannel->getChannel()->getChannelName() << endl; } - if(channelGet) channelGet->destroy(); } void PvaClientGet::channelStateChange(PvaClientChannelPtr const & pvaClientChannel, bool isConnected) @@ -184,7 +154,6 @@ void PvaClientGet::checkGetState() + channelGetConnectStatus.getMessage(); throw std::runtime_error(message); } - if(getState==getIdle) get(); } // from ChannelGetRequester @@ -253,6 +222,7 @@ void PvaClientGet::getDone( { Lock xx(mutex); channelGetStatus = status; + getState = getComplete; if(status.isOK()) { pvaClientData->setData(pvStructure,bitSet); } @@ -362,6 +332,7 @@ Status PvaClientGet::waitGet() { Lock xx(mutex); if(getState==getComplete) { + getState = getIdle; return channelGetStatus; } if(getState!=getActive){ @@ -376,7 +347,13 @@ Status PvaClientGet::waitGet() } PvaClientGetDataPtr PvaClientGet::getData() { + if(PvaClient::getDebug()) { + cout<< "PvaClientGet::getData" + << " channelName " << pvaClientChannel->getChannel()->getChannelName() + << endl; + } checkGetState(); + if(getState==getIdle) get(); return pvaClientData; } diff --git a/src/pvaClientGetData.cpp b/src/pvaClientGetData.cpp index 4eb84e6..6da72db 100644 --- a/src/pvaClientGetData.cpp +++ b/src/pvaClientGetData.cpp @@ -42,18 +42,29 @@ static string noTimeStamp("no timeStamp"); PvaClientGetDataPtr PvaClientGetData::create(StructureConstPtr const & structure) { + if(PvaClient::getDebug()) { + cout << "PvaClientGetData::create" + << endl; + } PvaClientGetDataPtr epv(new PvaClientGetData(structure)); return epv; } PvaClientGetData::PvaClientGetData(StructureConstPtr const & structure) -: structure(structure) +: structure(structure), + pvStructure(getPVDataCreate()->createPVStructure(structure)), + bitSet(BitSetPtr(new BitSet(pvStructure->getNumberFields()))) { messagePrefix = ""; + pvValue = pvStructure->getSubField("value"); } void PvaClientGetData::checkValue() { + if(PvaClient::getDebug()) { + cout << "PvaClientGetData::checkValue" + << endl; + } if(pvValue) return; throw std::runtime_error(messagePrefix + noValue); } @@ -100,6 +111,10 @@ void PvaClientGetData::setData( PVStructurePtr const & pvStructureFrom, BitSetPtr const & bitSetFrom) { + if(PvaClient::getDebug()) { + cout << "PvaClientGetData::setData" + << endl; + } pvStructure = pvStructureFrom; bitSet = bitSetFrom; pvValue = pvStructure->getSubField("value"); diff --git a/src/pvaClientMonitor.cpp b/src/pvaClientMonitor.cpp index 33088ca..d1f5317 100644 --- a/src/pvaClientMonitor.cpp +++ b/src/pvaClientMonitor.cpp @@ -150,7 +150,6 @@ PvaClientMonitor::~PvaClientMonitor() } if(monitor) { if(isStarted) monitor->stop(); - monitor->destroy(); } } @@ -257,13 +256,18 @@ void PvaClientMonitor::monitorConnect( cout << "PvaClientMonitor::monitorConnect calling waitForConnect.signal\n"; } waitForConnect.signal(); + if(PvaClient::getDebug()) { + cout << "PvaClientMonitor::monitorConnect calling start\n"; + } + start(); } else { if(PvaClient::getDebug()) { cout << "PvaClientMonitor::monitorConnect calling start\n"; } start(); } - + PvaClientMonitorRequesterPtr req(pvaClientMonitorRequester.lock()); + if(req) req->monitorConnect(status,shared_from_this(),structure); } void PvaClientMonitor::monitorEvent(MonitorPtr const & monitor) @@ -339,7 +343,8 @@ Status PvaClientMonitor::waitConnect() connectState = monitorConnectStatus.isOK() ? connected : connectIdle; if(PvaClient::getDebug()) { cout << "PvaClientMonitor::waitConnect" - << " monitorConnectStatus " << (monitorConnectStatus.isOK() ? "connected" : "not connected"); + << " monitorConnectStatus " << (monitorConnectStatus.isOK() ? "connected" : "not connected") + << endl; } return monitorConnectStatus; } @@ -399,7 +404,6 @@ void PvaClientMonitor::start(string const & request) if(!pvr) throw std::runtime_error(createRequest->getMessage()); if(monitor) { if(isStarted) monitor->stop(); - monitor->destroy(); } monitorRequester.reset(); monitor.reset(); @@ -411,7 +415,6 @@ void PvaClientMonitor::start(string const & request) new MonitorRequesterImpl(shared_from_this(),client)); pvRequest = pvr; connect(); - start(); } diff --git a/src/pvaClientProcess.cpp b/src/pvaClientProcess.cpp index 563f557..9461768 100644 --- a/src/pvaClientProcess.cpp +++ b/src/pvaClientProcess.cpp @@ -70,35 +70,92 @@ public: PvaClientProcessPtr PvaClientProcess::create( PvaClientPtr const &pvaClient, - Channel::shared_pointer const & channel, + PvaClientChannelPtr const & pvaClientChannel, PVStructurePtr const &pvRequest) { - PvaClientProcessPtr epv(new PvaClientProcess(pvaClient,channel,pvRequest)); - epv->channelProcessRequester = ChannelProcessRequesterImplPtr( - new ChannelProcessRequesterImpl(epv,pvaClient)); - return epv; + if(PvaClient::getDebug()) { + cout<< "PvaClientProcess::create(pvaClient,channelName,pvRequest)\n" + << " channelName " << pvaClientChannel->getChannel()->getChannelName() + << " pvRequest " << pvRequest + << endl; + } + PvaClientProcessPtr channelProcess(new PvaClientProcess(pvaClient,pvaClientChannel,pvRequest)); + channelProcess->channelProcessRequester = ChannelProcessRequesterImplPtr( + new ChannelProcessRequesterImpl(channelProcess,pvaClient)); + return channelProcess; } PvaClientProcess::PvaClientProcess( PvaClientPtr const &pvaClient, - Channel::shared_pointer const & channel, + PvaClientChannelPtr const & pvaClientChannel, PVStructurePtr const &pvRequest) : pvaClient(pvaClient), - channel(channel), + pvaClientChannel(pvaClientChannel), pvRequest(pvRequest), connectState(connectIdle), processState(processIdle) { - if(PvaClient::getDebug()) cout<< "PvaClientProcess::PvaClientProcess()\n"; + if(PvaClient::getDebug()) { + cout<< "PvaClientProcess::PvaClientProcess()" + << " channelName " << pvaClientChannel->getChannel()->getChannelName() + << endl; + } } PvaClientProcess::~PvaClientProcess() { - if(PvaClient::getDebug()) cout<< "PvaClientProcess::~PvaClientProcess()\n"; - channelProcess->destroy(); + if(PvaClient::getDebug()) { + cout<< "PvaClientProcess::~PvaClientProcess()" + << " channelName " << pvaClientChannel->getChannel()->getChannelName() + << endl; + } } +void PvaClientProcess::channelStateChange(PvaClientChannelPtr const & pvaClientChannel, bool isConnected) +{ + if(PvaClient::getDebug()) { + cout<< "PvaClientProcess::channelStateChange" + << " channelName " << pvaClientChannel->getChannel()->getChannelName() + << " isConnected " << (isConnected ? "true" : "false") + << endl; + } + if(isConnected) + { + connectState = connectActive; + channelProcess = pvaClientChannel->getChannel()->createChannelProcess(channelProcessRequester,pvRequest); + } + PvaClientChannelStateChangeRequesterPtr req(pvaClientChannelStateChangeRequester.lock()); + if(req) { + req->channelStateChange(pvaClientChannel,isConnected); + } +} + +void PvaClientProcess::checkProcessState() +{ + if(PvaClient::getDebug()) { + cout << "PvaClientProcess::checkProcessState" + << " channelName " << pvaClientChannel->getChannel()->getChannelName() + << endl; + } + if(!pvaClientChannel->getChannel()->isConnected()) { + string message = string("channel ") + pvaClientChannel->getChannel()->getChannelName() + + " PvaClientProcess::checkProcessState channel not connected "; + throw std::runtime_error(message); + } + if(connectState==connectIdle) { + connect(); + } + if(connectState==connectActive){ + string message = string("channel ") + pvaClientChannel->getChannel()->getChannelName() + + " " + + channelProcessConnectStatus.getMessage(); + throw std::runtime_error(message); + } + if(processState==processIdle) process(); +} + + // from ChannelProcessRequester string PvaClientProcess::getRequesterName() { @@ -118,9 +175,31 @@ void PvaClientProcess::channelProcessConnect( const Status& status, ChannelProcess::shared_pointer const & channelProcess) { - channelProcessConnectStatus = status; - connectState = connected; - this->channelProcess = channelProcess; + if(PvaClient::getDebug()) { + cout << "PvaClientProcess::channelProcessConnect" + << " channelName " << pvaClientChannel->getChannel()->getChannelName() + << " status.isOK " << (status.isOK() ? "true" : "false") + << endl; + } + { + Lock xx(mutex); + this->channelProcess = channelProcess; + if(status.isOK()) { + channelProcessConnectStatus = status; + connectState = connected; + } else { + stringstream ss; + ss << pvRequest; + string message = string("PvaClientProcess::channelProcessConnect") + + "\npvRequest\n" + ss.str() + + "\nerror\n" + status.getMessage(); + channelProcessConnectStatus = Status(Status::STATUSTYPE_ERROR,message); + } + } + PvaClientProcessRequesterPtr req(pvaClientProcessRequester.lock()); + if(req) { + req->channelProcessConnect(status,shared_from_this()); + } waitForConnect.signal(); } @@ -129,40 +208,69 @@ void PvaClientProcess::processDone( const Status& status, ChannelProcess::shared_pointer const & channelProcess) { - channelProcessStatus = status; - processState = processComplete; + if(PvaClient::getDebug()) { + cout << "PvaClientProcess::processDone" + << " channelName " << pvaClientChannel->getChannel()->getChannelName() + << " status.isOK " << (status.isOK() ? "true" : "false") + << endl; + } + { + Lock xx(mutex); + channelProcessStatus = status; + processState = processComplete; + } + + PvaClientProcessRequesterPtr req(pvaClientProcessRequester.lock()); + if(req) { + req->processDone(status,shared_from_this()); + } waitForProcess.signal(); } void PvaClientProcess::connect() { + if(PvaClient::getDebug()) { + cout << "PvaClientProcess::connect" + << " channelName " << pvaClientChannel->getChannel()->getChannelName() + << endl; + } issueConnect(); Status status = waitConnect(); if(status.isOK()) return; - string message = string("channel ") + channel->getChannelName() + string message = string("channel ") + pvaClientChannel->getChannel()->getChannelName() + " PvaClientProcess::connect " + status.getMessage(); throw std::runtime_error(message); } void PvaClientProcess::issueConnect() { + if(PvaClient::getDebug()) { + cout << "PvaClientProcess::issueConnect" + << " channelName " << pvaClientChannel->getChannel()->getChannelName() + << endl; + } if(connectState!=connectIdle) { - string message = string("channel ") + channel->getChannelName() + string message = string("channel ") + pvaClientChannel->getChannel()->getChannelName() + " pvaClientProcess already connected "; throw std::runtime_error(message); } connectState = connectActive; - channelProcess = channel->createChannelProcess(channelProcessRequester,pvRequest); + channelProcess = pvaClientChannel->getChannel()->createChannelProcess(channelProcessRequester,pvRequest); } Status PvaClientProcess::waitConnect() { + if(PvaClient::getDebug()) { + cout << "PvaClientProcess::waitConnect" + << " channelName " << pvaClientChannel->getChannel()->getChannelName() + << endl; + } if(connectState==connected) { if(!channelProcessConnectStatus.isOK()) connectState = connectIdle; return channelProcessConnectStatus; } if(connectState!=connectActive) { - string message = string("channel ") + channel->getChannelName() + string message = string("channel ") + pvaClientChannel->getChannel()->getChannelName() + " pvaClientProcess illegal connect state "; throw std::runtime_error(message); } @@ -173,19 +281,29 @@ Status PvaClientProcess::waitConnect() void PvaClientProcess::process() { + if(PvaClient::getDebug()) { + cout << "PvaClientProcess::process" + << " channelName " << pvaClientChannel->getChannel()->getChannelName() + << endl; + } issueProcess(); Status status = waitProcess(); if(status.isOK()) return; - string message = string("channel ") + channel->getChannelName() + string message = string("channel ") + pvaClientChannel->getChannel()->getChannelName() + " PvaClientProcess::process" + status.getMessage(); throw std::runtime_error(message); } void PvaClientProcess::issueProcess() { + if(PvaClient::getDebug()) { + cout << "PvaClientProcess::issueProcess" + << " channelName " << pvaClientChannel->getChannel()->getChannelName() + << endl; + } if(connectState==connectIdle) connect(); if(processState!=processIdle) { - string message = string("channel ") + channel->getChannelName() + string message = string("channel ") + pvaClientChannel->getChannel()->getChannelName() + " PvaClientProcess::issueProcess process aleady active "; throw std::runtime_error(message); } @@ -195,18 +313,42 @@ void PvaClientProcess::issueProcess() Status PvaClientProcess::waitProcess() { - if(processState==processComplete) { - processState = processIdle; - return channelProcessStatus; + if(PvaClient::getDebug()) { + cout << "PvaClientProcess::waitProcess" + << " channelName " << pvaClientChannel->getChannel()->getChannelName() + << endl; } - if(processState!=processActive){ - string message = string("channel ") + channel->getChannelName() - + " PvaClientProcess::waitProcess llegal process state"; - throw std::runtime_error(message); + { + Lock xx(mutex); + if(processState==processComplete) { + processState = processIdle; + return channelProcessStatus; + } + if(processState!=processActive){ + string message = string("channel ") + pvaClientChannel->getChannel()->getChannelName() + + " PvaClientProcess::waitProcess llegal process state"; + throw std::runtime_error(message); + } } waitForProcess.wait(); - processState = processIdle; + processState = processComplete; return channelProcessStatus; } +void PvaClientProcess::setRequester(PvaClientProcessRequesterPtr const & pvaClientProcessRequester) +{ + if(PvaClient::getDebug()) { + cout << "PvaClientProcess::setRequester" + << " channelName " << pvaClientChannel->getChannel()->getChannelName() + << endl; + } + this->pvaClientProcessRequester = pvaClientProcessRequester; +} + +PvaClientChannelPtr PvaClientProcess::getPvaClientChannel() +{ + return pvaClientChannel; +} + + }} diff --git a/src/pvaClientPut.cpp b/src/pvaClientPut.cpp index dc5c158..561d311 100644 --- a/src/pvaClientPut.cpp +++ b/src/pvaClientPut.cpp @@ -70,7 +70,7 @@ public: clientPut->getDone(status,channelPut,pvStructure,bitSet); } - virtual void putDone( + virtual void putDone( const Status& status, ChannelPut::shared_pointer const & channelPut) { @@ -91,35 +91,6 @@ PvaClientPutPtr PvaClientPut::create( 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, @@ -145,7 +116,6 @@ PvaClientPut::~PvaClientPut() << " channelName " << pvaClientChannel->getChannel()->getChannelName() << endl; } - if(channelPut) channelPut->destroy(); } void PvaClientPut::channelStateChange(PvaClientChannelPtr const & pvaClientChannel, bool isConnected) @@ -176,8 +146,6 @@ void PvaClientPut::checkPutState() } if(connectState==connectIdle){ connect(); - get(); - return; } if(connectState==connectActive){ string message = string("channel ") + pvaClientChannel->getChannel()->getChannelName() @@ -343,6 +311,11 @@ Status PvaClientPut::waitConnect() void PvaClientPut::get() { + if(PvaClient::getDebug()) { + cout << "PvaClientPut::get" + << " channelName " << pvaClientChannel->getChannel()->getChannelName() + << endl; + } issueGet(); Status status = waitGet(); if(status.isOK()) return; @@ -355,8 +328,13 @@ void PvaClientPut::get() void PvaClientPut::issueGet() { + if(PvaClient::getDebug()) { + cout << "PvaClientPut::issueGet" + << " channelName " << pvaClientChannel->getChannel()->getChannelName() + << endl; + } if(connectState==connectIdle) connect(); - if(putState!=putIdle) { + if(putState==getActive || putState==putActive) { string message = string("channel ") + pvaClientChannel->getChannel()->getChannelName() + "PvaClientPut::issueGet get or put aleady active "; @@ -368,6 +346,11 @@ void PvaClientPut::issueGet() Status PvaClientPut::waitGet() { + if(PvaClient::getDebug()) { + cout << "PvaClientPut::waitGet" + << " channelName " << pvaClientChannel->getChannel()->getChannelName() + << endl; + } if(putState!=getActive){ string message = string("channel ") + pvaClientChannel->getChannel()->getChannelName() @@ -375,12 +358,17 @@ Status PvaClientPut::waitGet() throw std::runtime_error(message); } waitForGetPut.wait(); - putState = putIdle; + putState = putComplete; return channelGetPutStatus; } void PvaClientPut::put() { + if(PvaClient::getDebug()) { + cout << "PvaClientPut::put" + << " channelName " << pvaClientChannel->getChannel()->getChannelName() + << endl; + } issuePut(); Status status = waitPut(); if(status.isOK()) return; @@ -393,8 +381,15 @@ void PvaClientPut::put() void PvaClientPut::issuePut() { + if(PvaClient::getDebug()) { + cout << "PvaClientPut::issuePut" + << " channelName " << pvaClientChannel->getChannel()->getChannelName() + << " pvStructure\n" << pvaClientData->getPVStructure() + << " bitSet " << *pvaClientData->getChangedBitSet() << endl + << endl; + } if(connectState==connectIdle) connect(); - if(putState!=putIdle) { + if(putState==getActive || putState==putActive) { string message = string("channel ") + pvaClientChannel->getChannel()->getChannelName() + "PvaClientPut::issueGet get or put aleady active "; @@ -406,6 +401,11 @@ void PvaClientPut::issuePut() Status PvaClientPut::waitPut() { + if(PvaClient::getDebug()) { + cout << "PvaClientPut::waitPut" + << " channelName " << pvaClientChannel->getChannel()->getChannelName() + << endl; + } if(putState!=putActive){ string message = string("channel ") + pvaClientChannel->getChannel()->getChannelName() @@ -413,7 +413,7 @@ Status PvaClientPut::waitPut() throw std::runtime_error(message); } waitForGetPut.wait(); - putState = putIdle; + putState = putComplete; if(channelGetPutStatus.isOK()) pvaClientData->getChangedBitSet()->clear(); return channelGetPutStatus; } @@ -426,6 +426,7 @@ PvaClientPutDataPtr PvaClientPut::getData() << endl; } checkPutState(); + if(putState==putIdle) get(); return pvaClientData; } diff --git a/src/pvaClientPutGet.cpp b/src/pvaClientPutGet.cpp index 65a009d..efe6e9c 100644 --- a/src/pvaClientPutGet.cpp +++ b/src/pvaClientPutGet.cpp @@ -96,28 +96,28 @@ public: PvaClientPutGetPtr PvaClientPutGet::create( PvaClientPtr const &pvaClient, - Channel::shared_pointer const & channel, + PvaClientChannelPtr const & pvaClientChannel, PVStructurePtr const &pvRequest) { - PvaClientPutGetPtr epv(new PvaClientPutGet(pvaClient,channel,pvRequest)); - epv->channelPutGetRequester = ChannelPutGetRequesterImplPtr( - new ChannelPutGetRequesterImpl(epv,pvaClient)); - return epv; + PvaClientPutGetPtr clientPutGet(new PvaClientPutGet(pvaClient,pvaClientChannel,pvRequest)); + clientPutGet->channelPutGetRequester = ChannelPutGetRequesterImplPtr( + new ChannelPutGetRequesterImpl(clientPutGet,pvaClient)); + return clientPutGet; } PvaClientPutGet::PvaClientPutGet( PvaClientPtr const &pvaClient, - Channel::shared_pointer const & channel, + PvaClientChannelPtr const & pvaClientChannel, PVStructurePtr const &pvRequest) : pvaClient(pvaClient), - channel(channel), + pvaClientChannel(pvaClientChannel), pvRequest(pvRequest), connectState(connectIdle), putGetState(putGetIdle) { if(PvaClient::getDebug()) { cout<< "PvaClientPutGet::PvaClientPutGet" - << " channelName " << channel->getChannelName() + << " channelName " << pvaClientChannel->getChannel()->getChannelName() << endl; } } @@ -125,21 +125,46 @@ PvaClientPutGet::PvaClientPutGet( PvaClientPutGet::~PvaClientPutGet() { if(PvaClient::getDebug()) { - string channelName("disconnected"); - Channel::shared_pointer chan(channel.lock()); - if(chan) channelName = chan->getChannelName(); cout<< "PvaClientPutGet::~PvaClientPutGet" - << " channelName " << channelName + << " channelName " << pvaClientChannel->getChannel()->getChannelName() << endl; } - channelPutGet->destroy(); +} + +void PvaClientPutGet::channelStateChange(PvaClientChannelPtr const & pvaClientChannel, bool isConnected) +{ + if(PvaClient::getDebug()) { + cout<< "PvaClientPutGet::channelStateChange" + << " channelName " << pvaClientChannel->getChannel()->getChannelName() + << " isConnected " << (isConnected ? "true" : "false") + << endl; + } + if(isConnected&&!channelPutGet) + { + connectState = connectActive; + channelPutGet = pvaClientChannel->getChannel()->createChannelPutGet(channelPutGetRequester,pvRequest); + } + PvaClientChannelStateChangeRequesterPtr req(pvaClientChannelStateChangeRequester.lock()); + if(req) { + req->channelStateChange(pvaClientChannel,isConnected); + } } void PvaClientPutGet::checkPutGetState() { + if(PvaClient::getDebug()) { + cout << "PvaClientPutGet::checkPutGetState" + << " channelName " << pvaClientChannel->getChannel()->getChannelName() + << endl; + } if(connectState==connectIdle){ - connect(); - getPut(); + connect(); + } + if(connectState==connectActive){ + string message = string("channel ") + pvaClientChannel->getChannel()->getChannelName() + + " " + + channelPutGetConnectStatus.getMessage(); + throw std::runtime_error(message); } } @@ -165,17 +190,33 @@ void PvaClientPutGet::channelPutGetConnect( { if(PvaClient::getDebug()) { cout << "PvaClientPutGet::channelPutGetConnect" - << " channelName " << channelPutGet->getChannel()->getChannelName() + << " channelName " << pvaClientChannel->getChannel()->getChannelName() << " status.isOK " << (status.isOK() ? "true" : "false") << endl; } - channelPutGetConnectStatus = status; - this->channelPutGet = channelPutGet; - if(status.isOK()) { - pvaClientPutData = PvaClientPutData::create(putStructure); - pvaClientPutData->setMessagePrefix(channelPutGet->getChannel()->getChannelName()); - pvaClientGetData = PvaClientGetData::create(getStructure); - pvaClientGetData->setMessagePrefix(channelPutGet->getChannel()->getChannelName()); + { + Lock xx(mutex); + this->channelPutGet = channelPutGet; + if(status.isOK()) { + channelPutGetConnectStatus = status; + connectState = connected; + pvaClientPutData = PvaClientPutData::create(putStructure); + pvaClientPutData->setMessagePrefix(channelPutGet->getChannel()->getChannelName()); + pvaClientGetData = PvaClientGetData::create(getStructure); + pvaClientGetData->setMessagePrefix(channelPutGet->getChannel()->getChannelName()); + + } else { + stringstream ss; + ss << pvRequest; + string message = string("\nPvaClientPutGet::channelPutGetConnect)") + + "\npvRequest\n" + ss.str() + + "\nerror\n" + status.getMessage(); + channelPutGetConnectStatus = Status(Status::STATUSTYPE_ERROR,message); + } + } + PvaClientPutGetRequesterPtr req(pvaClientPutGetRequester.lock()); + if(req) { + req->channelPutGetConnect(status,shared_from_this()); } waitForConnect.signal(); @@ -188,17 +229,22 @@ void PvaClientPutGet::putGetDone( BitSetPtr const & getChangedBitSet) { if(PvaClient::getDebug()) { - string channelName("disconnected"); - Channel::shared_pointer chan(channel.lock()); - if(chan) channelName = chan->getChannelName(); cout << "PvaClientPutGet::putGetDone" - << " channelName " << channelName + << " channelName " << pvaClientChannel->getChannel()->getChannelName() << " status.isOK " << (status.isOK() ? "true" : "false") << endl; } channelPutGetStatus = status; if(status.isOK()) { - pvaClientGetData->setData(getPVStructure,getChangedBitSet); + PVStructurePtr pvs = pvaClientGetData->getPVStructure(); + pvs->copyUnchecked(*getPVStructure,*getChangedBitSet); + BitSetPtr bs = pvaClientGetData->getChangedBitSet(); + bs->clear(); + *bs |= *getChangedBitSet; + } + PvaClientPutGetRequesterPtr req(pvaClientPutGetRequester.lock()); + if(req) { + req->putGetDone(status,shared_from_this()); } waitForPutGet.signal(); } @@ -210,11 +256,8 @@ void PvaClientPutGet::getPutDone( BitSetPtr const & putBitSet) { if(PvaClient::getDebug()) { - string channelName("disconnected"); - Channel::shared_pointer chan(channel.lock()); - if(chan) channelName = chan->getChannelName(); cout << "PvaClientPutGet::getPutDone" - << " channelName " << channelName + << " channelName " << pvaClientChannel->getChannel()->getChannelName() << " status.isOK " << (status.isOK() ? "true" : "false") << endl; } @@ -226,6 +269,10 @@ void PvaClientPutGet::getPutDone( bs->clear(); *bs |= *putBitSet; } + PvaClientPutGetRequesterPtr req(pvaClientPutGetRequester.lock()); + if(req) { + req->getPutDone(status,shared_from_this()); + } waitForPutGet.signal(); } @@ -236,31 +283,38 @@ void PvaClientPutGet::getGetDone( BitSetPtr const & getChangedBitSet) { if(PvaClient::getDebug()) { - string channelName("disconnected"); - Channel::shared_pointer chan(channel.lock()); - if(chan) channelName = chan->getChannelName(); cout << "PvaClientPutGet::getGetDone" - << " channelName " << channelName + << " channelName " << pvaClientChannel->getChannel()->getChannelName() << " status.isOK " << (status.isOK() ? "true" : "false") << endl; } channelPutGetStatus = status; if(status.isOK()) { - pvaClientGetData->setData(getPVStructure,getChangedBitSet); + PVStructurePtr pvs = pvaClientGetData->getPVStructure(); + pvs->copyUnchecked(*getPVStructure,*getChangedBitSet); + BitSetPtr bs = pvaClientGetData->getChangedBitSet(); + bs->clear(); + *bs |= *getChangedBitSet; + } + PvaClientPutGetRequesterPtr req(pvaClientPutGetRequester.lock()); + if(req) { + req->getGetDone(status,shared_from_this()); } waitForPutGet.signal(); } void PvaClientPutGet::connect() { + if(PvaClient::getDebug()) { + cout << "PvaClientPutGet::connect" + << " channelName " << pvaClientChannel->getChannel()->getChannelName() + << endl; + } 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() + " PvaClientPutGet::connect " + status.getMessage(); throw std::runtime_error(message); @@ -268,24 +322,29 @@ void PvaClientPutGet::connect() void PvaClientPutGet::issueConnect() { - Channel::shared_pointer chan(channel.lock()); + if(PvaClient::getDebug()) { + cout << "PvaClientPutGet::issueConnect" + << " channelName " << pvaClientChannel->getChannel()->getChannelName() + << endl; + } if(connectState!=connectIdle) { - string channelName("disconnected"); - if(chan) channelName = chan->getChannelName(); - string message = string("channel ") + channelName + string message = string("channel ") + + pvaClientChannel->getChannel()->getChannelName() + " pvaClientPutGet already connected "; throw std::runtime_error(message); } - if(chan) { - connectState = connectActive; - channelPutGet = chan->createChannelPutGet(channelPutGetRequester,pvRequest); - return; - } - throw std::runtime_error("PvaClientPutGet::issueConnect() but channel disconnected"); + connectState = connectActive; + channelPutGetConnectStatus = Status(Status::STATUSTYPE_ERROR, "connect active"); + channelPutGet = pvaClientChannel->getChannel()->createChannelPutGet(channelPutGetRequester,pvRequest); } Status PvaClientPutGet::waitConnect() { + if(PvaClient::getDebug()) { + cout << "PvaClientPutGet::waitConnect" + << " channelName " << pvaClientChannel->getChannel()->getChannelName() + << endl; + } { Lock xx(mutex); if(connectState==connected) { @@ -293,30 +352,30 @@ Status PvaClientPutGet::waitConnect() return channelPutGetConnectStatus; } 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() + " PvaClientPutGet::waitConnect illegal connect state "; throw std::runtime_error(message); } } waitForConnect.wait(); - connectState = channelPutGetConnectStatus.isOK() ? connected : connectIdle; + if(!channelPutGetConnectStatus.isOK()) connectState = connectIdle; return channelPutGetConnectStatus; } void PvaClientPutGet::putGet() { + if(PvaClient::getDebug()) { + cout << "PvaClientPutGet::putGet" + << " channelName " << pvaClientChannel->getChannel()->getChannelName() + << endl; + } issuePutGet(); Status status = waitPutGet(); 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::putGet " + status.getMessage(); throw std::runtime_error(message); @@ -324,12 +383,15 @@ void PvaClientPutGet::putGet() void PvaClientPutGet::issuePutGet() { + if(PvaClient::getDebug()) { + cout << "PvaClientPutGet::issuePutGet" + << " channelName " << pvaClientChannel->getChannel()->getChannelName() + << endl; + } if(connectState==connectIdle) connect(); - if(putGetState!=putGetIdle) { - Channel::shared_pointer chan(channel.lock()); - string channelName("disconnected"); - if(chan) channelName = chan->getChannelName(); - string message = string("channel ") + channelName + if(putGetState==putGetActive) { + string message = string("channel ") + + pvaClientChannel->getChannel()->getChannelName() + " PvaClientPutGet::issuePutGet get or put aleady active "; throw std::runtime_error(message); } @@ -340,29 +402,35 @@ void PvaClientPutGet::issuePutGet() Status PvaClientPutGet::waitPutGet() { + if(PvaClient::getDebug()) { + cout << "PvaClientPutGet::waitPutGet" + << " channelName " << pvaClientChannel->getChannel()->getChannelName() + << endl; + } if(putGetState!=putGetActive){ - 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() + " PvaClientPutGet::waitPutGet get or put aleady active "; throw std::runtime_error(message); } waitForPutGet.wait(); - putGetState = putGetIdle; + putGetState = putGetComplete; + if(channelPutGetStatus.isOK()) pvaClientPutData->getChangedBitSet()->clear(); return channelPutGetStatus; } void PvaClientPutGet::getGet() { + if(PvaClient::getDebug()) { + cout << "PvaClientPutGet::getGet" + << " channelName " << pvaClientChannel->getChannel()->getChannelName() + << endl; + } issueGetGet(); Status status = waitGetGet(); 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::getGet " + status.getMessage(); throw std::runtime_error(message); @@ -370,12 +438,15 @@ void PvaClientPutGet::getGet() void PvaClientPutGet::issueGetGet() { + if(PvaClient::getDebug()) { + cout << "PvaClientPutGet::issueGetGet" + << " channelName " << pvaClientChannel->getChannel()->getChannelName() + << endl; + } if(connectState==connectIdle) connect(); - if(putGetState!=putGetIdle) { - Channel::shared_pointer chan(channel.lock()); - string channelName("disconnected"); - if(chan) channelName = chan->getChannelName(); - string message = string("channel ") + channelName + if(putGetState==putGetActive) { + string message = string("channel ") + + pvaClientChannel->getChannel()->getChannelName() + " PvaClientPutGet::issueGetGet get or put aleady active "; throw std::runtime_error(message); } @@ -385,29 +456,34 @@ void PvaClientPutGet::issueGetGet() Status PvaClientPutGet::waitGetGet() { + if(PvaClient::getDebug()) { + cout << "PvaClientPutGet::waitGetGet" + << " channelName " << pvaClientChannel->getChannel()->getChannelName() + << endl; + } if(putGetState!=putGetActive){ - 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() + " PvaClientPutGet::waitGetGet get or put aleady active "; throw std::runtime_error(message); } waitForPutGet.wait(); - putGetState = putGetIdle; + putGetState = putGetComplete; return channelPutGetStatus; } void PvaClientPutGet::getPut() { + if(PvaClient::getDebug()) { + cout << "PvaClientPutGet::getGetPut" + << " channelName " << pvaClientChannel->getChannel()->getChannelName() + << endl; + } issueGetPut(); Status status = waitGetPut(); 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::getPut " + status.getMessage(); throw std::runtime_error(message); @@ -415,12 +491,15 @@ void PvaClientPutGet::getPut() void PvaClientPutGet::issueGetPut() { + if(PvaClient::getDebug()) { + cout << "PvaClientPutGet::issueGetPut" + << " channelName " << pvaClientChannel->getChannel()->getChannelName() + << endl; + } if(connectState==connectIdle) connect(); - if(putGetState!=putGetIdle) { - Channel::shared_pointer chan(channel.lock()); - string channelName("disconnected"); - if(chan) channelName = chan->getChannelName(); - string message = string("channel ") + channelName + if(putGetState==putGetActive) { + string message = string("channel ") + + pvaClientChannel->getChannel()->getChannelName() + " PvaClientPutGet::issueGetPut get or put aleady active "; throw std::runtime_error(message); } @@ -430,29 +509,62 @@ void PvaClientPutGet::issueGetPut() Status PvaClientPutGet::waitGetPut() { + if(PvaClient::getDebug()) { + cout << "PvaClientPutGet::waitGetPut" + << " channelName " << pvaClientChannel->getChannel()->getChannelName() + << endl; + } if(putGetState!=putGetActive){ - 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() + " PvaClientPutGet::waitGetPut get or put aleady active "; throw std::runtime_error(message); } waitForPutGet.wait(); - putGetState = putGetIdle; + putGetState = putGetComplete; return channelPutGetStatus; } PvaClientGetDataPtr PvaClientPutGet::getGetData() { + if(PvaClient::getDebug()) { + cout<< "PvaClientPutGet::getGetData" + << " channelName " << pvaClientChannel->getChannel()->getChannelName() + << endl; + } checkPutGetState(); + if(putGetState==putGetIdle) getGet(); return pvaClientGetData; } PvaClientPutDataPtr PvaClientPutGet::getPutData() { + if(PvaClient::getDebug()) { + cout<< "PvaClientPutGet::getPutData" + << " channelName " << pvaClientChannel->getChannel()->getChannelName() + << endl; + } checkPutGetState(); + if(putGetState==putGetIdle) getPut(); return pvaClientPutData; } +void PvaClientPutGet::setRequester(PvaClientPutGetRequesterPtr const & pvaClientPutGetRequester) +{ + if(PvaClient::getDebug()) { + cout << "PvaClientPutGet::setRequester" + << " channelName " << pvaClientChannel->getChannel()->getChannelName() + << endl; + } + this->pvaClientPutGetRequester = pvaClientPutGetRequester; +} + + +PvaClientChannelPtr PvaClientPutGet::getPvaClientChannel() +{ + return pvaClientChannel; +} + + + }}