From e071e0f9e319fdd63e5fe9856322ceeffdf46a9c Mon Sep 17 00:00:00 2001 From: mrkraimer Date: Wed, 14 Jun 2017 06:14:47 -0400 Subject: [PATCH 01/12] PvaClientChannel::channelStateChange set state before calling stateChangeRequester --- src/pvaClientChannel.cpp | 29 +++++++++++++++-------------- 1 file changed, 15 insertions(+), 14 deletions(-) diff --git a/src/pvaClientChannel.cpp b/src/pvaClientChannel.cpp index b3f4f31..c73bbec 100644 --- a/src/pvaClientChannel.cpp +++ b/src/pvaClientChannel.cpp @@ -246,25 +246,26 @@ void PvaClientChannel::channelStateChange( << " " << Channel::ConnectionStateNames[connectionState] << endl; } + + bool waitingForConnect = false; + if(connectState==connectActive) waitingForConnect = true; + if(connectionState!=Channel::CONNECTED) { + string mess(channelName + + " connection state " + Channel::ConnectionStateNames[connectionState]); + message(mess,errorMessage); + connectState = notConnected; + } else { + connectState = connected; + } + if(waitingForConnect) { + Lock xx(mutex); + waitForConnect.signal(); + } PvaClientChannelStateChangeRequesterPtr req(stateChangeRequester.lock()); if(req) { bool value = (connectionState==Channel::CONNECTED ? true : false); req->channelStateChange(shared_from_this(),value); } - - Lock xx(mutex); - bool waitingForConnect = false; - if(connectState==connectActive) waitingForConnect = true; - if(connectionState!=Channel::CONNECTED) { - string mess(channelName + - " connection state " + Channel::ConnectionStateNames[connectionState]); - message(mess,errorMessage); - connectState = notConnected; - return; - } else { - connectState = connected; - } - if(waitingForConnect) waitForConnect.signal(); } string PvaClientChannel::getRequesterName() From d8ab89e96a3f8095ca0547a6d5f92bfc09fc73a0 Mon Sep 17 00:00:00 2001 From: mrkraimer Date: Wed, 28 Jun 2017 10:36:23 -0400 Subject: [PATCH 02/12] changes for new-pva-api; improve pvaClientMonitor --- src/pv/pvaClient.h | 36 ++++++++--------------- src/pvaClientChannel.cpp | 58 +++++-------------------------------- src/pvaClientMonitor.cpp | 62 +++++++++++++++++++--------------------- 3 files changed, 49 insertions(+), 107 deletions(-) diff --git a/src/pv/pvaClient.h b/src/pv/pvaClient.h index 08cad2e..bb2619e 100644 --- a/src/pv/pvaClient.h +++ b/src/pv/pvaClient.h @@ -28,7 +28,6 @@ #include #include #include -#include #include #ifdef pvaClientEpicsExportSharedSymbols @@ -192,10 +191,6 @@ typedef std::tr1::shared_ptr PvaClientGetCachePtr; class PvaClientPutCache; typedef std::tr1::shared_ptr PvaClientPutCachePtr; -// NOTE: must use separate class that implements ChannelRequester, -// because pvAccess holds a shared_ptr to ChannelRequester instead of weak_pointer -class ChannelRequesterImpl; -typedef std::tr1::shared_ptr ChannelRequesterImplPtr; /** * @brief A callback for change in connection status. @@ -225,6 +220,7 @@ public: */ class epicsShareClass PvaClientChannel : + public epics::pvAccess::ChannelRequester, public std::tr1::enable_shared_from_this { public: @@ -431,18 +427,6 @@ public: */ void destroy() EPICS_DEPRECATED {} private: - //ChannelRequester methods - void channelCreated( - const epics::pvData::Status& status, - epics::pvAccess::Channel::shared_pointer const & channel); - void channelStateChange( - epics::pvAccess::Channel::shared_pointer const & channel, - epics::pvAccess::Channel::ConnectionState connectionState); - std::string getRequesterName(); - void message( - std::string const & message, - epics::pvData::MessageType messageType); - static PvaClientChannelPtr create( PvaClientPtr const &pvaClient, std::string const & channelName, @@ -466,11 +450,18 @@ private: epics::pvData::Mutex mutex; epics::pvData::Event waitForConnect; epics::pvAccess::Channel::shared_pointer channel; + epics::pvAccess::ChannelProvider::shared_pointer channelProvider; PvaClientChannelStateChangeRequesterWPtr stateChangeRequester; - ChannelRequesterImplPtr channelRequester; +public: + virtual std::string getRequesterName(); + virtual void message(std::string const & message, epics::pvData::MessageType messageType); + virtual void channelCreated( + const epics::pvData::Status& status, + epics::pvAccess::Channel::shared_pointer const & channel); + virtual void channelStateChange( + epics::pvAccess::Channel::shared_pointer const & channel, + epics::pvAccess::Channel::ConnectionState connectionState); friend class PvaClient; - friend class ChannelRequesterImpl; - }; /** @@ -1406,7 +1397,6 @@ typedef std::tr1::shared_ptr MonitorRequesterImplPtr; class epicsShareClass PvaClientMonitor : public PvaClientChannelStateChangeRequester, public PvaClientMonitorRequester, - public epics::pvData::Command, public std::tr1::enable_shared_from_this { public: @@ -1499,7 +1489,6 @@ public: */ void destroy() EPICS_DEPRECATED {} private: - static epics::pvData::ExecutorPtr executor; std::string getRequesterName(); void message(std::string const & message,epics::pvData::MessageType messageType); void monitorConnect( @@ -1515,7 +1504,7 @@ private: epics::pvData::PVStructurePtr const &pvRequest); void checkMonitorState(); - enum MonitorConnectState {connectIdle,connectActive,connected}; + enum MonitorConnectState {connectIdle,connectWait,connectActive,connected}; PvaClient::weak_pointer pvaClient; PvaClientChannelPtr pvaClientChannel; @@ -1541,7 +1530,6 @@ private: public: void channelStateChange(PvaClientChannelPtr const & channel, bool isConnected); void event(PvaClientMonitorPtr const & monitor); - void command(); friend class MonitorRequesterImpl; }; diff --git a/src/pvaClientChannel.cpp b/src/pvaClientChannel.cpp index 93c17ff..fcbc69b 100644 --- a/src/pvaClientChannel.cpp +++ b/src/pvaClientChannel.cpp @@ -122,60 +122,12 @@ size_t PvaClientPutCache::cacheSize() } -class epicsShareClass ChannelRequesterImpl : public ChannelRequester -{ - PvaClientChannel::weak_pointer pvaClientChannel; - PvaClient::weak_pointer pvaClient; -public: - ChannelRequesterImpl( - PvaClientChannelPtr const & pvaClientChannel, - PvaClientPtr const &pvaClient) - : pvaClientChannel(pvaClientChannel), - pvaClient(pvaClient) - {} - virtual ~ChannelRequesterImpl() { - if(PvaClient::getDebug()) std::cout << "~ChannelRequesterImpl" << std::endl; - } - - virtual std::string getRequesterName() { - PvaClientChannelPtr clientChannel(pvaClientChannel.lock()); - if(!clientChannel) return string("clientChannel is null"); - return clientChannel->getRequesterName(); - } - - virtual void message(std::string const & message, epics::pvData::MessageType messageType) { - PvaClientChannelPtr clientChannel(pvaClientChannel.lock()); - if(!clientChannel) return; - clientChannel->message(message,messageType); - } - - virtual void channelCreated( - const epics::pvData::Status& status, - Channel::shared_pointer const & channel) - { - PvaClientChannelPtr clientChannel(pvaClientChannel.lock()); - if(!clientChannel) return; - clientChannel->channelCreated(status,channel); - } - - virtual void channelStateChange( - Channel::shared_pointer const & channel, - Channel::ConnectionState connectionState) - { - PvaClientChannelPtr clientChannel(pvaClientChannel.lock()); - if(!clientChannel) return; - clientChannel->channelStateChange(channel,connectionState); - } -}; - PvaClientChannelPtr PvaClientChannel::create( PvaClientPtr const &pvaClient, string const & channelName, string const & providerName) { PvaClientChannelPtr channel(new PvaClientChannel(pvaClient,channelName,providerName)); - channel->channelRequester = ChannelRequesterImplPtr( - new ChannelRequesterImpl(channel,pvaClient)); return channel; } @@ -209,6 +161,7 @@ PvaClientChannel::~PvaClientChannel() void PvaClientChannel::channelCreated(const Status& status, Channel::shared_pointer const & channel) { +cout << "PvaClientChannel::channelCreated channel\n" << channel.get() << endl; if(PvaClient::getDebug()) { cout << "PvaClientChannel::channelCreated" << " channelName " << channelName @@ -240,6 +193,7 @@ void PvaClientChannel::channelStateChange( Channel::shared_pointer const & channel, Channel::ConnectionState connectionState) { +cout << "PvaClientChannel::channelStateChange channel\n" << channel.get() << endl; if(PvaClient::getDebug()) { cout << " PvaClientChannel::channelStateChange " << " channelName " << channelName @@ -333,12 +287,14 @@ void PvaClientChannel::issueConnect() connectState = connectActive; } ChannelProviderRegistry::shared_pointer reg(getChannelProviderRegistry());; - ChannelProvider::shared_pointer provider = reg->getProvider(providerName); - if(!provider) { + channelProvider = reg->getProvider(providerName); + if(!channelProvider) { throw std::runtime_error(channelName + " provider " + providerName + " not registered"); } if(PvaClient::getDebug()) cout << "PvaClientChannel::issueConnect calling provider->createChannel\n"; - channel = provider->createChannel(channelName,channelRequester,ChannelProvider::PRIORITY_DEFAULT); +cout << "before provider->createChannel channel " << channel.get() << endl; + channel = channelProvider->createChannel(channelName,shared_from_this(),ChannelProvider::PRIORITY_DEFAULT); +cout << "after provider->createChannel channel " << channel.get() << endl; if(!channel) { throw std::runtime_error(channelName + " channelCreate failed "); } diff --git a/src/pvaClientMonitor.cpp b/src/pvaClientMonitor.cpp index b794e33..8b78d81 100644 --- a/src/pvaClientMonitor.cpp +++ b/src/pvaClientMonitor.cpp @@ -25,8 +25,6 @@ using namespace std; namespace epics { namespace pvaClient { -ExecutorPtr PvaClientMonitor::executor(new Executor("pvaClientMonitor",middlePriority)); - class MonitorRequesterImpl : public MonitorRequester { PvaClientMonitor::weak_pointer pvaClientMonitor; @@ -114,26 +112,19 @@ PvaClientMonitorPtr PvaClientMonitor::create( CreateRequest::shared_pointer createRequest(CreateRequest::create()); PVStructurePtr pvRequest(createRequest->createRequest(request)); if(!pvRequest) throw std::runtime_error(createRequest->getMessage()); -cout << "calling pvaClient->createChannel\n"; PvaClientChannelPtr pvaClientChannel = pvaClient->createChannel(channelName,providerName); -cout << "calling createMonitor\n"; PvaClientMonitorPtr clientMonitor(new PvaClientMonitor(pvaClient,pvaClientChannel,pvRequest)); -cout << "after calling createMonitor\n"; clientMonitor->monitorRequester = MonitorRequesterImplPtr( new MonitorRequesterImpl(clientMonitor,pvaClient)); if(stateChangeRequester) clientMonitor->pvaClientChannelStateChangeRequester = stateChangeRequester; if(monitorRequester) clientMonitor->pvaClientMonitorRequester = monitorRequester; -cout << "calling init\n"; clientMonitor->init(); -cout << "after calling init\n"; return clientMonitor; } void PvaClientMonitor::init() { -cout << "init calling setStateChangeRequester\n"; pvaClientChannel->setStateChangeRequester(shared_from_this()); -cout << "init calling issueConnect\n"; pvaClientChannel->issueConnect(); } @@ -178,12 +169,12 @@ void PvaClientMonitor::channelStateChange(PvaClientChannelPtr const & channel, b } if(isConnected&&!monitor) { - if(PvaClient::getDebug()) cout<< "PvaClientMonitor::channelStateChange calling executor.execute\n"; - executor->execute(shared_from_this()); - PvaClientChannelStateChangeRequesterPtr req(pvaClientChannelStateChangeRequester.lock()); - if(req) { - req->channelStateChange(channel,isConnected); - } + connectState = connectActive; + monitor = pvaClientChannel->getChannel()->createMonitor(monitorRequester,pvRequest); + } + PvaClientChannelStateChangeRequesterPtr req(pvaClientChannelStateChangeRequester.lock()); + if(req) { + req->channelStateChange(channel,isConnected); } } @@ -193,13 +184,6 @@ void PvaClientMonitor::event(PvaClientMonitorPtr const & monitor) if(req) req->event(monitor); } -void PvaClientMonitor::command() -{ - if(PvaClient::getDebug()) cout<< "PvaClientMonitor::command\n"; - connect(); - if(connectState==connected && !isStarted) start(); -} - void PvaClientMonitor::checkMonitorState() { if(PvaClient::getDebug()) { @@ -237,9 +221,18 @@ void PvaClientMonitor::monitorConnect( << " status.isOK " << (status.isOK() ? "true" : "false") << endl; } + if(!status.isOK()) { + this->monitor.reset(); + connectState = connectIdle; + string message = string("PvaClientMonitor::monitorConnect channel ") + + pvaClientChannel->getChannel()->getChannelName() + + " " + + status.getMessage(); + throw std::runtime_error(message); + } + bool signal = (connectState==connectWait) ? true : false; connectStatus = status; connectState = connected; - this->monitor = monitor; if(isStarted) { if(PvaClient::getDebug()) { cout << "PvaClientMonitor::monitorConnect" @@ -249,14 +242,19 @@ void PvaClientMonitor::monitorConnect( } return; } - if(status.isOK()) { - pvaClientData = PvaClientMonitorData::create(structure); - pvaClientData->setMessagePrefix(pvaClientChannel->getChannel()->getChannelName()); + pvaClientData = PvaClientMonitorData::create(structure); + pvaClientData->setMessagePrefix(pvaClientChannel->getChannel()->getChannelName()); + if(signal) { + if(PvaClient::getDebug()) { + cout << "PvaClientMonitor::monitorConnect calling waitForConnect.signal\n"; + } + waitForConnect.signal(); + } else { + if(PvaClient::getDebug()) { + cout << "PvaClientMonitor::monitorConnect calling start\n"; + } + start(); } - if(PvaClient::getDebug()) { - cout << "PvaClientMonitor::monitorConnect calling waitForConnect.signal\n"; - } - waitForConnect.signal(); } @@ -306,7 +304,7 @@ void PvaClientMonitor::issueConnect() + " pvaClientMonitor already connected "; throw std::runtime_error(message); } - connectState = connectActive; + connectState = connectWait; monitor = pvaClientChannel->getChannel()->createMonitor(monitorRequester,pvRequest); } @@ -321,7 +319,7 @@ Status PvaClientMonitor::waitConnect() if(!connectStatus.isOK()) connectState = connectIdle; return connectStatus; } - if(connectState!=connectActive) { + if(connectState!=connectWait) { string message = string("channel ") + pvaClientChannel->getChannel()->getChannelName() + " PvaClientMonitor::waitConnect illegal connect state "; From 594d8dd19fcac5360c53682f3ab83a7b84f23d7d Mon Sep 17 00:00:00 2001 From: mrkraimer Date: Thu, 29 Jun 2017 09:47:14 -0400 Subject: [PATCH 03/12] changes to documentation --- documentation/RELEASE_NOTES.md | 43 +++++++- .../htmldoxygen/pvaClientMonitor.html | 104 ++++++++++++++++++ documentation/pvaClientCPP.html | 24 ++-- src/pv/pvaClient.h | 5 +- 4 files changed, 157 insertions(+), 19 deletions(-) create mode 100644 documentation/htmldoxygen/pvaClientMonitor.html diff --git a/documentation/RELEASE_NOTES.md b/documentation/RELEASE_NOTES.md index faa83ee..5d0aa9d 100644 --- a/documentation/RELEASE_NOTES.md +++ b/documentation/RELEASE_NOTES.md @@ -1,5 +1,44 @@ +EPICS V4 release 4.7 +==================== + +API changes to PvaClientMonitor +------------------------------- + +The second argument of method + + static PvaClientMonitorPtr create( + PvaClientPtr const &pvaClient, + epics::pvAccess::Channel::shared_pointer const & channel, + epics::pvData::PVStructurePtr const &pvRequest + ); + +Is now changed to + + static PvaClientMonitorPtr create( + PvaClientPtr const &pvaClient, + PvaClientChannelPtr const & pvaClientChannel, + epics::pvData::PVStructurePtr const &pvRequest + ); + +A new method is also implemented + + static PvaClientMonitorPtr create( + PvaClientPtr const &pvaClient, + std::string const & channelName, + std::string const & providerName, + std::string const & request, + PvaClientChannelStateChangeRequesterPtr const & stateChangeRequester, + PvaClientMonitorRequesterPtr const & monitorRequester + ); + +Works with release/6.0 of pvAccessCPP +-------------------------------------- + +Not sure this will work with older versions of pvAccessCPP. + + EPICS V4 release 4.6 -========================== +==================== * The examples are moved to exampleCPP. * Support for channelRPC is now available. @@ -8,7 +47,7 @@ EPICS V4 release 4.6 EPICS V4 release 4.5 -========================== +==================== pvaClient is a synchronous API for pvAccess. diff --git a/documentation/htmldoxygen/pvaClientMonitor.html b/documentation/htmldoxygen/pvaClientMonitor.html new file mode 100644 index 0000000..36d6461 --- /dev/null +++ b/documentation/htmldoxygen/pvaClientMonitor.html @@ -0,0 +1,104 @@ + + + + + + PvaClientMonitor + + + + + + + + +

PvaClientMonitor

+ +

Overview

+

+This provides an easier way to create a monitor on a channel than to use pvAccessCPP itself. +It provides two main ways to create a monitor: +

+

The client first creates a pvaClientChannel and then creates a monitor

+The client calls: +
+static PvaClientMonitorPtr create(
+    PvaClientPtr const &pvaClient,
+    PvaClientChannelPtr const & pvaClientChannel,
+    epics::pvData::PVStructurePtr const &pvRequest
+);
+
+where
+
+pvaClient
+    The pvaClient.
+
+pvaClientChannel
+    The pvaClientChannel that has already been created by the client.
+
+pvRequest
+    The pvRequest for creating the monitor.
+
+With this method the monitor is created and started. +This method blocks while the monitor is created. +

The client provides names for a channel and a provider

+The client calls: +
+static PvaClientMonitorPtr create(
+    PvaClientPtr const &pvaClient,
+    std::string const & channelName,
+    std::string const & providerName,
+    std::string const & request,
+    PvaClientChannelStateChangeRequesterPtr const & stateChangeRequester,
+    PvaClientMonitorRequesterPtr const & monitorRequester
+);
+
+where
+
+pvaClient
+    The pvaClient.
+
+channelName
+    The name of the channel.
+
+providerName
+    The name of the provider
+
+request
+    The request for creating the monitor
+
+stateChangeRequester
+    The client supplied state change requester.
+    This will be called each time a state change for the channel occurs.
+
+monitorRequester
+    The client supplied monitor requester.
+    This is called each time a new monitor event is available.
+
+With this method a pvaChannel is created and after it connects a pvaMonitor is created and started. +This method never blocks. + + + + diff --git a/documentation/pvaClientCPP.html b/documentation/pvaClientCPP.html index 20ee501..ee62eff 100644 --- a/documentation/pvaClientCPP.html +++ b/documentation/pvaClientCPP.html @@ -26,11 +26,11 @@

EPICS pvaClientCPP

-

Release 4.2.0-SNAPSHOT - 2016-07-14

+

Release 4.7.0-SNAPSHOT - 2017-06-29

Abstract

-

pvaClient is a software library that provides to an EPICS client programmer, a friendly +

pvaClient is a software library that provides, to an EPICS client programmer, a friendly client side programming interface to the data of an EPICS based control system. It is intended for such uses as rapid development of ad hoc programs by controls engineers, or to provide scientists a way to directly develop analytical applications.

@@ -62,11 +62,6 @@ The data for the channels is presented via normative type NTMultiChannel.
-
-

Table of Contents

-
- -

Overview

@@ -76,10 +71,10 @@ pvaClientCPP is one of the components of EPICS Version 4

-

This document is only a guide to help locate code and documentation related to pvDatabaseCPP +

This document is only a guide to help locate code and documentation related to pvaClientCPP

-It is intended for developers that want to use pvDatabaseCPP. +It is intended for developers that want to use pvaClientCPP.

Developer Guide

A guide for developers is available at @@ -88,14 +83,11 @@ href="http://epics-pvdata.sourceforge.net/informative/developerGuide/developerGu developerGuide

-

This guide discusses all the components that are part of an EPICS V4 release. +

This guide provides an overview of the components that are part of an EPICS V4 release. Some understanding of the components and how they are related is necessary in order to -develop code that uses pvDatabaseCPP. +develop code that uses pvaClientCPP. In particular read everything related to pvaClient.

-

The developerGuide discusses code in a way that applies to both CPP and C++. -For the descriptions of the CPP specific code consult the next section. -

doxygen

doxygen documentation is available at @@ -104,9 +96,9 @@ href="./html/index.html">doxygen

exampleCPP

-

Example code is available as part of this release. +

Example code is available at +href="https://github.com/epics-base/exampleCPP"> exampleCPP

diff --git a/src/pv/pvaClient.h b/src/pv/pvaClient.h index bb2619e..8a3bb46 100644 --- a/src/pv/pvaClient.h +++ b/src/pv/pvaClient.h @@ -84,6 +84,7 @@ typedef std::tr1::shared_ptr PvaClientChannelCachePtr; * * Thus it is easier to use than pvAccess itself. * In addition pvaClient provides many convenience methods. + * * @author mrk * @date 2015.02 */ @@ -98,6 +99,7 @@ public: */ ~PvaClient(); /** @brief Get the single instance of PvaClient. + * * @param providerNames Space separated list of provider names. * @return shared pointer to the single instance. */ @@ -1393,6 +1395,7 @@ typedef std::tr1::shared_ptr MonitorRequesterImplPtr; /** * @brief An easy to use alternative to Monitor. * + * pvaClientMonitor */ class epicsShareClass PvaClientMonitor : public PvaClientChannelStateChangeRequester, @@ -1688,6 +1691,6 @@ private: /** @page Overview Documentation * * pvaClientCPP.html - * + * */ From 696c251ecca2eac3883864a9940a79d526c2dd20 Mon Sep 17 00:00:00 2001 From: mrkraimer Date: Wed, 5 Jul 2017 10:08:53 -0400 Subject: [PATCH 04/12] remove some cout messages --- src/pvaClientChannel.cpp | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/pvaClientChannel.cpp b/src/pvaClientChannel.cpp index fcbc69b..55aaa7a 100644 --- a/src/pvaClientChannel.cpp +++ b/src/pvaClientChannel.cpp @@ -161,7 +161,6 @@ PvaClientChannel::~PvaClientChannel() void PvaClientChannel::channelCreated(const Status& status, Channel::shared_pointer const & channel) { -cout << "PvaClientChannel::channelCreated channel\n" << channel.get() << endl; if(PvaClient::getDebug()) { cout << "PvaClientChannel::channelCreated" << " channelName " << channelName @@ -193,7 +192,6 @@ void PvaClientChannel::channelStateChange( Channel::shared_pointer const & channel, Channel::ConnectionState connectionState) { -cout << "PvaClientChannel::channelStateChange channel\n" << channel.get() << endl; if(PvaClient::getDebug()) { cout << " PvaClientChannel::channelStateChange " << " channelName " << channelName @@ -292,9 +290,7 @@ void PvaClientChannel::issueConnect() throw std::runtime_error(channelName + " provider " + providerName + " not registered"); } if(PvaClient::getDebug()) cout << "PvaClientChannel::issueConnect calling provider->createChannel\n"; -cout << "before provider->createChannel channel " << channel.get() << endl; channel = channelProvider->createChannel(channelName,shared_from_this(),ChannelProvider::PRIORITY_DEFAULT); -cout << "after provider->createChannel channel " << channel.get() << endl; if(!channel) { throw std::runtime_error(channelName + " channelCreate failed "); } From ae49f8ad99a48bd3fe50f1d63580b0c3764f4bc6 Mon Sep 17 00:00:00 2001 From: mrkraimer Date: Thu, 6 Jul 2017 14:04:26 -0400 Subject: [PATCH 05/12] add PvaClientMonitor::getPvaClientChannel() --- documentation/htmldoxygen/README.md | 5 ++ documentation/htmldoxygen/pvaClient.html | 51 +++++++++++++++++++ .../htmldoxygen/pvaClientChannel.html | 44 ++++++++++++++++ .../htmldoxygen/pvaClientChannelGet.html | 44 ++++++++++++++++ .../htmldoxygen/pvaClientChannelProcess.html | 44 ++++++++++++++++ .../htmldoxygen/pvaClientChannelPut.html | 44 ++++++++++++++++ .../htmldoxygen/pvaClientChannelPutGet.html | 44 ++++++++++++++++ .../pvaClientChannelStateChangeRequester.html | 44 ++++++++++++++++ .../htmldoxygen/pvaClientGetData.html | 44 ++++++++++++++++ .../htmldoxygen/pvaClientMonitor.html | 26 +++++----- .../htmldoxygen/pvaClientMonitorData.html | 44 ++++++++++++++++ .../pvaClientMonitorRequester.html | 44 ++++++++++++++++ .../htmldoxygen/pvaClientProcess.html | 44 ++++++++++++++++ .../htmldoxygen/pvaClientPutData.html | 44 ++++++++++++++++ documentation/htmldoxygen/pvaClientRPC.html | 44 ++++++++++++++++ .../htmldoxygen/pvaClientRPCRequester.html | 44 ++++++++++++++++ src/pv/pvaClient.h | 35 +++++++++---- src/pvaClientMonitor.cpp | 5 ++ 18 files changed, 671 insertions(+), 23 deletions(-) create mode 100644 documentation/htmldoxygen/README.md create mode 100644 documentation/htmldoxygen/pvaClient.html create mode 100644 documentation/htmldoxygen/pvaClientChannel.html create mode 100644 documentation/htmldoxygen/pvaClientChannelGet.html create mode 100644 documentation/htmldoxygen/pvaClientChannelProcess.html create mode 100644 documentation/htmldoxygen/pvaClientChannelPut.html create mode 100644 documentation/htmldoxygen/pvaClientChannelPutGet.html create mode 100644 documentation/htmldoxygen/pvaClientChannelStateChangeRequester.html create mode 100644 documentation/htmldoxygen/pvaClientGetData.html create mode 100644 documentation/htmldoxygen/pvaClientMonitorData.html create mode 100644 documentation/htmldoxygen/pvaClientMonitorRequester.html create mode 100644 documentation/htmldoxygen/pvaClientProcess.html create mode 100644 documentation/htmldoxygen/pvaClientPutData.html create mode 100644 documentation/htmldoxygen/pvaClientRPC.html create mode 100644 documentation/htmldoxygen/pvaClientRPCRequester.html diff --git a/documentation/htmldoxygen/README.md b/documentation/htmldoxygen/README.md new file mode 100644 index 0000000..372621f --- /dev/null +++ b/documentation/htmldoxygen/README.md @@ -0,0 +1,5 @@ +NOT FOR DIRECT USE +================== + +This directory holds files that are used by doxygen. +The files are not meant to be read except via the doxygen documention. diff --git a/documentation/htmldoxygen/pvaClient.html b/documentation/htmldoxygen/pvaClient.html new file mode 100644 index 0000000..ccaccc4 --- /dev/null +++ b/documentation/htmldoxygen/pvaClient.html @@ -0,0 +1,51 @@ + + + + + + PvaClient + + + + + + + + +

PvaClient

+ +

+Not Yet Written +

+ +

Overview

+

+pvaClient is a synchronous wrapper for the pvAccess API, which is a callback based API. +Thus it is easier to use than pvAccess itself. +In addition pvaClient provides many convenience methods. +

+ + + + diff --git a/documentation/htmldoxygen/pvaClientChannel.html b/documentation/htmldoxygen/pvaClientChannel.html new file mode 100644 index 0000000..8ba227e --- /dev/null +++ b/documentation/htmldoxygen/pvaClientChannel.html @@ -0,0 +1,44 @@ + + + + + + PvaClientChannel + + + + + + + + +

PvaClientChannel

+ +

+Not Yet Written +

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

PvaClientGet

+ +

+Not Yet Written +

+ + + + diff --git a/documentation/htmldoxygen/pvaClientChannelProcess.html b/documentation/htmldoxygen/pvaClientChannelProcess.html new file mode 100644 index 0000000..70dda71 --- /dev/null +++ b/documentation/htmldoxygen/pvaClientChannelProcess.html @@ -0,0 +1,44 @@ + + + + + + PvaClientProcess + + + + + + + + +

PvaClientProcess

+ +

+Not Yet Written +

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

PvaClientChannelPut

+ +

+Not Yet Written +

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

PvaClientPutGet

+ +

+Not Yet Written +

+ + + + diff --git a/documentation/htmldoxygen/pvaClientChannelStateChangeRequester.html b/documentation/htmldoxygen/pvaClientChannelStateChangeRequester.html new file mode 100644 index 0000000..48d0ae6 --- /dev/null +++ b/documentation/htmldoxygen/pvaClientChannelStateChangeRequester.html @@ -0,0 +1,44 @@ + + + + + + PvaClientChannelStateChangeRequester + + + + + + + + +

PvaClientChannelStateChangeRequester

+ +

+Not Yet Written +

+ + + + diff --git a/documentation/htmldoxygen/pvaClientGetData.html b/documentation/htmldoxygen/pvaClientGetData.html new file mode 100644 index 0000000..06ac804 --- /dev/null +++ b/documentation/htmldoxygen/pvaClientGetData.html @@ -0,0 +1,44 @@ + + + + + + PvaClientGetData + + + + + + + + +

PvaClientGetData

+ +

+Not Yet Written +

+ + + + diff --git a/documentation/htmldoxygen/pvaClientMonitor.html b/documentation/htmldoxygen/pvaClientMonitor.html index 36d6461..f3b3f25 100644 --- a/documentation/htmldoxygen/pvaClientMonitor.html +++ b/documentation/htmldoxygen/pvaClientMonitor.html @@ -34,28 +34,30 @@

PvaClientMonitor

- +

+NOTE: This is a work in progress. +

Overview

This provides an easier way to create a monitor on a channel than to use pvAccessCPP itself. It provides two main ways to create a monitor:

-

The client first creates a pvaClientChannel and then creates a monitor

+

The client first creates a PvaClientMonitorChannel and then creates a monitor

The client calls:
 static PvaClientMonitorPtr create(
-    PvaClientPtr const &pvaClient,
-    PvaClientChannelPtr const & pvaClientChannel,
+    PvaClientMonitorPtr const &PvaClientMonitor,
+    PvaClientMonitorChannelPtr const & PvaClientMonitorChannel,
     epics::pvData::PVStructurePtr const &pvRequest
 );
 
 where
 
-pvaClient
-    The pvaClient.
+PvaClientMonitor
+    The PvaClientMonitor.
 
-pvaClientChannel
-    The pvaClientChannel that has already been created by the client.
+PvaClientMonitorChannel
+    The PvaClientMonitorChannel that has already been created by the client.
 
 pvRequest
     The pvRequest for creating the monitor.
@@ -66,18 +68,18 @@ This method blocks while the monitor is created.
 The client calls:
 
 static PvaClientMonitorPtr create(
-    PvaClientPtr const &pvaClient,
+    PvaClientMonitorPtr const &PvaClientMonitor,
     std::string const & channelName,
     std::string const & providerName,
     std::string const & request,
-    PvaClientChannelStateChangeRequesterPtr const & stateChangeRequester,
+    PvaClientMonitorChannelStateChangeRequesterPtr const & stateChangeRequester,
     PvaClientMonitorRequesterPtr const & monitorRequester
 );
 
 where
 
-pvaClient
-    The pvaClient.
+PvaClientMonitor
+    The PvaClientMonitor.
 
 channelName
     The name of the channel.
diff --git a/documentation/htmldoxygen/pvaClientMonitorData.html b/documentation/htmldoxygen/pvaClientMonitorData.html
new file mode 100644
index 0000000..0d8b29b
--- /dev/null
+++ b/documentation/htmldoxygen/pvaClientMonitorData.html
@@ -0,0 +1,44 @@
+
+
+
+
+  
+  PvaClientMonitotData
+  
+  
+  
+  
+  
+
+
+
+

PvaClientMonitotData

+ +

+Not Yet Written +

+ + + + diff --git a/documentation/htmldoxygen/pvaClientMonitorRequester.html b/documentation/htmldoxygen/pvaClientMonitorRequester.html new file mode 100644 index 0000000..43d36bd --- /dev/null +++ b/documentation/htmldoxygen/pvaClientMonitorRequester.html @@ -0,0 +1,44 @@ + + + + + + PvaClientMonitorRequester + + + + + + + + +

PvaClientMonitorRequester

+ +

+Not Yet Written +

+ + + + diff --git a/documentation/htmldoxygen/pvaClientProcess.html b/documentation/htmldoxygen/pvaClientProcess.html new file mode 100644 index 0000000..70dda71 --- /dev/null +++ b/documentation/htmldoxygen/pvaClientProcess.html @@ -0,0 +1,44 @@ + + + + + + PvaClientProcess + + + + + + + + +

PvaClientProcess

+ +

+Not Yet Written +

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

PvaClientPutData

+ +

+Not Yet Written +

+ + + + diff --git a/documentation/htmldoxygen/pvaClientRPC.html b/documentation/htmldoxygen/pvaClientRPC.html new file mode 100644 index 0000000..4a754c1 --- /dev/null +++ b/documentation/htmldoxygen/pvaClientRPC.html @@ -0,0 +1,44 @@ + + + + + + PvaClientRPC + + + + + + + + +

PvaClientRPC

+ +

+Not Yet Written +

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

PvaClientRPCRequester

+ +

+Not Yet Written +

+ + + + diff --git a/src/pv/pvaClient.h b/src/pv/pvaClient.h index 8a3bb46..61baf49 100644 --- a/src/pv/pvaClient.h +++ b/src/pv/pvaClient.h @@ -3,6 +3,10 @@ * EPICS pvData is distributed subject to a Software License Agreement found * in file LICENSE that is included with this distribution. */ +/** + * @author mrk + * @date 2015.02 + */ #ifndef PVACLIENT_H #define PVACLIENT_H @@ -82,11 +86,7 @@ typedef std::tr1::shared_ptr PvaClientChannelCachePtr; /** * @brief pvaClient is a synchronous wrapper for the pvAccess API, which is a callback based API. * - * Thus it is easier to use than pvAccess itself. - * In addition pvaClient provides many convenience methods. - * - * @author mrk - * @date 2015.02 + * pvaClient */ class epicsShareClass PvaClient : public epics::pvData::Requester, @@ -197,7 +197,8 @@ typedef std::tr1::shared_ptr PvaClientPutCachePtr; /** * @brief A callback for change in connection status. * - * @author mrk + * pvaClientChannelStateChangeRequesterpvaClientChannel */ class epicsShareClass PvaClientChannel : @@ -469,6 +470,7 @@ public: /** * @brief A class that holds data returned by PvaClientGet or PvaClientPutGet * + * pvaClientGetData */ class epicsShareClass PvaClientGetData { @@ -607,6 +609,7 @@ class PvaClientPostHandlerPvt; // private to PvaClientPutData /** * @brief A class that holds data given to by PvaClientPut or PvaClientPutGet * + * pvaClientPutData */ class epicsShareClass PvaClientPutData { @@ -745,6 +748,7 @@ private: /** * @brief A class that holds data returned by PvaClientMonitor * + * pvaClientMonitorData */ class epicsShareClass PvaClientMonitorData { @@ -902,7 +906,7 @@ typedef std::tr1::shared_ptr ChannelProcessRequeste /** * @brief An easy to use alternative to ChannelProcess. * - * @author mrk + * pvaClientChannelProcess */ class epicsShareClass PvaClientProcess { @@ -996,7 +1000,7 @@ typedef std::tr1::shared_ptr ChannelGetRequesterImplPtr /** * @brief An easy to use alternative to ChannelGet. * - * @author mrk + * pvaClientChannelGet */ class epicsShareClass PvaClientGet { @@ -1103,7 +1107,7 @@ typedef std::tr1::shared_ptr ChannelPutRequesterImplPtr /** * @brief An easy to use alternative to ChannelPut. * - * @author mrk + * pvaClientChannelPut */ class epicsShareClass PvaClientPut { @@ -1222,7 +1226,7 @@ typedef std::tr1::shared_ptr ChannelPutGetRequesterI /** * @brief An easy to use alternative to ChannelPutGet. * - * @author mrk + * pvaClientChannelPutGet */ class epicsShareClass PvaClientPutGet { @@ -1365,6 +1369,7 @@ private : /** * @brief Optional client callback. * + * pvaClientMonitorRequester */ class PvaClientMonitorRequester { @@ -1483,7 +1488,13 @@ public: /** @brief Release the monitorElement returned by poll */ void releaseEvent(); + /** @brief Get the PvaClientChannel; + * + * @return The interface. + */ + PvaClientChannelPtr getPvaClientChannel(); /** @brief The data in which monitor events are placed. + * * @return The interface. */ PvaClientMonitorDataPtr getData(); @@ -1541,6 +1552,7 @@ public: /** * @brief Optional client callback. * + * pvaClientRPCRequester */ class PvaClientRPCRequester { @@ -1566,6 +1578,7 @@ typedef std::tr1::shared_ptr RPCRequesterImplPtr; /** * @brief An easy to use alternative to RPC. * + * pvaClientRPC */ class epicsShareClass PvaClientRPC : public std::tr1::enable_shared_from_this diff --git a/src/pvaClientMonitor.cpp b/src/pvaClientMonitor.cpp index 8b78d81..57ecaa8 100644 --- a/src/pvaClientMonitor.cpp +++ b/src/pvaClientMonitor.cpp @@ -489,6 +489,11 @@ void PvaClientMonitor::releaseEvent() monitor->release(monitorElement); } +PvaClientChannelPtr PvaClientMonitor::getPvaClientChannel() +{ + return pvaClientChannel; +} + PvaClientMonitorDataPtr PvaClientMonitor::getData() { if(PvaClient::getDebug()) { From 8f6cc08f85ccfd86fd4955c46809f5374ed3ccd5 Mon Sep 17 00:00:00 2001 From: mrkraimer Date: Thu, 6 Jul 2017 15:33:08 -0400 Subject: [PATCH 06/12] MessageType::errorMessage => errorMessage --- documentation/htmldoxygen/pvaClient.html | 78 +++++++++++++++++++++++- src/pv/pvaClient.h | 48 ++++++--------- src/pvaClientMonitor.cpp | 2 +- 3 files changed, 95 insertions(+), 33 deletions(-) diff --git a/documentation/htmldoxygen/pvaClient.html b/documentation/htmldoxygen/pvaClient.html index ccaccc4..85a9ed3 100644 --- a/documentation/htmldoxygen/pvaClient.html +++ b/documentation/htmldoxygen/pvaClient.html @@ -35,9 +35,6 @@

PvaClient

-

-Not Yet Written -

Overview

@@ -45,6 +42,81 @@ pvaClient is a synchronous wrapper for the pvAccess API, which is a callback bas Thus it is easier to use than pvAccess itself. In addition pvaClient provides many convenience methods.

+

+Class PvaClient is a class that is used by all the other pvaClient classes. +An application that uses pvaClient must call:

+
+PvaClientPtr pvaClient = PvaClient::get(providers);
+
+

+before it uses any other pvaClient classes. +

+

+This is a singleton method, i. e. only one instance of PvaClient is created. +

+

+pvaClient must not be deleted until the client no longer wants to use any part +of pvaClient. +

+

+providers is a blank separated set of provider names. +For example:

+
+PvaClientPtr pvaClient = PvaClient::get("ca pva");
+
+

+The providers ca and pva are special. +For each of these a client context is created when the PvaClient +is constructed and the context destroyed when PvaClient is deleted. +

+

Channel Caching

+

+PvaClient has a method: +

+
+PvaClientChannelPtr channel(
+    string const & channelName,
+    string const &providerName = "pva",
+    double timeOut = 5.0);
+
+

+This method creates a +PvaClientChannel and then connects to the channel. +

+

+If a call is successful then multiple calls to the same channelName and providerName +share the same PvaClientChannel, i. e. the PvaClientChannel is cached. +

+

+pvaClientChannelGet and pvaClientChannelPut also implement caching. +

+

+For example consider a client that makes multiple calls like: +

+
+double value;
+value =  pva->channel(channelName)->get()->getData()->getDouble();
+...
+value =  pva->channel(channelName)->get()->getData()->getDouble();
+
+

+Only the first call creates a new PvaClientChannel and a new PvaClientGet. +The second call reuses the cached PvaClientChannel and PvaClientGet. +

+

Non Cached Channels

+

+PvaClient has a method: +

+
+PvaClientChannelPtr createChannel(
+    string const & channelName,
+    string const &providerName = "pva");
+
+

+This method is just creates a new PvaClientChannel and returns it to the caller. +The caller must call the PvaClientChannel connect methods. +

+ diff --git a/src/pv/pvaClient.h b/src/pv/pvaClient.h index 61baf49..ef12d31 100644 --- a/src/pv/pvaClient.h +++ b/src/pv/pvaClient.h @@ -86,7 +86,7 @@ typedef std::tr1::shared_ptr PvaClientChannelCachePtr; /** * @brief pvaClient is a synchronous wrapper for the pvAccess API, which is a callback based API. * - * pvaClient + * Overview of PvaClient */ class epicsShareClass PvaClient : public epics::pvData::Requester, @@ -104,14 +104,6 @@ public: * @return shared pointer to the single instance. */ static PvaClientPtr get(std::string const & providerNames = "pva ca"); - /** @brief Create an instance of PvaClient with providerName "pva ca". - * \deprecated This method will go away in future versions. Use get instead. - * @return shared pointer to the single instance - */ - static PvaClientPtr create() EPICS_DEPRECATED - { - return get(); - } /** @brief Get the requester name. * @return The name. */ @@ -127,6 +119,7 @@ public: std::string const & message, epics::pvData::MessageType messageType); /** @brief Get a cached channel or create and connect to a new channel. + * * @param channelName The channelName. * @param providerName The providerName. * @param timeOut The number of seconds to wait for connection. 0.0 means forever. @@ -138,6 +131,7 @@ public: std::string const &providerName = "pva", double timeOut = 5.0); /** @brief Create an PvaClientChannel with the specified provider. + * * @param channelName The channelName. * @param providerName The provider. * @return The interface. @@ -162,20 +156,16 @@ public: /** @brief Get the number of cached channels. */ size_t cacheSize(); - /** Should debug info be shown? + /** @brief Should debug info be shown? + * * @param value true or false */ static void setDebug(bool value) {debug = value;} /** @brief Is debug set? + * * @return true or false */ static bool getDebug() {return debug;} - - /** @brief Deprecated method - * \deprecated This method will go away in future versions. - */ - void destroy() EPICS_DEPRECATED {} - private: static bool debug; PvaClient(std::string const & providerNames); @@ -197,7 +187,7 @@ typedef std::tr1::shared_ptr PvaClientPutCachePtr; /** * @brief A callback for change in connection status. * - * pvaClientChannelStateChangeRequesterOverview of PvaClientChannelStateChangeRequesterpvaClientChannel + * Overview of PvaClientChannel */ class epicsShareClass PvaClientChannel : @@ -470,7 +460,7 @@ public: /** * @brief A class that holds data returned by PvaClientGet or PvaClientPutGet * - * pvaClientGetData + * Overview of PvaClientGetData */ class epicsShareClass PvaClientGetData { @@ -609,7 +599,7 @@ class PvaClientPostHandlerPvt; // private to PvaClientPutData /** * @brief A class that holds data given to by PvaClientPut or PvaClientPutGet * - * pvaClientPutData + * Overview of PvaClientPutData */ class epicsShareClass PvaClientPutData { @@ -748,7 +738,7 @@ private: /** * @brief A class that holds data returned by PvaClientMonitor * - * pvaClientMonitorData + * Overview of PvaClientMonitorData */ class epicsShareClass PvaClientMonitorData { @@ -906,7 +896,7 @@ typedef std::tr1::shared_ptr ChannelProcessRequeste /** * @brief An easy to use alternative to ChannelProcess. * - * pvaClientChannelProcess + * Overview of PvaClientChannelProcess */ class epicsShareClass PvaClientProcess { @@ -1000,7 +990,7 @@ typedef std::tr1::shared_ptr ChannelGetRequesterImplPtr /** * @brief An easy to use alternative to ChannelGet. * - * pvaClientChannelGet + * Overview of PvaClientChannelGet */ class epicsShareClass PvaClientGet { @@ -1107,7 +1097,7 @@ typedef std::tr1::shared_ptr ChannelPutRequesterImplPtr /** * @brief An easy to use alternative to ChannelPut. * - * pvaClientChannelPut + * Overview of PvaClientChannelPut */ class epicsShareClass PvaClientPut { @@ -1226,7 +1216,7 @@ typedef std::tr1::shared_ptr ChannelPutGetRequesterI /** * @brief An easy to use alternative to ChannelPutGet. * - * pvaClientChannelPutGet + * Overview of PvaClientChannelPutGet */ class epicsShareClass PvaClientPutGet { @@ -1369,7 +1359,7 @@ private : /** * @brief Optional client callback. * - * pvaClientMonitorRequester + * Overview of PvaClientMonitorRequester */ class PvaClientMonitorRequester { @@ -1400,7 +1390,7 @@ typedef std::tr1::shared_ptr MonitorRequesterImplPtr; /** * @brief An easy to use alternative to Monitor. * - * pvaClientMonitor + * Overview of PvaClientMonitor */ class epicsShareClass PvaClientMonitor : public PvaClientChannelStateChangeRequester, @@ -1552,7 +1542,7 @@ public: /** * @brief Optional client callback. * - * pvaClientRPCRequester + * Overview of PvaClientRPCRequester */ class PvaClientRPCRequester { @@ -1578,7 +1568,7 @@ typedef std::tr1::shared_ptr RPCRequesterImplPtr; /** * @brief An easy to use alternative to RPC. * - * pvaClientRPC + * Overview of PvaClientRPC */ class epicsShareClass PvaClientRPC : public std::tr1::enable_shared_from_this diff --git a/src/pvaClientMonitor.cpp b/src/pvaClientMonitor.cpp index 57ecaa8..b1c2c04 100644 --- a/src/pvaClientMonitor.cpp +++ b/src/pvaClientMonitor.cpp @@ -384,7 +384,7 @@ void PvaClientMonitor::start(string const & request) if(!pvaClientChannel->getChannel()->isConnected()) { client->message( "PvaClientMonitor::start(request) but not connected", - MessageType::errorMessage); + errorMessage); return; } CreateRequest::shared_pointer createRequest(CreateRequest::create()); From 609c887c197d708d1b40e435decd87be1971bfb0 Mon Sep 17 00:00:00 2001 From: mrkraimer Date: Fri, 7 Jul 2017 10:46:22 -0400 Subject: [PATCH 07/12] replace getChannelProviderRegistry with ChannelProviderRegistry::clients --- src/pvaClient.cpp | 2 +- src/pvaClientChannel.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/pvaClient.cpp b/src/pvaClient.cpp index 6078b49..cb3790d 100644 --- a/src/pvaClient.cpp +++ b/src/pvaClient.cpp @@ -105,7 +105,7 @@ PvaClient::PvaClient(std::string const & providerNames) : pvaClientChannelCache(new PvaClientChannelCache()), pvaStarted(false), caStarted(false), - channelRegistry(getChannelProviderRegistry()) + channelRegistry(ChannelProviderRegistry::clients()) { stringstream ss(providerNames); string providerName; diff --git a/src/pvaClientChannel.cpp b/src/pvaClientChannel.cpp index 55aaa7a..886018c 100644 --- a/src/pvaClientChannel.cpp +++ b/src/pvaClientChannel.cpp @@ -284,7 +284,7 @@ void PvaClientChannel::issueConnect() } connectState = connectActive; } - ChannelProviderRegistry::shared_pointer reg(getChannelProviderRegistry());; + ChannelProviderRegistry::shared_pointer reg(ChannelProviderRegistry::clients()); channelProvider = reg->getProvider(providerName); if(!channelProvider) { throw std::runtime_error(channelName + " provider " + providerName + " not registered"); From 8c7506449bdbe4d9c0456b0b7b5f7e1309fe1856 Mon Sep 17 00:00:00 2001 From: mrkraimer Date: Wed, 12 Jul 2017 06:11:29 -0400 Subject: [PATCH 08/12] doxygen changes --- README.md | 26 ----- documentation/RELEASE_NOTES.md | 15 ++- documentation/htmldoxygen/pvaClient.html | 23 +++++ .../htmldoxygen/pvaClientChannel.html | 81 +++++++++++++++- .../htmldoxygen/pvaClientChannelProcess.html | 44 --------- .../htmldoxygen/pvaClientChannelPut.html | 44 --------- .../htmldoxygen/pvaClientChannelPutGet.html | 44 --------- .../pvaClientChannelStateChangeRequester.html | 41 +++++++- ...lientChannelGet.html => pvaClientGet.html} | 32 ++++++- .../htmldoxygen/pvaClientGetData.html | 25 ++++- .../htmldoxygen/pvaClientMonitorData.html | 32 ++++++- .../htmldoxygen/pvaClientProcess.html | 29 +++++- documentation/htmldoxygen/pvaClientPut.html | 82 ++++++++++++++++ .../htmldoxygen/pvaClientPutData.html | 33 ++++++- .../htmldoxygen/pvaClientPutGet.html | 84 ++++++++++++++++ src/pv/pvaClient.h | 95 ++++++++++--------- 16 files changed, 509 insertions(+), 221 deletions(-) delete mode 100644 documentation/htmldoxygen/pvaClientChannelProcess.html delete mode 100644 documentation/htmldoxygen/pvaClientChannelPut.html delete mode 100644 documentation/htmldoxygen/pvaClientChannelPutGet.html rename documentation/htmldoxygen/{pvaClientChannelGet.html => pvaClientGet.html} (51%) create mode 100644 documentation/htmldoxygen/pvaClientPut.html create mode 100644 documentation/htmldoxygen/pvaClientPutGet.html diff --git a/README.md b/README.md index d664352..d64a0fa 100644 --- a/README.md +++ b/README.md @@ -21,29 +21,3 @@ It can also be built by: edit configure/RELEASE.local make - -Examples ------------- - -Project exampleCPP has examples for pvaClientCPP - -Status ------- - -* The API is for EPICS Version 4 release 4.6.0 -* Everything defined in pvaClient.h is ready but see below for remaining work. -* Everything defined in pvaClientMultiChannel.h is ready but see below for remaining work. - - -pvaClientChannel ---------------- - -Channel::getField and channelArray are not supported for release 4.6 - -pvaClientMultiChannel ---------------- - -For release 4.5 support is available for multiDouble and NTMultiChannel. -In the future additional support should be provided that at least includes NTScalarMultiChannel. - -Testing with some channels not connected has not been done. diff --git a/documentation/RELEASE_NOTES.md b/documentation/RELEASE_NOTES.md index 5d0aa9d..0070a25 100644 --- a/documentation/RELEASE_NOTES.md +++ b/documentation/RELEASE_NOTES.md @@ -1,6 +1,16 @@ EPICS V4 release 4.7 ==================== +Works with release/7.0 of pvDataCPP and release/6.0 of pvAccessCPP +------------------------------------------------------------------ + +Will not work with older versions. + +destroy methods removed +----------------------- + +All the destroy methods are removed since implementation is RAII compliant.s + API changes to PvaClientMonitor ------------------------------- @@ -31,11 +41,6 @@ A new method is also implemented PvaClientMonitorRequesterPtr const & monitorRequester ); -Works with release/6.0 of pvAccessCPP --------------------------------------- - -Not sure this will work with older versions of pvAccessCPP. - EPICS V4 release 4.6 ==================== diff --git a/documentation/htmldoxygen/pvaClient.html b/documentation/htmldoxygen/pvaClient.html index 85a9ed3..315f718 100644 --- a/documentation/htmldoxygen/pvaClient.html +++ b/documentation/htmldoxygen/pvaClient.html @@ -117,6 +117,29 @@ This method is just creates a new PvaClientChannel and returns it to the caller. The caller must call the PvaClientChannel connect methods.

+

Blocking vs Non-Blocking Methods

+

Each component of pvaClient provides a set of blocking and non-blocking calls. +For example several components (examples are PvaClientChannel and PvaChannelGet) +have methods:

+
+
connect
+
+ This calls issueConnect and then waitConnect. + If waitConnect fails an exception is thrown. + Since waitConnect is a blocking method so is this. +
+
issueConnect
+
+ This is a request to connect, i. e. issue a request to the server to create something + on the server. This is a non blocking call. +
+
waitConnect
+
+ This waits for the server to respond to issueConnect. + It blocks until the server responds or a timeout occurs. +
+
+ diff --git a/documentation/htmldoxygen/pvaClientChannel.html b/documentation/htmldoxygen/pvaClientChannel.html index 8ba227e..671b115 100644 --- a/documentation/htmldoxygen/pvaClientChannel.html +++ b/documentation/htmldoxygen/pvaClientChannel.html @@ -35,9 +35,88 @@

PvaClientChannel

+

Overview

-Not Yet Written +pvaClientChannel is a synchronous wrapper for the pvAccess::Channel API, which is a callback based API. +Thus it is easier to use than pvAccess::Channel itself.

+

An instance of PvaClientChannel connects to a single channel. +An instance can only be created via class PvaClient which has both synchronous methods, which block, and non blocking methods. +The synchrouous methods block until a connection is made to the channel and throw an exception if a +timeout occurs while trying to make a connection. +The non blocking methods leave connection to the caller. +

+

PvaClientChannel has methods:

+
+
Connect to channel
+
These can be called indirectly by a blocking request to PvaClient + or by the client if a non blocking request is made to PvaClient. +
+
Channel state change requester
+
The client can provide a callback that is called each time the connection state + of the channel changes. +
+
Creating all of the following
+
+
+PvaClientField      NOT IMPLEMENTED
+PvaClientProcess
+PvaClientGet
+PvaClientPut
+PvaClientPutGet
+PvaClientMonitor
+PvaClientArray      NOT IMPLEMENTED
+PvaClientRPC
+
+
+
+

Connect: Blocking vs Non-Blocking

+

PvaClientChannel has methods:

+
+
connect
+
+ This calls issueConnect and then waitConnect. + If waitConnect fails an exception is thrown. + Since waitConnect is a blocking method so is this. +
+
issueConnect
+
+ This is a request to connect to the channel. This is a non blocking call. +
+
waitConnect
+
+ This waits for the server to respond to issueConnect. + It blocks until the server responds or a timeout occurs. +
+
+ +

Get and Put Caching

+

+PvaClientChannel has methods: +

+
+PvaClientGetPtr get(std::string const & request);
+PvaClientPutPtr put(std::string const & request);
+
+

+Each of these caches. +For example all calls to get with the same request will share the same +PvaChannelGet +

+

+For example consider a client that makes multiple calls like: +

+
+double value;
+value =  pva->channel(channelName)->get()->getData()->getDouble();
+...
+value =  pva->channel(channelName)->get()->getData()->getDouble();
+
+

+Only the first call creates a new PvaClientChannel and a new PvaClientGet. +The second call reuses the cached PvaClientChannel and PvaClientGet. +

+ diff --git a/documentation/htmldoxygen/pvaClientChannelProcess.html b/documentation/htmldoxygen/pvaClientChannelProcess.html deleted file mode 100644 index 70dda71..0000000 --- a/documentation/htmldoxygen/pvaClientChannelProcess.html +++ /dev/null @@ -1,44 +0,0 @@ - - - - - - PvaClientProcess - - - - - - - - -

PvaClientProcess

- -

-Not Yet Written -

- - - - diff --git a/documentation/htmldoxygen/pvaClientChannelPut.html b/documentation/htmldoxygen/pvaClientChannelPut.html deleted file mode 100644 index 882887a..0000000 --- a/documentation/htmldoxygen/pvaClientChannelPut.html +++ /dev/null @@ -1,44 +0,0 @@ - - - - - - PvaClientChannelPut - - - - - - - - -

PvaClientChannelPut

- -

-Not Yet Written -

- - - - diff --git a/documentation/htmldoxygen/pvaClientChannelPutGet.html b/documentation/htmldoxygen/pvaClientChannelPutGet.html deleted file mode 100644 index e8d6aec..0000000 --- a/documentation/htmldoxygen/pvaClientChannelPutGet.html +++ /dev/null @@ -1,44 +0,0 @@ - - - - - - PvaClientPutGet - - - - - - - - -

PvaClientPutGet

- -

-Not Yet Written -

- - - - diff --git a/documentation/htmldoxygen/pvaClientChannelStateChangeRequester.html b/documentation/htmldoxygen/pvaClientChannelStateChangeRequester.html index 48d0ae6..6513646 100644 --- a/documentation/htmldoxygen/pvaClientChannelStateChangeRequester.html +++ b/documentation/htmldoxygen/pvaClientChannelStateChangeRequester.html @@ -35,9 +35,46 @@

PvaClientChannelStateChangeRequester

-

-Not Yet Written +

This class has the single method channelStateChange. +It is called each time the channel connection status changes.

+

+NOTE: +The implementation must not call a method that blocks waiting for a response from the server. +It it does the client may be blocked forever. +

+

+An example of illegal code is: +

+
+virtual void channelStateChange(PvaClientChannelPtr const & channel, bool isConnected)
+{
+    if(isConnected&&!pvaClientPut)
+    {
+       pvaClientPut  = pvaClientChannel->createPut(request);
+       pvaClientPut->connect();
+    }
+}
+
+

+This is illegal because the call to connect blocks. +

+

The following is an example of legal code: +

+
+virtual void channelStateChange(PvaClientChannelPtr const & channel, bool isConnected)
+{
+    if(isConnected&&!pvaClientPut)
+    {
+       pvaClientPut  = pvaClientChannel->createPut(request);
+       pvaClientPut->issueConnect();
+    }
+}
+
+

This is legal code because neither createPut or issueConnect +blocks. +

+ diff --git a/documentation/htmldoxygen/pvaClientChannelGet.html b/documentation/htmldoxygen/pvaClientGet.html similarity index 51% rename from documentation/htmldoxygen/pvaClientChannelGet.html rename to documentation/htmldoxygen/pvaClientGet.html index cab66cb..12984d6 100644 --- a/documentation/htmldoxygen/pvaClientChannelGet.html +++ b/documentation/htmldoxygen/pvaClientGet.html @@ -35,8 +35,38 @@

PvaClientGet

+

-Not Yet Written +pvaClientGet is a synchronous wrapper for the pvAccess::ChannelGet API, which is a callback based API. +Thus it is easier to use than pvAccess::ChannelGet itself. +

+

An instance of PvaClientGet is created via a call to one of the followimg:

+
+class PvaClientChannel
+...
+{
+...
+    PvaClientGetPtr get(std::string const & request = "field(value,alarm,timeStamp)");
+    PvaClientGetPtr createGet(std::string const & request = "");
+    PvaClientGetPtr createGet(epics::pvData::PVStructurePtr const &  pvRequest);
+...
+};
+

An instance of PvaClientGet/b> connects to a single channel. +PvaClientGet has both synchronous methods, which block, and non blocking methods. +

+

PvaClientChannel has methods:

+
+connect             Calls issueConnect and then waitConnect.
+issueConnect        issues a request to the server to create the server side of ChannelPut.
+waitConnect         blocks until server responds that it has created the ChannelPut.
+get                 Calls issueGet and then waitGet.
+issueGet            issues a get request to the server.
+waitGet             waits until the server send a message that the get is complete.
+getData             get the data.
+
+

+Note that issueConnect and issueGet do not block but all other methods +do block.

diff --git a/documentation/htmldoxygen/pvaClientGetData.html b/documentation/htmldoxygen/pvaClientGetData.html index 06ac804..e0926d7 100644 --- a/documentation/htmldoxygen/pvaClientGetData.html +++ b/documentation/htmldoxygen/pvaClientGetData.html @@ -35,9 +35,28 @@

PvaClientGetData

-

-Not Yet Written -

+

This class provides access to the data returned by calls to get data via PvaChannelGet +It provides methods:

+
+getStructure          Get the introspection interface for data returned from server
+getPVStructure        Get the complete set of data returned from the server.
+getChangedBitSet      Get the bitSet that shows which fields have a new value since last get.
+showChanged           Show all the fields that have changed value since the last get,
+getAlarm              If a alarm field is available get it.
+getTimeStamp          If a timeStamp field is available get it.
+hasValue              Does the PVStructure have a top level field named value
+NOTE: The following only apply it hasValue is true.
+isValueScalar         Is the value field a scalar?
+isValueScalarArray    Is the value field a scalar array?
+getValue              Get the value field.
+getScalarValue        Get a scalar value field.
+getArrayValue         Get an array value field.
+getScalarArrayValue   Get a scalar array value field.
+getDouble             Get scalar value field as a double.
+getString             Get value field as a string.
+getDoubleArray        Get value field as a double array.
+getStringArray        Get value field as a string array.
+
diff --git a/documentation/htmldoxygen/pvaClientMonitorData.html b/documentation/htmldoxygen/pvaClientMonitorData.html index 0d8b29b..7ce7710 100644 --- a/documentation/htmldoxygen/pvaClientMonitorData.html +++ b/documentation/htmldoxygen/pvaClientMonitorData.html @@ -4,7 +4,7 @@ - PvaClientMonitotData + PvaClientMonitorData -

PvaClientMonitotData

+

PvaClientMonitorData

-

-Not Yet Written -

+ +

This class provides access to the data returned by calls to get data via PvaChannelGet +It provides methods:

+
+getStructure          Get the introspection interface for data returned from server
+getPVStructure        Get the complete set of data returned from the server.
+getChangedBitSet      Get the bitSet that shows which fields have a new value since last monitor event.
+getOverrunBitSet      Get the bitSet that shows which fields have changed more than once since last monitor event.
+showChanged           Show all the fields that have changed value since the last monitor event,
+showChanged           Show all the fields that have changed value more than once since last monitor event.
+getAlarm              If a alarm field is available get it.
+getTimeStamp          If a timeStamp field is available get it.
+hasValue              Does the PVStructure have a top level field named value
+NOTE: The following only apply it hasValue is true.
+isValueScalar         Is the value field a scalar?
+isValueScalarArray    Is the value field a scalar array?
+getValue              Get the value field.
+getScalarValue        Get a scalar value field.
+getArrayValue         Get an array value field.
+getScalarArrayValue   Get a scalar array value field.
+getDouble             Get scalar value field as a double.
+getString             Get value field as a string.
+getDoubleArray        Get value field as a double array.
+getStringArray        Get value field as a string array.
+
diff --git a/documentation/htmldoxygen/pvaClientProcess.html b/documentation/htmldoxygen/pvaClientProcess.html index 70dda71..9b944f1 100644 --- a/documentation/htmldoxygen/pvaClientProcess.html +++ b/documentation/htmldoxygen/pvaClientProcess.html @@ -36,7 +36,34 @@

PvaClientProcess

-Not Yet Written +pvaClientProcess is a synchronous wrapper for the pvAccess::ChannelProcess API, which is a callback based API. +Thus it is easier to use than pvAccess::ChannelProcess itself. +

+

An instance of PvaClientProcess is created via a call to one of the followimg:

+
+class PvaClientChannel
+...
+{
+...
+    PvaClientProcessPtr createProcess(std::string const & request = "");
+    PvaClientProcessPtr createProcess(epics::pvData::PVStructurePtr const &  pvRequest);
+...
+};
+

An instance of PvaClientProcess/b> connects to a single channel. +PvaClientProcess has both synchronous methods, which block, and non blocking methods. +

+

PvaClientChannel has methods:

+
+connect             Calls issueConnect and then waitConnect.
+issueConnect        issues a request to the server to create the server side of ChannelPut.
+waitConnect         blocks until server responds that it has created the ChannelPut.
+process             Calls issueProcess and then waitProcess.
+issueProcess        issues a process request to the server.
+waitProcess         waits until the server send a message that the process is complete.
+
+

+Note that issueConnect and issueProcess do not block but all other methods +do block.

diff --git a/documentation/htmldoxygen/pvaClientPut.html b/documentation/htmldoxygen/pvaClientPut.html new file mode 100644 index 0000000..7fef373 --- /dev/null +++ b/documentation/htmldoxygen/pvaClientPut.html @@ -0,0 +1,82 @@ + + + + + + PvaClientChannelPut + + + + + + + + +

PvaClientChannelPut

s + +

+pvaClientPut is a synchronous wrapper for the pvAccess::ChannelPut API, which is a callback based API. +Thus it is easier to use than pvAccess::ChannelPut itself. +

+

+NOTE: +Except for union fields pvaClientPut takes care of modifying the bitSet associated with +the data sent to the server. +

+

An instance of PvaClientPut is created via a call to one of the followimg:

+
+class PvaClientChannel
+...
+{
+...
+    PvaClientPutPtr put(std::string const & request = "field(value,alarm,timeStamp)");
+    PvaClientPutPtr createPut(std::string const & request = "");
+    PvaClientPutPtr createPut(epics::pvData::PVStructurePtr const &  pvRequest);
+...
+};
+

An instance of PvaClientPut/b> connects to a single channel. +PvaClientPut has both synchronous methods, which block, and non blocking methods. +

+

PvaClientPut has methods:

+
+connect             Calls issueConnect and then waitConnect.
+issueConnect        issues a request to the server to create the server side of ChannelPut.
+waitConnect         blocks until server responds that it has created the ChannelPut.
+get                 Calls issueGet and then waitGet.
+issueGet            issues a request to the server to get the latest data.
+waitGet             waits until the server send a message that the get is complete.
+put                 Calls issuePut and then waitPut.
+issuePut            issues a put request to the server.
+waitPut             waits until the server send a message that the put is complete.
+getData             get the data.
+
+

+Note that issueConnect, issueGet and issuePut do not block but all other methods +do block. +

+ + + + + diff --git a/documentation/htmldoxygen/pvaClientPutData.html b/documentation/htmldoxygen/pvaClientPutData.html index c51d21c..c4e2869 100644 --- a/documentation/htmldoxygen/pvaClientPutData.html +++ b/documentation/htmldoxygen/pvaClientPutData.html @@ -35,10 +35,41 @@

PvaClientPutData

+

This class provides access to data to send to the server via a PvaChannelPut +It is created by PvaChannelPut or PvaChannelPutGet. +This the client only gets access to an instance by getting it from PvaChannelPut or PvaChannelPutGet.

-Not Yet Written +

Note also that for all field types except union the BitSet for the data is updated +by PvaChannelPut or PvaChannelPutGet whenever the client changes a field. +For a union or unionArray field the client must update the BitSet.

+

+PvaClientPutData provides methods:

+
+getStructure          Get the introspection interface for data sent to server
+getPVStructure        Get the complete set of data sent to the server.
+getChangedBitSet      Get the bitSet that shows which fields have a new value since last get.
+showChanged           Show all the fields that have changed value since the last get,
+getAlarm              If a alarm field is available get it.
+getTimeStamp          If a timeStamp field is available get it.
+hasValue              Does the PVStructure have a top level field named value
+NOTE: The following only apply it hasValue is true.
+isValueScalar         Is the value field a scalar?
+isValueScalarArray    Is the value field a scalar array?
+getValue              Get the value field.
+getScalarValue        Get a scalar value field.
+getArrayValue         Get an array value field.
+getScalarArrayValue   Get a scalar array value field.
+getDouble             Get scalar value field as a double.
+getString             Get value field as a string.
+getDoubleArray        Get value field as a double array.
+getStringArray        Get value field as a string array.
+putDouble             Put scalar value field as a double.
+putString             Put value field as a string.
+putDoubleArray        Put value field as a double array.
+putStringArray        Put value field as a string array.
+
diff --git a/documentation/htmldoxygen/pvaClientPutGet.html b/documentation/htmldoxygen/pvaClientPutGet.html new file mode 100644 index 0000000..d0d11d8 --- /dev/null +++ b/documentation/htmldoxygen/pvaClientPutGet.html @@ -0,0 +1,84 @@ + + + + + + PvaClientPutGetGet + + + + + + + + +

PvaClientPutGetGet

+ +

+pvaClientPutGet is a synchronous wrapper for the pvAccess::ChannelPutGet API, which is a callback based API. +Thus it is easier to use than pvAccess::ChannelPut itself. +

+

+NOTE: +Except for union fields pvaClientPutGet takes care of modifying the bitSet associated with +the data sent to the server. +

+

An instance of PvaClientPutGet is created via a call to one of the followimg:

+
+class PvaClientChannel
+...
+{
+...
+    PvaClientPutGetPtr createPutGet(std::string const & request);
+    PvaClientPutGetPtr createPutGet(epics::pvData::PVStructurePtr const &  pvRequest);
+...
+};
+

An instance of PvaClientPutGet/b> connects to a single channel. +PvaClientPutGet has both synchronous methods, which block, and non blocking methods. +

+

PvaClientPutGet has methods:

+
+connect             calls issueConnect and then waitConnect.
+issueConnect        issues a request to the server to create the server side of ChannelPut.
+waitConnect         blocks until server responds that it has created the ChannelPut.
+putGet              call issuePutGet and then waitPutGet.
+issuePutGet         issue a putGet and return immediately.
+waitPutGet          wait until putGet completes.
+getGet              calls issueGetGet and then waitGetGet.
+issueGetGet         issues a request to the server to get the latest data for the get data.
+waitGetGet          waits until the server send a message that the getGet is complete.
+getPut              calls issueGetPut and then waitGetPut.
+issueGetPut         issues a request to the server to get the latest data for the put data.
+waitGetPut          waits until the server send a message that the getPut is complete.
+getPutData          get the put portion of the data.
+getGetData          get the get portion of the data.
+
+

+Note that issueConnect, issuePutGet, issueGetGet and issueGetPut do not block but all other methods block. +

+ + + + + diff --git a/src/pv/pvaClient.h b/src/pv/pvaClient.h index ef12d31..f332019 100644 --- a/src/pv/pvaClient.h +++ b/src/pv/pvaClient.h @@ -187,7 +187,7 @@ typedef std::tr1::shared_ptr PvaClientPutCachePtr; /** * @brief A callback for change in connection status. * - * Overview of PvaClientChannelStateChangeRequesterOverview of PvaClientChannelStateChangeRequester * */ class PvaClientChannelStateChangeRequester @@ -200,6 +200,8 @@ public: virtual ~PvaClientChannelStateChangeRequester(){} /** * @brief A channel connection state change has occurred. + * + * Warning A call to a method that blocks should not be made by this method. * @param channel The channel. * @param isConnected The new connection status. */ @@ -222,12 +224,18 @@ public: * @brief Destructor */ ~PvaClientChannel(); + /** @brief Set a client stateChangeRequester. + * + * @param stateChangeRequester The client stateChangeRequester implementation. + */ void setStateChangeRequester(PvaClientChannelStateChangeRequesterPtr const &stateChangeRequester); /** @brief Get the name of the channel to which PvaClientChannel is connected. + * * @return The channel name. */ std::string getChannelName(); /** @brief Get the the channel to which PvaClientChannel is connected. + * * @return The channel interface. */ epics::pvAccess::Channel::shared_pointer getChannel(); @@ -239,50 +247,53 @@ public: */ void connect(double timeout=5.0); /** @brief Issue a connect request and return immediately. + * */ void issueConnect(); /** @brief Wait until the connection completes or for timeout. + * * @param timeout The time in seconds to wait. A value of 0 means forever. * @return status. - * @throw runtime_error if failure. */ epics::pvData::Status waitConnect(double timeout = 5.0); /** @brief Create a PvaClientField for the specified subField. + * * @param subField The desired subField, i. e. "field.field...." * An empty string, i. e. "", asks for the entire top level struture as defined by the server. * @return The interface. */ PvaClientFieldPtr createField(std::string const & subField = ""); /** @brief First call createRequest as implemented by pvDataCPP and then call the next method. + * * @param request The syntax of request is defined by the copy facility of pvData. * @return The interface. * @throw runtime_error if failure. */ PvaClientProcessPtr createProcess(std::string const & request = ""); - /** Creates an PvaClientProcess. + /** Creates a PvaClientProcess. + * * @param pvRequest The syntax of pvRequest is defined by the copy facility of pvData. * @return The interface. * @throw runtime_error if failure. */ PvaClientProcessPtr createProcess(epics::pvData::PVStructurePtr const & pvRequest); - /** @brief Get a cached PvaClientGet or create and connect to a new PvaClientGet. + /** @brief create a PvaChannelGet * - * If connection can not be made an exception is thrown. - * @param request The syntax of request is defined by the copy facility of pvData. + * Get a cached PvaClientGet or create and connect to a new PvaClientGet. * @return The interface. * @throw runtime_error if failure. */ PvaClientGetPtr get(std::string const & request = "field(value,alarm,timeStamp)"); /** @brief create a PvaClientGet. * - * First call createRequest as implemented by pvDataJava and then call the next method. - * Then get a cached PvaClientGet or create and connect to a new PvaClientGet. + * First call createRequest as implemented by pvData and then call the next method. * @param request The syntax of request is defined by the copy facility of pvData. * @return The interface. * @throw runtime_error if failure. */ PvaClientGetPtr createGet(std::string const & request = "field(value,alarm,timeStamp)"); /** @brief Creates an PvaClientGet. + * * @param pvRequest The syntax of pvRequest is defined by the copy facility of pvData. * @return The interface. * @throw runtime_error if failure. @@ -290,8 +301,7 @@ public: PvaClientGetPtr createGet(epics::pvData::PVStructurePtr const & pvRequest); /** @brief create a PvaClientPut. * - * First call createRequest as implemented by pvDataJava. - * Then get a cached PvaClientPut or create and connect to a new PvaClientPut. + * Get a cached PvaClientPut or create and connect to a new PvaClientPut. * Then call it's get method. * @param request The syntax of request is defined by the copy facility of pvData. * @return The interface. @@ -307,6 +317,7 @@ public: */ PvaClientPutPtr createPut(std::string const & request = "field(value)"); /** @brief Create a PvaClientPut. + * * @param pvRequest The syntax of pvRequest is defined by the copy facility of pvData. * @return The interface. */ @@ -321,6 +332,7 @@ public: PvaClientPutGetPtr createPutGet( std::string const & request = "putField(argument)getField(result)"); /** @brief Create a PvaClientPutGet. + * * @param pvRequest The syntax of pvRequest is defined by the copy facility of pvData. * @return The interface. */ @@ -350,6 +362,7 @@ public: */ PvaClientMonitorPtr monitor(std::string const & request = "field(value,alarm,timeStamp)"); /** @brief Call the next method with request = "field(value,alarm,timeStamp)" + * * @param pvaClientMonitorRequester The client callback. * @return The interface. * @throw runtime_error if failure. @@ -368,7 +381,8 @@ public: std::string const & request, PvaClientMonitorRequesterPtr const & pvaClientMonitorRequester); /** - * @brief First call createRequest as implemented by pvDataJava and then calls the next method. + * @brief 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. * @return The interface. * @throw runtime_error if failure. @@ -377,11 +391,13 @@ public: std::string const & request = "field(value,alarm,timeStamp)"); /** Create an PvaClientMonitor. * @param pvRequest The syntax of pvRequest is defined by the copy facility of pvData. + * * @return The interface. * @throw runtime_error if failure. */ PvaClientMonitorPtr createMonitor(epics::pvData::PVStructurePtr const & pvRequest); /** @brief Issue a channelRPC request + * * @param pvRequest The pvRequest that is passed to createRPC. * @param pvArgument The argument for a request. * @return The result. @@ -391,6 +407,7 @@ public: epics::pvData::PVStructurePtr const & pvRequest, epics::pvData::PVStructurePtr const & pvArgument); /** @brief Issue a channelRPC request + * * @param pvArgument The argument for the request. * @return The result. * @throw runtime_error if failure. @@ -398,11 +415,13 @@ public: epics::pvData::PVStructurePtr rpc( epics::pvData::PVStructurePtr const & pvArgument); /** @brief Create a PvaClientRPC. + * * @return The interface. * @throw runtime_error if failure. */ PvaClientRPCPtr createRPC(); /** @brief Create a PvaClientRPC. + * * @param pvRequest The pvRequest that must have the same interface * as a pvArgument that is passed to an rpc request. * @return The interface. @@ -415,10 +434,6 @@ public: /** @brief Get the number of cached gets and puts. */ size_t cacheSize(); - /** Deprecated method - * \deprecated This method will go away in future versions. - */ - void destroy() EPICS_DEPRECATED {} private: static PvaClientChannelPtr create( PvaClientPtr const &pvaClient, @@ -477,11 +492,13 @@ public: */ void setMessagePrefix(std::string const & value); /** @brief Get the structure. + * * @return The Structure * @throw runtime_error if failure. */ epics::pvData::StructureConstPtr getStructure(); /** @brief Get the pvStructure. + * * @return the pvStructure. * @throw runtime_error if failure. */ @@ -494,6 +511,7 @@ public: */ epics::pvData::BitSetPtr getChangedBitSet(); /** @brief Show the fields that have changed value since the last get. + * * @param out The stream that shows the changed fields. * @return The stream that was passed as out. */ @@ -610,36 +628,43 @@ public: */ ~PvaClientPutData() {} /** @brief Set a prefix for throw messages. + * * @param value The prefix. */ void setMessagePrefix(std::string const & value); /** @brief Get the structure. - * @return The Structure - * @throw runtime_error if failure. - */ - epics::pvData::StructureConstPtr getStructure(); + * + * @return The Structure + * @throw runtime_error if failure. + */ + epics::pvData::StructureConstPtr getStructure(); /** @brief Get the pvStructure. + * * @return the pvStructure. * @throw runtime_error if failure. */ epics::pvData::PVStructurePtr getPVStructure(); /** @brief Get the changed BitSet for the pvStructure + * * This shows which fields have changed values. * @return The bitSet * @throw runtime_error if failure. */ epics::pvData::BitSetPtr getChangedBitSet(); /** @brief Show the fields that have changed values. + * * @param out The stream that shows the changed fields. * @return The stream that was passed as out. */ std::ostream & showChanged(std::ostream & out); /** * @brief Is there a top level field named value. + * * @return The answer. */ bool hasValue(); /** @brief Is the value field a scalar? + * * @return The answer. */ bool isValueScalar(); @@ -648,10 +673,12 @@ public: */ bool isValueScalarArray(); /** Get the interface to the value field. + * * @return The interface. an excetion is thrown if a value field does not exist. */ epics::pvData::PVFieldPtr getValue(); /** @brief Get the interface to a scalar value field. + * * @return The interface for a scalar value field. * @throw runtime_error if failure. */ @@ -896,7 +923,7 @@ typedef std::tr1::shared_ptr ChannelProcessRequeste /** * @brief An easy to use alternative to ChannelProcess. * - * Overview of PvaClientChannelProcess + * Overview of PvaClientProcess */ class epicsShareClass PvaClientProcess { @@ -936,17 +963,13 @@ public: * An exception is thrown if get fails. */ void process(); - /** @brief Issue a process and return immediately. + /** @brief Issue a process request and return immediately. */ void issueProcess(); /** @brief Wait until process completes. * @return status. */ epics::pvData::Status waitProcess(); - /** Deprecated method - * \deprecated This method will go away in future versions. - */ - void destroy() EPICS_DEPRECATED {} private: std::string getRequesterName(); void message(std::string const & message,epics::pvData::MessageType messageType); @@ -990,7 +1013,7 @@ typedef std::tr1::shared_ptr ChannelGetRequesterImplPtr /** * @brief An easy to use alternative to ChannelGet. * - * Overview of PvaClientChannelGet + * Overview of PvaClientGet */ class epicsShareClass PvaClientGet { @@ -1042,10 +1065,6 @@ public: * @return The interface. */ PvaClientGetDataPtr getData(); - /** Deprecated method - * \deprecated This method will go away in future versions. - */ - void destroy() EPICS_DEPRECATED {} private: std::string getRequesterName(); void message(std::string const & message,epics::pvData::MessageType messageType); @@ -1097,7 +1116,7 @@ typedef std::tr1::shared_ptr ChannelPutRequesterImplPtr /** * @brief An easy to use alternative to ChannelPut. * - * Overview of PvaClientChannelPut + * Overview of PvaClientPut */ class epicsShareClass PvaClientPut { @@ -1162,10 +1181,6 @@ public: * @return The interface. */ PvaClientPutDataPtr getData(); - /** Deprecated method - * \deprecated This method will go away in future versions. - */ - void destroy() EPICS_DEPRECATED {} private : std::string getRequesterName(); void message(std::string const & message,epics::pvData::MessageType messageType); @@ -1216,7 +1231,7 @@ typedef std::tr1::shared_ptr ChannelPutGetRequesterI /** * @brief An easy to use alternative to ChannelPutGet. * - * Overview of PvaClientChannelPutGet + * Overview of PvaClientPutGet */ class epicsShareClass PvaClientPutGet { @@ -1300,10 +1315,6 @@ public: * @return The interface. */ PvaClientGetDataPtr getGetData(); - /** Deprecated method - * \deprecated This method will go away in future versions. - */ - void destroy() EPICS_DEPRECATED {} private : std::string getRequesterName(); void message(std::string const & message,epics::pvData::MessageType messageType); @@ -1488,10 +1499,6 @@ public: * @return The interface. */ PvaClientMonitorDataPtr getData(); - /** Deprecated method - * \deprecated This method will go away in future versions. - */ - void destroy() EPICS_DEPRECATED {} private: std::string getRequesterName(); void message(std::string const & message,epics::pvData::MessageType messageType); From 9b1539f3685b42d7a41f7f4cb6cc327d5531cd00 Mon Sep 17 00:00:00 2001 From: mrkraimer Date: Wed, 12 Jul 2017 06:38:55 -0400 Subject: [PATCH 09/12] more work on doxygen --- documentation/RELEASE_NOTES.md | 2 +- documentation/htmldoxygen/pvaClientGet.html | 14 ++++---- .../htmldoxygen/pvaClientGetData.html | 2 +- .../htmldoxygen/pvaClientMonitorData.html | 2 +- .../htmldoxygen/pvaClientProcess.html | 10 +++--- .../htmldoxygen/pvaClientPutData.html | 8 ++--- .../htmldoxygen/pvaClientPutGet.html | 9 +++--- src/pv/pvaClient.h | 1 - src/pv/pvaClientMultiChannel.h | 32 ------------------- 9 files changed, 24 insertions(+), 56 deletions(-) diff --git a/documentation/RELEASE_NOTES.md b/documentation/RELEASE_NOTES.md index 0070a25..628422d 100644 --- a/documentation/RELEASE_NOTES.md +++ b/documentation/RELEASE_NOTES.md @@ -9,7 +9,7 @@ Will not work with older versions. destroy methods removed ----------------------- -All the destroy methods are removed since implementation is RAII compliant.s +All the destroy methods are removed since implementation is RAII compliant. API changes to PvaClientMonitor ------------------------------- diff --git a/documentation/htmldoxygen/pvaClientGet.html b/documentation/htmldoxygen/pvaClientGet.html index 12984d6..0845e92 100644 --- a/documentation/htmldoxygen/pvaClientGet.html +++ b/documentation/htmldoxygen/pvaClientGet.html @@ -40,18 +40,18 @@ pvaClientGet is a synchronous wrapper for the pvAccess::ChannelGet API, which is a callback based API. Thus it is easier to use than pvAccess::ChannelGet itself.

-

An instance of PvaClientGet is created via a call to one of the followimg:

+

An instance of PvaClientGet is created via a call to one of the following:

 class PvaClientChannel
 ...
 {
 ...
-    PvaClientGetPtr get(std::string const & request = "field(value,alarm,timeStamp)");
-    PvaClientGetPtr createGet(std::string const & request = "");
-    PvaClientGetPtr createGet(epics::pvData::PVStructurePtr const &  pvRequest);
+    PvaClientGetPtr get(std::string const & request = "field(value,alarm,timeStamp)");
+    PvaClientGetPtr createGet(std::string const & request = "");
+    PvaClientGetPtr createGet(epics::pvData::PVStructurePtr const &  pvRequest);
 ...
 };
-

An instance of PvaClientGet/b> connects to a single channel. +

An instance of PvaClientGet connects to a single channel. PvaClientGet has both synchronous methods, which block, and non blocking methods.

PvaClientChannel has methods:

@@ -65,8 +65,8 @@ waitGet waits until the server send a message that the get is comple getData get the data.

-Note that issueConnect and issueGet do not block but all other methods -do block. +issueConnect and issueGet do not block. +All other methods can block.

diff --git a/documentation/htmldoxygen/pvaClientGetData.html b/documentation/htmldoxygen/pvaClientGetData.html index e0926d7..8625301 100644 --- a/documentation/htmldoxygen/pvaClientGetData.html +++ b/documentation/htmldoxygen/pvaClientGetData.html @@ -45,7 +45,7 @@ showChanged Show all the fields that have changed value since the last getAlarm If a alarm field is available get it. getTimeStamp If a timeStamp field is available get it. hasValue Does the PVStructure have a top level field named value -NOTE: The following only apply it hasValue is true. +NOTE: The following only apply if hasValue is true. isValueScalar Is the value field a scalar? isValueScalarArray Is the value field a scalar array? getValue Get the value field. diff --git a/documentation/htmldoxygen/pvaClientMonitorData.html b/documentation/htmldoxygen/pvaClientMonitorData.html index 7ce7710..1b76f83 100644 --- a/documentation/htmldoxygen/pvaClientMonitorData.html +++ b/documentation/htmldoxygen/pvaClientMonitorData.html @@ -48,7 +48,7 @@ showChanged Show all the fields that have changed value more than once getAlarm If a alarm field is available get it. getTimeStamp If a timeStamp field is available get it. hasValue Does the PVStructure have a top level field named value -NOTE: The following only apply it hasValue is true. +NOTE: The following only apply if hasValue is true. isValueScalar Is the value field a scalar? isValueScalarArray Is the value field a scalar array? getValue Get the value field. diff --git a/documentation/htmldoxygen/pvaClientProcess.html b/documentation/htmldoxygen/pvaClientProcess.html index 9b944f1..b1de4f2 100644 --- a/documentation/htmldoxygen/pvaClientProcess.html +++ b/documentation/htmldoxygen/pvaClientProcess.html @@ -45,11 +45,11 @@ class PvaClientChannel ... { ... - PvaClientProcessPtr createProcess(std::string const & request = ""); - PvaClientProcessPtr createProcess(epics::pvData::PVStructurePtr const & pvRequest); + PvaClientProcessPtr createProcess(std::string const & request = ""); + PvaClientProcessPtr createProcess(epics::pvData::PVStructurePtr const & pvRequest); ... }; -

An instance of PvaClientProcess/b> connects to a single channel. +

An instance of PvaClientProcess connects to a single channel. PvaClientProcess has both synchronous methods, which block, and non blocking methods.

PvaClientChannel has methods:

@@ -62,8 +62,8 @@ issueProcess issues a process request to the server. waitProcess waits until the server send a message that the process is complete.

-Note that issueConnect and issueProcess do not block but all other methods -do block. +issueConnect and issueProcess do not block. +All other methods can block.

diff --git a/documentation/htmldoxygen/pvaClientPutData.html b/documentation/htmldoxygen/pvaClientPutData.html index c4e2869..09cff35 100644 --- a/documentation/htmldoxygen/pvaClientPutData.html +++ b/documentation/htmldoxygen/pvaClientPutData.html @@ -36,11 +36,11 @@

PvaClientPutData

This class provides access to data to send to the server via a PvaChannelPut -It is created by PvaChannelPut or PvaChannelPutGet. -This the client only gets access to an instance by getting it from PvaChannelPut or PvaChannelPutGet. +It is created by PvaChannelPut or PvaChannelPutGet. +This the client only gets access to an instance by getting it from PvaChannelPut or PvaChannelPutGet.

Note also that for all field types except union the BitSet for the data is updated -by PvaChannelPut or PvaChannelPutGet whenever the client changes a field. +by PvaChannelPut or PvaChannelPutGet whenever the client changes a field. For a union or unionArray field the client must update the BitSet.

@@ -54,7 +54,7 @@ showChanged Show all the fields that have changed value since the last getAlarm If a alarm field is available get it. getTimeStamp If a timeStamp field is available get it. hasValue Does the PVStructure have a top level field named value -NOTE: The following only apply it hasValue is true. +NOTE: The following only apply if hasValue is true. isValueScalar Is the value field a scalar? isValueScalarArray Is the value field a scalar array? getValue Get the value field. diff --git a/documentation/htmldoxygen/pvaClientPutGet.html b/documentation/htmldoxygen/pvaClientPutGet.html index d0d11d8..f0db3bf 100644 --- a/documentation/htmldoxygen/pvaClientPutGet.html +++ b/documentation/htmldoxygen/pvaClientPutGet.html @@ -50,11 +50,11 @@ class PvaClientChannel ... { ... - PvaClientPutGetPtr createPutGet(std::string const & request); - PvaClientPutGetPtr createPutGet(epics::pvData::PVStructurePtr const & pvRequest); + PvaClientPutGetPtr createPutGet(std::string const & request); + PvaClientPutGetPtr createPutGet(epics::pvData::PVStructurePtr const & pvRequest); ... }; -

An instance of PvaClientPutGet/b> connects to a single channel. +

An instance of PvaClientPutGet connects to a single channel. PvaClientPutGet has both synchronous methods, which block, and non blocking methods.

PvaClientPutGet has methods:

@@ -75,7 +75,8 @@ getPutData get the put portion of the data. getGetData get the get portion of the data.

-Note that issueConnect, issuePutGet, issueGetGet and issueGetPut do not block but all other methods block. +issueConnect, issuePutGet, issueGetGet and issueGetPut do not block. +All other methods can block.

diff --git a/src/pv/pvaClient.h b/src/pv/pvaClient.h index f332019..cbb3b57 100644 --- a/src/pv/pvaClient.h +++ b/src/pv/pvaClient.h @@ -17,7 +17,6 @@ #include #include -#include #include #include #include diff --git a/src/pv/pvaClientMultiChannel.h b/src/pv/pvaClientMultiChannel.h index ffaff18..c58ad7a 100644 --- a/src/pv/pvaClientMultiChannel.h +++ b/src/pv/pvaClientMultiChannel.h @@ -145,10 +145,6 @@ public: */ PvaClientNTMultiMonitorPtr createNTMonitor( std::string const &request= "field(value,alarm,timeStamp)"); - /** Deprecated method - * \deprecated This method will go away in future versions. - */ - void destroy() EPICS_DEPRECATED {} private: PvaClientMultiChannel( PvaClientPtr const &pvaClient, @@ -209,10 +205,6 @@ public: { return shared_from_this(); } - /** Deprecated method - * \deprecated This method will go away in future versions. - */ - void destroy() EPICS_DEPRECATED {} private: PvaClientMultiGetDouble( PvaClientMultiChannelPtr const &pvaClientMultiChannel, @@ -262,10 +254,6 @@ public: { return shared_from_this(); } - /** Deprecated method - * \deprecated This method will go away in future versions. - */ - void destroy() EPICS_DEPRECATED {} private: PvaClientMultiPutDouble( PvaClientMultiChannelPtr const &pvaClientMultiChannel, @@ -329,10 +317,6 @@ public: { return shared_from_this(); } - /** Deprecated method - * \deprecated This method will go away in future versions. - */ - void destroy() EPICS_DEPRECATED {} private: PvaClientMultiMonitorDouble( PvaClientMultiChannelPtr const &pvaClientMultiChannel, @@ -390,10 +374,6 @@ public: { return shared_from_this(); } - /** Deprecated method - * \deprecated This method will go away in future versions. - */ - void destroy() EPICS_DEPRECATED {} private: PvaClientNTMultiGet( epics::pvData::UnionConstPtr const & u, @@ -453,10 +433,6 @@ public: { return shared_from_this(); } - /** Deprecated method - * \deprecated This method will go away in future versions. - */ - void destroy() EPICS_DEPRECATED {} private: PvaClientNTMultiPut( PvaClientMultiChannelPtr const &pvaClientMultiChannel, @@ -523,10 +499,6 @@ public: { return shared_from_this(); } - /** Deprecated method - * \deprecated This method will go away in future versions. - */ - void destroy() EPICS_DEPRECATED {} private: PvaClientNTMultiMonitor( epics::pvData::UnionConstPtr const & u, @@ -601,10 +573,6 @@ public: { return shared_from_this(); } - /** Deprecated method - * \deprecated This method will go away in future versions. - */ - void destroy() EPICS_DEPRECATED {} private: PvaClientNTMultiData( epics::pvData::UnionConstPtr const & u, From d7bf6a8910244be3229082f14212ead9a6ca4c8e Mon Sep 17 00:00:00 2001 From: mrkraimer Date: Fri, 14 Jul 2017 15:16:49 -0400 Subject: [PATCH 10/12] add nowait support to pvaClientGet, pvaClientPut, pvaClientMonitor --- .../htmldoxygen/pvaClientGetRequester.html | 44 +++++ .../htmldoxygen/pvaClientPutRequester.html | 44 +++++ src/pv/pvaClient.h | 168 ++++++++++++++++-- src/pvaClientChannel.cpp | 4 +- src/pvaClientGet.cpp | 147 +++++++++------ src/pvaClientMonitor.cpp | 9 +- src/pvaClientPut.cpp | 168 +++++++++++------- 7 files changed, 444 insertions(+), 140 deletions(-) create mode 100644 documentation/htmldoxygen/pvaClientGetRequester.html create mode 100644 documentation/htmldoxygen/pvaClientPutRequester.html 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; +} }} From 932d90ff7034961c72783724180114632a2f5489 Mon Sep 17 00:00:00 2001 From: mrkraimer Date: Tue, 18 Jul 2017 06:01:53 -0400 Subject: [PATCH 11/12] minor changes --- src/Makefile | 2 +- src/pv/pvaClient.h | 3 +- src/pvaClientGet.cpp | 63 ++++++++++++++++++++++++++++++++++++-- src/pvaClientMonitor.cpp | 66 ++++++++++++++++++++++++---------------- src/pvaClientPut.cpp | 46 +++++++++++++++++++++++++--- 5 files changed, 143 insertions(+), 37 deletions(-) diff --git a/src/Makefile b/src/Makefile index 7e945c7..ffa1083 100644 --- a/src/Makefile +++ b/src/Makefile @@ -31,7 +31,7 @@ LIBSRCS += pvaClientNTMultiGet.cpp LIBSRCS += pvaClientNTMultiMonitor.cpp LIBSRCS += pvaClientRPC.cpp -pvaClient_LIBS += pvAccess nt pvData Com +pvaClient_LIBS += pvAccessCA pvAccess nt pvData Com pvaClient_LIBS += $(EPICS_BASE_IOC_LIBS) include $(TOP)/configure/RULES diff --git a/src/pv/pvaClient.h b/src/pv/pvaClient.h index 560a5a2..53e8cbd 100644 --- a/src/pv/pvaClient.h +++ b/src/pv/pvaClient.h @@ -17,6 +17,7 @@ #include #include +#include #include #include #include @@ -1666,7 +1667,7 @@ private: PvaClientMonitorDataPtr pvaClientData; bool isStarted; - epics::pvData::Status connectStatus; + epics::pvData::Status monitorConnectStatus; epics::pvData::MonitorPtr monitor; epics::pvData::MonitorElementPtr monitorElement; diff --git a/src/pvaClientGet.cpp b/src/pvaClientGet.cpp index b5386d0..83b964b 100644 --- a/src/pvaClientGet.cpp +++ b/src/pvaClientGet.cpp @@ -76,6 +76,12 @@ PvaClientGetPtr PvaClientGet::create( PvaClientChannelPtr const & pvaClientChannel, PVStructurePtr const &pvRequest) { + if(PvaClient::getDebug()) { + cout<< "PvaClientGet::create(pvaClient,channelName,providerName,pvRequest)\n" + << " channelName " << pvaClientChannel->getChannel()->getChannelName() + << " pvRequest " << pvRequest + << endl; + } PvaClientGetPtr clientGet(new PvaClientGet(pvaClient,pvaClientChannel,pvRequest)); clientGet->channelGetRequester = ChannelGetRequesterImplPtr( new ChannelGetRequesterImpl(clientGet,pvaClient)); @@ -159,12 +165,25 @@ void PvaClientGet::channelStateChange(PvaClientChannelPtr const & pvaClientChann void PvaClientGet::checkGetState() { + if(PvaClient::getDebug()) { + cout << "PvaClientGet::checkGetState" + << " channelName " << pvaClientChannel->getChannel()->getChannelName() + << endl; + } 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(connectState==connectIdle) { + connect(); + } + if(connectState==connectActive){ + string message = string("channel ") + pvaClientChannel->getChannel()->getChannelName() + + " " + + channelGetConnectStatus.getMessage(); + throw std::runtime_error(message); + } if(getState==getIdle) get(); } @@ -196,12 +215,19 @@ void PvaClientGet::channelGetConnect( } { Lock xx(mutex); - channelGetConnectStatus = status; - connectState = connected; this->channelGet = channelGet; if(status.isOK()) { + channelGetConnectStatus = status; + connectState = connected; pvaClientData = PvaClientGetData::create(structure); pvaClientData->setMessagePrefix(channelGet->getChannel()->getChannelName()); + } else { + stringstream ss; + ss << pvRequest; + string message = string("\nPvaClientGet::channelGetConnect)") + + "\npvRequest\n" + ss.str() + + "\nerror\n" + status.getMessage(); + channelGetConnectStatus = Status(Status::STATUSTYPE_ERROR,message); } } PvaClientGetRequesterPtr req(pvaClientGetRequester.lock()); @@ -240,6 +266,11 @@ void PvaClientGet::getDone( void PvaClientGet::connect() { + if(PvaClient::getDebug()) { + cout << "PvaClientGet::connect" + << " channelName " << pvaClientChannel->getChannel()->getChannelName() + << endl; + } issueConnect(); Status status = waitConnect(); if(status.isOK()) return; @@ -250,17 +281,28 @@ void PvaClientGet::connect() void PvaClientGet::issueConnect() { + if(PvaClient::getDebug()) { + cout << "PvaClientGet::issueConnect" + << " channelName " << pvaClientChannel->getChannel()->getChannelName() + << endl; + } if(connectState!=connectIdle) { string message = string("channel ") + pvaClientChannel->getChannel()->getChannelName() + " pvaClientGet already connected "; throw std::runtime_error(message); } connectState = connectActive; + channelGetConnectStatus = Status(Status::STATUSTYPE_ERROR, "connect active"); channelGet = pvaClientChannel->getChannel()->createChannelGet(channelGetRequester,pvRequest); } Status PvaClientGet::waitConnect() { + if(PvaClient::getDebug()) { + cout << "PvaClientGet::waitConnect" + << " channelName " << pvaClientChannel->getChannel()->getChannelName() + << endl; + } { Lock xx(mutex); if(connectState==connected) { @@ -280,6 +322,11 @@ Status PvaClientGet::waitConnect() void PvaClientGet::get() { + if(PvaClient::getDebug()) { + cout << "PvaClientGet::get" + << " channelName " << pvaClientChannel->getChannel()->getChannelName() + << endl; + } issueGet(); Status status = waitGet(); if(status.isOK()) return; @@ -290,6 +337,11 @@ void PvaClientGet::get() void PvaClientGet::issueGet() { + if(PvaClient::getDebug()) { + cout << "PvaClientGet::issueGet" + << " channelName " << pvaClientChannel->getChannel()->getChannelName() + << endl; + } if(connectState==connectIdle) connect(); if(getState==getActive) { string message = string("channel ") + pvaClientChannel->getChannel()->getChannelName() @@ -302,6 +354,11 @@ void PvaClientGet::issueGet() Status PvaClientGet::waitGet() { + if(PvaClient::getDebug()) { + cout << "PvaClientGet::waitGet" + << " channelName " << pvaClientChannel->getChannel()->getChannelName() + << endl; + } { Lock xx(mutex); if(getState==getComplete) { diff --git a/src/pvaClientMonitor.cpp b/src/pvaClientMonitor.cpp index db2b68b..33088ca 100644 --- a/src/pvaClientMonitor.cpp +++ b/src/pvaClientMonitor.cpp @@ -187,8 +187,17 @@ void PvaClientMonitor::checkMonitorState() << " connectState " << connectState << endl; } - if(connectState==connectIdle) connect(); - if(connectState==connected && !isStarted) start(); + if(connectState==connectIdle) { + connect(); + if(!isStarted) start(); + return; + } + if(connectState==connectActive){ + string message = string("channel ") + pvaClientChannel->getChannel()->getChannelName() + + " " + + monitorConnectStatus.getMessage(); + throw std::runtime_error(message); + } } string PvaClientMonitor::getRequesterName() @@ -216,17 +225,21 @@ void PvaClientMonitor::monitorConnect( << " status.isOK " << (status.isOK() ? "true" : "false") << endl; } - if(!status.isOK()) { - this->monitor.reset(); - connectState = connectIdle; - string message = string("PvaClientMonitor::monitorConnect channel ") - + pvaClientChannel->getChannel()->getChannelName() - + " " - + status.getMessage(); - throw std::runtime_error(message); + { + Lock xx(mutex); + this->monitor = monitor; + if(!status.isOK()) { + stringstream ss; + ss << pvRequest; + string message = string("\nPvaClientMonitor::monitorConnect)") + + "\npvRequest\n" + ss.str() + + "\nerror\n" + status.getMessage(); + monitorConnectStatus = Status(Status::STATUSTYPE_ERROR,message); + return; + } } bool signal = (connectState==connectWait) ? true : false; - connectStatus = status; + monitorConnectStatus = status; connectState = connected; if(isStarted) { if(PvaClient::getDebug()) { @@ -306,30 +319,29 @@ void PvaClientMonitor::issueConnect() Status PvaClientMonitor::waitConnect() { if(PvaClient::getDebug()) { - cout << "PvaClientMonitor::waitConnect" + cout << "PvaClientMonitor::waitConnect " << pvaClientChannel->getChannel()->getChannelName() << endl; } - if(connectState==connected) { - if(!connectStatus.isOK()) connectState = connectIdle; - return connectStatus; - } - if(connectState!=connectWait) { - string message = string("channel ") - + pvaClientChannel->getChannel()->getChannelName() - + " PvaClientMonitor::waitConnect illegal connect state "; - throw std::runtime_error(message); - } - if(PvaClient::getDebug()) { - cout << "PvaClientMonitor::waitConnect calling waitForConnect.wait\n"; + { + Lock xx(mutex); + if(connectState==connected) { + if(!monitorConnectStatus.isOK()) connectState = connectIdle; + return monitorConnectStatus; + } + if(connectState!=connectWait) { + string message = string("channel ") + pvaClientChannel->getChannel()->getChannelName() + + " PvaClientMonitor::waitConnect illegal connect state "; + throw std::runtime_error(message); + } } waitForConnect.wait(); - connectState = connectStatus.isOK() ? connected : connectIdle; + connectState = monitorConnectStatus.isOK() ? connected : connectIdle; if(PvaClient::getDebug()) { cout << "PvaClientMonitor::waitConnect" - << " connectStatus " << (connectStatus.isOK() ? "connected" : "not connected"); + << " monitorConnectStatus " << (monitorConnectStatus.isOK() ? "connected" : "not connected"); } - return connectStatus; + return monitorConnectStatus; } void PvaClientMonitor::setRequester(PvaClientMonitorRequesterPtr const & pvaClientMonitorRequester) diff --git a/src/pvaClientPut.cpp b/src/pvaClientPut.cpp index e267ef3..dc5c158 100644 --- a/src/pvaClientPut.cpp +++ b/src/pvaClientPut.cpp @@ -169,14 +169,21 @@ void PvaClientPut::channelStateChange(PvaClientChannelPtr const & pvaClientChann 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(PvaClient::getDebug()) { + cout << "PvaClientPut::checkPutState" + << " channelName " << pvaClientChannel->getChannel()->getChannelName() + << endl; } if(connectState==connectIdle){ connect(); get(); + return; + } + if(connectState==connectActive){ + string message = string("channel ") + pvaClientChannel->getChannel()->getChannelName() + + " " + + channelPutConnectStatus.getMessage(); + throw std::runtime_error(message); } } @@ -207,11 +214,19 @@ void PvaClientPut::channelPutConnect( } { Lock xx(mutex); - channelPutConnectStatus = status; this->channelPut = channelPut; if(status.isOK()) { + channelPutConnectStatus = status; + connectState = connected; pvaClientData = PvaClientPutData::create(structure); pvaClientData->setMessagePrefix(channelPut->getChannel()->getChannelName()); + } else { + stringstream ss; + ss << pvRequest; + string message = string("\nPvaClientPut::channelPutConnect)") + + "\npvRequest\n" + ss.str() + + "\nerror\n" + status.getMessage(); + channelPutConnectStatus = Status(Status::STATUSTYPE_ERROR,message); } } PvaClientPutRequesterPtr req(pvaClientPutRequester.lock()); @@ -269,6 +284,11 @@ void PvaClientPut::putDone( void PvaClientPut::connect() { + if(PvaClient::getDebug()) { + cout << "PvaClientPut::connect" + << " channelName " << pvaClientChannel->getChannel()->getChannelName() + << endl; + } issueConnect(); Status status = waitConnect(); if(status.isOK()) return; @@ -281,18 +301,29 @@ void PvaClientPut::connect() void PvaClientPut::issueConnect() { + if(PvaClient::getDebug()) { + cout << "PvaClientPut::issueConnect" + << " channelName " << pvaClientChannel->getChannel()->getChannelName() + << endl; + } if(connectState!=connectIdle) { string message = string("channel ") + pvaClientChannel->getChannel()->getChannelName() + " pvaClientPut already connected "; throw std::runtime_error(message); } connectState = connectActive; + channelPutConnectStatus = Status(Status::STATUSTYPE_ERROR, "connect active"); channelPut = pvaClientChannel->getChannel()->createChannelPut(channelPutRequester,pvRequest); } Status PvaClientPut::waitConnect() { + if(PvaClient::getDebug()) { + cout << "PvaClientPut::waitConnect" + << " channelName " << pvaClientChannel->getChannel()->getChannelName() + << endl; + } { Lock xx(mutex); if(connectState==connected) { @@ -389,6 +420,11 @@ Status PvaClientPut::waitPut() PvaClientPutDataPtr PvaClientPut::getData() { + if(PvaClient::getDebug()) { + cout<< "PvaClientPut::getData" + << " channelName " << pvaClientChannel->getChannel()->getChannelName() + << endl; + } checkPutState(); return pvaClientData; } From 5c99282ee2cf18dcbd774c52914d40874e9bd76b Mon Sep 17 00:00:00 2001 From: mrkraimer Date: Tue, 18 Jul 2017 14:47:44 -0400 Subject: [PATCH 12/12] change version number --- src/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Makefile b/src/Makefile index ffa1083..52d3327 100644 --- a/src/Makefile +++ b/src/Makefile @@ -6,7 +6,7 @@ include $(TOP)/configure/CONFIG LIBRARY += pvaClient # shared library ABI version. -SHRLIB_VERSION ?= 4.2.0 +SHRLIB_VERSION ?= 4.3.0 INC += pv/pvaClient.h INC += pv/pvaClientMultiChannel.h