Overview
This example provides the following:
- exampleLinkMain
-
A database with records named exampleMonitorLink, exampleGetLink, and examplePutLink.
Each has a link to another channel.
The process method of the records use pvaChannelMonitor, pvaChannelGet,
and pvaChannelPut to connect to the other channel.
- exampleLinkClient
-
This uses pvaClientPut to change values in the record to which exampleLinkMain
connects and uses pvaClientMonitor to monitor changes in pvaChannelMonitor.
- doubleArrayMain
-
This is an PVDatabase that holds a PVRecord in another IOC to which exampleLinkMain
can connect.
- v3IOC
-
A V3 softIOC that can be used to create a V3 DBRecord to which exampleLinkMain
can connect.
exampleLinkMain
exampleLinkMain supports help as follows:
mrk> pwd
/home/epicsv4/release4_6/exampleJava/exampleLink
mrk> scripts/exampleLinkMain -help
provider linkedRecordName generateLinkedRecord
default
pva doubleArray true
mrk>
The arguments are:
- provider
-
This can be pva or ca or local.
ca only works if channelName is a accessable via the ca network protocol,
e. g. it is the name of a DBRecord in a V3 IOC.
local only works if generateLinkedRecord is true.
- linkedRecordName
-
The name of the channel to which records
exampleMonitorLink, exampleGetLink, and examplePutLink connect.
- generateLinkedRecord
-
If true then record generateLinkedRecord is allocated in the same IOC.
exampleLinkClient
exampleLinkClient supports help as follows:
mrk> pwd
/home/epicsv4/release4_6/exampleJava/exampleLink
mrk> scripts/exampleLinkClient -help
provider linkedRecordName
default
pva doubleArray
The arguments are:
- provider
-
This can be pva or ca or local.
ca only works if channelName is a accessable via the ca network protocol,
e. g. it is the name of a DBRecord in a V3 IOC.
local only works if generateLinkedRecord is true.
- linkedRecordName
-
The name of the channel to which records
exampleMonitorLink, exampleGetLink, and examplePutLink connect.
doubleArrayMain
doubleArrayMain supports help as follows:
mrk> pwd
/home/epicsv4/release4_6/exampleJava/exampleLink
mrk> scripts/exampleLinkdoubleArrayMain -help
doubleArrayRecordName
default
doubleArrayExternal
The argument is:
- doubleArrayRecordName
-
The channel name of the PVRecord.
- linkedRecordName
-
The name of the channel to which records
exampleMonitorLink, exampleGetLink, and examplePutLink connect.
Using exampleLinkMain to test providers pva, local and ca
channel provider pva
Just start exampleLinkMain and exampleLinkClient with the default options.
channel provider local
start exampleLinkMain as:
scripts/exampleLinkMain local
exampleLinkClient can be started with the default options.
channel provider ca
In order to test using provider ca
a softIoc for record doubleArray must also be started:
mrk> pwd
/home/epicsv4/master/exampleJava/exampleLink/v3IOC
mrk> softIoc st.cmd
Start exampleLinkMain:
scripts/exampleLinkMain ca doubleArray false
Start exampleLinkClient:
scripts/exampleLinkClient ca
Discussion
Access Alternatives
The process routine of a PVRecord can access other PVRecords in two ways:
- Directly accessing local pvDatabase
-
If the other PVRecord is accessed via the master PVDatabase then
threading issues are up to the implementation.
- Access via channelProvider pva or ca
-
If provider pva or ca is used then locking is handled by pvAccess.
- Access via channelProvider local
-
If provider local is used the implementation must be careful that it does not
cause deadlocks.
When the process method is called the pvRecord for the process method is locked.
When it makes a pvAccess get, put, etc request the other record is locked.
Thus if a set of pvAccess links are implemented the possibility of deadlocks
exists. A simple example is two records that have links to each other.
More complex sets are easily created.
Unless the developer has complete control of the set of records then remote pvAccess should
be used.
But this results in more context switches.
Data synchronization
If pvAccess (provider pva or ca) is used then it handles data synchronization.
This is done by making a copy of the data that is transferred between the two pvRecords.
This is true if either remote or local pvAccess is used.
Each get, put, etc request results in data being copied between the two records.
If the linked channel is a local pvRecord then,
for scalar and structure arrays,
raw data is NOT copied for gets.
This is because pvData uses shared_vector to hold the raw data.
Instead of copying the raw data the reference count is incremented.
For puts the linked array will force a new allocation of the raw data in the linked record,
i. e. copy on write semantics are enforced. This is done automatically
by pvData and not by pvDatabase.