1 Commits

Author SHA1 Message Date
Andrew Johnson b8cb8d9ca4 Set dependency branches for cloudbees builds 2016-08-02 11:33:33 -05:00
40 changed files with 749 additions and 3004 deletions
-21
View File
@@ -1,21 +0,0 @@
#!/bin/sh
set -e -x
# set RTEMS to eg. "4.9" or "4.10"
# requires qemu, bison, flex, texinfo, install-info
if [ -n "$RTEMS" ]
then
# find local qemu-system-i386
export PATH="$HOME/.cache/qemu/usr/bin:$PATH"
echo -n "Using QEMU: "
type qemu-system-i386 || echo "Missing qemu"
EXTRA=RTEMS_QEMU_FIXUPS=YES
fi
make -j2 $EXTRA
if [ "$TEST" != "NO" ]
then
make tapfiles
make -s test-results
fi
-180
View File
@@ -1,180 +0,0 @@
#!/bin/sh
set -e -x
CURDIR="$PWD"
QDIR="$HOME/.cache/qemu"
if [ -n "$RTEMS" -a "$TEST" = "YES" ]
then
git clone --quiet --branch vme --depth 10 https://github.com/mdavidsaver/qemu.git "$HOME/.build/qemu"
cd "$HOME/.build/qemu"
HEAD=`git log -n1 --pretty=format:%H`
echo "HEAD revision $HEAD"
[ -e "$HOME/.cache/qemu/built" ] && BUILT=`cat "$HOME/.cache/qemu/built"`
echo "Cached revision $BUILT"
if [ "$HEAD" != "$BUILT" ]
then
echo "Building QEMU"
git submodule --quiet update --init
install -d "$HOME/.build/qemu/build"
cd "$HOME/.build/qemu/build"
"$HOME/.build/qemu/configure" --prefix="$HOME/.cache/qemu/usr" --target-list=i386-softmmu --disable-werror
make -j2
make install
echo "$HEAD" > "$HOME/.cache/qemu/built"
fi
fi
cat << EOF > $CURDIR/configure/RELEASE.local
EPICS_BASE=$HOME/.source/epics-base
EOF
install -d "$HOME/.source"
cd "$HOME/.source"
add_base_module() {
MODULE=$1
BRANCH=$2
( cd epics-base/modules && \
git clone --quiet --depth 5 --branch $MODULE/$BRANCH https://github.com/${REPOBASE:-epics-base}/epics-base.git $MODULE && \
cd $MODULE && git log -n1 )
}
add_gh_module() {
MODULE=$1
REPOOWNER=$2
REPONAME=$3
BRANCH=$4
( cd epics-base/modules && \
git clone --quiet --depth 5 --branch $BRANCH https://github.com/$REPOOWNER/$REPONAME.git $MODULE && \
cd $MODULE && git log -n1 )
}
add_gh_flat() {
MODULE=$1
REPOOWNER=$2
REPONAME=$3
BRANCH=$4
MODULE_UC=$(echo $MODULE | tr 'a-z' 'A-Z')
( git clone --quiet --depth 5 --branch $BRANCH https://github.com/$REPOOWNER/$REPONAME.git $MODULE && \
cd $MODULE && git log -n1 )
cat < $CURDIR/configure/RELEASE.local > $MODULE/configure/RELEASE.local
cat << EOF >> $CURDIR/configure/RELEASE.local
${MODULE_UC}=$HOME/.source/$MODULE
EOF
}
if [ "$BRBASE" ]
then
git clone --quiet --depth 5 --branch "$BRBASE" https://github.com/${REPOBASE:-epics-base}/epics-base.git epics-base
(cd epics-base && git log -n1 )
add_gh_flat pvData ${REPOPVD:-epics-base} pvDataCPP ${BRPVD:-master}
add_gh_flat pvAccess ${REPOPVA:-epics-base} pvAccessCPP ${BRPVA:-master}
add_gh_flat normativeTypes ${REPONT:-epics-base} normativeTypesCPP ${BRNT:-master}
else
git clone --quiet --depth 5 --branch core/"${BRCORE:-master}" https://github.com/${REPOBASE:-epics-base}/epics-base.git epics-base
( cd epics-base && git log -n1 )
add_base_module libcom "${BRLIBCOM:-master}"
add_base_module ca "${BRCA:-master}"
add_base_module database "${BRDATABASE:-master}"
add_gh_module pvData ${REPOPVD:-epics-base} pvDataCPP ${BRPVD:-master}
add_gh_module pvAccess ${REPOPVA:-epics-base} pvAccessCPP ${BRPVA:-master}
add_gh_module normativeTypes ${REPONT:-epics-base} normativeTypesCPP ${BRNT:-master}
fi
if [ -e $CURDIR/configure/RELEASE.local ]
then
cat $CURDIR/configure/RELEASE.local
fi
EPICS_HOST_ARCH=`sh epics-base/startup/EpicsHostArch`
# requires wine and g++-mingw-w64-i686
if [ "$WINE" = "32" ]
then
echo "Cross mingw32"
sed -i -e '/CMPLR_PREFIX/d' epics-base/configure/os/CONFIG_SITE.linux-x86.win32-x86-mingw
cat << EOF >> epics-base/configure/os/CONFIG_SITE.linux-x86.win32-x86-mingw
CMPLR_PREFIX=i686-w64-mingw32-
EOF
cat << EOF >> epics-base/configure/CONFIG_SITE
CROSS_COMPILER_TARGET_ARCHS+=win32-x86-mingw
EOF
fi
if [ "$STATIC" = "YES" ]
then
echo "Build static libraries/executables"
cat << EOF >> epics-base/configure/CONFIG_SITE
SHARED_LIBRARIES=NO
STATIC_BUILD=YES
EOF
fi
case "$CMPLR" in
clang)
echo "Host compiler is clang"
cat << EOF >> epics-base/configure/os/CONFIG_SITE.Common.$EPICS_HOST_ARCH
GNU = NO
CMPLR_CLASS = clang
CC = clang
CCC = clang++
EOF
# hack
sed -i -e 's/CMPLR_CLASS = gcc/CMPLR_CLASS = clang/' epics-base/configure/CONFIG.gnuCommon
clang --version
;;
*)
echo "Host compiler is default"
gcc --version
;;
esac
cat <<EOF >> epics-base/configure/CONFIG_SITE
USR_CPPFLAGS += $USR_CPPFLAGS
USR_CFLAGS += $USR_CFLAGS
USR_CXXFLAGS += $USR_CXXFLAGS
EOF
# set RTEMS to eg. "4.9" or "4.10"
# requires qemu, bison, flex, texinfo, install-info
if [ -n "$RTEMS" ]
then
echo "Cross RTEMS${RTEMS} for pc386"
install -d /home/travis/.cache
curl -L "https://github.com/mdavidsaver/rsb/releases/download/travis-20160306-2/rtems${RTEMS}-i386-trusty-20190306-2.tar.gz" \
| tar -C /home/travis/.cache -xj
sed -i -e '/^RTEMS_VERSION/d' -e '/^RTEMS_BASE/d' epics-base/configure/os/CONFIG_SITE.Common.RTEMS
cat << EOF >> epics-base/configure/os/CONFIG_SITE.Common.RTEMS
RTEMS_VERSION=$RTEMS
RTEMS_BASE=/home/travis/.cache/rtems${RTEMS}-i386
EOF
cat << EOF >> epics-base/configure/CONFIG_SITE
CROSS_COMPILER_TARGET_ARCHS+=RTEMS-pc386
EOF
# find local qemu-system-i386
export PATH="$HOME/.cache/qemu/usr/bin:$PATH"
echo -n "Using QEMU: "
type qemu-system-i386 || echo "Missing qemu"
EXTRA=RTEMS_QEMU_FIXUPS=YES
fi
make -j2 -C epics-base $EXTRA
if [ "$BRBASE" ]
then
make -j2 -C pvData $EXTRA
make -j2 -C pvAccess $EXTRA
make -j2 -C normativeTypes $EXTRA
fi
+12 -16
View File
@@ -1,17 +1,13 @@
/cfg/ bin/
/bin/ lib/
/lib/ doc/
/db/ include/
/dbd/ db/
/html/ dbd/
/include/ documentation/html
/templates/ documentation/*.tag
/configure/*.local
/documentation/html
/documentation/*.tag
O.*/
/QtC-*
envPaths envPaths
*.orig configure/*.local
*.log !configure/ExampleRELEASE.local
.*.swp **/O.*
QtC-*
-29
View File
@@ -1,29 +0,0 @@
sudo: false
dist: trusty
language: c++
compiler:
- gcc
addons:
apt:
packages:
- libreadline6-dev
- libncurses5-dev
- perl
- clang
- g++-mingw-w64-i686
install:
- ./.ci/travis-prepare.sh
script:
- ./.ci/travis-build.sh
env:
- BRCORE=master BRLIBCOM=master BRPVD=master BRPVA=master BRNT=master TEST=NO
- CMPLR=clang TEST=NO
- USR_CXXFLAGS=-std=c++11 TEST=NO
- CMPLR=clang USR_CXXFLAGS=-std=c++11 TEST=NO
- WINE=32 TEST=NO STATIC=YES
- WINE=32 TEST=NO STATIC=NO
- RTEMS=4.10 TEST=NO
- RTEMS=4.9 TEST=NO
- BRBASE=3.16 TEST=NO
- BRBASE=3.15 TEST=NO
- BRBASE=3.14 TEST=NO
+26
View File
@@ -21,3 +21,29 @@ It can also be built by:
edit configure/RELEASE.local edit configure/RELEASE.local
make 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.
+8
View File
@@ -0,0 +1,8 @@
EPICS4_DIR=/home/epicsv4/master
PVACCESS=${EPICS4_DIR}/pvAccessCPP
NORMATIVETYPES=${EPICS4_DIR}/normativeTypesCPP
PVDATA=${EPICS4_DIR}/pvDataCPP
PVCOMMON=${EPICS4_DIR}/pvCommonCPP
TEMPLATE_TOP=$(EPICS_BASE)/templates/makeBaseApp/top
EPICS_BASE=/home/install/epics/base
+19 -33
View File
@@ -1,44 +1,30 @@
# RELEASE - Location of external support modules # easyPVACPP RELEASE - Location of external support modules
# #
# IF YOU CHANGE ANY PATHS in this file or make API changes to # IF YOU CHANGE this file or any file it includes you must
# any modules it refers to, you should do a "make rebuild" in # subsequently do a "gnumake rebuild" in the application's
# this application's top level directory. # top level directory.
# #
# The EPICS build process does not check dependencies against # The build process does not check dependencies against files
# any files from outside the application, so it is safest to # that are outside this application, thus you should also do a
# rebuild it completely if any modules it depends on change. # "gnumake rebuild" in the top level directory after EPICS_BASE
# or any other external module pointed to below is rebuilt.
# #
# Host- or target-specific settings can be given in files named # Host- or target-specific settings can be given in files named
# RELEASE.$(EPICS_HOST_ARCH).Common # RELEASE.$(EPICS_HOST_ARCH).Common
# RELEASE.Common.$(T_A) # RELEASE.Common.$(T_A)
# RELEASE.$(EPICS_HOST_ARCH).$(T_A) # RELEASE.$(EPICS_HOST_ARCH).$(T_A)
# EPICS V4 Developers: Do not edit the locations in this file!
# #
# This file is parsed by both GNUmake and an EPICS Perl script, # A RELEASE.local must exist that has the following definitions
# so it may ONLY contain definititions of paths to other support # EPICS_BASE=/home/install/epics/base
# modules, variable definitions that are used in module paths, # EPICS4_DIR=/home/epicsv4
# and include statements that pull in other RELEASE files. # PVCOMMON=${EPICS4_DIR}/pvCommonCPP
# Variables may be used before their values have been set. # PVDATA=${EPICS4_DIR}/pvDataCPP
# Build variables that are NOT used in paths should be set in # NORMATIVETYPES=${EPICSV4}/normativeTypesCPP
# the CONFIG_SITE file. # PVACCESS=${EPICS4_DIR}/pvAccessCPP
#Either create a RELEASE.local one level above the TOP for this module
#OR copy ExampleRELEASE.local to RELEASE.local and edit it.
# Variables and paths to dependent modules:
#MODULES = /path/to/modules
#MYMODULE = $(MODULES)/my-module
# If building the EPICS modules individually, set these:
#EPICS_PVACCESS = $(MODULES)/pvAccess
#EPICS_NORMATIVETYPES = $(MODULES)/normativeTypes
#EPICS_PVDATA = $(MODULES)/pvData
#EPICS_DATABASE = $(MODULES)/database
#EPICS_CA = $(MODULES)/ca
#EPICS_LIBCOM = $(MODULES)/libcom
#EPICS_BASE = $(MODULES)/core
# Set RULES here if you want to use build rules from elsewhere:
#RULES = $(MODULES)/build-rules
# These allow developers to override the RELEASE variable settings
# without having to modify the configure/RELEASE file itself.
-include $(TOP)/../RELEASE.local -include $(TOP)/../RELEASE.local
-include $(TOP)/../RELEASE.$(EPICS_HOST_ARCH).local
-include $(TOP)/configure/RELEASE.local -include $(TOP)/configure/RELEASE.local
+3 -47
View File
@@ -1,58 +1,14 @@
pvaClientCPP Version 4.3.0 EPICS V4 release 4.6
========================== ==========================
Works with pvDataCPP-7.0 and pvAccessCPP-6.0 versions
-----------------------------------------------------
Will not work with older versions of these modules.
destroy methods removed
-----------------------
All the destroy methods are removed since implementation is RAII compliant.
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
);
pvaClientCPP Version 4.2
========================
* The examples are moved to exampleCPP. * The examples are moved to exampleCPP.
* Support for channelRPC is now available. * Support for channelRPC is now available.
* In PvaClientMultiChannel checkConnected() now throws an exception if connect fails. * In PvaClientMultiChannel checkConnected() now throws an exception if connect fails.
pvaClientCPP Version 4.1 EPICS V4 release 4.5
======================== ==========================
pvaClient is a synchronous API for pvAccess. pvaClient is a synchronous API for pvAccess.
-5
View File
@@ -1,5 +0,0 @@
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.
-146
View File
@@ -1,146 +0,0 @@
<?xml version="1.0" encoding="iso-8859-1"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="content-type" content="text/html; charset=iso-8859-1" />
<title>PvaClient</title>
<link rel="stylesheet" type="text/css"
href="http://epics-pvdata.sourceforge.net/base.css" />
<link rel="stylesheet" type="text/css"
href="http://epics-pvdata.sourceforge.net/epicsv4.css" />
<style type="text/css">
/*<![CDATA[*/
.about { margin-left: 3em; margin-right: 3em; font-size: .83em}
table { margin-left: auto; margin-right: auto }
.diagram { text-align: center; margin: 2.5em 0 }
span.opt { color: grey }
span.nterm { font-style:italic }
span.term { font-family:courier }
span.user { font-family:courier }
span.user:before { content:"<" }
span.user:after { content:">" }
.nonnorm { font-style:italic }
p.ed { color: #AA0000 }
span.ed { color: #AA0000 }
p.ed.priv { display: inline; }
span.ed.priv { display: inline; }
/*]]>*/</style>
<!-- Script that generates the Table of Contents -->
<script type="text/javascript"
src="http://epics-pvdata.sourceforge.net/script/tocgen.js">
</script>
</head>
<body>
<h1>PvaClient</h1>
<h2>Overview</h2>
<p>
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.
</p>
<p>
Class <b>PvaClient</b> is a class that is used by all the other pvaClient classes.
An application that uses pvaClient must call:</p>
<pre>
PvaClientPtr pvaClient = PvaClient::get(providers);
</pre>
<p>
before it uses any other pvaClient classes.
</p>
<p>
This is a singleton method, i. e. only one instance of PvaClient is created.
</p>
<p>
<b>pvaClient</b> must not be deleted until the client no longer wants to use any part
of pvaClient.
</p>
<p>
<b>providers</b> is a blank separated set of provider names.
For example:</p>
<pre>
PvaClientPtr pvaClient = PvaClient::get("ca pva");
</pre>
<p>
The providers <b>ca</b> and <b>pva</b> are special.
For each of these a client context is created when the <b>PvaClient</b>
is constructed and the context destroyed when <b>PvaClient</b> is deleted.
</p>
<h2>Channel Caching</h2>
<p>
<b>PvaClient</b> has a method:
</p>
<pre>
PvaClientChannelPtr channel(
string const &amp; channelName,
string const &amp;providerName = "pva",
double timeOut = 5.0);
</pre>
<p>
This method creates a
<b>PvaClientChannel</b> and then connects to the channel.
</p>
<p>
If a call is successful then multiple calls to the same channelName and providerName
share the same PvaClientChannel, i. e. the PvaClientChannel is cached.
</p>
<p>
<b>pvaClientChannelGet</b> and <b>pvaClientChannelPut</b> also implement caching.
</p>
<p>
For example consider a client that makes multiple calls like:
</p>
<pre>
double value;
value = pva->channel(channelName)->get()->getData()->getDouble();
...
value = pva->channel(channelName)->get()->getData()->getDouble();
</pre>
<p>
Only the first call creates a new PvaClientChannel and a new PvaClientGet.
The second call reuses the cached PvaClientChannel and PvaClientGet.
</p>
<h2>Non Cached Channels</h2>
<p>
<b>PvaClient</b> has a method:
</p>
<pre>
PvaClientChannelPtr createChannel(
string const &amp; channelName,
string const &amp;providerName = "pva");
</pre>
<p>
This method is just creates a new PvaClientChannel and returns it to the caller.
The caller must call the PvaClientChannel connect methods.
</p>
<h2>Blocking vs Non-Blocking Methods</h2>
<p>Each component of pvaClient provides a set of blocking and non-blocking calls.
For example several components (examples are <b>PvaClientChannel</b> and <b>PvaChannelGet</b>)
have methods:</p>
<dl>
<dt>connect</dt>
<dd>
This calls issueConnect and then waitConnect.
If waitConnect fails an exception is thrown.
Since waitConnect is a blocking method so is this.
</dd>
<dt>issueConnect</dt>
<dd>
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.
</dd>
<dt>waitConnect</dt>
<dd>
This waits for the server to respond to issueConnect.
It blocks until the server responds or a timeout occurs.
</dd>
</dl>
</body>
</html>
@@ -1,123 +0,0 @@
<?xml version="1.0" encoding="iso-8859-1"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="content-type" content="text/html; charset=iso-8859-1" />
<title>PvaClientChannel</title>
<link rel="stylesheet" type="text/css"
href="http://epics-pvdata.sourceforge.net/base.css" />
<link rel="stylesheet" type="text/css"
href="http://epics-pvdata.sourceforge.net/epicsv4.css" />
<style type="text/css">
/*<![CDATA[*/
.about { margin-left: 3em; margin-right: 3em; font-size: .83em}
table { margin-left: auto; margin-right: auto }
.diagram { text-align: center; margin: 2.5em 0 }
span.opt { color: grey }
span.nterm { font-style:italic }
span.term { font-family:courier }
span.user { font-family:courier }
span.user:before { content:"<" }
span.user:after { content:">" }
.nonnorm { font-style:italic }
p.ed { color: #AA0000 }
span.ed { color: #AA0000 }
p.ed.priv { display: inline; }
span.ed.priv { display: inline; }
/*]]>*/</style>
<!-- Script that generates the Table of Contents -->
<script type="text/javascript"
src="http://epics-pvdata.sourceforge.net/script/tocgen.js">
</script>
</head>
<body>
<h1>PvaClientChannel</h1>
<h2>Overview</h2>
<p>
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.
</p>
<p>An instance of <b>PvaClientChannel</b> connects to a single channel.
An instance can only be created via class <b>PvaClient</b> 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.
</p>
<p><b>PvaClientChannel</b> has methods:</p>
<dl>
<dt>Connect to channel</dt>
<dd>These can be called indirectly by a blocking request to <b>PvaClient</b>
or by the client if a non blocking request is made to <b>PvaClient</b>.
</dd>
<dt>Channel state change requester</dt>
<dd>The client can provide a callback that is called each time the connection state
of the channel changes.
</dd>
<dt>Creating all of the following</dt>
<dd>
<pre>
PvaClientField NOT IMPLEMENTED
PvaClientProcess
PvaClientGet
PvaClientPut
PvaClientPutGet
PvaClientMonitor
PvaClientArray NOT IMPLEMENTED
PvaClientRPC
</pre>
</dd>
</dl>
<h2>Connect: Blocking vs Non-Blocking </h2>
<p><b>PvaClientChannel</b> has methods:</p>
<dl>
<dt>connect</dt>
<dd>
This calls issueConnect and then waitConnect.
If waitConnect fails an exception is thrown.
Since waitConnect is a blocking method so is this.
</dd>
<dt>issueConnect</dt>
<dd>
This is a request to connect to the channel. This is a non blocking call.
</dd>
<dt>waitConnect</dt>
<dd>
This waits for the server to respond to issueConnect.
It blocks until the server responds or a timeout occurs.
</dd>
</dl>
<h2>Get and Put Caching</h2>
<p>
<b>PvaClientChannel</b> has methods:
</p>
<pre>
PvaClientGetPtr get(std::string const &amp; request);
PvaClientPutPtr put(std::string const &amp; request);
</pre>
<p>
Each of these caches.
For example all calls to <b>get</b> with the same <b>request</b> will share the same
<b>PvaChannelGet</b>
</p>
<p>
For example consider a client that makes multiple calls like:
</p>
<pre>
double value;
value = pva->channel(channelName)->get()->getData()->getDouble();
...
value = pva->channel(channelName)->get()->getData()->getDouble();
</pre>
<p>
Only the first call creates a new PvaClientChannel and a new PvaClientGet.
The second call reuses the cached PvaClientChannel and PvaClientGet.
</p>
</body>
</html>
@@ -1,81 +0,0 @@
<?xml version="1.0" encoding="iso-8859-1"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="content-type" content="text/html; charset=iso-8859-1" />
<title>PvaClientChannelStateChangeRequester</title>
<link rel="stylesheet" type="text/css"
href="http://epics-pvdata.sourceforge.net/base.css" />
<link rel="stylesheet" type="text/css"
href="http://epics-pvdata.sourceforge.net/epicsv4.css" />
<style type="text/css">
/*<![CDATA[*/
.about { margin-left: 3em; margin-right: 3em; font-size: .83em}
table { margin-left: auto; margin-right: auto }
.diagram { text-align: center; margin: 2.5em 0 }
span.opt { color: grey }
span.nterm { font-style:italic }
span.term { font-family:courier }
span.user { font-family:courier }
span.user:before { content:"<" }
span.user:after { content:">" }
.nonnorm { font-style:italic }
p.ed { color: #AA0000 }
span.ed { color: #AA0000 }
p.ed.priv { display: inline; }
span.ed.priv { display: inline; }
/*]]>*/</style>
<!-- Script that generates the Table of Contents -->
<script type="text/javascript"
src="http://epics-pvdata.sourceforge.net/script/tocgen.js">
</script>
</head>
<body>
<h1>PvaClientChannelStateChangeRequester</h1>
<p>This class has the single method <b>channelStateChange</b>.
It is called each time the channel connection status changes.
</p>
<p>
<b>NOTE:</b>
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.
</p>
<p>
An example of illegal code is:
</p>
<pre>
virtual void channelStateChange(PvaClientChannelPtr const & channel, bool isConnected)
{
if(isConnected&&!pvaClientPut)
{
pvaClientPut = pvaClientChannel->createPut(request);
pvaClientPut->connect();
}
}
</pre>
<p>
This is illegal because the call to <b>connect</b> blocks.
</p>
<p>The following is an example of legal code:
</p>
<pre>
virtual void channelStateChange(PvaClientChannelPtr const & channel, bool isConnected)
{
if(isConnected&&!pvaClientPut)
{
pvaClientPut = pvaClientChannel->createPut(request);
pvaClientPut->issueConnect();
}
}
</pre>
<p>This is legal code because neither <b>createPut</b> or <b>issueConnect</b>
blocks.
</p>
</body>
</html>
@@ -1,74 +0,0 @@
<?xml version="1.0" encoding="iso-8859-1"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="content-type" content="text/html; charset=iso-8859-1" />
<title>PvaClientGet</title>
<link rel="stylesheet" type="text/css"
href="http://epics-pvdata.sourceforge.net/base.css" />
<link rel="stylesheet" type="text/css"
href="http://epics-pvdata.sourceforge.net/epicsv4.css" />
<style type="text/css">
/*<![CDATA[*/
.about { margin-left: 3em; margin-right: 3em; font-size: .83em}
table { margin-left: auto; margin-right: auto }
.diagram { text-align: center; margin: 2.5em 0 }
span.opt { color: grey }
span.nterm { font-style:italic }
span.term { font-family:courier }
span.user { font-family:courier }
span.user:before { content:"<" }
span.user:after { content:">" }
.nonnorm { font-style:italic }
p.ed { color: #AA0000 }
span.ed { color: #AA0000 }
p.ed.priv { display: inline; }
span.ed.priv { display: inline; }
/*]]>*/</style>
<!-- Script that generates the Table of Contents -->
<script type="text/javascript"
src="http://epics-pvdata.sourceforge.net/script/tocgen.js">
</script>
</head>
<body>
<h1>PvaClientGet</h1>
<p>
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.
</p>
<p>An instance of PvaClientGet is created via a call to one of the following:</p>
<pre>
class PvaClientChannel
...
{
...
PvaClientGetPtr get(std::string const &amp; request = "field(value,alarm,timeStamp)");
PvaClientGetPtr createGet(std::string const &amp; request = "");
PvaClientGetPtr createGet(epics::pvData::PVStructurePtr const &amp; pvRequest);
...
};
<p>An instance of <b>PvaClientGet</b> connects to a single channel.
<b>PvaClientGet</b> has both synchronous methods, which block, and non blocking methods.
</p>
<p><b>PvaClientChannel</b> has methods:</p>
<pre>
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.
</pre>
<p>
<b>issueConnect</b> and <b>issueGet</b> do not block.
All other methods can block.
</p>
</body>
</html>
@@ -1,63 +0,0 @@
<?xml version="1.0" encoding="iso-8859-1"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="content-type" content="text/html; charset=iso-8859-1" />
<title>PvaClientGetData</title>
<link rel="stylesheet" type="text/css"
href="http://epics-pvdata.sourceforge.net/base.css" />
<link rel="stylesheet" type="text/css"
href="http://epics-pvdata.sourceforge.net/epicsv4.css" />
<style type="text/css">
/*<![CDATA[*/
.about { margin-left: 3em; margin-right: 3em; font-size: .83em}
table { margin-left: auto; margin-right: auto }
.diagram { text-align: center; margin: 2.5em 0 }
span.opt { color: grey }
span.nterm { font-style:italic }
span.term { font-family:courier }
span.user { font-family:courier }
span.user:before { content:"<" }
span.user:after { content:">" }
.nonnorm { font-style:italic }
p.ed { color: #AA0000 }
span.ed { color: #AA0000 }
p.ed.priv { display: inline; }
span.ed.priv { display: inline; }
/*]]>*/</style>
<!-- Script that generates the Table of Contents -->
<script type="text/javascript"
src="http://epics-pvdata.sourceforge.net/script/tocgen.js">
</script>
</head>
<body>
<h1>PvaClientGetData</h1>
<p>This class provides access to the data returned by calls to get data via <b>PvaChannelGet</b>
It provides methods:</p>
<pre>
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 if 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.
</pre>
</body>
</html>
@@ -1,59 +0,0 @@
<?xml version="1.0" encoding="iso-8859-1"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="content-type" content="text/html; charset=iso-8859-1" />
<title>PvaClientGetRequester</title>
<link rel="stylesheet" type="text/css"
href="http://epics-pvdata.sourceforge.net/base.css" />
<link rel="stylesheet" type="text/css"
href="http://epics-pvdata.sourceforge.net/epicsv4.css" />
<style type="text/css">
/*<![CDATA[*/
.about { margin-left: 3em; margin-right: 3em; font-size: .83em}
table { margin-left: auto; margin-right: auto }
.diagram { text-align: center; margin: 2.5em 0 }
span.opt { color: grey }
span.nterm { font-style:italic }
span.term { font-family:courier }
span.user { font-family:courier }
span.user:before { content:"<" }
span.user:after { content:">" }
.nonnorm { font-style:italic }
p.ed { color: #AA0000 }
span.ed { color: #AA0000 }
p.ed.priv { display: inline; }
span.ed.priv { display: inline; }
/*]]>*/</style>
<!-- Script that generates the Table of Contents -->
<script type="text/javascript"
src="http://epics-pvdata.sourceforge.net/script/tocgen.js">
</script>
</head>
<body>
<h1>PvaClientGetRequester</h1>
<p>This is a virtual class that can be implemented by a client that uses <b>PvaClientGet</b>.
It has the methods:</p>
<pre>
virtual void channelGetConnect(
const Status&amp; status,
PvaClientGetPtr const &amp; clientGet) {}
virtual void getDone(
const Status&amp; status,
PvaClientGetPtr const &amp; clientGet) = 0;
</pre>
<p>The client must call</p>
<pre>
pvaClientGet->setRequester(shared_from_this());
</pre>
<p>
after creating an instance of PvaClientGet.
</p>
</body>
</html>
@@ -1,106 +0,0 @@
<?xml version="1.0" encoding="iso-8859-1"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="content-type" content="text/html; charset=iso-8859-1" />
<title>PvaClientMonitor</title>
<link rel="stylesheet" type="text/css"
href="http://epics-pvdata.sourceforge.net/base.css" />
<link rel="stylesheet" type="text/css"
href="http://epics-pvdata.sourceforge.net/epicsv4.css" />
<style type="text/css">
/*<![CDATA[*/
.about { margin-left: 3em; margin-right: 3em; font-size: .83em}
table { margin-left: auto; margin-right: auto }
.diagram { text-align: center; margin: 2.5em 0 }
span.opt { color: grey }
span.nterm { font-style:italic }
span.term { font-family:courier }
span.user { font-family:courier }
span.user:before { content:"<" }
span.user:after { content:">" }
.nonnorm { font-style:italic }
p.ed { color: #AA0000 }
span.ed { color: #AA0000 }
p.ed.priv { display: inline; }
span.ed.priv { display: inline; }
/*]]>*/</style>
<!-- Script that generates the Table of Contents -->
<script type="text/javascript"
src="http://epics-pvdata.sourceforge.net/script/tocgen.js">
</script>
</head>
<body>
<h1>PvaClientMonitor</h1>
<p>
<b>NOTE:</b> This is a work in progress.
</p>
<h2>Overview</h2>
<p>
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:
</p>
<h3>The client first creates a PvaClientMonitorChannel and then creates a monitor</h3>
The client calls:
<pre>
static PvaClientMonitorPtr create(
PvaClientMonitorPtr const &amp;PvaClientMonitor,
PvaClientMonitorChannelPtr const &amp; PvaClientMonitorChannel,
epics::pvData::PVStructurePtr const &amp;pvRequest
);
where
PvaClientMonitor
The PvaClientMonitor.
PvaClientMonitorChannel
The PvaClientMonitorChannel that has already been created by the client.
pvRequest
The pvRequest for creating the monitor.
</pre>
With this method the monitor is created and started.
This method blocks while the monitor is created.
<h3>The client provides names for a channel and a provider</h3>
The client calls:
<pre>
static PvaClientMonitorPtr create(
PvaClientMonitorPtr const &amp;PvaClientMonitor,
std::string const &amp; channelName,
std::string const &amp; providerName,
std::string const &amp; request,
PvaClientMonitorChannelStateChangeRequesterPtr const &amp; stateChangeRequester,
PvaClientMonitorRequesterPtr const &amp; monitorRequester
);
where
PvaClientMonitor
The PvaClientMonitor.
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.
</pre>
With this method a pvaChannel is created and after it connects a pvaMonitor is created and started.
This method never blocks.
</body>
</html>
@@ -1,66 +0,0 @@
<?xml version="1.0" encoding="iso-8859-1"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="content-type" content="text/html; charset=iso-8859-1" />
<title>PvaClientMonitorData</title>
<link rel="stylesheet" type="text/css"
href="http://epics-pvdata.sourceforge.net/base.css" />
<link rel="stylesheet" type="text/css"
href="http://epics-pvdata.sourceforge.net/epicsv4.css" />
<style type="text/css">
/*<![CDATA[*/
.about { margin-left: 3em; margin-right: 3em; font-size: .83em}
table { margin-left: auto; margin-right: auto }
.diagram { text-align: center; margin: 2.5em 0 }
span.opt { color: grey }
span.nterm { font-style:italic }
span.term { font-family:courier }
span.user { font-family:courier }
span.user:before { content:"<" }
span.user:after { content:">" }
.nonnorm { font-style:italic }
p.ed { color: #AA0000 }
span.ed { color: #AA0000 }
p.ed.priv { display: inline; }
span.ed.priv { display: inline; }
/*]]>*/</style>
<!-- Script that generates the Table of Contents -->
<script type="text/javascript"
src="http://epics-pvdata.sourceforge.net/script/tocgen.js">
</script>
</head>
<body>
<h1>PvaClientMonitorData</h1>
<p>This class provides access to the data returned by calls to get data via <b>PvaChannelGet</b>
It provides methods:</p>
<pre>
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 if 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.
</pre>
</body>
</html>
@@ -1,65 +0,0 @@
<?xml version="1.0" encoding="iso-8859-1"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="content-type" content="text/html; charset=iso-8859-1" />
<title>PvaClientMonitorRequester</title>
<link rel="stylesheet" type="text/css"
href="http://epics-pvdata.sourceforge.net/base.css" />
<link rel="stylesheet" type="text/css"
href="http://epics-pvdata.sourceforge.net/epicsv4.css" />
<style type="text/css">
/*<![CDATA[*/
.about { margin-left: 3em; margin-right: 3em; font-size: .83em}
table { margin-left: auto; margin-right: auto }
.diagram { text-align: center; margin: 2.5em 0 }
span.opt { color: grey }
span.nterm { font-style:italic }
span.term { font-family:courier }
span.user { font-family:courier }
span.user:before { content:"<" }
span.user:after { content:">" }
.nonnorm { font-style:italic }
p.ed { color: #AA0000 }
span.ed { color: #AA0000 }
p.ed.priv { display: inline; }
span.ed.priv { display: inline; }
/*]]>*/</style>
<!-- Script that generates the Table of Contents -->
<script type="text/javascript"
src="http://epics-pvdata.sourceforge.net/script/tocgen.js">
</script>
</head>
<body>
<h1>PvaClientMonitorRequester</h1>
<p>This is a virtual class that can be implemented by a client that uses <b>PvaClientMonitor</b>.
It has the methods:</p>
<pre>
virtual void monitorConnect(
const Status&amp; status,
PvaClientMonitorPtr const &amp; clientMonitor,
StructureConstPtr const &amp; structure) {}
virtual void event(
PvaClientMonitor const &amp; clientGet) = 0;
virtual void unlisten()
{
std::cerr &lt;&lt; "PvaClientMonitorRequester::unlisten called"
&lt;&lt; " but no PvaClientMonitorRequester::unlisten\n";
}
</pre>
<p>The client must call</p>
<pre>
pvaClientMonitor->setRequester(shared_from_this());
</pre>
<p>
after creating an instance of PvaClientMonitor.
</p>
</body>
</html>
@@ -1,71 +0,0 @@
<?xml version="1.0" encoding="iso-8859-1"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="content-type" content="text/html; charset=iso-8859-1" />
<title>PvaClientProcess</title>
<link rel="stylesheet" type="text/css"
href="http://epics-pvdata.sourceforge.net/base.css" />
<link rel="stylesheet" type="text/css"
href="http://epics-pvdata.sourceforge.net/epicsv4.css" />
<style type="text/css">
/*<![CDATA[*/
.about { margin-left: 3em; margin-right: 3em; font-size: .83em}
table { margin-left: auto; margin-right: auto }
.diagram { text-align: center; margin: 2.5em 0 }
span.opt { color: grey }
span.nterm { font-style:italic }
span.term { font-family:courier }
span.user { font-family:courier }
span.user:before { content:"<" }
span.user:after { content:">" }
.nonnorm { font-style:italic }
p.ed { color: #AA0000 }
span.ed { color: #AA0000 }
p.ed.priv { display: inline; }
span.ed.priv { display: inline; }
/*]]>*/</style>
<!-- Script that generates the Table of Contents -->
<script type="text/javascript"
src="http://epics-pvdata.sourceforge.net/script/tocgen.js">
</script>
</head>
<body>
<h1>PvaClientProcess</h1>
<p>
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.
</p>
<p>An instance of PvaClientProcess is created via a call to one of the followimg:</p>
<pre>
class PvaClientChannel
...
{
...
PvaClientProcessPtr createProcess(std::string const &amp; request = "");
PvaClientProcessPtr createProcess(epics::pvData::PVStructurePtr const &amp; pvRequest);
...
};
<p>An instance of <b>PvaClientProcess</b> connects to a single channel.
<b>PvaClientProcess</b> has both synchronous methods, which block, and non blocking methods.
</p>
<p><b>PvaClientChannel</b> has methods:</p>
<pre>
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.
</pre>
<p>
<b>issueConnect</b> and <b>issueProcess</b> do not block.
All other methods can block.
</p>
</body>
</html>
@@ -1,82 +0,0 @@
<?xml version="1.0" encoding="iso-8859-1"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="content-type" content="text/html; charset=iso-8859-1" />
<title>PvaClientChannelPut</title>
<link rel="stylesheet" type="text/css"
href="http://epics-pvdata.sourceforge.net/base.css" />
<link rel="stylesheet" type="text/css"
href="http://epics-pvdata.sourceforge.net/epicsv4.css" />
<style type="text/css">
/*<![CDATA[*/
.about { margin-left: 3em; margin-right: 3em; font-size: .83em}
table { margin-left: auto; margin-right: auto }
.diagram { text-align: center; margin: 2.5em 0 }
span.opt { color: grey }
span.nterm { font-style:italic }
span.term { font-family:courier }
span.user { font-family:courier }
span.user:before { content:"<" }
span.user:after { content:">" }
.nonnorm { font-style:italic }
p.ed { color: #AA0000 }
span.ed { color: #AA0000 }
p.ed.priv { display: inline; }
span.ed.priv { display: inline; }
/*]]>*/</style>
<!-- Script that generates the Table of Contents -->
<script type="text/javascript"
src="http://epics-pvdata.sourceforge.net/script/tocgen.js">
</script>
</head>
<body>
<h1>PvaClientChannelPut</h1>s
<p>
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.
</p>
<p>
<b>NOTE:</b>
Except for union fields pvaClientPut takes care of modifying the bitSet associated with
the data sent to the server.
</p>
<p>An instance of PvaClientPut is created via a call to one of the followimg:</p>
<pre>
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);
...
};
<p>An instance of <b>PvaClientPut/b> connects to a single channel.
<b>PvaClientPut</b> has both synchronous methods, which block, and non blocking methods.
</p>
<p><b>PvaClientPut</b> has methods:</p>
<pre>
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.
</pre>
<p>
Note that <b>issueConnect</b>, <b>issueGet</b> and <b>issuePut</b> do not block but all other methods
do block.
</p>
</body>
</html>
@@ -1,75 +0,0 @@
<?xml version="1.0" encoding="iso-8859-1"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="content-type" content="text/html; charset=iso-8859-1" />
<title>PvaClientPutData</title>
<link rel="stylesheet" type="text/css"
href="http://epics-pvdata.sourceforge.net/base.css" />
<link rel="stylesheet" type="text/css"
href="http://epics-pvdata.sourceforge.net/epicsv4.css" />
<style type="text/css">
/*<![CDATA[*/
.about { margin-left: 3em; margin-right: 3em; font-size: .83em}
table { margin-left: auto; margin-right: auto }
.diagram { text-align: center; margin: 2.5em 0 }
span.opt { color: grey }
span.nterm { font-style:italic }
span.term { font-family:courier }
span.user { font-family:courier }
span.user:before { content:"<" }
span.user:after { content:">" }
.nonnorm { font-style:italic }
p.ed { color: #AA0000 }
span.ed { color: #AA0000 }
p.ed.priv { display: inline; }
span.ed.priv { display: inline; }
/*]]>*/</style>
<!-- Script that generates the Table of Contents -->
<script type="text/javascript"
src="http://epics-pvdata.sourceforge.net/script/tocgen.js">
</script>
</head>
<body>
<h1>PvaClientPutData</h1>
<p>This class provides access to data to send to the server via a <b>PvaChannelPut</b>
It is created by <b>PvaChannelPut</b> or <b>PvaChannelPutGet</b>.
This the client only gets access to an instance by getting it from <b>PvaChannelPut</b> or <b>PvaChannelPutGet</b>.
<p>
<p>Note also that for all field types except <b>union</b> the <b>BitSet</b> for the data is updated
by <b>PvaChannelPut</b> or <b>PvaChannelPutGet</b> whenever the client changes a field.
For a <b>union</b> or <b>unionArray</b> field the client must update the <b>BitSet</b>.
</p>
<p>
PvaClientPutData provides methods:</p>
<pre>
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 if 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.
</pre>
</body>
</html>
@@ -1,85 +0,0 @@
<?xml version="1.0" encoding="iso-8859-1"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="content-type" content="text/html; charset=iso-8859-1" />
<title>PvaClientPutGetGet</title>
<link rel="stylesheet" type="text/css"
href="http://epics-pvdata.sourceforge.net/base.css" />
<link rel="stylesheet" type="text/css"
href="http://epics-pvdata.sourceforge.net/epicsv4.css" />
<style type="text/css">
/*<![CDATA[*/
.about { margin-left: 3em; margin-right: 3em; font-size: .83em}
table { margin-left: auto; margin-right: auto }
.diagram { text-align: center; margin: 2.5em 0 }
span.opt { color: grey }
span.nterm { font-style:italic }
span.term { font-family:courier }
span.user { font-family:courier }
span.user:before { content:"<" }
span.user:after { content:">" }
.nonnorm { font-style:italic }
p.ed { color: #AA0000 }
span.ed { color: #AA0000 }
p.ed.priv { display: inline; }
span.ed.priv { display: inline; }
/*]]>*/</style>
<!-- Script that generates the Table of Contents -->
<script type="text/javascript"
src="http://epics-pvdata.sourceforge.net/script/tocgen.js">
</script>
</head>
<body>
<h1>PvaClientPutGetGet</h1>
<p>
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.
</p>
<p>
<b>NOTE:</b>
Except for union fields pvaClientPutGet takes care of modifying the bitSet associated with
the data sent to the server.
</p>
<p>An instance of PvaClientPutGet is created via a call to one of the followimg:</p>
<pre>
class PvaClientChannel
...
{
...
PvaClientPutGetPtr createPutGet(std::string const &amp; request);
PvaClientPutGetPtr createPutGet(epics::pvData::PVStructurePtr const &amp; pvRequest);
...
};
<p>An instance of <b>PvaClientPutGet</b> connects to a single channel.
<b>PvaClientPutGet</b> has both synchronous methods, which block, and non blocking methods.
</p>
<p><b>PvaClientPutGet</b> has methods:</p>
<pre>
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.
</pre>
<p>
<b>issueConnect</b>, <b>issuePutGet</b>, <b>issueGetGet</b> and <b>issueGetPut</b> do not block.
All other methods can block.
</p>
</body>
</html>
@@ -1,66 +0,0 @@
<?xml version="1.0" encoding="iso-8859-1"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="content-type" content="text/html; charset=iso-8859-1" />
<title>PvaClientPutGetRequester</title>
<link rel="stylesheet" type="text/css"
href="http://epics-pvdata.sourceforge.net/base.css" />
<link rel="stylesheet" type="text/css"
href="http://epics-pvdata.sourceforge.net/epicsv4.css" />
<style type="text/css">
/*<![CDATA[*/
.about { margin-left: 3em; margin-right: 3em; font-size: .83em}
table { margin-left: auto; margin-right: auto }
.diagram { text-align: center; margin: 2.5em 0 }
span.opt { color: grey }
span.nterm { font-style:italic }
span.term { font-family:courier }
span.user { font-family:courier }
span.user:before { content:"<" }
span.user:after { content:">" }
.nonnorm { font-style:italic }
p.ed { color: #AA0000 }
span.ed { color: #AA0000 }
p.ed.priv { display: inline; }
span.ed.priv { display: inline; }
/*]]>*/</style>
<!-- Script that generates the Table of Contents -->
<script type="text/javascript"
src="http://epics-pvdata.sourceforge.net/script/tocgen.js">
</script>
</head>
<body>
<h1>PvaClientPutGetRequester</h1>
<p>This is a virtual class that can be implemented by a client that uses <b>PvaClientPut</b>.
It has the methods:</p>
<pre>
virtual void channelPutGetConnect(
const Status&amp; status,
PvaClientPutGetPtr const &amp; clientPutGet) {}
virtual void putGetDone(
const Status&amp; status,
PvaClientPutGetPtr const &amp; clientPutGet) {}
virtual void getPutDone(
const Status&amp; status,
PvaClientPutGetPtr const &amp; clientPutGet) = 0;
virtual void getGetDone(
const Status&amp; status,
PvaClientPutGetPtr const &amp; clientPutGet) = 0;
</pre>
<p>The client must call</p>
<pre>
pvaClientPutGet->setRequester(shared_from_this());
</pre>
<p>
after creating an instance of PvaClientPutGet.
</p>
</body>
</html>
@@ -1,63 +0,0 @@
<?xml version="1.0" encoding="iso-8859-1"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="content-type" content="text/html; charset=iso-8859-1" />
<title>PvaClientPutRequester</title>
<link rel="stylesheet" type="text/css"
href="http://epics-pvdata.sourceforge.net/base.css" />
<link rel="stylesheet" type="text/css"
href="http://epics-pvdata.sourceforge.net/epicsv4.css" />
<style type="text/css">
/*<![CDATA[*/
.about { margin-left: 3em; margin-right: 3em; font-size: .83em}
table { margin-left: auto; margin-right: auto }
.diagram { text-align: center; margin: 2.5em 0 }
span.opt { color: grey }
span.nterm { font-style:italic }
span.term { font-family:courier }
span.user { font-family:courier }
span.user:before { content:"<" }
span.user:after { content:">" }
.nonnorm { font-style:italic }
p.ed { color: #AA0000 }
span.ed { color: #AA0000 }
p.ed.priv { display: inline; }
span.ed.priv { display: inline; }
/*]]>*/</style>
<!-- Script that generates the Table of Contents -->
<script type="text/javascript"
src="http://epics-pvdata.sourceforge.net/script/tocgen.js">
</script>
</head>
<body>
<h1>PvaClientPutRequester</h1>
<p>This is a virtual class that can be implemented by a client that uses <b>PvaClientPut</b>.
It has the methods:</p>
<pre>
virtual void channelPutConnect(
const Status&amp; status,
PvaClientPutPtr const &amp; clientPut) {}
virtual void getDone(
const Status&amp; status,
PvaClientPutPtr const &amp; clientPut) {}
virtual void putDone(
const Status&amp; status,
PvaClientPutPtr const &amp; clientPut) = 0;
</pre>
<p>The client must call</p>
<pre>
pvaClientPut->setRequester(shared_from_this());
</pre>
<p>
after creating an instance of PvaClientPut.
</p>
</body>
</html>
@@ -1,44 +0,0 @@
<?xml version="1.0" encoding="iso-8859-1"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="content-type" content="text/html; charset=iso-8859-1" />
<title>PvaClientRPC</title>
<link rel="stylesheet" type="text/css"
href="http://epics-pvdata.sourceforge.net/base.css" />
<link rel="stylesheet" type="text/css"
href="http://epics-pvdata.sourceforge.net/epicsv4.css" />
<style type="text/css">
/*<![CDATA[*/
.about { margin-left: 3em; margin-right: 3em; font-size: .83em}
table { margin-left: auto; margin-right: auto }
.diagram { text-align: center; margin: 2.5em 0 }
span.opt { color: grey }
span.nterm { font-style:italic }
span.term { font-family:courier }
span.user { font-family:courier }
span.user:before { content:"<" }
span.user:after { content:">" }
.nonnorm { font-style:italic }
p.ed { color: #AA0000 }
span.ed { color: #AA0000 }
p.ed.priv { display: inline; }
span.ed.priv { display: inline; }
/*]]>*/</style>
<!-- Script that generates the Table of Contents -->
<script type="text/javascript"
src="http://epics-pvdata.sourceforge.net/script/tocgen.js">
</script>
</head>
<body>
<h1>PvaClientRPC</h1>
<p>
<b>Not Yet Written</b>
</p>
</body>
</html>
@@ -1,44 +0,0 @@
<?xml version="1.0" encoding="iso-8859-1"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="content-type" content="text/html; charset=iso-8859-1" />
<title>PvaClientRPCRequester</title>
<link rel="stylesheet" type="text/css"
href="http://epics-pvdata.sourceforge.net/base.css" />
<link rel="stylesheet" type="text/css"
href="http://epics-pvdata.sourceforge.net/epicsv4.css" />
<style type="text/css">
/*<![CDATA[*/
.about { margin-left: 3em; margin-right: 3em; font-size: .83em}
table { margin-left: auto; margin-right: auto }
.diagram { text-align: center; margin: 2.5em 0 }
span.opt { color: grey }
span.nterm { font-style:italic }
span.term { font-family:courier }
span.user { font-family:courier }
span.user:before { content:"<" }
span.user:after { content:">" }
.nonnorm { font-style:italic }
p.ed { color: #AA0000 }
span.ed { color: #AA0000 }
p.ed.priv { display: inline; }
span.ed.priv { display: inline; }
/*]]>*/</style>
<!-- Script that generates the Table of Contents -->
<script type="text/javascript"
src="http://epics-pvdata.sourceforge.net/script/tocgen.js">
</script>
</head>
<body>
<h1>PvaClientRPCRequester</h1>
<p>
<b>Not Yet Written</b>
</p>
</body>
</html>
+17 -9
View File
@@ -4,7 +4,7 @@
<html xmlns="http://www.w3.org/1999/xhtml"> <html xmlns="http://www.w3.org/1999/xhtml">
<head> <head>
<meta http-equiv="content-type" content="text/html; charset=iso-8859-1" /> <meta http-equiv="content-type" content="text/html; charset=iso-8859-1" />
<title>EPICS pvaClientCPP</title> <title>EPICS pva</title>
<link rel="stylesheet" type="text/css" <link rel="stylesheet" type="text/css"
href="http://epics-pvdata.sourceforge.net/base.css" /> href="http://epics-pvdata.sourceforge.net/base.css" />
<link rel="stylesheet" type="text/css" <link rel="stylesheet" type="text/css"
@@ -26,11 +26,11 @@
<div class="head"> <div class="head">
<h1>EPICS pvaClientCPP</h1> <h1>EPICS pvaClientCPP</h1>
<h2 class="nocount">Release 4.3.0 - 2017-12-14</h2> <h2 class="nocount">Release 4.2.0-SNAPSHOT - 2016-07-14</h2>
<h2 class="nocount">Abstract</h2> <h2 class="nocount">Abstract</h2>
<p>pvaClient is a software library that provides, to an EPICS client programmer, a friendly <p>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 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 for such uses as rapid development of ad hoc programs by controls engineers, or to provide
scientists a way to directly develop analytical applications.</p> scientists a way to directly develop analytical applications.</p>
@@ -62,6 +62,11 @@ The data for the channels is presented via normative type NTMultiChannel.
</div> <!-- head --> </div> <!-- head -->
<div id="toc">
<h2 class="nocount">Table of Contents</h2>
</div>
<!-- Place what you would like in the Table of Contents, inside the contents div -->
<div id="contents" class="contents"> <div id="contents" class="contents">
<hr /> <hr />
<h2>Overview</h2> <h2>Overview</h2>
@@ -71,10 +76,10 @@ pvaClientCPP is one of the components of
EPICS Version 4 EPICS Version 4
</a> </a>
</p> </p>
<p>This document is only a guide to help locate code and documentation related to pvaClientCPP <p>This document is only a guide to help locate code and documentation related to pvDatabaseCPP
</p> </p>
<p> <p>
It is intended for developers that want to use pvaClientCPP. It is intended for developers that want to use pvDatabaseCPP.
</p> </p>
<h2>Developer Guide</h2> <h2>Developer Guide</h2>
<p>A guide for developers is available at <p>A guide for developers is available at
@@ -83,11 +88,14 @@ href="http://epics-pvdata.sourceforge.net/informative/developerGuide/developerGu
developerGuide developerGuide
</a> </a>
</p> </p>
<p>This guide provides an overview of the components that are part of an <b>EPICS V4</b> release. <p>This guide discusses all the components that are part of an <b>EPICS V4</b> release.
Some understanding of the components and how they are related is necessary in order to Some understanding of the components and how they are related is necessary in order to
develop code that uses pvaClientCPP. develop code that uses pvDatabaseCPP.
In particular read everything related to pvaClient. In particular read everything related to pvaClient.
</p> </p>
<p>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.
</p>
<h2>doxygen</h2> <h2>doxygen</h2>
<p>doxygen documentation is available at <p>doxygen documentation is available at
@@ -96,9 +104,9 @@ href="./html/index.html">doxygen</a>
</p> </p>
<h2>exampleCPP</h2> <h2>exampleCPP</h2>
<p>Example code is available at <p>Example code is available as part of this release.
<a <a
href="https://github.com/epics-base/exampleCPP"> href="http://epics-pvdata.sourceforge.net/docbuild/exampleCPP/tip/documentation/exampleCPP.html">
exampleCPP exampleCPP
</a> </a>
</p> </p>
+15 -5
View File
@@ -21,22 +21,31 @@ installE4 () {
local module=$1 local module=$1
local branch=$2 local branch=$2
wget -nv https://openepics.ci.cloudbees.com/job/e4-cpp-${module}-${branch}-build/BASE=${BASE}/lastSuccessfulBuild/artifact/${module}.CB-dist.tar.gz # If microbench version does not exist, try without
if [ "${MB}" = "WITH_MICROBENCH" ]; then
if ! wget -nv https://openepics.ci.cloudbees.com/job/e4-cpp-${module}-${branch}-build/BASE=${BASE},MB=WITH_MICROBENCH/lastSuccessfulBuild/artifact/${module}.CB-dist.tar.gz; then
wget -nv https://openepics.ci.cloudbees.com/job/e4-cpp-${module}-${branch}-build/BASE=${BASE},MB=NO_MICROBENCH/lastSuccessfulBuild/artifact/${module}.CB-dist.tar.gz
fi
else
wget -nv https://openepics.ci.cloudbees.com/job/e4-cpp-${module}-${branch}-build/BASE=${BASE},MB=NO_MICROBENCH/lastSuccessfulBuild/artifact/${module}.CB-dist.tar.gz
fi
tar -xzf ${module}.CB-dist.tar.gz tar -xzf ${module}.CB-dist.tar.gz
} }
########################################### ###########################################
# Defaults for EPICS Base # Defaults for EPICS Base and MB
DEFAULT_BASE=3.15.4 DEFAULT_BASE=3.15.4
BASE=${BASE:-${DEFAULT_BASE}} BASE=${BASE:-${DEFAULT_BASE}}
MB=${MB:-"NO_MICROBENCH"}
########################################### ###########################################
# Dependent module branches # Dependent module branches
PVDATA_BRANCH="master" PVCOMMON_BRANCH="release-4.2"
PVACCESS_BRANCH="master" PVDATA_BRANCH="release-6.0"
NORMATIVETYPES_BRANCH="master" PVACCESS_BRANCH="release-5.0"
NORMATIVETYPES_BRANCH="release-5.1"
########################################### ###########################################
# Fetch and unpack dependencies # Fetch and unpack dependencies
@@ -50,6 +59,7 @@ cd ${STUFF}
installTool Boost 1.61.0 installTool Boost 1.61.0
installTool Base ${BASE} installTool Base ${BASE}
installE4 pvCommon ${PVCOMMON_BRANCH}
installE4 pvData ${PVDATA_BRANCH} installE4 pvData ${PVDATA_BRANCH}
installE4 pvAccess ${PVACCESS_BRANCH} installE4 pvAccess ${PVACCESS_BRANCH}
installE4 normativeTypes ${NORMATIVETYPES_BRANCH} installE4 normativeTypes ${NORMATIVETYPES_BRANCH}
+4 -4
View File
@@ -6,7 +6,7 @@ include $(TOP)/configure/CONFIG
LIBRARY += pvaClient LIBRARY += pvaClient
# shared library ABI version. # shared library ABI version.
SHRLIB_VERSION ?= 4.3.0 SHRLIB_VERSION ?= 4.2.0
INC += pv/pvaClient.h INC += pv/pvaClient.h
INC += pv/pvaClientMultiChannel.h INC += pv/pvaClientMultiChannel.h
@@ -31,8 +31,8 @@ LIBSRCS += pvaClientNTMultiGet.cpp
LIBSRCS += pvaClientNTMultiMonitor.cpp LIBSRCS += pvaClientNTMultiMonitor.cpp
LIBSRCS += pvaClientRPC.cpp LIBSRCS += pvaClientRPC.cpp
pvaClient_LIBS += nt pvaClient_LIBS += pvAccess nt pvData Com
pvaClient_LIBS += $(EPICS_BASE_PVA_CORE_LIBS) pvaClient_LIBS += $(EPICS_BASE_IOC_LIBS)
pvaClient_LIBS += $(EPICS_BASE_IOC_LIBS)
include $(TOP)/configure/RULES include $(TOP)/configure/RULES
+118 -392
View File
File diff suppressed because it is too large Load Diff
+32
View File
@@ -145,6 +145,10 @@ public:
*/ */
PvaClientNTMultiMonitorPtr createNTMonitor( PvaClientNTMultiMonitorPtr createNTMonitor(
std::string const &request= "field(value,alarm,timeStamp)"); std::string const &request= "field(value,alarm,timeStamp)");
/** Deprecated method
* \deprecated This method will go away in future versions.
*/
void destroy() EPICS_DEPRECATED {}
private: private:
PvaClientMultiChannel( PvaClientMultiChannel(
PvaClientPtr const &pvaClient, PvaClientPtr const &pvaClient,
@@ -205,6 +209,10 @@ public:
{ {
return shared_from_this(); return shared_from_this();
} }
/** Deprecated method
* \deprecated This method will go away in future versions.
*/
void destroy() EPICS_DEPRECATED {}
private: private:
PvaClientMultiGetDouble( PvaClientMultiGetDouble(
PvaClientMultiChannelPtr const &pvaClientMultiChannel, PvaClientMultiChannelPtr const &pvaClientMultiChannel,
@@ -254,6 +262,10 @@ public:
{ {
return shared_from_this(); return shared_from_this();
} }
/** Deprecated method
* \deprecated This method will go away in future versions.
*/
void destroy() EPICS_DEPRECATED {}
private: private:
PvaClientMultiPutDouble( PvaClientMultiPutDouble(
PvaClientMultiChannelPtr const &pvaClientMultiChannel, PvaClientMultiChannelPtr const &pvaClientMultiChannel,
@@ -317,6 +329,10 @@ public:
{ {
return shared_from_this(); return shared_from_this();
} }
/** Deprecated method
* \deprecated This method will go away in future versions.
*/
void destroy() EPICS_DEPRECATED {}
private: private:
PvaClientMultiMonitorDouble( PvaClientMultiMonitorDouble(
PvaClientMultiChannelPtr const &pvaClientMultiChannel, PvaClientMultiChannelPtr const &pvaClientMultiChannel,
@@ -374,6 +390,10 @@ public:
{ {
return shared_from_this(); return shared_from_this();
} }
/** Deprecated method
* \deprecated This method will go away in future versions.
*/
void destroy() EPICS_DEPRECATED {}
private: private:
PvaClientNTMultiGet( PvaClientNTMultiGet(
epics::pvData::UnionConstPtr const & u, epics::pvData::UnionConstPtr const & u,
@@ -433,6 +453,10 @@ public:
{ {
return shared_from_this(); return shared_from_this();
} }
/** Deprecated method
* \deprecated This method will go away in future versions.
*/
void destroy() EPICS_DEPRECATED {}
private: private:
PvaClientNTMultiPut( PvaClientNTMultiPut(
PvaClientMultiChannelPtr const &pvaClientMultiChannel, PvaClientMultiChannelPtr const &pvaClientMultiChannel,
@@ -499,6 +523,10 @@ public:
{ {
return shared_from_this(); return shared_from_this();
} }
/** Deprecated method
* \deprecated This method will go away in future versions.
*/
void destroy() EPICS_DEPRECATED {}
private: private:
PvaClientNTMultiMonitor( PvaClientNTMultiMonitor(
epics::pvData::UnionConstPtr const & u, epics::pvData::UnionConstPtr const & u,
@@ -573,6 +601,10 @@ public:
{ {
return shared_from_this(); return shared_from_this();
} }
/** Deprecated method
* \deprecated This method will go away in future versions.
*/
void destroy() EPICS_DEPRECATED {}
private: private:
PvaClientNTMultiData( PvaClientNTMultiData(
epics::pvData::UnionConstPtr const & u, epics::pvData::UnionConstPtr const & u,
+11 -32
View File
@@ -87,18 +87,7 @@ size_t PvaClientChannelCache::cacheSize()
} }
// MSVC doesn't like making this a class static data member: bool PvaClient::debug = false;
static bool debug = 0;
void PvaClient::setDebug(bool value)
{
debug = value;
}
bool PvaClient::getDebug()
{
return debug;
}
PvaClientPtr PvaClient::get(std::string const & providerNames) PvaClientPtr PvaClient::get(std::string const & providerNames)
{ {
@@ -115,53 +104,43 @@ PvaClientPtr PvaClient::get(std::string const & providerNames)
PvaClient::PvaClient(std::string const & providerNames) PvaClient::PvaClient(std::string const & providerNames)
: pvaClientChannelCache(new PvaClientChannelCache()), : pvaClientChannelCache(new PvaClientChannelCache()),
pvaStarted(false), pvaStarted(false),
caStarted(false), caStarted(false)
channelRegistry(ChannelProviderRegistry::clients())
{ {
stringstream ss(providerNames); stringstream ss(providerNames);
string providerName; string providerName;
if(getDebug()) {
cout<< "PvaClient::PvaClient()\n";
}
while (getline(ss, providerName, ' ')) while (getline(ss, providerName, ' '))
{ {
ChannelProviderRegistry::shared_pointer registry(getChannelProviderRegistry());
if(providerName=="pva") { if(providerName=="pva") {
if(getDebug()) {
cout<< "calling ClientFactory::start()\n";
}
ClientFactory::start(); ClientFactory::start();
pvaStarted = true; pvaStarted = true;
} else if(providerName=="ca") { } else if(providerName=="ca") {
if(getDebug()) {
cout<< "calling CAClientFactory::start()\n";
}
CAClientFactory::start(); CAClientFactory::start();
caStarted = true; caStarted = true;
} else { } else {
if(!channelRegistry->getProvider(providerName)) { if(!registry->getProvider(providerName)) {
cerr << "PvaClient::get provider " << providerName << " not known" << endl; cerr << "PvaClient::get provider " << providerName << " not known" << endl;
} }
} }
} }
} }
PvaClient::~PvaClient() { PvaClient::~PvaClient() {
if(getDebug()) { if(PvaClient::debug) {
cout<< "PvaClient::~PvaClient()\n" cout<< "PvaClient::~PvaClient()\n"
<< "pvaChannel cache:\n"; << "pvaChannel cache:\n";
showCache(); showCache();
} }
if(pvaStarted){ if(pvaStarted){
if(getDebug()) cout<< "calling ClientFactory::stop()\n"; if(PvaClient::debug) cout<< "calling ClientFactory::stop()\n";
ClientFactory::stop(); ClientFactory::stop();
if(getDebug()) cout<< "after calling ClientFactory::stop()\n"; if(PvaClient::debug) cout<< "after calling ClientFactory::stop()\n";
} }
if(caStarted) { if(caStarted) {
if(getDebug()) cout<< "calling CAClientFactory::stop()\n"; if(PvaClient::debug) cout<< "calling CAClientFactory::stop()\n";
CAClientFactory::stop(); CAClientFactory::stop();
if(getDebug()) cout<< "after calling CAClientFactory::stop()\n"; if(PvaClient::debug) cout<< "after calling CAClientFactory::stop()\n";
} }
channelRegistry.reset();
} }
string PvaClient:: getRequesterName() string PvaClient:: getRequesterName()
+80 -42
View File
@@ -122,12 +122,60 @@ 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( PvaClientChannelPtr PvaClientChannel::create(
PvaClientPtr const &pvaClient, PvaClientPtr const &pvaClient,
string const & channelName, string const & channelName,
string const & providerName) string const & providerName)
{ {
PvaClientChannelPtr channel(new PvaClientChannel(pvaClient,channelName,providerName)); PvaClientChannelPtr channel(new PvaClientChannel(pvaClient,channelName,providerName));
channel->channelRequester = ChannelRequesterImplPtr(
new ChannelRequesterImpl(channel,pvaClient));
return channel; return channel;
} }
@@ -198,26 +246,25 @@ void PvaClientChannel::channelStateChange(
<< " " << Channel::ConnectionStateNames[connectionState] << " " << Channel::ConnectionStateNames[connectionState]
<< endl; << 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()); PvaClientChannelStateChangeRequesterPtr req(stateChangeRequester.lock());
if(req) { if(req) {
bool value = (connectionState==Channel::CONNECTED ? true : false); bool value = (connectionState==Channel::CONNECTED ? true : false);
req->channelStateChange(shared_from_this(),value); 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() string PvaClientChannel::getRequesterName()
@@ -250,9 +297,6 @@ void PvaClientChannel::setStateChangeRequester(
PvaClientChannelStateChangeRequesterPtr const & stateChangeRequester) PvaClientChannelStateChangeRequesterPtr const & stateChangeRequester)
{ {
this->stateChangeRequester = stateChangeRequester; this->stateChangeRequester = stateChangeRequester;
bool isConnected = false;
if(channel) isConnected = channel->isConnected();
stateChangeRequester->channelStateChange(shared_from_this(),isConnected);
} }
void PvaClientChannel::connect(double timeout) void PvaClientChannel::connect(double timeout)
@@ -284,13 +328,13 @@ void PvaClientChannel::issueConnect()
} }
connectState = connectActive; connectState = connectActive;
} }
ChannelProviderRegistry::shared_pointer reg(ChannelProviderRegistry::clients()); ChannelProviderRegistry::shared_pointer reg = getChannelProviderRegistry();
channelProvider = reg->getProvider(providerName); ChannelProvider::shared_pointer provider = reg->getProvider(providerName);
if(!channelProvider) { if(!provider) {
throw std::runtime_error(channelName + " provider " + providerName + " not registered"); throw std::runtime_error(channelName + " provider " + providerName + " not registered");
} }
if(PvaClient::getDebug()) cout << "PvaClientChannel::issueConnect calling provider->createChannel\n"; if(PvaClient::getDebug()) cout << "PvaClientChannel::issueConnect calling provider->createChannel\n";
channel = channelProvider->createChannel(channelName,shared_from_this(),ChannelProvider::PRIORITY_DEFAULT); channel = provider->createChannel(channelName,channelRequester,ChannelProvider::PRIORITY_DEFAULT);
if(!channel) { if(!channel) {
throw std::runtime_error(channelName + " channelCreate failed "); throw std::runtime_error(channelName + " channelCreate failed ");
} }
@@ -304,7 +348,6 @@ Status PvaClientChannel::waitConnect(double timeout)
} }
{ {
Lock xx(mutex); Lock xx(mutex);
if(!channel) return Status(Status::STATUSTYPE_ERROR,"");
if(channel->isConnected()) return Status::Ok; if(channel->isConnected()) return Status::Ok;
} }
if(timeout>0.0) { if(timeout>0.0) {
@@ -312,9 +355,8 @@ Status PvaClientChannel::waitConnect(double timeout)
} else { } else {
waitForConnect.wait(); waitForConnect.wait();
} }
if(!channel) return Status(Status::STATUSTYPE_ERROR,"pvaClientChannel::waitConnect channel is null");
if(channel->isConnected()) return Status::Ok; if(channel->isConnected()) return Status::Ok;
return Status(Status::STATUSTYPE_ERROR," not connected"); return Status(Status::STATUSTYPE_ERROR,channelName + " not connected");
} }
@@ -341,19 +383,17 @@ PvaClientProcessPtr PvaClientChannel::createProcess(PVStructurePtr const & pvRe
if(connectState!=connected) connect(5.0); if(connectState!=connected) connect(5.0);
PvaClientPtr yyy = pvaClient.lock(); PvaClientPtr yyy = pvaClient.lock();
if(!yyy) throw std::runtime_error("PvaClient was destroyed"); if(!yyy) throw std::runtime_error("PvaClient was destroyed");
return PvaClientProcess::create(yyy,shared_from_this(),pvRequest); return PvaClientProcess::create(yyy,channel,pvRequest);
} }
PvaClientGetPtr PvaClientChannel::get(string const & request) PvaClientGetPtr PvaClientChannel::get(string const & request)
{ {
PvaClientGetPtr pvaClientGet = pvaClientGetCache->getGet(request); PvaClientGetPtr pvaClientGet = pvaClientGetCache->getGet(request);
if(!pvaClientGet) { if(pvaClientGet) return pvaClientGet;
pvaClientGet = createGet(request); pvaClientGet = createGet(request);
pvaClientGet->connect(); pvaClientGet->connect();
pvaClientGetCache->addGet(request,pvaClientGet); pvaClientGetCache->addGet(request,pvaClientGet);
}
pvaClientGet->get();
return pvaClientGet; return pvaClientGet;
} }
@@ -375,7 +415,7 @@ PvaClientGetPtr PvaClientChannel::createGet(PVStructurePtr const & pvRequest)
if(connectState!=connected) connect(5.0); if(connectState!=connected) connect(5.0);
PvaClientPtr yyy = pvaClient.lock(); PvaClientPtr yyy = pvaClient.lock();
if(!yyy) throw std::runtime_error("PvaClient was destroyed"); if(!yyy) throw std::runtime_error("PvaClient was destroyed");
return PvaClientGet::create(yyy,shared_from_this(),pvRequest); return PvaClientGet::create(yyy,channel,pvRequest);
} }
@@ -383,12 +423,10 @@ PvaClientPutPtr PvaClientChannel::put(string const & request)
{ {
PvaClientPutPtr pvaClientPut = pvaClientPutCache->getPut(request); PvaClientPutPtr pvaClientPut = pvaClientPutCache->getPut(request);
if(pvaClientPut) return pvaClientPut; if(pvaClientPut) return pvaClientPut;
if(!pvaClientPut) { pvaClientPut = createPut(request);
pvaClientPut = createPut(request); pvaClientPut->connect();
pvaClientPut->connect(); pvaClientPut->get();
pvaClientPut->get(); pvaClientPutCache->addPut(request,pvaClientPut);
pvaClientPutCache->addPut(request,pvaClientPut);
}
return pvaClientPut; return pvaClientPut;
} }
@@ -410,7 +448,7 @@ PvaClientPutPtr PvaClientChannel::createPut(PVStructurePtr const & pvRequest)
if(connectState!=connected) connect(5.0); if(connectState!=connected) connect(5.0);
PvaClientPtr yyy = pvaClient.lock(); PvaClientPtr yyy = pvaClient.lock();
if(!yyy) throw std::runtime_error("PvaClient was destroyed"); if(!yyy) throw std::runtime_error("PvaClient was destroyed");
return PvaClientPut::create(yyy,shared_from_this(),pvRequest); return PvaClientPut::create(yyy,channel,pvRequest);
} }
PvaClientPutGetPtr PvaClientChannel::createPutGet(string const & request) PvaClientPutGetPtr PvaClientChannel::createPutGet(string const & request)
@@ -430,7 +468,7 @@ PvaClientPutGetPtr PvaClientChannel::createPutGet(PVStructurePtr const & pvReque
if(connectState!=connected) connect(5.0); if(connectState!=connected) connect(5.0);
PvaClientPtr yyy = pvaClient.lock(); PvaClientPtr yyy = pvaClient.lock();
if(!yyy) throw std::runtime_error("PvaClient was destroyed"); if(!yyy) throw std::runtime_error("PvaClient was destroyed");
return PvaClientPutGet::create(yyy,shared_from_this(),pvRequest); return PvaClientPutGet::create(yyy,channel,pvRequest);
} }
@@ -494,7 +532,7 @@ PvaClientMonitorPtr PvaClientChannel::createMonitor(PVStructurePtr const & pvR
if(connectState!=connected) connect(5.0); if(connectState!=connected) connect(5.0);
PvaClientPtr yyy = pvaClient.lock(); PvaClientPtr yyy = pvaClient.lock();
if(!yyy) throw std::runtime_error("PvaClient was destroyed"); if(!yyy) throw std::runtime_error("PvaClient was destroyed");
return PvaClientMonitor::create(yyy,shared_from_this(),pvRequest); return PvaClientMonitor::create(yyy,channel,pvRequest);
} }
PVStructurePtr PvaClientChannel::rpc( PVStructurePtr PvaClientChannel::rpc(
+60 -138
View File
@@ -73,34 +73,29 @@ public:
PvaClientGetPtr PvaClientGet::create( PvaClientGetPtr PvaClientGet::create(
PvaClientPtr const &pvaClient, PvaClientPtr const &pvaClient,
PvaClientChannelPtr const & pvaClientChannel, Channel::shared_pointer const & channel,
PVStructurePtr const &pvRequest) PVStructurePtr const &pvRequest)
{ {
if(PvaClient::getDebug()) { PvaClientGetPtr epv(new PvaClientGet(pvaClient,channel,pvRequest));
cout<< "PvaClientGet::create(pvaClient,channelName,pvRequest)\n" epv->channelGetRequester = ChannelGetRequesterImplPtr(
<< " channelName " << pvaClientChannel->getChannel()->getChannelName() new ChannelGetRequesterImpl(epv,pvaClient));
<< " pvRequest " << pvRequest return epv;
<< endl;
}
PvaClientGetPtr clientGet(new PvaClientGet(pvaClient,pvaClientChannel,pvRequest));
clientGet->channelGetRequester = ChannelGetRequesterImplPtr(
new ChannelGetRequesterImpl(clientGet,pvaClient));
return clientGet;
} }
PvaClientGet::PvaClientGet( PvaClientGet::PvaClientGet(
PvaClientPtr const &pvaClient, PvaClientPtr const &pvaClient,
PvaClientChannelPtr const & pvaClientChannel, Channel::shared_pointer const & channel,
PVStructurePtr const &pvRequest) PVStructurePtr const &pvRequest)
: pvaClient(pvaClient), : pvaClient(pvaClient),
pvaClientChannel(pvaClientChannel), channel(channel),
pvRequest(pvRequest), pvRequest(pvRequest),
connectState(connectIdle), connectState(connectIdle),
getState(getIdle) getState(getIdle)
{ {
if(PvaClient::getDebug()) { if(PvaClient::getDebug()) {
cout << "PvaClientGet::PvaClientGet::PvaClientGet" cout << "PvaClientGet::PvaClientGet::PvaClientGet"
<< " channelName " << pvaClientChannel->getChannel()->getChannelName() << " channelName " << channel->getChannelName()
<< endl; << endl;
} }
} }
@@ -108,52 +103,20 @@ PvaClientGet::PvaClientGet(
PvaClientGet::~PvaClientGet() PvaClientGet::~PvaClientGet()
{ {
if(PvaClient::getDebug()) { if(PvaClient::getDebug()) {
cout<< "PvaClientGet::~PvaClientGet" string channelName("disconnected");
<< " channelName " << pvaClientChannel->getChannel()->getChannelName() Channel::shared_pointer chan(channel.lock());
if(chan) channelName = chan->getChannelName();
cout<< "PvaClientGet::~PvaClientGet"
<< " channelName " << channelName
<< endl; << 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() void PvaClientGet::checkGetState()
{ {
if(PvaClient::getDebug()) { if(connectState==connectIdle) connect();
cout << "PvaClientGet::checkGetState" if(getState==getIdle) get();
<< " 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==connectActive){
string message = string("channel ") + pvaClientChannel->getChannel()->getChannelName()
+ " "
+ channelGetConnectStatus.getMessage();
throw std::runtime_error(message);
}
} }
// from ChannelGetRequester // from ChannelGetRequester
@@ -177,32 +140,24 @@ void PvaClientGet::channelGetConnect(
StructureConstPtr const & structure) StructureConstPtr const & structure)
{ {
if(PvaClient::getDebug()) { if(PvaClient::getDebug()) {
string channelName("disconnected");
Channel::shared_pointer chan(channel.lock());
if(chan) channelName = chan->getChannelName();
cout << "PvaClientGet::channelGetConnect" cout << "PvaClientGet::channelGetConnect"
<< " channelName " << pvaClientChannel->getChannel()->getChannelName() << " channelName " << channelName
<< " status.isOK " << (status.isOK() ? "true" : "false") << " status.isOK " << (status.isOK() ? "true" : "false")
<< endl; << endl;
} }
{ {
Lock xx(mutex); Lock xx(mutex);
channelGetConnectStatus = status;
connectState = connected;
this->channelGet = channelGet; this->channelGet = channelGet;
if(status.isOK()) { if(status.isOK()) {
channelGetConnectStatus = status;
connectState = connected;
pvaClientData = PvaClientGetData::create(structure); pvaClientData = PvaClientGetData::create(structure);
pvaClientData->setMessagePrefix(channelGet->getChannel()->getChannelName()); 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());
if(req) {
req->channelGetConnect(status,shared_from_this());
}
waitForConnect.signal(); waitForConnect.signal();
} }
@@ -214,65 +169,57 @@ void PvaClientGet::getDone(
BitSetPtr const & bitSet) BitSetPtr const & bitSet)
{ {
if(PvaClient::getDebug()) { if(PvaClient::getDebug()) {
string channelName("disconnected");
Channel::shared_pointer chan(channel.lock());
if(chan) channelName = chan->getChannelName();
cout << "PvaClientGet::getDone" cout << "PvaClientGet::getDone"
<< " channelName " << pvaClientChannel->getChannel()->getChannelName() << " channelName " << channelName
<< " status.isOK " << (status.isOK() ? "true" : "false") << " status.isOK " << (status.isOK() ? "true" : "false")
<< endl; << endl;
} }
{ {
Lock xx(mutex); Lock xx(mutex);
channelGetStatus = status; channelGetStatus = status;
getState = getComplete;
if(status.isOK()) { if(status.isOK()) {
pvaClientData->setData(pvStructure,bitSet); pvaClientData->setData(pvStructure,bitSet);
} }
} }
PvaClientGetRequesterPtr req(pvaClientGetRequester.lock());
if(req) {
req->getDone(status,shared_from_this());
}
waitForGet.signal(); waitForGet.signal();
} }
void PvaClientGet::connect() void PvaClientGet::connect()
{ {
if(PvaClient::getDebug()) {
cout << "PvaClientGet::connect"
<< " channelName " << pvaClientChannel->getChannel()->getChannelName()
<< endl;
}
issueConnect(); issueConnect();
Status status = waitConnect(); Status status = waitConnect();
if(status.isOK()) return; if(status.isOK()) return;
string message = string("channel ") + pvaClientChannel->getChannel()->getChannelName() Channel::shared_pointer chan(channel.lock());
string channelName("disconnected");
if(chan) channelName = chan->getChannelName();
string message = string("channel ") + channelName
+ " PvaClientGet::connect " + status.getMessage(); + " PvaClientGet::connect " + status.getMessage();
throw std::runtime_error(message); throw std::runtime_error(message);
} }
void PvaClientGet::issueConnect() void PvaClientGet::issueConnect()
{ {
if(PvaClient::getDebug()) { Channel::shared_pointer chan(channel.lock());
cout << "PvaClientGet::issueConnect"
<< " channelName " << pvaClientChannel->getChannel()->getChannelName()
<< endl;
}
if(connectState!=connectIdle) { if(connectState!=connectIdle) {
string message = string("channel ") + pvaClientChannel->getChannel()->getChannelName() string channelName("disconnected");
if(chan) channelName = chan->getChannelName();
string message = string("channel ") + channelName
+ " pvaClientGet already connected "; + " pvaClientGet already connected ";
throw std::runtime_error(message); throw std::runtime_error(message);
} }
connectState = connectActive; if(chan) {
channelGetConnectStatus = Status(Status::STATUSTYPE_ERROR, "connect active"); connectState = connectActive;
channelGet = pvaClientChannel->getChannel()->createChannelGet(channelGetRequester,pvRequest); channelGet = chan->createChannelGet(channelGetRequester,pvRequest);
return;
}
throw std::runtime_error("PvaClientGet::issueConnect channel was destroyed");
} }
Status PvaClientGet::waitConnect() Status PvaClientGet::waitConnect()
{ {
if(PvaClient::getDebug()) {
cout << "PvaClientGet::waitConnect"
<< " channelName " << pvaClientChannel->getChannel()->getChannelName()
<< endl;
}
{ {
Lock xx(mutex); Lock xx(mutex);
if(connectState==connected) { if(connectState==connected) {
@@ -280,7 +227,10 @@ Status PvaClientGet::waitConnect()
return channelGetConnectStatus; return channelGetConnectStatus;
} }
if(connectState!=connectActive) { if(connectState!=connectActive) {
string message = string("channel ") + pvaClientChannel->getChannel()->getChannelName() Channel::shared_pointer chan(channel.lock());
string channelName("disconnected");
if(chan) channelName = chan->getChannelName();
string message = string("channel ") + channelName
+ " PvaClientGet::waitConnect illegal connect state "; + " PvaClientGet::waitConnect illegal connect state ";
throw std::runtime_error(message); throw std::runtime_error(message);
} }
@@ -292,29 +242,25 @@ Status PvaClientGet::waitConnect()
void PvaClientGet::get() void PvaClientGet::get()
{ {
if(PvaClient::getDebug()) {
cout << "PvaClientGet::get"
<< " channelName " << pvaClientChannel->getChannel()->getChannelName()
<< endl;
}
issueGet(); issueGet();
Status status = waitGet(); Status status = waitGet();
if(status.isOK()) return; if(status.isOK()) return;
string message = string("channel ") + pvaClientChannel->getChannel()->getChannelName() Channel::shared_pointer chan(channel.lock());
string channelName("disconnected");
if(chan) channelName = chan->getChannelName();
string message = string("channel ") + channelName
+ " PvaClientGet::get " + status.getMessage(); + " PvaClientGet::get " + status.getMessage();
throw std::runtime_error(message); throw std::runtime_error(message);
} }
void PvaClientGet::issueGet() void PvaClientGet::issueGet()
{ {
if(PvaClient::getDebug()) {
cout << "PvaClientGet::issueGet"
<< " channelName " << pvaClientChannel->getChannel()->getChannelName()
<< endl;
}
if(connectState==connectIdle) connect(); if(connectState==connectIdle) connect();
if(getState==getActive) { if(getState!=getIdle) {
string message = string("channel ") + pvaClientChannel->getChannel()->getChannelName() Channel::shared_pointer chan(channel.lock());
string channelName("disconnected");
if(chan) channelName = chan->getChannelName();
string message = string("channel ") + channelName
+ " PvaClientGet::issueGet get aleady active "; + " PvaClientGet::issueGet get aleady active ";
throw std::runtime_error(message); throw std::runtime_error(message);
} }
@@ -324,54 +270,30 @@ void PvaClientGet::issueGet()
Status PvaClientGet::waitGet() Status PvaClientGet::waitGet()
{ {
if(PvaClient::getDebug()) {
cout << "PvaClientGet::waitGet"
<< " channelName " << pvaClientChannel->getChannel()->getChannelName()
<< endl;
}
{ {
Lock xx(mutex); Lock xx(mutex);
if(getState==getComplete) { if(getState==getComplete) {
getState = getIdle; getState =getIdle;
return channelGetStatus; return channelGetStatus;
} }
if(getState!=getActive){ if(getState!=getActive){
string message = string("channel ") + pvaClientChannel->getChannel()->getChannelName() Channel::shared_pointer chan(channel.lock());
string channelName("disconnected");
if(chan) channelName = chan->getChannelName();
string message = string("channel ") + channelName
+ " PvaClientGet::waitGet llegal get state"; + " PvaClientGet::waitGet llegal get state";
throw std::runtime_error(message); throw std::runtime_error(message);
} }
} }
waitForGet.wait(); waitForGet.wait();
getState = getComplete; getState = getIdle;
return channelGetStatus; return channelGetStatus;
} }
PvaClientGetDataPtr PvaClientGet::getData() PvaClientGetDataPtr PvaClientGet::getData()
{ {
if(PvaClient::getDebug()) {
cout<< "PvaClientGet::getData"
<< " channelName " << pvaClientChannel->getChannel()->getChannelName()
<< endl;
}
checkGetState(); checkGetState();
if(getState==getIdle) get();
return pvaClientData; 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;
}
}} }}
+1 -16
View File
@@ -42,29 +42,18 @@ static string noTimeStamp("no timeStamp");
PvaClientGetDataPtr PvaClientGetData::create(StructureConstPtr const & structure) PvaClientGetDataPtr PvaClientGetData::create(StructureConstPtr const & structure)
{ {
if(PvaClient::getDebug()) {
cout << "PvaClientGetData::create"
<< endl;
}
PvaClientGetDataPtr epv(new PvaClientGetData(structure)); PvaClientGetDataPtr epv(new PvaClientGetData(structure));
return epv; return epv;
} }
PvaClientGetData::PvaClientGetData(StructureConstPtr const & structure) PvaClientGetData::PvaClientGetData(StructureConstPtr const & structure)
: structure(structure), : structure(structure)
pvStructure(getPVDataCreate()->createPVStructure(structure)),
bitSet(BitSetPtr(new BitSet(pvStructure->getNumberFields())))
{ {
messagePrefix = ""; messagePrefix = "";
pvValue = pvStructure->getSubField("value");
} }
void PvaClientGetData::checkValue() void PvaClientGetData::checkValue()
{ {
if(PvaClient::getDebug()) {
cout << "PvaClientGetData::checkValue"
<< endl;
}
if(pvValue) return; if(pvValue) return;
throw std::runtime_error(messagePrefix + noValue); throw std::runtime_error(messagePrefix + noValue);
} }
@@ -111,10 +100,6 @@ void PvaClientGetData::setData(
PVStructurePtr const & pvStructureFrom, PVStructurePtr const & pvStructureFrom,
BitSetPtr const & bitSetFrom) BitSetPtr const & bitSetFrom)
{ {
if(PvaClient::getDebug()) {
cout << "PvaClientGetData::setData"
<< endl;
}
pvStructure = pvStructureFrom; pvStructure = pvStructureFrom;
bitSet = bitSetFrom; bitSet = bitSetFrom;
pvValue = pvStructure->getSubField("value"); pvValue = pvStructure->getSubField("value");
+140 -192
View File
@@ -80,56 +80,21 @@ public:
PvaClientMonitorPtr PvaClientMonitor::create( PvaClientMonitorPtr PvaClientMonitor::create(
PvaClientPtr const &pvaClient, PvaClientPtr const &pvaClient,
PvaClientChannelPtr const & pvaClientChannel, Channel::shared_pointer const & channel,
PVStructurePtr const &pvRequest) PVStructurePtr const &pvRequest)
{ {
if(PvaClient::getDebug()) { PvaClientMonitorPtr epv(new PvaClientMonitor(pvaClient,channel,pvRequest));
cout<< "PvaClientMonitor::create(pvaClient,pvaClientChannel,pvRequest)\n" epv->monitorRequester = MonitorRequesterImplPtr(
<< " channelName " << pvaClientChannel->getChannel()->getChannelName() new MonitorRequesterImpl(epv,pvaClient));
<< endl; return epv;
}
PvaClientMonitorPtr clientMonitor(new PvaClientMonitor(pvaClient,pvaClientChannel,pvRequest));
clientMonitor->monitorRequester = MonitorRequesterImplPtr(
new MonitorRequesterImpl(clientMonitor,pvaClient));
return clientMonitor;
} }
PvaClientMonitorPtr PvaClientMonitor::create(
PvaClientPtr const &pvaClient,
std::string const & channelName,
std::string const & providerName,
std::string const & request,
PvaClientChannelStateChangeRequesterPtr const & stateChangeRequester,
PvaClientMonitorRequesterPtr const & monitorRequester)
{
if(PvaClient::getDebug()) {
cout<< "PvaClientMonitor::create(pvaClient,channelName,providerName,request,stateChangeRequester,monitorRequester)\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);
PvaClientMonitorPtr clientMonitor(new PvaClientMonitor(pvaClient,pvaClientChannel,pvRequest));
clientMonitor->monitorRequester = MonitorRequesterImplPtr(
new MonitorRequesterImpl(clientMonitor,pvaClient));
if(stateChangeRequester) clientMonitor->pvaClientChannelStateChangeRequester = stateChangeRequester;
if(monitorRequester) clientMonitor->pvaClientMonitorRequester = monitorRequester;
pvaClientChannel->setStateChangeRequester(clientMonitor);
pvaClientChannel->issueConnect();
return clientMonitor;
}
PvaClientMonitor::PvaClientMonitor( PvaClientMonitor::PvaClientMonitor(
PvaClientPtr const &pvaClient, PvaClientPtr const &pvaClient,
PvaClientChannelPtr const & pvaClientChannel, Channel::shared_pointer const & channel,
PVStructurePtr const &pvRequest) PVStructurePtr const &pvRequest)
: pvaClient(pvaClient), : pvaClient(pvaClient),
pvaClientChannel(pvaClientChannel), channel(channel),
pvRequest(pvRequest), pvRequest(pvRequest),
isStarted(false), isStarted(false),
connectState(connectIdle), connectState(connectIdle),
@@ -137,66 +102,42 @@ PvaClientMonitor::PvaClientMonitor(
userWait(false) userWait(false)
{ {
if(PvaClient::getDebug()) { if(PvaClient::getDebug()) {
cout<< "PvaClientMonitor::PvaClientMonitor()" << endl; cout<< "PvaClientMonitor::PvaClientMonitor()"
<< " channelName " << channel->getChannelName()
<< endl;
} }
} }
PvaClientMonitor::~PvaClientMonitor() PvaClientMonitor::~PvaClientMonitor()
{ {
if(PvaClient::getDebug()) cout<< "PvaClientMonitor::~PvaClientMonitor\n";
if(PvaClient::getDebug()) { if(PvaClient::getDebug()) {
string channelName("disconnected");
Channel::shared_pointer chan(channel.lock());
if(chan) channelName = chan->getChannelName();
cout<< "PvaClientMonitor::~PvaClientMonitor" cout<< "PvaClientMonitor::~PvaClientMonitor"
<< " channelName " << pvaClientChannel->getChannel()->getChannelName() << " channelName " << channelName
<< endl; << endl;
} }
if(monitor) { if(monitor) {
if(isStarted) monitor->stop(); if(isStarted) monitor->stop();
monitor->destroy();
} }
} }
void PvaClientMonitor::channelStateChange(PvaClientChannelPtr const & channel, bool isConnected)
{
if(PvaClient::getDebug()) {
cout<< "PvaClientMonitor::channelStateChange"
<< " channelName " << channel->getChannelName()
<< " isConnected " << (isConnected ? "true" : "false")
<< endl;
}
if(isConnected&&!monitor)
{
connectState = connectActive;
monitor = pvaClientChannel->getChannel()->createMonitor(monitorRequester,pvRequest);
}
PvaClientChannelStateChangeRequesterPtr req(pvaClientChannelStateChangeRequester.lock());
if(req) {
req->channelStateChange(channel,isConnected);
}
}
void PvaClientMonitor::event(PvaClientMonitorPtr const & monitor)
{
PvaClientMonitorRequesterPtr req(pvaClientMonitorRequester.lock());
if(req) req->event(monitor);
}
void PvaClientMonitor::checkMonitorState() void PvaClientMonitor::checkMonitorState()
{ {
if(PvaClient::getDebug()) { if(PvaClient::getDebug()) {
string channelName("disconnected");
Channel::shared_pointer chan(channel.lock());
if(chan) channelName = chan->getChannelName();
cout << "PvaClientMonitor::checkMonitorState" cout << "PvaClientMonitor::checkMonitorState"
<< " channelName " << pvaClientChannel->getChannel()->getChannelName() << " channelName " << channelName
<< " connectState " << connectState << " connectState " << connectState
<< endl; << endl;
} }
if(connectState==connectIdle) { if(connectState==connectIdle) connect();
connect(); if(connectState==connected && !isStarted) start();
if(!isStarted) start();
return;
}
if(connectState==connectActive){
string message = string("channel ") + pvaClientChannel->getChannel()->getChannelName()
+ " "
+ monitorConnectStatus.getMessage();
throw std::runtime_error(message);
}
} }
string PvaClientMonitor::getRequesterName() string PvaClientMonitor::getRequesterName()
@@ -218,63 +159,50 @@ void PvaClientMonitor::monitorConnect(
Monitor::shared_pointer const & monitor, Monitor::shared_pointer const & monitor,
StructureConstPtr const & structure) StructureConstPtr const & structure)
{ {
Channel::shared_pointer chan(channel.lock());
if(PvaClient::getDebug()) { if(PvaClient::getDebug()) {
string channelName("disconnected");
Channel::shared_pointer chan(channel.lock());
if(chan) channelName = chan->getChannelName();
cout << "PvaClientMonitor::monitorConnect" cout << "PvaClientMonitor::monitorConnect"
<< " channelName " << pvaClientChannel->getChannel()->getChannelName() << " channelName " << channelName
<< " status.isOK " << (status.isOK() ? "true" : "false") << " status.isOK " << (status.isOK() ? "true" : "false")
<< endl; << endl;
} }
{ connectStatus = status;
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;
monitorConnectStatus = status;
connectState = connected; connectState = connected;
this->monitor = monitor;
if(isStarted) { if(isStarted) {
if(PvaClient::getDebug()) { if(PvaClient::getDebug()) {
string channelName("disconnected");
Channel::shared_pointer chan(channel.lock());
if(chan) channelName = chan->getChannelName();
cout << "PvaClientMonitor::monitorConnect" cout << "PvaClientMonitor::monitorConnect"
<< " channelName " << pvaClientChannel->getChannel()->getChannelName() << " channelName " << channelName
<< " is already started " << " is already started "
<< endl; << endl;
} }
return; return;
} }
pvaClientData = PvaClientMonitorData::create(structure); if(status.isOK() && chan) {
pvaClientData->setMessagePrefix(pvaClientChannel->getChannel()->getChannelName()); pvaClientData = PvaClientMonitorData::create(structure);
if(signal) { pvaClientData->setMessagePrefix(chan->getChannelName());
if(PvaClient::getDebug()) {
cout << "PvaClientMonitor::monitorConnect calling waitForConnect.signal\n";
}
waitForConnect.signal();
if(PvaClient::getDebug()) {
cout << "PvaClientMonitor::monitorConnect calling start\n";
}
start();
} else {
if(PvaClient::getDebug()) {
cout << "PvaClientMonitor::monitorConnect calling start\n";
}
start();
} }
PvaClientMonitorRequesterPtr req(pvaClientMonitorRequester.lock()); if(PvaClient::getDebug()) {
if(req) req->monitorConnect(status,shared_from_this(),structure); cout << "PvaClientMonitor::monitorConnect calling waitForConnect.signal\n";
}
waitForConnect.signal();
} }
void PvaClientMonitor::monitorEvent(MonitorPtr const & monitor) void PvaClientMonitor::monitorEvent(MonitorPtr const & monitor)
{ {
if(PvaClient::getDebug()) { if(PvaClient::getDebug()) {
string channelName("disconnected");
Channel::shared_pointer chan(channel.lock());
if(chan) channelName = chan->getChannelName();
cout << "PvaClientMonitor::monitorEvent" cout << "PvaClientMonitor::monitorEvent"
<< " channelName " << pvaClientChannel->getChannel()->getChannelName() << " channelName " << channelName
<< endl; << endl;
} }
PvaClientMonitorRequesterPtr req = pvaClientMonitorRequester.lock(); PvaClientMonitorRequesterPtr req = pvaClientMonitorRequester.lock();
@@ -290,7 +218,10 @@ void PvaClientMonitor::unlisten(MonitorPtr const & monitor)
req->unlisten(); req->unlisten();
return; return;
} }
cerr << pvaClientChannel->getChannel()->getChannelName() + "pvaClientMonitor::unlisten called but no PvaClientMonitorRequester\n"; string channelName("disconnected");
Channel::shared_pointer chan(channel.lock());
if(chan) channelName = chan->getChannelName();
cerr << channelName + "pvaClientMonitor::unlisten called but no PvaClientMonitorRequester\n";
} }
@@ -300,8 +231,11 @@ void PvaClientMonitor::connect()
issueConnect(); issueConnect();
Status status = waitConnect(); Status status = waitConnect();
if(status.isOK()) return; if(status.isOK()) return;
Channel::shared_pointer chan(channel.lock());
string channelName("disconnected");
if(chan) channelName = chan->getChannelName();
string message = string("channel ") string message = string("channel ")
+ pvaClientChannel->getChannel()->getChannelName() + channelName
+ " PvaClientMonitor::connect " + " PvaClientMonitor::connect "
+ status.getMessage(); + status.getMessage();
throw std::runtime_error(message); throw std::runtime_error(message);
@@ -310,50 +244,59 @@ void PvaClientMonitor::connect()
void PvaClientMonitor::issueConnect() void PvaClientMonitor::issueConnect()
{ {
if(PvaClient::getDebug()) cout << "PvaClientMonitor::issueConnect\n"; if(PvaClient::getDebug()) cout << "PvaClientMonitor::issueConnect\n";
Channel::shared_pointer chan(channel.lock());
if(connectState!=connectIdle) { if(connectState!=connectIdle) {
string channelName("disconnected");
if(chan) channelName = chan->getChannelName();
string message = string("channel ") string message = string("channel ")
+ pvaClientChannel->getChannel()->getChannelName() + channelName
+ " pvaClientMonitor already connected "; + " pvaClientMonitor already connected ";
throw std::runtime_error(message); throw std::runtime_error(message);
} }
connectState = connectWait; if(chan) {
monitor = pvaClientChannel->getChannel()->createMonitor(monitorRequester,pvRequest); connectState = connectActive;
monitor = chan->createMonitor(monitorRequester,pvRequest);
return;
}
throw std::runtime_error("PvaClientMonitor::issueConnect() but channel disconnected");
} }
Status PvaClientMonitor::waitConnect() Status PvaClientMonitor::waitConnect()
{ {
if(PvaClient::getDebug()) { if(PvaClient::getDebug()) cout << "PvaClientMonitor::waitConnect\n";
cout << "PvaClientMonitor::waitConnect " if(connectState==connected) {
<< pvaClientChannel->getChannel()->getChannelName() if(!connectStatus.isOK()) connectState = connectIdle;
<< endl; return connectStatus;
} }
{ if(connectState!=connectActive) {
Lock xx(mutex); Channel::shared_pointer chan(channel.lock());
if(connectState==connected) { string channelName("disconnected");
if(!monitorConnectStatus.isOK()) connectState = connectIdle; if(chan) channelName = chan->getChannelName();
return monitorConnectStatus; string message = string("channel ")
} + channelName
if(connectState!=connectWait) { + " PvaClientMonitor::waitConnect illegal connect state ";
string message = string("channel ") + pvaClientChannel->getChannel()->getChannelName() throw std::runtime_error(message);
+ " PvaClientMonitor::waitConnect illegal connect state "; }
throw std::runtime_error(message); if(PvaClient::getDebug()) {
} cout << "PvaClientMonitor::waitConnect calling waitForConnect.wait\n";
} }
waitForConnect.wait(); waitForConnect.wait();
connectState = monitorConnectStatus.isOK() ? connected : connectIdle; connectState = connectStatus.isOK() ? connected : connectIdle;
if(PvaClient::getDebug()) { if(PvaClient::getDebug()) {
cout << "PvaClientMonitor::waitConnect" cout << "PvaClientMonitor::waitConnect"
<< " monitorConnectStatus " << (monitorConnectStatus.isOK() ? "connected" : "not connected") << " connectStatus " << (connectStatus.isOK() ? "connected" : "not connected");
<< endl;
} }
return monitorConnectStatus; return connectStatus;
} }
void PvaClientMonitor::setRequester(PvaClientMonitorRequesterPtr const & pvaClientMonitorRequester) void PvaClientMonitor::setRequester(PvaClientMonitorRequesterPtr const & pvaClientMonitorRequester)
{ {
if(PvaClient::getDebug()) { if(PvaClient::getDebug()) {
string channelName("disconnected");
Channel::shared_pointer chan(channel.lock());
if(chan) channelName = chan->getChannelName();
cout << "PvaClientMonitor::setRequester" cout << "PvaClientMonitor::setRequester"
<< " channelName " << pvaClientChannel->getChannel()->getChannelName() << " channelName " << channelName
<< endl; << endl;
} }
this->pvaClientMonitorRequester = pvaClientMonitorRequester; this->pvaClientMonitorRequester = pvaClientMonitorRequester;
@@ -362,17 +305,30 @@ void PvaClientMonitor::setRequester(PvaClientMonitorRequesterPtr const & pvaClie
void PvaClientMonitor::start() void PvaClientMonitor::start()
{ {
if(PvaClient::getDebug()) { if(PvaClient::getDebug()) {
string channelName("disconnected");
Channel::shared_pointer chan(channel.lock());
if(chan) channelName = chan->getChannelName();
cout << "PvaClientMonitor::start" cout << "PvaClientMonitor::start"
<< " channelName " << pvaClientChannel->getChannel()->getChannelName() << " channelName " << channelName
<< " connectState " << connectState << " connectState " << connectState
<< endl; << endl;
} }
if(isStarted) { if(isStarted) {
string channelName("disconnected");
Channel::shared_pointer chan(channel.lock());
if(chan) channelName = chan->getChannelName();
cerr << "PvaClientMonitor::start"
<< " channelName " << channelName
<< " why is this called twice "
<< endl;
return; return;
} }
if(connectState==connectIdle) connect(); if(connectState==connectIdle) connect();
if(connectState!=connected) { if(connectState!=connected) {
string message = string("channel ") + pvaClientChannel->getChannel()->getChannelName() Channel::shared_pointer chan(channel.lock());
string channelName("disconnected");
if(chan) channelName = chan->getChannelName();
string message = string("channel ") + channelName
+ " PvaClientMonitor::start illegal state "; + " PvaClientMonitor::start illegal state ";
throw std::runtime_error(message); throw std::runtime_error(message);
} }
@@ -380,45 +336,15 @@ void PvaClientMonitor::start()
monitor->start(); monitor->start();
} }
void PvaClientMonitor::start(string const & request)
{
if(PvaClient::getDebug()) {
cout<< "PvaMonitor::start(request)"
<< " request " << request
<< endl;
}
PvaClientPtr client(pvaClient.lock());
if(!client) throw std::runtime_error("pvaClient was deleted");
if(!pvaClientChannel->getChannel()->isConnected()) {
client->message(
"PvaClientMonitor::start(request) but not connected",
errorMessage);
return;
}
CreateRequest::shared_pointer createRequest(CreateRequest::create());
PVStructurePtr pvr(createRequest->createRequest(request));
if(!pvr) throw std::runtime_error(createRequest->getMessage());
if(monitor) {
if(isStarted) monitor->stop();
}
monitorRequester.reset();
monitor.reset();
isStarted = false;
connectState = connectIdle;
userPoll = false;
userWait = false;
monitorRequester = MonitorRequesterImplPtr(
new MonitorRequesterImpl(shared_from_this(),client));
pvRequest = pvr;
connect();
}
void PvaClientMonitor::stop() void PvaClientMonitor::stop()
{ {
if(PvaClient::getDebug()) { if(PvaClient::getDebug()) {
string channelName("disconnected");
Channel::shared_pointer chan(channel.lock());
if(chan) channelName = chan->getChannelName();
cout << "PvaClientMonitor::stop" cout << "PvaClientMonitor::stop"
<< " channelName " << pvaClientChannel->getChannel()->getChannelName() << " channelName " << channelName
<< endl; << endl;
} }
if(!isStarted) return; if(!isStarted) return;
@@ -429,18 +355,27 @@ void PvaClientMonitor::stop()
bool PvaClientMonitor::poll() bool PvaClientMonitor::poll()
{ {
if(PvaClient::getDebug()) { if(PvaClient::getDebug()) {
string channelName("disconnected");
Channel::shared_pointer chan(channel.lock());
if(chan) channelName = chan->getChannelName();
cout << "PvaClientMonitor::poll" cout << "PvaClientMonitor::poll"
<< " channelName " << pvaClientChannel->getChannel()->getChannelName() << " channelName " << channelName
<< endl; << endl;
} }
checkMonitorState(); checkMonitorState();
if(!isStarted) { if(!isStarted) {
string message = string("channel ") + pvaClientChannel->getChannel()->getChannelName() string channelName("disconnected");
Channel::shared_pointer chan(channel.lock());
if(chan) channelName = chan->getChannelName();
string message = string("channel ") + channelName
+ " PvaClientMonitor::poll illegal state "; + " PvaClientMonitor::poll illegal state ";
throw std::runtime_error(message); throw std::runtime_error(message);
} }
if(userPoll) { if(userPoll) {
string message = string("channel ") + pvaClientChannel->getChannel()->getChannelName() string channelName("disconnected");
Channel::shared_pointer chan(channel.lock());
if(chan) channelName = chan->getChannelName();
string message = string("channel ") + channelName
+ " PvaClientMonitor::poll did not release last"; + " PvaClientMonitor::poll did not release last";
throw std::runtime_error(message); throw std::runtime_error(message);
} }
@@ -454,12 +389,18 @@ bool PvaClientMonitor::poll()
bool PvaClientMonitor::waitEvent(double secondsToWait) bool PvaClientMonitor::waitEvent(double secondsToWait)
{ {
if(PvaClient::getDebug()) { if(PvaClient::getDebug()) {
string channelName("disconnected");
Channel::shared_pointer chan(channel.lock());
if(chan) channelName = chan->getChannelName();
cout << "PvaClientMonitor::waitEvent" cout << "PvaClientMonitor::waitEvent"
<< " channelName " << pvaClientChannel->getChannel()->getChannelName() << " channelName " << channelName
<< endl; << endl;
} }
if(!isStarted) { if(!isStarted) {
string message = string("channel ") + pvaClientChannel->getChannel()->getChannelName() Channel::shared_pointer chan(channel.lock());
string channelName("disconnected");
if(chan) channelName = chan->getChannelName();
string message = string("channel ") + channelName
+ " PvaClientMonitor::waitEvent illegal state "; + " PvaClientMonitor::waitEvent illegal state ";
throw std::runtime_error(message); throw std::runtime_error(message);
} }
@@ -477,17 +418,26 @@ bool PvaClientMonitor::waitEvent(double secondsToWait)
void PvaClientMonitor::releaseEvent() void PvaClientMonitor::releaseEvent()
{ {
if(PvaClient::getDebug()) { if(PvaClient::getDebug()) {
string channelName("disconnected");
Channel::shared_pointer chan(channel.lock());
if(chan) channelName = chan->getChannelName();
cout << "PvaClientMonitor::releaseEvent" cout << "PvaClientMonitor::releaseEvent"
<< " channelName " << pvaClientChannel->getChannel()->getChannelName() << " channelName " << channelName
<< endl; << endl;
} }
if(!isStarted) { if(!isStarted) {
string message = string("channel ") + pvaClientChannel->getChannel()->getChannelName() Channel::shared_pointer chan(channel.lock());
string channelName("disconnected");
if(chan) channelName = chan->getChannelName();
string message = string("channel ") + channelName
+ " PvaClientMonitor::releaseEvent monitor not started "; + " PvaClientMonitor::releaseEvent monitor not started ";
throw std::runtime_error(message); throw std::runtime_error(message);
} }
if(!userPoll) { if(!userPoll) {
string message = string("channel ") + pvaClientChannel->getChannel()->getChannelName() Channel::shared_pointer chan(channel.lock());
string channelName("disconnected");
if(chan) channelName = chan->getChannelName();
string message = string("channel ") + channelName
+ " PvaClientMonitor::releaseEvent did not call poll"; + " PvaClientMonitor::releaseEvent did not call poll";
throw std::runtime_error(message); throw std::runtime_error(message);
} }
@@ -495,16 +445,14 @@ void PvaClientMonitor::releaseEvent()
monitor->release(monitorElement); monitor->release(monitorElement);
} }
PvaClientChannelPtr PvaClientMonitor::getPvaClientChannel()
{
return pvaClientChannel;
}
PvaClientMonitorDataPtr PvaClientMonitor::getData() PvaClientMonitorDataPtr PvaClientMonitor::getData()
{ {
if(PvaClient::getDebug()) { if(PvaClient::getDebug()) {
string channelName("disconnected");
Channel::shared_pointer chan(channel.lock());
if(chan) channelName = chan->getChannelName();
cout << "PvaClientMonitor::getData" cout << "PvaClientMonitor::getData"
<< " channelName " << pvaClientChannel->getChannel()->getChannelName() << " channelName " << channelName
<< endl; << endl;
} }
checkMonitorState(); checkMonitorState();
+1 -1
View File
@@ -145,7 +145,7 @@ void PvaClientNTMultiData::endDeltaTime()
PVStructurePtr pvst = topPVStructure[i]; PVStructurePtr pvst = topPVStructure[i];
if(!pvst) { if(!pvst) {
unionValue[i] = PVUnionPtr(); unionValue[i] = PVUnionPtr();
} else if(unionValue[i]) { } else {
unionValue[i]->set(pvst->getSubField("value")); unionValue[i]->set(pvst->getSubField("value"));
if(gotAlarm) if(gotAlarm)
{ {
+29 -171
View File
@@ -70,92 +70,35 @@ public:
PvaClientProcessPtr PvaClientProcess::create( PvaClientProcessPtr PvaClientProcess::create(
PvaClientPtr const &pvaClient, PvaClientPtr const &pvaClient,
PvaClientChannelPtr const & pvaClientChannel, Channel::shared_pointer const & channel,
PVStructurePtr const &pvRequest) PVStructurePtr const &pvRequest)
{ {
if(PvaClient::getDebug()) { PvaClientProcessPtr epv(new PvaClientProcess(pvaClient,channel,pvRequest));
cout<< "PvaClientProcess::create(pvaClient,channelName,pvRequest)\n" epv->channelProcessRequester = ChannelProcessRequesterImplPtr(
<< " channelName " << pvaClientChannel->getChannel()->getChannelName() new ChannelProcessRequesterImpl(epv,pvaClient));
<< " pvRequest " << pvRequest return epv;
<< endl;
}
PvaClientProcessPtr channelProcess(new PvaClientProcess(pvaClient,pvaClientChannel,pvRequest));
channelProcess->channelProcessRequester = ChannelProcessRequesterImplPtr(
new ChannelProcessRequesterImpl(channelProcess,pvaClient));
return channelProcess;
} }
PvaClientProcess::PvaClientProcess( PvaClientProcess::PvaClientProcess(
PvaClientPtr const &pvaClient, PvaClientPtr const &pvaClient,
PvaClientChannelPtr const & pvaClientChannel, Channel::shared_pointer const & channel,
PVStructurePtr const &pvRequest) PVStructurePtr const &pvRequest)
: pvaClient(pvaClient), : pvaClient(pvaClient),
pvaClientChannel(pvaClientChannel), channel(channel),
pvRequest(pvRequest), pvRequest(pvRequest),
connectState(connectIdle), connectState(connectIdle),
processState(processIdle) processState(processIdle)
{ {
if(PvaClient::getDebug()) { if(PvaClient::getDebug()) cout<< "PvaClientProcess::PvaClientProcess()\n";
cout<< "PvaClientProcess::PvaClientProcess()"
<< " channelName " << pvaClientChannel->getChannel()->getChannelName()
<< endl;
}
} }
PvaClientProcess::~PvaClientProcess() PvaClientProcess::~PvaClientProcess()
{ {
if(PvaClient::getDebug()) { if(PvaClient::getDebug()) cout<< "PvaClientProcess::~PvaClientProcess()\n";
cout<< "PvaClientProcess::~PvaClientProcess()" channelProcess->destroy();
<< " channelName " << pvaClientChannel->getChannel()->getChannelName()
<< endl;
}
} }
void PvaClientProcess::channelStateChange(PvaClientChannelPtr const & pvaClientChannel, bool isConnected)
{
if(PvaClient::getDebug()) {
cout<< "PvaClientProcess::channelStateChange"
<< " channelName " << pvaClientChannel->getChannel()->getChannelName()
<< " isConnected " << (isConnected ? "true" : "false")
<< endl;
}
if(isConnected)
{
connectState = connectActive;
channelProcess = pvaClientChannel->getChannel()->createChannelProcess(channelProcessRequester,pvRequest);
}
PvaClientChannelStateChangeRequesterPtr req(pvaClientChannelStateChangeRequester.lock());
if(req) {
req->channelStateChange(pvaClientChannel,isConnected);
}
}
void PvaClientProcess::checkProcessState()
{
if(PvaClient::getDebug()) {
cout << "PvaClientProcess::checkProcessState"
<< " channelName " << pvaClientChannel->getChannel()->getChannelName()
<< endl;
}
if(!pvaClientChannel->getChannel()->isConnected()) {
string message = string("channel ") + pvaClientChannel->getChannel()->getChannelName()
+ " PvaClientProcess::checkProcessState channel not connected ";
throw std::runtime_error(message);
}
if(connectState==connectIdle) {
connect();
}
if(connectState==connectActive){
string message = string("channel ") + pvaClientChannel->getChannel()->getChannelName()
+ " "
+ channelProcessConnectStatus.getMessage();
throw std::runtime_error(message);
}
if(processState==processIdle) process();
}
// from ChannelProcessRequester // from ChannelProcessRequester
string PvaClientProcess::getRequesterName() string PvaClientProcess::getRequesterName()
{ {
@@ -175,31 +118,9 @@ void PvaClientProcess::channelProcessConnect(
const Status& status, const Status& status,
ChannelProcess::shared_pointer const & channelProcess) ChannelProcess::shared_pointer const & channelProcess)
{ {
if(PvaClient::getDebug()) { channelProcessConnectStatus = status;
cout << "PvaClientProcess::channelProcessConnect" connectState = connected;
<< " channelName " << pvaClientChannel->getChannel()->getChannelName() this->channelProcess = channelProcess;
<< " status.isOK " << (status.isOK() ? "true" : "false")
<< endl;
}
{
Lock xx(mutex);
this->channelProcess = channelProcess;
if(status.isOK()) {
channelProcessConnectStatus = status;
connectState = connected;
} else {
stringstream ss;
ss << pvRequest;
string message = string("PvaClientProcess::channelProcessConnect")
+ "\npvRequest\n" + ss.str()
+ "\nerror\n" + status.getMessage();
channelProcessConnectStatus = Status(Status::STATUSTYPE_ERROR,message);
}
}
PvaClientProcessRequesterPtr req(pvaClientProcessRequester.lock());
if(req) {
req->channelProcessConnect(status,shared_from_this());
}
waitForConnect.signal(); waitForConnect.signal();
} }
@@ -208,69 +129,40 @@ void PvaClientProcess::processDone(
const Status& status, const Status& status,
ChannelProcess::shared_pointer const & channelProcess) ChannelProcess::shared_pointer const & channelProcess)
{ {
if(PvaClient::getDebug()) { channelProcessStatus = status;
cout << "PvaClientProcess::processDone" processState = processComplete;
<< " channelName " << pvaClientChannel->getChannel()->getChannelName()
<< " status.isOK " << (status.isOK() ? "true" : "false")
<< endl;
}
{
Lock xx(mutex);
channelProcessStatus = status;
processState = processComplete;
}
PvaClientProcessRequesterPtr req(pvaClientProcessRequester.lock());
if(req) {
req->processDone(status,shared_from_this());
}
waitForProcess.signal(); waitForProcess.signal();
} }
void PvaClientProcess::connect() void PvaClientProcess::connect()
{ {
if(PvaClient::getDebug()) {
cout << "PvaClientProcess::connect"
<< " channelName " << pvaClientChannel->getChannel()->getChannelName()
<< endl;
}
issueConnect(); issueConnect();
Status status = waitConnect(); Status status = waitConnect();
if(status.isOK()) return; if(status.isOK()) return;
string message = string("channel ") + pvaClientChannel->getChannel()->getChannelName() string message = string("channel ") + channel->getChannelName()
+ " PvaClientProcess::connect " + status.getMessage(); + " PvaClientProcess::connect " + status.getMessage();
throw std::runtime_error(message); throw std::runtime_error(message);
} }
void PvaClientProcess::issueConnect() void PvaClientProcess::issueConnect()
{ {
if(PvaClient::getDebug()) {
cout << "PvaClientProcess::issueConnect"
<< " channelName " << pvaClientChannel->getChannel()->getChannelName()
<< endl;
}
if(connectState!=connectIdle) { if(connectState!=connectIdle) {
string message = string("channel ") + pvaClientChannel->getChannel()->getChannelName() string message = string("channel ") + channel->getChannelName()
+ " pvaClientProcess already connected "; + " pvaClientProcess already connected ";
throw std::runtime_error(message); throw std::runtime_error(message);
} }
connectState = connectActive; connectState = connectActive;
channelProcess = pvaClientChannel->getChannel()->createChannelProcess(channelProcessRequester,pvRequest); channelProcess = channel->createChannelProcess(channelProcessRequester,pvRequest);
} }
Status PvaClientProcess::waitConnect() Status PvaClientProcess::waitConnect()
{ {
if(PvaClient::getDebug()) {
cout << "PvaClientProcess::waitConnect"
<< " channelName " << pvaClientChannel->getChannel()->getChannelName()
<< endl;
}
if(connectState==connected) { if(connectState==connected) {
if(!channelProcessConnectStatus.isOK()) connectState = connectIdle; if(!channelProcessConnectStatus.isOK()) connectState = connectIdle;
return channelProcessConnectStatus; return channelProcessConnectStatus;
} }
if(connectState!=connectActive) { if(connectState!=connectActive) {
string message = string("channel ") + pvaClientChannel->getChannel()->getChannelName() string message = string("channel ") + channel->getChannelName()
+ " pvaClientProcess illegal connect state "; + " pvaClientProcess illegal connect state ";
throw std::runtime_error(message); throw std::runtime_error(message);
} }
@@ -281,29 +173,19 @@ Status PvaClientProcess::waitConnect()
void PvaClientProcess::process() void PvaClientProcess::process()
{ {
if(PvaClient::getDebug()) {
cout << "PvaClientProcess::process"
<< " channelName " << pvaClientChannel->getChannel()->getChannelName()
<< endl;
}
issueProcess(); issueProcess();
Status status = waitProcess(); Status status = waitProcess();
if(status.isOK()) return; if(status.isOK()) return;
string message = string("channel ") + pvaClientChannel->getChannel()->getChannelName() string message = string("channel ") + channel->getChannelName()
+ " PvaClientProcess::process" + status.getMessage(); + " PvaClientProcess::process" + status.getMessage();
throw std::runtime_error(message); throw std::runtime_error(message);
} }
void PvaClientProcess::issueProcess() void PvaClientProcess::issueProcess()
{ {
if(PvaClient::getDebug()) {
cout << "PvaClientProcess::issueProcess"
<< " channelName " << pvaClientChannel->getChannel()->getChannelName()
<< endl;
}
if(connectState==connectIdle) connect(); if(connectState==connectIdle) connect();
if(processState!=processIdle) { if(processState!=processIdle) {
string message = string("channel ") + pvaClientChannel->getChannel()->getChannelName() string message = string("channel ") + channel->getChannelName()
+ " PvaClientProcess::issueProcess process aleady active "; + " PvaClientProcess::issueProcess process aleady active ";
throw std::runtime_error(message); throw std::runtime_error(message);
} }
@@ -313,42 +195,18 @@ void PvaClientProcess::issueProcess()
Status PvaClientProcess::waitProcess() Status PvaClientProcess::waitProcess()
{ {
if(PvaClient::getDebug()) { if(processState==processComplete) {
cout << "PvaClientProcess::waitProcess" processState = processIdle;
<< " channelName " << pvaClientChannel->getChannel()->getChannelName() return channelProcessStatus;
<< endl;
} }
{ if(processState!=processActive){
Lock xx(mutex); string message = string("channel ") + channel->getChannelName()
if(processState==processComplete) { + " PvaClientProcess::waitProcess llegal process state";
processState = processIdle; throw std::runtime_error(message);
return channelProcessStatus;
}
if(processState!=processActive){
string message = string("channel ") + pvaClientChannel->getChannel()->getChannelName()
+ " PvaClientProcess::waitProcess llegal process state";
throw std::runtime_error(message);
}
} }
waitForProcess.wait(); waitForProcess.wait();
processState = processComplete; processState = processIdle;
return channelProcessStatus; return channelProcessStatus;
} }
void PvaClientProcess::setRequester(PvaClientProcessRequesterPtr const & pvaClientProcessRequester)
{
if(PvaClient::getDebug()) {
cout << "PvaClientProcess::setRequester"
<< " channelName " << pvaClientChannel->getChannel()->getChannelName()
<< endl;
}
this->pvaClientProcessRequester = pvaClientProcessRequester;
}
PvaClientChannelPtr PvaClientProcess::getPvaClientChannel()
{
return pvaClientChannel;
}
}} }}
+75 -148
View File
@@ -70,7 +70,7 @@ public:
clientPut->getDone(status,channelPut,pvStructure,bitSet); clientPut->getDone(status,channelPut,pvStructure,bitSet);
} }
virtual void putDone( virtual void putDone(
const Status& status, const Status& status,
ChannelPut::shared_pointer const & channelPut) ChannelPut::shared_pointer const & channelPut)
{ {
@@ -82,29 +82,30 @@ public:
PvaClientPutPtr PvaClientPut::create( PvaClientPutPtr PvaClientPut::create(
PvaClientPtr const &pvaClient, PvaClientPtr const &pvaClient,
PvaClientChannelPtr const & pvaClientChannel, Channel::shared_pointer const & channel,
PVStructurePtr const &pvRequest) PVStructurePtr const &pvRequest)
{ {
PvaClientPutPtr clientPut(new PvaClientPut(pvaClient,pvaClientChannel,pvRequest)); PvaClientPutPtr epv(new PvaClientPut(pvaClient,channel,pvRequest));
clientPut->channelPutRequester = ChannelPutRequesterImplPtr( epv->channelPutRequester = ChannelPutRequesterImplPtr(
new ChannelPutRequesterImpl(clientPut,pvaClient)); new ChannelPutRequesterImpl(epv,pvaClient));
return clientPut; return epv;
} }
PvaClientPut::PvaClientPut( PvaClientPut::PvaClientPut(
PvaClientPtr const &pvaClient, PvaClientPtr const &pvaClient,
PvaClientChannelPtr const & pvaClientChannel, Channel::shared_pointer const & channel,
PVStructurePtr const &pvRequest) PVStructurePtr const &pvRequest)
: pvaClient(pvaClient), : pvaClient(pvaClient),
pvaClientChannel(pvaClientChannel), channel(channel),
pvRequest(pvRequest), pvRequest(pvRequest),
connectState(connectIdle), connectState(connectIdle),
putState(putIdle) putState(putIdle)
{ {
if(PvaClient::getDebug()) { if(PvaClient::getDebug()) {
cout<< "PvaClientPut::PvaClientPut" cout<< "PvaClientPut::PvaClientPut"
<< " channelName " << pvaClientChannel->getChannel()->getChannelName() << " channelName " << channel->getChannelName()
<< endl; << endl;
} }
} }
@@ -112,46 +113,21 @@ PvaClientPut::PvaClientPut(
PvaClientPut::~PvaClientPut() PvaClientPut::~PvaClientPut()
{ {
if(PvaClient::getDebug()) { if(PvaClient::getDebug()) {
string channelName("disconnected");
Channel::shared_pointer chan(channel.lock());
if(chan) channelName = chan->getChannelName();
cout<< "PvaClientPut::~PvaClientPut" cout<< "PvaClientPut::~PvaClientPut"
<< " channelName " << pvaClientChannel->getChannel()->getChannelName() << " channelName " << channelName
<< endl; << 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() void PvaClientPut::checkPutState()
{ {
if(PvaClient::getDebug()) {
cout << "PvaClientPut::checkPutState"
<< " channelName " << pvaClientChannel->getChannel()->getChannelName()
<< endl;
}
if(connectState==connectIdle){ if(connectState==connectIdle){
connect(); connect();
} get();
if(connectState==connectActive){
string message = string("channel ") + pvaClientChannel->getChannel()->getChannelName()
+ " "
+ channelPutConnectStatus.getMessage();
throw std::runtime_error(message);
} }
} }
@@ -175,32 +151,23 @@ void PvaClientPut::channelPutConnect(
StructureConstPtr const & structure) StructureConstPtr const & structure)
{ {
if(PvaClient::getDebug()) { if(PvaClient::getDebug()) {
string channelName("disconnected");
Channel::shared_pointer chan(channel.lock());
if(chan) channelName = chan->getChannelName();
cout << "PvaClientPut::channelPutConnect" cout << "PvaClientPut::channelPutConnect"
<< " channelName " << pvaClientChannel->getChannel()->getChannelName() << " channelName " << channelName
<< " status.isOK " << (status.isOK() ? "true" : "false") << " status.isOK " << (status.isOK() ? "true" : "false")
<< endl; << endl;
} }
{ {
Lock xx(mutex); Lock xx(mutex);
channelPutConnectStatus = status;
this->channelPut = channelPut; this->channelPut = channelPut;
if(status.isOK()) { if(status.isOK()) {
channelPutConnectStatus = status;
connectState = connected;
pvaClientData = PvaClientPutData::create(structure); pvaClientData = PvaClientPutData::create(structure);
pvaClientData->setMessagePrefix(channelPut->getChannel()->getChannelName()); 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());
if(req) {
req->channelPutConnect(status,shared_from_this());
}
waitForConnect.signal(); waitForConnect.signal();
} }
@@ -212,8 +179,11 @@ void PvaClientPut::getDone(
BitSetPtr const & bitSet) BitSetPtr const & bitSet)
{ {
if(PvaClient::getDebug()) { if(PvaClient::getDebug()) {
string channelName("disconnected");
Channel::shared_pointer chan(channel.lock());
if(chan) channelName = chan->getChannelName();
cout << "PvaClientPut::getDone" cout << "PvaClientPut::getDone"
<< " channelName " << pvaClientChannel->getChannel()->getChannelName() << " channelName " << channelName
<< " status.isOK " << (status.isOK() ? "true" : "false") << " status.isOK " << (status.isOK() ? "true" : "false")
<< endl; << endl;
} }
@@ -225,10 +195,6 @@ void PvaClientPut::getDone(
bs->clear(); bs->clear();
*bs |= *bitSet; *bs |= *bitSet;
} }
PvaClientPutRequesterPtr req(pvaClientPutRequester.lock());
if(req) {
req->getDone(status,shared_from_this());
}
waitForGetPut.signal(); waitForGetPut.signal();
} }
@@ -237,31 +203,28 @@ void PvaClientPut::putDone(
ChannelPut::shared_pointer const & channelPut) ChannelPut::shared_pointer const & channelPut)
{ {
if(PvaClient::getDebug()) { if(PvaClient::getDebug()) {
string channelName("disconnected");
Channel::shared_pointer chan(channel.lock());
if(chan) channelName = chan->getChannelName();
cout << "PvaClientPut::putDone" cout << "PvaClientPut::putDone"
<< " channelName " << pvaClientChannel->getChannel()->getChannelName() << " channelName " << channelName
<< " status.isOK " << (status.isOK() ? "true" : "false") << " status.isOK " << (status.isOK() ? "true" : "false")
<< endl; << endl;
} }
channelGetPutStatus = status; channelGetPutStatus = status;
PvaClientPutRequesterPtr req(pvaClientPutRequester.lock());
if(req) {
req->putDone(status,shared_from_this());
}
waitForGetPut.signal(); waitForGetPut.signal();
} }
void PvaClientPut::connect() void PvaClientPut::connect()
{ {
if(PvaClient::getDebug()) {
cout << "PvaClientPut::connect"
<< " channelName " << pvaClientChannel->getChannel()->getChannelName()
<< endl;
}
issueConnect(); issueConnect();
Status status = waitConnect(); Status status = waitConnect();
if(status.isOK()) return; if(status.isOK()) return;
Channel::shared_pointer chan(channel.lock());
string channelName("disconnected");
if(chan) channelName = chan->getChannelName();
string message = string("channel ") string message = string("channel ")
+ pvaClientChannel->getChannel()->getChannelName() + channelName
+ " PvaClientPut::connect " + " PvaClientPut::connect "
+ status.getMessage(); + status.getMessage();
throw std::runtime_error(message); throw std::runtime_error(message);
@@ -269,29 +232,24 @@ void PvaClientPut::connect()
void PvaClientPut::issueConnect() void PvaClientPut::issueConnect()
{ {
if(PvaClient::getDebug()) { Channel::shared_pointer chan(channel.lock());
cout << "PvaClientPut::issueConnect"
<< " channelName " << pvaClientChannel->getChannel()->getChannelName()
<< endl;
}
if(connectState!=connectIdle) { if(connectState!=connectIdle) {
string message = string("channel ") + pvaClientChannel->getChannel()->getChannelName() string channelName("disconnected");
if(chan) channelName = chan->getChannelName();
string message = string("channel ") + channelName
+ " pvaClientPut already connected "; + " pvaClientPut already connected ";
throw std::runtime_error(message); throw std::runtime_error(message);
} }
connectState = connectActive; if(chan) {
channelPutConnectStatus = Status(Status::STATUSTYPE_ERROR, "connect active"); connectState = connectActive;
channelPut = pvaClientChannel->getChannel()->createChannelPut(channelPutRequester,pvRequest); channelPut = chan->createChannelPut(channelPutRequester,pvRequest);
return;
}
throw std::runtime_error("PvaClientPut::issueConnect() but channel disconnected");
} }
Status PvaClientPut::waitConnect() Status PvaClientPut::waitConnect()
{ {
if(PvaClient::getDebug()) {
cout << "PvaClientPut::waitConnect"
<< " channelName " << pvaClientChannel->getChannel()->getChannelName()
<< endl;
}
{ {
Lock xx(mutex); Lock xx(mutex);
if(connectState==connected) { if(connectState==connected) {
@@ -299,7 +257,10 @@ Status PvaClientPut::waitConnect()
return channelPutConnectStatus; return channelPutConnectStatus;
} }
if(connectState!=connectActive) { if(connectState!=connectActive) {
string message = string("channel ") + pvaClientChannel->getChannel()->getChannelName() Channel::shared_pointer chan(channel.lock());
string channelName("disconnected");
if(chan) channelName = chan->getChannelName();
string message = string("channel ") + channelName
+ " PvaClientPut::waitConnect illegal connect state "; + " PvaClientPut::waitConnect illegal connect state ";
throw std::runtime_error(message); throw std::runtime_error(message);
} }
@@ -311,16 +272,14 @@ Status PvaClientPut::waitConnect()
void PvaClientPut::get() void PvaClientPut::get()
{ {
if(PvaClient::getDebug()) {
cout << "PvaClientPut::get"
<< " channelName " << pvaClientChannel->getChannel()->getChannelName()
<< endl;
}
issueGet(); issueGet();
Status status = waitGet(); Status status = waitGet();
if(status.isOK()) return; if(status.isOK()) return;
Channel::shared_pointer chan(channel.lock());
string channelName("disconnected");
if(chan) channelName = chan->getChannelName();
string message = string("channel ") string message = string("channel ")
+ pvaClientChannel->getChannel()->getChannelName() + channelName
+ " PvaClientPut::get " + " PvaClientPut::get "
+ status.getMessage(); + status.getMessage();
throw std::runtime_error(message); throw std::runtime_error(message);
@@ -328,15 +287,13 @@ void PvaClientPut::get()
void PvaClientPut::issueGet() void PvaClientPut::issueGet()
{ {
if(PvaClient::getDebug()) {
cout << "PvaClientPut::issueGet"
<< " channelName " << pvaClientChannel->getChannel()->getChannelName()
<< endl;
}
if(connectState==connectIdle) connect(); if(connectState==connectIdle) connect();
if(putState==getActive || putState==putActive) { if(putState!=putIdle) {
Channel::shared_pointer chan(channel.lock());
string channelName("disconnected");
if(chan) channelName = chan->getChannelName();
string message = string("channel ") string message = string("channel ")
+ pvaClientChannel->getChannel()->getChannelName() + channelName
+ "PvaClientPut::issueGet get or put aleady active "; + "PvaClientPut::issueGet get or put aleady active ";
throw std::runtime_error(message); throw std::runtime_error(message);
} }
@@ -346,34 +303,30 @@ void PvaClientPut::issueGet()
Status PvaClientPut::waitGet() Status PvaClientPut::waitGet()
{ {
if(PvaClient::getDebug()) {
cout << "PvaClientPut::waitGet"
<< " channelName " << pvaClientChannel->getChannel()->getChannelName()
<< endl;
}
if(putState!=getActive){ if(putState!=getActive){
Channel::shared_pointer chan(channel.lock());
string channelName("disconnected");
if(chan) channelName = chan->getChannelName();
string message = string("channel ") string message = string("channel ")
+ pvaClientChannel->getChannel()->getChannelName() + channelName
+ " PvaClientPut::waitGet illegal put state"; + " PvaClientPut::waitGet illegal put state";
throw std::runtime_error(message); throw std::runtime_error(message);
} }
waitForGetPut.wait(); waitForGetPut.wait();
putState = putComplete; putState = putIdle;
return channelGetPutStatus; return channelGetPutStatus;
} }
void PvaClientPut::put() void PvaClientPut::put()
{ {
if(PvaClient::getDebug()) {
cout << "PvaClientPut::put"
<< " channelName " << pvaClientChannel->getChannel()->getChannelName()
<< endl;
}
issuePut(); issuePut();
Status status = waitPut(); Status status = waitPut();
if(status.isOK()) return; if(status.isOK()) return;
Channel::shared_pointer chan(channel.lock());
string channelName("disconnected");
if(chan) channelName = chan->getChannelName();
string message = string("channel ") string message = string("channel ")
+ pvaClientChannel->getChannel()->getChannelName() + channelName
+ " PvaClientPut::put " + " PvaClientPut::put "
+ status.getMessage(); + status.getMessage();
throw std::runtime_error(message); throw std::runtime_error(message);
@@ -381,17 +334,13 @@ void PvaClientPut::put()
void PvaClientPut::issuePut() void PvaClientPut::issuePut()
{ {
if(PvaClient::getDebug()) {
cout << "PvaClientPut::issuePut"
<< " channelName " << pvaClientChannel->getChannel()->getChannelName()
<< " pvStructure\n" << pvaClientData->getPVStructure()
<< " bitSet " << *pvaClientData->getChangedBitSet() << endl
<< endl;
}
if(connectState==connectIdle) connect(); if(connectState==connectIdle) connect();
if(putState==getActive || putState==putActive) { if(putState!=putIdle) {
Channel::shared_pointer chan(channel.lock());
string channelName("disconnected");
if(chan) channelName = chan->getChannelName();
string message = string("channel ") string message = string("channel ")
+ pvaClientChannel->getChannel()->getChannelName() + channelName
+ "PvaClientPut::issueGet get or put aleady active "; + "PvaClientPut::issueGet get or put aleady active ";
throw std::runtime_error(message); throw std::runtime_error(message);
} }
@@ -401,48 +350,26 @@ void PvaClientPut::issuePut()
Status PvaClientPut::waitPut() Status PvaClientPut::waitPut()
{ {
if(PvaClient::getDebug()) {
cout << "PvaClientPut::waitPut"
<< " channelName " << pvaClientChannel->getChannel()->getChannelName()
<< endl;
}
if(putState!=putActive){ if(putState!=putActive){
Channel::shared_pointer chan(channel.lock());
string channelName("disconnected");
if(chan) channelName = chan->getChannelName();
string message = string("channel ") string message = string("channel ")
+ pvaClientChannel->getChannel()->getChannelName() + channelName
+ " PvaClientPut::waitPut illegal put state"; + " PvaClientPut::waitPut illegal put state";
throw std::runtime_error(message); throw std::runtime_error(message);
} }
waitForGetPut.wait(); waitForGetPut.wait();
putState = putComplete; putState = putIdle;
if(channelGetPutStatus.isOK()) pvaClientData->getChangedBitSet()->clear(); if(channelGetPutStatus.isOK()) pvaClientData->getChangedBitSet()->clear();
return channelGetPutStatus; return channelGetPutStatus;
} }
PvaClientPutDataPtr PvaClientPut::getData() PvaClientPutDataPtr PvaClientPut::getData()
{ {
if(PvaClient::getDebug()) {
cout<< "PvaClientPut::getData"
<< " channelName " << pvaClientChannel->getChannel()->getChannelName()
<< endl;
}
checkPutState(); checkPutState();
if(putState==putIdle) get();
return pvaClientData; 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;
}
}} }}
+98 -210
View File
@@ -96,28 +96,28 @@ public:
PvaClientPutGetPtr PvaClientPutGet::create( PvaClientPutGetPtr PvaClientPutGet::create(
PvaClientPtr const &pvaClient, PvaClientPtr const &pvaClient,
PvaClientChannelPtr const & pvaClientChannel, Channel::shared_pointer const & channel,
PVStructurePtr const &pvRequest) PVStructurePtr const &pvRequest)
{ {
PvaClientPutGetPtr clientPutGet(new PvaClientPutGet(pvaClient,pvaClientChannel,pvRequest)); PvaClientPutGetPtr epv(new PvaClientPutGet(pvaClient,channel,pvRequest));
clientPutGet->channelPutGetRequester = ChannelPutGetRequesterImplPtr( epv->channelPutGetRequester = ChannelPutGetRequesterImplPtr(
new ChannelPutGetRequesterImpl(clientPutGet,pvaClient)); new ChannelPutGetRequesterImpl(epv,pvaClient));
return clientPutGet; return epv;
} }
PvaClientPutGet::PvaClientPutGet( PvaClientPutGet::PvaClientPutGet(
PvaClientPtr const &pvaClient, PvaClientPtr const &pvaClient,
PvaClientChannelPtr const & pvaClientChannel, Channel::shared_pointer const & channel,
PVStructurePtr const &pvRequest) PVStructurePtr const &pvRequest)
: pvaClient(pvaClient), : pvaClient(pvaClient),
pvaClientChannel(pvaClientChannel), channel(channel),
pvRequest(pvRequest), pvRequest(pvRequest),
connectState(connectIdle), connectState(connectIdle),
putGetState(putGetIdle) putGetState(putGetIdle)
{ {
if(PvaClient::getDebug()) { if(PvaClient::getDebug()) {
cout<< "PvaClientPutGet::PvaClientPutGet" cout<< "PvaClientPutGet::PvaClientPutGet"
<< " channelName " << pvaClientChannel->getChannel()->getChannelName() << " channelName " << channel->getChannelName()
<< endl; << endl;
} }
} }
@@ -125,46 +125,21 @@ PvaClientPutGet::PvaClientPutGet(
PvaClientPutGet::~PvaClientPutGet() PvaClientPutGet::~PvaClientPutGet()
{ {
if(PvaClient::getDebug()) { if(PvaClient::getDebug()) {
string channelName("disconnected");
Channel::shared_pointer chan(channel.lock());
if(chan) channelName = chan->getChannelName();
cout<< "PvaClientPutGet::~PvaClientPutGet" cout<< "PvaClientPutGet::~PvaClientPutGet"
<< " channelName " << pvaClientChannel->getChannel()->getChannelName() << " channelName " << channelName
<< endl; << endl;
} }
} channelPutGet->destroy();
void PvaClientPutGet::channelStateChange(PvaClientChannelPtr const & pvaClientChannel, bool isConnected)
{
if(PvaClient::getDebug()) {
cout<< "PvaClientPutGet::channelStateChange"
<< " channelName " << pvaClientChannel->getChannel()->getChannelName()
<< " isConnected " << (isConnected ? "true" : "false")
<< endl;
}
if(isConnected&&!channelPutGet)
{
connectState = connectActive;
channelPutGet = pvaClientChannel->getChannel()->createChannelPutGet(channelPutGetRequester,pvRequest);
}
PvaClientChannelStateChangeRequesterPtr req(pvaClientChannelStateChangeRequester.lock());
if(req) {
req->channelStateChange(pvaClientChannel,isConnected);
}
} }
void PvaClientPutGet::checkPutGetState() void PvaClientPutGet::checkPutGetState()
{ {
if(PvaClient::getDebug()) {
cout << "PvaClientPutGet::checkPutGetState"
<< " channelName " << pvaClientChannel->getChannel()->getChannelName()
<< endl;
}
if(connectState==connectIdle){ if(connectState==connectIdle){
connect(); connect();
} getPut();
if(connectState==connectActive){
string message = string("channel ") + pvaClientChannel->getChannel()->getChannelName()
+ " "
+ channelPutGetConnectStatus.getMessage();
throw std::runtime_error(message);
} }
} }
@@ -190,33 +165,17 @@ void PvaClientPutGet::channelPutGetConnect(
{ {
if(PvaClient::getDebug()) { if(PvaClient::getDebug()) {
cout << "PvaClientPutGet::channelPutGetConnect" cout << "PvaClientPutGet::channelPutGetConnect"
<< " channelName " << pvaClientChannel->getChannel()->getChannelName() << " channelName " << channelPutGet->getChannel()->getChannelName()
<< " status.isOK " << (status.isOK() ? "true" : "false") << " status.isOK " << (status.isOK() ? "true" : "false")
<< endl; << endl;
} }
{ channelPutGetConnectStatus = status;
Lock xx(mutex); this->channelPutGet = channelPutGet;
this->channelPutGet = channelPutGet; if(status.isOK()) {
if(status.isOK()) { pvaClientPutData = PvaClientPutData::create(putStructure);
channelPutGetConnectStatus = status; pvaClientPutData->setMessagePrefix(channelPutGet->getChannel()->getChannelName());
connectState = connected; pvaClientGetData = PvaClientGetData::create(getStructure);
pvaClientPutData = PvaClientPutData::create(putStructure); pvaClientGetData->setMessagePrefix(channelPutGet->getChannel()->getChannelName());
pvaClientPutData->setMessagePrefix(channelPutGet->getChannel()->getChannelName());
pvaClientGetData = PvaClientGetData::create(getStructure);
pvaClientGetData->setMessagePrefix(channelPutGet->getChannel()->getChannelName());
} else {
stringstream ss;
ss << pvRequest;
string message = string("\nPvaClientPutGet::channelPutGetConnect)")
+ "\npvRequest\n" + ss.str()
+ "\nerror\n" + status.getMessage();
channelPutGetConnectStatus = Status(Status::STATUSTYPE_ERROR,message);
}
}
PvaClientPutGetRequesterPtr req(pvaClientPutGetRequester.lock());
if(req) {
req->channelPutGetConnect(status,shared_from_this());
} }
waitForConnect.signal(); waitForConnect.signal();
@@ -229,22 +188,17 @@ void PvaClientPutGet::putGetDone(
BitSetPtr const & getChangedBitSet) BitSetPtr const & getChangedBitSet)
{ {
if(PvaClient::getDebug()) { if(PvaClient::getDebug()) {
string channelName("disconnected");
Channel::shared_pointer chan(channel.lock());
if(chan) channelName = chan->getChannelName();
cout << "PvaClientPutGet::putGetDone" cout << "PvaClientPutGet::putGetDone"
<< " channelName " << pvaClientChannel->getChannel()->getChannelName() << " channelName " << channelName
<< " status.isOK " << (status.isOK() ? "true" : "false") << " status.isOK " << (status.isOK() ? "true" : "false")
<< endl; << endl;
} }
channelPutGetStatus = status; channelPutGetStatus = status;
if(status.isOK()) { if(status.isOK()) {
PVStructurePtr pvs = pvaClientGetData->getPVStructure(); pvaClientGetData->setData(getPVStructure,getChangedBitSet);
pvs->copyUnchecked(*getPVStructure,*getChangedBitSet);
BitSetPtr bs = pvaClientGetData->getChangedBitSet();
bs->clear();
*bs |= *getChangedBitSet;
}
PvaClientPutGetRequesterPtr req(pvaClientPutGetRequester.lock());
if(req) {
req->putGetDone(status,shared_from_this());
} }
waitForPutGet.signal(); waitForPutGet.signal();
} }
@@ -256,8 +210,11 @@ void PvaClientPutGet::getPutDone(
BitSetPtr const & putBitSet) BitSetPtr const & putBitSet)
{ {
if(PvaClient::getDebug()) { if(PvaClient::getDebug()) {
string channelName("disconnected");
Channel::shared_pointer chan(channel.lock());
if(chan) channelName = chan->getChannelName();
cout << "PvaClientPutGet::getPutDone" cout << "PvaClientPutGet::getPutDone"
<< " channelName " << pvaClientChannel->getChannel()->getChannelName() << " channelName " << channelName
<< " status.isOK " << (status.isOK() ? "true" : "false") << " status.isOK " << (status.isOK() ? "true" : "false")
<< endl; << endl;
} }
@@ -269,10 +226,6 @@ void PvaClientPutGet::getPutDone(
bs->clear(); bs->clear();
*bs |= *putBitSet; *bs |= *putBitSet;
} }
PvaClientPutGetRequesterPtr req(pvaClientPutGetRequester.lock());
if(req) {
req->getPutDone(status,shared_from_this());
}
waitForPutGet.signal(); waitForPutGet.signal();
} }
@@ -283,38 +236,31 @@ void PvaClientPutGet::getGetDone(
BitSetPtr const & getChangedBitSet) BitSetPtr const & getChangedBitSet)
{ {
if(PvaClient::getDebug()) { if(PvaClient::getDebug()) {
string channelName("disconnected");
Channel::shared_pointer chan(channel.lock());
if(chan) channelName = chan->getChannelName();
cout << "PvaClientPutGet::getGetDone" cout << "PvaClientPutGet::getGetDone"
<< " channelName " << pvaClientChannel->getChannel()->getChannelName() << " channelName " << channelName
<< " status.isOK " << (status.isOK() ? "true" : "false") << " status.isOK " << (status.isOK() ? "true" : "false")
<< endl; << endl;
} }
channelPutGetStatus = status; channelPutGetStatus = status;
if(status.isOK()) { if(status.isOK()) {
PVStructurePtr pvs = pvaClientGetData->getPVStructure(); pvaClientGetData->setData(getPVStructure,getChangedBitSet);
pvs->copyUnchecked(*getPVStructure,*getChangedBitSet);
BitSetPtr bs = pvaClientGetData->getChangedBitSet();
bs->clear();
*bs |= *getChangedBitSet;
}
PvaClientPutGetRequesterPtr req(pvaClientPutGetRequester.lock());
if(req) {
req->getGetDone(status,shared_from_this());
} }
waitForPutGet.signal(); waitForPutGet.signal();
} }
void PvaClientPutGet::connect() void PvaClientPutGet::connect()
{ {
if(PvaClient::getDebug()) {
cout << "PvaClientPutGet::connect"
<< " channelName " << pvaClientChannel->getChannel()->getChannelName()
<< endl;
}
issueConnect(); issueConnect();
Status status = waitConnect(); Status status = waitConnect();
if(status.isOK()) return; if(status.isOK()) return;
Channel::shared_pointer chan(channel.lock());
string channelName("disconnected");
if(chan) channelName = chan->getChannelName();
string message = string("channel ") string message = string("channel ")
+ pvaClientChannel->getChannel()->getChannelName() + channelName
+ " PvaClientPutGet::connect " + " PvaClientPutGet::connect "
+ status.getMessage(); + status.getMessage();
throw std::runtime_error(message); throw std::runtime_error(message);
@@ -322,29 +268,24 @@ void PvaClientPutGet::connect()
void PvaClientPutGet::issueConnect() void PvaClientPutGet::issueConnect()
{ {
if(PvaClient::getDebug()) { Channel::shared_pointer chan(channel.lock());
cout << "PvaClientPutGet::issueConnect"
<< " channelName " << pvaClientChannel->getChannel()->getChannelName()
<< endl;
}
if(connectState!=connectIdle) { if(connectState!=connectIdle) {
string message = string("channel ") string channelName("disconnected");
+ pvaClientChannel->getChannel()->getChannelName() if(chan) channelName = chan->getChannelName();
string message = string("channel ") + channelName
+ " pvaClientPutGet already connected "; + " pvaClientPutGet already connected ";
throw std::runtime_error(message); throw std::runtime_error(message);
} }
connectState = connectActive; if(chan) {
channelPutGetConnectStatus = Status(Status::STATUSTYPE_ERROR, "connect active"); connectState = connectActive;
channelPutGet = pvaClientChannel->getChannel()->createChannelPutGet(channelPutGetRequester,pvRequest); channelPutGet = chan->createChannelPutGet(channelPutGetRequester,pvRequest);
return;
}
throw std::runtime_error("PvaClientPutGet::issueConnect() but channel disconnected");
} }
Status PvaClientPutGet::waitConnect() Status PvaClientPutGet::waitConnect()
{ {
if(PvaClient::getDebug()) {
cout << "PvaClientPutGet::waitConnect"
<< " channelName " << pvaClientChannel->getChannel()->getChannelName()
<< endl;
}
{ {
Lock xx(mutex); Lock xx(mutex);
if(connectState==connected) { if(connectState==connected) {
@@ -352,30 +293,30 @@ Status PvaClientPutGet::waitConnect()
return channelPutGetConnectStatus; return channelPutGetConnectStatus;
} }
if(connectState!=connectActive) { if(connectState!=connectActive) {
string message = string("channel ") Channel::shared_pointer chan(channel.lock());
+ pvaClientChannel->getChannel()->getChannelName() string channelName("disconnected");
if(chan) channelName = chan->getChannelName();
string message = string("channel ") + channelName
+ " PvaClientPutGet::waitConnect illegal connect state "; + " PvaClientPutGet::waitConnect illegal connect state ";
throw std::runtime_error(message); throw std::runtime_error(message);
} }
} }
waitForConnect.wait(); waitForConnect.wait();
if(!channelPutGetConnectStatus.isOK()) connectState = connectIdle; connectState = channelPutGetConnectStatus.isOK() ? connected : connectIdle;
return channelPutGetConnectStatus; return channelPutGetConnectStatus;
} }
void PvaClientPutGet::putGet() void PvaClientPutGet::putGet()
{ {
if(PvaClient::getDebug()) {
cout << "PvaClientPutGet::putGet"
<< " channelName " << pvaClientChannel->getChannel()->getChannelName()
<< endl;
}
issuePutGet(); issuePutGet();
Status status = waitPutGet(); Status status = waitPutGet();
if(status.isOK()) return; if(status.isOK()) return;
Channel::shared_pointer chan(channel.lock());
string channelName("disconnected");
if(chan) channelName = chan->getChannelName();
string message = string("channel ") string message = string("channel ")
+ pvaClientChannel->getChannel()->getChannelName() + channelName
+ " PvaClientPut::putGet " + " PvaClientPut::putGet "
+ status.getMessage(); + status.getMessage();
throw std::runtime_error(message); throw std::runtime_error(message);
@@ -383,15 +324,12 @@ void PvaClientPutGet::putGet()
void PvaClientPutGet::issuePutGet() void PvaClientPutGet::issuePutGet()
{ {
if(PvaClient::getDebug()) {
cout << "PvaClientPutGet::issuePutGet"
<< " channelName " << pvaClientChannel->getChannel()->getChannelName()
<< endl;
}
if(connectState==connectIdle) connect(); if(connectState==connectIdle) connect();
if(putGetState==putGetActive) { if(putGetState!=putGetIdle) {
string message = string("channel ") Channel::shared_pointer chan(channel.lock());
+ pvaClientChannel->getChannel()->getChannelName() string channelName("disconnected");
if(chan) channelName = chan->getChannelName();
string message = string("channel ") + channelName
+ " PvaClientPutGet::issuePutGet get or put aleady active "; + " PvaClientPutGet::issuePutGet get or put aleady active ";
throw std::runtime_error(message); throw std::runtime_error(message);
} }
@@ -402,35 +340,29 @@ void PvaClientPutGet::issuePutGet()
Status PvaClientPutGet::waitPutGet() Status PvaClientPutGet::waitPutGet()
{ {
if(PvaClient::getDebug()) {
cout << "PvaClientPutGet::waitPutGet"
<< " channelName " << pvaClientChannel->getChannel()->getChannelName()
<< endl;
}
if(putGetState!=putGetActive){ if(putGetState!=putGetActive){
string message = string("channel ") Channel::shared_pointer chan(channel.lock());
+ pvaClientChannel->getChannel()->getChannelName() string channelName("disconnected");
if(chan) channelName = chan->getChannelName();
string message = string("channel ") + channelName
+ " PvaClientPutGet::waitPutGet get or put aleady active "; + " PvaClientPutGet::waitPutGet get or put aleady active ";
throw std::runtime_error(message); throw std::runtime_error(message);
} }
waitForPutGet.wait(); waitForPutGet.wait();
putGetState = putGetComplete; putGetState = putGetIdle;
if(channelPutGetStatus.isOK()) pvaClientPutData->getChangedBitSet()->clear();
return channelPutGetStatus; return channelPutGetStatus;
} }
void PvaClientPutGet::getGet() void PvaClientPutGet::getGet()
{ {
if(PvaClient::getDebug()) {
cout << "PvaClientPutGet::getGet"
<< " channelName " << pvaClientChannel->getChannel()->getChannelName()
<< endl;
}
issueGetGet(); issueGetGet();
Status status = waitGetGet(); Status status = waitGetGet();
if(status.isOK()) return; if(status.isOK()) return;
Channel::shared_pointer chan(channel.lock());
string channelName("disconnected");
if(chan) channelName = chan->getChannelName();
string message = string("channel ") string message = string("channel ")
+ pvaClientChannel->getChannel()->getChannelName() + channelName
+ " PvaClientPut::getGet " + " PvaClientPut::getGet "
+ status.getMessage(); + status.getMessage();
throw std::runtime_error(message); throw std::runtime_error(message);
@@ -438,15 +370,12 @@ void PvaClientPutGet::getGet()
void PvaClientPutGet::issueGetGet() void PvaClientPutGet::issueGetGet()
{ {
if(PvaClient::getDebug()) {
cout << "PvaClientPutGet::issueGetGet"
<< " channelName " << pvaClientChannel->getChannel()->getChannelName()
<< endl;
}
if(connectState==connectIdle) connect(); if(connectState==connectIdle) connect();
if(putGetState==putGetActive) { if(putGetState!=putGetIdle) {
string message = string("channel ") Channel::shared_pointer chan(channel.lock());
+ pvaClientChannel->getChannel()->getChannelName() string channelName("disconnected");
if(chan) channelName = chan->getChannelName();
string message = string("channel ") + channelName
+ " PvaClientPutGet::issueGetGet get or put aleady active "; + " PvaClientPutGet::issueGetGet get or put aleady active ";
throw std::runtime_error(message); throw std::runtime_error(message);
} }
@@ -456,34 +385,29 @@ void PvaClientPutGet::issueGetGet()
Status PvaClientPutGet::waitGetGet() Status PvaClientPutGet::waitGetGet()
{ {
if(PvaClient::getDebug()) {
cout << "PvaClientPutGet::waitGetGet"
<< " channelName " << pvaClientChannel->getChannel()->getChannelName()
<< endl;
}
if(putGetState!=putGetActive){ if(putGetState!=putGetActive){
string message = string("channel ") Channel::shared_pointer chan(channel.lock());
+ pvaClientChannel->getChannel()->getChannelName() string channelName("disconnected");
if(chan) channelName = chan->getChannelName();
string message = string("channel ") + channelName
+ " PvaClientPutGet::waitGetGet get or put aleady active "; + " PvaClientPutGet::waitGetGet get or put aleady active ";
throw std::runtime_error(message); throw std::runtime_error(message);
} }
waitForPutGet.wait(); waitForPutGet.wait();
putGetState = putGetComplete; putGetState = putGetIdle;
return channelPutGetStatus; return channelPutGetStatus;
} }
void PvaClientPutGet::getPut() void PvaClientPutGet::getPut()
{ {
if(PvaClient::getDebug()) {
cout << "PvaClientPutGet::getGetPut"
<< " channelName " << pvaClientChannel->getChannel()->getChannelName()
<< endl;
}
issueGetPut(); issueGetPut();
Status status = waitGetPut(); Status status = waitGetPut();
if(status.isOK()) return; if(status.isOK()) return;
Channel::shared_pointer chan(channel.lock());
string channelName("disconnected");
if(chan) channelName = chan->getChannelName();
string message = string("channel ") string message = string("channel ")
+ pvaClientChannel->getChannel()->getChannelName() + channelName
+ " PvaClientPut::getPut " + " PvaClientPut::getPut "
+ status.getMessage(); + status.getMessage();
throw std::runtime_error(message); throw std::runtime_error(message);
@@ -491,15 +415,12 @@ void PvaClientPutGet::getPut()
void PvaClientPutGet::issueGetPut() void PvaClientPutGet::issueGetPut()
{ {
if(PvaClient::getDebug()) {
cout << "PvaClientPutGet::issueGetPut"
<< " channelName " << pvaClientChannel->getChannel()->getChannelName()
<< endl;
}
if(connectState==connectIdle) connect(); if(connectState==connectIdle) connect();
if(putGetState==putGetActive) { if(putGetState!=putGetIdle) {
string message = string("channel ") Channel::shared_pointer chan(channel.lock());
+ pvaClientChannel->getChannel()->getChannelName() string channelName("disconnected");
if(chan) channelName = chan->getChannelName();
string message = string("channel ") + channelName
+ " PvaClientPutGet::issueGetPut get or put aleady active "; + " PvaClientPutGet::issueGetPut get or put aleady active ";
throw std::runtime_error(message); throw std::runtime_error(message);
} }
@@ -509,62 +430,29 @@ void PvaClientPutGet::issueGetPut()
Status PvaClientPutGet::waitGetPut() Status PvaClientPutGet::waitGetPut()
{ {
if(PvaClient::getDebug()) {
cout << "PvaClientPutGet::waitGetPut"
<< " channelName " << pvaClientChannel->getChannel()->getChannelName()
<< endl;
}
if(putGetState!=putGetActive){ if(putGetState!=putGetActive){
string message = string("channel ") Channel::shared_pointer chan(channel.lock());
+ pvaClientChannel->getChannel()->getChannelName() string channelName("disconnected");
if(chan) channelName = chan->getChannelName();
string message = string("channel ") + channelName
+ " PvaClientPutGet::waitGetPut get or put aleady active "; + " PvaClientPutGet::waitGetPut get or put aleady active ";
throw std::runtime_error(message); throw std::runtime_error(message);
} }
waitForPutGet.wait(); waitForPutGet.wait();
putGetState = putGetComplete; putGetState = putGetIdle;
return channelPutGetStatus; return channelPutGetStatus;
} }
PvaClientGetDataPtr PvaClientPutGet::getGetData() PvaClientGetDataPtr PvaClientPutGet::getGetData()
{ {
if(PvaClient::getDebug()) {
cout<< "PvaClientPutGet::getGetData"
<< " channelName " << pvaClientChannel->getChannel()->getChannelName()
<< endl;
}
checkPutGetState(); checkPutGetState();
if(putGetState==putGetIdle) getGet();
return pvaClientGetData; return pvaClientGetData;
} }
PvaClientPutDataPtr PvaClientPutGet::getPutData() PvaClientPutDataPtr PvaClientPutGet::getPutData()
{ {
if(PvaClient::getDebug()) {
cout<< "PvaClientPutGet::getPutData"
<< " channelName " << pvaClientChannel->getChannel()->getChannelName()
<< endl;
}
checkPutGetState(); checkPutGetState();
if(putGetState==putGetIdle) getPut();
return pvaClientPutData; return pvaClientPutData;
} }
void PvaClientPutGet::setRequester(PvaClientPutGetRequesterPtr const & pvaClientPutGetRequester)
{
if(PvaClient::getDebug()) {
cout << "PvaClientPutGet::setRequester"
<< " channelName " << pvaClientChannel->getChannel()->getChannelName()
<< endl;
}
this->pvaClientPutGetRequester = pvaClientPutGetRequester;
}
PvaClientChannelPtr PvaClientPutGet::getPvaClientChannel()
{
return pvaClientChannel;
}
}} }}