Table of Contents

support for copy and monitor

copy and monitor are not used in this project. They are intended for use by pvAccess and by pvAccess servers. They are provided with this project because the code depends only on pvData itself.

This document describes C++ specific code. pvRequest.html provides a language independent overview of copy and monitor.

NOTE:pvRequest.html must be updated since it is based on an earlier version of pvCopy that had knowledge of PVRecord. The C++ version was implemented in pvDatabaseCPP and the Java version on pvIOCJava. At present only the C++ version of the new API for pvCopy is implemented.

Copy provides:

createRequest
The Channel create methods in pvAccess all have an argument PVStructure pvRequest.
Given an ascii string createRequest creates a PVStructure that provides a pvData representation of the information from the ascii string. It is this structure that can be passed to the channel create methods.
The information in a pvRequest selects an arbitrary subset of the fields in a top level structure that resides in the server. In addition options can be specified. Both global and field specific options can be specified.
pvCopy
This is a facility used by channel providers. It provides client specific code that manages a copy of an arbitrary subset of the fields in a top level structure that resides in the provider. It also allows provider access to options specified by the client.
Monitor provides:
monitor
This is support code for channel providers that implement channel monitor. It, together with the queue facility, provides support for monitor queues.

support for copy

copy provides the ability to create a structure that has a copy of an arbitrary subset of the fields in an existing top level structure. In addition it allows global options and field specific options. It has two main components: createRequest and pvCopy. Given a string createRequest creates a pvRequest, which is a PVStructure that has the format expected by pvCopy.

createRequest

This is mainly used by pvAccess clients. Given a request string it creates a pvRequest structure that can be passed to the pvAccess create methods. In turn pvAccess passes the pvRequest to a local channel provider which then passes it to pvCopy.

The definition of the public members is:

class CreateRequest {
...
     static CreateRequestPtr create();
     virtual PVStructurePtr createRequest(std::string const &request);
     std::string getMessage();
};

An example of how it is used is:

CreateRequestPtr createRequest = CreateRequest::create();
PVStructurePtr pvRequest = createRequest->createRequest(request);
if(pvRequest==NULL) {
    std::string error = createRequest->getMessage();
    // take some action
} else {
    //success do something
}

pvCopy

The definition of the public members is:

class epicsShareClass PVCopyTraverseMasterCallback
{
...
    virtual void nextMasterPVField(PVFieldPtr const &pvField);
};

class class epicsShareClass PVCopy
{
...
    static PVCopyPtr create(
        PVStructurePtr const &pvMaster,
        PVStructurePtr const &pvRequest,
        std::string const & structureName);
    PVStructurePtr getPVMaster();
    void traverseMaster(PVCopyTraverseMasterCallbackPtr const & callback);
    StructureConstPtr getStructure();
    PVStructurePtr createPVStructure();
    size_t getCopyOffset(PVFieldPtr const  &masterPVField);
    size_t getCopyOffset(
        PVStructurePtr const  &masterPVStructure,
        PVFieldPtr const  &masterPVField);
     PVFieldPtr getMasterPVField(std::size_t structureOffset);
     void initCopy(
        PVStructurePtr const  &copyPVStructure,
        BitSetPtr const  &bitSet);
     void updateCopySetBitSet(
        PVStructurePtr const  &copyPVStructure,
        BitSetPtr const  &bitSet);
    void updateCopyFromBitSet(
        PVStructurePtr const  &copyPVStructure,
        BitSetPtr const  &bitSet);
    void updateMaster(
        PVStructurePtr const  &copyPVStructure,
        BitSetPtr const  &bitSet);
    PVStructurePtr getOptions(std::size_t fieldOffset);
...
};
where
PVCopyTraverseMasterCallback::nextMasterPVField
PVCopyTraverseMasterCallback is a callback which must be implemented by the code that uses pvCopy, normally the channel provider. It has the single method nextMasterPVField
nextMasterPVField is called for each field in the master as a result of a call to traverseMaster.
create
This is the method for creating a PVCopy instance.
pvMaster
the top level structure managed by the server.
pvRequest
selects the set of subfields desired and options for each field.
structureName
the name for the top level of any PVStructure created.
getPVMaster
Gets the top level structure from pvMaster.
traverseMaster
Traverse all fields of the top level structure of pvMaster. For each field the callback is called.
getStructure
Get the introspection interface for a PVStructure for e copy.
createPVStructure
Create a copy instance. Monitors keep a queue of monitor elements. Since each element needs a PVStructure, multiple top level structures will be created.
getCopyOffset
Given a field in pvMaster. return the offset in copy for the same field. A value of std::string::npos means that the copy does not have this field. Two overloaded methods are provided. The first is called if the field of master is not a structure. The second is for subfields of a structure.
getMasterPVField
Given a offset in the copy get the corresponding field in pvMaster.
initCopy
Initialize the fields in copyPVStructure by giving each field the value from the corresponding field in pvMaster. bitSet will be set to show that all fields are changed. This means that bit set will have the value {0}.
updateCopySetBitSet
Set all fields in copyPVStructure to the value of the corresponding field in pvMaster. Each field that is changed has it's corresponding bit set in bitSet.
updateCopyFromBitSet
For each set bit in bitSet set the field in copyPVStructure to the value of the corresponding field in pvMaster.
updateMaster
For each set bit in bitSet set the field in pvMaster to the value of the corresponding field in copyPVStructure.
getOptions
Get the options for the field at the specified offset. A NULL is returned if no options were specified for the field. If options were specified,PVStructurePtr is a structure with a set of PVString subfields that specify name,value pairs. name is the subField name and value is the subField value.

support for monitor

This consists of two components:

monitor
Used by code that implements pvAccess monitors.

monitor

class MonitorElement {
    MonitorElement(PVStructurePtr const & pvStructurePtr);
    PVStructurePtr pvStructurePtr;
    BitSetPtr changedBitSet;
    BitSetPtr overrunBitSet;
};

class Monitor {
    virtual Status start() = 0;
    virtual Status stop() = 0;
    virtual MonitorElementPtr poll() = 0;
    virtual void release(MonitorElementPtr const & monitorElement) = 0;
};

class MonitorRequester : public virtual Requester {
    virtual void monitorConnect(Status const & status,
        MonitorPtr const & monitor, StructureConstPtr const & structure) = 0;
    virtual void monitorEvent(MonitorPtr const & monitor) = 0;
    virtual void unlisten(MonitorPtr const & monitor) = 0;
};

monitorElement

MonitorElement holds the data for one element of a monitor queue. It has the fields:

pvStructurePtr
A top level structure with data values at the time the monitors occurs.
changedBitSet
Shows which fields have changed since the previous monitor.
overrunBitSet
Shows which fields have changed more han once since the previous monitor.

monitorElement queue

A queue of monitor elements must be implemented by any channel provider that implements Channel::createMonitor. For an example implementation look at pvDatabaseCPP. It has the following:

typedef Queue<MonitorElement> MonitorElementQueue;
typedef std::tr1::shared_ptr<MonitorElementQueue> MonitorElementQueuePtr;

class MultipleElementQueue :
    public ElementQueue
{
public:
    POINTER_DEFINITIONS(MultipleElementQueue);
    virtual ~MultipleElementQueue(){}
    MultipleElementQueue(
        MonitorLocalPtr const &monitorLocal,
        MonitorElementQueuePtr const &queue,
        size_t nfields);
    virtual void destroy(){}
    virtual Status start();
    virtual Status stop();
    virtual bool dataChanged();
    virtual MonitorElementPtr poll();
    virtual void release(MonitorElementPtr const &monitorElement);
...
};

Monitor

Monitor must be implemented by any channel provider that implements Channel::createMonitor. Remote PVAccess also implements Monitor on the client side. Note that each client has it's own queue that is not shared with other client.

Monitor has the following methods:

start
Start monitoring. This will result in a an initial monitor that has the current value of all fields.
stop
Stop monitoring.
poll
Called to get a monitor element. If no new elements are available then a null pointer is returned.
release
Release the monitor element. The caller owns the monitor element between the calls to poll and release.

MonitorRequester

This must be implemented by a pvAccess client. It has the methods:

monitorConnect
A monitor has either connected of disconnected.
monitorEvent
A new monitor element is available.
unlisten
The channel is going away. The client cam no longer access the monitor.