diff --git a/documentation/RELEASE_NOTES.md b/documentation/RELEASE_NOTES.md index 9a33665..2136d10 100644 --- a/documentation/RELEASE_NOTES.md +++ b/documentation/RELEASE_NOTES.md @@ -2,6 +2,15 @@ This document summarizes the changes to the module between releases. +## Release 4.8.0 (EPICS 7.0.4.* March 2021 + +* PvaClientNTMultiData::getChannelChangeFlags is a new method. It fixes issue #66. +* Fix for issue #68. Both PvaClientArray and PvaClientField are not longer present. Neither was previously implemented. +* Several public methods are now protected. They were never meant to be called by clients. +* Issue #70 has been fixed. +* Changes was made to increase the performance of pvaMultiChannel. +* doxygen changes were made. + ## Release 4.7.1 (EPICS 7.0.3.2 May 2020) * support access to a union field that is a scalar or scalarArray diff --git a/documentation/htmldoxygen/README.md b/documentation/htmldoxygen/README.md deleted file mode 100644 index 372621f..0000000 --- a/documentation/htmldoxygen/README.md +++ /dev/null @@ -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. diff --git a/documentation/htmldoxygen/pvaClient.html b/documentation/htmldoxygen/pvaClient.html deleted file mode 100644 index 315f718..0000000 --- a/documentation/htmldoxygen/pvaClient.html +++ /dev/null @@ -1,146 +0,0 @@ - - - - - - PvaClient - - - - - - - - -

PvaClient

- - -

Overview

-

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

-

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

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

-before it uses any other pvaClient classes. -

-

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

-

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

-

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

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

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

-

Channel Caching

-

-PvaClient has a method: -

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

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

-

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

-

-pvaClientChannelGet and pvaClientChannelPut also implement caching. -

-

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

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

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

-

Non Cached Channels

-

-PvaClient has a method: -

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

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

- -

Blocking vs Non-Blocking Methods

-

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

-
-
connect
-
- This calls issueConnect and then waitConnect. - If waitConnect fails an exception is thrown. - Since waitConnect is a blocking method so is this. -
-
issueConnect
-
- This is a request to connect, i. e. issue a request to the server to create something - on the server. This is a non blocking call. -
-
waitConnect
-
- This waits for the server to respond to issueConnect. - It blocks until the server responds or a timeout occurs. -
-
- - - - - diff --git a/documentation/htmldoxygen/pvaClientChannel.html b/documentation/htmldoxygen/pvaClientChannel.html deleted file mode 100644 index 671b115..0000000 --- a/documentation/htmldoxygen/pvaClientChannel.html +++ /dev/null @@ -1,123 +0,0 @@ - - - - - - PvaClientChannel - - - - - - - - -

PvaClientChannel

- -

Overview

-

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

-

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

-

PvaClientChannel has methods:

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

Connect: Blocking vs Non-Blocking

-

PvaClientChannel has methods:

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

Get and Put Caching

-

-PvaClientChannel has methods: -

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

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

-

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

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

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

- - - - - diff --git a/documentation/htmldoxygen/pvaClientChannelStateChangeRequester.html b/documentation/htmldoxygen/pvaClientChannelStateChangeRequester.html deleted file mode 100644 index 6513646..0000000 --- a/documentation/htmldoxygen/pvaClientChannelStateChangeRequester.html +++ /dev/null @@ -1,81 +0,0 @@ - - - - - - PvaClientChannelStateChangeRequester - - - - - - - - -

PvaClientChannelStateChangeRequester

- -

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

-

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

-

-An example of illegal code is: -

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

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

-

The following is an example of legal code: -

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

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

- - - - - diff --git a/documentation/htmldoxygen/pvaClientGet.html b/documentation/htmldoxygen/pvaClientGet.html deleted file mode 100644 index 0845e92..0000000 --- a/documentation/htmldoxygen/pvaClientGet.html +++ /dev/null @@ -1,74 +0,0 @@ - - - - - - PvaClientGet - - - - - - - - -

PvaClientGet

- - -

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

-

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

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

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

-

PvaClientChannel has methods:

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

-issueConnect and issueGet do not block. -All other methods can block. -

- - - - diff --git a/documentation/htmldoxygen/pvaClientGetData.html b/documentation/htmldoxygen/pvaClientGetData.html deleted file mode 100644 index 8625301..0000000 --- a/documentation/htmldoxygen/pvaClientGetData.html +++ /dev/null @@ -1,63 +0,0 @@ - - - - - - PvaClientGetData - - - - - - - - -

PvaClientGetData

- -

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

-
-getStructure          Get the introspection interface for data returned from server
-getPVStructure        Get the complete set of data returned from the server.
-getChangedBitSet      Get the bitSet that shows which fields have a new value since last get.
-showChanged           Show all the fields that have changed value since the last get,
-getAlarm              If a alarm field is available get it.
-getTimeStamp          If a timeStamp field is available get it.
-hasValue              Does the PVStructure have a top level field named value
-NOTE: The following only apply 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.
-
- - - - diff --git a/documentation/htmldoxygen/pvaClientGetRequester.html b/documentation/htmldoxygen/pvaClientGetRequester.html deleted file mode 100644 index ad7fd7b..0000000 --- a/documentation/htmldoxygen/pvaClientGetRequester.html +++ /dev/null @@ -1,59 +0,0 @@ - - - - - - PvaClientGetRequester - - - - - - - - -

PvaClientGetRequester

- -

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

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

The client must call

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

-after creating an instance of PvaClientGet. -

- - - - diff --git a/documentation/htmldoxygen/pvaClientMonitor.html b/documentation/htmldoxygen/pvaClientMonitor.html deleted file mode 100644 index f3b3f25..0000000 --- a/documentation/htmldoxygen/pvaClientMonitor.html +++ /dev/null @@ -1,106 +0,0 @@ - - - - - - PvaClientMonitor - - - - - - - - -

PvaClientMonitor

-

-NOTE: This is a work in progress. -

-

Overview

-

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

-

The client first creates a PvaClientMonitorChannel and then creates a monitor

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

The client provides names for a channel and a provider

-The client calls: -
-static PvaClientMonitorPtr create(
-    PvaClientMonitorPtr const &PvaClientMonitor,
-    std::string const & channelName,
-    std::string const & providerName,
-    std::string const & request,
-    PvaClientMonitorChannelStateChangeRequesterPtr const & stateChangeRequester,
-    PvaClientMonitorRequesterPtr const & 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.
-
-With this method a pvaChannel is created and after it connects a pvaMonitor is created and started. -This method never blocks. - - - - diff --git a/documentation/htmldoxygen/pvaClientMonitorData.html b/documentation/htmldoxygen/pvaClientMonitorData.html deleted file mode 100644 index 1b76f83..0000000 --- a/documentation/htmldoxygen/pvaClientMonitorData.html +++ /dev/null @@ -1,66 +0,0 @@ - - - - - - PvaClientMonitorData - - - - - - - - -

PvaClientMonitorData

- - -

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

-
-getStructure          Get the introspection interface for data returned from server
-getPVStructure        Get the complete set of data returned from the server.
-getChangedBitSet      Get the bitSet that shows which fields have a new value since last monitor event.
-getOverrunBitSet      Get the bitSet that shows which fields have changed more than once since last monitor event.
-showChanged           Show all the fields that have changed value since the last monitor event,
-showChanged           Show all the fields that have changed value more than once since last monitor event.
-getAlarm              If a alarm field is available get it.
-getTimeStamp          If a timeStamp field is available get it.
-hasValue              Does the PVStructure have a top level field named value
-NOTE: The following only apply 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.
-
- - - - diff --git a/documentation/htmldoxygen/pvaClientMonitorRequester.html b/documentation/htmldoxygen/pvaClientMonitorRequester.html deleted file mode 100644 index 31daa94..0000000 --- a/documentation/htmldoxygen/pvaClientMonitorRequester.html +++ /dev/null @@ -1,65 +0,0 @@ - - - - - - PvaClientMonitorRequester - - - - - - - - -

PvaClientMonitorRequester

- -

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

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

The client must call

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

-after creating an instance of PvaClientMonitor. -

- - - - - diff --git a/documentation/htmldoxygen/pvaClientProcess.html b/documentation/htmldoxygen/pvaClientProcess.html deleted file mode 100644 index b1de4f2..0000000 --- a/documentation/htmldoxygen/pvaClientProcess.html +++ /dev/null @@ -1,71 +0,0 @@ - - - - - - PvaClientProcess - - - - - - - - -

PvaClientProcess

- -

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

-

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

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

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

-

PvaClientChannel has methods:

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

-issueConnect and issueProcess do not block. -All other methods can block. -

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

PvaClientChannelPut

s - -

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

-

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

-

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

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

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

-

PvaClientPut has methods:

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

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

- - - - - diff --git a/documentation/htmldoxygen/pvaClientPutData.html b/documentation/htmldoxygen/pvaClientPutData.html deleted file mode 100644 index 09cff35..0000000 --- a/documentation/htmldoxygen/pvaClientPutData.html +++ /dev/null @@ -1,75 +0,0 @@ - - - - - - PvaClientPutData - - - - - - - - -

PvaClientPutData

- -

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

-

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

- -

-PvaClientPutData provides methods:

-
-getStructure          Get the introspection interface for data sent to server
-getPVStructure        Get the complete set of data sent to the server.
-getChangedBitSet      Get the bitSet that shows which fields have a new value since last get.
-showChanged           Show all the fields that have changed value since the last get,
-getAlarm              If a alarm field is available get it.
-getTimeStamp          If a timeStamp field is available get it.
-hasValue              Does the PVStructure have a top level field named value
-NOTE: The following only apply 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.
-
- - - diff --git a/documentation/htmldoxygen/pvaClientPutGet.html b/documentation/htmldoxygen/pvaClientPutGet.html deleted file mode 100644 index f0db3bf..0000000 --- a/documentation/htmldoxygen/pvaClientPutGet.html +++ /dev/null @@ -1,85 +0,0 @@ - - - - - - PvaClientPutGetGet - - - - - - - - -

PvaClientPutGetGet

- -

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

-

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

-

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

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

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

-

PvaClientPutGet has methods:

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

-issueConnect, issuePutGet, issueGetGet and issueGetPut do not block. -All other methods can block. -

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

PvaClientPutGetRequester

- -

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

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

The client must call

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

-after creating an instance of PvaClientPutGet. -

- - - - - diff --git a/documentation/htmldoxygen/pvaClientPutRequester.html b/documentation/htmldoxygen/pvaClientPutRequester.html deleted file mode 100644 index 9206b6b..0000000 --- a/documentation/htmldoxygen/pvaClientPutRequester.html +++ /dev/null @@ -1,63 +0,0 @@ - - - - - - PvaClientPutRequester - - - - - - - - -

PvaClientPutRequester

- -

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

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

The client must call

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

-after creating an instance of PvaClientPut. -

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

PvaClientRPC

- -

-Not Yet Written -

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

PvaClientRPCRequester

- -

-Not Yet Written -

- - - - diff --git a/documentation/pvaClientCPP.html b/documentation/pvaClientCPP.html index 68fe4c2..c9b7687 100644 --- a/documentation/pvaClientCPP.html +++ b/documentation/pvaClientCPP.html @@ -26,7 +26,7 @@

EPICS pvaClientCPP

-

Release 4.4 - April 2019

+

Release 4.8 - March 2021

Abstract

@@ -66,9 +66,16 @@ The data for the channels is presented via normative type NTMultiChannel.

Overview

+Documentation for pvaClientCPP is available at: + +pvaClient + +

+

pvaClientCPP is one of the components of - -EPICS Version 4 + +EPICS-7

This document is only a guide to help locate code and documentation related to pvaClientCPP diff --git a/src/pv/pvaClient.h b/src/pv/pvaClient.h index c6dc54a..a737133 100644 --- a/src/pv/pvaClient.h +++ b/src/pv/pvaClient.h @@ -58,8 +58,6 @@ typedef std::tr1::shared_ptr PvaClientChan typedef std::tr1::weak_ptr PvaClientChannelStateChangeRequesterWPtr; class PvaClientChannel; typedef std::tr1::shared_ptr PvaClientChannelPtr; -class PvaClientField; -typedef std::tr1::shared_ptr PvaClientFieldPtr; class PvaClientProcessRequester; typedef std::tr1::shared_ptr PvaClientProcessRequesterPtr; typedef std::tr1::weak_ptr PvaClientProcessRequesterWPtr; @@ -85,8 +83,6 @@ typedef std::tr1::shared_ptr PvaClientMonitorPtr; class PvaClientMonitorRequester; typedef std::tr1::shared_ptr PvaClientMonitorRequesterPtr; typedef std::tr1::weak_ptr PvaClientMonitorRequesterWPtr; -class PvaClientArray; -typedef std::tr1::shared_ptr PvaClientArrayPtr; class PvaClientRPC; typedef std::tr1::shared_ptr PvaClientRPCPtr; class PvaClientRPCRequester; @@ -101,7 +97,6 @@ typedef std::tr1::shared_ptr PvaClientChannelCachePtr; /** * @brief pvaClient is a synchronous wrapper for the pvAccess API, which is a callback based API. * - * Overview of PvaClient */ class epicsShareClass PvaClient : public epics::pvData::Requester, @@ -119,16 +114,11 @@ public: * @return shared pointer to the single instance. */ static PvaClientPtr get(std::string const & providerNames = "pva ca"); - /** @brief Get the requester name. - * @return The name. - */ - /** @brief Create an instance of PvaClient with providerName "pva ca". + /** @brief Create an instance of PvaClient with providerName "pva ca". * @return shared pointer to the single instance * @deprecated This method will go away in future versions. Use get instead. */ static PvaClientPtr create() EPICS_DEPRECATED; - - std::string getRequesterName(); /** @brief A new message. * * If a requester is set then it is called otherwise message is displayed @@ -156,7 +146,6 @@ public: * @param channelName The channelName. * @param providerName The provider. * @return The interface. - * @throw runtime_error if connection fails. */ PvaClientChannelPtr createChannel( std::string const & channelName, @@ -168,6 +157,13 @@ public: * @param requester The requester. */ void setRequester(epics::pvData::RequesterPtr const & requester); + /** @brief Get the requester name. + * + * If client calls setRequester then the client supplies the name. + * Otherwise the name is pvaClient. + * @return The name. + */ + std::string getRequesterName(); /** @brief Clear the requester. PvaClient will handle messages. */ void clearRequester(); @@ -207,7 +203,6 @@ typedef std::tr1::shared_ptr PvaClientPutCachePtr; /** * @brief A callback for change in connection status. * - * Overview of PvaClientChannelStateChangeRequester * */ class epicsShareClass PvaClientChannelStateChangeRequester @@ -231,7 +226,6 @@ public: /** * @brief An easy to use alternative to directly calling the Channel methods of pvAccess. * - * Overview of PvaClientChannel */ class epicsShareClass PvaClientChannel : @@ -276,13 +270,6 @@ public: * @return status. */ epics::pvData::Status waitConnect(double timeout = 5.0); - /** @brief Create a PvaClientField for the specified subField. - * - * @param subField The desired subField, i. e. "field.field...." - * An empty string, i. e. "", asks for the entire top level struture as defined by the server. - * @return The interface. - */ - PvaClientFieldPtr createField(std::string const & subField = ""); /** @brief First call createRequest as implemented by pvDataCPP and then call the next method. * * @param request The syntax of request is defined by the copy facility of pvData. @@ -426,20 +413,6 @@ public: * @return The interface. */ PvaClientPutGetPtr createPutGet(epics::pvData::PVStructurePtr const & pvRequest); - /** @brief Create a PvaClientArray. - * - * First call createRequest as implemented by pvDataJava and then call the next method. - * @param request The syntax of request is defined by the copy facility of pvData. - * @return The interface. - * @throw runtime_error if failure. - */ - PvaClientArrayPtr createArray(std::string const & request = "field(value)"); - /** @brief Create a PvaClientArray. - * @param pvRequest The syntax of pvRequest is defined by the copy facility of pvData. - * @return The interface. - * @throw runtime_error if failure. - */ - PvaClientArrayPtr createArray(epics::pvData::PVStructurePtr const & pvRequest); /** @brief Create a PvaClientMonitor. * * Create and connect to a new PvaClientMonitor. @@ -564,7 +537,6 @@ public: /** * @brief A base class for PvaClientGetData, PvaClientPutData, and PvaClientMonitorData. * - * Overview of PvaClientData */ class epicsShareClass PvaClientData { @@ -685,15 +657,15 @@ public: * * Accepts arguments of the form json or field='value' where value is json syntax. * field is name.name... - * @param args The arguments + * @param args The arguments. * @throw runtime_error if failure. */ void parse(const std::vector &args); - /** @brief generate JSON output from the current PVStructure + /** @brief generate JSON output from the current PVStructure and displays it on the output stream. * - * @param strm output stream - * @param ignoreUnprintable false or true; default is true. - * @param multiline false or true; default is false + * @param strm The output stream. + * @param ignoreUnprintable false or true; The default is true. + * @param multiline false or true; The default is false. * * @throw runtime_error if failure. */ @@ -704,14 +676,8 @@ public: /** @brief set length of all array fields to 0 */ void zeroArrayLength(); - /** @brief Factory method for creating an instance of PvaClientData. - * - * NOTE: Not normally called by clients - * @param structure Introspection interface - * @throw runtime_error if failure. - */ - static PvaClientDataPtr create(epics::pvData::StructureConstPtr const & structure); protected: + static PvaClientDataPtr create(epics::pvData::StructureConstPtr const & structure); PvaClientData(epics::pvData::StructureConstPtr const & structure); epics::pvData::PVFieldPtr getSinglePVField(); void checkValue(); @@ -740,7 +706,6 @@ private: /** * @brief A class that holds data returned by PvaClientGet or PvaClientPutGet * - * Overview of PvaClientGetData */ class epicsShareClass PvaClientGetData : public PvaClientData { @@ -767,7 +732,6 @@ class PvaClientPostHandlerPvt; // private to PvaClientPutData /** * @brief A class that holds data given to by PvaClientPut or PvaClientPutGet * - * Overview of PvaClientPutData */ class epicsShareClass PvaClientPutData : public PvaClientData { @@ -819,8 +783,6 @@ private: /** * @brief A class that holds data returned by PvaClientMonitor - * - * Overview of PvaClientMonitorData */ class epicsShareClass PvaClientMonitorData : public PvaClientData { @@ -861,7 +823,6 @@ private: /** * @brief Optional client callback. * - * Overview of PvaClientProcessRequester */ class epicsShareClass PvaClientProcessRequester { @@ -896,7 +857,6 @@ typedef std::tr1::shared_ptr ChannelProcessRequeste /** * @brief An easy to use alternative to ChannelProcess. * - * Overview of PvaClientProcess */ class epicsShareClass PvaClientProcess : public std::tr1::enable_shared_from_this @@ -1001,7 +961,6 @@ typedef std::tr1::shared_ptr ChannelGetRequesterImplPtr /** * @brief Optional client callback. * - * Overview of PvaClientGetRequester */ class epicsShareClass PvaClientGetRequester { @@ -1030,7 +989,6 @@ public: /** * @brief An easy to use alternative to ChannelGet. * - * Overview of PvaClientGet */ class epicsShareClass PvaClientGet : public std::tr1::enable_shared_from_this @@ -1146,7 +1104,6 @@ typedef std::tr1::shared_ptr ChannelPutRequesterImplPtr /** * @brief Optional client callback. * - * Overview of PvaClientPutRequester */ class epicsShareClass PvaClientPutRequester { @@ -1186,7 +1143,6 @@ public: /** * @brief An easy to use alternative to ChannelPut. * - * Overview of PvaClientPut */ class epicsShareClass PvaClientPut : public std::tr1::enable_shared_from_this @@ -1312,7 +1268,6 @@ typedef std::tr1::shared_ptr ChannelPutGetRequesterI /** * @brief Optional client callback. * - * Overview of PvaClientPutGetRequester */ class epicsShareClass PvaClientPutGetRequester { @@ -1364,7 +1319,6 @@ public: /** * @brief An easy to use alternative to ChannelPutGet. * - * Overview of PvaClientPutGet */ class epicsShareClass PvaClientPutGet : public std::tr1::enable_shared_from_this @@ -1511,11 +1465,9 @@ public: friend class ChannelPutGetRequesterImpl; }; -//class ChannelMonitorRequester; // private to PvaClientMonitor /** * @brief Optional client callback. * - * Overview of PvaClientMonitorRequester */ class epicsShareClass PvaClientMonitorRequester { @@ -1556,7 +1508,6 @@ typedef std::tr1::shared_ptr MonitorRequesterImplPtr; /** * @brief An easy to use alternative to Monitor. * - * Overview of PvaClientMonitor */ class epicsShareClass PvaClientMonitor : public PvaClientChannelStateChangeRequester, // remove when deprecated create removed @@ -1705,7 +1656,6 @@ public: /** * @brief Optional client callback. * - * Overview of PvaClientRPCRequester */ class PvaClientRPCRequester { @@ -1731,7 +1681,6 @@ typedef std::tr1::shared_ptr RPCRequesterImplPtr; /** * @brief An easy to use alternative to RPC. * - * Overview of PvaClientRPC */ class epicsShareClass PvaClientRPC : public std::tr1::enable_shared_from_this @@ -1854,9 +1803,3 @@ private: }} #endif /* PVACLIENT_H */ - -/** @page Overview Documentation - * - * pvaClientCPP.html - * - */ diff --git a/src/pv/pvaClientMultiChannel.h b/src/pv/pvaClientMultiChannel.h index cb40de0..f2b1829 100644 --- a/src/pv/pvaClientMultiChannel.h +++ b/src/pv/pvaClientMultiChannel.h @@ -148,13 +148,13 @@ public: private: PvaClientMultiChannel( PvaClientPtr const &pvaClient, - epics::pvData::shared_vector const & channelName, + epics::pvData::shared_vector const & channelNames, std::string const & providerName, size_t maxNotConnected); void checkConnected(); PvaClientPtr pvaClient; - epics::pvData::shared_vector channelName; + epics::pvData::shared_vector channelNames; std::string providerName; size_t maxNotConnected; @@ -162,6 +162,7 @@ private: epics::pvData::Mutex mutex; size_t numConnected; + bool firstConnect; PvaClientChannelArray pvaClientChannelArray; epics::pvData::shared_vector isConnected; epics::pvData::CreateRequest::shared_pointer createRequest; @@ -176,19 +177,16 @@ class epicsShareClass PvaClientMultiGetDouble : public: POINTER_DEFINITIONS(PvaClientMultiGetDouble); - - /** - * @brief Create a PvaClientMultiGetDouble. - * @param pvaClientMultiChannel The interface to PvaClientMultiChannel. - * @param pvaClientChannelArray The PvaClientChannel array. - * @return The interface. - */ +protected: static PvaClientMultiGetDoublePtr create( PvaClientMultiChannelPtr const &pvaClientMultiChannel, PvaClientChannelArray const &pvaClientChannelArray); - + friend class PvaClientMultiChannel; +public: + /** + * @brief Destructor + */ ~PvaClientMultiGetDouble(); - /** * @brief Create a channelGet for each channel. */ @@ -198,13 +196,6 @@ public: * @return The double[] where each element is the value field of the corresponding channel. */ epics::pvData::shared_vector get(); - /** @brief Get the shared pointer to self. - * @return The shared pointer. - */ - PvaClientMultiGetDoublePtr getPtrSelf() - { - return shared_from_this(); - } private: PvaClientMultiGetDouble( PvaClientMultiChannelPtr const &pvaClientMultiChannel, @@ -229,15 +220,15 @@ class epicsShareClass PvaClientMultiPutDouble : public: POINTER_DEFINITIONS(PvaClientMultiPutDouble); - - /** @brief Create a PvaClientMultiPutDouble. - * @param pvaClientMultiChannel The interface to PvaClientMultiChannel. - * @param pvaClientChannelArray The PvaClientChannel array. - * @return The interface. - */ +protected: static PvaClientMultiPutDoublePtr create( PvaClientMultiChannelPtr const &pvaClientMultiChannel, PvaClientChannelArray const &pvaClientChannelArray); + friend class PvaClientMultiChannel; +public: + /** + * @brief Destructor + */ ~PvaClientMultiPutDouble(); /** * @brief Create a channelPut for each channel. @@ -247,13 +238,7 @@ public: * @param data The array of data for each channel. */ void put(epics::pvData::shared_vector const &data); - /** @brief Get the shared pointer to self. - * @return The shared pointer. - */ - PvaClientMultiPutDoublePtr getPtrSelf() - { - return shared_from_this(); - } + private: PvaClientMultiPutDouble( PvaClientMultiChannelPtr const &pvaClientMultiChannel, @@ -277,15 +262,15 @@ class epicsShareClass PvaClientMultiMonitorDouble : public: POINTER_DEFINITIONS(PvaClientMultiMonitorDouble); - - /** @brief Create a PvaClientMultiMonitorDouble. - * @param pvaClientMultiChannel The interface to PvaClientMultiChannel. - * @param pvaClientChannelArray The PvaClientChannel array. - * @return The interface. - */ +protected: static PvaClientMultiMonitorDoublePtr create( PvaClientMultiChannelPtr const &pvaClientMultiChannel, PvaClientChannelArray const &pvaClientChannelArray); + friend class PvaClientMultiChannel; +public: + /** + * @brief Destructor + */ ~PvaClientMultiMonitorDouble(); /** * @brief Connect a channel monitor for each channel. @@ -310,13 +295,7 @@ public: * @return The double[] where each element is the value field of the corresponding channel. */ epics::pvData::shared_vector get(); - /** @brief Monitor the shared pointer to self. - * @return The shared pointer. - */ - PvaClientMultiMonitorDoublePtr getPtrSelf() - { - return shared_from_this(); - } + private: PvaClientMultiMonitorDouble( PvaClientMultiChannelPtr const &pvaClientMultiChannel, @@ -341,18 +320,16 @@ class epicsShareClass PvaClientNTMultiGet : public: POINTER_DEFINITIONS(PvaClientNTMultiGet); - /** - * @brief Create a PvaClientNTMultiGet. - * @param pvaClientMultiChannel The interface to PvaClientMultiChannel. - * @param pvaClientChannelArray The PvaClientChannel array. - * @param pvRequest The pvRequest for each channel. - * @return The interface. - */ +protected: static PvaClientNTMultiGetPtr create( PvaClientMultiChannelPtr const &pvaClientMultiChannel, PvaClientChannelArray const &pvaClientChannelArray, epics::pvData::PVStructurePtr const & pvRequest); - + friend class PvaClientMultiChannel; +public: + /** + * @brief Destructor + */ ~PvaClientNTMultiGet(); /** * @brief Connect a channelGet for each channel. @@ -369,13 +346,7 @@ public: * @return the pvaClientNTMultiData. */ PvaClientNTMultiDataPtr getData(); - /** @brief Get the shared pointer to self. - * @return The shared pointer. - */ - PvaClientNTMultiGetPtr getPtrSelf() - { - return shared_from_this(); - } + private: PvaClientNTMultiGet( epics::pvData::UnionConstPtr const & u, @@ -389,7 +360,6 @@ private: size_t nchannel; epics::pvData::Mutex mutex; - PvaClientNTMultiDataPtr pvaClientNTMultiData; std::vector pvaClientGet; bool isConnected; @@ -404,16 +374,15 @@ class epicsShareClass PvaClientNTMultiPut : public: POINTER_DEFINITIONS(PvaClientNTMultiPut); - /** - * @brief Create a PvaClientNTMultiPut. - * @param pvaClientMultiChannel The interface to PvaClientMultiChannel. - * @param pvaClientChannelArray The PvaClientChannel array. - * @return The interface. - */ +protected: static PvaClientNTMultiPutPtr create( PvaClientMultiChannelPtr const &pvaClientMultiChannel, PvaClientChannelArray const &pvaClientChannelArray); - + friend class PvaClientMultiChannel; +public: + /** + * @brief Destructor + */ ~PvaClientNTMultiPut(); /** * @brief Connect a channelPut for each channel. @@ -426,15 +395,9 @@ public: epics::pvData::shared_vector getValues(); /** * @brief Issue a put for each channel. -' */ - void put(); - /** @brief Get the shared pointer to self. - * @return The shared pointer. */ - PvaClientNTMultiPutPtr getPtrSelf() - { - return shared_from_this(); - } + void put(); + private: PvaClientNTMultiPut( PvaClientMultiChannelPtr const &pvaClientMultiChannel, @@ -460,16 +423,16 @@ class epicsShareClass PvaClientNTMultiMonitor : public: POINTER_DEFINITIONS(PvaClientNTMultiMonitor); - /** @brief Create a PvaClientNTMultiMonitor. - * @param pvaClientMultiChannel The interface to PvaClientMultiChannel. - * @param pvaClientChannelArray The PvaClientChannel array. - * @param pvRequest The pvRequest for each channel. - * @return The interface. - */ +protected: static PvaClientNTMultiMonitorPtr create( PvaClientMultiChannelPtr const &pvaClientMultiChannel, PvaClientChannelArray const &pvaClientChannelArray, epics::pvData::PVStructurePtr const & pvRequest); + friend class PvaClientMultiChannel; +public: + /** + * @brief Destructor + */ ~PvaClientNTMultiMonitor(); /** * @brief Connect to a channel monitor for each channel. @@ -495,13 +458,7 @@ public: * @return the pvaClientNTMultiData. */ PvaClientNTMultiDataPtr getData(); - /** Monitor the shared pointer to self. - * @return The shared pointer. - */ - PvaClientNTMultiMonitorPtr getPtrSelf() - { - return shared_from_this(); - } + private: PvaClientNTMultiMonitor( epics::pvData::UnionConstPtr const & u, @@ -528,39 +485,13 @@ class epicsShareClass PvaClientNTMultiData : public: POINTER_DEFINITIONS(PvaClientNTMultiData); - /** - * @brief Create a PvaClientNTMultiData. - * - * Normally only called by PvaClientNTMultiGet and PvaClientNTMultiMonitor. - * @param u The union interface for the value field of each channel. - * @param pvaClientMultiChannel The interface to PvaClientMultiChannel. - * @param pvaClientChannelArray The PvaClientChannel array. - * @param pvRequest The pvRequest for each channel. - */ - static PvaClientNTMultiDataPtr create( - epics::pvData::UnionConstPtr const & u, - PvaClientMultiChannelPtr const &pvaClientMultiChannel, - PvaClientChannelArray const &pvaClientChannelArray, - epics::pvData::PVStructurePtr const & pvRequest); ~PvaClientNTMultiData(); - - /** + /** * @brief Get the number of channels. * @return The number of channels. */ size_t getNumber(); - - /** - * @brief Set the timeStamp base for computing deltaTimes. - */ - void startDeltaTime(); - /** - * @brief Update NTMultiChannel fields. - * - * @param valueOnly use only value for union. - */ - void endDeltaTime(bool valueOnly = true); - /** + /** * @brief Get the time when the last get was made. * @return The timeStamp. */ @@ -570,13 +501,21 @@ public: * @return The value. */ epics::nt::NTMultiChannelPtr getNTMultiChannel(); - /** @brief Get the shared pointer to self. - * @return The shared pointer. + /** + * @brief Get channel change flags. + * @return Array of boolean fields that are set to true if corresponding channel changed */ - PvaClientNTMultiDataPtr getPtrSelf() - { - return shared_from_this(); - } + epics::pvData::shared_vector getChannelChangeFlags(); +protected: + static PvaClientNTMultiDataPtr create( + epics::pvData::UnionConstPtr const & u, + PvaClientMultiChannelPtr const &pvaClientMultiChannel, + PvaClientChannelArray const &pvaClientChannelArray, + epics::pvData::PVStructurePtr const & pvRequest); + void startDeltaTime(); + void endDeltaTime(bool valueOnly = true); + friend class PvaClientNTMultiGet; + friend class PvaClientNTMultiMonitor; private: PvaClientNTMultiData( epics::pvData::UnionConstPtr const & u, @@ -594,7 +533,8 @@ private: std::vector topPVStructure; bool gotAlarm; bool gotTimeStamp; - + + epics::pvData::shared_vector changeFlags; epics::pvData::StructureConstPtr ntMultiChannelStructure; epics::pvData::shared_vector unionValue; epics::pvData::shared_vector severity; @@ -606,9 +546,6 @@ private: epics::pvData::Alarm alarm; epics::pvData::TimeStamp timeStamp;; epics::pvData::PVTimeStamp pvTimeStamp; - friend class PvaClientNTMultiGet; - friend class PvaClientNTMultiPut; - friend class PvaClientNTMultiMonitor; }; diff --git a/src/pvaClientChannel.cpp b/src/pvaClientChannel.cpp index 919204a..8a11213 100644 --- a/src/pvaClientChannel.cpp +++ b/src/pvaClientChannel.cpp @@ -182,10 +182,6 @@ void PvaClientChannel::channelCreated(const Status& status, Channel::shared_poin + " status " + status.getMessage() + " why??"; throw std::runtime_error(message); } - if(channel->isConnected()) { - connectState = connected; - waitForConnect.signal(); - } } void PvaClientChannel::channelStateChange( @@ -319,13 +315,6 @@ Status PvaClientChannel::waitConnect(double timeout) return Status(Status::STATUSTYPE_ERROR," not connected"); } - -PvaClientFieldPtr PvaClientChannel::createField(string const & subField) -{ - if(connectState!=connected) connect(5.0); - throw std::runtime_error("PvaClientChannel::createField not implemented"); -} - PvaClientProcessPtr PvaClientChannel::createProcess(string const & request) { PVStructurePtr pvRequest = createRequest->createRequest(request); @@ -493,27 +482,6 @@ PvaClientPutGetPtr PvaClientChannel::createPutGet(PVStructurePtr const & pvReque return PvaClientPutGet::create(yyy,shared_from_this(),pvRequest); } - - -PvaClientArrayPtr PvaClientChannel::createArray(string const & request) -{ - PVStructurePtr pvRequest = createRequest->createRequest(request); - if(!pvRequest) { - string message = string("channel ") + channelName - + " PvaClientChannel::createArray invalid pvRequest: " - + createRequest->getMessage(); - throw std::runtime_error(message); - } - return createArray(pvRequest); -} - -PvaClientArrayPtr PvaClientChannel::createArray(PVStructurePtr const & pvRequest) -{ - if(connectState!=connected) connect(5.0); - throw std::runtime_error("PvaClientChannel::createArray not implemented"); -} - - PvaClientMonitorPtr PvaClientChannel::monitor(string const & request) { PvaClientMonitorPtr pvaClientMonitor = createMonitor(request); diff --git a/src/pvaClientData.cpp b/src/pvaClientData.cpp index 29d336f..7ec2d2f 100644 --- a/src/pvaClientData.cpp +++ b/src/pvaClientData.cpp @@ -405,20 +405,20 @@ void PvaClientData::streamJSON( } -void PvaClientData::zeroArrayLength(const epics::pvData::PVStructurePtr &pvStructure) +void PvaClientData::zeroArrayLength(const PVStructurePtr &pvStructure) { const PVFieldPtrArray pvFields(pvStructure->getPVFields()); for(size_t i=0; igetField()->getType()); switch(type) { - case epics::pvData::scalarArray: + case scalarArray: { PVScalarArrayPtr pvScalarArray = static_pointer_cast(pvField); pvScalarArray->setLength(0); } break; - case epics::pvData::structureArray: + case structureArray: { PVStructureArrayPtr pvStructureArray = static_pointer_cast(pvField); pvStructureArray->setLength(0); diff --git a/src/pvaClientGet.cpp b/src/pvaClientGet.cpp index 81dc41c..ac792bd 100644 --- a/src/pvaClientGet.cpp +++ b/src/pvaClientGet.cpp @@ -42,7 +42,7 @@ public: return clientGet->getRequesterName(); } - virtual void message(std::string const & message, epics::pvData::MessageType messageType) { + virtual void message(std::string const & message, MessageType messageType) { PvaClientGetPtr clientGet(pvaClientGet.lock()); if(!clientGet) return; clientGet->message(message,messageType); @@ -162,27 +162,19 @@ void PvaClientGet::channelGetConnect( } { Lock xx(mutex); - this->channelGet = channelGet; + channelGetConnectStatus = status; if(status.isOK()) { - channelGetConnectStatus = status; + this->channelGet = channelGet; connectState = connected; pvaClientData = PvaClientGetData::create(structure); pvaClientData->setMessagePrefix(channelGet->getChannel()->getChannelName()); - } else { - stringstream ss; - ss << pvRequest; - string message = string("\nPvaClientGet::channelGetConnect)") - + "\npvRequest\n" + ss.str() - + "\nerror\n" + status.getMessage(); - channelGetConnectStatus = Status(Status::STATUSTYPE_ERROR,message); - } + } + waitForConnect.signal(); } PvaClientGetRequesterPtr req(pvaClientGetRequester.lock()); if(req) { req->channelGetConnect(status,shared_from_this()); - } - waitForConnect.signal(); - + } } void PvaClientGet::getDone( @@ -200,16 +192,16 @@ void PvaClientGet::getDone( { Lock xx(mutex); channelGetStatus = status; - getState = getComplete; if(status.isOK()) { pvaClientData->setData(pvStructure,bitSet); } + getState = getComplete; + waitForGet.signal(); } PvaClientGetRequesterPtr req(pvaClientGetRequester.lock()); if(req) { req->getDone(status,shared_from_this()); } - waitForGet.signal(); } void PvaClientGet::connect() @@ -248,20 +240,7 @@ Status PvaClientGet::waitConnect() cout << "PvaClientGet::waitConnect channelName " << pvaClientChannel->getChannel()->getChannelName() << "\n"; } - { - Lock xx(mutex); - if(connectState==connected) { - if(!channelGetConnectStatus.isOK()) connectState = connectIdle; - return channelGetConnectStatus; - } - if(connectState!=connectActive) { - string message = string("channel ") + pvaClientChannel->getChannel()->getChannelName() - + " PvaClientGet::waitConnect illegal connect state "; - throw std::runtime_error(message); - } - } waitForConnect.wait(); - if(!channelGetConnectStatus.isOK()) connectState = connectIdle; return channelGetConnectStatus; } @@ -301,20 +280,7 @@ Status PvaClientGet::waitGet() cout << "PvaClientGet::waitGet channelName " << pvaClientChannel->getChannel()->getChannelName() << "\n"; } - { - Lock xx(mutex); - if(getState==getComplete) { - getState = getIdle; - return channelGetStatus; - } - if(getState!=getActive){ - string message = string("channel ") + pvaClientChannel->getChannel()->getChannelName() - + " PvaClientGet::waitGet llegal get state"; - throw std::runtime_error(message); - } - } waitForGet.wait(); - getState = getComplete; return channelGetStatus; } PvaClientGetDataPtr PvaClientGet::getData() diff --git a/src/pvaClientMonitor.cpp b/src/pvaClientMonitor.cpp index ef321c5..76dd13b 100644 --- a/src/pvaClientMonitor.cpp +++ b/src/pvaClientMonitor.cpp @@ -44,7 +44,7 @@ public: return clientMonitor->getRequesterName(); } - virtual void message(std::string const & message, epics::pvData::MessageType messageType) { + virtual void message(std::string const & message, MessageType messageType) { PvaClientMonitorPtr clientMonitor(pvaClientMonitor.lock()); if(!clientMonitor) return; clientMonitor->message(message,messageType); @@ -60,14 +60,14 @@ public: clientMonitor->monitorConnect(status,monitor,structure); } - virtual void unlisten(epics::pvData::MonitorPtr const & monitor) + virtual void unlisten(MonitorPtr const & monitor) { PvaClientMonitorPtr clientMonitor(pvaClientMonitor.lock()); if(!clientMonitor) return; clientMonitor->unlisten(monitor); } - virtual void monitorEvent(epics::pvData::MonitorPtr const & monitor) + virtual void monitorEvent(MonitorPtr const & monitor) { PvaClientMonitorPtr clientMonitor(pvaClientMonitor.lock()); if(!clientMonitor) return; @@ -226,19 +226,24 @@ void PvaClientMonitor::monitorConnect( } { Lock xx(mutex); - this->monitor = monitor; - if(!status.isOK()) { + monitorConnectStatus = status; + if(status.isOK()) { + this->monitor = monitor; + } else { stringstream ss; ss << pvRequest; string message = string("\nPvaClientMonitor::monitorConnect)") + + "\nchannelName=" + pvaClientChannel->getChannel()->getChannelName() + "\npvRequest\n" + ss.str() + "\nerror\n" + status.getMessage(); monitorConnectStatus = Status(Status::STATUSTYPE_ERROR,message); + waitForConnect.signal(); + PvaClientMonitorRequesterPtr req(pvaClientMonitorRequester.lock()); + if(req) req->monitorConnect(status,shared_from_this(),structure); return; } } bool signal = (connectState==connectWait) ? true : false; - monitorConnectStatus = status; connectState = connected; if(isStarted) { if(PvaClient::getDebug()) { @@ -247,6 +252,9 @@ void PvaClientMonitor::monitorConnect( << " is already started " << endl; } + waitForConnect.signal(); + PvaClientMonitorRequesterPtr req(pvaClientMonitorRequester.lock()); + if(req) req->monitorConnect(status,shared_from_this(),structure); return; } pvaClientData = PvaClientMonitorData::create(structure); @@ -288,9 +296,7 @@ void PvaClientMonitor::unlisten(MonitorPtr const & monitor) PvaClientMonitorRequesterPtr req = pvaClientMonitorRequester.lock(); if(req) { req->unlisten(); - return; } - cerr << pvaClientChannel->getChannel()->getChannelName() + "pvaClientMonitor::unlisten called but no PvaClientMonitorRequester\n"; } @@ -327,20 +333,7 @@ Status PvaClientMonitor::waitConnect() << pvaClientChannel->getChannel()->getChannelName() << endl; } - { - Lock xx(mutex); - if(connectState==connected) { - if(!monitorConnectStatus.isOK()) connectState = connectIdle; - return monitorConnectStatus; - } - if(connectState!=connectWait) { - string message = string("channel ") + pvaClientChannel->getChannel()->getChannelName() - + " PvaClientMonitor::waitConnect illegal connect state "; - throw std::runtime_error(message); - } - } waitForConnect.wait(); - connectState = monitorConnectStatus.isOK() ? connected : connectIdle; if(PvaClient::getDebug()) { cout << "PvaClientMonitor::waitConnect" << " monitorConnectStatus " << (monitorConnectStatus.isOK() ? "connected" : "not connected") @@ -438,7 +431,7 @@ bool PvaClientMonitor::poll() if(!monitorElement) return false; userPoll = true; pvaClientData->setData(monitorElement); - return true; + return true; } bool PvaClientMonitor::waitEvent(double secondsToWait) diff --git a/src/pvaClientMultiChannel.cpp b/src/pvaClientMultiChannel.cpp index 5267bd1..e147579 100644 --- a/src/pvaClientMultiChannel.cpp +++ b/src/pvaClientMultiChannel.cpp @@ -28,7 +28,7 @@ static CreateRequest::shared_pointer createRequestPvt = CreateRequest::create() PvaClientMultiChannelPtr PvaClientMultiChannel::create( PvaClientPtr const &pvaClient, - epics::pvData::shared_vector const & channelNames, + shared_vector const & channelNames, string const & providerName, size_t maxNotConnected) { @@ -39,17 +39,18 @@ PvaClientMultiChannelPtr PvaClientMultiChannel::create( PvaClientMultiChannel::PvaClientMultiChannel( PvaClientPtr const &pvaClient, - epics::pvData::shared_vector const & channelName, + shared_vector const & channelNames, string const & providerName, size_t maxNotConnected) : pvaClient(pvaClient), - channelName(channelName), + channelNames(channelNames), providerName(providerName), maxNotConnected(maxNotConnected), - numChannel(channelName.size()), + numChannel(channelNames.size()), numConnected(0), + firstConnect(true), pvaClientChannelArray(PvaClientChannelArray(numChannel,PvaClientChannelPtr())), - isConnected(shared_vector(numChannel,false)), + isConnected(shared_vector(numChannel,false)), createRequest(CreateRequest::create()) { if(PvaClient::getDebug()) cout<< "PvaClientMultiChannel::PvaClientMultiChannel()\n"; @@ -62,18 +63,23 @@ PvaClientMultiChannel::~PvaClientMultiChannel() void PvaClientMultiChannel::checkConnected() { - if(numConnected==0) connect(); + if(firstConnect) { + connect(); + firstConnect = false; + } } -epics::pvData::shared_vector PvaClientMultiChannel::getChannelNames() +shared_vector PvaClientMultiChannel::getChannelNames() { - return channelName; + return channelNames; } Status PvaClientMultiChannel::connect(double timeout) { + if(!firstConnect) return Status::Ok; + firstConnect = false; for(size_t i=0; i< numChannel; ++i) { - pvaClientChannelArray[i] = pvaClient->createChannel(channelName[i],providerName); + pvaClientChannelArray[i] = pvaClient->createChannel(channelNames[i],providerName); pvaClientChannelArray[i]->issueConnect(); } Status returnStatus = Status::Ok; @@ -88,11 +94,10 @@ Status PvaClientMultiChannel::connect(double timeout) if(status.isOK()) { ++numConnected; isConnected[i] = true; - continue; + } else { + if(returnStatus.isOK()) returnStatus = status; + ++numBad; } - if(returnStatus.isOK()) returnStatus = status; - ++numBad; - if(numBad>maxNotConnected) break; } return numBad>maxNotConnected ? returnStatus : Status::Ok; } @@ -115,7 +120,7 @@ bool PvaClientMultiChannel::connectionChange() return false; } -epics::pvData::shared_vector PvaClientMultiChannel::getIsConnected() +shared_vector PvaClientMultiChannel::getIsConnected() { for(size_t i=0; i(nchannel)), + doubleValue( shared_vector(nchannel)), pvaClientGet(std::vector(nchannel,PvaClientGetPtr())), isGetConnected(false) { @@ -53,7 +53,7 @@ PvaClientMultiGetDouble::~PvaClientMultiGetDouble() void PvaClientMultiGetDouble::connect() { - shared_vector isConnected = pvaClientMultiChannel->getIsConnected(); + shared_vectorisConnected = pvaClientMultiChannel->getIsConnected(); string request = "value"; for(size_t i=0; i PvaClientMultiGetDouble::get() +shared_vector PvaClientMultiGetDouble::get() { if(!isGetConnected) connect(); - shared_vector isConnected = pvaClientMultiChannel->getIsConnected(); - + shared_vector isConnected = pvaClientMultiChannel->getIsConnected(); for(size_t i=0; icreateGet("value"); pvaClientGet[i]->issueGet(); } } @@ -96,13 +96,22 @@ epics::pvData::shared_vector PvaClientMultiGetDouble::get() throw std::runtime_error(message); } } - for(size_t i=0; igetData()->getPVStructure(); - doubleValue[i] = getConvert()->toDouble(pvStructure->getSubField("value")); + PVScalarPtr pvScalar(pvStructure->getSubField("value")); + if(pvScalar) { + ScalarType scalarType = pvScalar->getScalar()->getScalarType(); + if(ScalarTypeFunc::isNumeric(scalarType)) { + doubleValue[i] = getConvert()->toDouble(pvScalar); + } else { + doubleValue[i] = epicsNAN; + } + } else { + doubleValue[i] = epicsNAN; + } } else { doubleValue[i] = epicsNAN; } diff --git a/src/pvaClientMultiMonitorDouble.cpp b/src/pvaClientMultiMonitorDouble.cpp index db1cf1b..eaaac01 100644 --- a/src/pvaClientMultiMonitorDouble.cpp +++ b/src/pvaClientMultiMonitorDouble.cpp @@ -53,7 +53,7 @@ PvaClientMultiMonitorDouble::~PvaClientMultiMonitorDouble() void PvaClientMultiMonitorDouble::connect() { - shared_vector isConnected = pvaClientMultiChannel->getIsConnected(); + shared_vector isConnected = pvaClientMultiChannel->getIsConnected(); string request = "value"; for(size_t i=0; i isConnected = pvaClientMultiChannel->getIsConnected(); + shared_vector isConnected = pvaClientMultiChannel->getIsConnected(); for(size_t i=0; icreateMonitor("value"); + pvaClientMonitor[i]->issueConnect(); + Status status = pvaClientMonitor[i]->waitConnect(); + if(!status.isOK()) { + string message = string("channel ") + pvaClientChannelArray[i]->getChannelName() + + " PvaChannelMonitor::waitConnect " + status.getMessage(); + throw std::runtime_error(message); + } + pvaClientMonitor[i]->start(); + } if(pvaClientMonitor[i]->poll()) { doubleValue[i] = pvaClientMonitor[i]->getData()->getDouble(); pvaClientMonitor[i]->releaseEvent(); @@ -116,7 +127,7 @@ bool PvaClientMultiMonitorDouble::waitEvent(double waitForEvent) return false; } -epics::pvData::shared_vector PvaClientMultiMonitorDouble::get() +shared_vector PvaClientMultiMonitorDouble::get() { return doubleValue; } diff --git a/src/pvaClientMultiPutDouble.cpp b/src/pvaClientMultiPutDouble.cpp index aa9befe..dc45a5d 100644 --- a/src/pvaClientMultiPutDouble.cpp +++ b/src/pvaClientMultiPutDouble.cpp @@ -55,7 +55,7 @@ PvaClientMultiPutDouble::~PvaClientMultiPutDouble() void PvaClientMultiPutDouble::connect() { - shared_vector isConnected = pvaClientMultiChannel->getIsConnected(); + shared_vector isConnected = pvaClientMultiChannel->getIsConnected(); for(size_t i=0; i const &data) +void PvaClientMultiPutDouble::put(shared_vector const &data) { if(!isPutConnected) connect(); if(data.size()!=nchannel) { throw std::runtime_error("data has wrong size"); } - shared_vector isConnected = pvaClientMultiChannel->getIsConnected(); + shared_vector isConnected = pvaClientMultiChannel->getIsConnected(); for(size_t i=0; icreatePut("value"); PVStructurePtr pvTop = pvaClientPut[i]->getData()->getPVStructure(); - PVScalarPtr pvValue = pvTop->getSubField("value"); - getConvert()->fromDouble(pvValue,data[i]); - pvaClientPut[i]->issuePut(); + PVScalarPtr pvScalar= pvTop->getSubField("value"); + if(pvScalar && ScalarTypeFunc::isNumeric(pvScalar->getScalar()->getScalarType())) { + getConvert()->fromDouble(pvScalar,data[i]); + pvaClientPut[i]->issuePut(); + } else { + string message = string("channel ") + + pvaClientChannelArray[i]->getChannelName() + + " is not a numeric scalar"; + throw std::runtime_error(message); + } } if(isConnected[i]) { Status status = pvaClientPut[i]->waitPut(); diff --git a/src/pvaClientNTMultiData.cpp b/src/pvaClientNTMultiData.cpp index 403af89..6ba92c9 100644 --- a/src/pvaClientNTMultiData.cpp +++ b/src/pvaClientNTMultiData.cpp @@ -23,7 +23,7 @@ using namespace std; namespace epics { namespace pvaClient { PvaClientNTMultiDataPtr PvaClientNTMultiData::create( - epics::pvData::UnionConstPtr const & u, + UnionConstPtr const & u, PvaClientMultiChannelPtr const &pvaMultiChannel, PvaClientChannelArray const &pvaClientChannelArray, PVStructurePtr const & pvRequest) @@ -33,18 +33,21 @@ PvaClientNTMultiDataPtr PvaClientNTMultiData::create( } PvaClientNTMultiData::PvaClientNTMultiData( - epics::pvData::UnionConstPtr const & u, + UnionConstPtr const & u, PvaClientMultiChannelPtr const &pvaClientMultiChannel, PvaClientChannelArray const &pvaClientChannelArray, - epics::pvData::PVStructurePtr const & pvRequest) + PVStructurePtr const & pvRequest) : pvaClientMultiChannel(pvaClientMultiChannel), pvaClientChannelArray(pvaClientChannelArray), nchannel(pvaClientChannelArray.size()), gotAlarm(false), gotTimeStamp(false) + { if(PvaClient::getDebug()) cout<< "PvaClientNTMultiData::PvaClientNTMultiData()\n"; + changeFlags = shared_vector(nchannel); topPVStructure.resize(nchannel); + unionValue.resize(nchannel); PVDataCreatePtr pvDataCreate = getPVDataCreate(); for(size_t i=0; i< nchannel; ++i) { @@ -90,12 +93,18 @@ void PvaClientNTMultiData::setPVStructure( topPVStructure[index] = pvStructure; } +shared_vector PvaClientNTMultiData::getChannelChangeFlags() +{ + return changeFlags; +} size_t PvaClientNTMultiData::getNumber() { return nchannel; } + + void PvaClientNTMultiData::startDeltaTime() { for(size_t i=0; igetSubField("value"); if(pvValue) { unionValue[i]->set(pvst->getSubField("value")); - } else { - unionValue[i] = PVUnionPtr(); } } else { unionValue[i]->set(pvst); @@ -180,11 +187,11 @@ NTMultiChannelPtr PvaClientNTMultiData::getNTMultiChannel() PVStructurePtr pvStructure = getPVDataCreate()->createPVStructure(ntMultiChannelStructure); NTMultiChannelPtr ntMultiChannel = NTMultiChannel::wrap(pvStructure); ntMultiChannel->getChannelName()->replace(pvaClientMultiChannel->getChannelNames()); - shared_vector val(nchannel); + shared_vector val(nchannel); for(size_t i=0; igetValue()->replace(freeze(val)); - shared_vector connected = pvaClientMultiChannel->getIsConnected(); - shared_vector isConnected(nchannel); + shared_vector connected = pvaClientMultiChannel->getIsConnected(); + shared_vector isConnected(nchannel); for(size_t i=0; igetIsConnected()->replace(freeze(isConnected)); if(gotAlarm) diff --git a/src/pvaClientNTMultiGet.cpp b/src/pvaClientNTMultiGet.cpp index c9c36e6..b517436 100644 --- a/src/pvaClientNTMultiGet.cpp +++ b/src/pvaClientNTMultiGet.cpp @@ -38,7 +38,7 @@ PvaClientNTMultiGet::PvaClientNTMultiGet( UnionConstPtr const & u, PvaClientMultiChannelPtr const &pvaClientMultiChannel, PvaClientChannelArray const &pvaClientChannelArray, - epics::pvData::PVStructurePtr const & pvRequest) + PVStructurePtr const & pvRequest) : pvaClientMultiChannel(pvaClientMultiChannel), pvaClientChannelArray(pvaClientChannelArray), pvRequest(pvRequest), @@ -62,7 +62,7 @@ PvaClientNTMultiGet::~PvaClientNTMultiGet() void PvaClientNTMultiGet::connect() { pvaClientGet.resize(nchannel); - shared_vector isConnected = pvaClientMultiChannel->getIsConnected(); + shared_vector isConnected = pvaClientMultiChannel->getIsConnected(); for(size_t i=0; i isConnected = pvaClientMultiChannel->getIsConnected(); + shared_vector isConnected = pvaClientMultiChannel->getIsConnected(); for(size_t i=0; icreateGet(pvRequest); + pvaClientGet[i]->connect(); + } pvaClientGet[i]->issueGet(); } } diff --git a/src/pvaClientNTMultiMonitor.cpp b/src/pvaClientNTMultiMonitor.cpp index 6758ec6..ed7fe97 100644 --- a/src/pvaClientNTMultiMonitor.cpp +++ b/src/pvaClientNTMultiMonitor.cpp @@ -28,7 +28,7 @@ namespace epics { namespace pvaClient { PvaClientNTMultiMonitorPtr PvaClientNTMultiMonitor::create( PvaClientMultiChannelPtr const &pvaMultiChannel, PvaClientChannelArray const &pvaClientChannelArray, - epics::pvData::PVStructurePtr const & pvRequest) + PVStructurePtr const & pvRequest) { UnionConstPtr u = getFieldCreate()->createVariantUnion(); PvaClientNTMultiMonitorPtr pvaClientNTMultiMonitor( @@ -66,7 +66,7 @@ PvaClientNTMultiMonitor::~PvaClientNTMultiMonitor() void PvaClientNTMultiMonitor::connect() { pvaClientMonitor.resize(nchannel); - shared_vector isConnected = pvaClientMultiChannel->getIsConnected(); + shared_vector isConnected = pvaClientMultiChannel->getIsConnected(); for(size_t i=0; i isConnected = pvaClientMultiChannel->getIsConnected(); - pvaClientNTMultiData->startDeltaTime(); + shared_vector isConnected = pvaClientMultiChannel->getIsConnected(); + pvaClientNTMultiData->startDeltaTime(); for(size_t i=0; ipoll()) { + if(!pvaClientMonitor[i]){ + pvaClientMonitor[i]=pvaClientChannelArray[i]->createMonitor(pvRequest); + pvaClientMonitor[i]->connect(); + pvaClientMonitor[i]->start(); + } + if(pvaClientMonitor[i]->poll()) { pvaClientNTMultiData->setPVStructure( - pvaClientMonitor[i]->getData()->getPVStructure(),i); + pvaClientMonitor[i]->getData()->getPVStructure(),i); pvaClientMonitor[i]->releaseEvent(); result = true; } } - } - if(result) pvaClientNTMultiData->endDeltaTime(valueOnly); + } + if(result) pvaClientNTMultiData->endDeltaTime(valueOnly); return result; } diff --git a/src/pvaClientNTMultiPut.cpp b/src/pvaClientNTMultiPut.cpp index 21d444b..9a6552e 100644 --- a/src/pvaClientNTMultiPut.cpp +++ b/src/pvaClientNTMultiPut.cpp @@ -38,8 +38,8 @@ PvaClientNTMultiPut::PvaClientNTMultiPut( : pvaClientMultiChannel(pvaClientMultiChannel), pvaClientChannelArray(pvaClientChannelArray), nchannel(pvaClientChannelArray.size()), - unionValue(shared_vector(nchannel,PVUnionPtr())), - value(shared_vector(nchannel,PVFieldPtr())), + unionValue(shared_vector(nchannel,PVUnionPtr())), + value(shared_vector(nchannel,PVFieldPtr())), isConnected(false) { if(PvaClient::getDebug()) cout<< "PvaClientNTMultiPut::PvaClientNTMultiPut()\n"; @@ -54,7 +54,7 @@ PvaClientNTMultiPut::~PvaClientNTMultiPut() void PvaClientNTMultiPut::connect() { pvaClientPut.resize(nchannel); - shared_vector isConnected = pvaClientMultiChannel->getIsConnected(); + shared_vector isConnected = pvaClientMultiChannel->getIsConnected(); for(size_t i=0; iisConnected = true; } -shared_vector PvaClientNTMultiPut::getValues() +shared_vector PvaClientNTMultiPut::getValues() { if(!isConnected) connect(); + shared_vector isConnected = pvaClientMultiChannel->getIsConnected(); + for(size_t i=0; icreatePut(); + pvaClientPut[i]->connect(); + pvaClientPut[i]->get(); + value[i] = pvaClientPut[i]->getData()->getValue(); + FieldCreatePtr fieldCreate = getFieldCreate(); + PVDataCreatePtr pvDataCreate = getPVDataCreate(); + FieldBuilderPtr builder = fieldCreate->createFieldBuilder(); + builder->add("value",value[i]->getField()); + unionValue[i] = pvDataCreate->createPVUnion(builder->createUnion()); + } + } + } return unionValue; } void PvaClientNTMultiPut::put() { if(!isConnected) connect(); - shared_vector isConnected = pvaClientMultiChannel->getIsConnected(); + shared_vector isConnected = pvaClientMultiChannel->getIsConnected(); for(size_t i=0; icreatePut(); + pvaClientPut[i]->connect(); + pvaClientPut[i]->get(); + value[i] = pvaClientPut[i]->getData()->getValue(); + FieldCreatePtr fieldCreate = getFieldCreate(); + PVDataCreatePtr pvDataCreate = getPVDataCreate(); + FieldBuilderPtr builder = fieldCreate->createFieldBuilder(); + builder->add("value",value[i]->getField()); + unionValue[i] = pvDataCreate->createPVUnion(builder->createUnion()); + } value[i]->copy(*unionValue[i]->get()); pvaClientPut[i]->issuePut(); } - if(isConnected[i]) { - Status status = pvaClientPut[i]->waitPut(); - if(status.isOK()) continue; - string message = string("channel ") +pvaClientChannelArray[i]->getChannelName() - + " PvaChannelPut::waitPut " + status.getMessage(); - throw std::runtime_error(message); + } + for(size_t i=0; iwaitPut(); + if(status.isOK()) continue; + string message = string("channel ") +pvaClientChannelArray[i]->getChannelName() + + " PvaChannelPut::waitPut " + status.getMessage(); + throw std::runtime_error(message); } } } diff --git a/src/pvaClientProcess.cpp b/src/pvaClientProcess.cpp index 59ec66f..789fe44 100644 --- a/src/pvaClientProcess.cpp +++ b/src/pvaClientProcess.cpp @@ -42,7 +42,7 @@ public: return clientProcess->getRequesterName(); } - virtual void message(std::string const & message, epics::pvData::MessageType messageType) { + virtual void message(std::string const & message, MessageType messageType) { PvaClientProcessPtr clientProcess(pvaClientProcess.lock()); if(!clientProcess) return; clientProcess->message(message,messageType); @@ -138,25 +138,17 @@ void PvaClientProcess::channelProcessConnect( } { Lock xx(mutex); - this->channelProcess = channelProcess; + channelProcessConnectStatus = status; if(status.isOK()) { - channelProcessConnectStatus = status; + this->channelProcess = channelProcess; 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); - } + } + waitForConnect.signal(); } PvaClientProcessRequesterPtr req(pvaClientProcessRequester.lock()); if(req) { req->channelProcessConnect(status,shared_from_this()); } - waitForConnect.signal(); - } void PvaClientProcess::processDone( @@ -173,13 +165,12 @@ void PvaClientProcess::processDone( Lock xx(mutex); channelProcessStatus = status; processState = processComplete; + waitForProcess.signal(); } - PvaClientProcessRequesterPtr req(pvaClientProcessRequester.lock()); if(req) { req->processDone(status,shared_from_this()); } - waitForProcess.signal(); } void PvaClientProcess::connect() @@ -221,17 +212,7 @@ Status PvaClientProcess::waitConnect() << " channelName " << pvaClientChannel->getChannel()->getChannelName() << endl; } - if(connectState==connected) { - if(!channelProcessConnectStatus.isOK()) connectState = connectIdle; - return channelProcessConnectStatus; - } - if(connectState!=connectActive) { - string message = string("channel ") + pvaClientChannel->getChannel()->getChannelName() - + " pvaClientProcess illegal connect state "; - throw std::runtime_error(message); - } waitForConnect.wait(); - if(!channelProcessConnectStatus.isOK()) connectState = connectIdle; return channelProcessConnectStatus; } @@ -274,18 +255,6 @@ Status PvaClientProcess::waitProcess() << " channelName " << pvaClientChannel->getChannel()->getChannelName() << endl; } - { - Lock xx(mutex); - if(processState==processComplete) { - processState = processIdle; - return channelProcessStatus; - } - if(processState!=processActive){ - string message = string("channel ") + pvaClientChannel->getChannel()->getChannelName() - + " PvaClientProcess::waitProcess llegal process state"; - throw std::runtime_error(message); - } - } waitForProcess.wait(); processState = processComplete; return channelProcessStatus; diff --git a/src/pvaClientPut.cpp b/src/pvaClientPut.cpp index 4e00e7a..81d6196 100644 --- a/src/pvaClientPut.cpp +++ b/src/pvaClientPut.cpp @@ -42,7 +42,7 @@ public: return clientPut->getRequesterName(); } - virtual void message(std::string const & message, epics::pvData::MessageType messageType) { + virtual void message(std::string const & message, MessageType messageType) { PvaClientPutPtr clientPut(pvaClientPut.lock()); if(!clientPut) return; clientPut->message(message,messageType); @@ -163,27 +163,19 @@ void PvaClientPut::channelPutConnect( } { Lock xx(mutex); - this->channelPut = channelPut; + channelPutConnectStatus = status; if(status.isOK()) { - channelPutConnectStatus = status; + this->channelPut = channelPut; connectState = connected; pvaClientData = PvaClientPutData::create(structure); pvaClientData->setMessagePrefix(channelPut->getChannel()->getChannelName()); - } else { - stringstream ss; - ss << pvRequest; - string message = string("\nPvaClientPut::channelPutConnect)") - + "\npvRequest\n" + ss.str() - + "\nerror\n" + status.getMessage(); - channelPutConnectStatus = Status(Status::STATUSTYPE_ERROR,message); - } + } + waitForConnect.signal(); } PvaClientPutRequesterPtr req(pvaClientPutRequester.lock()); if(req) { req->channelPutConnect(status,shared_from_this()); } - waitForConnect.signal(); - } void PvaClientPut::getDone( @@ -207,14 +199,14 @@ void PvaClientPut::getDone( BitSetPtr bs = pvaClientData->getChangedBitSet(); bs->clear(); *bs |= *bitSet; - putState = putComplete; - } + } + putState = putComplete; + waitForGetPut.signal(); } PvaClientPutRequesterPtr req(pvaClientPutRequester.lock()); if(req) { req->getDone(status,shared_from_this()); } - waitForGetPut.signal(); } void PvaClientPut::putDone( @@ -231,12 +223,10 @@ void PvaClientPut::putDone( Lock xx(mutex); channelGetPutStatus = status; putState = putComplete; + waitForGetPut.signal(); } PvaClientPutRequesterPtr req(pvaClientPutRequester.lock()); - if(req) { - req->putDone(status,shared_from_this()); - } - waitForGetPut.signal(); + if(req) { req->putDone(status,shared_from_this());} } void PvaClientPut::connect() @@ -281,20 +271,7 @@ Status PvaClientPut::waitConnect() << " channelName " << pvaClientChannel->getChannel()->getChannelName() << endl; } - { - Lock xx(mutex); - if(connectState==connected) { - if(!channelPutConnectStatus.isOK()) connectState = connectIdle; - return channelPutConnectStatus; - } - if(connectState!=connectActive) { - string message = string("channel ") + pvaClientChannel->getChannel()->getChannelName() - + " PvaClientPut::waitConnect illegal connect state "; - throw std::runtime_error(message); - } - } waitForConnect.wait(); - if(!channelPutConnectStatus.isOK()) connectState = connectIdle; return channelPutConnectStatus; } @@ -340,17 +317,8 @@ Status PvaClientPut::waitGet() << " channelName " << pvaClientChannel->getChannel()->getChannelName() << endl; } - { - Lock xx(mutex); - if(putState==putComplete) return channelGetPutStatus; - if(putState!=getActive){ - string message = string("channel ") - + pvaClientChannel->getChannel()->getChannelName() - + " PvaClientPut::waitGet illegal put state"; - throw std::runtime_error(message); - } - } waitForGetPut.wait(); + putState = putComplete; return channelGetPutStatus; } @@ -379,12 +347,12 @@ void PvaClientPut::issuePut() << " pvStructure\n" << pvaClientData->getPVStructure() << " bitSet " << *pvaClientData->getChangedBitSet() << endl << endl; - } + } if(connectState==connectIdle) connect(); if(putState==getActive || putState==putActive) { string message = string("channel ") + pvaClientChannel->getChannel()->getChannelName() - + "PvaClientPut::issuePut get or put aleady active "; + + " PvaClientPut::issuePut get or put aleady active "; throw std::runtime_error(message); } putState = putActive; @@ -398,17 +366,8 @@ Status PvaClientPut::waitPut() << " channelName " << pvaClientChannel->getChannel()->getChannelName() << endl; } - { - Lock xx(mutex); - if(putState==putComplete) return channelGetPutStatus; - if(putState!=putActive){ - string message = string("channel ") - + pvaClientChannel->getChannel()->getChannelName() - + " PvaClientPut::waitPut illegal put state"; - throw std::runtime_error(message); - } - } waitForGetPut.wait(); + putState = putComplete; if(channelGetPutStatus.isOK()) pvaClientData->getChangedBitSet()->clear(); return channelGetPutStatus; } diff --git a/src/pvaClientPutGet.cpp b/src/pvaClientPutGet.cpp index 0bffd17..2f0e47b 100644 --- a/src/pvaClientPutGet.cpp +++ b/src/pvaClientPutGet.cpp @@ -41,7 +41,7 @@ public: return clientPutGet->getRequesterName(); } - virtual void message(std::string const & message, epics::pvData::MessageType messageType) { + virtual void message(std::string const & message, MessageType messageType) { PvaClientPutGetPtr clientPutGet(pvaClientPutGet.lock()); if(!clientPutGet) return; clientPutGet->message(message,messageType); @@ -176,30 +176,21 @@ void PvaClientPutGet::channelPutGetConnect( } { Lock xx(mutex); - this->channelPutGet = channelPutGet; + channelPutGetConnectStatus = status; if(status.isOK()) { - channelPutGetConnectStatus = status; + this->channelPutGet = channelPutGet; connectState = connected; pvaClientPutData = PvaClientPutData::create(putStructure); pvaClientPutData->setMessagePrefix(channelPutGet->getChannel()->getChannelName()); pvaClientGetData = PvaClientGetData::create(getStructure); pvaClientGetData->setMessagePrefix(channelPutGet->getChannel()->getChannelName()); - - } else { - stringstream ss; - ss << pvRequest; - string message = string("\nPvaClientPutGet::channelPutGetConnect)") - + "\npvRequest\n" + ss.str() - + "\nerror\n" + status.getMessage(); - channelPutGetConnectStatus = Status(Status::STATUSTYPE_ERROR,message); - } + } + waitForConnect.signal(); } PvaClientPutGetRequesterPtr req(pvaClientPutGetRequester.lock()); if(req) { req->channelPutGetConnect(status,shared_from_this()); } - waitForConnect.signal(); - } void PvaClientPutGet::putGetDone( @@ -217,16 +208,16 @@ void PvaClientPutGet::putGetDone( { Lock xx(mutex); channelPutGetStatus = status; - putGetState = putGetComplete; if(status.isOK()) { pvaClientGetData->setData(getPVStructure,getChangedBitSet); } + putGetState = putGetComplete; + waitForPutGet.signal(); } PvaClientPutGetRequesterPtr req(pvaClientPutGetRequester.lock()); if(req) { req->putGetDone(status,shared_from_this()); } - waitForPutGet.signal(); } void PvaClientPutGet::getPutDone( @@ -244,7 +235,6 @@ void PvaClientPutGet::getPutDone( { Lock xx(mutex); channelPutGetStatus = status; - putGetState = putGetComplete; if(status.isOK()) { PVStructurePtr pvs = pvaClientPutData->getPVStructure(); pvs->copyUnchecked(*putPVStructure,*putBitSet); @@ -252,12 +242,13 @@ void PvaClientPutGet::getPutDone( bs->clear(); *bs |= *putBitSet; } + putGetState = putGetComplete; + waitForPutGet.signal(); } PvaClientPutGetRequesterPtr req(pvaClientPutGetRequester.lock()); if(req) { req->getPutDone(status,shared_from_this()); } - waitForPutGet.signal(); } void PvaClientPutGet::getGetDone( @@ -275,16 +266,16 @@ void PvaClientPutGet::getGetDone( { Lock xx(mutex); channelPutGetStatus = status; - putGetState = putGetComplete; if(status.isOK()) { pvaClientGetData->setData(getPVStructure,getChangedBitSet); } + putGetState = putGetComplete; + waitForPutGet.signal(); } PvaClientPutGetRequesterPtr req(pvaClientPutGetRequester.lock()); if(req) { req->getGetDone(status,shared_from_this()); } - waitForPutGet.signal(); } void PvaClientPutGet::connect() @@ -329,21 +320,7 @@ Status PvaClientPutGet::waitConnect() << " channelName " << pvaClientChannel->getChannel()->getChannelName() << endl; } - { - Lock xx(mutex); - if(connectState==connected) { - if(!channelPutGetConnectStatus.isOK()) connectState = connectIdle; - return channelPutGetConnectStatus; - } - if(connectState!=connectActive) { - string message = string("channel ") - + pvaClientChannel->getChannel()->getChannelName() - + " PvaClientPutGet::waitConnect illegal connect state "; - throw std::runtime_error(message); - } - } waitForConnect.wait(); - if(!channelPutGetConnectStatus.isOK()) connectState = connectIdle; return channelPutGetConnectStatus; } @@ -391,13 +368,6 @@ Status PvaClientPutGet::waitPutGet() << " channelName " << pvaClientChannel->getChannel()->getChannelName() << endl; } - if(putGetState==putGetComplete) return channelPutGetStatus; - if(putGetState!=putGetActive){ - string message = string("channel ") - + pvaClientChannel->getChannel()->getChannelName() - + " PvaClientPutGet::waitPutGet get or put aleady active "; - throw std::runtime_error(message); - } waitForPutGet.wait(); if(channelPutGetStatus.isOK()) pvaClientPutData->getChangedBitSet()->clear(); return channelPutGetStatus; @@ -445,13 +415,6 @@ Status PvaClientPutGet::waitGetGet() << " channelName " << pvaClientChannel->getChannel()->getChannelName() << endl; } - if(putGetState==putGetComplete) return channelPutGetStatus; - if(putGetState!=putGetActive){ - string message = string("channel ") - + pvaClientChannel->getChannel()->getChannelName() - + " PvaClientPutGet::waitGetGet get or put aleady active "; - throw std::runtime_error(message); - } waitForPutGet.wait(); return channelPutGetStatus; } @@ -498,13 +461,6 @@ Status PvaClientPutGet::waitGetPut() << " channelName " << pvaClientChannel->getChannel()->getChannelName() << endl; } - if(putGetState==putGetComplete) return channelPutGetStatus; - if(putGetState!=putGetActive){ - string message = string("channel ") - + pvaClientChannel->getChannel()->getChannelName() - + " PvaClientPutGet::waitGetPut get or put aleady active "; - throw std::runtime_error(message); - } waitForPutGet.wait(); return channelPutGetStatus; } diff --git a/src/pvaClientRPC.cpp b/src/pvaClientRPC.cpp index 9b95551..feedf7d 100644 --- a/src/pvaClientRPC.cpp +++ b/src/pvaClientRPC.cpp @@ -45,14 +45,14 @@ public: return clientRPC->getRequesterName(); } - virtual void message(std::string const & message, epics::pvData::MessageType messageType) { + virtual void message(std::string const & message, MessageType messageType) { PvaClientRPCPtr clientRPC(pvaClientRPC.lock()); if(!clientRPC) return; clientRPC->message(message,messageType); } virtual void channelRPCConnect( - const epics::pvData::Status& status, + const Status& status, ChannelRPC::shared_pointer const & channelRPC) { PvaClientRPCPtr clientRPC(pvaClientRPC.lock());