mainly documentation changes; did much testing
This commit is contained in:
@ -267,7 +267,6 @@ void LongArrayChannelPut::run()
|
||||
if(iterBetweenCreateChannel!=0) {
|
||||
if(numChannelCreate>=iterBetweenCreateChannel) {
|
||||
channel->destroy();
|
||||
epicsThreadSleep(1.0);
|
||||
ChannelProvider::shared_pointer channelProvider =
|
||||
getChannelProviderRegistry()->getProvider(providerName);
|
||||
channel = channelProvider->createChannel(
|
||||
|
@ -1,9 +1,8 @@
|
||||
<h1>TODO</h1>
|
||||
<h2>monitorPlugin</h2>
|
||||
<p>A debate is on-going about what semantics should be.</p>
|
||||
<h2>memory leak</h2>
|
||||
<p>arrayPerformanceMain shows a slight memory leak at termination.</p>
|
||||
<h2>channel destroy and recreate</h2>
|
||||
<p>longArrayGet and longArrayPut fail if the channel is destroyed and immediately recreated. If epicsThreadSleep(1.0) is called between destroy and recreate then they work. The current version of each does wait.</p>
|
||||
<h2>Must test record delete.</h2>
|
||||
<p>Must test removing a record from the PVDatabase while a pvAccess client
|
||||
is attached. Also why do both unlisten and detach exists?</p>
|
||||
<h2>create more regresion tests</h2>
|
||||
<p>Currently only some simple tests exist. Most of the testing has been via the examples</p>
|
@ -6,16 +6,12 @@ monitorPlugin
|
||||
|
||||
A debate is on-going about what semantics should be.
|
||||
|
||||
|
||||
memory leak
|
||||
--------
|
||||
|
||||
arrayPerformanceMain shows a slight memory leak at termination.
|
||||
|
||||
channel destroy and recreate
|
||||
Must test record delete.
|
||||
-------------------
|
||||
|
||||
longArrayGet and longArrayPut fail if the channel is destroyed and immediately recreated. If epicsThreadSleep(1.0) is called between destroy and recreate then they work. The current version of each does wait.
|
||||
Must test removing a record from the PVDatabase while a pvAccess client
|
||||
is attached. Also why do both unlisten and detach exists?
|
||||
|
||||
|
||||
create more regresion tests
|
||||
----------------
|
||||
|
@ -38,7 +38,7 @@
|
||||
<h1>pvDatabaseCPP</h1>
|
||||
<!-- Maturity: Working Draft or Request for Comments, or Recommendation, and date. -->
|
||||
|
||||
<h2 class="nocount">EPICS v4 Working Group, Working Draft, 10-July-2014</h2>
|
||||
<h2 class="nocount">EPICS v4 Working Group, Working Draft, 11-August-2014</h2>
|
||||
<dl>
|
||||
<dt>Latest version:</dt>
|
||||
<dd><a
|
||||
@ -78,7 +78,7 @@ V4 control system programming environment:<br />
|
||||
|
||||
<h2 class="nocount">Status of this Document</h2>
|
||||
|
||||
<p>This is the 10-July-2014 version of of pvDatabaseCPP.</p>
|
||||
<p>This is the 11-August-2014 version of of pvDatabaseCPP.</p>
|
||||
</p>
|
||||
<p>This version is a complete implementation of what is described in this manual.
|
||||
</div>
|
||||
@ -98,6 +98,7 @@ A service can be run as a main process or can be part of a V3 IOC.
|
||||
Thus services can be developed that interact with V3 records, asynDriver,
|
||||
areaDetector, etc.
|
||||
</p>
|
||||
|
||||
<p>A brief description of a pvDatabase is that it is a set of network accessible, smart,
|
||||
memory resident records.
|
||||
Each record has data composed of a top level PVStructure.
|
||||
@ -146,6 +147,8 @@ level PVStructure and the following three methods:</p>
|
||||
<dt>destroy</dt>
|
||||
<dd>This releases and resources used by the implementation.</dd>
|
||||
</dl>
|
||||
<p>Doxygen documentation is available at <a
|
||||
href="./html/index.html">doxygenDoc</a></p>
|
||||
<h3>Getting started</h3>
|
||||
<p>The first step is to build pvDatabaseCPP as described in the next section.</p>
|
||||
<p>One of the examples is exampleServer.
|
||||
@ -897,6 +900,174 @@ It provides access to PVRecords and is accessed by the server side of remote pvA
|
||||
It uses the copy and monitor facilities from pvDataCPP and connects
|
||||
them to a PVRecord.
|
||||
</p>
|
||||
<p>The implementation is a complete implementation of channelProvider
|
||||
and channel except for channelRPC, which is implement by pvAccess as a separate
|
||||
channel provider.</p>
|
||||
<p>The following provides a brief description of each channel method that
|
||||
is implemented.</p>
|
||||
<h3>channelProcessLocal</h3>
|
||||
<p>Needs to be described.</p>
|
||||
<h3>channelGetLocal</h3>
|
||||
<p>Needs to be described.</p>
|
||||
<h3>channelPutLocal</h3>
|
||||
<p>Needs to be described.</p>
|
||||
<h3>channelPutGetLocal</h3>
|
||||
<p>Needs to be described.</p>
|
||||
<h3>channelArrayLocal</h3>
|
||||
<p>Needs to be described.</p>
|
||||
<h3>MonitorLocal</h3>
|
||||
<p>This is the code that implements monitors on changes to fields of a PVRecord.
|
||||
Because it is called by pvAccess client (monitor methods) and by
|
||||
PVRecord (when postPut is called), it must be careful to prevent deadlocks.
|
||||
The implementation is via class MonitorLocal (implmented in monitorFactory.cpp)
|
||||
and PVCopyMonitor.
|
||||
MonitorLocal is the interface between pvAccess and PVCopyMonitor.
|
||||
PVCopyMonitor is the interface between MonitorLocal and PVRecord.
|
||||
MonitorLocal manages a MonitorElement queue.
|
||||
While monitoring is active (between start and stop) it keeps an active element
|
||||
for use by PVCopyMonitor.
|
||||
While monitoring is active PVCopyMonitor updates the active monitor element whenever
|
||||
a postPut is issued to any field being monitored.
|
||||
</p>
|
||||
<p>The following two sections provide a few more details about MonitorLocal
|
||||
and PVCopyMonitor.<p>
|
||||
<h4>MonitorLocal</h4>
|
||||
<p>MonitorLocal implements the following abstract base classes:</p>
|
||||
<dl>
|
||||
<dt>Monitor</dt>
|
||||
<dd>This is described by pvDataCPP.
|
||||
It has methods start, stop, poll, and release.
|
||||
These methods are called by the pvAccess client
|
||||
</dd>
|
||||
<dt>PVCopyMonitorRequester</dt>
|
||||
<dd>This has methods releaseActiveElement and unlisten.
|
||||
These methods are called by PVCopyMonitor.
|
||||
</dd>
|
||||
</dl>
|
||||
MonitorLocal manages the following:
|
||||
<dl>
|
||||
<dt>MonitorElementQueue</dt>
|
||||
<dd>This is a queue of monitor elements.
|
||||
A Queue is implemented by pvDataCPP and used by MonitorLocal.
|
||||
It is a finite queue.
|
||||
A monitor element is described by pvDataCPP.
|
||||
It has fields pvStructure, changedBitSet, and overrunBitSet.
|
||||
The pvStructure holds data for a subset of the fields in a PVRecord.
|
||||
The changedBitSet and overrunBitSet describe changes between
|
||||
monitor event.
|
||||
MonitorLocal creates an instance of PVCopy (implemented by pvDataCPP),
|
||||
which manages the interaction between the set of fields being
|
||||
monitored and the fields in the top level PVStructure of the PVRecord.
|
||||
pvCopy is also used to create the pvStructure for each monitor element.
|
||||
</dd>
|
||||
<dt>activeElement</dt>
|
||||
<dd>Whenever monitoring is active monitorLocal
|
||||
keeps an active element for use by pvCopyMonitor.
|
||||
It changes the active element based on calls to poll (by the
|
||||
client) and calls to releaseActiveElement (by pvCopyMonitor).
|
||||
If there are no free element when releaseActiveElement is
|
||||
called the current active element is returned.
|
||||
If a free element is available the client is notified that a new
|
||||
monitor element is available and the free element becomes the
|
||||
active element.
|
||||
</dd>
|
||||
</dl>
|
||||
<p>A brief description on each method in MonitorLocal is:</p>
|
||||
<dl>
|
||||
<dt>start</dt>
|
||||
<dd>
|
||||
Called by client.
|
||||
With a lock held it clears the monitorElement queue
|
||||
and allocates an active element.
|
||||
With no lock held calls pvCopyMonitor->startMonitoring(activeElement)
|
||||
<dd>
|
||||
<dt>stop</dt>
|
||||
<dd>
|
||||
Called by client.
|
||||
With no lock held calls pvCopyMonitor->stopMonitoring(activeElement)
|
||||
</dd>
|
||||
<dt>poll</dt>
|
||||
<dd>
|
||||
Called by client.
|
||||
With a lock held it calls queue->getUsed();
|
||||
</dd>
|
||||
<dt>release</dt>
|
||||
<dd>
|
||||
Called by client.
|
||||
With a lock held it calls queue->releaseUsed();
|
||||
</dd>
|
||||
<dt>releaseActiveElement</dt>
|
||||
<dd>
|
||||
Called by PVCopyMonitor with no locks held.
|
||||
With a lock held it tries to get a new free element.
|
||||
If it can't it just returns the current active element.
|
||||
Otherwise it does the following.
|
||||
Using the activeElement it updates the pvStructure
|
||||
and compresses the changed and overrun bitSet.
|
||||
It then calls queue->setUsed(activeElement);
|
||||
It then sets the active element to the new free element.
|
||||
With no lock held it calls monitorRequester->monitorEvent(getPtrSelf())
|
||||
and finally returns the new active element,
|
||||
</dd>
|
||||
<dt>unlisten</dt>
|
||||
<dd>
|
||||
With no lock held it calls monitorRequester->unlisten(getPtrSelf());
|
||||
</dd>
|
||||
</dl>
|
||||
<h4>PVCopyMonitor</h4>
|
||||
<p>
|
||||
pvCopyMonitor is the code that manages changes to
|
||||
fields in the record.
|
||||
It is called by PVRecord whenever a postPut is issued to a field.
|
||||
pvCopyMonitor uses the active monitor element provided by monitorFactory.
|
||||
Note that this method is called with the record locked.
|
||||
It only modifies the changedBitSet and overrunBitSet of the
|
||||
active element but never modifies the pvStructure.
|
||||
</p>
|
||||
<p>A brief description of the pvCopyMonitor methods is:</p>
|
||||
<dl>
|
||||
<dt>startMonitoring</dt>
|
||||
<dd>With no lock held it sets its monitorElement to the
|
||||
startElement pased by monitorLocal and calls pvRecord->addListener(getPtrSelf()).
|
||||
It locks the pvRecord.
|
||||
It calls calls addListener for every field in the record that is being
|
||||
monitored.
|
||||
It clears the overrun and changed bit sets.
|
||||
It sets bit 0 of the changed bit set and calls
|
||||
pvCopyMonitorRequester->releaseActiveElement();
|
||||
Thus the client will get the initial values for every field being monitored.
|
||||
The record is unlocked and the method returns to the caller.
|
||||
</dd>
|
||||
<dt>stopMonitoring</dt>
|
||||
<dd>
|
||||
With no lock held it calls pvRecord->removeListener(getPtrSelf());
|
||||
</dd>
|
||||
<dt>dataPut</dt>
|
||||
<dd>
|
||||
This is called because of a call to postPut.
|
||||
It is called with the record locked.
|
||||
It updates the changed and overrun bitSets.
|
||||
It isGroupPut is false it calls
|
||||
pvCopyMonitorRequester->releaseActiveElement().
|
||||
Otherwise it sets dataChanged true.
|
||||
</dd>
|
||||
<dt>beginGroupPut</dt>
|
||||
<dd>
|
||||
With a lock held it
|
||||
sets isGroupPut true and dataChanged false.
|
||||
</dd>
|
||||
<dt>endGroupPut</dt>
|
||||
<dd>
|
||||
With a lock held it sets isGroupPut false.
|
||||
With no lock held and dataChanged true it calls
|
||||
pvCopyMonitorRequester->releaseActiveElement()
|
||||
</dd>
|
||||
<dt>unlisten</dt>
|
||||
<dd>
|
||||
Just calls pvCopyMonitorRequester->unlisten();
|
||||
</dd>
|
||||
</dl>
|
||||
|
||||
<h2>special</h2>
|
||||
<p>This section provides two useful record support modules
|
||||
and one that is used for testing.</p>
|
||||
|
@ -1295,7 +1295,7 @@ void ChannelLocal::printInfo()
|
||||
|
||||
void ChannelLocal::printInfo(std::ostream& out)
|
||||
{
|
||||
out << "ChannelLocal provides access to service";
|
||||
out << "ChannelLocal provides access to a record in the local PVDatabase";
|
||||
}
|
||||
|
||||
}}
|
||||
|
@ -71,8 +71,10 @@ ChannelProviderLocalPtr getChannelProviderLocal()
|
||||
if(channelProviderLocal.get()==NULL) {
|
||||
channelProviderLocal = ChannelProviderLocalPtr(
|
||||
new ChannelProviderLocal());
|
||||
ChannelProvider::shared_pointer xxx = dynamic_pointer_cast<ChannelProvider>(channelProviderLocal);
|
||||
channelProviderLocal->channelFinder = SyncChannelFind::shared_pointer(new SyncChannelFind(xxx));
|
||||
ChannelProvider::shared_pointer xxx =
|
||||
dynamic_pointer_cast<ChannelProvider>(channelProviderLocal);
|
||||
channelProviderLocal->channelFinder =
|
||||
SyncChannelFind::shared_pointer(new SyncChannelFind(xxx));
|
||||
LocalChannelProviderFactory::create(channelProviderLocal);
|
||||
}
|
||||
return channelProviderLocal;
|
||||
|
@ -57,12 +57,32 @@ typedef std::tr1::shared_ptr<ChannelLocal> ChannelLocalPtr;
|
||||
|
||||
epicsShareExtern MonitorFactoryPtr getMonitorFactory();
|
||||
|
||||
/** MonitorFactory
|
||||
* This class provides a static method to create a monitor for a PVRecord
|
||||
*/
|
||||
class epicsShareClass MonitorFactory
|
||||
{
|
||||
public:
|
||||
POINTER_DEFINITIONS(MonitorFactory);
|
||||
/**
|
||||
* Destructor
|
||||
*/
|
||||
virtual ~MonitorFactory();
|
||||
/**
|
||||
* Destroy the monitor factory.
|
||||
*/
|
||||
virtual void destroy();
|
||||
/**
|
||||
* Create a monitor on a record.
|
||||
* This is called by the local channel provider.
|
||||
* @param pvRecord The record to monitor.
|
||||
* @param monitorRequester The client callback.
|
||||
* @param pvRequest Options specified by the client.
|
||||
* This includes the subset of the fields in the record to monitor.
|
||||
* @return A shared pointer to the newly created monitor.
|
||||
* If the monitor can not be created a null monitor is returned.
|
||||
* This means the pvRequest specified options that could not be satisfied.
|
||||
*/
|
||||
epics::pvData::MonitorPtr createMonitor(
|
||||
PVRecordPtr const & pvRecord,
|
||||
epics::pvData::MonitorRequester::shared_pointer const & monitorRequester,
|
||||
@ -78,24 +98,79 @@ private:
|
||||
|
||||
epicsShareExtern ChannelProviderLocalPtr getChannelProviderLocal();
|
||||
|
||||
/**
|
||||
* An implementation of channelProvider that provides access to records in PVDatabase.
|
||||
*/
|
||||
class epicsShareClass ChannelProviderLocal :
|
||||
public epics::pvAccess::ChannelProvider,
|
||||
public std::tr1::enable_shared_from_this<ChannelProviderLocal>
|
||||
{
|
||||
public:
|
||||
POINTER_DEFINITIONS(ChannelProviderLocal);
|
||||
/**
|
||||
* Destructor
|
||||
*/
|
||||
virtual ~ChannelProviderLocal();
|
||||
/**
|
||||
* Destroy the channel provider.
|
||||
* Probably never called.
|
||||
*/
|
||||
virtual void destroy();
|
||||
/**
|
||||
* Returns the channel provider name.
|
||||
* @return <b>local</b>
|
||||
*/
|
||||
virtual std::string getProviderName();
|
||||
/**
|
||||
* Returns either a null channelFind or a channelFind for records in the PVDatabase.
|
||||
* @param channelName The name of the channel desired.
|
||||
* @param channelFindRequester The client callback.
|
||||
* @return shared pointer to ChannelFind.
|
||||
* This is null if the channelName is not the name of a record in the PVDatabase.
|
||||
* It is an implementation of SyncChannelFind if the channelName is the name
|
||||
* of a record in the PVDatabase.
|
||||
* The interface for SyncChannelFind is defined by pvAccessCPP.
|
||||
* The channelFindResult method of channelFindRequester is called before the
|
||||
* method returns.
|
||||
*/
|
||||
virtual epics::pvAccess::ChannelFind::shared_pointer channelFind(
|
||||
std::string const &channelName,
|
||||
epics::pvAccess::ChannelFindRequester::shared_pointer const & channelFindRequester);
|
||||
/**
|
||||
* Calls method channelListRequester::channelListResult which provides the
|
||||
* caller with a list of the record names on the PVDatabase.
|
||||
* A record name is the same as a channel name.
|
||||
* @param channelListRequester The client callback.
|
||||
* @return shared pointer to ChannelFind.
|
||||
* The interface for SyncChannelFind is defined by pvAccessCPP.
|
||||
*/
|
||||
virtual epics::pvAccess::ChannelFind::shared_pointer channelList(
|
||||
epics::pvAccess::ChannelListRequester::shared_pointer const & channelListRequester);
|
||||
/**
|
||||
* Create a channel for a record.
|
||||
* This method just calls the next method with a address of "".
|
||||
* @param channelName The name of the channel desired.
|
||||
* @param channelRequester The client callback.
|
||||
* @param priority The priority.
|
||||
* @return shared pointer to Channel.
|
||||
*/
|
||||
virtual epics::pvAccess::Channel::shared_pointer createChannel(
|
||||
std::string const &channelName,
|
||||
epics::pvAccess::ChannelRequester::shared_pointer const &channelRequester,
|
||||
short priority);
|
||||
/**
|
||||
* Create a channel for a record.
|
||||
* @param channelName The name of the channel desired.
|
||||
* @param channelRequester The callback to call with the result.
|
||||
* @param priority The priority.
|
||||
* This is ignored.
|
||||
* @param address The address.
|
||||
* This is ignored.
|
||||
* @return shared pointer to Channel.
|
||||
* This is null if the channelName is not the name of a record in the PVDatabase.
|
||||
* Otherwise it is a newly created channel inteface.
|
||||
* ChannelRequester::channelCreated is called to give the result.
|
||||
*/
|
||||
virtual epics::pvAccess::Channel::shared_pointer createChannel(
|
||||
std::string const &channelName,
|
||||
epics::pvAccess::ChannelRequester::shared_pointer const &channelRequester,
|
||||
@ -115,6 +190,10 @@ private:
|
||||
friend class ChannelProviderLocalRun;
|
||||
};
|
||||
|
||||
/**
|
||||
* A Channel for accessing a record in the PVDatabase.
|
||||
* It is a complete implementation of Channel
|
||||
*/
|
||||
class epicsShareClass ChannelLocal :
|
||||
public epics::pvAccess::Channel,
|
||||
public PVRecordClient,
|
||||
@ -122,54 +201,185 @@ class epicsShareClass ChannelLocal :
|
||||
{
|
||||
public:
|
||||
POINTER_DEFINITIONS(ChannelLocal);
|
||||
/** Constructor
|
||||
* @param channelProvider The channel provider.
|
||||
* @param requester The client callback.
|
||||
* @param pvRecord The record the channel will access.
|
||||
*/
|
||||
ChannelLocal(
|
||||
ChannelProviderLocalPtr const &channelProvider,
|
||||
epics::pvAccess::ChannelRequester::shared_pointer const & requester,
|
||||
PVRecordPtr const & pvRecord
|
||||
);
|
||||
/**
|
||||
* Destructor
|
||||
*/
|
||||
virtual ~ChannelLocal();
|
||||
/**
|
||||
* Destroy the channel.
|
||||
* It cleans up all resources used to access the record.
|
||||
* Note that this assumes that client has destroyed any objects that
|
||||
* have been created for the channel like channelGet, etc.
|
||||
* The remote pvAccess server does this cleanup.
|
||||
*/
|
||||
virtual void destroy();
|
||||
/**
|
||||
* Get the requester name.
|
||||
* @param returns the name of the channel requester.
|
||||
*/
|
||||
virtual std::string getRequesterName();
|
||||
/**
|
||||
* Passes the message to the channel requester.
|
||||
* @param message The message.
|
||||
* @param messageType The message type.
|
||||
*/
|
||||
virtual void message(
|
||||
std::string const & message,
|
||||
epics::pvData::MessageType messageType);
|
||||
/**
|
||||
* Get the channel provider
|
||||
* @return The provider.
|
||||
*/
|
||||
virtual epics::pvAccess::ChannelProvider::shared_pointer getProvider()
|
||||
{
|
||||
return provider;
|
||||
}
|
||||
/**
|
||||
* Get the remote address
|
||||
* @return <b>local</b>
|
||||
*/
|
||||
virtual std::string getRemoteAddress();
|
||||
/**
|
||||
* Get the connection state.
|
||||
* @return Channel::CONNECTED.
|
||||
*/
|
||||
virtual epics::pvAccess::Channel::ConnectionState getConnectionState();
|
||||
/**
|
||||
* Get the channel name.
|
||||
* @return the record name.
|
||||
*/
|
||||
virtual std::string getChannelName();
|
||||
/**
|
||||
* Get the channel requester
|
||||
* @return The channel requester.
|
||||
*/
|
||||
virtual epics::pvAccess::ChannelRequester::shared_pointer getChannelRequester();
|
||||
/**
|
||||
* Is the channel connected?
|
||||
* @return true
|
||||
*/
|
||||
virtual bool isConnected();
|
||||
/**
|
||||
* Get the introspection interface for subField.
|
||||
* The introspection interface is given via GetFieldRequester::getDone.
|
||||
* @param requester The client callback.
|
||||
* @param The subField of the record.
|
||||
* If an empty string then the interface for the top level structure of
|
||||
* the record is provided.
|
||||
*/
|
||||
virtual void getField(
|
||||
epics::pvAccess::GetFieldRequester::shared_pointer const &requester,
|
||||
std::string const & subField);
|
||||
/**
|
||||
* Get the access rights for the record.
|
||||
* This throws an exception because it is assumed that access rights are
|
||||
* handled by a higher level.
|
||||
*/
|
||||
virtual epics::pvAccess::AccessRights getAccessRights(
|
||||
epics::pvData::PVField::shared_pointer const &pvField);
|
||||
/**
|
||||
* Create a channelProcess.
|
||||
* See pvAccess.html for details.
|
||||
* @param requester The client callback.
|
||||
* @param pvRequest The options specified by the client.
|
||||
* @return A shared pointer to the newly created implementation.
|
||||
* The implementation is null if pvRequest has invalid options.
|
||||
*/
|
||||
virtual epics::pvAccess::ChannelProcess::shared_pointer createChannelProcess(
|
||||
epics::pvAccess::ChannelProcessRequester::shared_pointer const &requester,
|
||||
epics::pvData::PVStructurePtr const &pvRequest);
|
||||
/**
|
||||
* Create a channelGet.
|
||||
* See pvAccess.html for details.
|
||||
* @param requester The client callback.
|
||||
* @param pvRequest The options specified by the client.
|
||||
* @return A shared pointer to the newly created implementation.
|
||||
* The implementation is null if pvRequest has invalid options.
|
||||
*/
|
||||
virtual epics::pvAccess::ChannelGet::shared_pointer createChannelGet(
|
||||
epics::pvAccess::ChannelGetRequester::shared_pointer const &requester,
|
||||
epics::pvData::PVStructurePtr const &pvRequest);
|
||||
/**
|
||||
* Create a channelPut.
|
||||
* See pvAccess.html for details.
|
||||
* @param requester The client callback.
|
||||
* @param pvRequest The options specified by the client.
|
||||
* @return A shared pointer to the newly created implementation.
|
||||
* The implementation is null if pvRequest has invalid options.
|
||||
*/
|
||||
virtual epics::pvAccess::ChannelPut::shared_pointer createChannelPut(
|
||||
epics::pvAccess::ChannelPutRequester::shared_pointer const &requester,
|
||||
epics::pvData::PVStructurePtr const &pvRequest);
|
||||
/**
|
||||
* Create a channelPutGet.
|
||||
* See pvAccess.html for details.
|
||||
* @param requester The client callback.
|
||||
* @param pvRequest The options specified by the client.
|
||||
* @return A shared pointer to the newly created implementation.
|
||||
* The implementation is null if pvRequest has invalid options.
|
||||
*/
|
||||
virtual epics::pvAccess::ChannelPutGet::shared_pointer createChannelPutGet(
|
||||
epics::pvAccess::ChannelPutGetRequester::shared_pointer const &requester,
|
||||
epics::pvData::PVStructurePtr const &pvRequest);
|
||||
/**
|
||||
* Create a channelRPC.
|
||||
* This is not implemented because pvAccessCPP implements channelRPC.
|
||||
* The server side of remote pvAccess implements a channel provider
|
||||
* just for channelRPC.
|
||||
* @param requester The client callback
|
||||
* @param pvRequest The options specified by the client.
|
||||
* @return null.
|
||||
*/
|
||||
virtual epics::pvAccess::ChannelRPC::shared_pointer createChannelRPC(
|
||||
epics::pvAccess::ChannelRPCRequester::shared_pointer const &requester,
|
||||
epics::pvData::PVStructurePtr const &pvRequest);
|
||||
/**
|
||||
* Create a monitor.
|
||||
* See pvAccess.html for details.
|
||||
* @param requester The client callback.
|
||||
* @param pvRequest The options specified by the client.
|
||||
* @return A shared pointer to the newly created implementation.
|
||||
* The implementation is null if pvRequest has invalid options.
|
||||
*/
|
||||
virtual epics::pvData::Monitor::shared_pointer createMonitor(
|
||||
epics::pvData::MonitorRequester::shared_pointer const &requester,
|
||||
epics::pvData::PVStructurePtr const &pvRequest);
|
||||
/**
|
||||
* Create a channelArray.
|
||||
* See pvAccess.html for details.
|
||||
* @param requester The client callback.
|
||||
* @param pvRequest The options specified by the client.
|
||||
* @return A shared pointer to the newly created implementation.
|
||||
* The implementation is null if pvRequest has invalid options.
|
||||
*/
|
||||
virtual epics::pvAccess::ChannelArray::shared_pointer createChannelArray(
|
||||
epics::pvAccess::ChannelArrayRequester::shared_pointer const &requester,
|
||||
epics::pvData::PVStructurePtr const &pvRequest);
|
||||
/**
|
||||
* calls printInfo(std::cout);
|
||||
*/
|
||||
virtual void printInfo();
|
||||
/**
|
||||
* displays a message
|
||||
* "ChannelLocal provides access to a record in the local PVDatabase".
|
||||
* @param out the stream on which the message is displayed.
|
||||
*/
|
||||
virtual void printInfo(std::ostream& out);
|
||||
/**
|
||||
* This is called when a record is being removed from the database.
|
||||
* Calls destroy.
|
||||
* @record The record being destroyed.
|
||||
*/
|
||||
virtual void detach(PVRecordPtr const &pvRecord);
|
||||
protected:
|
||||
shared_pointer getPtrSelf()
|
||||
|
@ -168,18 +168,6 @@ void MonitorLocal::release(MonitorElementPtr const & monitorElement)
|
||||
queue->releaseUsed(monitorElement);
|
||||
}
|
||||
|
||||
|
||||
MonitorElementPtr MonitorLocal::getActiveElement()
|
||||
{
|
||||
if(pvRecord->getTraceLevel()>1)
|
||||
{
|
||||
cout << "MonitorLocal::getActiveElement() " << endl;
|
||||
}
|
||||
if(isDestroyed) return activeElement;
|
||||
Lock xx(mutex);
|
||||
return activeElement;
|
||||
}
|
||||
|
||||
MonitorElementPtr MonitorLocal::releaseActiveElement()
|
||||
{
|
||||
if(pvRecord->getTraceLevel()>1)
|
||||
|
@ -45,6 +45,10 @@ struct PVCopyMonitorFieldNode;
|
||||
typedef std::tr1::shared_ptr<PVCopyMonitorFieldNode> PVCopyMonitorFieldNodePtr;
|
||||
|
||||
|
||||
/**
|
||||
* PVCopyMonitor
|
||||
* This class manages changes to fields being monitored in a PVRecord.
|
||||
*/
|
||||
class epicsShareClass PVCopyMonitor :
|
||||
public PVListener,
|
||||
public epics::pvData::PVCopyTraverseMasterCallback,
|
||||
@ -52,25 +56,80 @@ class epicsShareClass PVCopyMonitor :
|
||||
{
|
||||
public:
|
||||
POINTER_DEFINITIONS(PVCopyMonitor);
|
||||
/**
|
||||
* Factory method to create a PVCopyMonoitor
|
||||
* @param pvCopyMonitorRequester This is usually MonitorLocal.
|
||||
* @param pvRecord The record being monitored.
|
||||
* @param pvCopy An instance of pvCopy
|
||||
* @return A shared pointer to a PVCopyMonitor.
|
||||
*/
|
||||
static PVCopyMonitorPtr create(
|
||||
PVCopyMonitorRequesterPtr const &pvCopyMonitorRequester,
|
||||
PVRecordPtr const &pvRecord,
|
||||
epics::pvData::PVCopyPtr const & pvCopy);
|
||||
/**
|
||||
* Destructor
|
||||
*/
|
||||
virtual ~PVCopyMonitor();
|
||||
/**
|
||||
* Destroy the PVCopyMonitor
|
||||
*/
|
||||
virtual void destroy();
|
||||
/**
|
||||
* Calls pvRecord methods to start monitoring for calls to postPut.
|
||||
* @param monitorElement the initial monotorElement
|
||||
* This holds the change and overrun bitSets that are updated
|
||||
* when postPut is called.
|
||||
*/
|
||||
void startMonitoring(
|
||||
epics::pvData::MonitorElementPtr const & monitorElement);
|
||||
/**
|
||||
* Calls pvRecord methods to stop monitoring for calls to postPut.
|
||||
*/
|
||||
void stopMonitoring();
|
||||
// following are PVListener methods
|
||||
/**
|
||||
* The record is being removed from the PVDatabase.
|
||||
* @param The record being removed.
|
||||
*/
|
||||
virtual void detach(PVRecordPtr const & pvRecord);
|
||||
/**
|
||||
* A postPut has been issued to a field being monitored.
|
||||
* @param pvRecordField The field.
|
||||
*/
|
||||
virtual void dataPut(PVRecordFieldPtr const & pvRecordField);
|
||||
/**
|
||||
* A postPut has been issued to a subfield of a field being monitored.
|
||||
* @param requested The field being monitored.
|
||||
* @param pvRecordField The field being modified.
|
||||
*/
|
||||
virtual void dataPut(
|
||||
PVRecordStructurePtr const & requested,
|
||||
PVRecordFieldPtr const & pvRecordField);
|
||||
/**
|
||||
* A group of puts are being changed.
|
||||
* No monitors should be issued until endGroupPut is called.
|
||||
* @param pvRecord The record.
|
||||
*/
|
||||
virtual void beginGroupPut(PVRecordPtr const & pvRecord);
|
||||
/**
|
||||
* The end of a group of puts.
|
||||
* If any fields have changed value since beginGroupPut a monitor
|
||||
* can be issued.
|
||||
* @param pvRecord The record.
|
||||
*/
|
||||
virtual void endGroupPut(PVRecordPtr const & pvRecord);
|
||||
/**
|
||||
* The record is being removed from the database.
|
||||
* @param pvRecord The record.
|
||||
*/
|
||||
virtual void unlisten(PVRecordPtr const & pvRecord);
|
||||
// following is PVCopyTraverseMasterCallback method
|
||||
/**
|
||||
* The PVCopyTraverseMasterCallback callback
|
||||
* Called for every field of PVRecord that is being monoitored.
|
||||
* @param pvField The field in the PVRecord.
|
||||
*/
|
||||
virtual void nextMasterPVField(epics::pvData::PVFieldPtr const &pvField);
|
||||
private:
|
||||
PVCopyMonitorPtr getPtrSelf()
|
||||
@ -100,7 +159,6 @@ class epicsShareClass PVCopyMonitorRequester
|
||||
public:
|
||||
POINTER_DEFINITIONS(PVCopyMonitorRequester);
|
||||
virtual ~PVCopyMonitorRequester() {}
|
||||
virtual epics::pvData::MonitorElementPtr getActiveElement() = 0;
|
||||
virtual epics::pvData::MonitorElementPtr releaseActiveElement() = 0;
|
||||
virtual void unlisten() = 0;
|
||||
};
|
||||
|
@ -20,16 +20,39 @@ namespace epics { namespace pvDatabase {
|
||||
class RecordListRecord;
|
||||
typedef std::tr1::shared_ptr<RecordListRecord> RecordListRecordPtr;
|
||||
|
||||
/**
|
||||
* This is a record that provides a PVStringArray that
|
||||
* has the record names of all records in the local PVDatabase.
|
||||
* It is meant to be used by a channelPutGet request.
|
||||
*/
|
||||
class epicsShareClass RecordListRecord :
|
||||
public PVRecord
|
||||
{
|
||||
public:
|
||||
POINTER_DEFINITIONS(RecordListRecord);
|
||||
/**
|
||||
* Factory methods to create RecordListRecord.
|
||||
* @param recordName The name for the RecordListRecord.
|
||||
* @return A shared pointer to RecordListRecord..
|
||||
*/
|
||||
static RecordListRecordPtr create(
|
||||
std::string const & recordName);
|
||||
/**
|
||||
* destructor
|
||||
*/
|
||||
virtual ~RecordListRecord();
|
||||
/**
|
||||
* Clean up any resources used.
|
||||
*/
|
||||
virtual void destroy();
|
||||
/**
|
||||
* standard init method required by PVRecord
|
||||
* @return true unless record name already exists.
|
||||
*/
|
||||
virtual bool init();
|
||||
/*
|
||||
* Generated the list of record names.
|
||||
*/
|
||||
virtual void process();
|
||||
private:
|
||||
RecordListRecord(std::string const & recordName,
|
||||
|
@ -18,6 +18,12 @@
|
||||
namespace epics { namespace pvDatabase {
|
||||
|
||||
|
||||
/**
|
||||
* A record to set the trace value for another record
|
||||
* It is meant to be used via a channelPutGet request.
|
||||
* The argument has two fields: recordName and level.
|
||||
* The result has a field named status.
|
||||
*/
|
||||
class TraceRecord;
|
||||
typedef std::tr1::shared_ptr<TraceRecord> TraceRecordPtr;
|
||||
|
||||
@ -26,11 +32,29 @@ class epicsShareClass TraceRecord :
|
||||
{
|
||||
public:
|
||||
POINTER_DEFINITIONS(TraceRecord);
|
||||
/**
|
||||
* Factory methods to create TraceRecord.
|
||||
* @param recordName The name for the TraceRecord.
|
||||
* @return A shared pointer to TraceRecord..
|
||||
*/
|
||||
static TraceRecordPtr create(
|
||||
std::string const & recordName);
|
||||
/**
|
||||
* destructor
|
||||
*/
|
||||
virtual ~TraceRecord();
|
||||
/**
|
||||
* Clean up any resources used.
|
||||
*/
|
||||
virtual void destroy();
|
||||
/**
|
||||
* standard init method required by PVRecord
|
||||
* @return true unless record name already exists.
|
||||
*/
|
||||
virtual bool init();
|
||||
/**
|
||||
* Set the trace level.
|
||||
*/
|
||||
virtual void process();
|
||||
private:
|
||||
TraceRecord(
|
||||
|
Reference in New Issue
Block a user