From be69a74094a0eeeb480295fc58542ffaab82990e Mon Sep 17 00:00:00 2001 From: Marty Kraimer Date: Mon, 2 Mar 2015 15:09:24 -0500 Subject: [PATCH] more work on EasyGet and conneection management; still work in progress --- documentation/easyPVA.html | 111 ++++++++------------------------- example/src/exampleEasyGet.cpp | 56 +++++++++++++++-- exampleDatabaseEasyPVA.zip | Bin 0 -> 17489 bytes src/easyChannel.cpp | 18 ++++-- src/easyGet.cpp | 78 ++++++++++++----------- src/easyPVA.cpp | 46 +++++++++++++- 6 files changed, 175 insertions(+), 134 deletions(-) create mode 100644 exampleDatabaseEasyPVA.zip diff --git a/documentation/easyPVA.html b/documentation/easyPVA.html index 7e12516..0280942 100644 --- a/documentation/easyPVA.html +++ b/documentation/easyPVA.html @@ -28,7 +28,7 @@

EPICS easyPVA

EPICS V4 Working Group, Working Draft, -19-Feb-2015

+02-Mar-2015
This version:
  • Allows efficient client side programs.
  • -

    The following describes the CPP version of EasyPVA.

    - -

    This is the overview for EasyPVACPP. JavaDoc documentation is available at This document briefly describes the CPP version of EasyPVA. +Doxygen documentation is available at doxygenDoc

    Initialization

    A client obtains the interface to EasyPVA via the call:

    -
    EasyPVA easy = EasyPVAFactory.get();
    +
    EasyPVAPtr easyPVA = EasyPVAFactorys->create();
    -

    The client can make this call many times, but an instance of the EastPVA interface object is -only created in the first call. This first call also -starts the PVAccess client factory.

    +

    The client can call this an arbitrary number of times. +On the first call the PVAccess client factory is started. +When the last EasyPVA is destroyed the PVAccess client factory is stopped. +

    EasyPVA Overview

    @@ -139,13 +139,6 @@ starts the PVAccess client factory.

    - -

    There are additional methods that allows the client to:

    -
      -
    1. Control how error messages are handled.
    2. -
    3. Control when get/put commands are sent the channel or channels.
    4. -
    -

    EasyChannel Overview

    This interface creates Easy support for each PVAccess::Channel create @@ -208,15 +201,17 @@ The only requirement of the channels is that each must have a top level field na -

    shell

    -

    Directory shell has the following files:

    -
    -
    exampleDatabaseEasyPVA.zip
    -
    - When unzipped this is used to create an example IOC database. - The database has the record used by the examples are tests that come with easyPVAJava. - It uses pvDatabaseCPP to build the database. - After unzipping the file: +

    example source code

    +

    Example Database

    +

    The examples require that an example pvAccess server is runnimg. +This distribution has a file exampleDatabaseEasyPVA.zip. +When unzipped this is used to create an example IOC database. +The database has the record used by the examples are tests that come with easyPVAJava. +It uses pvDatabaseCPP to build the database. +

    +

    +After unzipping the file: +

     cd configure
     cp ExampleRELEASE.local RELEASE.local
    @@ -226,68 +221,16 @@ make
     cd iocBoot/exampleDatabase
     ../../bin/<arch:>/exampleDatabase st.cmd
     
    - You now have a running database. -
    -
    source
    -
    - This file creates the CLASSPATH required - to run the examples and tests. - You have to edit it for your environment. -
    -
    rpcServiceExample
    -
    - This starts the RPCServiceExample. - This is required by ExampleEasyRPC. -
    -
    exampleGet
    -
    - This runs ExampleGet. -
    -
    exampleGetDouble
    -
    - This runs ExampleGetDouble -
    -
    doublePut
    -
    - This runs DoublePut. -
    -
    doubleArrayPut
    -
    - This runs DoubleArrayPut -
    -
    exampleMonitor
    -
    - This runs ExampleMonitor -
    -
    exampleMonitorCallback
    -
    - This runs ExampleMonitorCallback -
    -
    exampleMultiMonitor
    -
    - This runs ExampleMultiMonitor. - It and polls every few seconds for monitor events. - It gets data as NTMultiChannel. -
    -
    exampleMultiMonitorDouble
    -
    - This runs ExampleMultiMonitorDouble. - It has an event listener for new events. - It gets data as an array of doubles. -
    -

    Examples

    -

    These are examples in package org.epics.pvaccess.easyPVA.example +

    These are examples in directory example/src. +An example of how to run them is:

    +
    +mrk> pwd
    +/home/hg/easyPVACPP/example
    +mrk> bin/linux-x86_64/exampleEasyGet 
    +
    +

    See the source code for each example. -In order to run the examples exampleDatabaseEasyPVA must be running. -

    -

    There is a shell command to run each example,

    -

    Tests

    -

    A test directory has a number of tests for easyPVAJava. -In order to run the tests both exampleDatabaseEasyPVA and rpcServiceExample -must be running. -For now these tests are being run as eclipse unit tests. -The tests also provide examples of using EasyPVA.

    diff --git a/example/src/exampleEasyGet.cpp b/example/src/exampleEasyGet.cpp index 8ecffca..113feee 100644 --- a/example/src/exampleEasyGet.cpp +++ b/example/src/exampleEasyGet.cpp @@ -13,18 +13,17 @@ #include #include -#include using namespace std; using namespace epics::pvData; using namespace epics::pvAccess; using namespace epics::easyPVA; -int main(int argc,char *argv[]) -{ - ClientFactory::start(); - EasyPVAPtr easyPVA = EasyPVA::create(); +static EasyPVAPtr easyPVA; +static void exampleDouble() +{ + cout << "example double scalar\n"; double value; try { cout << "short way\n"; @@ -43,7 +42,52 @@ int main(int argc,char *argv[]) } catch (std::runtime_error e) { cout << "exception " << e.what() << endl; } +} + +static void exampleDoubleArray() +{ + cout << "example double array\n"; + shared_vector value; + try { + cout << "short way\n"; + value = easyPVA->createChannel("exampleDoubleArray")->createGet()->getDoubleArray(); + cout << "as doubleArray " << value << endl; + } catch (std::runtime_error e) { + cout << "exception " << e.what() << endl; + } + try { + cout << "long way\n"; + EasyChannelPtr easyChannel = easyPVA->createChannel("exampleDoubleArray"); + easyChannel->connect(2.0); + EasyGetPtr easyGet = easyChannel->createGet(); + value = easyGet->getDoubleArray(); + cout << "as doubleArray " << value << endl; + } catch (std::runtime_error e) { + cout << "exception " << e.what() << endl; + } +} + +static void examplePowerSupply() +{ + cout << "example powerSupply\n"; + PVStructurePtr pvStructure; + try { + cout << "short way\n"; + pvStructure = easyPVA->createChannel("examplePowerSupply")->createGet("field()")->getPVStructure(); + cout << pvStructure << endl; + } catch (std::runtime_error e) { + cout << "exception " << e.what() << endl; + } + +} + +int main(int argc,char *argv[]) +{ + easyPVA = EasyPVA::create(); + exampleDouble(); + exampleDoubleArray(); + examplePowerSupply(); cout << "done\n"; - ClientFactory::stop(); + easyPVA->destroy(); return 0; } diff --git a/exampleDatabaseEasyPVA.zip b/exampleDatabaseEasyPVA.zip new file mode 100644 index 0000000000000000000000000000000000000000..3e49135213ced2d7265ad55b01af57dde9173950 GIT binary patch literal 17489 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 = channel; + if(status.isOK()) { + this->channel = channel; + return; + } + cout << "EasyChannelImpl::channelCreated status " << status.getMessage() << " why??\n"; } void EasyChannelImpl::channelStateChange( Channel::shared_pointer const & channel, Channel::ConnectionState connectionState) { - if(isDestroyed) throw std::runtime_error("easyChannel was destroyed"); + if(isDestroyed) return; bool waitingForConnect = false; if(connectState==connectActive) waitingForConnect = true; if(connectionState!=Channel::CONNECTED) { - string mess(channelName + " connection state " + Channel::ConnectionStateNames[connectionState]); + string mess(channelName + + " connection state " + Channel::ConnectionStateNames[connectionState]); message(mess,errorMessage); channelConnectStatus = Status(Status::STATUSTYPE_ERROR,mess); connectState = notConnected; @@ -220,10 +224,14 @@ void EasyChannelImpl::issueConnect() } channelRequester = ChannelRequester::shared_pointer(new ChannelRequesterImpl(this)); + channelConnectStatus = Status(Status::STATUSTYPE_ERROR,"createChannel failed"); connectState = connectActive; ChannelProviderRegistry::shared_pointer reg = getChannelProviderRegistry(); ChannelProvider::shared_pointer provider = reg->getProvider(providerName); channel = provider->createChannel(channelName,channelRequester,ChannelProvider::PRIORITY_DEFAULT); + if(!channel) { + throw std::runtime_error(channelConnectStatus.getMessage()); + } } Status EasyChannelImpl::waitConnect(double timeout) @@ -268,7 +276,7 @@ EasyProcessPtr EasyChannelImpl::createProcess(PVStructurePtr const & pvRequest) EasyGetPtr EasyChannelImpl::createGet() { - return EasyChannelImpl::createGet("value,alarm.timeStamp"); + return EasyChannelImpl::createGet("value,alarm,timeStamp"); } EasyGetPtr EasyChannelImpl::createGet(string const & request) diff --git a/src/easyGet.cpp b/src/easyGet.cpp index da2415d..c197698 100644 --- a/src/easyGet.cpp +++ b/src/easyGet.cpp @@ -101,6 +101,7 @@ public: return shared_from_this(); } private: + void checkGetState(); enum GetConnectState {connectIdle,connectActive,connected}; EasyPVAPtr easyPVA; @@ -176,6 +177,12 @@ EasyGetImpl::~EasyGetImpl() destroy(); } +void EasyGetImpl::checkGetState() +{ + if(isDestroyed) throw std::runtime_error("easyGet was destroyed"); + if(connectState==connectIdle) connect(); + if(getState==getIdle) get(); +} // from ChannelGetRequester string EasyGetImpl::getRequesterName() @@ -257,7 +264,6 @@ void EasyGetImpl::issueConnect() throw std::runtime_error(ss.str()); } getRequester = ChannelGetRequester::shared_pointer(new ChannelGetRequesterImpl(this)); - connectState = connectActive; channelGet = channel->createChannelGet(getRequester,pvRequest); } @@ -335,206 +341,206 @@ void EasyGetImpl::setPVStructure(epics::pvData::PVStructurePtr const & pvStructu Alarm EasyGetImpl::getAlarm() { - if(isDestroyed) throw std::runtime_error("easyGet was destroyed"); + checkGetState(); return easyPVStructure->getAlarm(); } TimeStamp EasyGetImpl::getTimeStamp() { - if(isDestroyed) throw std::runtime_error("easyGet was destroyed"); + checkGetState(); return easyPVStructure->getTimeStamp(); } bool EasyGetImpl::hasValue() { - if(isDestroyed) throw std::runtime_error("easyGet was destroyed"); + checkGetState(); return easyPVStructure->hasValue(); } bool EasyGetImpl::isValueScalar() { - if(isDestroyed) throw std::runtime_error("easyGet was destroyed"); + checkGetState(); return easyPVStructure->isValueScalar(); } bool EasyGetImpl::isValueScalarArray() { - if(isDestroyed) throw std::runtime_error("easyGet was destroyed"); + checkGetState(); return easyPVStructure->isValueScalarArray(); } PVFieldPtr EasyGetImpl::getValue() { - if(isDestroyed) throw std::runtime_error("easyGet was destroyed"); + checkGetState(); return easyPVStructure->getValue(); } PVScalarPtr EasyGetImpl::getScalarValue() { - if(isDestroyed) throw std::runtime_error("easyGet was destroyed"); + checkGetState(); return easyPVStructure->getScalarValue(); } std::tr1::shared_ptr EasyGetImpl::getArrayValue() { - if(isDestroyed) throw std::runtime_error("easyGet was destroyed"); + checkGetState(); return easyPVStructure->getArrayValue(); } std::tr1::shared_ptr EasyGetImpl::getScalarArrayValue() { - if(isDestroyed) throw std::runtime_error("easyGet was destroyed"); + checkGetState(); return easyPVStructure->getScalarArrayValue(); } bool EasyGetImpl::getBoolean() { - if(isDestroyed) throw std::runtime_error("easyGet was destroyed"); + checkGetState(); return easyPVStructure->getBoolean(); } int8 EasyGetImpl::getByte() { - if(isDestroyed) throw std::runtime_error("easyGet was destroyed"); + checkGetState(); return easyPVStructure->getByte(); } int16 EasyGetImpl::getShort() { - if(isDestroyed) throw std::runtime_error("easyGet was destroyed"); + checkGetState(); return easyPVStructure->getShort(); } int32 EasyGetImpl::getInt() { - if(isDestroyed) throw std::runtime_error("easyGet was destroyed"); + checkGetState(); return easyPVStructure->getInt(); } int64 EasyGetImpl::getLong() { - if(isDestroyed) throw std::runtime_error("easyGet was destroyed"); + checkGetState(); return easyPVStructure->getLong(); } uint8 EasyGetImpl::getUByte() { - if(isDestroyed) throw std::runtime_error("easyGet was destroyed"); + checkGetState(); return easyPVStructure->getUByte(); } uint16 EasyGetImpl::getUShort() { - if(isDestroyed) throw std::runtime_error("easyGet was destroyed"); + checkGetState(); return easyPVStructure->getUShort(); } uint32 EasyGetImpl::getUInt() { - if(isDestroyed) throw std::runtime_error("easyGet was destroyed"); + checkGetState(); return easyPVStructure->getUInt(); } uint64 EasyGetImpl::getULong() { - if(isDestroyed) throw std::runtime_error("easyGet was destroyed"); + checkGetState(); return easyPVStructure->getULong(); } float EasyGetImpl::getFloat() { - if(isDestroyed) throw std::runtime_error("easyGet was destroyed"); + checkGetState(); return easyPVStructure->getFloat(); } double EasyGetImpl::getDouble() { - if(isDestroyed) throw std::runtime_error("easyGet was destroyed"); - return easyPVStructure->isValueScalar(); + checkGetState(); + return easyPVStructure->getDouble(); } std::string EasyGetImpl::getString() { - if(isDestroyed) throw std::runtime_error("easyGet was destroyed"); + checkGetState(); return easyPVStructure->getString(); } shared_vector EasyGetImpl::getBooleanArray() { - if(isDestroyed) throw std::runtime_error("easyGet was destroyed"); + checkGetState(); return easyPVStructure->getBooleanArray(); } shared_vector EasyGetImpl::getByteArray() { - if(isDestroyed) throw std::runtime_error("easyGet was destroyed"); + checkGetState(); return easyPVStructure->getByteArray(); } shared_vector EasyGetImpl::getShortArray() { - if(isDestroyed) throw std::runtime_error("easyGet was destroyed"); + checkGetState(); return easyPVStructure->getShortArray(); } shared_vector EasyGetImpl::getIntArray() { - if(isDestroyed) throw std::runtime_error("easyGet was destroyed"); + checkGetState(); return easyPVStructure->getIntArray(); } shared_vector EasyGetImpl::getLongArray() { - if(isDestroyed) throw std::runtime_error("easyGet was destroyed"); + checkGetState(); return easyPVStructure->getLongArray(); } shared_vector EasyGetImpl::getUByteArray() { - if(isDestroyed) throw std::runtime_error("easyGet was destroyed"); + checkGetState(); return easyPVStructure->getUByteArray(); } shared_vector EasyGetImpl::getUShortArray() { - if(isDestroyed) throw std::runtime_error("easyGet was destroyed"); + checkGetState(); return easyPVStructure->getUShortArray(); } shared_vector EasyGetImpl::getUIntArray() { - if(isDestroyed) throw std::runtime_error("easyGet was destroyed"); + checkGetState(); return easyPVStructure->getUIntArray(); } shared_vector EasyGetImpl::getULongArray() { - if(isDestroyed) throw std::runtime_error("easyGet was destroyed"); + checkGetState(); return easyPVStructure->getULongArray(); } shared_vector EasyGetImpl::getFloatArray() { - if(isDestroyed) throw std::runtime_error("easyGet was destroyed"); + checkGetState(); return easyPVStructure->getFloatArray(); } shared_vector EasyGetImpl::getDoubleArray() { - if(isDestroyed) throw std::runtime_error("easyGet was destroyed"); + checkGetState(); return easyPVStructure->getDoubleArray(); } shared_vector EasyGetImpl::getStringArray() { - if(isDestroyed) throw std::runtime_error("easyGet was destroyed"); + checkGetState(); return easyPVStructure->getStringArray(); } PVStructurePtr EasyGetImpl::getPVStructure() { - if(isDestroyed) throw std::runtime_error("easyGet was destroyed"); + checkGetState(); return easyPVStructure->getPVStructure(); } diff --git a/src/easyPVA.cpp b/src/easyPVA.cpp index 6eaf4ab..922bba8 100644 --- a/src/easyPVA.cpp +++ b/src/easyPVA.cpp @@ -11,6 +11,7 @@ #define epicsExportSharedSymbols #include #include +#include using std::tr1::static_pointer_cast; using namespace epics::pvData; @@ -24,9 +25,46 @@ static const string easyPVAName = "easyPVA"; static const string defaultProvider = "pva"; static UnionConstPtr variantUnion = fieldCreate->createVariantUnion(); +namespace easyPVAPvt { + +static size_t numberEasyPVA = 0; +static bool firstTime = true; +static Mutex mutex; + +class StartStopClientFactory { + +public: + static void EasyPVABeingConstructed() + { + bool saveFirst = false; + { + Lock xx(mutex); + ++numberEasyPVA; + saveFirst = firstTime; + firstTime = false; + } + if(saveFirst) ClientFactory::start(); + } + + static void EasyPVABeingDestroyed() { + size_t numLeft = 0; + { + Lock xx(mutex); + --numberEasyPVA; + numLeft = numberEasyPVA; + } + if(numLeft<=0) ClientFactory::stop(); + } +}; +} + +using namespace epics::easyPVA::easyPVAPvt; + + EasyPVAPtr EasyPVA::create() { EasyPVAPtr xx(new EasyPVA()); + StartStopClientFactory::EasyPVABeingConstructed(); return xx; } @@ -45,7 +83,9 @@ EasyPVA::EasyPVA() { } -EasyPVA::~EasyPVA() {destroy();} +EasyPVA::~EasyPVA() { + destroy(); +} void EasyPVA::destroy() { @@ -61,8 +101,8 @@ void EasyPVA::destroy() channelList.erase(channelIter); (*channelIter)->destroy(); } - std::list::iterator multiChannelIter; #ifdef NOTDONE + std::list::iterator multiChannelIter; while(true) { multiChannelIter = multiChannelList.begin(); if(multiChannelIter==multiChannelList.end()) break; @@ -70,7 +110,7 @@ void EasyPVA::destroy() (*multiChannelIter)->destroy(); } #endif - + StartStopClientFactory::EasyPVABeingDestroyed(); } string EasyPVA:: getRequesterName()